p12-0x.cpp revision ac71351acdefc9de0c770c1d717e621ac9e684bf
1// RUN: %clang_cc1 -std=c++11 -verify %s 2 3template<typename T, bool B> struct trivially_copyable_check { 4 static_assert(B == __has_trivial_copy(T), ""); 5 static_assert(B == __is_trivially_constructible(T, T), ""); 6 static_assert(B == __is_trivially_constructible(T, const T &), ""); 7 static_assert(B == __is_trivially_constructible(T, T &&), ""); 8 typedef void type; 9}; 10template<typename T> using trivially_copyable = 11 typename trivially_copyable_check<T, true>::type; 12template<typename T> using not_trivially_copyable = 13 typename trivially_copyable_check<T, false>::type; 14 15struct Trivial {}; 16using _ = trivially_copyable<Trivial>; 17 18// A copy/move constructor for class X is trivial if it is not user-provided, 19struct UserProvided { 20 UserProvided(const UserProvided &); 21}; 22using _ = not_trivially_copyable<UserProvided>; 23 24// its declared parameter type is the same as if it had been implicitly 25// declared, 26struct NonConstCopy { 27 NonConstCopy(NonConstCopy &) = default; 28}; 29using _ = not_trivially_copyable<NonConstCopy>; 30 31// class X has no virtual functions 32struct VFn { 33 virtual void f(); 34}; 35using _ = not_trivially_copyable<VFn>; 36 37// and no virtual base classes 38struct VBase : virtual Trivial {}; 39using _ = not_trivially_copyable<VBase>; 40 41// and the constructor selected to copy/move each [direct subobject] is trivial 42struct TemplateCtor { 43 template<typename T> TemplateCtor(T &); 44}; 45using _ = trivially_copyable<TemplateCtor>; 46struct TemplateCtorMember { 47 TemplateCtor tc; 48}; 49using _ = trivially_copyable<TemplateCtorMember>; 50 51// We can select a non-trivial copy ctor even if there is a trivial one. 52struct MutableTemplateCtorMember { 53 mutable TemplateCtor mtc; 54}; 55// FIXME: This is wrong! The "trivial" copy constructor calls the templated 56// constructor for the mutable member. 57static_assert(!__is_trivially_constructible(MutableTemplateCtorMember, const MutableTemplateCtorMember &), ""); // expected-error {{}} 58static_assert(__is_trivially_constructible(MutableTemplateCtorMember, MutableTemplateCtorMember &&), ""); 59struct MutableTemplateCtorMember2 { 60 MutableTemplateCtorMember2(const MutableTemplateCtorMember2 &) = default; 61 MutableTemplateCtorMember2(MutableTemplateCtorMember2 &&) = default; 62 mutable TemplateCtor mtc; 63}; 64static_assert(!__is_trivially_constructible(MutableTemplateCtorMember2, const MutableTemplateCtorMember2 &), ""); 65static_assert(__is_trivially_constructible(MutableTemplateCtorMember2, MutableTemplateCtorMember2 &&), ""); 66 67// Both trivial and non-trivial special members. 68struct TNT { 69 TNT(const TNT &) = default; // trivial 70 TNT(TNT &); // non-trivial 71 72 TNT(TNT &&) = default; // trivial 73 TNT(const TNT &&); // non-trivial 74}; 75 76static_assert(!__has_trivial_copy(TNT), "lie deliberately for gcc compatibility"); 77static_assert(__is_trivially_constructible(TNT, TNT), ""); 78static_assert(!__is_trivially_constructible(TNT, TNT &), ""); 79static_assert(__is_trivially_constructible(TNT, const TNT &), ""); 80static_assert(!__is_trivially_constructible(TNT, volatile TNT &), ""); 81static_assert(__is_trivially_constructible(TNT, TNT &&), ""); 82static_assert(!__is_trivially_constructible(TNT, const TNT &&), ""); 83static_assert(!__is_trivially_constructible(TNT, volatile TNT &&), ""); 84 85// This has only trivial special members. 86struct DerivedFromTNT : TNT {}; 87 88static_assert(__has_trivial_copy(DerivedFromTNT), ""); 89static_assert(__is_trivially_constructible(DerivedFromTNT, DerivedFromTNT), ""); 90static_assert(__is_trivially_constructible(DerivedFromTNT, DerivedFromTNT &), ""); 91static_assert(__is_trivially_constructible(DerivedFromTNT, const DerivedFromTNT &), ""); 92static_assert(!__is_trivially_constructible(DerivedFromTNT, volatile DerivedFromTNT &), ""); 93static_assert(__is_trivially_constructible(DerivedFromTNT, DerivedFromTNT &&), ""); 94static_assert(__is_trivially_constructible(DerivedFromTNT, const DerivedFromTNT &&), ""); 95static_assert(!__is_trivially_constructible(DerivedFromTNT, volatile DerivedFromTNT &&), ""); 96 97// This has only trivial special members. 98struct TNTMember { 99 TNT tnt; 100}; 101 102static_assert(__has_trivial_copy(TNTMember), ""); 103static_assert(__is_trivially_constructible(TNTMember, TNTMember), ""); 104static_assert(__is_trivially_constructible(TNTMember, TNTMember &), ""); 105static_assert(__is_trivially_constructible(TNTMember, const TNTMember &), ""); 106static_assert(!__is_trivially_constructible(TNTMember, volatile TNTMember &), ""); 107static_assert(__is_trivially_constructible(TNTMember, TNTMember &&), ""); 108static_assert(__is_trivially_constructible(TNTMember, const TNTMember &&), ""); 109static_assert(!__is_trivially_constructible(TNTMember, volatile TNTMember &&), ""); 110 111struct NCCTNT : NonConstCopy, TNT {}; 112 113static_assert(!__has_trivial_copy(NCCTNT), ""); 114static_assert(!__is_trivially_constructible(NCCTNT, NCCTNT), ""); 115static_assert(!__is_trivially_constructible(NCCTNT, NCCTNT &), ""); 116static_assert(!__is_trivially_constructible(NCCTNT, const NCCTNT &), ""); 117static_assert(!__is_trivially_constructible(NCCTNT, volatile NCCTNT &), ""); 118static_assert(!__is_trivially_constructible(NCCTNT, NCCTNT &&), ""); 119static_assert(!__is_trivially_constructible(NCCTNT, const NCCTNT &&), ""); 120static_assert(!__is_trivially_constructible(NCCTNT, volatile NCCTNT &&), ""); 121