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