[clang] [ASTMatchers] fix `isStaticStorageClass` not matching definitions of forward declared functions (PR #120027)

Julian Schmidt via cfe-commits cfe-commits at lists.llvm.org
Sun Dec 15 16:29:21 PST 2024


https://github.com/5chmidti updated https://github.com/llvm/llvm-project/pull/120027

>From 07dd31ddd40cdb792d33fc3394f6356de029a137 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <git.julian.schmidt at gmail.com>
Date: Mon, 16 Dec 2024 01:28:42 +0100
Subject: [PATCH] [ASTMatchers] fix `isStaticStorageClass` not matching
 definitions of forward declared functions

```c++
static void foo();
void foo() {}

struct A {
    static void bar();
};
void A::bar() {}
```

Both definitions refer to their previous declaration, but were not
considered `static`, because the matcher did not check the canonical
declaration.
---
 clang/docs/LibASTMatchersReference.html                  | 4 +++-
 clang/docs/ReleaseNotes.rst                              | 3 +++
 clang/include/clang/ASTMatchers/ASTMatchers.h            | 6 ++++--
 clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp | 8 ++++++++
 4 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html
index f18e9cf1341696..fe24bd3ab9a0cd 100644
--- a/clang/docs/LibASTMatchersReference.html
+++ b/clang/docs/LibASTMatchersReference.html
@@ -4683,8 +4683,10 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
   static int i = 0;
   extern int j;
   int k;
+  static void l();
+  void l() {}
 functionDecl(isStaticStorageClass())
-  matches the function declaration f.
+  matches the function declaration of f and l, and the definition of l.
 varDecl(isStaticStorageClass())
   matches the variable declaration i.
 </pre></td></tr>
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index befa411e882b4c..66d3cd6b53c7eb 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1041,6 +1041,9 @@ AST Matchers
 
 - Ensure ``pointee`` matches Objective-C pointer types.
 
+- Fixed `isStaticStorageClass` not matching the definition if the definition was
+  not marked `static` as well.
+
 clang-format
 ------------
 
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index 897aa25dc95cc1..e7ab6c184349e4 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -5418,15 +5418,17 @@ AST_POLYMORPHIC_MATCHER(isExternC, AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
 ///   static int i = 0;
 ///   extern int j;
 ///   int k;
+///   static void l();
+///   void l() {}
 /// \endcode
 /// functionDecl(isStaticStorageClass())
-///   matches the function declaration f.
+///   matches the function declaration of f and l, and the definition of l.
 /// varDecl(isStaticStorageClass())
 ///   matches the variable declaration i.
 AST_POLYMORPHIC_MATCHER(isStaticStorageClass,
                         AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
                                                         VarDecl)) {
-  return Node.getStorageClass() == SC_Static;
+  return Node.getCanonicalDecl()->getStorageClass() == SC_Static;
 }
 
 /// Matches deleted function declarations.
diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
index 056b7c7b571ef4..f1efba5b0650fa 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -1826,6 +1826,14 @@ TEST_P(ASTMatchersTest, IsStaticStorageClass) {
   EXPECT_TRUE(notMatches("int i = 1;", varDecl(isStaticStorageClass())));
   EXPECT_TRUE(notMatches("extern int i;", varDecl(isStaticStorageClass())));
   EXPECT_TRUE(notMatches("void f() {}", functionDecl(isStaticStorageClass())));
+
+  if (!GetParam().isCXX())
+    return;
+
+  EXPECT_TRUE(matches("static void foo(); void foo() {}",
+                      functionDecl(isDefinition(), isStaticStorageClass())));
+  EXPECT_TRUE(matches("struct A { static void bar(); }; void A::bar() {}",
+                      cxxMethodDecl(isDefinition(), isStaticStorageClass())));
 }
 
 TEST_P(ASTMatchersTest, IsDefaulted) {



More information about the cfe-commits mailing list