// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s // If an expression of literal class type is used in a context where an integral // constant expression is required, then that class type shall have a single // non-explicit conversion function to an integral or unscoped enumeration type namespace std_example { struct A { constexpr A(int i) : val(i) { } constexpr operator int() const { return val; } constexpr operator long() const { return 43; } private: int val; }; template<int> struct X { }; constexpr A a = 42; X<a> x; // ok, unique conversion to int int ary[a]; // expected-error {{size of array has non-integer type 'const std_example::A'}} } struct OK { constexpr OK() {} constexpr operator int() const { return 8; } } constexpr ok; extern struct Incomplete incomplete; // expected-note 4{{forward decl}} struct Explicit { constexpr Explicit() {} constexpr explicit operator int() const { return 4; } // expected-note 4{{here}} } constexpr expl; struct Ambiguous { constexpr Ambiguous() {} constexpr operator int() const { return 2; } // expected-note 4{{here}} constexpr operator long() const { return 1; } // expected-note 4{{here}} } constexpr ambig; constexpr int test_ok = ok; // ok constexpr int test_explicit(expl); // ok constexpr int test_ambiguous = ambig; // ok static_assert(test_ok == 8, ""); static_assert(test_explicit == 4, ""); static_assert(test_ambiguous == 2, ""); // [expr.new]p6: Every constant-expression in a noptr-new-declarator shall be // an integral constant expression auto new1 = new int[1][ok]; auto new2 = new int[1][incomplete]; // expected-error {{incomplete}} auto new3 = new int[1][expl]; // expected-error {{explicit conversion}} auto new4 = new int[1][ambig]; // expected-error {{ambiguous conversion}} // [dcl.enum]p5: If the underlying type is not fixed [...] the initializing // value [...] shall be an integral constant expression. enum NotFixed { enum1 = ok, enum2 = incomplete, // expected-error {{incomplete}} enum3 = expl, // expected-error {{explicit conversion}} enum4 = ambig // expected-error {{ambiguous conversion}} }; // [dcl.align]p2: When the alignment-specifier is of the form // alignas(assignment-expression), the assignment-expression shall be an // integral constant expression alignas(ok) int alignas1; alignas(incomplete) int alignas2; // expected-error {{incomplete}} alignas(expl) int alignas3; // expected-error {{explicit conversion}} alignas(ambig) int alignas4; // expected-error {{ambiguous conversion}} // [dcl.array]p1: If the constant-expression is present, it shall be an integral // constant expression // FIXME: The VLA recovery results in us giving diagnostics which aren't great // here. int array1[ok]; int array2[incomplete]; // expected-error {{non-integer type}} int array3[expl]; // expected-error {{non-integer type}} int array4[ambig]; // expected-error {{non-integer type}} // [class.bit]p1: The constasnt-expression shall be an integral constant // expression struct Bitfields { int bitfield1 : ok; int bitfield2 : incomplete; // expected-error {{incomplete}} int bitfield3 : expl; // expected-error {{explicit conversion}} int bitfield4 : ambig; // expected-error {{ambiguous conversion}} };