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