1 | // RUN: %clang_cc1 -fsyntax-only -std=c++03 -fdiagnostics-show-option -Wbind-to-temporary-copy -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 | |
9 | struct X1 { |
10 | X1(); |
11 | explicit X1(const X1&); |
12 | }; |
13 | |
14 | struct X2 { |
15 | X2(); |
16 | |
17 | private: |
18 | X2(const X2&); // expected-note{{declared private here}} |
19 | }; |
20 | |
21 | struct X3 { |
22 | X3(); // expected-note{{requires 0 arguments, but 1 was provided}} |
23 | |
24 | private: |
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 |
29 | template<typename T> |
30 | T 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 | |
37 | template<typename T> |
38 | struct 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. |
44 | struct X5 { |
45 | X5(); // expected-note {{requires 0 arguments}} |
46 | X5(const X5&, const X5& = X5()); // expected-warning{{no viable constructor copying parameter of type 'X5'}} expected-note {{requires 2 arguments}} |
47 | }; |
48 | |
49 | void g1(const X1&); |
50 | void g2(const X2&); |
51 | void g3(const X3&); |
52 | void g4(const X4<int>&); |
53 | void g5(const X5&); |
54 | |
55 | void 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. |
64 | template<int> struct int_c { }; |
65 | |
66 | template<typename T> T f(const T&); |
67 | |
68 | // Would be ambiguous with the next g(), except the instantiation failure in |
69 | // sizeof() prevents that. |
70 | template<typename T> |
71 | int &g(int_c<sizeof(f(T()))> * = 0); |
72 | |
73 | template<typename T> float &g(); |
74 | |
75 | void h() { |
76 | float &fp2 = g<X3>(); // Not ambiguous. |
77 | } |
78 | |