[clang-tidy] Add recursion protection in ExceptionSpecAnalyzer (#66810)

Normally endless recursion should not happen in ExceptionSpecAnalyzer,
but if AST would be malformed (missing include), this could cause crash.

I run into this issue when due to missing include constructor argument
were parsed as FieldDecl.
As checking for recursion cost nothing, why not to do this in check just
in case.

Fixes #111436
This commit is contained in:
Piotr Zegar 2025-02-13 17:51:28 +01:00 committed by GitHub
parent 1138a4964a
commit a663e78a6e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 24 additions and 6 deletions

View File

@ -14,13 +14,14 @@ namespace clang::tidy::utils {
ExceptionSpecAnalyzer::State
ExceptionSpecAnalyzer::analyze(const FunctionDecl *FuncDecl) {
// Check if the function has already been analyzed and reuse that result.
const auto CacheEntry = FunctionCache.find(FuncDecl);
if (CacheEntry == FunctionCache.end()) {
// Check if function exist in cache or add temporary value to cache to protect
// against endless recursion.
const auto [CacheEntry, NotFound] =
FunctionCache.try_emplace(FuncDecl, State::NotThrowing);
if (NotFound) {
ExceptionSpecAnalyzer::State State = analyzeImpl(FuncDecl);
// Cache the result of the analysis.
FunctionCache.try_emplace(FuncDecl, State);
// Update result with calculated value
FunctionCache[FuncDecl] = State;
return State;
}

View File

@ -1,4 +1,6 @@
// RUN: %check_clang_tidy %s performance-noexcept-move-constructor %t -- -- -fexceptions
// RUN: %check_clang_tidy -std=c++17 -check-suffixes=,ERR %s performance-noexcept-move-constructor %t \
// RUN: -- --fix-errors -- -fexceptions -DENABLE_ERROR
namespace std
{
@ -397,3 +399,18 @@ namespace gh68101
Container(Container&&) noexcept(std::is_nothrow_move_constructible<T>::value);
};
} // namespace gh68101
namespace gh111436
{
template <typename value_type> class set {
set(set &&) = default;
#ifdef ENABLE_ERROR
set(initializer_list<value_type> __l) {};
// CHECK-MESSAGES-ERR: :[[@LINE-1]]:7: error: member 'initializer_list' cannot have template arguments [clang-diagnostic-error]
// CHECK-MESSAGES-ERR: :[[@LINE-2]]:36: error: expected ')' [clang-diagnostic-error]
#endif
};
} // namespace gh111436