| 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 | |