Author: Zeyi Xu Date: 2026-04-11T12:39:24+08:00 New Revision: f6167ec430d9323652e8914602085ae1d4ee780c
URL: https://github.com/llvm/llvm-project/commit/f6167ec430d9323652e8914602085ae1d4ee780c DIFF: https://github.com/llvm/llvm-project/commit/f6167ec430d9323652e8914602085ae1d4ee780c.diff LOG: [clang-tidy] Fix FP in bugprone-exception-escape with unevaluated exception specs (#190593) Functions whose exception spec has not yet been evaluated have no body in the AST. Because the compiler does not generate call sites for these functions before evaluating their spec, they cannot propagate exceptions. Closes https://github.com/llvm/llvm-project/issues/188730 Added: Modified: clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-treat-functions-without-specification-as-throwing.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp index 9165be3c850d7..8f0d6b1360cd5 100644 --- a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp +++ b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp @@ -330,6 +330,12 @@ static bool canThrow(const FunctionDecl *Func) { if (!FunProto) return true; + // Clang evaluates unresolved exception specs before generating any call to + // the function, so these functions cannot appear at a call site and cannot + // throw. + if (isUnresolvedExceptionSpec(FunProto->getExceptionSpecType())) + return false; + switch (FunProto->canThrow()) { case CT_Cannot: return false; @@ -499,6 +505,9 @@ ExceptionAnalyzer::ExceptionInfo ExceptionAnalyzer::throwsException( auto Result = ExceptionInfo::createUnknown(); if (const auto *FPT = Func->getType()->getAs<FunctionProtoType>()) { + if (isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) + return ExceptionInfo::createNonThrowing(); + for (const QualType &Ex : FPT->exceptions()) { CallStack.insert({Func, CallLoc}); Result.registerException( diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-treat-functions-without-specification-as-throwing.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-treat-functions-without-specification-as-throwing.cpp index 6f955fa5a012a..9ff54acff6729 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-treat-functions-without-specification-as-throwing.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-escape-treat-functions-without-specification-as-throwing.cpp @@ -68,22 +68,18 @@ struct Member { }; struct S { - // CHECK-MESSAGES-ALL: :[[@LINE-1]]:8: warning: an exception may be thrown in function 'S' which should not throw exceptions - // CHECK-MESSAGES-ALL: :[[@LINE-2]]:8: note: frame #0: an exception of unknown type may be thrown in function 'S' here - // CHECK-MESSAGES-ALL: :[[@LINE-3]]:8: warning: an exception may be thrown in function 'operator=' which should not throw exceptions - // CHECK-MESSAGES-ALL: :[[@LINE-4]]:8: note: frame #0: an exception of unknown type may be thrown in function 'operator=' here - // CHECK-MESSAGES-ALL: :[[@LINE-5]]:8: warning: an exception may be thrown in function '~S' which should not throw exceptions - // CHECK-MESSAGES-ALL: :[[@LINE-6]]:8: note: frame #0: an exception of unknown type may be thrown in function '~S' here - // CHECK-MESSAGES-UNDEFINED: :[[@LINE-7]]:8: warning: an exception may be thrown in function 'S' which should not throw exceptions - // CHECK-MESSAGES-UNDEFINED: :[[@LINE-8]]:8: note: frame #0: an exception of unknown type may be thrown in function 'S' here - // CHECK-MESSAGES-UNDEFINED: :[[@LINE-9]]:8: warning: an exception may be thrown in function 'operator=' which should not throw exceptions - // CHECK-MESSAGES-UNDEFINED: :[[@LINE-10]]:8: note: frame #0: an exception of unknown type may be thrown in function 'operator=' here - // CHECK-MESSAGES-UNDEFINED: :[[@LINE-11]]:8: warning: an exception may be thrown in function '~S' which should not throw exceptions - // CHECK-MESSAGES-UNDEFINED: :[[@LINE-12]]:8: note: frame #0: an exception of unknown type may be thrown in function '~S' here - // FIXME: clearly non-throwing functions should not be marked as throwing Member m; }; +template <typename T> +struct TmplNoexcept { + void method() noexcept(noexcept(T())) {} +}; + +void instantiate_tmpl_noexcept() { + TmplNoexcept<int> t; +} + void explicit_throw() { throw 1; } void calls_explicit_throw() noexcept { // CHECK-MESSAGES-ALL: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'calls_explicit_throw' which should not throw exceptions _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
