1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 %s -emit-llvm -o %t.ll -triple=x86_64-apple-darwin10 2*f4a2713aSLionel Sambuc // RUN: FileCheck %s < %t.ll 3*f4a2713aSLionel Sambuc // RUN: FileCheck -check-prefix=CHECK-GLOBAL %s < %t.ll 4*f4a2713aSLionel Sambuc // RUN: %clang_cc1 %s -emit-llvm -o %t-opt.ll -triple=x86_64-apple-darwin10 -O3 5*f4a2713aSLionel Sambuc // RUN: FileCheck --check-prefix=CHECK-O3 %s < %t-opt.ll 6*f4a2713aSLionel Sambuc 7*f4a2713aSLionel Sambuc struct A { int a; int b; }; 8*f4a2713aSLionel Sambuc struct B { int b; }; 9*f4a2713aSLionel Sambuc struct C : B, A { }; 10*f4a2713aSLionel Sambuc 11*f4a2713aSLionel Sambuc // Zero init. 12*f4a2713aSLionel Sambuc namespace ZeroInit { 13*f4a2713aSLionel Sambuc // CHECK-GLOBAL: @_ZN8ZeroInit1aE = global i64 -1 14*f4a2713aSLionel Sambuc int A::* a; 15*f4a2713aSLionel Sambuc 16*f4a2713aSLionel Sambuc // CHECK-GLOBAL: @_ZN8ZeroInit2aaE = global [2 x i64] [i64 -1, i64 -1] 17*f4a2713aSLionel Sambuc int A::* aa[2]; 18*f4a2713aSLionel Sambuc 19*f4a2713aSLionel Sambuc // CHECK-GLOBAL: @_ZN8ZeroInit3aaaE = global [2 x [2 x i64]] {{\[}}[2 x i64] [i64 -1, i64 -1], [2 x i64] [i64 -1, i64 -1]] 20*f4a2713aSLionel Sambuc int A::* aaa[2][2]; 21*f4a2713aSLionel Sambuc 22*f4a2713aSLionel Sambuc // CHECK-GLOBAL: @_ZN8ZeroInit1bE = global i64 -1, 23*f4a2713aSLionel Sambuc int A::* b = 0; 24*f4a2713aSLionel Sambuc 25*f4a2713aSLionel Sambuc // CHECK-GLOBAL: @_ZN8ZeroInit2saE = internal global %struct.anon { i64 -1 } 26*f4a2713aSLionel Sambuc struct { 27*f4a2713aSLionel Sambuc int A::*a; 28*f4a2713aSLionel Sambuc } sa; 29*f4a2713aSLionel Sambuc void test_sa() { (void) sa; } // force emission 30*f4a2713aSLionel Sambuc 31*f4a2713aSLionel Sambuc // CHECK-GLOBAL: @_ZN8ZeroInit3ssaE = internal 32*f4a2713aSLionel Sambuc // CHECK-GLOBAL: [2 x i64] [i64 -1, i64 -1] 33*f4a2713aSLionel Sambuc struct { 34*f4a2713aSLionel Sambuc int A::*aa[2]; 35*f4a2713aSLionel Sambuc } ssa[2]; 36*f4a2713aSLionel Sambuc void test_ssa() { (void) ssa; } 37*f4a2713aSLionel Sambuc 38*f4a2713aSLionel Sambuc // CHECK-GLOBAL: @_ZN8ZeroInit2ssE = internal global %struct.anon.1 { %struct.anon.2 { i64 -1 } } 39*f4a2713aSLionel Sambuc struct { 40*f4a2713aSLionel Sambuc struct { 41*f4a2713aSLionel Sambuc int A::*pa; 42*f4a2713aSLionel Sambuc } s; 43*f4a2713aSLionel Sambuc } ss; 44*f4a2713aSLionel Sambuc void test_ss() { (void) ss; } 45*f4a2713aSLionel Sambuc 46*f4a2713aSLionel Sambuc struct A { 47*f4a2713aSLionel Sambuc int A::*a; 48*f4a2713aSLionel Sambuc int b; 49*f4a2713aSLionel Sambuc }; 50*f4a2713aSLionel Sambuc 51*f4a2713aSLionel Sambuc struct B { 52*f4a2713aSLionel Sambuc A a[10]; 53*f4a2713aSLionel Sambuc char c; 54*f4a2713aSLionel Sambuc int B::*b; 55*f4a2713aSLionel Sambuc }; 56*f4a2713aSLionel Sambuc 57*f4a2713aSLionel Sambuc struct C : A, B { int j; }; 58*f4a2713aSLionel Sambuc // CHECK-GLOBAL: @_ZN8ZeroInit1cE = global {{%.*}} { %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::B" { [10 x %"struct.ZeroInit::A"] [%"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }, %"struct.ZeroInit::A" { i64 -1, i32 0 }], i8 0, i64 -1 }, i32 0 }, align 8 59*f4a2713aSLionel Sambuc C c; 60*f4a2713aSLionel Sambuc } 61*f4a2713aSLionel Sambuc 62*f4a2713aSLionel Sambuc // PR5674 63*f4a2713aSLionel Sambuc namespace PR5674 { 64*f4a2713aSLionel Sambuc // CHECK-GLOBAL: @_ZN6PR56742pbE = global i64 4 65*f4a2713aSLionel Sambuc int A::*pb = &A::b; 66*f4a2713aSLionel Sambuc } 67*f4a2713aSLionel Sambuc 68*f4a2713aSLionel Sambuc // Casts. 69*f4a2713aSLionel Sambuc namespace Casts { 70*f4a2713aSLionel Sambuc 71*f4a2713aSLionel Sambuc int A::*pa; 72*f4a2713aSLionel Sambuc int C::*pc; 73*f4a2713aSLionel Sambuc 74*f4a2713aSLionel Sambuc void f() { 75*f4a2713aSLionel Sambuc // CHECK: store i64 -1, i64* @_ZN5Casts2paE 76*f4a2713aSLionel Sambuc pa = 0; 77*f4a2713aSLionel Sambuc 78*f4a2713aSLionel Sambuc // CHECK-NEXT: [[TMP:%.*]] = load i64* @_ZN5Casts2paE, align 8 79*f4a2713aSLionel Sambuc // CHECK-NEXT: [[ADJ:%.*]] = add nsw i64 [[TMP]], 4 80*f4a2713aSLionel Sambuc // CHECK-NEXT: [[ISNULL:%.*]] = icmp eq i64 [[TMP]], -1 81*f4a2713aSLionel Sambuc // CHECK-NEXT: [[RES:%.*]] = select i1 [[ISNULL]], i64 [[TMP]], i64 [[ADJ]] 82*f4a2713aSLionel Sambuc // CHECK-NEXT: store i64 [[RES]], i64* @_ZN5Casts2pcE 83*f4a2713aSLionel Sambuc pc = pa; 84*f4a2713aSLionel Sambuc 85*f4a2713aSLionel Sambuc // CHECK-NEXT: [[TMP:%.*]] = load i64* @_ZN5Casts2pcE, align 8 86*f4a2713aSLionel Sambuc // CHECK-NEXT: [[ADJ:%.*]] = sub nsw i64 [[TMP]], 4 87*f4a2713aSLionel Sambuc // CHECK-NEXT: [[ISNULL:%.*]] = icmp eq i64 [[TMP]], -1 88*f4a2713aSLionel Sambuc // CHECK-NEXT: [[RES:%.*]] = select i1 [[ISNULL]], i64 [[TMP]], i64 [[ADJ]] 89*f4a2713aSLionel Sambuc // CHECK-NEXT: store i64 [[RES]], i64* @_ZN5Casts2paE 90*f4a2713aSLionel Sambuc pa = static_cast<int A::*>(pc); 91*f4a2713aSLionel Sambuc } 92*f4a2713aSLionel Sambuc 93*f4a2713aSLionel Sambuc } 94*f4a2713aSLionel Sambuc 95*f4a2713aSLionel Sambuc // Comparisons 96*f4a2713aSLionel Sambuc namespace Comparisons { 97*f4a2713aSLionel Sambuc void f() { 98*f4a2713aSLionel Sambuc int A::*a; 99*f4a2713aSLionel Sambuc 100*f4a2713aSLionel Sambuc // CHECK: icmp ne i64 {{.*}}, -1 101*f4a2713aSLionel Sambuc if (a) { } 102*f4a2713aSLionel Sambuc 103*f4a2713aSLionel Sambuc // CHECK: icmp ne i64 {{.*}}, -1 104*f4a2713aSLionel Sambuc if (a != 0) { } 105*f4a2713aSLionel Sambuc 106*f4a2713aSLionel Sambuc // CHECK: icmp ne i64 -1, {{.*}} 107*f4a2713aSLionel Sambuc if (0 != a) { } 108*f4a2713aSLionel Sambuc 109*f4a2713aSLionel Sambuc // CHECK: icmp eq i64 {{.*}}, -1 110*f4a2713aSLionel Sambuc if (a == 0) { } 111*f4a2713aSLionel Sambuc 112*f4a2713aSLionel Sambuc // CHECK: icmp eq i64 -1, {{.*}} 113*f4a2713aSLionel Sambuc if (0 == a) { } 114*f4a2713aSLionel Sambuc } 115*f4a2713aSLionel Sambuc } 116*f4a2713aSLionel Sambuc 117*f4a2713aSLionel Sambuc namespace ValueInit { 118*f4a2713aSLionel Sambuc 119*f4a2713aSLionel Sambuc struct A { 120*f4a2713aSLionel Sambuc int A::*a; 121*f4a2713aSLionel Sambuc 122*f4a2713aSLionel Sambuc char c; 123*f4a2713aSLionel Sambuc 124*f4a2713aSLionel Sambuc A(); 125*f4a2713aSLionel Sambuc }; 126*f4a2713aSLionel Sambuc 127*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_ZN9ValueInit1AC2Ev(%"struct.ValueInit::A"* %this) unnamed_addr 128*f4a2713aSLionel Sambuc // CHECK: store i64 -1, i64* 129*f4a2713aSLionel Sambuc // CHECK: ret void 130*f4a2713aSLionel Sambuc A::A() : a() {} 131*f4a2713aSLionel Sambuc 132*f4a2713aSLionel Sambuc } 133*f4a2713aSLionel Sambuc 134*f4a2713aSLionel Sambuc namespace PR7139 { 135*f4a2713aSLionel Sambuc 136*f4a2713aSLionel Sambuc struct pair { 137*f4a2713aSLionel Sambuc int first; 138*f4a2713aSLionel Sambuc int second; 139*f4a2713aSLionel Sambuc }; 140*f4a2713aSLionel Sambuc 141*f4a2713aSLionel Sambuc typedef int pair::*ptr_to_member_type; 142*f4a2713aSLionel Sambuc 143*f4a2713aSLionel Sambuc struct ptr_to_member_struct { 144*f4a2713aSLionel Sambuc ptr_to_member_type data; 145*f4a2713aSLionel Sambuc int i; 146*f4a2713aSLionel Sambuc }; 147*f4a2713aSLionel Sambuc 148*f4a2713aSLionel Sambuc struct A { 149*f4a2713aSLionel Sambuc ptr_to_member_struct a; 150*f4a2713aSLionel Sambuc 151*f4a2713aSLionel Sambuc A() : a() {} 152*f4a2713aSLionel Sambuc }; 153*f4a2713aSLionel Sambuc 154*f4a2713aSLionel Sambuc // CHECK-O3: define zeroext i1 @_ZN6PR71395checkEv() [[NUW:#[0-9]+]] 155*f4a2713aSLionel Sambuc bool check() { 156*f4a2713aSLionel Sambuc // CHECK-O3: ret i1 true 157*f4a2713aSLionel Sambuc return A().a.data == 0; 158*f4a2713aSLionel Sambuc } 159*f4a2713aSLionel Sambuc 160*f4a2713aSLionel Sambuc // CHECK-O3: define zeroext i1 @_ZN6PR71396check2Ev() [[NUW]] 161*f4a2713aSLionel Sambuc bool check2() { 162*f4a2713aSLionel Sambuc // CHECK-O3: ret i1 true 163*f4a2713aSLionel Sambuc return ptr_to_member_type() == 0; 164*f4a2713aSLionel Sambuc } 165*f4a2713aSLionel Sambuc 166*f4a2713aSLionel Sambuc } 167*f4a2713aSLionel Sambuc 168*f4a2713aSLionel Sambuc namespace VirtualBases { 169*f4a2713aSLionel Sambuc 170*f4a2713aSLionel Sambuc struct A { 171*f4a2713aSLionel Sambuc char c; 172*f4a2713aSLionel Sambuc int A::*i; 173*f4a2713aSLionel Sambuc }; 174*f4a2713aSLionel Sambuc 175*f4a2713aSLionel Sambuc // CHECK-GLOBAL: @_ZN12VirtualBases1bE = global %"struct.VirtualBases::B" { i32 (...)** null, %"struct.VirtualBases::A" { i8 0, i64 -1 } }, align 8 176*f4a2713aSLionel Sambuc struct B : virtual A { }; 177*f4a2713aSLionel Sambuc B b; 178*f4a2713aSLionel Sambuc 179*f4a2713aSLionel Sambuc // CHECK-GLOBAL: @_ZN12VirtualBases1cE = global %"struct.VirtualBases::C" { i32 (...)** null, i64 -1, %"struct.VirtualBases::A" { i8 0, i64 -1 } }, align 8 180*f4a2713aSLionel Sambuc struct C : virtual A { int A::*i; }; 181*f4a2713aSLionel Sambuc C c; 182*f4a2713aSLionel Sambuc 183*f4a2713aSLionel Sambuc // CHECK-GLOBAL: @_ZN12VirtualBases1dE = global %"struct.VirtualBases::D" { %"struct.VirtualBases::C.base" { i32 (...)** null, i64 -1 }, i64 -1, %"struct.VirtualBases::A" { i8 0, i64 -1 } }, align 8 184*f4a2713aSLionel Sambuc struct D : C { int A::*i; }; 185*f4a2713aSLionel Sambuc D d; 186*f4a2713aSLionel Sambuc 187*f4a2713aSLionel Sambuc } 188*f4a2713aSLionel Sambuc 189*f4a2713aSLionel Sambuc namespace Test1 { 190*f4a2713aSLionel Sambuc 191*f4a2713aSLionel Sambuc // Don't crash when A contains a bit-field. 192*f4a2713aSLionel Sambuc struct A { 193*f4a2713aSLionel Sambuc int A::* a; 194*f4a2713aSLionel Sambuc int b : 10; 195*f4a2713aSLionel Sambuc }; 196*f4a2713aSLionel Sambuc A a; 197*f4a2713aSLionel Sambuc 198*f4a2713aSLionel Sambuc } 199*f4a2713aSLionel Sambuc 200*f4a2713aSLionel Sambuc namespace BoolPtrToMember { 201*f4a2713aSLionel Sambuc struct X { 202*f4a2713aSLionel Sambuc bool member; 203*f4a2713aSLionel Sambuc }; 204*f4a2713aSLionel Sambuc 205*f4a2713aSLionel Sambuc // CHECK-LABEL: define i8* @_ZN15BoolPtrToMember1fERNS_1XEMS0_b 206*f4a2713aSLionel Sambuc bool &f(X &x, bool X::*member) { 207*f4a2713aSLionel Sambuc // CHECK: {{bitcast.* to i8\*}} 208*f4a2713aSLionel Sambuc // CHECK-NEXT: getelementptr inbounds i8* 209*f4a2713aSLionel Sambuc // CHECK-NEXT: ret i8* 210*f4a2713aSLionel Sambuc return x.*member; 211*f4a2713aSLionel Sambuc } 212*f4a2713aSLionel Sambuc } 213*f4a2713aSLionel Sambuc 214*f4a2713aSLionel Sambuc namespace PR8507 { 215*f4a2713aSLionel Sambuc 216*f4a2713aSLionel Sambuc struct S; 217*f4a2713aSLionel Sambuc void f(S* p, double S::*pm) { 218*f4a2713aSLionel Sambuc if (0 < p->*pm) { 219*f4a2713aSLionel Sambuc } 220*f4a2713aSLionel Sambuc } 221*f4a2713aSLionel Sambuc 222*f4a2713aSLionel Sambuc } 223*f4a2713aSLionel Sambuc 224*f4a2713aSLionel Sambuc namespace test4 { 225*f4a2713aSLionel Sambuc struct A { int A_i; }; 226*f4a2713aSLionel Sambuc struct B : virtual A { int A::*B_p; }; 227*f4a2713aSLionel Sambuc struct C : virtual B { int *C_p; }; 228*f4a2713aSLionel Sambuc struct D : C { int *D_p; }; 229*f4a2713aSLionel Sambuc 230*f4a2713aSLionel Sambuc // CHECK-GLOBAL: @_ZN5test41dE = global %"struct.test4::D" { %"struct.test4::C.base" zeroinitializer, i32* null, %"struct.test4::B.base" { i32 (...)** null, i64 -1 }, %"struct.test4::A" zeroinitializer }, align 8 231*f4a2713aSLionel Sambuc D d; 232*f4a2713aSLionel Sambuc } 233*f4a2713aSLionel Sambuc 234*f4a2713aSLionel Sambuc namespace PR11487 { 235*f4a2713aSLionel Sambuc union U 236*f4a2713aSLionel Sambuc { 237*f4a2713aSLionel Sambuc int U::* mptr; 238*f4a2713aSLionel Sambuc char x[16]; 239*f4a2713aSLionel Sambuc } x; 240*f4a2713aSLionel Sambuc // CHECK-GLOBAL: @_ZN7PR114871xE = global %"union.PR11487::U" { i64 -1, [8 x i8] zeroinitializer }, align 8 241*f4a2713aSLionel Sambuc 242*f4a2713aSLionel Sambuc } 243*f4a2713aSLionel Sambuc 244*f4a2713aSLionel Sambuc namespace PR13097 { 245*f4a2713aSLionel Sambuc struct X { int x; X(const X&); }; 246*f4a2713aSLionel Sambuc struct A { 247*f4a2713aSLionel Sambuc int qq; 248*f4a2713aSLionel Sambuc X x; 249*f4a2713aSLionel Sambuc }; 250*f4a2713aSLionel Sambuc A f(); 251*f4a2713aSLionel Sambuc X g() { return f().*&A::x; } 252*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_ZN7PR130971gEv 253*f4a2713aSLionel Sambuc // CHECK: call void @_ZN7PR130971fEv 254*f4a2713aSLionel Sambuc // CHECK-NOT: memcpy 255*f4a2713aSLionel Sambuc // CHECK: call void @_ZN7PR130971XC1ERKS0_ 256*f4a2713aSLionel Sambuc } 257*f4a2713aSLionel Sambuc 258*f4a2713aSLionel Sambuc // CHECK-O3: attributes [[NUW]] = { nounwind readnone{{.*}} } 259