aboutsummaryrefslogtreecommitdiff
path: root/clang
diff options
context:
space:
mode:
authormartinboehme <mboehme@google.com>2024-01-22 09:23:06 +0100
committerGitHub <noreply@github.com>2024-01-22 09:23:06 +0100
commita2caa4929e8e8a2ffff4ee5f03ab37a9be7462a0 (patch)
tree59d019a84dfc24503b09053a132ee932a49f30e7 /clang
parent3b943c0203df5c35089417567cc470d5cdbc497e (diff)
downloadllvm-a2caa4929e8e8a2ffff4ee5f03ab37a9be7462a0.zip
llvm-a2caa4929e8e8a2ffff4ee5f03ab37a9be7462a0.tar.gz
llvm-a2caa4929e8e8a2ffff4ee5f03ab37a9be7462a0.tar.bz2
[clang][dataflow] Treat comma operator correctly in `getResultObjectLocation()`. (#78427)
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp9
-rw-r--r--clang/unittests/Analysis/FlowSensitive/TransferTest.cpp22
2 files changed, 23 insertions, 8 deletions
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index 07dc3a9..196a136 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -782,8 +782,13 @@ Environment::getResultObjectLocation(const Expr &RecordPRValue) const {
return Val->getLoc();
}
- // Expression nodes that propagate a record prvalue should have exactly one
- // child.
+ if (auto *Op = dyn_cast<BinaryOperator>(&RecordPRValue);
+ Op && Op->isCommaOp()) {
+ return getResultObjectLocation(*Op->getRHS());
+ }
+
+ // All other expression nodes that propagate a record prvalue should have
+ // exactly one child.
llvm::SmallVector<const Stmt *> children(RecordPRValue.child_begin(),
RecordPRValue.child_end());
assert(children.size() == 1);
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index d0a0e6d..85ae24f 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -2642,14 +2642,17 @@ TEST(TransferTest, ResultObjectLocation) {
};
void target() {
- A();
+ 0, A();
(void)0; // [[p]]
}
)";
+ using ast_matchers::binaryOperator;
using ast_matchers::cxxBindTemporaryExpr;
using ast_matchers::cxxTemporaryObjectExpr;
using ast_matchers::exprWithCleanups;
using ast_matchers::has;
+ using ast_matchers::hasOperatorName;
+ using ast_matchers::hasRHS;
using ast_matchers::match;
using ast_matchers::selectFirst;
using ast_matchers::traverse;
@@ -2659,26 +2662,33 @@ TEST(TransferTest, ResultObjectLocation) {
ASTContext &ASTCtx) {
const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
- // The expresssion `A()` in the code above produces the following
- // structure, consisting of three prvalues of record type.
+ // The expression `0, A()` in the code above produces the following
+ // structure, consisting of four prvalues of record type.
// `Env.getResultObjectLocation()` should return the same location for
// all of these.
auto MatchResult = match(
traverse(TK_AsIs,
exprWithCleanups(
- has(cxxBindTemporaryExpr(
- has(cxxTemporaryObjectExpr().bind("toe")))
- .bind("bte")))
+ has(binaryOperator(
+ hasOperatorName(","),
+ hasRHS(cxxBindTemporaryExpr(
+ has(cxxTemporaryObjectExpr().bind(
+ "toe")))
+ .bind("bte")))
+ .bind("comma")))
.bind("ewc")),
ASTCtx);
auto *TOE = selectFirst<CXXTemporaryObjectExpr>("toe", MatchResult);
ASSERT_NE(TOE, nullptr);
+ auto *Comma = selectFirst<BinaryOperator>("comma", MatchResult);
+ ASSERT_NE(Comma, nullptr);
auto *EWC = selectFirst<ExprWithCleanups>("ewc", MatchResult);
ASSERT_NE(EWC, nullptr);
auto *BTE = selectFirst<CXXBindTemporaryExpr>("bte", MatchResult);
ASSERT_NE(BTE, nullptr);
RecordStorageLocation &Loc = Env.getResultObjectLocation(*TOE);
+ EXPECT_EQ(&Loc, &Env.getResultObjectLocation(*Comma));
EXPECT_EQ(&Loc, &Env.getResultObjectLocation(*EWC));
EXPECT_EQ(&Loc, &Env.getResultObjectLocation(*BTE));
});