p5-cxx03-extra-copy.cpp revision 0d3317e0a2e0adb57ce8d075ebdcb41a3f939805
1// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-show-option -verify %s 2 3// C++03 requires that we check for a copy constructor when binding a 4// reference to a temporary, since we are allowed to make a copy, Even 5// though we don't actually make that copy, make sure that we diagnose 6// cases where that copy constructor is somehow unavailable. As an 7// extension, this is only a warning. 8 9struct X1 { 10 X1(); 11 explicit X1(const X1&); 12}; 13 14struct X2 { 15 X2(); 16 17private: 18 X2(const X2&); // expected-note{{declared private here}} 19}; 20 21struct X3 { 22 X3(); 23 24private: 25 X3(X3&); // expected-note{{candidate constructor not viable: expects an l-value for 1st argument}} 26}; 27 28// Check for instantiation of default arguments 29template<typename T> 30T get_value_badly() { 31 double *dp = 0; 32 // The extension doesn't extend far enough to turn this error into a warning. 33 T *tp = dp; // expected-error{{cannot initialize a variable of type 'int *' with an lvalue of type 'double *'}} 34 return T(); 35} 36 37template<typename T> 38struct X4 { 39 X4(); 40 X4(const X4&, T = get_value_badly<T>()); // expected-note{{in instantiation of}} 41}; 42 43// Check for "dangerous" default arguments that could cause recursion. 44struct X5 { 45 X5(); 46 X5(const X5&, const X5& = X5()); // expected-warning{{no viable constructor copying parameter of type 'X5'}} 47}; 48 49void g1(const X1&); 50void g2(const X2&); 51void g3(const X3&); 52void g4(const X4<int>&); 53void g5(const X5&); 54 55void test() { 56 g1(X1()); 57 g2(X2()); // expected-warning{{C++98 requires an accessible copy constructor for class 'X2' when binding a reference to a temporary; was private}} 58 g3(X3()); // expected-warning{{no viable constructor copying parameter of type 'X3'}} 59 g4(X4<int>()); 60 g5(X5()); // Generates a warning in the default argument. 61} 62 63// Check that unavailable copy constructors still cause SFINAE failures. 64template<int> struct int_c { }; 65 66template<typename T> T f(const T&); 67 68// Would be ambiguous with the next g(), except the instantiation failure in 69// sizeof() prevents that. 70template<typename T> 71int &g(int_c<sizeof(f(T()))> * = 0); 72 73template<typename T> float &g(); 74 75void h() { 76 float &fp2 = g<X3>(); // Not ambiguous. 77} 78