diff --git a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp index 6ae46e2b1262a4..9bfb7e2677533a 100644 --- a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp +++ b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp @@ -141,7 +141,10 @@ bool isStandardPointerConvertible(QualType From, QualType To) { if (RD->isCompleteDefinition() && isBaseOf(From->getPointeeType().getTypePtr(), To->getPointeeType().getTypePtr())) { - return true; + // If B is an inaccessible or ambiguous base class of D, a program + // that necessitates this conversion is ill-formed + return isUnambiguousPublicBaseClass(From->getPointeeType().getTypePtr(), + To->getPointeeType().getTypePtr()); } } @@ -375,10 +378,7 @@ bool ExceptionAnalyzer::ExceptionInfo::filterByCatch( isPointerOrPointerToMember(ExceptionCanTy->getTypePtr())) { // A standard pointer conversion not involving conversions to pointers to // private or protected or ambiguous classes ... - if (isStandardPointerConvertible(ExceptionCanTy, HandlerCanTy) && - isUnambiguousPublicBaseClass( - ExceptionCanTy->getTypePtr()->getPointeeType().getTypePtr(), - HandlerCanTy->getTypePtr()->getPointeeType().getTypePtr())) { + if (isStandardPointerConvertible(ExceptionCanTy, HandlerCanTy)) { TypesToDelete.push_back(ExceptionTy); } // A function pointer conversion ... diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index a23483e6df6d20..233fb0e01be86c 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -245,6 +245,10 @@ Changes in existing checks where source is already a ``void``` pointer, making middle ``void`` pointer casts bug-free. +- Improved :doc:`bugprone-exception-escape + ` check to correctly detect exception + handler of type ``CV void *`` as catching all ``CV`` compatible pointer types. + - Improved :doc:`bugprone-forwarding-reference-overload ` check to ignore deleted constructors which won't hide other overloads. diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape.cpp index f5e74df1621cee..26c443b1396294 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape.cpp @@ -756,3 +756,21 @@ struct test_implicit_throw { }; }} + +void pointer_exception_can_not_escape_with_const_void_handler() noexcept { + // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'pointer_exception_can_not_escape_with_const_void_handler' which should not throw exceptions + const int value = 42; + try { + throw &value; + } catch (const void *) { + } +} + +void pointer_exception_can_not_escape_with_void_handler() noexcept { + // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'pointer_exception_can_not_escape_with_void_handler' which should not throw exceptions + int value = 42; + try { + throw &value; + } catch (void *) { + } +}