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