Skip to content

Commit 2825342

Browse files
authored
[clang][dataflow] Handle AtomicExpr in ResultObjectVisitor. (#94963)
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.
1 parent 876c620 commit 2825342

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ class ResultObjectVisitor : public AnalysisASTVisitor<ResultObjectVisitor> {
415415
// below them can initialize the same object (or part of it).
416416
if (isa<CXXConstructExpr>(E) || isa<CallExpr>(E) || isa<LambdaExpr>(E) ||
417417
isa<CXXDefaultArgExpr>(E) || isa<CXXDefaultInitExpr>(E) ||
418-
isa<CXXStdInitializerListExpr>(E) ||
418+
isa<CXXStdInitializerListExpr>(E) || isa<AtomicExpr>(E) ||
419419
// We treat `BuiltinBitCastExpr` as an "original initializer" too as
420420
// it may not even be casting from a record type -- and even if it is,
421421
// the two objects are in general of unrelated type.

clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3345,6 +3345,32 @@ TEST(TransferTest, ResultObjectLocationForBuiltinBitCastExpr) {
33453345
});
33463346
}
33473347

3348+
TEST(TransferTest, ResultObjectLocationForAtomicExpr) {
3349+
std::string Code = R"(
3350+
struct S {};
3351+
void target(_Atomic(S) *ptr) {
3352+
S s = __c11_atomic_load(ptr, __ATOMIC_SEQ_CST);
3353+
// [[p]]
3354+
}
3355+
)";
3356+
using ast_matchers::atomicExpr;
3357+
using ast_matchers::match;
3358+
using ast_matchers::selectFirst;
3359+
using ast_matchers::traverse;
3360+
runDataflow(
3361+
Code,
3362+
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
3363+
ASTContext &ASTCtx) {
3364+
const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
3365+
3366+
auto *Atomic = selectFirst<AtomicExpr>(
3367+
"atomic", match(atomicExpr().bind("atomic"), ASTCtx));
3368+
3369+
EXPECT_EQ(&Env.getResultObjectLocation(*Atomic),
3370+
&getLocForDecl<RecordStorageLocation>(ASTCtx, Env, "s"));
3371+
});
3372+
}
3373+
33483374
TEST(TransferTest, ResultObjectLocationPropagatesThroughConditionalOperator) {
33493375
std::string Code = R"(
33503376
struct A {

0 commit comments

Comments
 (0)