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