aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Analysis/FlowSensitive/Transfer.cpp
diff options
context:
space:
mode:
authormartinboehme <mboehme@google.com>2023-12-18 09:10:03 +0100
committerGitHub <noreply@github.com>2023-12-18 09:10:03 +0100
commitca1034341cfec226c09ff0e473c6ecbcc2a1194c (patch)
tree109ad3d6307f9a701738ef979ecf5e5c7bc919b7 /clang/lib/Analysis/FlowSensitive/Transfer.cpp
parent9bb47f7f8bcc17d90763d201f383d28489b9b071 (diff)
downloadllvm-ca1034341cfec226c09ff0e473c6ecbcc2a1194c.zip
llvm-ca1034341cfec226c09ff0e473c6ecbcc2a1194c.tar.gz
llvm-ca1034341cfec226c09ff0e473c6ecbcc2a1194c.tar.bz2
[clang][dataflow] Fix an issue with `Environment::getResultObjectLocation()`. (#75483)
So far, if there was a chain of record type prvalues, `getResultObjectLocation()` would assign a different result object location to each one. This makes no sense, of course, as all of these prvalues end up initializing the same result object. This patch fixes this by propagating storage locations up through the entire chain of prvalues. The new implementation also has the desirable effect of making it possible to make `getResultObjectLocation()` const, which seems appropriate given that, logically, it is just an accessor.
Diffstat (limited to 'clang/lib/Analysis/FlowSensitive/Transfer.cpp')
-rw-r--r--clang/lib/Analysis/FlowSensitive/Transfer.cpp9
1 files changed, 8 insertions, 1 deletions
diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp
index bbf5f12..3464696 100644
--- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp
+++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp
@@ -489,7 +489,6 @@ public:
if (S->getType()->isRecordType()) {
auto &InitialVal = *cast<RecordValue>(Env.createValue(S->getType()));
Env.setValue(*S, InitialVal);
- copyRecord(InitialVal.getLoc(), Env.getResultObjectLocation(*S), Env);
}
transferInlineCall(S, ConstructorDecl);
@@ -582,6 +581,14 @@ public:
Env.setValue(*S, *ArgVal);
} else if (const FunctionDecl *F = S->getDirectCallee()) {
transferInlineCall(S, F);
+
+ // If this call produces a prvalue of record type, make sure that we have
+ // a `RecordValue` for it. This is required so that
+ // `Environment::getResultObjectLocation()` is able to return a location
+ // for this `CallExpr`.
+ if (S->getType()->isRecordType() && S->isPRValue())
+ if (Env.getValue(*S) == nullptr)
+ refreshRecordValue(*S, Env);
}
}