Richard Smith | afb4918 | 2012-11-29 01:34:07 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s |
Anders Carlsson | 5c478cf | 2009-12-04 22:33:25 +0000 | [diff] [blame] | 2 | |
John McCall | 3d04336 | 2010-04-13 07:45:41 +0000 | [diff] [blame] | 3 | struct A { }; |
Sean Hunt | f961ea5 | 2011-05-10 19:08:14 +0000 | [diff] [blame] | 4 | A::A() { } // expected-error {{definition of implicitly declared default constructor}} |
Anders Carlsson | 5c478cf | 2009-12-04 22:33:25 +0000 | [diff] [blame] | 5 | |
John McCall | 3d04336 | 2010-04-13 07:45:41 +0000 | [diff] [blame] | 6 | struct B { }; |
Anders Carlsson | 5c478cf | 2009-12-04 22:33:25 +0000 | [diff] [blame] | 7 | B::B(const B&) { } // expected-error {{definition of implicitly declared copy constructor}} |
| 8 | |
John McCall | 3d04336 | 2010-04-13 07:45:41 +0000 | [diff] [blame] | 9 | struct C { }; |
Anders Carlsson | 5c478cf | 2009-12-04 22:33:25 +0000 | [diff] [blame] | 10 | C& C::operator=(const C&) { return *this; } // expected-error {{definition of implicitly declared copy assignment operator}} |
| 11 | |
John McCall | 3d04336 | 2010-04-13 07:45:41 +0000 | [diff] [blame] | 12 | struct D { }; |
Anders Carlsson | 5c478cf | 2009-12-04 22:33:25 +0000 | [diff] [blame] | 13 | D::~D() { } // expected-error {{definition of implicitly declared destructor}} |
| 14 | |
Douglas Gregor | 6275e0c | 2010-04-12 17:09:20 +0000 | [diff] [blame] | 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 | } |
Sebastian Redl | cddc69f | 2010-07-08 23:07:34 +0000 | [diff] [blame] | 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 | } |
Richard Smith | afb4918 | 2012-11-29 01:34:07 +0000 | [diff] [blame] | 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 { |
Stephen Hines | 651f13c | 2014-04-23 16:59:28 -0700 | [diff] [blame] | 61 | // expected-note@-1 {{while substituting deduced template arguments}} |
Richard Smith | afb4918 | 2012-11-29 01:34:07 +0000 | [diff] [blame] | 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}} |
Richard Smith | afb4918 | 2012-11-29 01:34:07 +0000 | [diff] [blame] | 68 | }; |
| 69 | struct B { // expected-note {{candidate constructor (the implicit move }} |
| 70 | B(); // expected-note {{candidate constructor not viable}} |
| 71 | A a; |
| 72 | }; |
| 73 | // Triggering the declaration of B's copy constructor causes overload |
| 74 | // resolution to occur for A's copying constructor, which instantiates |
| 75 | // InvokeCopyConstructor<B>, which triggers the declaration of B's copy |
| 76 | // constructor. Notionally, this happens when we get to the end of the |
| 77 | // definition of 'struct B', so there is no declared copy constructor yet. |
| 78 | // |
| 79 | // This behavior is g++-compatible, but isn't exactly right; the class is |
| 80 | // supposed to be incomplete when we implicitly declare its special members. |
| 81 | B b = B(); |
| 82 | |
| 83 | |
| 84 | // Another case, which isn't ill-formed under our rules. This is inspired by |
| 85 | // a problem which occurs when combining CGAL with libstdc++-4.7. |
| 86 | |
| 87 | template<typename T> T &&declval(); |
| 88 | template<typename T, typename U> struct pair { |
| 89 | pair(); |
| 90 | template<typename V, typename W, |
| 91 | typename = decltype(T(declval<const V&>())), |
| 92 | typename = decltype(U(declval<const W&>()))> |
| 93 | pair(const pair<V,W> &); |
| 94 | }; |
| 95 | |
| 96 | template<typename K> struct Line; |
| 97 | |
| 98 | template<typename K> struct Vector { |
| 99 | Vector(const Line<K> &l); |
| 100 | }; |
| 101 | |
| 102 | template<typename K> struct Point { |
| 103 | Vector<K> v; |
| 104 | }; |
| 105 | |
| 106 | template<typename K> struct Line { |
| 107 | pair<Point<K>, Vector<K>> x; |
| 108 | }; |
| 109 | |
| 110 | // Trigger declaration of Line copy ctor, which causes substitution into |
| 111 | // pair's templated constructor, which triggers instantiation of the |
| 112 | // definition of Point's copy constructor, which performs overload resolution |
| 113 | // on Vector's constructors, which requires declaring all of Line's |
| 114 | // constructors. That should not find a copy constructor (because we've not |
| 115 | // declared it yet), but by the time we get all the way back here, we should |
| 116 | // find the copy constructor. |
| 117 | Line<void> L1; |
| 118 | Line<void> L2(L1); |
| 119 | } |