]> granicus.if.org Git - clang/commitdiff
Make RequireLiteralType work correctly with incomplete array types. PR12037.
authorEli Friedman <eli.friedman@gmail.com>
Mon, 20 Feb 2012 23:58:14 +0000 (23:58 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Mon, 20 Feb 2012 23:58:14 +0000 (23:58 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151005 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaType.cpp
test/CXX/basic/basic.types/p10.cpp

index 9c8a68b3da0292dd78e5ff70d1fdfc8778ee69d8..d9867fd1b01791af4ede518c9759cad4747ee5b2 100644 (file)
@@ -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
index 7641e09f61e096a969f47e6b5a79fe2f66cff0b5..83b910b60640dc1c3bee359c549591fad0856615 100644 (file)
@@ -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}}