1 // RUN: %clang_cc1 -triple x86_64-linux -fexperimental-new-constant-interpreter -verify=both,expected -std=c++11 %s
2 // RUN: %clang_cc1 -triple x86_64-linux -verify=both,ref -std=c++11 %s
7 template<int n
> struct S
{};
12 template <int> struct C
{};
13 template struct C
<cval
>;
16 /// FIXME: This example does not get properly diagnosed in the new interpreter.
17 extern const int recurse1
;
18 const int recurse2
= recurse1
; // both-note {{here}}
19 const int recurse1
= 1;
21 int array2
[recurse2
]; // both-warning {{variable length arrays in C++}} \
22 // both-note {{initializer of 'recurse2' is not a constant expression}} \
23 // expected-error {{variable length array declaration not allowed at file scope}} \
24 // ref-warning {{variable length array folded to constant array as an extension}}
29 constexpr S s
= { 5 };
30 constexpr const int *p
= &s
.m
+ 1;
32 constexpr const int *np2
= &(*(int(*)[4])nullptr)[0]; // ok
34 constexpr int preDec(int x
) { // both-error {{never produces a constant expression}}
35 return --x
; // both-note {{subexpression}}
38 constexpr int postDec(int x
) { // both-error {{never produces a constant expression}}
39 return x
--; // both-note {{subexpression}}
42 constexpr int preInc(int x
) { // both-error {{never produces a constant expression}}
43 return ++x
; // both-note {{subexpression}}
46 constexpr int postInc(int x
) { // both-error {{never produces a constant expression}}
47 return x
++; // both-note {{subexpression}}
51 namespace ReferenceToConst
{
52 template<int n
> struct S
; // both-note 1{{here}}
54 constexpr LiteralType(int n
) : n(n
) {}
57 template<int n
> struct T
{
59 static const int ki
= 42;
61 typename S
<i2
>::T check5
; // both-error {{undefined template}}
69 // Enums without fixed underlying type
70 enum E1
{e11
=-4, e12
=4};
71 enum E2
{e21
=0, e22
=4};
72 enum E3
{e31
=-4, e32
=1024};
74 // Empty but as-if it had a single enumerator with value 0
77 // Enum with fixed underlying type because the underlying type is explicitly specified
78 enum EFixed
: int {efixed1
=-4, efixed2
=4};
79 // Enum with fixed underlying type because it is scoped
80 enum class EScoped
{escoped1
=-4, escoped2
=4};
82 enum EMaxInt
{emaxint1
=-1, emaxint2
=__INT_MAX__
};
86 E2
testDefaultArgForParam(E2 e2Param
= (E2
)-1) { // ok, not a constant expression context
87 E2 e2LocalInit
= e2Param
; // ok, not a constant expression context
91 // #include <enum-constexpr-conversion-system-header.h>
93 void testValueInRangeOfEnumerationValues() {
94 constexpr E1 x1
= static_cast<E1
>(-8);
95 constexpr E1 x2
= static_cast<E1
>(8);
96 // both-error@-1 {{constexpr variable 'x2' must be initialized by a constant expression}}
97 // both-note@-2 {{integer value 8 is outside the valid range of values [-8, 7] for the enumeration type 'E1'}}
98 E1 x2b
= static_cast<E1
>(8); // ok, not a constant expression context
100 constexpr E2 x3
= static_cast<E2
>(-8);
101 // both-error@-1 {{constexpr variable 'x3' must be initialized by a constant expression}}
102 // both-note@-2 {{integer value -8 is outside the valid range of values [0, 7] for the enumeration type 'E2'}}
103 constexpr E2 x4
= static_cast<E2
>(0);
104 constexpr E2 x5
= static_cast<E2
>(8);
105 // both-error@-1 {{constexpr variable 'x5' must be initialized by a constant expression}}
106 // both-note@-2 {{integer value 8 is outside the valid range of values [0, 7] for the enumeration type 'E2'}}
108 constexpr E3 x6
= static_cast<E3
>(-2048);
109 constexpr E3 x7
= static_cast<E3
>(-8);
110 constexpr E3 x8
= static_cast<E3
>(0);
111 constexpr E3 x9
= static_cast<E3
>(8);
112 constexpr E3 x10
= static_cast<E3
>(2048);
113 // both-error@-1 {{constexpr variable 'x10' must be initialized by a constant expression}}
114 // both-note@-2 {{integer value 2048 is outside the valid range of values [-2048, 2047] for the enumeration type 'E3'}}
116 constexpr E4 x11
= static_cast<E4
>(0);
117 constexpr E4 x12
= static_cast<E4
>(1);
118 constexpr E4 x13
= static_cast<E4
>(2);
119 // both-error@-1 {{constexpr variable 'x13' must be initialized by a constant expression}}
120 // both-note@-2 {{integer value 2 is outside the valid range of values [0, 1] for the enumeration type 'E4'}}
122 constexpr EEmpty x14
= static_cast<EEmpty
>(0);
123 constexpr EEmpty x15
= static_cast<EEmpty
>(1);
124 constexpr EEmpty x16
= static_cast<EEmpty
>(2);
125 // both-error@-1 {{constexpr variable 'x16' must be initialized by a constant expression}}
126 // both-note@-2 {{integer value 2 is outside the valid range of values [0, 1] for the enumeration type 'EEmpty'}}
128 constexpr EFixed x17
= static_cast<EFixed
>(100);
129 constexpr EScoped x18
= static_cast<EScoped
>(100);
131 constexpr EMaxInt x19
= static_cast<EMaxInt
>(__INT_MAX__
-1);
132 constexpr EMaxInt x20
= static_cast<EMaxInt
>((long)__INT_MAX__
+1);
133 // both-error@-1 {{constexpr variable 'x20' must be initialized by a constant expression}}
134 // both-note@-2 {{integer value 2147483648 is outside the valid range of values [-2147483648, 2147483647] for the enumeration type 'EMaxInt'}}
136 const NumberType neg_one
= (NumberType
) ((NumberType
) 0 - (NumberType
) 1); // ok, not a constant expression context
139 template<class T
, unsigned size
> struct Bitfield
{
140 static constexpr T max
= static_cast<T
>((1 << size
) - 1);
141 // both-error@-1 {{constexpr variable 'max' must be initialized by a constant expression}}
142 // both-note@-2 {{integer value 15 is outside the valid range of values [0, 7] for the enumeration type 'E2'}}
145 void testValueInRangeOfEnumerationValuesViaTemplate() {
146 Bitfield
<E2
, 3> good
;
147 Bitfield
<E2
, 4> bad
; // both-note {{in instantiation}}
156 static void f(SortOrder order
);
159 void A::f(SortOrder order
) {
160 if (order
== SortOrder(-1)) // ok, not a constant expression context
165 namespace FinalLtorDiags
{
166 template<int*> struct A
{}; // both-note {{template parameter is declared here}}
168 int *q
= &k
; // both-note {{declared here}}
169 A
<q
> c
; // both-error {{non-type template argument of type 'int *' is not a constant expression}} \
170 // both-note {{read of non-constexpr variable 'q' is not allowed in a constant expression}}
175 int a9
[1] = {[d
= 0] = 1}; // both-error {{not an integral constant expression}}