Author: rsmith Date: Mon Oct 31 13:18:29 2016 New Revision: 285610 URL: http://llvm.org/viewvc/llvm-project?rev=285610&view=rev Log: When diagnosing that a defaulted function is ill-formed because it would be implicitly deleted and overrides a non-deleted function, explain why the function is deleted. For PR30844.
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp cfe/trunk/test/CXX/class.derived/class.abstract/p16.cpp cfe/trunk/test/CXX/special/class.dtor/p5-0x.cpp cfe/trunk/test/CXX/special/class.dtor/p9.cpp Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=285610&r1=285609&r2=285610&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Oct 31 13:18:29 2016 @@ -13850,7 +13850,7 @@ void Sema::SetDeclDeleted(Decl *Dcl, Sou // See if we're deleting a function which is already known to override a // non-deleted virtual function. - if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Fn)) { + if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Fn)) { bool IssuedDiagnostic = false; for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(), E = MD->end_overridden_methods(); @@ -13863,6 +13863,11 @@ void Sema::SetDeclDeleted(Decl *Dcl, Sou Diag((*I)->getLocation(), diag::note_overridden_virtual_function); } } + // If this function was implicitly deleted because it was defaulted, + // explain why it was deleted. + if (IssuedDiagnostic && MD->isDefaulted()) + ShouldDeleteSpecialMember(MD, getSpecialMember(MD), nullptr, + /*Diagnose*/true); } // C++11 [basic.start.main]p3: Modified: cfe/trunk/test/CXX/class.derived/class.abstract/p16.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class.derived/class.abstract/p16.cpp?rev=285610&r1=285609&r2=285610&view=diff ============================================================================== --- cfe/trunk/test/CXX/class.derived/class.abstract/p16.cpp (original) +++ cfe/trunk/test/CXX/class.derived/class.abstract/p16.cpp Mon Oct 31 13:18:29 2016 @@ -31,12 +31,20 @@ private: D &operator=(D&&) = default; virtual ~D(); // expected-note 2{{here}} }; -struct E : D {}; // expected-error {{deleted function '~E' cannot override a non-deleted function}} \ - // expected-error {{deleted function 'operator=' cannot override a non-deleted function}} +struct E : D {}; +// expected-error@-1 {{deleted function '~E' cannot override a non-deleted function}} +// expected-note@-2 {{destructor of 'E' is implicitly deleted because base class 'D' has an inaccessible destructor}} +// expected-error@-3 {{deleted function 'operator=' cannot override a non-deleted function}} +// expected-note@-4 {{copy assignment operator of 'E' is implicitly deleted because base class 'D' has an inaccessible copy assignment operator}} struct F : D {}; -struct G : D {}; // expected-error {{deleted function '~G' cannot override a non-deleted function}} - // expected-error@-1 {{deleted function 'operator=' cannot override a non-deleted function}} +struct G : D {}; +// expected-error@-1 {{deleted function '~G' cannot override a non-deleted function}} +// expected-note@-2 {{move assignment operator of 'G' is implicitly deleted because base class 'D' has an inaccessible move assignment operator}} +// expected-error@-3 {{deleted function 'operator=' cannot override a non-deleted function}} +// expected-note@-4 {{destructor of 'G' is implicitly deleted because base class 'D' has an inaccessible destructor}} struct H : D { - H &operator=(H&&) = default; // expected-error {{deleted function 'operator=' cannot override a non-deleted function}} + H &operator=(H&&) = default; + // expected-error@-1 {{deleted function 'operator=' cannot override a non-deleted function}} + // expected-note@-3 {{move assignment operator of 'H' is implicitly deleted because base class 'D' has an inaccessible move assignment operator}} ~H(); }; Modified: cfe/trunk/test/CXX/special/class.dtor/p5-0x.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/special/class.dtor/p5-0x.cpp?rev=285610&r1=285609&r2=285610&view=diff ============================================================================== --- cfe/trunk/test/CXX/special/class.dtor/p5-0x.cpp (original) +++ cfe/trunk/test/CXX/special/class.dtor/p5-0x.cpp Mon Oct 31 13:18:29 2016 @@ -90,7 +90,7 @@ class D1 { public: virtual ~D1() = default; // expected-note {{here}} } d1; // ok -struct D2 : D1 { // expected-note {{virtual destructor requires an unambiguous, accessible 'operator delete'}} \ +struct D2 : D1 { // expected-note 2{{virtual destructor requires an unambiguous, accessible 'operator delete'}} \ // expected-error {{deleted function '~D2' cannot override a non-deleted}} // implicitly-virtual destructor } d2; // expected-error {{deleted function}} Modified: cfe/trunk/test/CXX/special/class.dtor/p9.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/special/class.dtor/p9.cpp?rev=285610&r1=285609&r2=285610&view=diff ============================================================================== --- cfe/trunk/test/CXX/special/class.dtor/p9.cpp (original) +++ cfe/trunk/test/CXX/special/class.dtor/p9.cpp Mon Oct 31 13:18:29 2016 @@ -88,7 +88,7 @@ namespace test2 { } #else struct CBase { virtual ~CBase(); }; // expected-note {{overridden virtual function is here}} - struct C : CBase { // expected-error {{deleted function '~C' cannot override a non-deleted function}} expected-note {{requires an unambiguous, accessible 'operator delete'}} + struct C : CBase { // expected-error {{deleted function '~C' cannot override a non-deleted function}} expected-note 2{{requires an unambiguous, accessible 'operator delete'}} static void operator delete(void*, const int &); }; void test() { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits