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