1 | // RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -std=c++11 -verify %s |
2 | |
3 | // If an expression of literal class type is used in a context where an integral |
4 | // constant expression is required, then that class type shall have a single |
5 | // non-explicit conversion function to an integral or unscoped enumeration type |
6 | namespace std_example { |
7 | |
8 | struct A { |
9 | constexpr A(int i) : val(i) { } |
10 | constexpr operator int() const { return val; } |
11 | constexpr operator long() const { return 43; } |
12 | private: |
13 | int val; |
14 | }; |
15 | template<int> struct X { }; |
16 | constexpr A a = 42; |
17 | X<a> x; // ok, unique conversion to int |
18 | int ary[a]; // expected-error {{size of array has non-integer type 'const std_example::A'}} |
19 | |
20 | } |
21 | |
22 | struct OK { |
23 | constexpr OK() {} |
24 | constexpr operator int() const { return 8; } |
25 | } constexpr ok; |
26 | extern struct Incomplete incomplete; // expected-note 4{{forward decl}} |
27 | struct Explicit { |
28 | constexpr Explicit() {} |
29 | constexpr explicit operator int() const { return 4; } // expected-note 4{{here}} |
30 | } constexpr expl; |
31 | struct Ambiguous { |
32 | constexpr Ambiguous() {} |
33 | constexpr operator int() const { return 2; } // expected-note 4{{here}} |
34 | constexpr operator long() const { return 1; } // expected-note 4{{here}} |
35 | } constexpr ambig; |
36 | |
37 | constexpr int test_ok = ok; // ok |
38 | constexpr int test_explicit(expl); // ok |
39 | constexpr int test_ambiguous = ambig; // ok |
40 | |
41 | static_assert(test_ok == 8, ""); |
42 | static_assert(test_explicit == 4, ""); |
43 | static_assert(test_ambiguous == 2, ""); |
44 | |
45 | // [expr.new]p6: Every constant-expression in a noptr-new-declarator shall be |
46 | // an integral constant expression |
47 | auto new1 = new int[1][ok]; |
48 | auto new2 = new int[1][incomplete]; // expected-error {{incomplete}} |
49 | auto new3 = new int[1][expl]; // expected-error {{explicit conversion}} |
50 | auto new4 = new int[1][ambig]; // expected-error {{ambiguous conversion}} |
51 | |
52 | // [dcl.enum]p5: If the underlying type is not fixed [...] the initializing |
53 | // value [...] shall be an integral constant expression. |
54 | enum NotFixed { |
55 | enum1 = ok, |
56 | enum2 = incomplete, // expected-error {{incomplete}} |
57 | enum3 = expl, // expected-error {{explicit conversion}} |
58 | enum4 = ambig // expected-error {{ambiguous conversion}} |
59 | }; |
60 | |
61 | // [dcl.align]p2: When the alignment-specifier is of the form |
62 | // alignas(assignment-expression), the assignment-expression shall be an |
63 | // integral constant expression |
64 | alignas(ok) int alignas1; |
65 | alignas(incomplete) int alignas2; // expected-error {{incomplete}} |
66 | alignas(expl) int alignas3; // expected-error {{explicit conversion}} |
67 | alignas(ambig) int alignas4; // expected-error {{ambiguous conversion}} |
68 | |
69 | // [dcl.array]p1: If the constant-expression is present, it shall be an integral |
70 | // constant expression |
71 | // FIXME: The VLA recovery results in us giving diagnostics which aren't great |
72 | // here. |
73 | int array1[ok]; |
74 | int array2[incomplete]; // expected-error {{non-integer type}} |
75 | int array3[expl]; // expected-error {{non-integer type}} |
76 | int array4[ambig]; // expected-error {{non-integer type}} |
77 | |
78 | // [class.bit]p1: The constasnt-expression shall be an integral constant |
79 | // expression |
80 | struct Bitfields { |
81 | int bitfield1 : ok; |
82 | int bitfield2 : incomplete; // expected-error {{incomplete}} |
83 | int bitfield3 : expl; // expected-error {{explicit conversion}} |
84 | int bitfield4 : ambig; // expected-error {{ambiguous conversion}} |
85 | }; |
86 | |