p5-var.cpp revision ccfe15ea60d055936a15b370765006c10c25d81a
1// RUN: %clang_cc1 -fsyntax-only -verify %s 2 3struct Base { }; // expected-note{{candidate function}} 4struct Derived : Base { }; // expected-note{{candidate function}} 5struct Unrelated { }; 6struct Derived2 : Base { }; 7struct Diamond : Derived, Derived2 { }; 8 9struct ConvertibleToBaseRef { 10 operator Base&() const; 11}; 12 13struct ConvertibleToDerivedRef { 14 operator Derived&() const; 15}; 16 17struct ConvertibleToBothDerivedRef { 18 operator Derived&(); // expected-note{{candidate function}} 19 operator Derived2&(); // expected-note{{candidate function}} 20}; 21 22struct ConvertibleToIntRef { 23 operator int&(); 24}; 25 26struct ConvertibleToBase { 27 operator Base() const; 28}; 29 30struct ConvertibleToDerived { 31 operator Derived() const; 32}; 33 34struct ConvertibleToBothDerived { 35 operator Derived(); // expected-note{{candidate function}} 36 operator Derived2(); // expected-note{{candidate function}} 37}; 38 39struct ConvertibleToInt { 40 operator int(); 41}; 42 43template<typename T> T create(); 44 45// First bullet: lvalue references binding to lvalues (the simple cases). 46void bind_lvalue_to_lvalue(Base b, Derived d, 47 const Base bc, const Derived dc, 48 Diamond diamond, 49 int i) { 50 // Reference-compatible 51 Base &br1 = b; 52 Base &br2 = d; 53 Derived &dr1 = d; 54 Derived &dr2 = b; // expected-error{{non-const lvalue reference to type 'struct Derived' cannot bind to a value of unrelated type 'struct Base'}} 55 Base &br3 = bc; // expected-error{{drops qualifiers}} 56 Base &br4 = dc; // expected-error{{drops qualifiers}} 57 Base &br5 = diamond; // expected-error{{ambiguous conversion from derived class 'struct Diamond' to base class 'struct Base'}} 58 int &ir = i; 59 long &lr = i; // expected-error{{non-const lvalue reference to type 'long' cannot bind to a value of unrelated type 'int'}} 60} 61 62void bind_lvalue_quals(volatile Base b, volatile Derived d, 63 volatile const Base bvc, volatile const Derived dvc, 64 volatile const int ivc) { 65 volatile Base &bvr1 = b; 66 volatile Base &bvr2 = d; 67 volatile Base &bvr3 = bvc; // expected-error{{binding of reference to type 'struct Base volatile' to a value of type 'struct Base const volatile' drops qualifiers}} 68 volatile Base &bvr4 = dvc; // expected-error{{binding of reference to type 'struct Base volatile' to a value of type 'struct Derived const volatile' drops qualifiers}} 69 70 volatile int &ir = ivc; // expected-error{{binding of reference to type 'int volatile' to a value of type 'int const volatile' drops qualifiers}} 71} 72 73void bind_lvalue_to_rvalue() { 74 Base &br1 = Base(); // expected-error{{non-const lvalue reference to type 'struct Base' cannot bind to a temporary of type 'struct Base'}} 75 Base &br2 = Derived(); // expected-error{{non-const lvalue reference to type 'struct Base' cannot bind to a temporary of type 'struct Derived'}} 76 77 int &ir = 17; // expected-error{{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}} 78} 79 80void bind_lvalue_to_unrelated(Unrelated ur) { 81 Base &br1 = ur; // expected-error{{non-const lvalue reference to type 'struct Base' cannot bind to a value of unrelated type 'struct Unrelated'}} 82} 83 84void bind_lvalue_to_conv_lvalue() { 85 // Not reference-related, but convertible 86 Base &nbr1 = ConvertibleToBaseRef(); 87 Base &nbr2 = ConvertibleToDerivedRef(); 88 Derived &ndr1 = ConvertibleToDerivedRef(); 89 int &ir = ConvertibleToIntRef(); 90} 91 92void bind_lvalue_to_conv_lvalue_ambig(ConvertibleToBothDerivedRef both) { 93 Derived &dr1 = both; 94 Base &br1 = both; // expected-error{{reference initialization of type 'struct Base &' with initializer of type 'struct ConvertibleToBothDerivedRef' is ambiguous}} 95} 96 97struct IntBitfield { 98 int i : 17; // expected-note{{bit-field is declared here}} 99}; 100 101void test_bitfield(IntBitfield ib) { 102 int & ir1 = (ib.i); // expected-error{{non-const reference cannot bind to bit-field 'i'}} 103} 104 105// Second bullet: const lvalue reference binding to an rvalue with 106// similar type (both of which are class types). 107void bind_const_lvalue_to_rvalue() { 108 const Base &br1 = create<Base>(); 109 const Base &br2 = create<Derived>(); 110 const Derived &dr1 = create<Base>(); // expected-error{{no viable conversion}} 111 112 const Base &br3 = create<const Base>(); 113 const Base &br4 = create<const Derived>(); 114 115 const Base &br5 = create<const volatile Base>(); // expected-error{{binding of reference to type 'struct Base const' to a value of type 'struct Base const volatile' drops qualifiers}} 116 const Base &br6 = create<const volatile Derived>(); // expected-error{{binding of reference to type 'struct Base const' to a value of type 'struct Derived const volatile' drops qualifiers}} 117 118 const int &ir = create<int>(); 119} 120 121// Second bullet: const lvalue reference binds to the result of a conversion. 122void bind_const_lvalue_to_class_conv_temporary() { 123 const Base &br1 = ConvertibleToBase(); 124 const Base &br2 = ConvertibleToDerived(); 125} 126void bind_lvalue_to_conv_rvalue_ambig(ConvertibleToBothDerived both) { 127 const Derived &dr1 = both; 128 const Base &br1 = both; // expected-error{{reference initialization of type 'struct Base const &' with initializer of type 'struct ConvertibleToBothDerived' is ambiguous}} 129} 130