[clang] [clang][dataflow] Model assignment to derived class from base. (PR #85064)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 18 07:56:30 PDT 2024
================
@@ -35,45 +69,27 @@ void clang::dataflow::copyRecord(RecordStorageLocation &Src,
});
assert(compatibleTypes);
- for (auto [Field, DstFieldLoc] : Dst.children()) {
- StorageLocation *SrcFieldLoc = Src.getChild(*Field);
-
- assert(Field->getType()->isReferenceType() ||
- (SrcFieldLoc != nullptr && DstFieldLoc != nullptr));
-
- if (Field->getType()->isRecordType()) {
- copyRecord(cast<RecordStorageLocation>(*SrcFieldLoc),
- cast<RecordStorageLocation>(*DstFieldLoc), Env);
- } else if (Field->getType()->isReferenceType()) {
- Dst.setChild(*Field, SrcFieldLoc);
- } else {
- if (Value *Val = Env.getValue(*SrcFieldLoc))
- Env.setValue(*DstFieldLoc, *Val);
- else
- Env.clearValue(*DstFieldLoc);
- }
- }
-
- for (const auto &[Name, SynthFieldLoc] : Src.synthetic_fields()) {
- if (SynthFieldLoc->getType()->isRecordType()) {
- copyRecord(*cast<RecordStorageLocation>(SynthFieldLoc),
- cast<RecordStorageLocation>(Dst.getSyntheticField(Name)), Env);
- } else {
- if (Value *Val = Env.getValue(*SynthFieldLoc))
- Env.setValue(Dst.getSyntheticField(Name), *Val);
- else
- Env.clearValue(Dst.getSyntheticField(Name));
- }
+ if (SrcType == DstType || (SrcDecl != nullptr && DstDecl != nullptr &&
+ SrcDecl->isDerivedFrom(DstDecl))) {
+ for (auto [Field, DstFieldLoc] : Dst.children())
----------------
martinboehme wrote:
The two `lambda()` calls would be in the if and the else branch, respectively? I.e.
```cxx
if (SrcType == DstType || (SrcDecl != nullptr && DstDecl != nullptr &&
SrcDecl->isDerivedFrom(DstDecl))) {
lambda(Dst);
// And synthetic fields
} else {
lambda(Src);
// And synthetic fields
}
```
The problem is that this doesn't work because it changes behavior. This is what we have in the if branch right now:
```cxx
for (auto [Field, DstFieldLoc] : Dst.children())
copyField(Field, Src.getChild(*Field), DstFieldLoc, Dst, Env);
```
Changing this to `lambda(Dst)` would mean that the behavior becomes:
```
for (auto [Field, SrcFieldLoc] : Dst.children())
copyField(Field, SrcFieldLoc, Dst.getChild(*Field), Dst, Env);
```
Note that the name `SrcFieldLoc` is now essentially wrong, and the `copyField()` becomes a no-op because it's copying a field to itself.
https://github.com/llvm/llvm-project/pull/85064
More information about the cfe-commits
mailing list