1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 -pedantic %s
2*67e74705SXin Li // C++ [expr.const]p1:
3*67e74705SXin Li // In several places, C++ requires expressions that evaluate to an integral
4*67e74705SXin Li // or enumeration constant: as array bounds, as case expressions, as
5*67e74705SXin Li // bit-field lengths, as enumerator initializers, as static member
6*67e74705SXin Li // initializers, and as integral or enumeration non-type template arguments.
7*67e74705SXin Li // An integral constant-expression can involve only literals, enumerators,
8*67e74705SXin Li // const variables or static data members of integral or enumeration types
9*67e74705SXin Li // initialized with constant expressions, and sizeof expressions. Floating
10*67e74705SXin Li // literals can appear only if they are cast to integral or enumeration types.
11*67e74705SXin Li
12*67e74705SXin Li enum Enum { eval = 1 };
13*67e74705SXin Li const int cval = 2;
14*67e74705SXin Li const Enum ceval = eval;
15*67e74705SXin Li struct Struct {
16*67e74705SXin Li static const int sval = 3;
17*67e74705SXin Li static const Enum seval = eval;
18*67e74705SXin Li };
19*67e74705SXin Li
20*67e74705SXin Li template <int itval, Enum etval> struct C {
21*67e74705SXin Li enum E {
22*67e74705SXin Li v1 = 1,
23*67e74705SXin Li v2 = eval,
24*67e74705SXin Li v3 = cval,
25*67e74705SXin Li v4 = ceval,
26*67e74705SXin Li v5 = Struct::sval,
27*67e74705SXin Li v6 = Struct::seval,
28*67e74705SXin Li v7 = itval,
29*67e74705SXin Li v8 = etval,
30*67e74705SXin Li v9 = (int)1.5,
31*67e74705SXin Li v10 = sizeof(Struct),
32*67e74705SXin Li v11 = true? 1 + cval * Struct::sval ^ itval / (int)1.5 - sizeof(Struct) : 0
33*67e74705SXin Li };
34*67e74705SXin Li unsigned
35*67e74705SXin Li b1 : 1,
36*67e74705SXin Li b2 : eval,
37*67e74705SXin Li b3 : cval,
38*67e74705SXin Li b4 : ceval,
39*67e74705SXin Li b5 : Struct::sval,
40*67e74705SXin Li b6 : Struct::seval,
41*67e74705SXin Li b7 : itval,
42*67e74705SXin Li b8 : etval,
43*67e74705SXin Li b9 : (int)1.5,
44*67e74705SXin Li b10 : sizeof(Struct),
45*67e74705SXin Li b11 : true? 1 + cval * Struct::sval ^ itval / (int)1.5 - sizeof(Struct) : 0
46*67e74705SXin Li ;
47*67e74705SXin Li static const int
48*67e74705SXin Li i1 = 1,
49*67e74705SXin Li i2 = eval,
50*67e74705SXin Li i3 = cval,
51*67e74705SXin Li i4 = ceval,
52*67e74705SXin Li i5 = Struct::sval,
53*67e74705SXin Li i6 = Struct::seval,
54*67e74705SXin Li i7 = itval,
55*67e74705SXin Li i8 = etval,
56*67e74705SXin Li i9 = (int)1.5,
57*67e74705SXin Li i10 = sizeof(Struct),
58*67e74705SXin Li i11 = true? 1 + cval * Struct::sval ^ itval / (int)1.5 - sizeof(Struct) : 0
59*67e74705SXin Li ;
fC60*67e74705SXin Li void f(int cond) {
61*67e74705SXin Li switch(cond) {
62*67e74705SXin Li case 0 + 1:
63*67e74705SXin Li case 100 + eval:
64*67e74705SXin Li case 200 + cval:
65*67e74705SXin Li case 300 + ceval:
66*67e74705SXin Li case 400 + Struct::sval:
67*67e74705SXin Li case 500 + Struct::seval:
68*67e74705SXin Li case 600 + itval:
69*67e74705SXin Li case 700 + etval:
70*67e74705SXin Li case 800 + (int)1.5:
71*67e74705SXin Li case 900 + sizeof(Struct):
72*67e74705SXin Li case 1000 + (true? 1 + cval * Struct::sval ^
73*67e74705SXin Li itval / (int)1.5 - sizeof(Struct) : 0):
74*67e74705SXin Li ;
75*67e74705SXin Li }
76*67e74705SXin Li }
77*67e74705SXin Li typedef C<itval, etval> T0;
78*67e74705SXin Li };
79*67e74705SXin Li
80*67e74705SXin Li template struct C<1, eval>;
81*67e74705SXin Li template struct C<cval, ceval>;
82*67e74705SXin Li template struct C<Struct::sval, Struct::seval>;
83*67e74705SXin Li
84*67e74705SXin Li enum {
85*67e74705SXin Li a = sizeof(int) == 8,
86*67e74705SXin Li b = a? 8 : 4
87*67e74705SXin Li };
88*67e74705SXin Li
diags(int n)89*67e74705SXin Li void diags(int n) {
90*67e74705SXin Li switch (n) {
91*67e74705SXin Li case (1/0, 1): // expected-error {{not an integral constant expression}} expected-note {{division by zero}}
92*67e74705SXin Li case (int)(1/0, 2.0): // expected-error {{not an integral constant expression}} expected-note {{division by zero}}
93*67e74705SXin Li case __imag(1/0): // expected-error {{not an integral constant expression}} expected-note {{division by zero}}
94*67e74705SXin Li case (int)__imag((double)(1/0)): // expected-error {{not an integral constant expression}} expected-note {{division by zero}}
95*67e74705SXin Li ;
96*67e74705SXin Li }
97*67e74705SXin Li }
98*67e74705SXin Li
99*67e74705SXin Li namespace IntOrEnum {
100*67e74705SXin Li const int k = 0;
101*67e74705SXin Li const int &p = k;
102*67e74705SXin Li template<int n> struct S {};
103*67e74705SXin Li S<p> s; // expected-error {{not an integral constant expression}}
104*67e74705SXin Li }
105*67e74705SXin Li
106*67e74705SXin Li extern const int recurse1;
107*67e74705SXin Li // recurse2 cannot be used in a constant expression because it is not
108*67e74705SXin Li // initialized by a constant expression. The same expression appearing later in
109*67e74705SXin Li // the TU would be a constant expression, but here it is not.
110*67e74705SXin Li const int recurse2 = recurse1;
111*67e74705SXin Li const int recurse1 = 1;
112*67e74705SXin Li int array1[recurse1]; // ok
113*67e74705SXin Li int array2[recurse2]; // expected-warning {{variable length array}} expected-warning {{integer constant expression}}
114*67e74705SXin Li
115*67e74705SXin Li namespace FloatConvert {
116*67e74705SXin Li typedef int a[(int)42.3];
117*67e74705SXin Li typedef int a[(int)42.997];
118*67e74705SXin Li typedef int b[(long long)4e20]; // expected-warning {{variable length}} expected-error {{variable length}} expected-warning {{'long long' is a C++11 extension}}
119*67e74705SXin Li }
120*67e74705SXin Li
121*67e74705SXin Li // PR12626
122*67e74705SXin Li namespace test3 {
123*67e74705SXin Li struct X; // expected-note {{forward declaration of 'test3::X'}}
124*67e74705SXin Li struct Y { bool b; X x; }; // expected-error {{field has incomplete type 'test3::X'}}
f()125*67e74705SXin Li int f() { return Y().b; }
126*67e74705SXin Li }
127*67e74705SXin Li
128*67e74705SXin Li // PR18283
129*67e74705SXin Li namespace test4 {
130*67e74705SXin Li template <int> struct A {};
131*67e74705SXin Li int const i = { 42 };
132*67e74705SXin Li // i can be used as non-type template-parameter as "const int x = { 42 };" is
133*67e74705SXin Li // equivalent to "const int x = 42;" as per C++03 8.5/p13.
134*67e74705SXin Li typedef A<i> Ai; // ok
135*67e74705SXin Li }
136*67e74705SXin Li
137*67e74705SXin Li // rdar://16064952
138*67e74705SXin Li namespace rdar16064952 {
fn1()139*67e74705SXin Li template < typename T > void fn1() {
140*67e74705SXin Li T b;
141*67e74705SXin Li unsigned w = ({int a = b.val[sizeof(0)]; 0; }); // expected-warning {{use of GNU statement expression extension}}
142*67e74705SXin Li }
143*67e74705SXin Li }
144*67e74705SXin Li
145*67e74705SXin Li char PR17381_ice = 1000000 * 1000000; // expected-warning {{overflow}} expected-warning {{changes value}}
146