@@ -62,3 +62,93 @@ namespace ReferenceToConst {
6262 }
6363 };
6464}
65+
66+
67+
68+ namespace GH50055 {
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 };
73+ enum E4 {e41 =0 };
74+ // Empty but as-if it had a single enumerator with value 0
75+ enum EEmpty {};
76+
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 };
81+
82+ enum EMaxInt {emaxint1=-1 , emaxint2=__INT_MAX__};
83+
84+ enum NumberType {};
85+
86+ E2 testDefaultArgForParam (E2 e2Param = (E2 )-1) { // ok, not a constant expression context
87+ E2 e2LocalInit = e2Param; // ok, not a constant expression context
88+ return e2LocalInit;
89+ }
90+
91+ // #include <enum-constexpr-conversion-system-header.h>
92+
93+ void testValueInRangeOfEnumerationValues () {
94+ constexpr E1 x1 = static_cast <E1 >(-8 );
95+ constexpr E1 x2 = static_cast <E1 >(8 );
96+ // both-error@-1 {{integer value 8 is outside the valid range of values [-8, 7] for the enumeration type 'E1'}}
97+ E1 x2b = static_cast <E1 >(8 ); // ok, not a constant expression context
98+
99+ constexpr E2 x3 = static_cast <E2 >(-8 );
100+ // both-error@-1 {{integer value -8 is outside the valid range of values [0, 7] for the enumeration type 'E2'}}
101+ constexpr E2 x4 = static_cast <E2 >(0 );
102+ constexpr E2 x5 = static_cast <E2 >(8 );
103+ // both-error@-1 {{integer value 8 is outside the valid range of values [0, 7] for the enumeration type 'E2'}}
104+
105+ constexpr E3 x6 = static_cast <E3 >(-2048 );
106+ constexpr E3 x7 = static_cast <E3 >(-8 );
107+ constexpr E3 x8 = static_cast <E3 >(0 );
108+ constexpr E3 x9 = static_cast <E3 >(8 );
109+ constexpr E3 x10 = static_cast <E3 >(2048 );
110+ // both-error@-1 {{integer value 2048 is outside the valid range of values [-2048, 2047] for the enumeration type 'E3'}}
111+
112+ constexpr E4 x11 = static_cast <E4 >(0 );
113+ constexpr E4 x12 = static_cast <E4 >(1 );
114+ constexpr E4 x13 = static_cast <E4 >(2 );
115+ // both-error@-1 {{integer value 2 is outside the valid range of values [0, 1] for the enumeration type 'E4'}}
116+
117+ constexpr EEmpty x14 = static_cast <EEmpty>(0 );
118+ constexpr EEmpty x15 = static_cast <EEmpty>(1 );
119+ constexpr EEmpty x16 = static_cast <EEmpty>(2 );
120+ // both-error@-1 {{integer value 2 is outside the valid range of values [0, 1] for the enumeration type 'EEmpty'}}
121+
122+ constexpr EFixed x17 = static_cast <EFixed>(100 );
123+ constexpr EScoped x18 = static_cast <EScoped>(100 );
124+
125+ constexpr EMaxInt x19 = static_cast <EMaxInt>(__INT_MAX__-1 );
126+ constexpr EMaxInt x20 = static_cast <EMaxInt>((long )__INT_MAX__+1 );
127+ // both-error@-1 {{integer value 2147483648 is outside the valid range of values [-2147483648, 2147483647] for the enumeration type 'EMaxInt'}}
128+
129+ const NumberType neg_one = (NumberType) ((NumberType) 0 - (NumberType) 1 ); // ok, not a constant expression context
130+ }
131+
132+ template <class T , unsigned size> struct Bitfield {
133+ static constexpr T max = static_cast <T>((1 << size) - 1 ); // #enum
134+ };
135+
136+ void testValueInRangeOfEnumerationValuesViaTemplate () {
137+ Bitfield<E2 , 3 > good;
138+ Bitfield<E2 , 4 > bad; // both-error@#enum {{integer value 15 is outside the valid range of values [0, 7] for the enumeration type 'E2'}}
139+ }
140+
141+ enum SortOrder {
142+ AscendingOrder,
143+ DescendingOrder
144+ };
145+
146+ class A {
147+ static void f (SortOrder order);
148+ };
149+
150+ void A::f (SortOrder order) {
151+ if (order == SortOrder (-1 )) // ok, not a constant expression context
152+ return ;
153+ }
154+ }
0 commit comments