Home | History | Annotate | Download | only in dcl.init.ref
      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