aaron.ballman created this revision.
aaron.ballman added reviewers: congliu, alexfh.
aaron.ballman added a subscriber: cfe-commits.

Special member functions don't always have names, and so calling 
FunctionDecl::getName() can cause assertions. This patch addresses the issue by 
assuming any such function needs to have the rest of its signature checked, 
regardless of the function name. The test case was pulled from MSVC's STL 
headers, where this check is causing failed assertions.

http://reviews.llvm.org/D16377

Files:
  clang-tidy/misc/VirtualNearMissCheck.cpp
  test/clang-tidy/misc-virtual-near-miss.cpp

Index: test/clang-tidy/misc-virtual-near-miss.cpp
===================================================================
--- test/clang-tidy/misc-virtual-near-miss.cpp
+++ test/clang-tidy/misc-virtual-near-miss.cpp
@@ -63,3 +63,20 @@
 private:
   void funk(); // Should not warn: access qualifers don't match.
 };
+
+namespace {
+// Ensure this code does not crash due to special member functions.
+class  _Facet_base {
+public:
+  virtual ~_Facet_base() noexcept {}
+};
+
+class facet : public _Facet_base {
+protected:
+  virtual ~facet() noexcept {}
+
+public:
+  facet(const facet&) = delete;
+  facet& operator=(const facet&) = delete;
+};
+}
Index: clang-tidy/misc/VirtualNearMissCheck.cpp
===================================================================
--- clang-tidy/misc/VirtualNearMissCheck.cpp
+++ clang-tidy/misc/VirtualNearMissCheck.cpp
@@ -244,8 +244,15 @@
         if (isOverriddenByDerivedClass(BaseMD, DerivedRD))
           continue;
 
+        // If the function has an identifier for a name, then use that
+        // identifier to determine the edit distance. If the function is a
+        // special member function without an identifier, assume the edit
+        // distance is nonzero to determine whether the signature is a near
+        // miss or not.
         unsigned EditDistance =
-            BaseMD->getName().edit_distance(DerivedMD->getName());
+            BaseMD->getDeclName().isIdentifier()
+                ? BaseMD->getName().edit_distance(DerivedMD->getName())
+                : 1;
         if (EditDistance > 0 && EditDistance <= EditDistanceThreshold) {
           if (checkOverrideWithoutName(Context, BaseMD, DerivedMD)) {
             // A "virtual near miss" is found.


Index: test/clang-tidy/misc-virtual-near-miss.cpp
===================================================================
--- test/clang-tidy/misc-virtual-near-miss.cpp
+++ test/clang-tidy/misc-virtual-near-miss.cpp
@@ -63,3 +63,20 @@
 private:
   void funk(); // Should not warn: access qualifers don't match.
 };
+
+namespace {
+// Ensure this code does not crash due to special member functions.
+class  _Facet_base {
+public:
+  virtual ~_Facet_base() noexcept {}
+};
+
+class facet : public _Facet_base {
+protected:
+  virtual ~facet() noexcept {}
+
+public:
+  facet(const facet&) = delete;
+  facet& operator=(const facet&) = delete;
+};
+}
Index: clang-tidy/misc/VirtualNearMissCheck.cpp
===================================================================
--- clang-tidy/misc/VirtualNearMissCheck.cpp
+++ clang-tidy/misc/VirtualNearMissCheck.cpp
@@ -244,8 +244,15 @@
         if (isOverriddenByDerivedClass(BaseMD, DerivedRD))
           continue;
 
+        // If the function has an identifier for a name, then use that
+        // identifier to determine the edit distance. If the function is a
+        // special member function without an identifier, assume the edit
+        // distance is nonzero to determine whether the signature is a near
+        // miss or not.
         unsigned EditDistance =
-            BaseMD->getName().edit_distance(DerivedMD->getName());
+            BaseMD->getDeclName().isIdentifier()
+                ? BaseMD->getName().edit_distance(DerivedMD->getName())
+                : 1;
         if (EditDistance > 0 && EditDistance <= EditDistanceThreshold) {
           if (checkOverrideWithoutName(Context, BaseMD, DerivedMD)) {
             // A "virtual near miss" is found.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to