mirror of
https://github.com/intel/llvm.git
synced 2026-01-26 12:26:52 +08:00
[clang][dataflow] Copy records relative to the destination type for c… (#160557)
…opy/move assignments. This mirrors the handling of copy/move constructors. Also fix a couple capitalizations of variables in an adjacent and related test.
This commit is contained in:
@@ -657,7 +657,12 @@ public:
|
||||
if (LocSrc == nullptr || LocDst == nullptr)
|
||||
return;
|
||||
|
||||
copyRecord(*LocSrc, *LocDst, Env);
|
||||
// If the destination object here is of a derived class, `Arg0` may be a
|
||||
// cast of that object to a base class, and the source object may be of a
|
||||
// sibling derived class. To handle these cases, ensure we are copying
|
||||
// only the fields for `Arg0`'s type, not the type of the underlying
|
||||
// `RecordStorageLocation`.
|
||||
copyRecord(*LocSrc, *LocDst, Env, Arg0->getType());
|
||||
|
||||
// The assignment operator can have an arbitrary return type. We model the
|
||||
// return value only if the return type is the same as or a base class of
|
||||
|
||||
@@ -1554,8 +1554,8 @@ TEST(TransferTest, BaseClassInitializerFromSiblingDerivedInstance) {
|
||||
struct DerivedTwo : public Base {
|
||||
int DerivedTwoField;
|
||||
|
||||
DerivedTwo(const DerivedOne& d1)
|
||||
: Base(d1), DerivedTwoField(d1.DerivedOneField) {
|
||||
DerivedTwo(const DerivedOne& D1)
|
||||
: Base(D1), DerivedTwoField(D1.DerivedOneField) {
|
||||
(void)BaseField;
|
||||
}
|
||||
};
|
||||
@@ -1565,7 +1565,34 @@ TEST(TransferTest, BaseClassInitializerFromSiblingDerivedInstance) {
|
||||
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
|
||||
ASTContext &ASTCtx) {
|
||||
// Regression test only; we used to crash when transferring the base
|
||||
// class initializer from the DerivedToBase-cast `d1`.
|
||||
// class initializer from the DerivedToBase-cast `D1`.
|
||||
},
|
||||
LangStandard::lang_cxx17, /*ApplyBuiltinTransfer=*/true, "DerivedTwo");
|
||||
}
|
||||
|
||||
TEST(TransferTest, CopyAssignmentToDerivedToBase) {
|
||||
std::string Code = R"cc(
|
||||
struct Base {};
|
||||
|
||||
struct DerivedOne : public Base {
|
||||
int DerivedOneField;
|
||||
};
|
||||
|
||||
struct DerivedTwo : public Base {
|
||||
int DerivedTwoField;
|
||||
|
||||
explicit DerivedTwo(const DerivedOne& D1) {
|
||||
*static_cast<Base*>(this) = D1;
|
||||
}
|
||||
};
|
||||
)cc";
|
||||
|
||||
runDataflow(
|
||||
Code,
|
||||
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
|
||||
ASTContext &ASTCtx) {
|
||||
// Regression test only; we used to crash when transferring the copy
|
||||
// assignment operator in the constructor for `DerivedTwo`.
|
||||
},
|
||||
LangStandard::lang_cxx17, /*ApplyBuiltinTransfer=*/true, "DerivedTwo");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user