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

Reply via email to