diff options
-rw-r--r-- | clang/include/clang/AST/DeclCXX.h | 7 | ||||
-rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 2 | ||||
-rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 1 | ||||
-rw-r--r-- | clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp | 33 |
6 files changed, 47 insertions, 1 deletions
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index dde0270ce3b..d5cdc09fc4a 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -421,6 +421,10 @@ class CXXRecordDecl : public RecordDecl { /// constructor which is neither the copy nor move constructor. bool HasConstexprNonCopyMoveConstructor : 1; + /// \brief True if this class has a (possibly implicit) defaulted default + /// constructor. + bool HasDefaultedDefaultConstructor : 1; + /// \brief True if a defaulted default constructor for this class would /// be constexpr. bool DefaultedDefaultConstructorIsConstexpr : 1; @@ -1278,7 +1282,8 @@ public: /// per core issue 253. bool allowConstDefaultInit() const { return !data().HasUninitializedFields || - hasUserProvidedDefaultConstructor(); + !(data().HasDefaultedDefaultConstructor || + needsImplicitDefaultConstructor()); } /// \brief Determine whether this class has a destructor which has no diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 1ea44fe6006..d6b9424fb4d 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -2040,6 +2040,8 @@ bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To, ToData.HasIrrelevantDestructor = FromData.HasIrrelevantDestructor; ToData.HasConstexprNonCopyMoveConstructor = FromData.HasConstexprNonCopyMoveConstructor; + ToData.HasDefaultedDefaultConstructor + = FromData.HasDefaultedDefaultConstructor; ToData.DefaultedDefaultConstructorIsConstexpr = FromData.DefaultedDefaultConstructorIsConstexpr; ToData.HasConstexprDefaultConstructor diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index e84b91388fb..65bfc49daec 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -61,6 +61,7 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D) DefaultedDestructorIsDeleted(false), HasTrivialSpecialMembers(SMF_All), DeclaredNonTrivialSpecialMembers(0), HasIrrelevantDestructor(true), HasConstexprNonCopyMoveConstructor(false), + HasDefaultedDefaultConstructor(false), DefaultedDefaultConstructorIsConstexpr(true), HasConstexprDefaultConstructor(false), HasNonLiteralTypeFieldsOrBases(false), ComputedVisibleConversions(false), @@ -497,6 +498,8 @@ void CXXRecordDecl::addedMember(Decl *D) { data().UserProvidedDefaultConstructor = true; if (Constructor->isConstexpr()) data().HasConstexprDefaultConstructor = true; + if (Constructor->isDefaulted()) + data().HasDefaultedDefaultConstructor = true; } if (!FunTmpl) { diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index bf60ba9478a..5ef31c31bfa 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -1423,6 +1423,7 @@ void ASTDeclReader::ReadCXXDefinitionData( Data.DeclaredNonTrivialSpecialMembers = Record[Idx++]; Data.HasIrrelevantDestructor = Record[Idx++]; Data.HasConstexprNonCopyMoveConstructor = Record[Idx++]; + Data.HasDefaultedDefaultConstructor = Record[Idx++]; Data.DefaultedDefaultConstructorIsConstexpr = Record[Idx++]; Data.HasConstexprDefaultConstructor = Record[Idx++]; Data.HasNonLiteralTypeFieldsOrBases = Record[Idx++]; @@ -1548,6 +1549,7 @@ void ASTDeclReader::MergeDefinitionData( OR_FIELD(DeclaredNonTrivialSpecialMembers) MATCH_FIELD(HasIrrelevantDestructor) OR_FIELD(HasConstexprNonCopyMoveConstructor) + OR_FIELD(HasDefaultedDefaultConstructor) MATCH_FIELD(DefaultedDefaultConstructorIsConstexpr) OR_FIELD(HasConstexprDefaultConstructor) MATCH_FIELD(HasNonLiteralTypeFieldsOrBases) diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 1d1c99874b6..a88ab5fb5f2 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -5558,6 +5558,7 @@ void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Rec Record.push_back(Data.DeclaredNonTrivialSpecialMembers); Record.push_back(Data.HasIrrelevantDestructor); Record.push_back(Data.HasConstexprNonCopyMoveConstructor); + Record.push_back(Data.HasDefaultedDefaultConstructor); Record.push_back(Data.DefaultedDefaultConstructorIsConstexpr); Record.push_back(Data.HasConstexprDefaultConstructor); Record.push_back(Data.HasNonLiteralTypeFieldsOrBases); diff --git a/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp b/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp index f671bd190ec..17215fedf0a 100644 --- a/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp +++ b/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp @@ -74,6 +74,33 @@ struct some_init_container_ctor { struct no_fields_container { no_fields nf; }; +struct param_pack_ctor { + template <typename... T> + param_pack_ctor(T...); + int n; +}; +struct param_pack_ctor_field { + param_pack_ctor ndc; +}; +struct multi_param_pack_ctor { + template <typename... T, typename... U> + multi_param_pack_ctor(T..., U..., int f = 0); + int n; +}; +struct ignored_template_ctor_and_def { + template <class T> ignored_template_ctor_and_def(T* f = nullptr); + ignored_template_ctor_and_def() = default; + int field; +}; +template<bool, typename = void> struct enable_if {}; +template<typename T> struct enable_if<true, T> { typedef T type; }; +struct multi_param_pack_and_defaulted { + template <typename... T, + typename enable_if<sizeof...(T) != 0>::type* = nullptr> + multi_param_pack_and_defaulted(T...); + multi_param_pack_and_defaulted() = default; + int n; +}; void constobjs() { const no_fields nf; // ok @@ -88,6 +115,12 @@ void constobjs() { const some_init_container sicon; // expected-error {{default initialization of an object of const type 'const some_init_container' without a user-provided default constructor}} const some_init_container_ctor siconc; // ok const no_fields_container nfc; // ok + const param_pack_ctor ppc; // ok + const param_pack_ctor_field ppcf; // ok + const multi_param_pack_ctor mppc; // ok + const multi_param_pack_and_defaulted mppad; // expected-error {{default initialization of an object of const type 'const multi_param_pack_and_defaulted' without a user-provided default constructor}} + const ignored_template_ctor_and_def itcad; // expected-error {{default initialization of an object of const type 'const ignored_template_ctor_and_def' without a user-provided default constructor}} + } struct non_const_derived : non_const_copy { |