xref: /aosp_15_r20/external/clang/test/SemaCXX/references.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify %s
2*67e74705SXin Li int g(int);
3*67e74705SXin Li 
f()4*67e74705SXin Li void f() {
5*67e74705SXin Li   int i;
6*67e74705SXin Li   int &r = i;
7*67e74705SXin Li   r = 1;
8*67e74705SXin Li   int *p = &r;
9*67e74705SXin Li   int &rr = r;
10*67e74705SXin Li   int (&rg)(int) = g;
11*67e74705SXin Li   rg(i);
12*67e74705SXin Li   int a[3];
13*67e74705SXin Li   int (&ra)[3] = a;
14*67e74705SXin Li   ra[1] = i;
15*67e74705SXin Li   int *Q;
16*67e74705SXin Li   int *& P = Q;
17*67e74705SXin Li   P[1] = 1;
18*67e74705SXin Li }
19*67e74705SXin Li 
20*67e74705SXin Li typedef int t[1];
test2()21*67e74705SXin Li void test2() {
22*67e74705SXin Li     t a;
23*67e74705SXin Li     t& b = a;
24*67e74705SXin Li 
25*67e74705SXin Li 
26*67e74705SXin Li     int c[3];
27*67e74705SXin Li     int (&rc)[3] = c;
28*67e74705SXin Li }
29*67e74705SXin Li 
30*67e74705SXin Li // C++ [dcl.init.ref]p5b1
31*67e74705SXin Li struct A { };
32*67e74705SXin Li struct B : A { } b;
33*67e74705SXin Li 
test3()34*67e74705SXin Li void test3() {
35*67e74705SXin Li   double d = 2.0;
36*67e74705SXin Li   double& rd = d; // rd refers to d
37*67e74705SXin Li   const double& rcd = d; // rcd refers to d
38*67e74705SXin Li 
39*67e74705SXin Li   A& ra = b; // ra refers to A subobject in b
40*67e74705SXin Li   const A& rca = b; // rca refers to A subobject in b
41*67e74705SXin Li }
42*67e74705SXin Li 
43*67e74705SXin Li B fB();
44*67e74705SXin Li 
45*67e74705SXin Li // C++ [dcl.init.ref]p5b2
test4()46*67e74705SXin Li void test4() {
47*67e74705SXin Li   double& rd2 = 2.0; // expected-error{{non-const lvalue reference to type 'double' cannot bind to a temporary of type 'double'}}
48*67e74705SXin Li   int i = 2;
49*67e74705SXin Li   double& rd3 = i; // expected-error{{non-const lvalue reference to type 'double' cannot bind to a value of unrelated type 'int'}}
50*67e74705SXin Li 
51*67e74705SXin Li   const A& rca = fB();
52*67e74705SXin Li }
53*67e74705SXin Li 
test5()54*67e74705SXin Li void test5() {
55*67e74705SXin Li   //  const double& rcd2 = 2; // rcd2 refers to temporary with value 2.0
56*67e74705SXin Li   const volatile int cvi = 1;
57*67e74705SXin Li   const int& r = cvi; // expected-error{{binding value of type 'const volatile int' to reference to type 'const int' drops 'volatile' qualifier}}
58*67e74705SXin Li }
59*67e74705SXin Li 
60*67e74705SXin Li // C++ [dcl.init.ref]p3
test6(int & x)61*67e74705SXin Li int& test6(int& x) {
62*67e74705SXin Li   int& yo; // expected-error{{declaration of reference variable 'yo' requires an initializer}}
63*67e74705SXin Li 
64*67e74705SXin Li   return x;
65*67e74705SXin Li }
66*67e74705SXin Li int& not_initialized_error; // expected-error{{declaration of reference variable 'not_initialized_error' requires an initializer}}
67*67e74705SXin Li extern int& not_initialized_okay;
68*67e74705SXin Li 
69*67e74705SXin Li class Test6 { // expected-warning{{class 'Test6' does not declare any constructor to initialize its non-modifiable members}}
70*67e74705SXin Li   int& okay; // expected-note{{reference member 'okay' will never be initialized}}
71*67e74705SXin Li };
72*67e74705SXin Li 
73*67e74705SXin Li struct C : B, A { }; // expected-warning {{direct base 'A' is inaccessible due to ambiguity:\n    struct C -> struct B -> struct A\nstruct C -> struct A}}
74*67e74705SXin Li 
test7(C & c)75*67e74705SXin Li void test7(C& c) {
76*67e74705SXin Li   A& a1 = c; // expected-error {{ambiguous conversion from derived class 'C' to base class 'A':}}
77*67e74705SXin Li }
78*67e74705SXin Li 
79*67e74705SXin Li // C++ [dcl.ref]p1, C++ [dcl.ref]p4
test8(int & const,void &,int & &)80*67e74705SXin Li void test8(int& const,// expected-error{{'const' qualifier may not be applied to a reference}}
81*67e74705SXin Li 
82*67e74705SXin Li            void&,     // expected-error{{cannot form a reference to 'void'}}
83*67e74705SXin Li            int& &)    // expected-error{{type name declared as a reference to a reference}}
84*67e74705SXin Li {
85*67e74705SXin Li   typedef int& intref;
86*67e74705SXin Li   typedef intref& intrefref; // C++ DR 106: reference collapsing
87*67e74705SXin Li 
88*67e74705SXin Li   typedef intref const intref_c; // expected-warning {{'const' qualifier on reference type 'intref' (aka 'int &') has no effect}}
89*67e74705SXin Li   typedef intref_c intref; // ok, same type
90*67e74705SXin Li 
91*67e74705SXin Li   typedef intref volatile intref; // expected-warning {{'volatile' qualifier on reference type 'intref' (aka 'int &') has no effect}}
92*67e74705SXin Li   typedef intref _Atomic intref; // expected-warning {{'_Atomic' qualifier on reference type 'intref' (aka 'int &') has no effect}}
93*67e74705SXin Li 
94*67e74705SXin Li   void restrict_ref(__restrict intref); // ok
95*67e74705SXin Li   void restrict_ref(int &__restrict); // ok
96*67e74705SXin Li }
97*67e74705SXin Li 
const_param(const T)98*67e74705SXin Li template<typename T> int const_param(const T) {}
99*67e74705SXin Li int const_ref_param = const_param<int&>(const_ref_param); // no-warning
100*67e74705SXin Li 
101*67e74705SXin Li 
102*67e74705SXin Li class string {
103*67e74705SXin Li   char *Data;
104*67e74705SXin Li   unsigned Length;
105*67e74705SXin Li public:
106*67e74705SXin Li   string();
107*67e74705SXin Li   ~string();
108*67e74705SXin Li };
109*67e74705SXin Li 
110*67e74705SXin Li string getInput();
111*67e74705SXin Li 
test9()112*67e74705SXin Li void test9() {
113*67e74705SXin Li   string &s = getInput(); // expected-error{{lvalue reference}}
114*67e74705SXin Li }
115*67e74705SXin Li 
test10()116*67e74705SXin Li void test10() {
117*67e74705SXin Li   __attribute((vector_size(16))) typedef int vec4;
118*67e74705SXin Li   typedef __attribute__(( ext_vector_type(4) )) int ext_vec4;
119*67e74705SXin Li 
120*67e74705SXin Li   vec4 v;
121*67e74705SXin Li   int &a = v[0]; // expected-error{{non-const reference cannot bind to vector element}}
122*67e74705SXin Li   const int &b = v[0];
123*67e74705SXin Li 
124*67e74705SXin Li   ext_vec4 ev;
125*67e74705SXin Li   int &c = ev.x; // expected-error{{non-const reference cannot bind to vector element}}
126*67e74705SXin Li   const int &d = ev.x;
127*67e74705SXin Li }
128*67e74705SXin Li 
129*67e74705SXin Li namespace PR7149 {
130*67e74705SXin Li   template<typename T> struct X0
131*67e74705SXin Li   {
132*67e74705SXin Li     T& first;
X0PR7149::X0133*67e74705SXin Li     X0(T& p1) : first(p1) { }
134*67e74705SXin Li   };
135*67e74705SXin Li 
136*67e74705SXin Li 
f()137*67e74705SXin Li   void f()
138*67e74705SXin Li   {
139*67e74705SXin Li     int p1[1];
140*67e74705SXin Li     X0< const int[1]> c(p1);
141*67e74705SXin Li   }
142*67e74705SXin Li }
143*67e74705SXin Li 
144*67e74705SXin Li namespace PR8608 {
f(unsigned char & c)145*67e74705SXin Li   bool& f(unsigned char& c) { return (bool&)c; }
146*67e74705SXin Li }
147*67e74705SXin Li 
148*67e74705SXin Li // The following crashed trying to recursively evaluate the LValue.
149*67e74705SXin Li const int &do_not_crash = do_not_crash; // expected-warning{{reference 'do_not_crash' is not yet bound to a value when used within its own initialization}}
150*67e74705SXin Li 
151*67e74705SXin Li namespace ExplicitRefInit {
152*67e74705SXin Li   // This is invalid: we can't copy-initialize an 'A' temporary using an
153*67e74705SXin Li   // explicit constructor.
154*67e74705SXin Li   struct A { explicit A(int); };
155*67e74705SXin Li   const A &a(0); // expected-error {{reference to type 'const ExplicitRefInit::A' could not bind to an rvalue of type 'int'}}
156*67e74705SXin Li }
157