From c799a6a5c884831c3c3ea57d30fbe4ab35709d49 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Wed, 25 Apr 2012 23:23:48 +0000 Subject: [PATCH] If a type is non-literal by virtue of being incomplete produce notes explaining that. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155598 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 2 ++ lib/Sema/SemaType.cpp | 9 +++++++-- test/CXX/basic/basic.types/p10.cpp | 6 +++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index f9fb2bb4fb..b0e5deba51 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1367,6 +1367,8 @@ def err_constexpr_virtual : Error<"virtual function cannot be constexpr">; def err_constexpr_virtual_base : Error< "constexpr %select{member function|constructor}0 not allowed in " "%select{class|struct}1 with virtual base %plural{1:class|:classes}2">; +def note_non_literal_incomplete : Note< + "incomplete type %0 is not a literal type">; def note_non_literal_virtual_base : Note<"%select{class|struct}0 with virtual " "base %plural{1:class|:classes}1 is not a literal type">; def note_constexpr_virtual_base_here : Note<"virtual base class declared here">; diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 1b95f05c79..8b237c8a3c 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -4301,9 +4301,14 @@ bool Sema::RequireLiteralType(SourceLocation Loc, QualType T, const CXXRecordDecl *RD = cast(RT->getDecl()); - // FIXME: Better diagnostic for incomplete class? - if (!RD->isCompleteDefinition()) + // A partially-defined class type can't be a literal type, because a literal + // class type must have a trivial destructor (which can't be checked until + // the class definition is complete). + if (!RD->isCompleteDefinition()) { + RequireCompleteType(Loc, ElemType, + PDiag(diag::note_non_literal_incomplete) << T); 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, diff --git a/test/CXX/basic/basic.types/p10.cpp b/test/CXX/basic/basic.types/p10.cpp index 83b910b606..191d42bebd 100644 --- a/test/CXX/basic/basic.types/p10.cpp +++ b/test/CXX/basic/basic.types/p10.cpp @@ -22,11 +22,11 @@ struct BeingDefined { // (implied) - it is complete -struct Incomplete; +struct Incomplete; // expected-note 2{{forward declaration of 'Incomplete'}} template 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 Incomplete incomplete = {}; // expected-error {{constexpr variable cannot have non-literal type 'const Incomplete'}} expected-note {{incomplete type 'const Incomplete' is not a literal type}} +constexpr Incomplete incomplete2[] = {}; // expected-error {{constexpr variable cannot have non-literal type 'Incomplete const[]'}} expected-note {{incomplete type 'Incomplete const[]' is not a literal type}} constexpr ClassTemp classtemplate = {}; constexpr ClassTemp classtemplate2[] = {}; -- 2.40.0