Author: nico Date: Wed Feb 24 14:58:14 2016 New Revision: 261770 URL: http://llvm.org/viewvc/llvm-project?rev=261770&view=rev Log: Fix rejects-valid caused by r261297.
r261297 called hasUserProvidedDefaultConstructor() to check if defining a const object is ok. This is incorrect for this example: struct X { template<typename ...T> X(T...); int n; }; const X x; // formerly OK, now bogus error Instead, track if a class has a defaulted default constructor, and disallow a const object for classes that either have defaulted default constructors or if they need an implicit constructor. Bug report and fix approach by Richard Smith, thanks! Modified: cfe/trunk/include/clang/AST/DeclCXX.h cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/lib/AST/DeclCXX.cpp cfe/trunk/lib/Serialization/ASTReaderDecl.cpp cfe/trunk/lib/Serialization/ASTWriter.cpp cfe/trunk/test/SemaCXX/cxx0x-cursory-default-delete.cpp Modified: cfe/trunk/include/clang/AST/DeclCXX.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=261770&r1=261769&r2=261770&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/DeclCXX.h (original) +++ cfe/trunk/include/clang/AST/DeclCXX.h Wed Feb 24 14:58:14 2016 @@ -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 Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=261770&r1=261769&r2=261770&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Wed Feb 24 14:58:14 2016 @@ -2040,6 +2040,8 @@ bool ASTNodeImporter::ImportDefinition(R ToData.HasIrrelevantDestructor = FromData.HasIrrelevantDestructor; ToData.HasConstexprNonCopyMoveConstructor = FromData.HasConstexprNonCopyMoveConstructor; + ToData.HasDefaultedDefaultConstructor + = FromData.HasDefaultedDefaultConstructor; ToData.DefaultedDefaultConstructorIsConstexpr = FromData.DefaultedDefaultConstructorIsConstexpr; ToData.HasConstexprDefaultConstructor Modified: cfe/trunk/lib/AST/DeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=261770&r1=261769&r2=261770&view=diff ============================================================================== --- cfe/trunk/lib/AST/DeclCXX.cpp (original) +++ cfe/trunk/lib/AST/DeclCXX.cpp Wed Feb 24 14:58:14 2016 @@ -61,6 +61,7 @@ CXXRecordDecl::DefinitionData::Definitio 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) { Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=261770&r1=261769&r2=261770&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Wed Feb 24 14:58:14 2016 @@ -1423,6 +1423,7 @@ void ASTDeclReader::ReadCXXDefinitionDat 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) Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=261770&r1=261769&r2=261770&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original) +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Wed Feb 24 14:58:14 2016 @@ -5558,6 +5558,7 @@ void ASTWriter::AddCXXDefinitionData(con 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); Modified: cfe/trunk/test/SemaCXX/cxx0x-cursory-default-delete.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-cursory-default-delete.cpp?rev=261770&r1=261769&r2=261770&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/cxx0x-cursory-default-delete.cpp (original) +++ cfe/trunk/test/SemaCXX/cxx0x-cursory-default-delete.cpp Wed Feb 24 14:58:14 2016 @@ -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 { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits