[PATCH] D101103: [InstSimplify] Treat invariant group insts as bitcasts for load operands
Piotr Padlewski via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 28 02:51:53 PDT 2021
Prazek added a comment.
In D101103#2721429 <https://reviews.llvm.org/D101103#2721429>, @aeubanks wrote:
> looks like the strip is coming from `CodeGenFunction::EmitLValueForField()`:
>
> if (auto *ClassDef = dyn_cast<CXXRecordDecl>(rec)) {
> if (CGM.getCodeGenOpts().StrictVTablePointers &&
> ClassDef->isDynamicClass()) {
> // Getting to any field of dynamic object requires stripping dynamic
> // information provided by invariant.group. This is because accessing
> // fields may leak the real address of dynamic object, which could result
> // in miscompilation when leaked pointer would be compared.
> auto *stripped = Builder.CreateStripInvariantGroup(addr.getPointer());
> addr = Address(stripped, addr.getAlignment());
> }
> }
>
> is this actually true?
It is essentially more complex case of leaking the value of the pointer through comparison (documented in the docs)
struct A {
virtual void foo();
int field;
};
struct B {
void foo() override;
};
external A* clobber(A* a) {
return new(a) B;
}
void bar(A *a) {
int* addr = &a->field;
A* new_a = clobber(a);
if (addr == &new_a->field) {
new_a->foo();
}
}
Here if you don't strip "virtual information" from the pointer before getting the address of the field, the compiler will be able to figure out that the address
of ```a``` and ```new_a``` is the same in the branch, which would result in RAUW of new_a for a, resulting in incorrect devirtualization.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D101103/new/
https://reviews.llvm.org/D101103
More information about the llvm-commits
mailing list