PiotrZSL updated this revision to Diff 551776.
PiotrZSL marked an inline comment as done.
PiotrZSL added a comment.

Add throw_basefn_catch_const_basefn test


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148461/new/

https://reviews.llvm.org/D148461

Files:
  clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-throw.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape.cpp
@@ -1,10 +1,9 @@
-// RUN: %check_clang_tidy -std=c++11,c++14 %s bugprone-exception-escape %t -- \
+// RUN: %check_clang_tidy -std=c++11-or-later %s bugprone-exception-escape %t -- \
 // RUN:     -config="{CheckOptions: { \
 // RUN:         bugprone-exception-escape.IgnoredExceptions: 'ignored1,ignored2', \
 // RUN:         bugprone-exception-escape.FunctionsThatShouldNotThrow: 'enabled1,enabled2,enabled3' \
 // RUN:     }}" \
 // RUN:     -- -fexceptions
-// FIXME: Fix the checker to work in C++17 or later mode.
 
 struct throwing_destructor {
   ~throwing_destructor() {
@@ -420,6 +419,7 @@
 struct baseMember {
     int *iptr;
     virtual void foo(){};
+    void boo(){};
 };
 
 struct derivedMember : baseMember {
@@ -441,6 +441,29 @@
   }
 }
 
+void throw_basefn_catch_const_basefn() noexcept {
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_basefn_catch_const_basefn' which should not throw exceptions
+  try {
+    throw &baseMember::foo;
+  } catch(const void(baseMember::*)()) {
+  }
+}
+
+void throw_derivedfn_catch_basefn() noexcept {
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_derivedfn_catch_basefn' which should not throw exceptions
+  try {
+    throw &derivedMember::foo;
+  } catch(void(baseMember::*)()) {
+  }
+}
+
+void throw_basefn_via_derivedfn_catch_basefn() noexcept {
+  try {
+    throw &derivedMember::boo;
+  } catch(void(baseMember::*)()) {
+  }
+}
+
 void throw_basem_catch_basem_throw() noexcept {
   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_basem_catch_basem_throw' which should not throw exceptions
   try {
@@ -721,28 +744,3 @@
   test_basic_no_throw();
   test_basic_throw();
 }
-
-namespace PR55143 { namespace PR40583 {
-
-struct test_explicit_throw {
-    test_explicit_throw() throw(int) { throw 42; }
-    test_explicit_throw(const test_explicit_throw&) throw(int) { throw 42; }
-    test_explicit_throw(test_explicit_throw&&) throw(int) { throw 42; }
-    test_explicit_throw& operator=(const test_explicit_throw&) throw(int) { throw 42; }
-    test_explicit_throw& operator=(test_explicit_throw&&) throw(int) { throw 42; }
-    ~test_explicit_throw() throw(int) { throw 42; }
-};
-
-struct test_implicit_throw {
-    test_implicit_throw() { throw 42; }
-    test_implicit_throw(const test_implicit_throw&) { throw 42; }
-    test_implicit_throw(test_implicit_throw&&) { throw 42; }
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'test_implicit_throw' which should not throw exceptions
-    test_implicit_throw& operator=(const test_implicit_throw&) { throw 42; }
-    test_implicit_throw& operator=(test_implicit_throw&&) { throw 42; }
-    // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: an exception may be thrown in function 'operator=' which should not throw exceptions
-    ~test_implicit_throw() { throw 42; }
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function '~test_implicit_throw' which should not throw exceptions
-};
-
-}}
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-throw.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-throw.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-throw.cpp
@@ -29,3 +29,28 @@
   sub_throws() throw() : super_throws() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: an exception may be thrown in function 'sub_throws' which should not throw exceptions
 };
+
+namespace PR55143 { namespace PR40583 {
+
+struct test_explicit_throw {
+    test_explicit_throw() throw(int) { throw 42; }
+    test_explicit_throw(const test_explicit_throw&) throw(int) { throw 42; }
+    test_explicit_throw(test_explicit_throw&&) throw(int) { throw 42; }
+    test_explicit_throw& operator=(const test_explicit_throw&) throw(int) { throw 42; }
+    test_explicit_throw& operator=(test_explicit_throw&&) throw(int) { throw 42; }
+    ~test_explicit_throw() throw(int) { throw 42; }
+};
+
+struct test_implicit_throw {
+    test_implicit_throw() { throw 42; }
+    test_implicit_throw(const test_implicit_throw&) { throw 42; }
+    test_implicit_throw(test_implicit_throw&&) { throw 42; }
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'test_implicit_throw' which should not throw exceptions
+    test_implicit_throw& operator=(const test_implicit_throw&) { throw 42; }
+    test_implicit_throw& operator=(test_implicit_throw&&) { throw 42; }
+    // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: an exception may be thrown in function 'operator=' which should not throw exceptions
+    ~test_implicit_throw() { throw 42; }
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function '~test_implicit_throw' which should not throw exceptions
+};
+
+}}
Index: clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
===================================================================
--- clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
+++ clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "ExceptionAnalyzer.h"
+#include <clang/AST/ODRHash.h>
 
 namespace clang::tidy::utils {
 
@@ -149,37 +150,27 @@
 }
 
 bool isFunctionPointerConvertible(QualType From, QualType To) {
-  if (!From->isFunctionPointerType() && !From->isFunctionType() &&
-      !From->isMemberFunctionPointerType())
-    return false;
-
-  if (!To->isFunctionPointerType() && !To->isMemberFunctionPointerType())
+  ODRHash FromHash, ToHash;
+
+  if (From->isFunctionPointerType())
+    FromHash.AddType(From->getPointeeType().getTypePtr());
+  else if (From->isFunctionType())
+    FromHash.AddType(From->castAs<FunctionType>());
+  else if (From->isMemberFunctionPointerType())
+    FromHash.AddType(From->castAs<MemberPointerType>());
+  else
     return false;
 
-  if (To->isFunctionPointerType()) {
-    if (From->isFunctionPointerType())
-      return To->getPointeeType() == From->getPointeeType();
-
-    if (From->isFunctionType())
-      return To->getPointeeType() == From;
-
+  if (To->isFunctionPointerType())
+    ToHash.AddType(To->getPointeeType().getTypePtr());
+  else if (From->isFunctionType())
+    ToHash.AddType(To->castAs<FunctionType>());
+  else if (From->isMemberFunctionPointerType())
+    ToHash.AddType(To->castAs<MemberPointerType>());
+  else
     return false;
-  }
-
-  if (To->isMemberFunctionPointerType()) {
-    if (!From->isMemberFunctionPointerType())
-      return false;
-
-    const auto *FromMember = cast<MemberPointerType>(From);
-    const auto *ToMember = cast<MemberPointerType>(To);
 
-    // Note: converting Derived::* to Base::* is a different kind of conversion,
-    // called Pointer-to-member conversion.
-    return FromMember->getClass() == ToMember->getClass() &&
-           FromMember->getPointeeType() == ToMember->getPointeeType();
-  }
-
-  return false;
+  return FromHash.CalculateHash() == ToHash.CalculateHash();
 }
 
 // Checks if From is qualification convertible to To based on the current
@@ -278,16 +269,17 @@
       return false;
 
     if (!isSameP_i(From, To)) {
-      if (LangOpts.CPlusPlus20) {
-        if (From->isConstantArrayType() && !To->isIncompleteArrayType())
-          return false;
+      if (!LangOpts.CPlusPlus20)
+        return false;
 
-        if (From->isIncompleteArrayType() && !To->isIncompleteArrayType())
-          return false;
+      if (From->isConstantArrayType() && !To->isIncompleteArrayType())
+        return false;
 
-      } else {
+      if (From->isIncompleteArrayType() && !To->isIncompleteArrayType())
+        return false;
+
+      if (From->isMemberPointerType() || To->isMemberPointerType())
         return false;
-      }
     }
 
     ++I;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to