[MS] Apply adjustments after storing 'this'
Summary:
The MS ABI convention is that the 'this' pointer on entry is the address
of the vfptr that was used to make the virtual method call. In other
words, the pointer on entry always points to the base subobject that
introduced the virtual method. Consider this hierarchy:
struct A { virtual void f() = 0; };
struct B { virtual void g() = 0; };
struct C : A, B {
void f() override;
void g() override;
};
On entry to C::g, [ER]CX will contain the address of C's B subobject,
and C::g will have to subtract sizeof(A) to recover a pointer to C.
Before this change, we applied this adjustment in the prologue and
stored the new value into the "this" local variable alloca used for
debug info. However, MSVC does not do this, presumably because it is
often profitable to fold the adjustment into later field accesses. This
creates a problem, because the debugger expects the variable to be
unadjusted. Unfortunately, CodeView doesn't have anything like DWARF
expressions for computing variables that aren't in the program anymore,
so we have to declare 'this' to be the unadjusted value if we want the
debugger to see the right value.
This has the side benefit that, in optimized builds, the 'this' pointer
will usually be available on function entry because it doesn't require
any adjustment.
Reviewers: hans
Subscribers: aprantl, cfe-commits
Differential Revision: https://reviews.llvm.org/D40109
llvm-svn: 318440
2017-11-17 03:09:36 +08:00
|
|
|
// RUN: %clang_cc1 %s -fno-rtti -std=c++11 -Wno-inaccessible-base -triple=i386-pc-win32 -emit-llvm -o %t
|
2013-10-17 02:24:06 +08:00
|
|
|
// RUN: FileCheck %s < %t
|
|
|
|
// RUN: FileCheck --check-prefix=CHECK2 %s < %t
|
2013-06-29 04:45:28 +08:00
|
|
|
|
2013-10-10 02:16:58 +08:00
|
|
|
// For now, just make sure x86_64 doesn't crash.
|
[MS] Apply adjustments after storing 'this'
Summary:
The MS ABI convention is that the 'this' pointer on entry is the address
of the vfptr that was used to make the virtual method call. In other
words, the pointer on entry always points to the base subobject that
introduced the virtual method. Consider this hierarchy:
struct A { virtual void f() = 0; };
struct B { virtual void g() = 0; };
struct C : A, B {
void f() override;
void g() override;
};
On entry to C::g, [ER]CX will contain the address of C's B subobject,
and C::g will have to subtract sizeof(A) to recover a pointer to C.
Before this change, we applied this adjustment in the prologue and
stored the new value into the "this" local variable alloca used for
debug info. However, MSVC does not do this, presumably because it is
often profitable to fold the adjustment into later field accesses. This
creates a problem, because the debugger expects the variable to be
unadjusted. Unfortunately, CodeView doesn't have anything like DWARF
expressions for computing variables that aren't in the program anymore,
so we have to declare 'this' to be the unadjusted value if we want the
debugger to see the right value.
This has the side benefit that, in optimized builds, the 'this' pointer
will usually be available on function entry because it doesn't require
any adjustment.
Reviewers: hans
Subscribers: aprantl, cfe-commits
Differential Revision: https://reviews.llvm.org/D40109
llvm-svn: 318440
2017-11-17 03:09:36 +08:00
|
|
|
// RUN: %clang_cc1 %s -fno-rtti -std=c++11 -Wno-inaccessible-base -triple=x86_64-pc-win32 -emit-llvm -o %t
|
2013-10-10 02:16:58 +08:00
|
|
|
|
2013-08-21 14:25:03 +08:00
|
|
|
struct VBase {
|
2013-10-10 02:16:58 +08:00
|
|
|
virtual ~VBase();
|
2013-08-21 14:25:03 +08:00
|
|
|
virtual void foo();
|
|
|
|
virtual void bar();
|
|
|
|
int field;
|
2013-06-29 04:45:28 +08:00
|
|
|
};
|
2013-08-21 14:25:03 +08:00
|
|
|
|
|
|
|
struct B : virtual VBase {
|
2013-09-27 22:48:01 +08:00
|
|
|
B();
|
2013-10-10 02:16:58 +08:00
|
|
|
virtual ~B();
|
2013-08-21 14:25:03 +08:00
|
|
|
virtual void foo();
|
|
|
|
virtual void bar();
|
2013-06-29 04:45:28 +08:00
|
|
|
};
|
|
|
|
|
2013-09-27 22:48:01 +08:00
|
|
|
B::B() {
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK-LABEL: define dso_local x86_thiscallcc %struct.B* @"??0B@@QAE@XZ"
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK: %[[THIS:.*]] = load %struct.B*, %struct.B**
|
2013-09-27 22:48:01 +08:00
|
|
|
// CHECK: br i1 %{{.*}}, label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]]
|
2013-10-10 02:16:58 +08:00
|
|
|
|
|
|
|
// Don't check the INIT_VBASES case as it's covered by the ctor tests.
|
|
|
|
|
2013-09-27 22:48:01 +08:00
|
|
|
// CHECK: %[[SKIP_VBASES]]
|
|
|
|
// CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 0
|
2013-10-10 02:16:58 +08:00
|
|
|
// ...
|
|
|
|
// CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 %{{.*}}
|
2014-12-04 05:00:21 +08:00
|
|
|
// CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK: store i32 (...)** bitcast ({ [3 x i8*] }* @"??_7B@@6B@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
|
2013-10-10 02:16:58 +08:00
|
|
|
|
|
|
|
// Initialize vtorDisp:
|
|
|
|
// CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 0
|
2013-10-10 02:16:58 +08:00
|
|
|
// ...
|
|
|
|
// CHECK: %[[VBASE_OFFSET:.*]] = add nsw i32 0, %{{.*}}
|
|
|
|
// CHECK: %[[VTORDISP_VAL:.*]] = sub i32 %[[VBASE_OFFSET]], 8
|
|
|
|
// CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 %[[VBASE_OFFSET]]
|
|
|
|
// CHECK: %[[VTORDISP_i8:.*]] = getelementptr i8, i8* %[[VBASE_i8]], i32 -4
|
2013-10-10 02:16:58 +08:00
|
|
|
// CHECK: %[[VTORDISP_PTR:.*]] = bitcast i8* %[[VTORDISP_i8]] to i32*
|
|
|
|
// CHECK: store i32 %[[VTORDISP_VAL]], i32* %[[VTORDISP_PTR]]
|
|
|
|
|
|
|
|
// CHECK: ret
|
|
|
|
}
|
|
|
|
|
|
|
|
B::~B() {
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK-LABEL: define dso_local x86_thiscallcc void @"??1B@@UAE@XZ"
|
[MS] Apply adjustments after storing 'this'
Summary:
The MS ABI convention is that the 'this' pointer on entry is the address
of the vfptr that was used to make the virtual method call. In other
words, the pointer on entry always points to the base subobject that
introduced the virtual method. Consider this hierarchy:
struct A { virtual void f() = 0; };
struct B { virtual void g() = 0; };
struct C : A, B {
void f() override;
void g() override;
};
On entry to C::g, [ER]CX will contain the address of C's B subobject,
and C::g will have to subtract sizeof(A) to recover a pointer to C.
Before this change, we applied this adjustment in the prologue and
stored the new value into the "this" local variable alloca used for
debug info. However, MSVC does not do this, presumably because it is
often profitable to fold the adjustment into later field accesses. This
creates a problem, because the debugger expects the variable to be
unadjusted. Unfortunately, CodeView doesn't have anything like DWARF
expressions for computing variables that aren't in the program anymore,
so we have to declare 'this' to be the unadjusted value if we want the
debugger to see the right value.
This has the side benefit that, in optimized builds, the 'this' pointer
will usually be available on function entry because it doesn't require
any adjustment.
Reviewers: hans
Subscribers: aprantl, cfe-commits
Differential Revision: https://reviews.llvm.org/D40109
llvm-svn: 318440
2017-11-17 03:09:36 +08:00
|
|
|
// Store initial this:
|
|
|
|
// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.B*
|
|
|
|
// CHECK: store %struct.B* %{{.*}}, %struct.B** %[[THIS_ADDR]], align 4
|
|
|
|
// Reload and adjust the this parameter:
|
|
|
|
// CHECK: %[[THIS_RELOAD:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
|
|
|
|
// CHECK: %[[THIS_UNADJ_i8:.*]] = bitcast %struct.B* %[[THIS_RELOAD]] to i8*
|
|
|
|
// CHECK: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_UNADJ_i8]], i32 -8
|
|
|
|
// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJ_i8]] to %struct.B*
|
2013-10-10 02:16:58 +08:00
|
|
|
|
|
|
|
// Restore the vfptr that could have been changed by a subclass.
|
|
|
|
// CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 0
|
2013-10-10 02:16:58 +08:00
|
|
|
// ...
|
2013-09-27 22:48:01 +08:00
|
|
|
// CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 %{{.*}}
|
2014-12-04 05:00:21 +08:00
|
|
|
// CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK: store i32 (...)** bitcast ({ [3 x i8*] }* @"??_7B@@6B@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
|
2013-10-10 02:16:58 +08:00
|
|
|
|
|
|
|
// Initialize vtorDisp:
|
|
|
|
// CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 0
|
2013-10-10 02:16:58 +08:00
|
|
|
// ...
|
|
|
|
// CHECK: %[[VBASE_OFFSET:.*]] = add nsw i32 0, %{{.*}}
|
|
|
|
// CHECK: %[[VTORDISP_VAL:.*]] = sub i32 %[[VBASE_OFFSET]], 8
|
|
|
|
// CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 %[[VBASE_OFFSET]]
|
|
|
|
// CHECK: %[[VTORDISP_i8:.*]] = getelementptr i8, i8* %[[VBASE_i8]], i32 -4
|
2013-10-10 02:16:58 +08:00
|
|
|
// CHECK: %[[VTORDISP_PTR:.*]] = bitcast i8* %[[VTORDISP_i8]] to i32*
|
|
|
|
// CHECK: store i32 %[[VTORDISP_VAL]], i32* %[[VTORDISP_PTR]]
|
|
|
|
|
|
|
|
foo(); // Avoid the "trivial destructor" optimization.
|
|
|
|
|
2013-09-27 22:48:01 +08:00
|
|
|
// CHECK: ret
|
2013-10-17 02:24:06 +08:00
|
|
|
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK2-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"??_DB@@QAEXXZ"(%struct.B*
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK2: %[[THIS:.*]] = load %struct.B*, %struct.B** {{.*}}
|
2013-10-17 02:24:06 +08:00
|
|
|
// CHECK2: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK2: %[[B_i8:.*]] = getelementptr i8, i8* %[[THIS_i8]], i32 8
|
2013-10-17 02:24:06 +08:00
|
|
|
// CHECK2: %[[B:.*]] = bitcast i8* %[[B_i8]] to %struct.B*
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK2: call x86_thiscallcc void @"??1B@@UAE@XZ"(%struct.B* %[[B]])
|
2013-10-17 02:24:06 +08:00
|
|
|
// CHECK2: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
// CHECK2: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 8
|
2013-10-17 02:24:06 +08:00
|
|
|
// CHECK2: %[[VBASE:.*]] = bitcast i8* %[[VBASE_i8]] to %struct.VBase*
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK2: call x86_thiscallcc void @"??1VBase@@UAE@XZ"(%struct.VBase* %[[VBASE]])
|
2013-10-17 02:24:06 +08:00
|
|
|
// CHECK2: ret
|
|
|
|
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK2-LABEL: define linkonce_odr dso_local x86_thiscallcc i8* @"??_GB@@UAEPAXI@Z"
|
[MS] Apply adjustments after storing 'this'
Summary:
The MS ABI convention is that the 'this' pointer on entry is the address
of the vfptr that was used to make the virtual method call. In other
words, the pointer on entry always points to the base subobject that
introduced the virtual method. Consider this hierarchy:
struct A { virtual void f() = 0; };
struct B { virtual void g() = 0; };
struct C : A, B {
void f() override;
void g() override;
};
On entry to C::g, [ER]CX will contain the address of C's B subobject,
and C::g will have to subtract sizeof(A) to recover a pointer to C.
Before this change, we applied this adjustment in the prologue and
stored the new value into the "this" local variable alloca used for
debug info. However, MSVC does not do this, presumably because it is
often profitable to fold the adjustment into later field accesses. This
creates a problem, because the debugger expects the variable to be
unadjusted. Unfortunately, CodeView doesn't have anything like DWARF
expressions for computing variables that aren't in the program anymore,
so we have to declare 'this' to be the unadjusted value if we want the
debugger to see the right value.
This has the side benefit that, in optimized builds, the 'this' pointer
will usually be available on function entry because it doesn't require
any adjustment.
Reviewers: hans
Subscribers: aprantl, cfe-commits
Differential Revision: https://reviews.llvm.org/D40109
llvm-svn: 318440
2017-11-17 03:09:36 +08:00
|
|
|
// CHECK2: store %struct.B* %{{.*}}, %struct.B** %[[THIS_ADDR:.*]], align 4
|
|
|
|
// CHECK2: %[[THIS:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
|
|
|
|
// CHECK2: %[[THIS_PARAM_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK2: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_PARAM_i8:.*]], i32 -8
|
2013-10-17 02:24:06 +08:00
|
|
|
// CHECK2: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.B*
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK2: call x86_thiscallcc void @"??_DB@@QAEXXZ"(%struct.B* %[[THIS]])
|
2013-10-17 02:24:06 +08:00
|
|
|
// ...
|
|
|
|
// CHECK2: ret
|
2013-09-27 22:48:01 +08:00
|
|
|
}
|
|
|
|
|
2013-08-21 14:25:03 +08:00
|
|
|
void B::foo() {
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK-LABEL: define dso_local x86_thiscallcc void @"?foo@B@@UAEXXZ"(i8*
|
2013-08-21 14:25:03 +08:00
|
|
|
//
|
|
|
|
// B::foo gets 'this' cast to VBase* in ECX (i.e. this+8) so we
|
|
|
|
// need to adjust 'this' before use.
|
|
|
|
//
|
2018-01-23 06:29:24 +08:00
|
|
|
// Coerce this to correct type:
|
|
|
|
// CHECK: %[[THIS_STORE:.*]] = alloca %struct.B*
|
2017-12-22 04:52:59 +08:00
|
|
|
// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.B*
|
2018-01-23 06:29:24 +08:00
|
|
|
// CHECK: %[[COERCE_VAL:.*]] = bitcast i8* %{{.*}} to %struct.B*
|
|
|
|
// CHECK: store %struct.B* %[[COERCE_VAL]], %struct.B** %[[THIS_STORE]], align 4
|
|
|
|
//
|
|
|
|
// Store initial this:
|
|
|
|
// CHECK: %[[THIS_INIT:.*]] = load %struct.B*, %struct.B** %[[THIS_STORE]]
|
|
|
|
// CHECK: store %struct.B* %[[THIS_INIT]], %struct.B** %[[THIS_ADDR]], align 4
|
[MS] Apply adjustments after storing 'this'
Summary:
The MS ABI convention is that the 'this' pointer on entry is the address
of the vfptr that was used to make the virtual method call. In other
words, the pointer on entry always points to the base subobject that
introduced the virtual method. Consider this hierarchy:
struct A { virtual void f() = 0; };
struct B { virtual void g() = 0; };
struct C : A, B {
void f() override;
void g() override;
};
On entry to C::g, [ER]CX will contain the address of C's B subobject,
and C::g will have to subtract sizeof(A) to recover a pointer to C.
Before this change, we applied this adjustment in the prologue and
stored the new value into the "this" local variable alloca used for
debug info. However, MSVC does not do this, presumably because it is
often profitable to fold the adjustment into later field accesses. This
creates a problem, because the debugger expects the variable to be
unadjusted. Unfortunately, CodeView doesn't have anything like DWARF
expressions for computing variables that aren't in the program anymore,
so we have to declare 'this' to be the unadjusted value if we want the
debugger to see the right value.
This has the side benefit that, in optimized builds, the 'this' pointer
will usually be available on function entry because it doesn't require
any adjustment.
Reviewers: hans
Subscribers: aprantl, cfe-commits
Differential Revision: https://reviews.llvm.org/D40109
llvm-svn: 318440
2017-11-17 03:09:36 +08:00
|
|
|
//
|
|
|
|
// Reload and adjust the this parameter:
|
|
|
|
// CHECK: %[[THIS_RELOAD:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
|
|
|
|
// CHECK: %[[THIS_UNADJ_i8:.*]] = bitcast %struct.B* %[[THIS_RELOAD]] to i8*
|
|
|
|
// CHECK: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_UNADJ_i8]], i32 -8
|
|
|
|
// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJ_i8]] to %struct.B*
|
2013-08-21 14:25:03 +08:00
|
|
|
|
|
|
|
field = 42;
|
|
|
|
// CHECK: %[[THIS8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS8]], i32 0
|
2014-10-23 01:26:00 +08:00
|
|
|
// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR8]]
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 1
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK: %[[VBOFFSET32:.*]] = load i32, i32* %[[VBENTRY]]
|
2013-08-21 14:25:03 +08:00
|
|
|
// CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]]
|
|
|
|
// CHECK: %[[THIS8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS8]], i32 %[[VBOFFSET]]
|
2013-08-21 14:25:03 +08:00
|
|
|
// CHECK: %[[VBASE:.*]] = bitcast i8* %[[VBASE_i8]] to %struct.VBase*
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[FIELD:.*]] = getelementptr inbounds %struct.VBase, %struct.VBase* %[[VBASE]], i32 0, i32 1
|
2013-08-21 14:25:03 +08:00
|
|
|
// CHECK: store i32 42, i32* %[[FIELD]], align 4
|
|
|
|
//
|
|
|
|
// CHECK: ret void
|
|
|
|
}
|
|
|
|
|
|
|
|
void call_vbase_bar(B *obj) {
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK-LABEL: define dso_local void @"?call_vbase_bar@@YAXPAUB@@@Z"(%struct.B* %obj)
|
2013-08-21 14:25:03 +08:00
|
|
|
// CHECK: %[[OBJ:.*]] = load %struct.B
|
|
|
|
|
|
|
|
obj->bar();
|
|
|
|
// When calling a vbase's virtual method, one needs to adjust 'this'
|
|
|
|
// at the caller site.
|
|
|
|
//
|
|
|
|
// CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8*
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 0
|
2014-10-23 01:26:00 +08:00
|
|
|
// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR8]]
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 1
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK: %[[VBOFFSET32:.*]] = load i32, i32* %[[VBENTRY]]
|
2013-08-21 14:25:03 +08:00
|
|
|
// CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]]
|
2018-02-06 07:09:13 +08:00
|
|
|
// CHECK: %[[VBASE:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 %[[VBOFFSET]]
|
2013-08-21 14:25:03 +08:00
|
|
|
//
|
|
|
|
// CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8*
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 0
|
2014-10-23 01:26:00 +08:00
|
|
|
// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR8]]
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 1
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK: %[[VBOFFSET32:.*]] = load i32, i32* %[[VBENTRY]]
|
2013-08-21 14:25:03 +08:00
|
|
|
// CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]]
|
2018-02-06 07:09:13 +08:00
|
|
|
// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 %[[VBOFFSET]]
|
|
|
|
// CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VBASE_i8]] to void (i8*)***
|
|
|
|
// CHECK: %[[VFTABLE:.*]] = load void (i8*)**, void (i8*)*** %[[VFPTR]]
|
|
|
|
// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (i8*)*, void (i8*)** %[[VFTABLE]], i64 2
|
|
|
|
// CHECK: %[[VFUN_VALUE:.*]] = load void (i8*)*, void (i8*)** %[[VFUN]]
|
2013-08-21 14:25:03 +08:00
|
|
|
//
|
|
|
|
// CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](i8* %[[VBASE]])
|
|
|
|
//
|
|
|
|
// CHECK: ret void
|
|
|
|
}
|
2013-10-09 17:23:58 +08:00
|
|
|
|
2013-10-17 02:24:06 +08:00
|
|
|
void delete_B(B *obj) {
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK-LABEL: define dso_local void @"?delete_B@@YAXPAUB@@@Z"(%struct.B* %obj)
|
2013-10-17 02:24:06 +08:00
|
|
|
// CHECK: %[[OBJ:.*]] = load %struct.B
|
|
|
|
|
|
|
|
delete obj;
|
|
|
|
// CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8*
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 0
|
2014-10-23 01:26:00 +08:00
|
|
|
// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR8]]
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 1
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK: %[[VBOFFSET32:.*]] = load i32, i32* %[[VBENTRY]]
|
2013-10-17 02:24:06 +08:00
|
|
|
// CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]]
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 %[[VBOFFSET]]
|
2018-02-06 07:09:13 +08:00
|
|
|
// CHECK: %[[VBASE:.*]] = bitcast i8* %[[VBASE_i8]] to %struct.B*
|
2013-10-17 02:24:06 +08:00
|
|
|
//
|
|
|
|
// CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8*
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 0
|
2014-10-23 01:26:00 +08:00
|
|
|
// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR8]]
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 1
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK: %[[VBOFFSET32:.*]] = load i32, i32* %[[VBENTRY]]
|
2013-10-17 02:24:06 +08:00
|
|
|
// CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]]
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 %[[VBOFFSET]]
|
2018-02-06 07:09:13 +08:00
|
|
|
// CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VBASE_i8]] to i8* (%struct.B*, i32)***
|
|
|
|
// CHECK: %[[VFTABLE:.*]] = load i8* (%struct.B*, i32)**, i8* (%struct.B*, i32)*** %[[VFPTR]]
|
|
|
|
// CHECK: %[[VFUN:.*]] = getelementptr inbounds i8* (%struct.B*, i32)*, i8* (%struct.B*, i32)** %[[VFTABLE]], i64 0
|
|
|
|
// CHECK: %[[VFUN_VALUE:.*]] = load i8* (%struct.B*, i32)*, i8* (%struct.B*, i32)** %[[VFUN]]
|
2013-10-17 02:24:06 +08:00
|
|
|
//
|
2014-11-01 04:09:12 +08:00
|
|
|
// CHECK: call x86_thiscallcc i8* %[[VFUN_VALUE]](%struct.B* %[[VBASE]], i32 1)
|
2013-10-17 02:24:06 +08:00
|
|
|
// CHECK: ret void
|
|
|
|
}
|
|
|
|
|
|
|
|
void call_complete_dtor() {
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK-LABEL: define dso_local void @"?call_complete_dtor@@YAXXZ"
|
2013-10-17 02:24:06 +08:00
|
|
|
B b;
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK: call x86_thiscallcc %struct.B* @"??0B@@QAE@XZ"(%struct.B* %[[B:.*]], i32 1)
|
2013-10-17 02:24:06 +08:00
|
|
|
// CHECK-NOT: getelementptr
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK: call x86_thiscallcc void @"??_DB@@QAEXXZ"(%struct.B* %[[B]])
|
2013-10-17 02:24:06 +08:00
|
|
|
// CHECK: ret
|
|
|
|
}
|
|
|
|
|
2014-03-07 17:34:59 +08:00
|
|
|
struct C : B {
|
2013-10-09 17:23:58 +08:00
|
|
|
C();
|
|
|
|
// has an implicit vdtor.
|
|
|
|
};
|
|
|
|
|
|
|
|
// Used to crash on an assertion.
|
2013-10-17 02:24:06 +08:00
|
|
|
C::C() {
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK-LABEL: define dso_local x86_thiscallcc %struct.C* @"??0C@@QAE@XZ"
|
2013-10-17 02:24:06 +08:00
|
|
|
}
|
2013-10-10 02:16:58 +08:00
|
|
|
|
|
|
|
namespace multiple_vbases {
|
|
|
|
struct A {
|
|
|
|
virtual void a();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B {
|
|
|
|
virtual void b();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct C {
|
|
|
|
virtual void c();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct D : virtual A, virtual B, virtual C {
|
|
|
|
virtual void a();
|
|
|
|
virtual void b();
|
|
|
|
virtual void c();
|
|
|
|
D();
|
|
|
|
};
|
|
|
|
|
|
|
|
D::D() {
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK-LABEL: define dso_local x86_thiscallcc %"struct.multiple_vbases::D"* @"??0D@multiple_vbases@@QAE@XZ"
|
2013-10-10 02:16:58 +08:00
|
|
|
// Just make sure we emit 3 vtordisps after initializing vfptrs.
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7D@multiple_vbases@@6BA@1@@" to i32 (...)**), i32 (...)*** %{{.*}}
|
|
|
|
// CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7D@multiple_vbases@@6BB@1@@" to i32 (...)**), i32 (...)*** %{{.*}}
|
|
|
|
// CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7D@multiple_vbases@@6BC@1@@" to i32 (...)**), i32 (...)*** %{{.*}}
|
2013-10-10 02:16:58 +08:00
|
|
|
// ...
|
|
|
|
// CHECK: store i32 %{{.*}}, i32* %{{.*}}
|
|
|
|
// CHECK: store i32 %{{.*}}, i32* %{{.*}}
|
|
|
|
// CHECK: store i32 %{{.*}}, i32* %{{.*}}
|
|
|
|
// CHECK: ret
|
|
|
|
}
|
2013-10-17 02:24:06 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
namespace diamond {
|
|
|
|
struct A {
|
|
|
|
A();
|
|
|
|
virtual ~A();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B : virtual A {
|
|
|
|
B();
|
|
|
|
~B();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct C : virtual A {
|
|
|
|
C();
|
|
|
|
~C();
|
|
|
|
int c1, c2, c3;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Z {
|
|
|
|
int z;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct D : virtual Z, B, C {
|
|
|
|
D();
|
|
|
|
~D();
|
|
|
|
} d;
|
|
|
|
|
|
|
|
D::~D() {
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK-LABEL: define dso_local x86_thiscallcc void @"??1D@diamond@@UAE@XZ"(%"struct.diamond::D"*{{.*}})
|
[MS] Apply adjustments after storing 'this'
Summary:
The MS ABI convention is that the 'this' pointer on entry is the address
of the vfptr that was used to make the virtual method call. In other
words, the pointer on entry always points to the base subobject that
introduced the virtual method. Consider this hierarchy:
struct A { virtual void f() = 0; };
struct B { virtual void g() = 0; };
struct C : A, B {
void f() override;
void g() override;
};
On entry to C::g, [ER]CX will contain the address of C's B subobject,
and C::g will have to subtract sizeof(A) to recover a pointer to C.
Before this change, we applied this adjustment in the prologue and
stored the new value into the "this" local variable alloca used for
debug info. However, MSVC does not do this, presumably because it is
often profitable to fold the adjustment into later field accesses. This
creates a problem, because the debugger expects the variable to be
unadjusted. Unfortunately, CodeView doesn't have anything like DWARF
expressions for computing variables that aren't in the program anymore,
so we have to declare 'this' to be the unadjusted value if we want the
debugger to see the right value.
This has the side benefit that, in optimized builds, the 'this' pointer
will usually be available on function entry because it doesn't require
any adjustment.
Reviewers: hans
Subscribers: aprantl, cfe-commits
Differential Revision: https://reviews.llvm.org/D40109
llvm-svn: 318440
2017-11-17 03:09:36 +08:00
|
|
|
// Store initial this:
|
|
|
|
// CHECK: %[[THIS_ADDR:.*]] = alloca %"struct.diamond::D"*
|
|
|
|
// CHECK: store %"struct.diamond::D"* %{{.*}}, %"struct.diamond::D"** %[[THIS_ADDR]], align 4
|
|
|
|
//
|
|
|
|
// Reload and adjust the this parameter:
|
|
|
|
// CHECK: %[[THIS_RELOAD:.*]] = load %"struct.diamond::D"*, %"struct.diamond::D"** %[[THIS_ADDR]]
|
|
|
|
// CHECK: %[[THIS_UNADJ_i8:.*]] = bitcast %"struct.diamond::D"* %[[THIS_RELOAD]] to i8*
|
|
|
|
// CHECK: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_UNADJ_i8]], i32 -24
|
|
|
|
// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJ_i8]] to %"struct.diamond::D"*
|
|
|
|
//
|
2013-10-17 02:24:06 +08:00
|
|
|
// CHECK: %[[D_i8:.*]] = bitcast %"struct.diamond::D"* %[[THIS]] to i8*
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
// CHECK: %[[C_i8:.*]] = getelementptr inbounds i8, i8* %[[D_i8]], i32 4
|
2013-10-17 02:24:06 +08:00
|
|
|
// CHECK: %[[C:.*]] = bitcast i8* %[[C_i8]] to %"struct.diamond::C"*
|
|
|
|
// CHECK: %[[C_i8:.*]] = bitcast %"struct.diamond::C"* %[[C]] to i8*
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[ARG_i8:.*]] = getelementptr i8, i8* %{{.*}}, i32 16
|
2013-10-17 02:24:06 +08:00
|
|
|
// FIXME: We might consider changing the dtor this parameter type to i8*.
|
|
|
|
// CHECK: %[[ARG:.*]] = bitcast i8* %[[ARG_i8]] to %"struct.diamond::C"*
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK: call x86_thiscallcc void @"??1C@diamond@@UAE@XZ"(%"struct.diamond::C"* %[[ARG]])
|
2013-10-17 02:24:06 +08:00
|
|
|
|
|
|
|
// CHECK: %[[B:.*]] = bitcast %"struct.diamond::D"* %[[THIS]] to %"struct.diamond::B"*
|
|
|
|
// CHECK: %[[B_i8:.*]] = bitcast %"struct.diamond::B"* %[[B]] to i8*
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[ARG_i8:.*]] = getelementptr i8, i8* %[[B_i8]], i32 4
|
2013-10-17 02:24:06 +08:00
|
|
|
// CHECK: %[[ARG:.*]] = bitcast i8* %[[ARG_i8]] to %"struct.diamond::B"*
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK: call x86_thiscallcc void @"??1B@diamond@@UAE@XZ"(%"struct.diamond::B"* %[[ARG]])
|
2013-10-17 02:24:06 +08:00
|
|
|
// CHECK: ret void
|
|
|
|
}
|
2013-10-10 02:16:58 +08:00
|
|
|
|
|
|
|
}
|
2014-01-14 06:57:31 +08:00
|
|
|
|
|
|
|
namespace test2 {
|
|
|
|
struct A { A(); };
|
|
|
|
struct B : virtual A { B() {} };
|
|
|
|
struct C : B, A { C() {} };
|
|
|
|
|
|
|
|
// PR18435: Order mattered here. We were generating code for the delegating
|
|
|
|
// call to B() from C().
|
|
|
|
void callC() { C x; }
|
|
|
|
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc %"struct.test2::C"* @"??0C@test2@@QAE@XZ"
|
2014-01-14 06:57:31 +08:00
|
|
|
// CHECK: (%"struct.test2::C"* returned %this, i32 %is_most_derived)
|
|
|
|
// CHECK: br i1
|
|
|
|
// Virtual bases
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK: call x86_thiscallcc %"struct.test2::A"* @"??0A@test2@@QAE@XZ"(%"struct.test2::A"* %{{.*}})
|
2014-01-14 06:57:31 +08:00
|
|
|
// CHECK: br label
|
|
|
|
// Non-virtual bases
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK: call x86_thiscallcc %"struct.test2::B"* @"??0B@test2@@QAE@XZ"(%"struct.test2::B"* %{{.*}}, i32 0)
|
|
|
|
// CHECK: call x86_thiscallcc %"struct.test2::A"* @"??0A@test2@@QAE@XZ"(%"struct.test2::A"* %{{.*}})
|
2014-01-14 06:57:31 +08:00
|
|
|
// CHECK: ret
|
|
|
|
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK2-LABEL: define linkonce_odr dso_local x86_thiscallcc %"struct.test2::B"* @"??0B@test2@@QAE@XZ"
|
2014-01-14 06:57:31 +08:00
|
|
|
// CHECK2: (%"struct.test2::B"* returned %this, i32 %is_most_derived)
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK2: call x86_thiscallcc %"struct.test2::A"* @"??0A@test2@@QAE@XZ"(%"struct.test2::A"* %{{.*}})
|
2014-01-14 06:57:31 +08:00
|
|
|
// CHECK2: ret
|
|
|
|
|
|
|
|
}
|
2014-03-15 01:43:37 +08:00
|
|
|
|
|
|
|
namespace test3 {
|
|
|
|
// PR19104: A non-virtual call of a virtual method doesn't use vftable thunks,
|
|
|
|
// so requires only static adjustment which is different to the one used
|
|
|
|
// for virtual calls.
|
|
|
|
struct A {
|
|
|
|
virtual void foo();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B : virtual A {
|
|
|
|
virtual void bar();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct C : virtual A {
|
|
|
|
virtual void foo();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct D : B, C {
|
|
|
|
virtual void bar();
|
|
|
|
int field; // Laid out between C and A subobjects in D.
|
|
|
|
};
|
|
|
|
|
|
|
|
void D::bar() {
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK-LABEL: define dso_local x86_thiscallcc void @"?bar@D@test3@@UAEXXZ"(%"struct.test3::D"* %this)
|
2014-03-15 01:43:37 +08:00
|
|
|
|
|
|
|
C::foo();
|
|
|
|
// Shouldn't need any vbtable lookups. All we have to do is adjust to C*,
|
|
|
|
// then compensate for the adjustment performed in the C::foo() prologue.
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK-NOT: load i8*, i8**
|
2014-03-15 01:43:37 +08:00
|
|
|
// CHECK: %[[OBJ_i8:.*]] = bitcast %"struct.test3::D"* %{{.*}} to i8*
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[C_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 8
|
2014-03-15 01:43:37 +08:00
|
|
|
// CHECK: %[[C:.*]] = bitcast i8* %[[C_i8]] to %"struct.test3::C"*
|
|
|
|
// CHECK: %[[C_i8:.*]] = bitcast %"struct.test3::C"* %[[C]] to i8*
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[ARG:.*]] = getelementptr i8, i8* %[[C_i8]], i32 4
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK: call x86_thiscallcc void @"?foo@C@test3@@UAEXXZ"(i8* %[[ARG]])
|
2014-03-15 01:43:37 +08:00
|
|
|
// CHECK: ret
|
|
|
|
}
|
|
|
|
}
|
2014-03-21 04:38:34 +08:00
|
|
|
|
|
|
|
namespace test4{
|
|
|
|
// PR19172: We used to merge method vftable locations wrong.
|
|
|
|
|
|
|
|
struct A {
|
|
|
|
virtual ~A() {}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B {
|
|
|
|
virtual ~B() {}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct C : virtual A, B {
|
|
|
|
virtual ~C();
|
|
|
|
};
|
|
|
|
|
|
|
|
void foo(void*);
|
|
|
|
|
|
|
|
C::~C() {
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK-LABEL: define dso_local x86_thiscallcc void @"??1C@test4@@UAE@XZ"(%"struct.test4::C"* %this)
|
2014-03-21 04:38:34 +08:00
|
|
|
|
|
|
|
// In this case "this" points to the most derived class, so no GEPs needed.
|
|
|
|
// CHECK-NOT: getelementptr
|
|
|
|
// CHECK-NOT: bitcast
|
2014-12-04 05:00:21 +08:00
|
|
|
// CHECK: %[[VFPTR_i8:.*]] = bitcast %"struct.test4::C"* %{{.*}} to i32 (...)***
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7C@test4@@6BB@1@@" to i32 (...)**), i32 (...)*** %[[VFPTR_i8]]
|
2014-03-21 04:38:34 +08:00
|
|
|
|
|
|
|
foo(this);
|
2014-03-21 19:07:24 +08:00
|
|
|
// CHECK: ret
|
2014-03-21 04:38:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void destroy(C *obj) {
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK-LABEL: define dso_local void @"?destroy@test4@@YAXPAUC@1@@Z"(%"struct.test4::C"* %obj)
|
2014-03-21 04:38:34 +08:00
|
|
|
|
|
|
|
delete obj;
|
2014-11-01 04:09:12 +08:00
|
|
|
// CHECK: %[[VPTR:.*]] = bitcast %"struct.test4::C"* %[[OBJ:.*]] to i8* (%"struct.test4::C"*, i32)***
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK: %[[VFTABLE:.*]] = load i8* (%"struct.test4::C"*, i32)**, i8* (%"struct.test4::C"*, i32)*** %[[VPTR]]
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[VFTENTRY:.*]] = getelementptr inbounds i8* (%"struct.test4::C"*, i32)*, i8* (%"struct.test4::C"*, i32)** %[[VFTABLE]], i64 0
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK: %[[VFUN:.*]] = load i8* (%"struct.test4::C"*, i32)*, i8* (%"struct.test4::C"*, i32)** %[[VFTENTRY]]
|
2014-11-01 04:09:12 +08:00
|
|
|
// CHECK: call x86_thiscallcc i8* %[[VFUN]](%"struct.test4::C"* %[[OBJ]], i32 1)
|
2014-03-21 19:07:24 +08:00
|
|
|
// CHECK: ret
|
|
|
|
}
|
|
|
|
|
|
|
|
struct D {
|
|
|
|
virtual void d();
|
|
|
|
};
|
|
|
|
|
|
|
|
// The first non-virtual base doesn't have a vdtor,
|
|
|
|
// but "this adjustment" is not needed.
|
|
|
|
struct E : D, B, virtual A {
|
|
|
|
virtual ~E();
|
|
|
|
};
|
|
|
|
|
|
|
|
E::~E() {
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK-LABEL: define dso_local x86_thiscallcc void @"??1E@test4@@UAE@XZ"(%"struct.test4::E"* %this)
|
2014-03-21 19:07:24 +08:00
|
|
|
|
|
|
|
// In this case "this" points to the most derived class, so no GEPs needed.
|
|
|
|
// CHECK-NOT: getelementptr
|
|
|
|
// CHECK-NOT: bitcast
|
2014-12-04 05:00:21 +08:00
|
|
|
// CHECK: %[[VFPTR_i8:.*]] = bitcast %"struct.test4::E"* %{{.*}} to i32 (...)***
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7E@test4@@6BD@1@@" to i32 (...)**), i32 (...)*** %[[VFPTR_i8]]
|
2014-03-21 19:07:24 +08:00
|
|
|
foo(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void destroy(E *obj) {
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK-LABEL: define dso_local void @"?destroy@test4@@YAXPAUE@1@@Z"(%"struct.test4::E"* %obj)
|
2014-03-21 19:07:24 +08:00
|
|
|
|
|
|
|
// CHECK-NOT: getelementptr
|
2018-02-06 07:09:13 +08:00
|
|
|
// CHECK: %[[OBJ_i8:.*]] = bitcast %"struct.test4::E"* %[[OBJ]] to i8*
|
|
|
|
// CHECK: %[[B_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 4
|
|
|
|
// FIXME: in fact, the call should take i8* and the bitcast is redundant.
|
|
|
|
// CHECK: %[[B_as_E:.*]] = bitcast i8* %[[B_i8]] to %"struct.test4::E"*
|
2014-03-21 19:07:24 +08:00
|
|
|
// CHECK: %[[OBJ_i8:.*]] = bitcast %"struct.test4::E"* %[[OBJ:.*]] to i8*
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[B_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 4
|
2014-11-01 04:09:12 +08:00
|
|
|
// CHECK: %[[VPTR:.*]] = bitcast i8* %[[B_i8]] to i8* (%"struct.test4::E"*, i32)***
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK: %[[VFTABLE:.*]] = load i8* (%"struct.test4::E"*, i32)**, i8* (%"struct.test4::E"*, i32)*** %[[VPTR]]
|
2015-02-28 03:18:17 +08:00
|
|
|
// CHECK: %[[VFTENTRY:.*]] = getelementptr inbounds i8* (%"struct.test4::E"*, i32)*, i8* (%"struct.test4::E"*, i32)** %[[VFTABLE]], i64 0
|
2015-02-28 05:19:58 +08:00
|
|
|
// CHECK: %[[VFUN:.*]] = load i8* (%"struct.test4::E"*, i32)*, i8* (%"struct.test4::E"*, i32)** %[[VFTENTRY]]
|
2014-11-01 04:09:12 +08:00
|
|
|
// CHECK: call x86_thiscallcc i8* %[[VFUN]](%"struct.test4::E"* %[[B_as_E]], i32 1)
|
2014-03-21 19:07:24 +08:00
|
|
|
delete obj;
|
2014-03-21 04:38:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2015-11-02 17:01:44 +08:00
|
|
|
|
|
|
|
namespace test5 {
|
|
|
|
// PR25370: Don't zero-initialize vbptrs in virtual bases.
|
|
|
|
struct A {
|
|
|
|
virtual void f();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct B : virtual A {
|
|
|
|
int Field;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct C : B {
|
|
|
|
C();
|
|
|
|
};
|
|
|
|
|
|
|
|
C::C() : B() {}
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK-LABEL: define dso_local x86_thiscallcc %"struct.test5::C"* @"??0C@test5@@QAE@XZ"(
|
2015-11-02 17:01:44 +08:00
|
|
|
// CHECK: %[[THIS:.*]] = load %"struct.test5::C"*, %"struct.test5::C"**
|
|
|
|
// CHECK: br i1 %{{.*}}, label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]]
|
|
|
|
|
|
|
|
// CHECK: %[[SKIP_VBASES]]
|
|
|
|
// CHECK: %[[B:.*]] = bitcast %"struct.test5::C"* %[[THIS]] to %"struct.test5::B"*
|
|
|
|
// CHECK: %[[B_i8:.*]] = bitcast %"struct.test5::B"* %[[B]] to i8*
|
|
|
|
// CHECK: %[[FIELD:.*]] = getelementptr inbounds i8, i8* %[[B_i8]], i32 4
|
Change memcpy/memove/memset to have dest and source alignment attributes (Step 1).
Summary:
Upstream LLVM is changing the the prototypes of the @llvm.memcpy/memmove/memset
intrinsics. This change updates the Clang tests for this change.
The @llvm.memcpy/memmove/memset intrinsics currently have an explicit argument
which is required to be a constant integer. It represents the alignment of the
dest (and source), and so must be the minimum of the actual alignment of the
two.
This change removes the alignment argument in favour of placing the alignment
attribute on the source and destination pointers of the memory intrinsic call.
For example, code which used to read:
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 100, i32 4, i1 false)
will now read
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %dest, i8* align 4 %src, i32 100, i1 false)
At this time the source and destination alignments must be the same (Step 1).
Step 2 of the change, to be landed shortly, will relax that contraint and allow
the source and destination to have different alignments.
llvm-svn: 322964
2018-01-20 01:12:54 +08:00
|
|
|
// CHECK: call void @llvm.memset.p0i8.i32(i8* align 4 %[[FIELD]], i8 0, i32 4, i1 false)
|
2015-11-02 17:01:44 +08:00
|
|
|
}
|
2016-05-04 02:44:29 +08:00
|
|
|
|
|
|
|
namespace pr27621 {
|
|
|
|
// Devirtualization through a static_cast used to make us compute the 'this'
|
|
|
|
// adjustment for B::g instead of C::g. When we directly call C::g, 'this' is a
|
|
|
|
// B*, and the prologue of C::g will adjust it to a C*.
|
|
|
|
struct A { virtual void f(); };
|
|
|
|
struct B { virtual void g(); };
|
|
|
|
struct C final : A, B {
|
|
|
|
virtual void h();
|
|
|
|
void g() override;
|
|
|
|
};
|
|
|
|
void callit(C *p) {
|
|
|
|
static_cast<B*>(p)->g();
|
|
|
|
}
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK-LABEL: define dso_local void @"?callit@pr27621@@YAXPAUC@1@@Z"(%"struct.pr27621::C"* %{{.*}})
|
2016-05-04 02:48:50 +08:00
|
|
|
// CHECK: %[[B_i8:.*]] = getelementptr i8, i8* %{{.*}}, i32 4
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK: call x86_thiscallcc void @"?g@C@pr27621@@UAEXXZ"(i8* %[[B_i8]])
|
2016-05-04 02:44:29 +08:00
|
|
|
}
|
2016-05-12 11:51:52 +08:00
|
|
|
|
|
|
|
namespace test6 {
|
|
|
|
class A {};
|
|
|
|
class B : virtual A {};
|
|
|
|
class C : virtual B {
|
|
|
|
virtual void m_fn1();
|
|
|
|
float field;
|
|
|
|
};
|
|
|
|
class D : C {
|
|
|
|
D();
|
|
|
|
};
|
|
|
|
D::D() : C() {}
|
2018-03-17 04:36:49 +08:00
|
|
|
// CHECK-LABEL: define dso_local x86_thiscallcc %"class.test6::D"* @"??0D@test6@@AAE@XZ"(
|
2016-05-12 11:51:52 +08:00
|
|
|
// CHECK: %[[THIS:.*]] = load %"class.test6::D"*, %"class.test6::D"**
|
|
|
|
// CHECK: br i1 %{{.*}}, label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]]
|
|
|
|
|
|
|
|
// CHECK: %[[SKIP_VBASES]]
|
|
|
|
// CHECK: %[[C:.*]] = bitcast %"class.test6::D"* %[[THIS]] to %"class.test6::C"*
|
|
|
|
// CHECK: %[[C_i8:.*]] = bitcast %"class.test6::C"* %[[C]] to i8*
|
|
|
|
// CHECK: %[[FIELD:.*]] = getelementptr inbounds i8, i8* %[[C_i8]], i32 8
|
Change memcpy/memove/memset to have dest and source alignment attributes (Step 1).
Summary:
Upstream LLVM is changing the the prototypes of the @llvm.memcpy/memmove/memset
intrinsics. This change updates the Clang tests for this change.
The @llvm.memcpy/memmove/memset intrinsics currently have an explicit argument
which is required to be a constant integer. It represents the alignment of the
dest (and source), and so must be the minimum of the actual alignment of the
two.
This change removes the alignment argument in favour of placing the alignment
attribute on the source and destination pointers of the memory intrinsic call.
For example, code which used to read:
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 100, i32 4, i1 false)
will now read
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %dest, i8* align 4 %src, i32 100, i1 false)
At this time the source and destination alignments must be the same (Step 1).
Step 2 of the change, to be landed shortly, will relax that contraint and allow
the source and destination to have different alignments.
llvm-svn: 322964
2018-01-20 01:12:54 +08:00
|
|
|
// CHECK: call void @llvm.memset.p0i8.i32(i8* align 4 %[[FIELD]], i8 0, i32 4, i1 false)
|
2016-05-12 11:51:52 +08:00
|
|
|
}
|
2018-03-29 02:23:35 +08:00
|
|
|
|
|
|
|
namespace pr36921 {
|
|
|
|
struct A {
|
|
|
|
virtual ~A() {}
|
|
|
|
};
|
|
|
|
struct B {
|
|
|
|
virtual ~B() {}
|
|
|
|
};
|
|
|
|
struct C : virtual B {};
|
|
|
|
struct D : virtual A, C {};
|
|
|
|
D d;
|
|
|
|
// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc i8* @"??_GD@pr36921@@UAEPAXI@Z"(
|
|
|
|
// CHECK: %[[THIS:.*]] = load %"struct.pr36921::D"*, %"struct.pr36921::D"**
|
|
|
|
// CHECK: %[[THIS_UNADJ_i8:.*]] = bitcast %"struct.pr36921::D"* %[[THIS_RELOAD]] to i8*
|
|
|
|
// CHECK: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_UNADJ_i8]], i32 -4
|
|
|
|
// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJ_i8]] to %"struct.pr36921::D"*
|
|
|
|
}
|