aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGenCXX/references.cpp
blob: 8e0e1cbe84e831cec107e7181468a38167512c21 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// RUN: clang-cc -verify -emit-llvm -o - %s | FileCheck %s

void t1() {
  extern int& a;
  int b = a; 
}

void t2(int& a) {
  int b = a;
}

int g;
int& gr = g;
int& grr = gr;
void t3() {
  int b = gr;
}

// Test reference binding.

struct C { int a; };

void f(const bool&);
void f(const int&);
void f(const _Complex int&);
void f(const C&);

C aggregate_return();

bool& bool_reference_return();
int& int_reference_return();
_Complex int& complex_int_reference_return();
C& aggregate_reference_return();

void test_bool() {
  bool a = true;
  f(a);

  f(true);
  
  bool_reference_return() = true;
  a = bool_reference_return();
}

void test_scalar() {
  int a = 10;
  f(a);
  
  struct { int bitfield : 3; } s = { 3 };
  f(s.bitfield);
  
  f(10);

  __attribute((vector_size(16))) typedef int vec4;
  f((vec4){1,2,3,4}[0]);
  
  int_reference_return() = 10;
  a = int_reference_return();
}

void test_complex() {
  _Complex int a = 10i;
  f(a);
  
  f(10i);
  
  complex_int_reference_return() = 10i;
  a = complex_int_reference_return();
}

void test_aggregate() {
  C c;
  f(c);

  f(aggregate_return());
  aggregate_reference_return().a = 10;

  c = aggregate_reference_return();
}

int& reference_return() {
  return g;
}

int reference_decl() {
  int& a = g;
  const int& b = 1;
  return a+b;
}

struct A {
  int& b();
};

void f(A* a) {
  int b = a->b();
}

// PR5122
void *foo = 0;
void * const & kFoo = foo;

struct D : C { D(); ~D(); };

void h() {
  // CHECK: call void @_ZN1DD1Ev
  const C& c = D();
}

namespace T {
  struct A {
    A();
    ~A();
  };

  struct B {
    B();
    ~B();
    A f();
  };

  void f() {
    // CHECK: call void @_ZN1T1BC1Ev
    // CHECK: call void @_ZN1T1B1fEv
    // CHECK: call void @_ZN1T1BD1Ev
    const A& a = B().f();
    // CHECK: call void @_ZN1T1fEv
    f();
    // CHECK: call void @_ZN1T1AD1Ev
  }
}

// PR5227.
namespace PR5227 {
void f(int &a) {
  (a = 10) = 20;
}
}