aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaType.cpp10
-rw-r--r--test/CXX/basic/basic.types/p10.cpp17
2 files changed, 25 insertions, 2 deletions
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 9c8a68b3da..d9867fd1b0 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -4249,7 +4249,9 @@ bool Sema::RequireLiteralType(SourceLocation Loc, QualType T,
const PartialDiagnostic &PD) {
assert(!T->isDependentType() && "type should not be dependent");
- RequireCompleteType(Loc, T, 0);
+ QualType ElemType = Context.getBaseElementType(T);
+ RequireCompleteType(Loc, ElemType, 0);
+
if (T->isLiteralType())
return false;
@@ -4261,12 +4263,16 @@ bool Sema::RequireLiteralType(SourceLocation Loc, QualType T,
if (T->isVariableArrayType())
return true;
- const RecordType *RT = T->getBaseElementTypeUnsafe()->getAs<RecordType>();
+ const RecordType *RT = ElemType->getAs<RecordType>();
if (!RT)
return true;
const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+ // FIXME: Better diagnostic for incomplete class?
+ if (!RD->isCompleteDefinition())
+ return true;
+
// If the class has virtual base classes, then it's not an aggregate, and
// cannot have any constexpr constructors or a trivial default constructor,
// so is non-literal. This is better to diagnose than the resulting absence
diff --git a/test/CXX/basic/basic.types/p10.cpp b/test/CXX/basic/basic.types/p10.cpp
index 7641e09f61..83b910b606 100644
--- a/test/CXX/basic/basic.types/p10.cpp
+++ b/test/CXX/basic/basic.types/p10.cpp
@@ -11,8 +11,25 @@ constexpr int f1(double) { return 0; }
struct S { S(); };
constexpr int f2(S &) { return 0; }
+// FIXME: I'm not entirely sure whether the following is legal or not...
+struct BeingDefined;
+extern BeingDefined beingdefined;
+struct BeingDefined {
+ static constexpr BeingDefined& t = beingdefined;
+};
+
// - a class type that has all of the following properties:
+// (implied) - it is complete
+
+struct Incomplete;
+template<class T> struct ClassTemp {};
+
+constexpr Incomplete incomplete = {}; // expected-error {{constexpr variable cannot have non-literal type 'const Incomplete'}}
+constexpr Incomplete incomplete2[] = {}; // expected-error {{constexpr variable cannot have non-literal type 'Incomplete const[]'}}
+constexpr ClassTemp<int> classtemplate = {};
+constexpr ClassTemp<int> classtemplate2[] = {};
+
// - it has a trivial destructor
struct UserProvDtor {
constexpr int f(); // expected-error {{non-literal type 'UserProvDtor' cannot have constexpr members}}