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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits