[clang-tools-extra] r255758 - [clang-tidy] Fix a crash in misc-new-delete-overloads

Alexander Kornienko via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 16 02:58:14 PST 2015


Author: alexfh
Date: Wed Dec 16 04:58:14 2015
New Revision: 255758

URL: http://llvm.org/viewvc/llvm-project?rev=255758&view=rev
Log:
[clang-tidy] Fix a crash in misc-new-delete-overloads

Modified:
    clang-tools-extra/trunk/clang-tidy/misc/NewDeleteOverloadsCheck.cpp
    clang-tools-extra/trunk/test/clang-tidy/misc-new-delete-overloads.cpp

Modified: clang-tools-extra/trunk/clang-tidy/misc/NewDeleteOverloadsCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/NewDeleteOverloadsCheck.cpp?rev=255758&r1=255757&r2=255758&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/NewDeleteOverloadsCheck.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/misc/NewDeleteOverloadsCheck.cpp Wed Dec 16 04:58:14 2015
@@ -98,32 +98,30 @@ bool areCorrespondingOverloads(const Fun
   return RHS->getOverloadedOperator() == getCorrespondingOverload(LHS);
 }
 
-bool hasCorrespondingOverloadInOneClass(const CXXRecordDecl *RD,
-                                        const CXXMethodDecl *MD) {
-  // Check the methods in the given class and accessible to derived classes.
-  for (const auto *BMD : RD->methods())
-    if (BMD->isOverloadedOperator() && BMD->getAccess() != AS_private &&
-        areCorrespondingOverloads(MD, BMD))
-      return true;
-
-  // Check base classes.
-  for (const auto &BS : RD->bases())
-    if (hasCorrespondingOverloadInOneClass(BS.getType()->getAsCXXRecordDecl(),
-                                           MD))
-      return true;
+bool hasCorrespondingOverloadInBaseClass(const CXXMethodDecl *MD,
+                                         const CXXRecordDecl *RD = nullptr) {
+  if (RD) {
+    // Check the methods in the given class and accessible to derived classes.
+    for (const auto *BMD : RD->methods())
+      if (BMD->isOverloadedOperator() && BMD->getAccess() != AS_private &&
+          areCorrespondingOverloads(MD, BMD))
+        return true;
+  } else {
+    // Get the parent class of the method; we do not need to care about checking
+    // the methods in this class as the caller has already done that by looking
+    // at the declaration contexts.
+    RD = MD->getParent();
+  }
 
-  return false;
-}
-bool hasCorrespondingOverloadInBaseClass(const CXXMethodDecl *MD) {
-  // Get the parent class of the method; we do not need to care about checking
-  // the methods in this class as the caller has already done that by looking
-  // at the declaration contexts.
-  const CXXRecordDecl *RD = MD->getParent();
-
-  for (const auto &BS : RD->bases())
-    if (hasCorrespondingOverloadInOneClass(BS.getType()->getAsCXXRecordDecl(),
-                                           MD))
+  for (const auto &BS : RD->bases()) {
+    // We can't say much about a dependent base class, but to avoid false
+    // positives assume it can have a corresponding overload.
+    if (BS.getType()->isDependentType())
       return true;
+    if (const auto *BaseRD = BS.getType()->getAsCXXRecordDecl())
+      if (hasCorrespondingOverloadInBaseClass(MD, BaseRD))
+        return true;
+  }
 
   return false;
 }
@@ -174,24 +172,23 @@ void NewDeleteOverloadsCheck::onEndOfTra
     // to shard the overloads by declaration context to reduce the algorithmic
     // complexity when searching for corresponding free store functions.
     for (const auto *Overload : RP.second) {
-      const auto *Match = std::find_if(
-          RP.second.begin(), RP.second.end(), [&](const FunctionDecl *FD) {
-            if (FD == Overload)
-              return false;
-            // If the declaration contexts don't match, we don't
-            // need to check
-            // any further.
-            if (FD->getDeclContext() != Overload->getDeclContext())
-              return false;
-
-            // Since the declaration contexts match, see whether
-            // the current
-            // element is the corresponding operator.
-            if (!areCorrespondingOverloads(Overload, FD))
-              return false;
+      const auto *Match =
+          std::find_if(RP.second.begin(), RP.second.end(),
+                       [&Overload](const FunctionDecl *FD) {
+                         if (FD == Overload)
+                           return false;
+                         // If the declaration contexts don't match, we don't
+                         // need to check any further.
+                         if (FD->getDeclContext() != Overload->getDeclContext())
+                           return false;
+
+                         // Since the declaration contexts match, see whether
+                         // the current element is the corresponding operator.
+                         if (!areCorrespondingOverloads(Overload, FD))
+                           return false;
 
-            return true;
-          });
+                         return true;
+                       });
 
       if (Match == RP.second.end()) {
         // Check to see if there is a corresponding overload in a base class

Modified: clang-tools-extra/trunk/test/clang-tidy/misc-new-delete-overloads.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/misc-new-delete-overloads.cpp?rev=255758&r1=255757&r2=255758&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/misc-new-delete-overloads.cpp (original)
+++ clang-tools-extra/trunk/test/clang-tidy/misc-new-delete-overloads.cpp Wed Dec 16 04:58:14 2015
@@ -75,3 +75,7 @@ struct H : G {
   // CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope
   void *operator new(size_t) noexcept; // base class operator is inaccessible
 };
+
+template <typename Base> struct Derived : Base {
+  void operator delete(void *);
+};




More information about the cfe-commits mailing list