1 // RUN: %clang_cc1 -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