Skip to content

Commit a8fb0dc

Browse files
[dataflow] CXXOperatorCallExpr equal operator might not be a glvalue (#80991)
Although in a normal implementation the assumption is reasonable, it seems that some esoteric implementation are not returning a T&. This should be handled correctly and the values be propagated. --------- Co-authored-by: martinboehme <[email protected]>
1 parent 9ca1a15 commit a8fb0dc

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

clang/lib/Analysis/FlowSensitive/Transfer.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,19 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
535535
return;
536536

537537
copyRecord(*LocSrc, *LocDst, Env);
538-
Env.setStorageLocation(*S, *LocDst);
538+
539+
// If the expr is a glvalue, we can reasonably assume the operator is
540+
// returning T& and thus we can assign it `LocDst`.
541+
if (S->isGLValue()) {
542+
Env.setStorageLocation(*S, *LocDst);
543+
} else if (S->getType()->isRecordType()) {
544+
// Make sure that we have a `RecordValue` for this expression so that
545+
// `Environment::getResultObjectLocation()` is able to return a location
546+
// for it.
547+
if (Env.getValue(*S) == nullptr)
548+
refreshRecordValue(*S, Env);
549+
}
550+
539551
return;
540552
}
541553

clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2313,6 +2313,42 @@ TEST(TransferTest, AssignmentOperatorWithInitAndInheritance) {
23132313
ASTContext &ASTCtx) {});
23142314
}
23152315

2316+
TEST(TransferTest, AssignmentOperatorReturnsVoid) {
2317+
// This is a crash repro.
2318+
std::string Code = R"(
2319+
struct S {
2320+
void operator=(S&& other);
2321+
};
2322+
void target() {
2323+
S s;
2324+
s = S();
2325+
// [[p]]
2326+
}
2327+
)";
2328+
runDataflow(
2329+
Code,
2330+
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
2331+
ASTContext &ASTCtx) {});
2332+
}
2333+
2334+
TEST(TransferTest, AssignmentOperatorReturnsByValue) {
2335+
// This is a crash repro.
2336+
std::string Code = R"(
2337+
struct S {
2338+
S operator=(S&& other);
2339+
};
2340+
void target() {
2341+
S s;
2342+
s = S();
2343+
// [[p]]
2344+
}
2345+
)";
2346+
runDataflow(
2347+
Code,
2348+
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
2349+
ASTContext &ASTCtx) {});
2350+
}
2351+
23162352
TEST(TransferTest, CopyConstructor) {
23172353
std::string Code = R"(
23182354
struct A {

0 commit comments

Comments
 (0)