mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-14 11:39:35 +00:00
[clang][dataflow] Ignore assignment where base class's operator is used (#66364)
In C++ it seems it is legit to use base class's operator (e.g. `using Base::operator=`) to perform copy if the base class is the common ancestor of the source and destination object. In such a case we shouldn't try to access fields beyond that of the base class, however such a case seems to be very rare (typical code would implement a copy constructor instead), and could add complexities, so in this patch we simply bail if the method operator's parent class is different from the type of the destination object that this framework recognizes.
This commit is contained in:
parent
f45f1c3585
commit
0612c9b09a
@ -531,6 +531,13 @@ public:
|
||||
auto *LocDst =
|
||||
cast_or_null<RecordStorageLocation>(Env.getStorageLocation(*Arg0));
|
||||
|
||||
// The assignment operators are different from the type of the destination
|
||||
// in this model (i.e. in one of their base classes). This must be very rare
|
||||
// and we just bail.
|
||||
if (Method->getThisObjectType().getCanonicalType().getUnqualifiedType() !=
|
||||
LocDst->getType().getCanonicalType().getUnqualifiedType())
|
||||
return;
|
||||
|
||||
if (LocSrc != nullptr && LocDst != nullptr) {
|
||||
copyRecord(*LocSrc, *LocDst, Env);
|
||||
Env.setStorageLocation(*S, *LocDst);
|
||||
|
@ -2124,6 +2124,30 @@ TEST(TransferTest, AssignmentOperator) {
|
||||
});
|
||||
}
|
||||
|
||||
TEST(TransferTest, AssignmentOperatorFromBase) {
|
||||
// This is a crash repro. We don't model the copy this case, so no
|
||||
// expectations on the copied field of the base class are checked.
|
||||
std::string Code = R"(
|
||||
struct Base {
|
||||
int base;
|
||||
};
|
||||
struct Derived : public Base {
|
||||
using Base::operator=;
|
||||
int derived;
|
||||
};
|
||||
void target(Base B, Derived D) {
|
||||
D.base = 1;
|
||||
D.derived = 1;
|
||||
D = B;
|
||||
// [[p]]
|
||||
}
|
||||
)";
|
||||
runDataflow(
|
||||
Code,
|
||||
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
|
||||
ASTContext &ASTCtx) {});
|
||||
}
|
||||
|
||||
TEST(TransferTest, AssignmentOperatorFromCallResult) {
|
||||
std::string Code = R"(
|
||||
struct A {};
|
||||
|
Loading…
Reference in New Issue
Block a user