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