[PATCH] D140430: [clang][dataflow] Fix bug in handling of `return` statements.
Yitzhak Mandelbaum via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Dec 20 13:05:16 PST 2022
ymandel created this revision.
ymandel added reviewers: xazax.hun, gribozavr2.
Herald added subscribers: martong, rnkovacs.
Herald added a reviewer: NoQ.
Herald added a project: All.
ymandel requested review of this revision.
Herald added a project: clang.
The handling of return statements, added in support of context-sensitive
analysis, has a bug relating to functions that return reference
types. Specifically, interpretation of such functions can result in a crash from
a bad cast. This patch fixes the bug and guards all of that code with the
context-sensitive option, since there's no reason to execute at all when
context-sensitive analysis is off.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D140430
Files:
clang/lib/Analysis/FlowSensitive/Transfer.cpp
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
Index: clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
===================================================================
--- clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -4018,6 +4018,35 @@
{TransferOptions{/*.ContextSensitiveOpts=*/std::nullopt}});
}
+// This test is a regression test, based on a real crash.
+TEST(TransferTest, ContextSensitiveReturnReferenceFromNonReferenceLvalue) {
+ // This code exercises an unusual code path. If we return an lvalue directly,
+ // the code will catch that it's an l-value based on the `Value`'s kind. If we
+ // pass through a dummy function, the framework won't populate a value at
+ // all. In contrast, this code results in a (fresh) value, but it is not
+ // `ReferenceValue`. This test verifies that we catch this case as well.
+ std::string Code = R"(
+ class S {};
+ S& target(bool b, S &s) {
+ return b ? s : s;
+ // [[p]]
+ }
+ )";
+ runDataflow(
+ Code,
+ [](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
+ ASTContext &ASTCtx) {
+ ASSERT_THAT(Results.keys(), UnorderedElementsAre("p"));
+ const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+ auto *Loc = Env.getReturnStorageLocation();
+ ASSERT_THAT(Loc, NotNull());
+
+ EXPECT_THAT(Env.getValue(*Loc), IsNull());
+ },
+ {TransferOptions{ContextSensitiveOptions{}}});
+}
+
TEST(TransferTest, ContextSensitiveDepthZero) {
std::string Code = R"(
bool GiveBool();
Index: clang/lib/Analysis/FlowSensitive/Transfer.cpp
===================================================================
--- clang/lib/Analysis/FlowSensitive/Transfer.cpp
+++ clang/lib/Analysis/FlowSensitive/Transfer.cpp
@@ -429,6 +429,9 @@
}
void VisitReturnStmt(const ReturnStmt *S) {
+ if (!Options.ContextSensitiveOpts)
+ return;
+
auto *Ret = S->getRetValue();
if (Ret == nullptr)
return;
@@ -443,6 +446,10 @@
auto *Loc = Env.getReturnStorageLocation();
assert(Loc != nullptr);
+ // FIXME: Support reference-type returns.
+ if (Loc->getType()->isReferenceType())
+ return;
+
// FIXME: Model NRVO.
Env.setValue(*Loc, *Val);
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D140430.484367.patch
Type: text/x-patch
Size: 2295 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20221220/7eef260c/attachment-0001.bin>
More information about the cfe-commits
mailing list