Author: Balázs Benics Date: 2025-11-23T09:18:09Z New Revision: a088e745b7211ab732c99a210ec99345913f668c
URL: https://github.com/llvm/llvm-project/commit/a088e745b7211ab732c99a210ec99345913f668c DIFF: https://github.com/llvm/llvm-project/commit/a088e745b7211ab732c99a210ec99345913f668c.diff LOG: [analyzer] Fix [[clang::suppress]] for template instantiations (#168954) BugSuppression works by traversing the lexical decl context of the decl-with-issue to record what source ranges should be suppressed by some attribute. Note that the decl-with-issue will be changed to the lexical decl context of the original decl-with-issue, to make suppression attributes work that were attached to the CXXRecordDecl containing the CXXMethodDecl (bug report's DeclWithIssue). It happens so that it uses a DynamicRecursiveASTVisitor, which has a couple of traversal options. Namely: - ShouldVisitTemplateInstantiations - ShouldWalkTypesOfTypeLocs - ShouldVisitImplicitCode - ShouldVisitLambdaBody By default, these have the correct values, except for ShouldVisitTemplateInstantiations. We should traverse template instantiations because that might be where the bug is reported - thus, where we might have a [[clang::suppress]] that we should honor. In this patch I'll explicitly set these traversal options to avoid further confusion. rdar://164646398 Added: Modified: clang/lib/StaticAnalyzer/Core/BugSuppression.cpp clang/test/Analysis/suppression-attr.cpp Removed: ################################################################################ diff --git a/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp b/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp index 5b5f9df9cb0dc..a7300b7183590 100644 --- a/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp @@ -117,7 +117,12 @@ class CacheInitializer : public DynamicRecursiveASTVisitor { } } - CacheInitializer(Ranges &R) : Result(R) {} + CacheInitializer(Ranges &R) : Result(R) { + ShouldVisitTemplateInstantiations = true; + ShouldWalkTypesOfTypeLocs = false; + ShouldVisitImplicitCode = false; + ShouldVisitLambdaBody = true; + } Ranges &Result; }; diff --git a/clang/test/Analysis/suppression-attr.cpp b/clang/test/Analysis/suppression-attr.cpp index 89bc3c47dbd51..9ba56d976fddb 100644 --- a/clang/test/Analysis/suppression-attr.cpp +++ b/clang/test/Analysis/suppression-attr.cpp @@ -1,4 +1,27 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s + +void clang_analyzer_warnIfReached(); + +struct Clazz { + template <typename T> + static void templated_memfn(); +}; + +// This must come before the 'templated_memfn' is defined! +static void instantiate() { + Clazz::templated_memfn<int>(); +} + +template <typename T> +void Clazz::templated_memfn() { + // When we report a bug in a function, we traverse the lexical decl context + // of it while looking for suppression attributes to record what source + // ranges should the suppression apply to. + // In the past, that traversal didn't follow template instantiations, only + // primary templates. + [[clang::suppress]] clang_analyzer_warnIfReached(); // no-warning + +} namespace [[clang::suppress]] suppressed_namespace { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
