[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