1 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s |
2 | |
3 | struct A { }; |
4 | A::A() { } // expected-error {{definition of implicitly declared default constructor}} |
5 | |
6 | struct B { }; |
7 | B::B(const B&) { } // expected-error {{definition of implicitly declared copy constructor}} |
8 | |
9 | struct C { }; |
10 | C& C::operator=(const C&) { return *this; } // expected-error {{definition of implicitly declared copy assignment operator}} |
11 | |
12 | struct D { }; |
13 | D::~D() { } // expected-error {{definition of implicitly declared destructor}} |
14 | |
15 | // Make sure that the special member functions are introduced for |
16 | // name-lookup purposes and overload with user-declared |
17 | // constructors and assignment operators. |
18 | namespace PR6570 { |
19 | class A { }; |
20 | |
21 | class B { |
22 | public: |
23 | B() {} |
24 | |
25 | B(const A& a) { |
26 | operator = (CONST); |
27 | operator = (a); |
28 | } |
29 | |
30 | B& operator = (const A& a) { |
31 | return *this; |
32 | } |
33 | |
34 | void f(const A &a) { |
35 | B b(a); |
36 | }; |
37 | |
38 | static const B CONST; |
39 | }; |
40 | |
41 | } |
42 | |
43 | namespace PR7594 { |
44 | // If the lazy declaration of special member functions is triggered |
45 | // in an out-of-line initializer, make sure the functions aren't in |
46 | // the initializer scope. This used to crash Clang: |
47 | struct C { |
48 | C(); |
49 | static C *c; |
50 | }; |
51 | C *C::c = new C(); |
52 | } |
53 | |
54 | namespace Recursion { |
55 | template<typename T> struct InvokeCopyConstructor { |
56 | static const T &get(); |
57 | typedef decltype(T(get())) type; // expected-error {{no matching conver}} |
58 | }; |
59 | struct B; |
60 | struct A { |
61 | // expected-note@-1 {{while substituting deduced template arguments}} |
62 | typedef B type; |
63 | template<typename T, |
64 | typename = typename InvokeCopyConstructor<typename T::type>::type> |
65 | // expected-note@-1 {{in instantiation of template class}} |
66 | A(const T &); |
67 | // expected-note@-1 {{in instantiation of default argument}} |
68 | }; |
69 | struct B { // expected-note {{while declaring the implicit copy constructor for 'B'}} |
70 | // expected-note@-1 {{candidate constructor (the implicit move }} |
71 | B(); // expected-note {{candidate constructor not viable}} |
72 | A a; |
73 | }; |
74 | // Triggering the declaration of B's copy constructor causes overload |
75 | // resolution to occur for A's copying constructor, which instantiates |
76 | // InvokeCopyConstructor<B>, which triggers the declaration of B's copy |
77 | // constructor. Notionally, this happens when we get to the end of the |
78 | // definition of 'struct B', so there is no declared copy constructor yet. |
79 | // |
80 | // This behavior is g++-compatible, but isn't exactly right; the class is |
81 | // supposed to be incomplete when we implicitly declare its special members. |
82 | B b = B(); |
83 | |
84 | |
85 | // Another case, which isn't ill-formed under our rules. This is inspired by |
86 | // a problem which occurs when combining CGAL with libstdc++-4.7. |
87 | |
88 | template<typename T> T &&declval(); |
89 | template<typename T, typename U> struct pair { |
90 | pair(); |
91 | template<typename V, typename W, |
92 | typename = decltype(T(declval<const V&>())), |
93 | typename = decltype(U(declval<const W&>()))> |
94 | pair(const pair<V,W> &); |
95 | }; |
96 | |
97 | template<typename K> struct Line; |
98 | |
99 | template<typename K> struct Vector { |
100 | Vector(const Line<K> &l); |
101 | }; |
102 | |
103 | template<typename K> struct Point { |
104 | Vector<K> v; |
105 | }; |
106 | |
107 | template<typename K> struct Line { |
108 | pair<Point<K>, Vector<K>> x; |
109 | }; |
110 | |
111 | // Trigger declaration of Line copy ctor, which causes substitution into |
112 | // pair's templated constructor, which triggers instantiation of the |
113 | // definition of Point's copy constructor, which performs overload resolution |
114 | // on Vector's constructors, which requires declaring all of Line's |
115 | // constructors. That should not find a copy constructor (because we've not |
116 | // declared it yet), but by the time we get all the way back here, we should |
117 | // find the copy constructor. |
118 | Line<void> L1; |
119 | Line<void> L2(L1); |
120 | } |
121 | |