[cfe-commits] r166254 - in /cfe/trunk: lib/Sema/SemaDeclCXX.cpp test/SemaCXX/warn-overloaded-virtual.cpp

David Blaikie dblaikie at gmail.com
Thu Oct 18 17:53:08 PDT 2012


Author: dblaikie
Date: Thu Oct 18 19:53:08 2012
New Revision: 166254

URL: http://llvm.org/viewvc/llvm-project?rev=166254&view=rev
Log:
Handle diamond inheritance in -Woverloaded-virtual.

Modified:
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/SemaCXX/warn-overloaded-virtual.cpp

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=166254&r1=166253&r2=166254&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Oct 18 19:53:08 2012
@@ -4739,6 +4739,19 @@
   };
 }
 
+/// \brief Check whether any most overriden method from MD in Methods
+static bool CheckMostOverridenMethods(const CXXMethodDecl *MD,
+                   const llvm::SmallPtrSet<const CXXMethodDecl *, 8>& Methods) {
+  if (MD->size_overridden_methods() == 0)
+    return Methods.count(MD->getCanonicalDecl());
+  for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(),
+                                      E = MD->end_overridden_methods();
+       I != E; ++I)
+    if (CheckMostOverridenMethods(*I, Methods))
+      return true;
+  return false;
+}
+
 /// \brief Member lookup function that determines whether a given C++
 /// method overloads virtual methods in a base class without overriding any,
 /// to be used with CXXRecordDecl::lookupInBases().
@@ -4770,12 +4783,7 @@
       if (!Data.S->IsOverload(Data.Method, MD, false))
         return true;
       // Collect the overload only if its hidden.
-      bool Using = Data.OverridenAndUsingBaseMethods.count(MD);
-      for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(),
-                                          E = MD->end_overridden_methods();
-           I != E && !Using; ++I)
-        Using = Data.OverridenAndUsingBaseMethods.count(*I);
-      if (!Using)
+      if (!CheckMostOverridenMethods(MD, Data.OverridenAndUsingBaseMethods))
         overloadedMethods.push_back(MD);
     }
   }
@@ -4786,6 +4794,17 @@
   return foundSameNameMethod;
 }
 
+/// \brief Add the most overriden methods from MD to Methods
+static void AddMostOverridenMethods(const CXXMethodDecl *MD,
+                         llvm::SmallPtrSet<const CXXMethodDecl *, 8>& Methods) {
+  if (MD->size_overridden_methods() == 0)
+    Methods.insert(MD->getCanonicalDecl());
+  for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(),
+                                      E = MD->end_overridden_methods();
+       I != E; ++I)
+    AddMostOverridenMethods(*I, Methods);
+}
+
 /// \brief See if a method overloads virtual methods in a base class without
 /// overriding any.
 void Sema::DiagnoseHiddenVirtualMethods(CXXRecordDecl *DC, CXXMethodDecl *MD) {
@@ -4806,14 +4825,11 @@
   // by 'using' in a set. A base method not in this set is hidden.
   for (DeclContext::lookup_result res = DC->lookup(MD->getDeclName());
        res.first != res.second; ++res.first) {
-    if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(*res.first))
-      for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(),
-                                          E = MD->end_overridden_methods();
-           I != E; ++I)
-        Data.OverridenAndUsingBaseMethods.insert((*I)->getCanonicalDecl());
+    NamedDecl *ND = *res.first;
     if (UsingShadowDecl *shad = dyn_cast<UsingShadowDecl>(*res.first))
-      if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(shad->getTargetDecl()))
-        Data.OverridenAndUsingBaseMethods.insert(MD->getCanonicalDecl());
+      ND = shad->getTargetDecl();
+    if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(ND))
+      AddMostOverridenMethods(MD, Data.OverridenAndUsingBaseMethods);
   }
 
   if (DC->lookupInBases(&FindHiddenVirtualMethod, &Data, Paths) &&

Modified: cfe/trunk/test/SemaCXX/warn-overloaded-virtual.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-overloaded-virtual.cpp?rev=166254&r1=166253&r2=166254&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-overloaded-virtual.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-overloaded-virtual.cpp Thu Oct 18 19:53:08 2012
@@ -80,3 +80,43 @@
   using A::f;
 };
 }
+
+namespace UnbalancedVirtual {
+struct Base {
+  virtual void func();
+};
+
+struct Derived1: virtual Base {
+  virtual void func();
+};
+
+struct Derived2: virtual Base {
+};
+
+struct MostDerived: Derived1, Derived2 {
+  void func(int);
+  void func();
+};
+}
+
+namespace UnbalancedVirtual2 {
+struct Base {
+  virtual void func();
+};
+
+struct Derived1: virtual Base {
+  virtual void func();
+};
+
+struct Derived2: virtual Base {
+};
+
+struct Derived3: Derived1 {
+  virtual void func();
+};
+
+struct MostDerived: Derived3, Derived2 {
+  void func(int);
+  void func();
+};
+}





More information about the cfe-commits mailing list