Skip to content

Commit 2f93bbb

Browse files
committed
[clang][dataflow] Relax Environment comparison operation.
Ignore `MemberLocToStruct` in environment comparison. As an ancillary data structure, including it is redundant. We also can generate environments which differ in their `MemberLocToStruct` but are otherwise equivalent. Differential Revision: https://reviews.llvm.org/D126314
1 parent dcf9ba8 commit 2f93bbb

File tree

2 files changed

+55
-3
lines changed

2 files changed

+55
-3
lines changed

clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,6 @@ bool Environment::equivalentTo(const Environment &Other,
239239
if (ExprToLoc != Other.ExprToLoc)
240240
return false;
241241

242-
if (MemberLocToStruct != Other.MemberLocToStruct)
243-
return false;
244-
245242
// Compare the contents for the intersection of their domains.
246243
for (auto &Entry : LocToVal) {
247244
const StorageLocation *Loc = Entry.first;

clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3120,4 +3120,59 @@ TEST_F(TransferTest, LoopWithReferenceAssignmentConverges) {
31203120
});
31213121
}
31223122

3123+
TEST_F(TransferTest, LoopWithStructReferenceAssignmentConverges) {
3124+
std::string Code = R"(
3125+
struct Lookup {
3126+
int x;
3127+
};
3128+
3129+
void target(Lookup val, bool b) {
3130+
const Lookup* l = nullptr;
3131+
while (b) {
3132+
l = &val;
3133+
/*[[p-inner]]*/
3134+
}
3135+
(void)0;
3136+
/*[[p-outer]]*/
3137+
}
3138+
)";
3139+
// The key property that we are verifying is implicit in `runDataflow` --
3140+
// namely, that the analysis succeeds, rather than hitting the maximum number
3141+
// of iterations.
3142+
runDataflow(
3143+
Code, [](llvm::ArrayRef<
3144+
std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
3145+
Results,
3146+
ASTContext &ASTCtx) {
3147+
ASSERT_THAT(Results,
3148+
ElementsAre(Pair("p-outer", _), Pair("p-inner", _)));
3149+
const Environment &OuterEnv = Results[0].second.Env;
3150+
const Environment &InnerEnv = Results[1].second.Env;
3151+
3152+
const ValueDecl *ValDecl = findValueDecl(ASTCtx, "val");
3153+
ASSERT_THAT(ValDecl, NotNull());
3154+
3155+
const ValueDecl *LDecl = findValueDecl(ASTCtx, "l");
3156+
ASSERT_THAT(LDecl, NotNull());
3157+
3158+
// Inner.
3159+
auto *LVal = dyn_cast<IndirectionValue>(
3160+
InnerEnv.getValue(*LDecl, SkipPast::None));
3161+
ASSERT_THAT(LVal, NotNull());
3162+
3163+
EXPECT_EQ(&LVal->getPointeeLoc(),
3164+
InnerEnv.getStorageLocation(*ValDecl, SkipPast::Reference));
3165+
3166+
// Outer.
3167+
LVal = dyn_cast<IndirectionValue>(
3168+
OuterEnv.getValue(*LDecl, SkipPast::None));
3169+
ASSERT_THAT(LVal, NotNull());
3170+
3171+
// The loop body may not have been executed, so we should not conclude
3172+
// that `l` points to `val`.
3173+
EXPECT_NE(&LVal->getPointeeLoc(),
3174+
OuterEnv.getStorageLocation(*ValDecl, SkipPast::Reference));
3175+
});
3176+
}
3177+
31233178
} // namespace

0 commit comments

Comments
 (0)