1 // RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 | FileCheck %s 2 3 struct Left { 4 virtual void left(); 5 }; 6 7 struct Right { 8 virtual void right(); 9 }; 10 11 struct ChildNoOverride : Left, Right { 12 }; 13 14 struct ChildOverride : Left, Right { 15 virtual void left(); 16 virtual void right(); 17 }; 18 19 extern "C" void foo(void *); 20 21 void call_left_no_override(ChildNoOverride *child) { 22 // CHECK-LABEL: define dso_local void @"?call_left_no_override 23 // CHECK: %[[CHILD:.*]] = load %struct.ChildNoOverride 24 25 child->left(); 26 // Only need to cast 'this' to Left*. 27 // CHECK: %[[LEFT:.*]] = bitcast %struct.ChildNoOverride* %[[CHILD]] to %struct.Left* 28 // CHECK: %[[VFPTR:.*]] = bitcast %struct.Left* %[[LEFT]] to void (%struct.Left*)*** 29 // CHECK: %[[VFTABLE:.*]] = load void (%struct.Left*)**, void (%struct.Left*)*** %[[VFPTR]] 30 // CHECK: %[[VFUN:.*]] = getelementptr inbounds void (%struct.Left*)*, void (%struct.Left*)** %[[VFTABLE]], i64 0 31 // CHECK: %[[VFUN_VALUE:.*]] = load void (%struct.Left*)*, void (%struct.Left*)** %[[VFUN]] 32 // CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](%struct.Left* {{[^,]*}} %[[LEFT]]) 33 // CHECK: ret 34 } 35 36 void ChildOverride::left() { 37 // CHECK-LABEL: define dso_local x86_thiscallcc void @"?left@ChildOverride@@UAEXXZ" 38 // CHECK-SAME: (%struct.ChildOverride* {{[^,]*}} %[[THIS:.*]]) 39 // 40 // No need to adjust 'this' as the ChildOverride's layout begins with Left. 41 // CHECK: %[[THIS_ADDR:.*]] = alloca %struct.ChildOverride*, align 4 42 // CHECK: store %struct.ChildOverride* %[[THIS]], %struct.ChildOverride** %[[THIS_ADDR]], align 4 43 44 foo(this); 45 // CHECK: %[[THIS:.*]] = load %struct.ChildOverride*, %struct.ChildOverride** %[[THIS_ADDR]] 46 // CHECK: %[[THIS_i8:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i8* 47 // CHECK: call void @foo(i8* noundef %[[THIS_i8]]) 48 // CHECK: ret 49 } 50 51 void call_left_override(ChildOverride *child) { 52 // CHECK-LABEL: define dso_local void @"?call_left_override 53 // CHECK: %[[CHILD:.*]] = load %struct.ChildOverride 54 55 child->left(); 56 // CHECK: %[[VFPTR:.*]] = bitcast %struct.ChildOverride* %[[CHILD]] to void (%struct.ChildOverride*)*** 57 // CHECK: %[[VFTABLE:.*]] = load void (%struct.ChildOverride*)**, void (%struct.ChildOverride*)*** %[[VFPTR]] 58 // CHECK: %[[VFUN:.*]] = getelementptr inbounds void (%struct.ChildOverride*)*, void (%struct.ChildOverride*)** %[[VFTABLE]], i64 0 59 // CHECK: %[[VFUN_VALUE:.*]] = load void (%struct.ChildOverride*)*, void (%struct.ChildOverride*)** %[[VFUN]] 60 // 61 // CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](%struct.ChildOverride* {{[^,]*}} %[[CHILD]]) 62 // CHECK: ret 63 } 64 65 void call_right_no_override(ChildNoOverride *child) { 66 // CHECK-LABEL: define dso_local void @"?call_right_no_override 67 // CHECK: %[[CHILD:.*]] = load %struct.ChildNoOverride 68 69 child->right(); 70 // When calling a right base's virtual method, one needs to adjust 'this' at 71 // the caller site. 72 // 73 // CHECK: %[[CHILD_i8:.*]] = bitcast %struct.ChildNoOverride* %[[CHILD]] to i8* 74 // CHECK: %[[RIGHT_i8:.*]] = getelementptr inbounds i8, i8* %[[CHILD_i8]], i32 4 75 // CHECK: %[[RIGHT:.*]] = bitcast i8* %[[RIGHT_i8]] to %struct.Right* 76 // 77 // CHECK: %[[VFPTR:.*]] = bitcast %struct.Right* %[[RIGHT]] to void (%struct.Right*)*** 78 // CHECK: %[[VFTABLE:.*]] = load void (%struct.Right*)**, void (%struct.Right*)*** %[[VFPTR]] 79 // CHECK: %[[VFUN:.*]] = getelementptr inbounds void (%struct.Right*)*, void (%struct.Right*)** %[[VFTABLE]], i64 0 80 // CHECK: %[[VFUN_VALUE:.*]] = load void (%struct.Right*)*, void (%struct.Right*)** %[[VFUN]] 81 // CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](%struct.Right* {{[^,]*}} %[[RIGHT]]) 82 // CHECK: ret 83 } 84 85 void ChildOverride::right() { 86 // CHECK-LABEL: define dso_local x86_thiscallcc void @"?right@ChildOverride@@UAEXXZ"(i8* 87 // 88 // ChildOverride::right gets 'this' cast to Right* in ECX (i.e. this+4) so we 89 // need to adjust 'this' before use. 90 // 91 // CHECK: %[[THIS_STORE:.*]] = alloca %struct.ChildOverride*, align 4 92 // CHECK: %[[THIS_ADDR:.*]] = alloca %struct.ChildOverride*, align 4 93 // CHECK: %[[COERCE_VAL:.*]] = bitcast i8* %[[ECX:.*]] to %struct.ChildOverride* 94 // CHECK: store %struct.ChildOverride* %[[COERCE_VAL]], %struct.ChildOverride** %[[THIS_STORE]], align 4 95 // CHECK: %[[THIS_INIT:.*]] = load %struct.ChildOverride*, %struct.ChildOverride** %[[THIS_STORE]], align 4 96 // CHECK: store %struct.ChildOverride* %[[THIS_INIT]], %struct.ChildOverride** %[[THIS_ADDR]], align 4 97 // CHECK: %[[THIS_RELOAD:.*]] = load %struct.ChildOverride*, %struct.ChildOverride** %[[THIS_ADDR]] 98 // CHECK: %[[THIS_i8:.*]] = bitcast %struct.ChildOverride* %[[THIS_RELOAD]] to i8* 99 // CHECK: %[[THIS_ADJUSTED:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 -4 100 // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJUSTED]] to %struct.ChildOverride* 101 102 foo(this); 103 // CHECK: %[[THIS_PARAM:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i8* 104 // CHECK: call void @foo(i8* noundef %[[THIS_PARAM]]) 105 // CHECK: ret 106 } 107 108 void call_right_override(ChildOverride *child) { 109 // CHECK-LABEL: define dso_local void @"?call_right_override 110 // CHECK: %[[CHILD:.*]] = load %struct.ChildOverride 111 112 child->right(); 113 // When calling a right child's virtual method, one needs to adjust 'this' at 114 // the caller site. 115 // 116 // CHECK: %[[CHILD_i8:.*]] = bitcast %struct.ChildOverride* %[[CHILD]] to i8* 117 // CHECK: %[[RIGHT:.*]] = getelementptr inbounds i8, i8* %[[CHILD_i8]], i32 4 118 // 119 // CHECK: %[[CHILD_i8:.*]] = bitcast %struct.ChildOverride* %[[CHILD]] to i8* 120 // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[CHILD_i8]], i32 4 121 // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to void (i8*)*** 122 // CHECK: %[[VFTABLE:.*]] = load void (i8*)**, void (i8*)*** %[[VFPTR]] 123 // CHECK: %[[VFUN:.*]] = getelementptr inbounds void (i8*)*, void (i8*)** %[[VFTABLE]], i64 0 124 // CHECK: %[[VFUN_VALUE:.*]] = load void (i8*)*, void (i8*)** %[[VFUN]] 125 // 126 // CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](i8* noundef %[[RIGHT]]) 127 // CHECK: ret 128 } 129 130 struct GrandchildOverride : ChildOverride { 131 virtual void right(); 132 }; 133 134 void GrandchildOverride::right() { 135 // CHECK-LABEL: define dso_local x86_thiscallcc void @"?right@GrandchildOverride@@UAEXXZ"(i8* 136 // 137 // CHECK: %[[THIS_STORE:.*]] = alloca %struct.GrandchildOverride*, align 4 138 // CHECK: %[[THIS_ADDR:.*]] = alloca %struct.GrandchildOverride*, align 4 139 // CHECK: %[[COERCE_VAL:.*]] = bitcast i8* %[[ECX:.*]] to %struct.GrandchildOverride* 140 // CHECK: store %struct.GrandchildOverride* %[[COERCE_VAL]], %struct.GrandchildOverride** %[[THIS_STORE]], align 4 141 // CHECK: %[[THIS_INIT:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride** %[[THIS_STORE]], align 4 142 // CHECK: store %struct.GrandchildOverride* %[[THIS_INIT]], %struct.GrandchildOverride** %[[THIS_ADDR]], align 4 143 // CHECK: %[[THIS_RELOAD:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride** %[[THIS_ADDR]] 144 // CHECK: %[[THIS_i8:.*]] = bitcast %struct.GrandchildOverride* %[[THIS_RELOAD]] to i8* 145 // CHECK: %[[THIS_ADJUSTED:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 -4 146 // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJUSTED]] to %struct.GrandchildOverride* 147 148 foo(this); 149 // CHECK: %[[THIS_PARAM:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i8* 150 // CHECK: call void @foo(i8* noundef %[[THIS_PARAM]]) 151 // CHECK: ret 152 } 153 154 void call_grandchild_right(GrandchildOverride *obj) { 155 // Just make sure we don't crash. 156 obj->right(); 157 } 158 159 void emit_ctors() { 160 Left l; 161 // CHECK-LABEL: define {{.*}} @"??0Left@@QAE@XZ" 162 // CHECK-NOT: getelementptr 163 // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7Left@@6B@" to i32 (...)**) 164 // CHECK: ret 165 166 Right r; 167 // CHECK-LABEL: define {{.*}} @"??0Right@@QAE@XZ" 168 // CHECK-NOT: getelementptr 169 // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7Right@@6B@" to i32 (...)**) 170 // CHECK: ret 171 172 ChildOverride co; 173 // CHECK-LABEL: define {{.*}} @"??0ChildOverride@@QAE@XZ" 174 // CHECK: %[[THIS:.*]] = load %struct.ChildOverride*, %struct.ChildOverride** 175 // CHECK: %[[VFPTR:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i32 (...)*** 176 // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7ChildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]] 177 // CHECK: %[[THIS_i8:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i8* 178 // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 4 179 // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)*** 180 // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7ChildOverride@@6BRight@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]] 181 // CHECK: ret 182 183 GrandchildOverride gc; 184 // CHECK-LABEL: define {{.*}} @"??0GrandchildOverride@@QAE@XZ" 185 // CHECK: %[[THIS:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride** 186 // CHECK: %[[VFPTR:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i32 (...)*** 187 // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7GrandchildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]] 188 // CHECK: %[[THIS_i8:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i8* 189 // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 4 190 // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)*** 191 // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"??_7GrandchildOverride@@6BRight@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]] 192 // CHECK: ret 193 } 194 195 struct LeftWithNonVirtualDtor { 196 virtual void left(); 197 ~LeftWithNonVirtualDtor(); 198 }; 199 200 struct AsymmetricChild : LeftWithNonVirtualDtor, Right { 201 virtual ~AsymmetricChild(); 202 }; 203 204 void call_asymmetric_child_complete_dtor() { 205 // CHECK-LABEL: define dso_local void @"?call_asymmetric_child_complete_dtor@@YAXXZ" 206 AsymmetricChild obj; 207 // CHECK: call x86_thiscallcc noundef %struct.AsymmetricChild* @"??0AsymmetricChild@@QAE@XZ"(%struct.AsymmetricChild* {{[^,]*}} %[[OBJ:.*]]) 208 // CHECK-NOT: getelementptr 209 // CHECK: call x86_thiscallcc void @"??1AsymmetricChild@@UAE@XZ"(%struct.AsymmetricChild* {{[^,]*}} %[[OBJ]]) 210 // CHECK: ret 211 } 212