Home | History | Annotate | Download | only in CodeGenCXX
      1 // RUN: %clang_cc1 -triple x86_64-apple-darwin -verify -emit-llvm -o - %s | FileCheck %s
      2 void t1() {
      3   extern int& a;
      4   int b = a;
      5 }
      6 
      7 void t2(int& a) {
      8   int b = a;
      9 }
     10 
     11 int g;
     12 int& gr = g;
     13 int& grr = gr;
     14 void t3() {
     15   int b = gr;
     16 }
     17 
     18 // Test reference binding.
     19 
     20 struct C { int a; };
     21 void f(const bool&);
     22 void f(const int&);
     23 void f(const _Complex int&);
     24 void f(const C&);
     25 
     26 C aggregate_return();
     27 
     28 bool& bool_reference_return();
     29 int& int_reference_return();
     30 _Complex int& complex_int_reference_return();
     31 C& aggregate_reference_return();
     32 
     33 void test_bool() {
     34   bool a = true;
     35   f(a);
     36 
     37   f(true);
     38 
     39   bool_reference_return() = true;
     40   a = bool_reference_return();
     41 
     42   struct { const bool& b; } b = { true };
     43 }
     44 
     45 void test_scalar() {
     46   int a = 10;
     47   f(a);
     48 
     49   struct { int bitfield : 3; } s = { 3 };
     50   f(s.bitfield);
     51 
     52   f(10);
     53 
     54   __attribute((vector_size(16))) typedef int vec4;
     55   f((vec4){1,2,3,4}[0]);
     56 
     57   int_reference_return() = 10;
     58   a = int_reference_return();
     59 
     60   struct { const int& a; } agg = { 10 };
     61 }
     62 
     63 void test_complex() {
     64   _Complex int a = 10i;
     65   f(a);
     66 
     67   f(10i);
     68 
     69   complex_int_reference_return() = 10i;
     70   a = complex_int_reference_return();
     71 
     72   struct { const _Complex int &a; } agg = { 10i };
     73 }
     74 
     75 void test_aggregate() {
     76   C c;
     77   f(c);
     78 
     79   f(aggregate_return());
     80   aggregate_reference_return().a = 10;
     81 
     82   c = aggregate_reference_return();
     83 
     84   struct { const C& a; } agg = { C() };
     85 }
     86 
     87 int& reference_return() {
     88   return g;
     89 }
     90 
     91 int reference_decl() {
     92   int& a = g;
     93   const int& b = 1;
     94   return a+b;
     95 }
     96 
     97 struct A {
     98   int& b();
     99 };
    100 
    101 void f(A* a) {
    102   int b = a->b();
    103 }
    104 
    105 // PR5122
    106 void *foo = 0;
    107 void * const & kFoo = foo;
    108 
    109 struct D : C { D(); ~D(); };
    110 
    111 void h() {
    112   // CHECK: call void @_ZN1DD1Ev
    113   const C& c = D();
    114 }
    115 
    116 namespace T {
    117   struct A {
    118     A();
    119     ~A();
    120   };
    121 
    122   struct B {
    123     B();
    124     ~B();
    125     A f();
    126   };
    127 
    128   void f() {
    129     // CHECK: call void @_ZN1T1BC1Ev
    130     // CHECK: call void @_ZN1T1B1fEv
    131     // CHECK: call void @_ZN1T1BD1Ev
    132     const A& a = B().f();
    133     // CHECK: call void @_ZN1T1fEv
    134     f();
    135     // CHECK: call void @_ZN1T1AD1Ev
    136   }
    137 }
    138 
    139 // PR5227.
    140 namespace PR5227 {
    141 void f(int &a) {
    142   (a = 10) = 20;
    143 }
    144 }
    145 
    146 // PR5590
    147 struct s0;
    148 struct s1 { struct s0 &s0; };
    149 void f0(s1 a) { s1 b = a; }
    150 
    151 // PR6024
    152 // CHECK: @_Z2f2v()
    153 // CHECK: alloca i32,
    154 // CHECK-NEXT: store
    155 // CHECK-NEXT: ret
    156 const int &f2() { return 0; }
    157 
    158 // Don't constant fold const reference parameters with default arguments to
    159 // their default arguments.
    160 namespace N1 {
    161   const int foo = 1;
    162   // CHECK: @_ZN2N14test
    163   void test(const int& arg = foo) {
    164     // Ensure this array is on the stack where we can set values instead of
    165     // being a global constant.
    166     // CHECK: %args_array = alloca
    167     const int* const args_array[] = { &arg };
    168   }
    169 }
    170 
    171 // Bind to subobjects while extending the life of the complete object.
    172 namespace N2 {
    173   class X {
    174   public:
    175     X(const X&);
    176     X &operator=(const X&);
    177     ~X();
    178   };
    179 
    180   struct P {
    181     X first;
    182   };
    183 
    184   P getP();
    185 
    186   // CHECK: define void @_ZN2N21fEi
    187   // CHECK: call void @_ZN2N24getPEv
    188   // CHECK: getelementptr inbounds
    189   // CHECK: store i32 17
    190   // CHECK: call void @_ZN2N21PD1Ev
    191   void f(int i) {
    192     const X& xr = getP().first;
    193     i = 17;
    194   }
    195 
    196   struct SpaceWaster {
    197     int i, j;
    198   };
    199 
    200   struct ReallyHasX {
    201     X x;
    202   };
    203 
    204   struct HasX : ReallyHasX { };
    205 
    206   struct HasXContainer {
    207     HasX has;
    208   };
    209 
    210   struct Y : SpaceWaster, HasXContainer { };
    211   struct Z : SpaceWaster, Y { };
    212 
    213   Z getZ();
    214 
    215   // CHECK: define void @_ZN2N21gEi
    216   // CHECK: call void @_ZN2N24getZEv
    217   // CHECK: {{getelementptr inbounds.*i32 0, i32 0}}
    218   // CHECK: {{getelementptr inbounds.*i32 0, i32 0}}
    219   // CHECK: store i32 19
    220   // CHECK: call void @_ZN2N21ZD1Ev
    221   // CHECK: ret void
    222   void g(int i) {
    223     const X &xr = getZ().has.x;
    224     i = 19;
    225   }
    226 }
    227 
    228 namespace N3 {
    229 
    230 // PR7326
    231 
    232 struct A {
    233   explicit A(int);
    234   ~A();
    235 };
    236 
    237 // CHECK: define internal void @__cxx_global_var_init
    238 // CHECK: call void @_ZN2N31AC1Ei(%"struct.N3::A"* @_ZGRN2N35sA123E, i32 123)
    239 // CHECK: call i32 @__cxa_atexit
    240 // CHECK: ret void
    241 const A &sA123 = A(123);
    242 }
    243 
    244 namespace N4 {
    245 
    246 struct A {
    247   A();
    248   ~A();
    249 };
    250 
    251 void f() {
    252   // CHECK: define void @_ZN2N41fEv
    253   // CHECK: call void @_ZN2N41AC1Ev(%"struct.N4::A"* @_ZGRZN2N41fEvE2ar)
    254   // CHECK: call i32 @__cxa_atexit
    255   // CHECK: ret void
    256   static const A& ar = A();
    257 
    258 }
    259 }
    260 
    261 // PR9494
    262 namespace N5 {
    263 struct AnyS { bool b; };
    264 void f(const bool&);
    265 AnyS g();
    266 void h() {
    267   // CHECK: call i8 @_ZN2N51gEv()
    268   // CHECK: call void @_ZN2N51fERKb(i8*
    269   f(g().b);
    270 }
    271 }
    272 
    273 // PR9565
    274 namespace PR9565 {
    275   struct a { int a : 10, b : 10; };
    276   // CHECK: define void @_ZN6PR95651fEv()
    277   void f() {
    278     // CHECK: call void @llvm.memcpy
    279     a x = { 0, 0 };
    280     // CHECK: [[WITH_SEVENTEEN:%[a-zA-Z0-9]+]] = or i32 [[WITHOUT_SEVENTEEN:%[a-zA-Z0-9]+]], 17
    281     // CHECK: store i32 [[WITH_SEVENTEEN]], i32* [[XA:%[a-zA-Z0-9]+]]
    282     x.a = 17;
    283     // CHECK-NEXT: bitcast
    284     // CHECK-NEXT: load
    285     // CHECK-NEXT: and
    286     // CHECK-NEXT: shl
    287     // CHECK-NEXT: ashr
    288     // CHECK-NEXT: store i32
    289     // CHECK-NEXT: store i32*
    290     const int &y = x.a;
    291     // CHECK-NEXT: bitcast
    292     // CHECK-NEXT: load
    293     // CHECK-NEXT: and
    294     // CHECK-NEXT: or
    295     // CHECK-NEXT: store i32
    296     x.b = 19;
    297     // CHECK-NEXT: ret void
    298   }
    299 }
    300