diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2012-02-20 23:58:14 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2012-02-20 23:58:14 +0000 |
commit | ee0653963537f6ea60f655856fb0c83d7d4010db (patch) | |
tree | dae6cfe50c9f84c2ca80a099e32c70dfa555c517 | |
parent | a4c29b6e55c9d4ef44a51c45c6785e8b4fe9deed (diff) |
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
-rw-r--r-- | lib/Sema/SemaType.cpp | 10 | ||||
-rw-r--r-- | test/CXX/basic/basic.types/p10.cpp | 17 |
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}} |