FYI, this breaks bootstrap builds of llvm. I'll commit a fix in few minutes. Apparently the equivalent check in gcc doesn't work on templates or something.
On Tue, Oct 16, 2012 at 5:47 PM, David Blaikie <[email protected]> wrote: > Author: dblaikie > Date: Tue Oct 16 19:47:58 2012 > New Revision: 166082 > > URL: http://llvm.org/viewvc/llvm-project?rev=166082&view=rev > Log: > Implement C++ 10.3p16 - overrides involving deleted functions must match. > > Only deleted functions may override deleted functions and non-deleted > functions > may only override non-deleted functions. > > Added: > cfe/trunk/test/CXX/class.derived/class.abstract/p16.cpp > Modified: > cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > cfe/trunk/lib/Sema/SemaDecl.cpp > > Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=166082&r1=166081&r2=166082&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Oct 16 > 19:47:58 2012 > @@ -865,6 +865,12 @@ > def err_deleted_decl_not_first : Error< > "deleted definition must be first declaration">; > > +def err_deleted_override : Error< > + "deleted function %0 cannot override a non-deleted function">; > + > +def err_non_deleted_override : Error< > + "non-deleted function %0 cannot override a deleted function">; > + > def warn_weak_vtable : Warning< > "%0 has no out-of-line virtual method definitions; its vtable will be " > "emitted in every translation unit">, > > Modified: cfe/trunk/lib/Sema/SemaDecl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=166082&r1=166081&r2=166082&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Oct 16 19:47:58 2012 > @@ -4733,6 +4733,31 @@ > return false; > } > > +namespace { > + enum OverrideErrorKind { OEK_All, OEK_NonDeleted, OEK_Deleted }; > +} > +/// \brief Report an error regarding overriding, along with any relevant > +/// overriden methods. > +/// > +/// \param DiagID the primary error to report. > +/// \param MD the overriding method. > +/// \param OEK which overrides to include as notes. > +static void ReportOverrides(Sema& S, unsigned DiagID, const CXXMethodDecl > *MD, > + OverrideErrorKind OEK = OEK_All) { > + S.Diag(MD->getLocation(), DiagID) << MD->getDeclName(); > + for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(), > + E = MD->end_overridden_methods(); > + I != E; ++I) { > + // This check (& the OEK parameter) could be replaced by a predicate, > but > + // without lambdas that would be overkill. This is still nicer than > writing > + // out the diag loop 3 times. > + if ((OEK == OEK_All) || > + (OEK == OEK_NonDeleted && !(*I)->isDeleted()) || > + (OEK == OEK_Deleted && (*I)->isDeleted())) > + S.Diag((*I)->getLocation(), diag::note_overridden_virtual_function); > + } > +} > + > /// AddOverriddenMethods - See if a method overrides any in the base > classes, > /// and if so, check that it's a valid override and remember it. > bool Sema::AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD) { > @@ -4741,6 +4766,8 @@ > FindOverriddenMethodData Data; > Data.Method = MD; > Data.S = this; > + bool hasDeletedOverridenMethods = false; > + bool hasNonDeletedOverridenMethods = false; > bool AddedAny = false; > if (DC->lookupInBases(&FindOverriddenMethod, &Data, Paths)) { > for (CXXBasePaths::decl_iterator I = Paths.found_decls_begin(), > @@ -4750,12 +4777,21 @@ > if (!CheckOverridingFunctionReturnType(MD, OldMD) && > !CheckOverridingFunctionExceptionSpec(MD, OldMD) && > !CheckIfOverriddenFunctionIsMarkedFinal(MD, OldMD)) { > + hasDeletedOverridenMethods |= OldMD->isDeleted(); > + hasNonDeletedOverridenMethods |= !OldMD->isDeleted(); > AddedAny = true; > } > } > } > } > - > + > + if (hasDeletedOverridenMethods && !MD->isDeleted()) { > + ReportOverrides(*this, diag::err_non_deleted_override, MD, > OEK_Deleted); > + } > + if (hasNonDeletedOverridenMethods && MD->isDeleted()) { > + ReportOverrides(*this, diag::err_deleted_override, MD, > OEK_NonDeleted); > + } > + > return AddedAny; > } > > @@ -6068,16 +6104,7 @@ > if (AddOverriddenMethods(Method->getParent(), Method)) { > // If the function was marked as "static", we have a problem. > if (NewFD->getStorageClass() == SC_Static) { > - Diag(NewFD->getLocation(), diag::err_static_overrides_virtual) > - << NewFD->getDeclName(); > - for (CXXMethodDecl::method_iterator > - Overridden = Method->begin_overridden_methods(), > - OverriddenEnd = Method->end_overridden_methods(); > - Overridden != OverriddenEnd; > - ++Overridden) { > - Diag((*Overridden)->getLocation(), > - diag::note_overridden_virtual_function); > - } > + ReportOverrides(*this, diag::err_static_overrides_virtual, > Method); > } > } > } > > Added: 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=166082&view=auto > > ============================================================================== > --- cfe/trunk/test/CXX/class.derived/class.abstract/p16.cpp (added) > +++ cfe/trunk/test/CXX/class.derived/class.abstract/p16.cpp Tue Oct 16 > 19:47:58 2012 > @@ -0,0 +1,16 @@ > +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s > + > +struct A { > + virtual void a(); // expected-note{{overridden virtual function is > here}} > + virtual void b() = delete; // expected-note{{overridden virtual > function is here}} > +}; > + > +struct B: A { > + virtual void a() = delete; // expected-error{{deleted function 'a' > cannot override a non-deleted function}} > + virtual void b(); // expected-error{{non-deleted function 'b' cannot > override a deleted function}} > +}; > + > +struct C: A { > + virtual void a(); > + virtual void b() = delete; > +}; > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits > -- ~Craig
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
