summaryrefslogtreecommitdiff
path: root/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref')
-rw-r--r--clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/basic.cpp19
-rw-r--r--clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p1.cpp14
-rw-r--r--clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p3.cpp3
-rw-r--r--clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp194
-rw-r--r--clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp77
-rw-r--r--clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx0x-no-extra-copy.cpp64
-rw-r--r--clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp53
-rw-r--r--clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp135
-rw-r--r--clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp40
9 files changed, 599 insertions, 0 deletions
diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/basic.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/basic.cpp
new file mode 100644
index 0000000..885d11b
--- /dev/null
+++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/basic.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR5787
+class C {
+ public:
+ ~C() {}
+};
+
+template <typename T>
+class E {
+ public:
+ E& Foo(const C&);
+ E& Bar() { return Foo(C()); }
+};
+
+void Test() {
+ E<int> e;
+ e.Bar();
+}
diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p1.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p1.cpp
new file mode 100644
index 0000000..20c059e
--- /dev/null
+++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p1.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+int g(int);
+void f() {
+ int i;
+ int& r = i;
+ r = 1;
+ int* p = &r;
+ int &rr=r;
+ int (&rg)(int) = g;
+ rg(i);
+ int a[3];
+ int (&ra)[3] = a;
+ ra[1] = i;
+}
diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p3.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p3.cpp
new file mode 100644
index 0000000..47e215a
--- /dev/null
+++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p3.cpp
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+int& r1; // expected-error{{declaration of reference variable 'r1' requires an initializer}}
+extern int& r2;
diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp
new file mode 100644
index 0000000..adbdff6
--- /dev/null
+++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp
@@ -0,0 +1,194 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -pedantic %s
+
+// Test the c++0x-specific reference initialization rules, e.g., the
+// rules for rvalue references.
+template<typename T> T prvalue();
+template<typename T> T&& xvalue();
+template<typename T> T& lvalue();
+
+struct Base { };
+struct Derived : Base { };
+
+struct HasArray {
+ int array[5];
+};
+
+int f(int);
+
+template<typename T>
+struct ConvertsTo {
+ operator T(); // expected-note 2{{candidate function}}
+};
+
+void test_rvalue_refs() {
+ // If the initializer expression...
+ // - is an xvalue, class prvalue, array prvalue or function lvalue
+ // and "cv1 T1" is reference-compatible with "cv2 T2", or
+
+ // xvalue case
+ Base&& base0 = xvalue<Base>();
+ Base&& base1 = xvalue<Derived>();
+ int&& int0 = xvalue<int>();
+
+ // class prvalue case
+ Base&& base2 = prvalue<Base>();
+ Base&& base3 = prvalue<Derived>();
+
+ // array prvalue case
+ int (&&array0)[5] = HasArray().array;
+
+ // function lvalue case
+ int (&&function0)(int) = f;
+
+ // - has a class type (i.e., T2 is a class type), where T1 is not
+ // reference-related to T2, and can be implicitly converted to
+ // an xvalue, class prvalue, or function lvalue of type "cv3
+ // T3", where "cv1 T1" is reference-compatible with "cv3 T3",
+
+ // xvalue
+ Base&& base4 = ConvertsTo<Base&&>();
+ Base&& base5 = ConvertsTo<Derived&&>();
+ int && int1 = ConvertsTo<int&&>();
+
+ // class prvalue
+ Base&& base6 = ConvertsTo<Base>();
+ Base&& base7 = ConvertsTo<Derived>();
+
+ // function lvalue
+ int (&&function1)(int) = ConvertsTo<int(&)(int)>();
+
+ // In the second case, if the reference is an rvalue reference and
+ // the second standard conversion sequence of the user-defined
+ // conversion sequence includes an lvalue-to-rvalue conversion, the
+ // program is ill-formed.
+ int &&int2 = ConvertsTo<int&>(); // expected-error{{no viable conversion from 'ConvertsTo<int &>' to 'int'}}
+ int &&int3 = ConvertsTo<float&>(); // expected-error{{no viable conversion from 'ConvertsTo<float &>' to 'int'}}
+}
+
+class NonCopyable {
+ NonCopyable(const NonCopyable&);
+};
+
+class NonCopyableDerived : public NonCopyable {
+ NonCopyableDerived(const NonCopyableDerived&);
+};
+
+// Make sure we get direct bindings with no copies.
+void test_direct_binding() {
+ NonCopyable &&nc0 = prvalue<NonCopyable>();
+ NonCopyable &&nc1 = prvalue<NonCopyableDerived>();
+ NonCopyable &&nc2 = xvalue<NonCopyable>();
+ NonCopyable &&nc3 = xvalue<NonCopyableDerived>();
+ const NonCopyable &nc4 = prvalue<NonCopyable>();
+ const NonCopyable &nc5 = prvalue<NonCopyableDerived>();
+ const NonCopyable &nc6 = xvalue<NonCopyable>();
+ const NonCopyable &nc7 = xvalue<NonCopyableDerived>();
+ NonCopyable &&nc8 = ConvertsTo<NonCopyable&&>();
+ NonCopyable &&nc9 = ConvertsTo<NonCopyableDerived&&>();
+ const NonCopyable &nc10 = ConvertsTo<NonCopyable&&>();
+ const NonCopyable &nc11 = ConvertsTo<NonCopyableDerived&&>();
+}
+
+namespace std_example_1 {
+ double d = 2.0;
+ double& rd = d;
+ const double& rcd = d;
+ struct A { };
+ struct B : A {
+ operator int&();
+ } b;
+ A& ra = b;
+ const A& rca = b;
+ int& ir = B();
+}
+
+namespace std_example_2 {
+ double& rd2 = 2.0; // expected-error{{non-const lvalue reference to type 'double' cannot bind to a temporary of type 'double'}}
+ int i = 2;
+ double& rd3 = i; // expected-error{{non-const lvalue reference to type 'double' cannot bind to a value of unrelated type 'int'}}
+ struct A { };
+ struct B : A { } b;
+ extern B f();
+ const A& rca = f();
+ A&& rra = f();
+ struct X {
+ operator B(); // expected-note{{candidate function}}
+ operator int&(); // expected-note{{candidate function}}
+ } x;
+ const A& r = x;
+ int&& rri = static_cast<int&&>(i);
+ B&& rrb = x;
+ int&& rri2 = X(); // expected-error{{no viable conversion from 'std_example_2::X' to 'int'}}
+
+ const double& rcd2 = 2;
+ double&& rrd = 2;
+ const volatile int cvi = 1;
+ const int& r2 = cvi; // expected-error{{binding of reference to type 'const int' to a value of type 'const volatile int' drops qualifiers}}
+
+ double d;
+ double&& rrd2 = d; // expected-error{{rvalue reference to type 'double' cannot bind to lvalue of type 'double'}}
+ double&& rrd3 = i;
+}
+
+namespace argument_passing {
+ void base_rvalue_ref(Base&&);
+ void int_rvalue_ref(int&&); // expected-note{{candidate function not viable: no known conversion from 'ConvertsTo<int &>' to 'int &&' for 1st argument}} \
+ // expected-note{{candidate function not viable: no known conversion from 'ConvertsTo<float &>' to 'int &&' for 1st argument}}
+
+ void array_rvalue_ref(int (&&)[5]);
+ void function_rvalue_ref(int (&&)(int));
+
+ void test() {
+ base_rvalue_ref(xvalue<Base>());
+ base_rvalue_ref(xvalue<Derived>());
+ int_rvalue_ref(xvalue<int>());
+
+ base_rvalue_ref(prvalue<Base>());
+ base_rvalue_ref(prvalue<Derived>());
+
+ array_rvalue_ref(HasArray().array);
+
+ function_rvalue_ref(f);
+
+ base_rvalue_ref(ConvertsTo<Base&&>());
+ base_rvalue_ref(ConvertsTo<Derived&&>());
+ int_rvalue_ref(ConvertsTo<int&&>());
+
+ base_rvalue_ref(ConvertsTo<Base>());
+ base_rvalue_ref(ConvertsTo<Derived>());
+
+ function_rvalue_ref(ConvertsTo<int(&)(int)>());
+
+ int_rvalue_ref(ConvertsTo<int&>()); // expected-error{{no matching function for call to 'int_rvalue_ref'}}
+ int_rvalue_ref(ConvertsTo<float&>()); // expected-error{{no matching function for call to 'int_rvalue_ref'}}
+ }
+
+}
+
+namespace pr10644 {
+ struct string {
+ string(const char* __s);
+ };
+ class map {
+ int& operator[](const string& __k);
+ public:
+ int& operator[](const string&& __k);
+ };
+ void foo() {
+ static map key_map;
+ key_map["line"];
+ }
+}
+
+namespace PR11003 {
+ class Value {
+ };
+ struct MoveRef {
+ operator Value &() const ;
+ };
+ MoveRef Move(int);
+ void growTo() {
+ Value x = Move(0);
+ Value y(Move(0));
+ }
+}
diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp
new file mode 100644
index 0000000..d58a129
--- /dev/null
+++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp
@@ -0,0 +1,77 @@
+// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-show-option -verify %s
+
+// C++03 requires that we check for a copy constructor when binding a
+// reference to a temporary, since we are allowed to make a copy, Even
+// though we don't actually make that copy, make sure that we diagnose
+// cases where that copy constructor is somehow unavailable. As an
+// extension, this is only a warning.
+
+struct X1 {
+ X1();
+ explicit X1(const X1&);
+};
+
+struct X2 {
+ X2();
+
+private:
+ X2(const X2&); // expected-note{{declared private here}}
+};
+
+struct X3 {
+ X3();
+
+private:
+ X3(X3&); // expected-note{{candidate constructor not viable: no known conversion from 'X3' to 'X3 &' for 1st argument}}
+};
+
+// Check for instantiation of default arguments
+template<typename T>
+T get_value_badly() {
+ double *dp = 0;
+ // The extension doesn't extend far enough to turn this error into a warning.
+ T *tp = dp; // expected-error{{cannot initialize a variable of type 'int *' with an lvalue of type 'double *'}}
+ return T();
+}
+
+template<typename T>
+struct X4 {
+ X4();
+ X4(const X4&, T = get_value_badly<T>()); // expected-note{{in instantiation of}}
+};
+
+// Check for "dangerous" default arguments that could cause recursion.
+struct X5 {
+ X5();
+ X5(const X5&, const X5& = X5()); // expected-warning{{no viable constructor copying parameter of type 'X5'}}
+};
+
+void g1(const X1&);
+void g2(const X2&);
+void g3(const X3&);
+void g4(const X4<int>&);
+void g5(const X5&);
+
+void test() {
+ g1(X1());
+ g2(X2()); // expected-warning{{C++98 requires an accessible copy constructor for class 'X2' when binding a reference to a temporary; was private}}
+ g3(X3()); // expected-warning{{no viable constructor copying parameter of type 'X3'}}
+ g4(X4<int>());
+ g5(X5()); // Generates a warning in the default argument.
+}
+
+// Check that unavailable copy constructors still cause SFINAE failures.
+template<int> struct int_c { };
+
+template<typename T> T f(const T&);
+
+// Would be ambiguous with the next g(), except the instantiation failure in
+// sizeof() prevents that.
+template<typename T>
+int &g(int_c<sizeof(f(T()))> * = 0);
+
+template<typename T> float &g();
+
+void h() {
+ float &fp2 = g<X3>(); // Not ambiguous.
+}
diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx0x-no-extra-copy.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx0x-no-extra-copy.cpp
new file mode 100644
index 0000000..27eb6d1
--- /dev/null
+++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx0x-no-extra-copy.cpp
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+// C++03 requires that we check for a copy constructor when binding a
+// reference to a reference-compatible rvalue, since we are allowed to
+// make a copy. C++0x does not permit the copy, so ensure that we
+// don't diagnose cases where the copy constructor is unavailable.
+
+struct X1 {
+ X1();
+ explicit X1(const X1&);
+};
+
+struct X2 {
+ X2();
+
+private:
+ X2(const X2&);
+};
+
+struct X3 {
+ X3();
+
+private:
+ X3(X3&);
+};
+
+template<typename T>
+T get_value_badly() {
+ double *dp = 0;
+ T *tp = dp;
+ return T();
+}
+
+template<typename T>
+struct X4 {
+ X4();
+ X4(const X4&, T = get_value_badly<T>());
+};
+
+void g1(const X1&);
+void g2(const X2&);
+void g3(const X3&);
+void g4(const X4<int>&);
+
+void test() {
+ g1(X1());
+ g2(X2());
+ g3(X3());
+ g4(X4<int>());
+}
+
+// Check that unavailable copy constructors do not cause SFINAE failures.
+template<int> struct int_c { };
+
+template<typename T> T f(const T&);
+
+template<typename T>
+int &g(int_c<sizeof(f(T()))> * = 0); // expected-note{{candidate function [with T = X3]}}
+
+template<typename T> float &g(); // expected-note{{candidate function [with T = X3]}}
+
+void h() {
+ float &fp = g<X3>(); // expected-error{{call to 'g' is ambiguous}}
+}
diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp
new file mode 100644
index 0000000..08d9639
--- /dev/null
+++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -ast-dump %s 2>&1 | FileCheck %s
+
+// CHECK: example0
+void example0() {
+ double d = 2.0;
+ // CHECK: double &rd =
+ // CHECK-NEXT: DeclRefExpr
+ double &rd = d;
+ // CHECK: const double &rcd =
+ // CHECK-NEXT: ImplicitCastExpr{{.*}}'const double' lvalue <NoOp>
+ const double &rcd = d;
+}
+
+struct A { };
+struct B : A { } b;
+
+// CHECK: example1
+void example1() {
+ // CHECK: A &ra =
+ // CHECK: ImplicitCastExpr{{.*}}'struct A' lvalue <DerivedToBase (A)>
+ A &ra = b;
+ // CHECK: const A &rca =
+ // CHECK: ImplicitCastExpr{{.*}}'const struct A' lvalue <NoOp>
+ // CHECK: ImplicitCastExpr{{.*}}'struct A' lvalue <DerivedToBase (A)>
+ const A& rca = b;
+}
+
+extern B f();
+
+struct X {
+ operator B();
+} x;
+
+// CHECK: example2
+void example2() {
+ // CHECK: const A &rca =
+ // CHECK: ImplicitCastExpr{{.*}}'const struct A' <NoOp>
+ // CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase (A)>
+ // CHECK: CallExpr{{.*}}B
+ const A &rca = f();
+ // CHECK: const A &r =
+ // CHECK: ImplicitCastExpr{{.*}}'const struct A' <NoOp>
+ // CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase (A)>
+ // CHECK: CXXMemberCallExpr{{.*}}'struct B'
+ const A& r = x;
+}
+
+// CHECK: example3
+void example3() {
+ // CHECK: const double &rcd2 =
+ // CHECK: ImplicitCastExpr{{.*}} <IntegralToFloating>
+ const double& rcd2 = 2;
+}
diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp
new file mode 100644
index 0000000..fee5f96
--- /dev/null
+++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp
@@ -0,0 +1,135 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct Base { };
+struct Derived : Base { }; // expected-note{{candidate constructor (the implicit copy constructor) not viable}}
+struct Unrelated { };
+struct Derived2 : Base { };
+struct Diamond : Derived, Derived2 { };
+
+struct ConvertibleToBaseRef {
+ operator Base&() const;
+};
+
+struct ConvertibleToDerivedRef {
+ operator Derived&() const;
+};
+
+struct ConvertibleToBothDerivedRef {
+ operator Derived&(); // expected-note{{candidate function}}
+ operator Derived2&(); // expected-note{{candidate function}}
+};
+
+struct ConvertibleToIntRef {
+ operator int&();
+};
+
+struct ConvertibleToBase {
+ operator Base() const;
+};
+
+struct ConvertibleToDerived {
+ operator Derived() const;
+};
+
+struct ConvertibleToBothDerived {
+ operator Derived(); // expected-note{{candidate function}}
+ operator Derived2(); // expected-note{{candidate function}}
+};
+
+struct ConvertibleToInt {
+ operator int();
+};
+
+template<typename T> T create();
+
+// First bullet: lvalue references binding to lvalues (the simple cases).
+void bind_lvalue_to_lvalue(Base b, Derived d,
+ const Base bc, const Derived dc,
+ Diamond diamond,
+ int i) {
+ // Reference-compatible
+ Base &br1 = b;
+ Base &br2 = d;
+ Derived &dr1 = d;
+ Derived &dr2 = b; // expected-error{{non-const lvalue reference to type 'Derived' cannot bind to a value of unrelated type 'Base'}}
+ Base &br3 = bc; // expected-error{{drops qualifiers}}
+ Base &br4 = dc; // expected-error{{drops qualifiers}}
+ Base &br5 = diamond; // expected-error{{ambiguous conversion from derived class 'Diamond' to base class 'Base':}}
+ int &ir = i;
+ long &lr = i; // expected-error{{non-const lvalue reference to type 'long' cannot bind to a value of unrelated type 'int'}}
+}
+
+void bind_lvalue_quals(volatile Base b, volatile Derived d,
+ volatile const Base bvc, volatile const Derived dvc,
+ volatile const int ivc) {
+ volatile Base &bvr1 = b;
+ volatile Base &bvr2 = d;
+ volatile Base &bvr3 = bvc; // expected-error{{binding of reference to type 'volatile Base' to a value of type 'const volatile Base' drops qualifiers}}
+ volatile Base &bvr4 = dvc; // expected-error{{binding of reference to type 'volatile Base' to a value of type 'const volatile Derived' drops qualifiers}}
+
+ volatile int &ir = ivc; // expected-error{{binding of reference to type 'volatile int' to a value of type 'const volatile int' drops qualifiers}}
+
+ const volatile Base &bcvr1 = b;
+ const volatile Base &bcvr2 = d;
+}
+
+void bind_lvalue_to_rvalue() {
+ Base &br1 = Base(); // expected-error{{non-const lvalue reference to type 'Base' cannot bind to a temporary of type 'Base'}}
+ Base &br2 = Derived(); // expected-error{{non-const lvalue reference to type 'Base' cannot bind to a temporary of type 'Derived'}}
+ const volatile Base &br3 = Base(); // expected-error{{volatile lvalue reference to type 'const volatile Base' cannot bind to a temporary of type 'Base'}}
+ const volatile Base &br4 = Derived(); // expected-error{{volatile lvalue reference to type 'const volatile Base' cannot bind to a temporary of type 'Derived'}}
+
+ int &ir = 17; // expected-error{{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}}
+}
+
+void bind_lvalue_to_unrelated(Unrelated ur) {
+ Base &br1 = ur; // expected-error{{non-const lvalue reference to type 'Base' cannot bind to a value of unrelated type 'Unrelated'}}
+ const volatile Base &br2 = ur; // expected-error{{volatile lvalue reference to type 'const volatile Base' cannot bind to a value of unrelated type 'Unrelated'}}
+}
+
+void bind_lvalue_to_conv_lvalue() {
+ // Not reference-related, but convertible
+ Base &nbr1 = ConvertibleToBaseRef();
+ Base &nbr2 = ConvertibleToDerivedRef();
+ Derived &ndr1 = ConvertibleToDerivedRef();
+ int &ir = ConvertibleToIntRef();
+}
+
+void bind_lvalue_to_conv_lvalue_ambig(ConvertibleToBothDerivedRef both) {
+ Derived &dr1 = both;
+ Base &br1 = both; // expected-error{{reference initialization of type 'Base &' with initializer of type 'ConvertibleToBothDerivedRef' is ambiguous}}
+}
+
+struct IntBitfield {
+ int i : 17; // expected-note{{bit-field is declared here}}
+};
+
+void test_bitfield(IntBitfield ib) {
+ int & ir1 = (ib.i); // expected-error{{non-const reference cannot bind to bit-field 'i'}}
+}
+
+// Second bullet: const lvalue reference binding to an rvalue with
+// similar type (both of which are class types).
+void bind_const_lvalue_to_rvalue() {
+ const Base &br1 = create<Base>();
+ const Base &br2 = create<Derived>();
+ const Derived &dr1 = create<Base>(); // expected-error{{no viable conversion}}
+
+ const Base &br3 = create<const Base>();
+ const Base &br4 = create<const Derived>();
+
+ 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}}
+ 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}}
+
+ const int &ir = create<int>();
+}
+
+// Second bullet: const lvalue reference binds to the result of a conversion.
+void bind_const_lvalue_to_class_conv_temporary() {
+ const Base &br1 = ConvertibleToBase();
+ const Base &br2 = ConvertibleToDerived();
+}
+void bind_lvalue_to_conv_rvalue_ambig(ConvertibleToBothDerived both) {
+ const Derived &dr1 = both;
+ const Base &br1 = both; // expected-error{{reference initialization of type 'const Base &' with initializer of type 'ConvertibleToBothDerived' is ambiguous}}
+}
diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp
new file mode 100644
index 0000000..51d61a5
--- /dev/null
+++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace PR5909 {
+ struct Foo {
+ int x : 20;
+ };
+
+ bool Test(const int& foo);
+
+ const Foo f = { 0 }; // It compiles without the 'const'.
+ bool z = Test(f.x);
+}
+
+namespace PR6264 {
+ typedef int (&T)[3];
+ struct S
+ {
+ operator T ();
+ };
+ void f()
+ {
+ T bar = S();
+ }
+}
+
+namespace PR6066 {
+ struct B { };
+ struct A : B {
+ operator B*();
+ operator B&(); // expected-warning{{conversion function converting 'PR6066::A' to its base class 'PR6066::B' will never be used}}
+ };
+
+ void f(B&); // no rvalues accepted
+ void f(B*);
+
+ int g() {
+ f(A()); // calls f(B*)
+ return 0;
+ }
+}