// RUN: %clang_cc1 -fsyntax-only -std=c++03 -fdiagnostics-show-option -Wbind-to-temporary-copy -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(); // expected-note{{requires 0 arguments, but 1 was provided}} private: X3(X3&); // expected-note{{candidate constructor not viable: expects an l-value 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(); // expected-note {{requires 0 arguments}} X5(const X5&, const X5& = X5()); // expected-warning{{no viable constructor copying parameter of type 'X5'}} expected-note {{requires 2 arguments}} }; 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. } |