diff options
author | martinboehme <mboehme@google.com> | 2023-12-18 09:10:03 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-18 09:10:03 +0100 |
commit | ca1034341cfec226c09ff0e473c6ecbcc2a1194c (patch) | |
tree | 109ad3d6307f9a701738ef979ecf5e5c7bc919b7 /clang/lib/Analysis/FlowSensitive/Transfer.cpp | |
parent | 9bb47f7f8bcc17d90763d201f383d28489b9b071 (diff) | |
download | llvm-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.cpp | 9 |
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); } } |