[PATCH] Use GEPs correctly when adjusting "this" in MicrosoftCXXABI

Timur Iskhodzhanov timurrrr at google.com
Wed Oct 23 07:16:25 PDT 2013


2013/10/23 Richard Smith <richard at metafoo.co.uk>:
>
>
> ================
> Comment at: lib/CodeGen/MicrosoftCXXABI.cpp:636-638
> @@ +635,5 @@
> +    if (ML.VBase) {
> +      // Non-virtual adjustment might result in a pointer outside the allocated
> +      // object, e.g. if the final overrider class is laid out after the virtual
> +      // base that declares a method in the most derived class.
> +      // FIXME: Update the code that emits this adjustment in thunks prologues.
> ----------------
> Richard Smith wrote:
>> How can this give an offset that takes you outside the complete object?
> OK, I think I see. During construction or destruction, we have a static offset based on an assumption that vbases are laid out as if we are the most-derived type, and then an additional offset to correct that assumption. And the vbase layout can change between this class and the most-derived class such that the location where we thought the vbase would be is no longer within the object. Something like:
>
>   struct A { int x, y; };
>   struct B : virtual A { int n; };
>   struct C : virtual A, virtual B {};
>
>   |-- complete-object layout of B --|
>   |-- B members --| |-- A members --|
>
>   |-- complete-object layout of C --|
>   |-- A members --| |-- B members --|
>
> During the construction of B (within the construction of a C complete object), if we want to access the 'y' member, we add an offset of 8 to get to 'y' assuming we're using B's complete-object layout, then subtract off 12 to adjust for the A vbase not being at the offset where we expected. And that transiently takes us outside the object. Is that it?

You were close :)
Please see Test4::X in
test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp for a
good example of when it's needed.

> Ugh.
>
>
> http://llvm-reviews.chandlerc.com/D1977

2013/10/23 Richard Smith <richard at metafoo.co.uk>:
>
>
> ================
> Comment at: lib/CodeGen/MicrosoftCXXABI.cpp:636-638
> @@ +635,5 @@
> +    if (ML.VBase) {
> +      // Non-virtual adjustment might result in a pointer outside the allocated
> +      // object, e.g. if the final overrider class is laid out after the virtual
> +      // base that declares a method in the most derived class.
> +      // FIXME: Update the code that emits this adjustment in thunks prologues.
> ----------------
> Richard Smith wrote:
>> How can this give an offset that takes you outside the complete object?
> OK, I think I see. During construction or destruction, we have a static offset based on an assumption that vbases are laid out as if we are the most-derived type, and then an additional offset to correct that assumption. And the vbase layout can change between this class and the most-derived class such that the location where we thought the vbase would be is no longer within the object. Something like:
>
>   struct A { int x, y; };
>   struct B : virtual A { int n; };
>   struct C : virtual A, virtual B {};
>
>   |-- complete-object layout of B --|
>   |-- B members --| |-- A members --|
>
>   |-- complete-object layout of C --|
>   |-- A members --| |-- B members --|
>
> During the construction of B (within the construction of a C complete object), if we want to access the 'y' member, we add an offset of 8 to get to 'y' assuming we're using B's complete-object layout, then subtract off 12 to adjust for the A vbase not being at the offset where we expected. And that transiently takes us outside the object. Is that it?
>
> Ugh.
>
>
> http://llvm-reviews.chandlerc.com/D1977




More information about the cfe-commits mailing list