https://github.com/steakhal created 
https://github.com/llvm/llvm-project/pull/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.

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

From be78fc784911df1e84d3796ac5376be047011975 Mon Sep 17 00:00:00 2001
From: Balazs Benics <[email protected]>
Date: Thu, 20 Nov 2025 22:43:35 +0100
Subject: [PATCH] [analyzer] Fix [[clang::suppress]] for template
 instantiations

BugSuppression works by traversing the lexical decl context of the decl
with issue to record what source ranges should be suppressed by some
attribute.

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
---
 .../StaticAnalyzer/Core/BugSuppression.cpp    |  7 +++++-
 clang/test/Analysis/suppression-attr.cpp      | 25 ++++++++++++++++++-
 2 files changed, 30 insertions(+), 2 deletions(-)

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