================
@@ -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
----------------
steakhal wrote:

> I'm trying to understand how `BugSuppression` works: The bug is at the 
> `clang_analyzer_warnIfReached()` call so the decl context being visited is 
> the instantiated definition of `Clazz::templated_memfn<int>() {...}`. [...]

You are right. Sharp eyes. I lied a bit because we also swap the decl context 
to the parent context, which is going to be the class definition itself, that 
has the template instantiations as child nodes in the AST - including the one 
where we have the suppression. However, if we skip traversing instantiations 
then we would not see the suppression.
https://github.com/llvm/llvm-project/blob/main/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp#L175-L189
```c++
  } else {
    // This is the fast path. However, we should still consider the topmost
    // declaration that isn't TranslationUnitDecl, because we should respect
    // attributes on the entire declaration chain.
    while (true) {
      // Use the "lexical" parent. Eg., if the attribute is on a class, suppress
      // warnings in inline methods but not in out-of-line methods.
      const Decl *Parent =
          dyn_cast_or_null<Decl>(DeclWithIssue->getLexicalDeclContext());
      if (Parent == nullptr || isa<TranslationUnitDecl>(Parent))
        break;

      DeclWithIssue = Parent;
    }
  }
```

> What would happen if I move `[[clang::suppress]]` to line 12: 
> `[[clang::suppress]] Clazz::templated_memfn<int>();`?

I've not tried, but I'm almost certain that having a suppress for a statement 
(such as your proposed attribute at that CallExpr) would only suppress issues 
raised within the source range of the effective statement (CallExpr).
Since the bug is raised within the callee of that CallExpr, the bug should not 
be suppressed by that attribute.

If it would suppress it, than that would be a bug in the suppression algorithm.

https://github.com/llvm/llvm-project/pull/168954
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to