1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify %s 2*67e74705SXin Li int g(int); 3*67e74705SXin Li f()4*67e74705SXin Livoid 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 Livoid 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 Livoid 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 Livoid 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 Livoid 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 Liint& 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 Livoid 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 Livoid 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 Litemplate<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 Livoid test9() { 113*67e74705SXin Li string &s = getInput(); // expected-error{{lvalue reference}} 114*67e74705SXin Li } 115*67e74705SXin Li test10()116*67e74705SXin Livoid 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