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