diff options
author | martinboehme <mboehme@google.com> | 2024-01-22 09:23:06 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-22 09:23:06 +0100 |
commit | a2caa4929e8e8a2ffff4ee5f03ab37a9be7462a0 (patch) | |
tree | 59d019a84dfc24503b09053a132ee932a49f30e7 /clang | |
parent | 3b943c0203df5c35089417567cc470d5cdbc497e (diff) | |
download | llvm-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.cpp | 9 | ||||
-rw-r--r-- | clang/unittests/Analysis/FlowSensitive/TransferTest.cpp | 22 |
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)); }); |