Author: Samira Bazuzi Date: 2024-08-19T13:25:49-04:00 New Revision: 2575ea6e17889e6d83198fc1c80963f81485bfcc
URL: https://github.com/llvm/llvm-project/commit/2575ea6e17889e6d83198fc1c80963f81485bfcc DIFF: https://github.com/llvm/llvm-project/commit/2575ea6e17889e6d83198fc1c80963f81485bfcc.diff LOG: [clang][dataflow] Collect local variables referenced within a functio… (#104459) …n/statement. We don't need these for the same in-tree purposes as the other sets, i.e. for making sure we model these Decls that are declared outside the function, but we have an out-of-tree use for these sets that would benefit from this simple addition and would avoid duplicating so much of this code. Added: Modified: clang/include/clang/Analysis/FlowSensitive/ASTOps.h clang/lib/Analysis/FlowSensitive/ASTOps.cpp clang/unittests/Analysis/FlowSensitive/ASTOpsTest.cpp Removed: ################################################################################ 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; } 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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits