1 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s |
2 | |
3 | static_assert(__is_literal(int), "fail"); |
4 | static_assert(__is_literal_type(int), "fail"); // alternate spelling for GCC |
5 | static_assert(__is_literal(void*), "fail"); |
6 | enum E { E1 }; |
7 | static_assert(__is_literal(E), "fail"); |
8 | static_assert(__is_literal(decltype(E1)), "fail"); |
9 | typedef int IAR[10]; |
10 | static_assert(__is_literal(IAR), "fail"); |
11 | typedef int Vector __attribute__((vector_size(16))); |
12 | typedef int VectorExt __attribute__((ext_vector_type(4))); |
13 | static_assert(__is_literal(Vector), "fail"); |
14 | static_assert(__is_literal(VectorExt), "fail"); |
15 | |
16 | // C++0x [basic.types]p10: |
17 | // A type is a literal type if it is: |
18 | // [...] |
19 | // -- a class type that has all of the following properties: |
20 | // -- it has a trivial destructor |
21 | // -- every constructor call and full-expression in the |
22 | // brace-or-equal-initializers for non-static data members (if an) is |
23 | // a constant expression, |
24 | // -- it is an aggregate type or has at least one constexpr constructor |
25 | // or constructor template that is not a copy or move constructor, and |
26 | // [DR1452 adds class types with trivial default constructors to |
27 | // this list] |
28 | // -- it has all non-static data members and base classes of literal |
29 | // types |
30 | struct Empty {}; |
31 | struct LiteralType { |
32 | int x; |
33 | E e; |
34 | IAR arr; |
35 | Empty empty; |
36 | int method(); |
37 | }; |
38 | struct HasDtor { ~HasDtor(); }; |
39 | |
40 | class NonAggregate { int x; }; |
41 | struct NonLiteral { NonLiteral(); }; |
42 | struct HasNonLiteralBase : NonLiteral {}; |
43 | struct HasNonLiteralMember { HasDtor x; }; |
44 | |
45 | static_assert(__is_literal(Empty), "fail"); |
46 | static_assert(__is_literal(LiteralType), "fail"); |
47 | static_assert(__is_literal(NonAggregate), "fail"); |
48 | static_assert(!__is_literal(NonLiteral), "fail"); |
49 | static_assert(!__is_literal(HasDtor), "fail"); |
50 | static_assert(!__is_literal(HasNonLiteralBase), "fail"); |
51 | static_assert(!__is_literal(HasNonLiteralMember), "fail"); |
52 | |
53 | // DR1361 removes the brace-or-equal-initializer bullet so that we can allow: |
54 | extern int f(); // expected-note {{here}} |
55 | struct HasNonConstExprMemInit { |
56 | int x = f(); // expected-note {{non-constexpr function}} |
57 | constexpr HasNonConstExprMemInit() {} // expected-error {{never produces a constant expression}} |
58 | constexpr HasNonConstExprMemInit(int y) : x(y) {} // ok |
59 | }; |
60 | static_assert(__is_literal(HasNonConstExprMemInit), "fail"); |
61 | |
62 | class HasConstExprCtor { |
63 | int x; |
64 | public: |
65 | constexpr HasConstExprCtor(int x) : x(x) {} |
66 | }; |
67 | template <typename T> class HasConstExprCtorTemplate { |
68 | T x; |
69 | public: |
70 | template <typename U> constexpr HasConstExprCtorTemplate(U y) : x(y) {} |
71 | }; |
72 | template <typename T> class HasConstExprCtorT { |
73 | constexpr HasConstExprCtorT(T) {} |
74 | }; |
75 | static_assert(__is_literal(HasConstExprCtor), "fail"); |
76 | static_assert(__is_literal(HasConstExprCtorTemplate<int>), "fail"); |
77 | static_assert(__is_literal(HasConstExprCtorT<NonLiteral>), "fail"); |
78 | |