1704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith// RUN: %clang_cc1 -std=c++11 %s -verify
28e8fb3be5bd78f0564444eca02b404566a5f3b5dAndy Gibbs// expected-no-diagnostics
3704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith
4704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith// C++98 [class.copy]p5 / C++11 [class.copy]p8.
5704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith
6704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith// The implicitly-declared copy constructor for a class X will have the form
7704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith//   X::X(const X&)
8704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith// if [every direct subobject] has a copy constructor whose first parameter is
9704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith// of type 'const volatile[opt] T &'. Otherwise, it will have the form
10704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith//   X::X(X&)
11704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith
12704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smithstruct ConstCopy {
13704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith  ConstCopy(const ConstCopy &);
14704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith};
15704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith
16704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smithstruct NonConstCopy {
17704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith  NonConstCopy(NonConstCopy &);
18704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith};
19704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith
20704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smithstruct DeletedConstCopy {
21704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith  DeletedConstCopy(const DeletedConstCopy &) = delete;
22704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith};
23704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith
24704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smithstruct DeletedNonConstCopy {
25704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith  DeletedNonConstCopy(DeletedNonConstCopy &) = delete;
26704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith};
27704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith
28704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smithstruct ImplicitlyDeletedConstCopy {
29704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith  ImplicitlyDeletedConstCopy(ImplicitlyDeletedConstCopy &&);
30704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith};
31704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith
32704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith
33704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smithstruct A : ConstCopy {};
34704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smithstruct B : NonConstCopy { ConstCopy a; };
35704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smithstruct C : ConstCopy { NonConstCopy a; };
36704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smithstruct D : DeletedConstCopy {};
37704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smithstruct E : DeletedNonConstCopy {};
38704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smithstruct F { ImplicitlyDeletedConstCopy a; };
39704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smithstruct G : virtual B {};
40704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith
41704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smithstruct Test {
42704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith  friend A::A(const A &);
43704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith  friend B::B(B &);
44704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith  friend C::C(C &);
45704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith  friend D::D(const D &);
46704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith  friend E::E(E &);
473f5f558a4ca08fe952cbbdf69b87487163c9a719Richard Smith  constexpr friend F::F(const F &);
48704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith  friend G::G(G &);
49704c8f76bbe2de68375f7f146e75bd74de6dd518Richard Smith};
50