congliu created this revision.
congliu added a reviewer: alexfh.
congliu added a subscriber: cfe-commits.

Fix the assertion failure for the user-defined conversion method. e.g.: 
operator bool()

http://reviews.llvm.org/D16536

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
@@ -69,6 +69,7 @@
   int decaz(const char str[]);
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::decaz' has {{.*}} 
'Mother::decay'
 
+  operator bool();
 private:
   void funk();
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::funk' has {{.*}} 
'Father::func'
Index: clang-tidy/misc/VirtualNearMissCheck.cpp
===================================================================
--- clang-tidy/misc/VirtualNearMissCheck.cpp
+++ clang-tidy/misc/VirtualNearMissCheck.cpp
@@ -169,6 +169,14 @@
   return MD->getQualifiedNameAsString() + " " + MD->getType().getAsString();
 }
 
+/// Finds out if the given method is a user-defined conversion.
+/// A user-defined conversion is of the following form:
+///   operator TypeName()
+static bool isUserDefinedConversion(const CXXMethodDecl *MD) {
+  return StringRef(MD->getNameAsString()).find(StringRef("operator ")) !=
+         StringRef::npos;
+}
+
 bool VirtualNearMissCheck::isPossibleToBeOverridden(
     const CXXMethodDecl *BaseMD) {
   std::string Id = generateMethodId(BaseMD);
@@ -178,7 +186,8 @@
 
   bool IsPossible = !BaseMD->isImplicit() && !isa<CXXConstructorDecl>(BaseMD) 
&&
                     !isa<CXXDestructorDecl>(BaseMD) && BaseMD->isVirtual() &&
-                    !BaseMD->isOverloadedOperator();
+                    !BaseMD->isOverloadedOperator() &&
+                    !isUserDefinedConversion(BaseMD);
   PossibleMap[Id] = IsPossible;
   return IsPossible;
 }
@@ -226,6 +235,9 @@
   if (DerivedMD->isOverloadedOperator())
     return;
 
+  if (isUserDefinedConversion(DerivedMD))
+    return;
+
   const ASTContext *Context = Result.Context;
 
   const auto *DerivedRD = DerivedMD->getParent();


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
@@ -69,6 +69,7 @@
   int decaz(const char str[]);
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::decaz' has {{.*}} 'Mother::decay'
 
+  operator bool();
 private:
   void funk();
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::funk' has {{.*}} 'Father::func'
Index: clang-tidy/misc/VirtualNearMissCheck.cpp
===================================================================
--- clang-tidy/misc/VirtualNearMissCheck.cpp
+++ clang-tidy/misc/VirtualNearMissCheck.cpp
@@ -169,6 +169,14 @@
   return MD->getQualifiedNameAsString() + " " + MD->getType().getAsString();
 }
 
+/// Finds out if the given method is a user-defined conversion.
+/// A user-defined conversion is of the following form:
+///   operator TypeName()
+static bool isUserDefinedConversion(const CXXMethodDecl *MD) {
+  return StringRef(MD->getNameAsString()).find(StringRef("operator ")) !=
+         StringRef::npos;
+}
+
 bool VirtualNearMissCheck::isPossibleToBeOverridden(
     const CXXMethodDecl *BaseMD) {
   std::string Id = generateMethodId(BaseMD);
@@ -178,7 +186,8 @@
 
   bool IsPossible = !BaseMD->isImplicit() && !isa<CXXConstructorDecl>(BaseMD) &&
                     !isa<CXXDestructorDecl>(BaseMD) && BaseMD->isVirtual() &&
-                    !BaseMD->isOverloadedOperator();
+                    !BaseMD->isOverloadedOperator() &&
+                    !isUserDefinedConversion(BaseMD);
   PossibleMap[Id] = IsPossible;
   return IsPossible;
 }
@@ -226,6 +235,9 @@
   if (DerivedMD->isOverloadedOperator())
     return;
 
+  if (isUserDefinedConversion(DerivedMD))
+    return;
+
   const ASTContext *Context = Result.Context;
 
   const auto *DerivedRD = DerivedMD->getParent();
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to