David Majnemer | c10b838 | 2015-10-08 06:31:22 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -std=c++11 -verify %s |
Richard Smith | 3c7ad4e | 2012-02-08 06:41:34 +0000 | [diff] [blame] | 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) { } |
Richard Smith | 034185c | 2013-04-21 01:08:50 +0000 | [diff] [blame] | 10 | constexpr operator int() const { return val; } |
| 11 | constexpr operator long() const { return 43; } |
Richard Smith | 3c7ad4e | 2012-02-08 06:41:34 +0000 | [diff] [blame] | 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() {} |
Richard Smith | 034185c | 2013-04-21 01:08:50 +0000 | [diff] [blame] | 24 | constexpr operator int() const { return 8; } |
Richard Smith | 3c7ad4e | 2012-02-08 06:41:34 +0000 | [diff] [blame] | 25 | } constexpr ok; |
| 26 | extern struct Incomplete incomplete; // expected-note 4{{forward decl}} |
| 27 | struct Explicit { |
| 28 | constexpr Explicit() {} |
Richard Smith | 034185c | 2013-04-21 01:08:50 +0000 | [diff] [blame] | 29 | constexpr explicit operator int() const { return 4; } // expected-note 4{{here}} |
Richard Smith | 3c7ad4e | 2012-02-08 06:41:34 +0000 | [diff] [blame] | 30 | } constexpr expl; |
| 31 | struct Ambiguous { |
| 32 | constexpr Ambiguous() {} |
Richard Smith | 034185c | 2013-04-21 01:08:50 +0000 | [diff] [blame] | 33 | constexpr operator int() const { return 2; } // expected-note 4{{here}} |
| 34 | constexpr operator long() const { return 1; } // expected-note 4{{here}} |
Richard Smith | 3c7ad4e | 2012-02-08 06:41:34 +0000 | [diff] [blame] | 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 |
Michael Han | 64536a6 | 2012-11-06 19:34:54 +0000 | [diff] [blame] | 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}} |
Richard Smith | 3c7ad4e | 2012-02-08 06:41:34 +0000 | [diff] [blame] | 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 | }; |