Skip to content

Commit

Permalink
[clang][dataflow] Handle AtomicExpr in ResultObjectVisitor. (#94963)
Browse files Browse the repository at this point in the history
This is one of the node kinds that should be considered an "original
initializer". The patch adds a test that was causing an assertion
failure in
`assert(Children.size() == 1)` without the fix.
  • Loading branch information
martinboehme authored Jun 11, 2024
1 parent 876c620 commit 2825342
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
2 changes: 1 addition & 1 deletion clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ class ResultObjectVisitor : public AnalysisASTVisitor<ResultObjectVisitor> {
// below them can initialize the same object (or part of it).
if (isa<CXXConstructExpr>(E) || isa<CallExpr>(E) || isa<LambdaExpr>(E) ||
isa<CXXDefaultArgExpr>(E) || isa<CXXDefaultInitExpr>(E) ||
isa<CXXStdInitializerListExpr>(E) ||
isa<CXXStdInitializerListExpr>(E) || isa<AtomicExpr>(E) ||
// We treat `BuiltinBitCastExpr` as an "original initializer" too as
// it may not even be casting from a record type -- and even if it is,
// the two objects are in general of unrelated type.
Expand Down
26 changes: 26 additions & 0 deletions clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3345,6 +3345,32 @@ TEST(TransferTest, ResultObjectLocationForBuiltinBitCastExpr) {
});
}

TEST(TransferTest, ResultObjectLocationForAtomicExpr) {
std::string Code = R"(
struct S {};
void target(_Atomic(S) *ptr) {
S s = __c11_atomic_load(ptr, __ATOMIC_SEQ_CST);
// [[p]]
}
)";
using ast_matchers::atomicExpr;
using ast_matchers::match;
using ast_matchers::selectFirst;
using ast_matchers::traverse;
runDataflow(
Code,
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
ASTContext &ASTCtx) {
const Environment &Env = getEnvironmentAtAnnotation(Results, "p");

auto *Atomic = selectFirst<AtomicExpr>(
"atomic", match(atomicExpr().bind("atomic"), ASTCtx));

EXPECT_EQ(&Env.getResultObjectLocation(*Atomic),
&getLocForDecl<RecordStorageLocation>(ASTCtx, Env, "s"));
});
}

TEST(TransferTest, ResultObjectLocationPropagatesThroughConditionalOperator) {
std::string Code = R"(
struct A {
Expand Down

0 comments on commit 2825342

Please sign in to comment.