Author: rsmith Date: Tue Nov 22 16:55:12 2016 New Revision: 287713 URL: http://llvm.org/viewvc/llvm-project?rev=287713&view=rev Log: Make diagnostic for use of default member initializer before enclosing class is complete a little more general; it is produced in other cases than the one that it previously talked about.
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/SemaDeclCXX.cpp cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp cfe/trunk/test/SemaCXX/cxx1y-initializer-aggregates.cpp cfe/trunk/test/SemaCXX/implicit-exception-spec.cpp cfe/trunk/test/SemaCXX/member-init.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=287713&r1=287712&r2=287713&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Nov 22 16:55:12 2016 @@ -7099,12 +7099,11 @@ def err_in_class_initializer_literal_typ "'constexpr' specifier">; def err_in_class_initializer_non_constant : Error< "in-class initializer for static data member is not a constant expression">; -def err_in_class_initializer_not_yet_parsed - : Error<"cannot use defaulted default constructor of %0 within the class " - "outside of member functions because %1 has an initializer">; -def err_in_class_initializer_not_yet_parsed_outer_class - : Error<"cannot use defaulted default constructor of %0 within " - "%1 outside of member functions because %2 has an initializer">; +def err_in_class_initializer_not_yet_parsed : Error< + "default member initializer for %1 needed within definition of enclosing " + "class %0 outside of member functions">; +def note_in_class_initializer_not_yet_parsed : Note< + "default member initializer declared here">; def err_in_class_initializer_cycle : Error<"default member initializer for %0 uses itself">; def err_exception_spec_cycle Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=287713&r1=287712&r2=287713&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Nov 22 16:55:12 2016 @@ -12378,14 +12378,9 @@ ExprResult Sema::BuildCXXDefaultInitExpr // constructor before the initializer is lexically complete will ultimately // come here at which point we can diagnose it. RecordDecl *OutermostClass = ParentRD->getOuterLexicalRecordContext(); - if (OutermostClass == ParentRD) { - Diag(Field->getLocEnd(), diag::err_in_class_initializer_not_yet_parsed) - << ParentRD << Field; - } else { - Diag(Field->getLocEnd(), - diag::err_in_class_initializer_not_yet_parsed_outer_class) - << ParentRD << OutermostClass << Field; - } + Diag(Loc, diag::err_in_class_initializer_not_yet_parsed) + << OutermostClass << Field; + Diag(Field->getLocEnd(), diag::note_in_class_initializer_not_yet_parsed); return ExprError(); } Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=287713&r1=287712&r2=287713&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Tue Nov 22 16:55:12 2016 @@ -2198,14 +2198,10 @@ bool Sema::InstantiateInClassInitializer if (!OldInit) { RecordDecl *PatternRD = Pattern->getParent(); RecordDecl *OutermostClass = PatternRD->getOuterLexicalRecordContext(); - if (OutermostClass == PatternRD) { - Diag(Pattern->getLocEnd(), diag::err_in_class_initializer_not_yet_parsed) - << PatternRD << Pattern; - } else { - Diag(Pattern->getLocEnd(), - diag::err_in_class_initializer_not_yet_parsed_outer_class) - << PatternRD << OutermostClass << Pattern; - } + Diag(PointOfInstantiation, + diag::err_in_class_initializer_not_yet_parsed) + << OutermostClass << Pattern; + Diag(Pattern->getLocEnd(), diag::note_in_class_initializer_not_yet_parsed); Instantiation->setInvalidDecl(); return true; } Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=287713&r1=287712&r2=287713&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original) +++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Tue Nov 22 16:55:12 2016 @@ -1862,8 +1862,8 @@ namespace ZeroSizeTypes { namespace BadDefaultInit { template<int N> struct X { static const int n = N; }; - struct A { - int k = // expected-error {{cannot use defaulted default constructor of 'A' within the class outside of member functions because 'k' has an initializer}} + struct A { // expected-error {{default member initializer for 'k' needed within definition of enclosing class}} + int k = // expected-note {{default member initializer declared here}} X<A().k>::n; // expected-error {{not a constant expression}} expected-note {{implicit default constructor for 'BadDefaultInit::A' first required here}} }; Modified: cfe/trunk/test/SemaCXX/cxx1y-initializer-aggregates.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-initializer-aggregates.cpp?rev=287713&r1=287712&r2=287713&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/cxx1y-initializer-aggregates.cpp (original) +++ cfe/trunk/test/SemaCXX/cxx1y-initializer-aggregates.cpp Tue Nov 22 16:55:12 2016 @@ -61,3 +61,19 @@ namespace nested_aggregate_init { }; static_assert(B(6).f() == 18, ""); } + +namespace use_self { + struct FibTree { + int n; + FibTree *l = // expected-note {{declared here}} + n > 1 ? new FibTree{n-1} : &fib0; // expected-error {{default member initializer for 'l' needed}} + FibTree *r = // expected-note {{declared here}} + n > 2 ? new FibTree{n-2} : &fib0; // expected-error {{default member initializer for 'r' needed}} + int v = l->v + r->v; + + static FibTree fib0; + }; + FibTree FibTree::fib0{0, nullptr, nullptr, 1}; + + int fib(int n) { return FibTree{n}.v; } +} Modified: cfe/trunk/test/SemaCXX/implicit-exception-spec.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/implicit-exception-spec.cpp?rev=287713&r1=287712&r2=287713&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/implicit-exception-spec.cpp (original) +++ cfe/trunk/test/SemaCXX/implicit-exception-spec.cpp Tue Nov 22 16:55:12 2016 @@ -16,31 +16,31 @@ namespace InClassInitializers { // Noexcept::Noexcept is not declared constexpr, therefore noexcept(Noexcept()) // is false. bool ThrowSomething() noexcept(false); - struct ConstExpr { - bool b = noexcept(ConstExpr()) && ThrowSomething(); // expected-error {{cannot use defaulted default constructor of 'ConstExpr' within the class outside of member functions}} + struct ConstExpr { // expected-error {{default member initializer for 'b' needed}} + bool b = noexcept(ConstExpr()) && ThrowSomething(); // expected-note {{declared here}} // expected-note@-1 {{implicit default constructor for 'InClassInitializers::ConstExpr' first required here}} }; // Much more obviously broken: we can't parse the initializer without already // knowing whether it produces a noexcept expression. - struct TemplateArg { - int n = ExceptionIf<noexcept(TemplateArg())>::f(); // expected-error {{cannot use defaulted default constructor of 'TemplateArg' within the class outside of member functions}} + struct TemplateArg { // expected-error {{default member initializer for 'n' needed}} + int n = ExceptionIf<noexcept(TemplateArg())>::f(); // expected-note {{declared here}} // expected-note@-1 {{implicit default constructor for 'InClassInitializers::TemplateArg' first required here}} }; // And within a nested class. struct Nested { // expected-note {{implicit default constructor for 'InClassInitializers::Nested::Inner' first required here}} - struct Inner { - // expected-error@+1 {{cannot use defaulted default constructor of 'Inner' within 'Nested' outside of member functions}} - int n = ExceptionIf<noexcept(Nested())>::f(); // expected-note {{implicit default constructor for 'InClassInitializers::Nested' first required here}} + struct Inner { // expected-error {{default member initializer for 'n' needed}} + int n = // expected-note {{declared here}} + ExceptionIf<noexcept(Nested())>::f(); // expected-note {{implicit default constructor for 'InClassInitializers::Nested' first required here}} } inner; }; struct Nested2 { // expected-error {{implicit default constructor for 'InClassInitializers::Nested2' must explicitly initialize the member 'inner' which does not have a default constructor}} struct Inner; int n = Inner().n; // expected-note {{implicit default constructor for 'InClassInitializers::Nested2::Inner' first required here}} - struct Inner { // expected-note {{declared here}} - // expected-error@+1 {{cannot use defaulted default constructor of 'Inner' within 'Nested2' outside of member functions}} + struct Inner { // expected-error {{initializer for 'n' needed}} expected-note {{declared here}} + // expected-note@+1 {{declared here}} int n = ExceptionIf<noexcept(Nested2())>::f(); // expected-note@-1 {{implicit default constructor for 'InClassInitializers::Nested2' first required here}} } inner; // expected-note {{member is declared here}} Modified: cfe/trunk/test/SemaCXX/member-init.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/member-init.cpp?rev=287713&r1=287712&r2=287713&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/member-init.cpp (original) +++ cfe/trunk/test/SemaCXX/member-init.cpp Tue Nov 22 16:55:12 2016 @@ -13,8 +13,8 @@ public: bool b(); int k; -struct Recurse { - int &n = // expected-error {{cannot use defaulted default constructor of 'Recurse' within the class outside of member functions because 'n' has an initializer}} +struct Recurse { // expected-error {{initializer for 'n' needed}} + int &n = // expected-note {{declared here}} b() ? Recurse().n : // expected-note {{implicit default constructor for 'Recurse' first required here}} k; @@ -128,8 +128,8 @@ A::A() {} namespace template_default_ctor { struct A { template <typename T> - struct B { - int m1 = 0; // expected-error {{cannot use defaulted default constructor of 'B' within 'A' outside of member functions because 'm1' has an initializer}} + struct B { // expected-error {{initializer for 'm1' needed}} + int m1 = 0; // expected-note {{declared here}} }; // expected-note@+1 {{implicit default constructor for 'template_default_ctor::A::B<int>' first required here}} enum { NOE = noexcept(B<int>()) }; @@ -138,8 +138,8 @@ struct A { namespace default_ctor { struct A { - struct B { - int m1 = 0; // expected-error {{cannot use defaulted default constructor of 'B' within 'A' outside of member functions because 'm1' has an initializer}} + struct B { // expected-error {{initializer for 'm1' needed}} + int m1 = 0; // expected-note {{declared here}} }; // expected-note@+1 {{implicit default constructor for 'default_ctor::A::B' first required here}} enum { NOE = noexcept(B()) }; @@ -150,12 +150,12 @@ namespace member_template { struct A { template <typename T> struct B { - struct C { - int m1 = 0; // expected-error {{cannot use defaulted default constructor of 'C' within 'A' outside of member functions because 'm1' has an initializer}} + struct C { // expected-error {{initializer for 'm1' needed}} + int m1 = 0; // expected-note {{declared here}} }; template <typename U> - struct D { - int m1 = 0; // expected-error {{cannot use defaulted default constructor of 'D' within 'A' outside of member functions because 'm1' has an initializer}} + struct D { // expected-error {{initializer for 'm1' needed}} + int m1 = 0; // expected-note {{declared here}} }; }; enum { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits