llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-tools-extra Author: Hana Dusíková (hanickadot) <details> <summary>Changes</summary> As in title, code which check eligibility of exceptions with pointer types to be handled by exception handler of type `void *` disallowed this case. It was check: ```c++ if (isStandardPointerConvertible(ExceptionCanTy, HandlerCanTy) && isUnambiguousPublicBaseClass( ExceptionCanTy->getTypePtr()->getPointeeType().getTypePtr(), HandlerCanTy->getTypePtr()->getPointeeType().getTypePtr())) { ``` but in `isUnambiguousPublicBaseClass` there was code which looked for definitions: ```c++ bool isUnambiguousPublicBaseClass(const Type *DerivedType, const Type *BaseType) { const auto *DerivedClass = DerivedType->getCanonicalTypeUnqualified()->getAsCXXRecordDecl(); const auto *BaseClass = BaseType->getCanonicalTypeUnqualified()->getAsCXXRecordDecl(); if (!DerivedClass || !BaseClass) return false; ``` This code disallowed usage of `void *` type which was correctly detected in `isStandardPointerConvertible`. AFAIK this seems like misinterpretation of specification: > 14.4 Handling an exception > a standard [pointer conversion](https://eel.is/c++draft/conv.ptr) not involving conversions to pointers to private or protected or ambiguous classes (https://eel.is/c++draft/except.handle#<!-- -->3.3.1) and > 7.3.12 Pointer conversions > ... If B is an inaccessible ([[class.access]](https://eel.is/c++draft/class.access)) or ambiguous ([[class.member.lookup]](https://eel.is/c++draft/class.member.lookup)) base class of D, a program that necessitates this conversion is ill-formed[.](https://eel.is/c++draft/conv.ptr#<!-- -->3.sentence-2) ... (https://eel.is/c++draft/conv.ptr#<!-- -->3) 14.4 is carving out private, protected, and ambiguous base classes, but they are already carved out in 7.3.12 and implemented in `isStandardPointerConvertible` --- Full diff: https://github.com/llvm/llvm-project/pull/99773.diff 3 Files Affected: - (modified) clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp (+5-5) - (modified) clang-tools-extra/docs/ReleaseNotes.rst (+4) - (modified) clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape.cpp (+18) ``````````diff diff --git a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp index 6ae46e2b1262a..9bfb7e2677533 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 a23483e6df6d2..8e8c0cd0cc3d8 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -518,6 +518,10 @@ Changes in existing checks usages of ``std::string_view::compare``. Added a `StringLikeClasses` option to detect usages of ``compare`` method in custom string-like classes. +- Improved :doc:`exception-escape <clang-tidy/checks/bugprone/exception-escape>` + check to correctly detect exception handler of type `CV void *` as catching all + `CV` compatible pointer types. + Removed checks ^^^^^^^^^^^^^^ 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 f5e74df1621ce..26c443b139629 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 *) { + } +} `````````` </details> https://github.com/llvm/llvm-project/pull/99773 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits