Skip to content

Commit 5c2da28

Browse files
[clang][dataflow] fix assert in Environment::getResultObjectLocation (#79608)
When calling `Environment::getResultObjectLocation` with a CXXOperatorCallExpr that is a prvalue, we just hit an assert because no record was ever created. --------- Co-authored-by: martinboehme <[email protected]>
1 parent 0cd8348 commit 5c2da28

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

clang/lib/Analysis/FlowSensitive/Transfer.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,13 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
536536

537537
copyRecord(*LocSrc, *LocDst, Env);
538538
Env.setStorageLocation(*S, *LocDst);
539+
return;
539540
}
541+
542+
// CXXOperatorCallExpr can be prvalues. Call `VisitCallExpr`() to create
543+
// a `RecordValue` for them so that `Environment::getResultObjectLocation()`
544+
// can return a value.
545+
VisitCallExpr(S);
540546
}
541547

542548
void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *S) {

clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2735,6 +2735,39 @@ TEST(TransferTest, ResultObjectLocationForDefaultInitExpr) {
27352735
});
27362736
}
27372737

2738+
// This test ensures that CXXOperatorCallExpr returning prvalues are correctly
2739+
// handled by the transfer functions, especially that `getResultObjectLocation`
2740+
// correctly returns a storage location for those.
2741+
TEST(TransferTest, ResultObjectLocationForCXXOperatorCallExpr) {
2742+
std::string Code = R"(
2743+
struct A {
2744+
A operator+(int);
2745+
};
2746+
2747+
void target() {
2748+
A a;
2749+
a + 3;
2750+
(void)0; // [[p]]
2751+
}
2752+
)";
2753+
using ast_matchers::cxxOperatorCallExpr;
2754+
using ast_matchers::match;
2755+
using ast_matchers::selectFirst;
2756+
using ast_matchers::traverse;
2757+
runDataflow(
2758+
Code,
2759+
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
2760+
ASTContext &ASTCtx) {
2761+
const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
2762+
2763+
auto *CallExpr = selectFirst<CXXOperatorCallExpr>(
2764+
"call_expr",
2765+
match(cxxOperatorCallExpr().bind("call_expr"), ASTCtx));
2766+
2767+
EXPECT_NE(&Env.getResultObjectLocation(*CallExpr), nullptr);
2768+
});
2769+
}
2770+
27382771
TEST(TransferTest, StaticCast) {
27392772
std::string Code = R"(
27402773
void target(int Foo) {

0 commit comments

Comments
 (0)