Home | History | Annotate | Download | only in expr.const
      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