1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 -pedantic %s
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.
12 enum Enum
{ eval
= 1 };
14 const Enum ceval
= eval
;
16 static const int sval
= 3;
17 static const Enum seval
= eval
;
20 template <int itval
, Enum etval
> struct C
{
32 v11
= true? 1 + cval
* Struct::sval
^ itval
/ (int)1.5 - sizeof(Struct
) : 0
45 b11
: true? 1 + cval
* Struct::sval
^ itval
/ (int)1.5 - sizeof(Struct
) : 0
58 i11
= true? 1 + cval
* Struct::sval
^ itval
/ (int)1.5 - sizeof(Struct
) : 0
66 case 400 + Struct::sval
:
67 case 500 + Struct::seval
:
71 case 900 + sizeof(Struct
):
72 case 1000 + (true? 1 + cval
* Struct::sval
^
73 itval
/ (int)1.5 - sizeof(Struct
) : 0):
77 typedef C
<itval
, etval
> T0
;
80 template struct C
<1, eval
>;
81 template struct C
<cval
, ceval
>;
82 template struct C
<Struct::sval
, Struct::seval
>;
91 case (1/0, 1): // expected-error {{not an integral constant expression}} expected-note {{division by zero}} expected-warning {{left operand of comma operator has no effect}}
92 case (int)(1/0, 2.0): // expected-error {{not an integral constant expression}} expected-note {{division by zero}} expected-warning {{left operand of comma operator has no effect}}
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}}
101 const int &p
= k
; // expected-note {{declared here}}
102 template<int n
> struct S
{};
103 S
<p
> s
; // expected-error {{not an integral constant expression}} expected-note {{read of variable 'p' of non-integral, non-enumeration type 'const int &'}}
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
; // expected-note {{here}}
111 const int recurse1
= 1;
112 int array1
[recurse1
]; // ok
113 int array2
[recurse2
]; // expected-warning 2{{variable length array}} expected-note {{initializer of 'recurse2' is not a constant expression}}
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}} expected-note {{value 4.0E+20 is outside the range of representable values}}
123 struct X
; // expected-note {{forward declaration of 'test3::X'}}
124 struct Y
{ bool b
; X x
; }; // expected-error {{field has incomplete type 'X'}}
125 int f() { return Y().b
; }
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
137 namespace rdar16064952
{
138 template < typename T
> void fn1() {
140 unsigned w
= ({int a
= b
.val
[sizeof(0)]; 0; }); // expected-warning {{use of GNU statement expression extension}}
144 char PR17381_ice
= 1000000 * 1000000; // expected-warning {{overflow}} expected-warning {{changes value}}
148 template<int i
> static int n
; // expected-warning {{extension}}
150 template <int M
> class D
;
152 template<int i
> void D
<M
>::set() { // expected-error {{from class 'D<M>' without definition}}
159 } const PR65784
[] = {(int *)""};
160 PR65784s
PR65784f() { return *PR65784
; }