[clang] [clang][dataflow] Collect local variables referenced within a functio… (PR #104459)

Samira Bazuzi via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 19 08:07:08 PDT 2024


https://github.com/bazuzi updated https://github.com/llvm/llvm-project/pull/104459

>From 5aaa8c5e65b59b0f21775811f48dec350ae210c7 Mon Sep 17 00:00:00 2001
From: Samira Bazuzi <bazuzi at google.com>
Date: Thu, 15 Aug 2024 11:11:30 -0400
Subject: [PATCH 1/2] [clang][dataflow] Collect local variables referenced
 within a function/statement.

---
 clang/include/clang/Analysis/FlowSensitive/ASTOps.h | 3 +++
 clang/lib/Analysis/FlowSensitive/ASTOps.cpp         | 9 +++++++++
 2 files changed, 12 insertions(+)

diff --git a/clang/include/clang/Analysis/FlowSensitive/ASTOps.h b/clang/include/clang/Analysis/FlowSensitive/ASTOps.h
index f9c923a36ad229..ec4d041254877f 100644
--- a/clang/include/clang/Analysis/FlowSensitive/ASTOps.h
+++ b/clang/include/clang/Analysis/FlowSensitive/ASTOps.h
@@ -139,6 +139,9 @@ struct ReferencedDecls {
   /// All variables with static storage duration, notably including static
   /// member variables and static variables declared within a function.
   llvm::DenseSet<const VarDecl *> Globals;
+  /// Local variables, not including parameters or static variables declared
+  /// within a function.
+  llvm::DenseSet<const VarDecl *> Locals;
   /// Free functions and member functions which are referenced (but not
   /// necessarily called).
   llvm::DenseSet<const FunctionDecl *> Functions;
diff --git a/clang/lib/Analysis/FlowSensitive/ASTOps.cpp b/clang/lib/Analysis/FlowSensitive/ASTOps.cpp
index 27d42a7b508562..fdba139628d8ff 100644
--- a/clang/lib/Analysis/FlowSensitive/ASTOps.cpp
+++ b/clang/lib/Analysis/FlowSensitive/ASTOps.cpp
@@ -170,6 +170,13 @@ static void insertIfGlobal(const Decl &D,
       Globals.insert(V);
 }
 
+static void insertIfLocal(const Decl &D,
+                          llvm::DenseSet<const VarDecl *> &Locals) {
+  if (auto *V = dyn_cast<VarDecl>(&D))
+    if (V->hasLocalStorage() && !isa<ParmVarDecl>(V))
+      Locals.insert(V);
+}
+
 static void insertIfFunction(const Decl &D,
                              llvm::DenseSet<const FunctionDecl *> &Funcs) {
   if (auto *FD = dyn_cast<FunctionDecl>(&D))
@@ -220,12 +227,14 @@ class ReferencedDeclsVisitor
 
   bool VisitDecl(Decl *D) {
     insertIfGlobal(*D, Referenced.Globals);
+    insertIfLocal(*D, Referenced.Locals);
     insertIfFunction(*D, Referenced.Functions);
     return true;
   }
 
   bool VisitDeclRefExpr(DeclRefExpr *E) {
     insertIfGlobal(*E->getDecl(), Referenced.Globals);
+    insertIfLocal(*E->getDecl(), Referenced.Locals);
     insertIfFunction(*E->getDecl(), Referenced.Functions);
     return true;
   }

>From 0852bb9cea4916a94c7c168d99458f19abab5ee8 Mon Sep 17 00:00:00 2001
From: Samira Bazuzi <bazuzi at google.com>
Date: Mon, 19 Aug 2024 11:06:24 -0400
Subject: [PATCH 2/2] Add test confirming local non-static, non-param variables
 are included.

---
 .../Analysis/FlowSensitive/ASTOpsTest.cpp     | 22 +++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/clang/unittests/Analysis/FlowSensitive/ASTOpsTest.cpp b/clang/unittests/Analysis/FlowSensitive/ASTOpsTest.cpp
index cd1c076ab09e6b..834aa7f4c2ac2e 100644
--- a/clang/unittests/Analysis/FlowSensitive/ASTOpsTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/ASTOpsTest.cpp
@@ -85,4 +85,26 @@ TEST(ASTOpsTest, ReferencedDeclsOnUnionInitList) {
               UnorderedElementsAre(IDecl));
 }
 
+TEST(ASTOpsTest, ReferencedDeclsLocalsNotParamsOrStatics) {
+  std::string Code = R"cc(
+    void func(int Param) {
+      static int Static = 0;
+      int Local = Param;
+      Local = Static;
+    }
+  )cc";
+  std::unique_ptr<ASTUnit> Unit =
+      tooling::buildASTFromCodeWithArgs(Code, {"-fsyntax-only", "-std=c++17"});
+  auto &ASTCtx = Unit->getASTContext();
+
+  ASSERT_EQ(ASTCtx.getDiagnostics().getClient()->getNumErrors(), 0U);
+
+  auto *Func = cast<FunctionDecl>(findValueDecl(ASTCtx, "func"));
+  ASSERT_NE(Func, nullptr);
+  auto *LocalDecl = cast<VarDecl>(findValueDecl(ASTCtx, "Local"));
+
+  EXPECT_THAT(getReferencedDecls(*Func).Locals,
+              UnorderedElementsAre(LocalDecl));
+}
+
 } // namespace



More information about the cfe-commits mailing list