183c478d3SRichard Smith // RUN: %clang_cc1 -std=c++11 %s -verify 2*c6e68daaSAndy Gibbs // expected-no-diagnostics 383c478d3SRichard Smith 483c478d3SRichard Smith // C++98 [class.copy]p5 / C++11 [class.copy]p8. 583c478d3SRichard Smith 683c478d3SRichard Smith // The implicitly-declared copy constructor for a class X will have the form 783c478d3SRichard Smith // X::X(const X&) 883c478d3SRichard Smith // if [every direct subobject] has a copy constructor whose first parameter is 983c478d3SRichard Smith // of type 'const volatile[opt] T &'. Otherwise, it will have the form 1083c478d3SRichard Smith // X::X(X&) 1183c478d3SRichard Smith 1283c478d3SRichard Smith struct ConstCopy { 1383c478d3SRichard Smith ConstCopy(const ConstCopy &); 1483c478d3SRichard Smith }; 1583c478d3SRichard Smith 1683c478d3SRichard Smith struct NonConstCopy { 1783c478d3SRichard Smith NonConstCopy(NonConstCopy &); 1883c478d3SRichard Smith }; 1983c478d3SRichard Smith 2083c478d3SRichard Smith struct DeletedConstCopy { 2183c478d3SRichard Smith DeletedConstCopy(const DeletedConstCopy &) = delete; 2283c478d3SRichard Smith }; 2383c478d3SRichard Smith 2483c478d3SRichard Smith struct DeletedNonConstCopy { 2583c478d3SRichard Smith DeletedNonConstCopy(DeletedNonConstCopy &) = delete; 2683c478d3SRichard Smith }; 2783c478d3SRichard Smith 2883c478d3SRichard Smith struct ImplicitlyDeletedConstCopy { 2983c478d3SRichard Smith ImplicitlyDeletedConstCopy(ImplicitlyDeletedConstCopy &&); 3083c478d3SRichard Smith }; 3183c478d3SRichard Smith 3283c478d3SRichard Smith 3383c478d3SRichard Smith struct A : ConstCopy {}; 3483c478d3SRichard Smith struct B : NonConstCopy { ConstCopy a; }; 3583c478d3SRichard Smith struct C : ConstCopy { NonConstCopy a; }; 3683c478d3SRichard Smith struct D : DeletedConstCopy {}; 3783c478d3SRichard Smith struct E : DeletedNonConstCopy {}; 3883c478d3SRichard Smith struct F { ImplicitlyDeletedConstCopy a; }; 3983c478d3SRichard Smith struct G : virtual B {}; 4083c478d3SRichard Smith 4183c478d3SRichard Smith struct Test { 4283c478d3SRichard Smith friend A::A(const A &); 4383c478d3SRichard Smith friend B::B(B &); 4483c478d3SRichard Smith friend C::C(C &); 4583c478d3SRichard Smith friend D::D(const D &); 4683c478d3SRichard Smith friend E::E(E &); 4712f247f4SRichard Smith constexpr friend F::F(const F &); 4883c478d3SRichard Smith friend G::G(G &); 4983c478d3SRichard Smith }; 50