[clang] 5c2da28 - [clang][dataflow] fix assert in `Environment::getResultObjectLocation` (#79608)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 31 08:18:21 PST 2024
Author: Paul Semel
Date: 2024-01-31T17:18:16+01:00
New Revision: 5c2da289d2514e35708832fed41501d136cc3cb0
URL: https://github.com/llvm/llvm-project/commit/5c2da289d2514e35708832fed41501d136cc3cb0
DIFF: https://github.com/llvm/llvm-project/commit/5c2da289d2514e35708832fed41501d136cc3cb0.diff
LOG: [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 <mboehme at google.com>
Added:
Modified:
clang/lib/Analysis/FlowSensitive/Transfer.cpp
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp
index 2271a75fbcaf7..bb3aec763c29c 100644
--- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp
+++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp
@@ -536,7 +536,13 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
copyRecord(*LocSrc, *LocDst, Env);
Env.setStorageLocation(*S, *LocDst);
+ return;
}
+
+ // CXXOperatorCallExpr can be prvalues. Call `VisitCallExpr`() to create
+ // a `RecordValue` for them so that `Environment::getResultObjectLocation()`
+ // can return a value.
+ VisitCallExpr(S);
}
void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *S) {
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index 268ea4c7431f6..8bbb04024dcce 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -2735,6 +2735,39 @@ TEST(TransferTest, ResultObjectLocationForDefaultInitExpr) {
});
}
+// This test ensures that CXXOperatorCallExpr returning prvalues are correctly
+// handled by the transfer functions, especially that `getResultObjectLocation`
+// correctly returns a storage location for those.
+TEST(TransferTest, ResultObjectLocationForCXXOperatorCallExpr) {
+ std::string Code = R"(
+ struct A {
+ A operator+(int);
+ };
+
+ void target() {
+ A a;
+ a + 3;
+ (void)0; // [[p]]
+ }
+ )";
+ using ast_matchers::cxxOperatorCallExpr;
+ using ast_matchers::match;
+ using ast_matchers::selectFirst;
+ using ast_matchers::traverse;
+ runDataflow(
+ Code,
+ [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+ ASTContext &ASTCtx) {
+ const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+ auto *CallExpr = selectFirst<CXXOperatorCallExpr>(
+ "call_expr",
+ match(cxxOperatorCallExpr().bind("call_expr"), ASTCtx));
+
+ EXPECT_NE(&Env.getResultObjectLocation(*CallExpr), nullptr);
+ });
+}
+
TEST(TransferTest, StaticCast) {
std::string Code = R"(
void target(int Foo) {
More information about the cfe-commits
mailing list