289 lines · cpp
1// RUN: %clang_cc1 %s -emit-llvm -o %t.ll -triple=x86_64-apple-darwin102// RUN: %clang_cc1 %s -emit-llvm -o %t.ll -triple=x86_64-apple-darwin10 -fexperimental-new-constant-interpreter3// RUN: FileCheck %s < %t.ll4// RUN: FileCheck -check-prefix=CHECK-GLOBAL %s < %t.ll5 6struct A { int a; int b; };7struct B { int b; };8struct C : B, A { };9 10// Zero init.11namespace ZeroInit {12 // CHECK-GLOBAL: @_ZN8ZeroInit1aE ={{.*}} global i64 -113 int A::* a;14 15 // CHECK-GLOBAL: @_ZN8ZeroInit2aaE ={{.*}} global [2 x i64] [i64 -1, i64 -1]16 int A::* aa[2];17 18 // CHECK-GLOBAL: @_ZN8ZeroInit3aaaE ={{.*}} global [2 x [2 x i64]] {{\[}}[2 x i64] [i64 -1, i64 -1], [2 x i64] [i64 -1, i64 -1]]19 int A::* aaa[2][2];20 21 // CHECK-GLOBAL: @_ZN8ZeroInit1bE ={{.*}} global i64 -1,22 int A::* b = 0;23 24 // CHECK-GLOBAL: @_ZN8ZeroInit2saE = internal global %struct.anon { i64 -1 }25 struct {26 int A::*a;27 } sa;28 void test_sa() { (void) sa; } // force emission29 30 // CHECK-GLOBAL: @_ZN8ZeroInit3ssaE = internal31 // CHECK-GLOBAL: [2 x i64] [i64 -1, i64 -1]32 struct {33 int A::*aa[2];34 } ssa[2];35 void test_ssa() { (void) ssa; }36 37 // CHECK-GLOBAL: @_ZN8ZeroInit2ssE = internal global %struct.anon.1 { %struct.anon.2 { i64 -1 } }38 struct {39 struct {40 int A::*pa;41 } s;42 } ss;43 void test_ss() { (void) ss; }44 45 struct A {46 int A::*a;47 int b;48 };49 50 struct B {51 A a[10];52 char c;53 int B::*b;54 };55 56 struct C : A, B { int j; };57 // 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 858 C c;59}60 61// PR567462namespace PR5674 {63 // CHECK-GLOBAL: @_ZN6PR56742pbE ={{.*}} global i64 464 int A::*pb = &A::b;65}66 67// Casts.68namespace Casts {69 70int A::*pa;71int C::*pc;72 73void f() {74 // CHECK: store i64 -1, ptr @_ZN5Casts2paE75 pa = 0;76 77 // CHECK-NEXT: [[TMP:%.*]] = load i64, ptr @_ZN5Casts2paE, align 878 // CHECK-NEXT: [[ADJ:%.*]] = add nsw i64 [[TMP]], 479 // CHECK-NEXT: [[ISNULL:%.*]] = icmp eq i64 [[TMP]], -180 // CHECK-NEXT: [[RES:%.*]] = select i1 [[ISNULL]], i64 [[TMP]], i64 [[ADJ]]81 // CHECK-NEXT: store i64 [[RES]], ptr @_ZN5Casts2pcE82 pc = pa;83 84 // CHECK-NEXT: [[TMP:%.*]] = load i64, ptr @_ZN5Casts2pcE, align 885 // CHECK-NEXT: [[ADJ:%.*]] = sub nsw i64 [[TMP]], 486 // CHECK-NEXT: [[ISNULL:%.*]] = icmp eq i64 [[TMP]], -187 // CHECK-NEXT: [[RES:%.*]] = select i1 [[ISNULL]], i64 [[TMP]], i64 [[ADJ]]88 // CHECK-NEXT: store i64 [[RES]], ptr @_ZN5Casts2paE89 pa = static_cast<int A::*>(pc);90}91 92}93 94// Comparisons95namespace Comparisons {96 void f() {97 int A::*a;98 99 // CHECK: icmp ne i64 {{.*}}, -1100 if (a) { }101 102 // CHECK: icmp ne i64 {{.*}}, -1103 if (a != 0) { }104 105 // CHECK: icmp ne i64 -1, {{.*}}106 if (0 != a) { }107 108 // CHECK: icmp eq i64 {{.*}}, -1109 if (a == 0) { }110 111 // CHECK: icmp eq i64 -1, {{.*}}112 if (0 == a) { }113 }114}115 116namespace ValueInit {117 118struct A {119 int A::*a;120 121 char c;122 123 A();124};125 126// CHECK-LABEL: define{{.*}} void @_ZN9ValueInit1AC2Ev(ptr {{[^,]*}} %this) unnamed_addr127// CHECK: store i64 -1, ptr128// CHECK: ret void129A::A() : a() {}130 131}132 133namespace VirtualBases {134 135struct A {136 char c;137 int A::*i;138};139 140// CHECK-GLOBAL: @_ZN12VirtualBases1bE ={{.*}} global %"struct.VirtualBases::B" { ptr null, %"struct.VirtualBases::A" { i8 0, i64 -1 } }, align 8141struct B : virtual A { };142B b;143 144// CHECK-GLOBAL: @_ZN12VirtualBases1cE ={{.*}} global %"struct.VirtualBases::C" { ptr null, i64 -1, %"struct.VirtualBases::A" { i8 0, i64 -1 } }, align 8145struct C : virtual A { int A::*i; };146C c;147 148// CHECK-GLOBAL: @_ZN12VirtualBases1dE ={{.*}} global %"struct.VirtualBases::D" { %"struct.VirtualBases::C.base" { ptr null, i64 -1 }, i64 -1, %"struct.VirtualBases::A" { i8 0, i64 -1 } }, align 8149struct D : C { int A::*i; };150D d;151 152}153 154namespace Test1 {155 156// Don't crash when A contains a bit-field.157struct A {158 int A::* a;159 int b : 10;160};161A a;162 163}164 165namespace BoolPtrToMember {166 struct X {167 bool member;168 };169 170 // CHECK-LABEL: define{{.*}} nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @_ZN15BoolPtrToMember1fERNS_1XEMS0_b171 bool &f(X &x, bool X::*member) {172 // CHECK: getelementptr inbounds i8, ptr173 // CHECK-NEXT: ret ptr174 return x.*member;175 }176}177 178namespace PR8507 {179 180struct S;181void f(S* p, double S::*pm) {182 if (0 < p->*pm) {183 }184}185 186}187 188namespace 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, ptr null, %"struct.test4::B.base" { ptr null, i64 -1 }, %"struct.test4::A" zeroinitializer }, align 8195 D d;196}197 198namespace PR11487 {199 union U200 {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 8205 206}207 208namespace 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 @_ZN7PR130971gEv217 // CHECK: call void @_ZN7PR130971fEv218 // CHECK-NOT: memcpy219 // CHECK: call void @_ZN7PR130971XC1ERKS0_220}221 222namespace PR21089 {223struct A {224 bool : 1;225 int A::*x;226 bool y;227 A();228};229struct B : A {230};231B 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 8233}234 235namespace PR21282 {236union U {237 int U::*x;238 long y[2];239};240U u;241// CHECK-GLOBAL: @_ZN7PR212821uE ={{.*}} global %"union.PR21282::U" { i64 -1, [8 x i8] zeroinitializer }, align 8242}243 244namespace FlexibleArrayMember {245struct S {246 int S::*x[];247};248S s;249// CHECK-GLOBAL: @_ZN19FlexibleArrayMember1sE ={{.*}} global %"struct.FlexibleArrayMember::S" zeroinitializer, align 8250}251 252namespace IndirectPDM {253union U {254 union {255 int U::*m;256 };257};258U u;259// CHECK-GLOBAL: @_ZN11IndirectPDM1uE ={{.*}} global %"union.IndirectPDM::U" { %union.anon { i64 -1 } }, align 8260}261 262namespace PR47864 {263 struct B;264 struct B {};265 struct D : B { int m; };266 auto x = (int B::*)&D::m;267}268 269namespace ContainerOf {270 using size_t = unsigned long long;271 272 struct List {273 int data;274 };275 276 struct Node {277 int data;278 struct List list1;279 struct List list2;280 };281 282 // CHECK-LABEL: define{{.*}} ptr @_ZN11ContainerOf8getOwnerEPNS_4ListEMNS_4NodeES0_283 // CHECK: %memptr.offset = getelementptr i8, ptr null, i64 {{.*}}284 Node* getOwner(List *list, List Node::*member) {285 size_t offset = reinterpret_cast<size_t>(&((Node*)nullptr->*member));286 return reinterpret_cast<Node*>(reinterpret_cast<char*>(list) - offset);287 }288}289