Skip to content

Commit a663e78

Browse files
authored
[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
1 parent 1138a49 commit a663e78

File tree

2 files changed

+24
-6
lines changed

2 files changed

+24
-6
lines changed

clang-tools-extra/clang-tidy/utils/ExceptionSpecAnalyzer.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@ namespace clang::tidy::utils {
1414

1515
ExceptionSpecAnalyzer::State
1616
ExceptionSpecAnalyzer::analyze(const FunctionDecl *FuncDecl) {
17-
// Check if the function has already been analyzed and reuse that result.
18-
const auto CacheEntry = FunctionCache.find(FuncDecl);
19-
if (CacheEntry == FunctionCache.end()) {
17+
// Check if function exist in cache or add temporary value to cache to protect
18+
// against endless recursion.
19+
const auto [CacheEntry, NotFound] =
20+
FunctionCache.try_emplace(FuncDecl, State::NotThrowing);
21+
if (NotFound) {
2022
ExceptionSpecAnalyzer::State State = analyzeImpl(FuncDecl);
21-
22-
// Cache the result of the analysis.
23-
FunctionCache.try_emplace(FuncDecl, State);
23+
// Update result with calculated value
24+
FunctionCache[FuncDecl] = State;
2425
return State;
2526
}
2627

clang-tools-extra/test/clang-tidy/checkers/performance/noexcept-move-constructor.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
// RUN: %check_clang_tidy %s performance-noexcept-move-constructor %t -- -- -fexceptions
2+
// RUN: %check_clang_tidy -std=c++17 -check-suffixes=,ERR %s performance-noexcept-move-constructor %t \
3+
// RUN: -- --fix-errors -- -fexceptions -DENABLE_ERROR
24

35
namespace std
46
{
@@ -397,3 +399,18 @@ namespace gh68101
397399
Container(Container&&) noexcept(std::is_nothrow_move_constructible<T>::value);
398400
};
399401
} // namespace gh68101
402+
403+
namespace gh111436
404+
{
405+
406+
template <typename value_type> class set {
407+
set(set &&) = default;
408+
409+
#ifdef ENABLE_ERROR
410+
set(initializer_list<value_type> __l) {};
411+
// CHECK-MESSAGES-ERR: :[[@LINE-1]]:7: error: member 'initializer_list' cannot have template arguments [clang-diagnostic-error]
412+
// CHECK-MESSAGES-ERR: :[[@LINE-2]]:36: error: expected ')' [clang-diagnostic-error]
413+
#endif
414+
};
415+
416+
} // namespace gh111436

0 commit comments

Comments
 (0)