Skip to content

Commit

Permalink
[clang][dataflow] Bugfix for refreshStructValue().
Browse files Browse the repository at this point in the history
In the case where the expression was not yet associated with a storage location, we created a new storage location but failed to associate it with the expression.

The newly added test fails without the fix.

Reviewed By: xazax.hun

Differential Revision: https://reviews.llvm.org/D155465
  • Loading branch information
martinboehme committed Jul 17, 2023
1 parent 47cf7a4 commit 0f6cf55
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 0 deletions.
1 change: 1 addition & 0 deletions clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1005,6 +1005,7 @@ StructValue &refreshStructValue(const Expr &Expr, Environment &Env) {
StorageLocation *Loc = Env.getStorageLocationStrict(Expr);
if (Loc == nullptr) {
Loc = &Env.createStorageLocation(Expr);
Env.setStorageLocation(Expr, *Loc);
}
Env.setValue(*Loc, NewVal);
}
Expand Down
32 changes: 32 additions & 0 deletions clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ namespace {
using namespace clang;
using namespace dataflow;
using ::clang::dataflow::test::getFieldValue;
using ::testing::IsNull;
using ::testing::NotNull;

class EnvironmentTest : public ::testing::Test {
Expand Down Expand Up @@ -252,4 +253,35 @@ TEST_F(EnvironmentTest, InitGlobalVarsConstructor) {
EXPECT_THAT(Env.getValue(*Var), NotNull());
}

TEST_F(EnvironmentTest, RefreshStructValue) {
using namespace ast_matchers;

std::string Code = R"cc(
struct S {};
void target () {
S s;
s;
}
)cc";

auto Unit =
tooling::buildASTFromCodeWithArgs(Code, {"-fsyntax-only", "-std=c++11"});
auto &Context = Unit->getASTContext();

ASSERT_EQ(Context.getDiagnostics().getClient()->getNumErrors(), 0U);

auto Results = match(functionDecl(hasName("target")).bind("target"), Context);
const auto *Target = selectFirst<FunctionDecl>("target", Results);
ASSERT_THAT(Target, NotNull());

Results = match(declRefExpr(to(varDecl(hasName("s")))).bind("s"), Context);
const auto *DRE = selectFirst<DeclRefExpr>("s", Results);
ASSERT_THAT(DRE, NotNull());

Environment Env(DAContext, *Target);
EXPECT_THAT(Env.getStorageLocationStrict(*DRE), IsNull());
refreshStructValue(*DRE, Env);
EXPECT_THAT(Env.getStorageLocationStrict(*DRE), NotNull());
}

} // namespace

0 comments on commit 0f6cf55

Please sign in to comment.