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