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>