Skip to content

Commit 2575ea6

Browse files
authored
[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.
1 parent 564bd20 commit 2575ea6

File tree

3 files changed

+34
-0
lines changed

3 files changed

+34
-0
lines changed

clang/include/clang/Analysis/FlowSensitive/ASTOps.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ struct ReferencedDecls {
139139
/// All variables with static storage duration, notably including static
140140
/// member variables and static variables declared within a function.
141141
llvm::DenseSet<const VarDecl *> Globals;
142+
/// Local variables, not including parameters or static variables declared
143+
/// within a function.
144+
llvm::DenseSet<const VarDecl *> Locals;
142145
/// Free functions and member functions which are referenced (but not
143146
/// necessarily called).
144147
llvm::DenseSet<const FunctionDecl *> Functions;

clang/lib/Analysis/FlowSensitive/ASTOps.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,13 @@ static void insertIfGlobal(const Decl &D,
170170
Globals.insert(V);
171171
}
172172

173+
static void insertIfLocal(const Decl &D,
174+
llvm::DenseSet<const VarDecl *> &Locals) {
175+
if (auto *V = dyn_cast<VarDecl>(&D))
176+
if (V->hasLocalStorage() && !isa<ParmVarDecl>(V))
177+
Locals.insert(V);
178+
}
179+
173180
static void insertIfFunction(const Decl &D,
174181
llvm::DenseSet<const FunctionDecl *> &Funcs) {
175182
if (auto *FD = dyn_cast<FunctionDecl>(&D))
@@ -220,12 +227,14 @@ class ReferencedDeclsVisitor
220227

221228
bool VisitDecl(Decl *D) {
222229
insertIfGlobal(*D, Referenced.Globals);
230+
insertIfLocal(*D, Referenced.Locals);
223231
insertIfFunction(*D, Referenced.Functions);
224232
return true;
225233
}
226234

227235
bool VisitDeclRefExpr(DeclRefExpr *E) {
228236
insertIfGlobal(*E->getDecl(), Referenced.Globals);
237+
insertIfLocal(*E->getDecl(), Referenced.Locals);
229238
insertIfFunction(*E->getDecl(), Referenced.Functions);
230239
return true;
231240
}

clang/unittests/Analysis/FlowSensitive/ASTOpsTest.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,26 @@ TEST(ASTOpsTest, ReferencedDeclsOnUnionInitList) {
8585
UnorderedElementsAre(IDecl));
8686
}
8787

88+
TEST(ASTOpsTest, ReferencedDeclsLocalsNotParamsOrStatics) {
89+
std::string Code = R"cc(
90+
void func(int Param) {
91+
static int Static = 0;
92+
int Local = Param;
93+
Local = Static;
94+
}
95+
)cc";
96+
std::unique_ptr<ASTUnit> Unit =
97+
tooling::buildASTFromCodeWithArgs(Code, {"-fsyntax-only", "-std=c++17"});
98+
auto &ASTCtx = Unit->getASTContext();
99+
100+
ASSERT_EQ(ASTCtx.getDiagnostics().getClient()->getNumErrors(), 0U);
101+
102+
auto *Func = cast<FunctionDecl>(findValueDecl(ASTCtx, "func"));
103+
ASSERT_NE(Func, nullptr);
104+
auto *LocalDecl = cast<VarDecl>(findValueDecl(ASTCtx, "Local"));
105+
106+
EXPECT_THAT(getReferencedDecls(*Func).Locals,
107+
UnorderedElementsAre(LocalDecl));
108+
}
109+
88110
} // namespace

0 commit comments

Comments
 (0)