Make RequireLiteralType work correctly with incomplete array types.  PR12037.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151005 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 9c8a68b..d9867fd 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -4249,7 +4249,9 @@
                               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 @@
   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 7641e09..83b910b 100644
--- a/test/CXX/basic/basic.types/p10.cpp
+++ b/test/CXX/basic/basic.types/p10.cpp
@@ -11,8 +11,25 @@
 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}}