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