annotate gcc/testsuite/g++.dg/cpp0x/constexpr-arith-overflow.C @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 04ced10e8804
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 // PR c++/70507 - integer overflow builtins not constant expressions
kono
parents:
diff changeset
2 // { dg-do compile { target c++11 } }
kono
parents:
diff changeset
3
kono
parents:
diff changeset
4 #define SCHAR_MAX __SCHAR_MAX__
kono
parents:
diff changeset
5 #define SHRT_MAX __SHRT_MAX__
kono
parents:
diff changeset
6 #define INT_MAX __INT_MAX__
kono
parents:
diff changeset
7 #define LONG_MAX __LONG_MAX__
kono
parents:
diff changeset
8 #define LLONG_MAX __LONG_LONG_MAX__
kono
parents:
diff changeset
9
kono
parents:
diff changeset
10 #define SCHAR_MIN (-__SCHAR_MAX__ - 1)
kono
parents:
diff changeset
11 #define SHRT_MIN (-__SHRT_MAX__ - 1)
kono
parents:
diff changeset
12 #define INT_MIN (-__INT_MAX__ - 1)
kono
parents:
diff changeset
13 #define LONG_MIN (-__LONG_MAX__ - 1)
kono
parents:
diff changeset
14 #define LLONG_MIN (-__LONG_LONG_MAX__ - 1)
kono
parents:
diff changeset
15
kono
parents:
diff changeset
16 #define UCHAR_MAX (SCHAR_MAX * 2U + 1)
kono
parents:
diff changeset
17 #define USHRT_MAX (SHRT_MAX * 2U + 1)
kono
parents:
diff changeset
18 #define UINT_MAX (INT_MAX * 2U + 1)
kono
parents:
diff changeset
19 #define ULONG_MAX (LONG_MAX * 2LU + 1)
kono
parents:
diff changeset
20 #define ULLONG_MAX (LLONG_MAX * 2LLU + 1)
kono
parents:
diff changeset
21
kono
parents:
diff changeset
22 #define USCHAR_MIN (-__USCHAR_MAX__ - 1)
kono
parents:
diff changeset
23 #define USHRT_MIN (-__USHRT_MAX__ - 1)
kono
parents:
diff changeset
24 #define UINT_MIN (-__UINT_MAX__ - 1)
kono
parents:
diff changeset
25 #define ULONG_MIN (-__ULONG_MAX__ - 1)
kono
parents:
diff changeset
26 #define ULLONG_MIN (-__ULONG_LONG_MAX__ - 1)
kono
parents:
diff changeset
27
kono
parents:
diff changeset
28 #define Assert(expr) static_assert ((expr), #expr)
kono
parents:
diff changeset
29
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 111
diff changeset
30 #if __cplusplus >= 201402L
111
kono
parents:
diff changeset
31 template <class T>
kono
parents:
diff changeset
32 constexpr T add (T x, T y, T z = T ())
kono
parents:
diff changeset
33 {
kono
parents:
diff changeset
34 return __builtin_add_overflow (x, y, &z) ? 0 : z;
kono
parents:
diff changeset
35 }
kono
parents:
diff changeset
36
kono
parents:
diff changeset
37 template <class T>
kono
parents:
diff changeset
38 constexpr T sub (T x, T y, T z = T ())
kono
parents:
diff changeset
39 {
kono
parents:
diff changeset
40 return __builtin_sub_overflow (x, y, &z) ? 0 : z;
kono
parents:
diff changeset
41 }
kono
parents:
diff changeset
42
kono
parents:
diff changeset
43 template <class T>
kono
parents:
diff changeset
44 constexpr T mul (T x, T y, T z = T ())
kono
parents:
diff changeset
45 {
kono
parents:
diff changeset
46 return __builtin_mul_overflow (x, y, &z) ? 0 : z;
kono
parents:
diff changeset
47 }
kono
parents:
diff changeset
48
kono
parents:
diff changeset
49 #define TEST_ADD(T, x, y, z) Assert (z == add<T>(x, y))
kono
parents:
diff changeset
50 #define TEST_SUB(T, x, y, z) Assert (z == sub<T>(x, y))
kono
parents:
diff changeset
51 #define TEST_MUL(T, x, y, z) Assert (z == mul<T>(x, y))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 111
diff changeset
52 #else
1830386684a0 gcc-9.2.0
anatofuz
parents: 111
diff changeset
53 #define TEST_ADD(T, x, y, z) Assert (true)
1830386684a0 gcc-9.2.0
anatofuz
parents: 111
diff changeset
54 #define TEST_SUB(T, x, y, z) Assert (true)
1830386684a0 gcc-9.2.0
anatofuz
parents: 111
diff changeset
55 #define TEST_MUL(T, x, y, z) Assert (true)
1830386684a0 gcc-9.2.0
anatofuz
parents: 111
diff changeset
56 #endif
111
kono
parents:
diff changeset
57
kono
parents:
diff changeset
58
kono
parents:
diff changeset
59 TEST_ADD (signed char, 0, 0, 0);
kono
parents:
diff changeset
60 TEST_ADD (signed char, 0, SCHAR_MAX, SCHAR_MAX);
kono
parents:
diff changeset
61 TEST_ADD (signed char, 1, SCHAR_MAX, 0); // overflow
kono
parents:
diff changeset
62 TEST_ADD (signed char, SCHAR_MAX, SCHAR_MAX, 0); // overflow
kono
parents:
diff changeset
63 TEST_ADD (signed char, 0, SCHAR_MIN, SCHAR_MIN);
kono
parents:
diff changeset
64 TEST_ADD (signed char, -1, SCHAR_MIN, 0); // overflow
kono
parents:
diff changeset
65
kono
parents:
diff changeset
66 TEST_ADD (short, 0, 0, 0);
kono
parents:
diff changeset
67 TEST_ADD (short, 0, SHRT_MAX, SHRT_MAX);
kono
parents:
diff changeset
68 TEST_ADD (short, 1, SHRT_MAX, 0); // overflow
kono
parents:
diff changeset
69 TEST_ADD (short, SHRT_MAX, SHRT_MAX, 0); // overflow
kono
parents:
diff changeset
70 TEST_ADD (short, 0, SHRT_MIN, SHRT_MIN);
kono
parents:
diff changeset
71 TEST_ADD (short, -1, SHRT_MIN, 0); // overflow
kono
parents:
diff changeset
72 TEST_ADD (short, SHRT_MIN, SHRT_MIN, 0); // overflow
kono
parents:
diff changeset
73
kono
parents:
diff changeset
74 TEST_ADD (int, 0, 0, 0);
kono
parents:
diff changeset
75 TEST_ADD (int, 0, INT_MAX, INT_MAX);
kono
parents:
diff changeset
76 TEST_ADD (int, 1, INT_MAX, 0); // overflow
kono
parents:
diff changeset
77 TEST_ADD (int, INT_MAX, INT_MAX, 0); // overflow
kono
parents:
diff changeset
78 TEST_ADD (int, 0, INT_MIN, INT_MIN);
kono
parents:
diff changeset
79 TEST_ADD (int, -1, INT_MIN, 0); // overflow
kono
parents:
diff changeset
80 TEST_ADD (int, INT_MIN, INT_MIN, 0); // overflow
kono
parents:
diff changeset
81
kono
parents:
diff changeset
82 TEST_ADD (long, 0, 0, 0);
kono
parents:
diff changeset
83 TEST_ADD (long, 0, LONG_MAX, LONG_MAX);
kono
parents:
diff changeset
84 TEST_ADD (long, 1, LONG_MAX, 0); // overflow
kono
parents:
diff changeset
85 TEST_ADD (long, LONG_MAX, LONG_MAX, 0); // overflow
kono
parents:
diff changeset
86 TEST_ADD (long, 0, LONG_MIN, LONG_MIN);
kono
parents:
diff changeset
87 TEST_ADD (long, -1, LONG_MIN, 0); // overflow
kono
parents:
diff changeset
88 TEST_ADD (long, LONG_MIN, LONG_MIN, 0); // overflow
kono
parents:
diff changeset
89
kono
parents:
diff changeset
90 TEST_ADD (long long, 0, 0, 0);
kono
parents:
diff changeset
91 TEST_ADD (long long, 0, LLONG_MAX, LLONG_MAX);
kono
parents:
diff changeset
92 TEST_ADD (long long, 1, LLONG_MAX, 0); // overflow
kono
parents:
diff changeset
93 TEST_ADD (long long, LLONG_MAX, LLONG_MAX, 0); // overflow
kono
parents:
diff changeset
94 TEST_ADD (long long, 0, LLONG_MIN, LLONG_MIN);
kono
parents:
diff changeset
95 TEST_ADD (long long, -1, LLONG_MIN, 0); // overflow
kono
parents:
diff changeset
96 TEST_ADD (long long, LLONG_MIN, LLONG_MIN, 0); // overflow
kono
parents:
diff changeset
97
kono
parents:
diff changeset
98 TEST_ADD (unsigned char, 0, 0, 0);
kono
parents:
diff changeset
99 TEST_ADD (unsigned char, 0, UCHAR_MAX, UCHAR_MAX);
kono
parents:
diff changeset
100 TEST_ADD (unsigned char, 1, UCHAR_MAX, 0); // overflow
kono
parents:
diff changeset
101
kono
parents:
diff changeset
102 TEST_ADD (unsigned char, UCHAR_MAX, UCHAR_MAX, 0); // overflow
kono
parents:
diff changeset
103 TEST_ADD (unsigned short, 0, 0, 0);
kono
parents:
diff changeset
104 TEST_ADD (unsigned short, 0, USHRT_MAX, USHRT_MAX);
kono
parents:
diff changeset
105 TEST_ADD (unsigned short, 1, USHRT_MAX, 0); // overflow
kono
parents:
diff changeset
106 TEST_ADD (unsigned short, USHRT_MAX, USHRT_MAX, 0); // overflow
kono
parents:
diff changeset
107
kono
parents:
diff changeset
108 TEST_ADD (unsigned, 0, 0, 0);
kono
parents:
diff changeset
109 TEST_ADD (unsigned, 0, UINT_MAX, UINT_MAX);
kono
parents:
diff changeset
110 TEST_ADD (unsigned, 1, UINT_MAX, 0); // overflow
kono
parents:
diff changeset
111 TEST_ADD (unsigned, UINT_MAX, UINT_MAX, 0); // overflow
kono
parents:
diff changeset
112
kono
parents:
diff changeset
113 TEST_ADD (unsigned long, 0, 0, 0);
kono
parents:
diff changeset
114 TEST_ADD (unsigned long, 0, ULONG_MAX, ULONG_MAX);
kono
parents:
diff changeset
115 TEST_ADD (unsigned long, 1, ULONG_MAX, 0); // overflow
kono
parents:
diff changeset
116 TEST_ADD (unsigned long, ULONG_MAX, ULONG_MAX, 0); // overflow
kono
parents:
diff changeset
117
kono
parents:
diff changeset
118 TEST_ADD (unsigned long long, 0, 0, 0);
kono
parents:
diff changeset
119 TEST_ADD (unsigned long long, 0, ULLONG_MAX, ULLONG_MAX);
kono
parents:
diff changeset
120 TEST_ADD (unsigned long long, 1, ULLONG_MAX, 0); // overflow
kono
parents:
diff changeset
121 TEST_ADD (unsigned long long, ULLONG_MAX, ULLONG_MAX, 0); // overflow
kono
parents:
diff changeset
122
kono
parents:
diff changeset
123
kono
parents:
diff changeset
124 // Make sure the built-ins are accepted in the following contexts
kono
parents:
diff changeset
125 // where constant expressions are required and that they return
kono
parents:
diff changeset
126 // the expected overflow value.
kono
parents:
diff changeset
127
kono
parents:
diff changeset
128 namespace Enum {
kono
parents:
diff changeset
129
kono
parents:
diff changeset
130 enum Add {
kono
parents:
diff changeset
131 a0 = __builtin_add_overflow_p ( 1, 1, 0),
kono
parents:
diff changeset
132 a1 = __builtin_add_overflow_p (INT_MAX, 1, 0)
kono
parents:
diff changeset
133 };
kono
parents:
diff changeset
134
kono
parents:
diff changeset
135 Assert (a0 == 0);
kono
parents:
diff changeset
136 Assert (a1 == 1);
kono
parents:
diff changeset
137
kono
parents:
diff changeset
138 enum Sub {
kono
parents:
diff changeset
139 s0 = __builtin_sub_overflow_p ( 1, 1, 0),
kono
parents:
diff changeset
140 s1 = __builtin_sub_overflow_p (INT_MIN, 1, 0)
kono
parents:
diff changeset
141 };
kono
parents:
diff changeset
142
kono
parents:
diff changeset
143 Assert (s0 == 0);
kono
parents:
diff changeset
144 Assert (s1 == 1);
kono
parents:
diff changeset
145
kono
parents:
diff changeset
146 enum Mul {
kono
parents:
diff changeset
147 m0 = __builtin_add_overflow_p ( 1, 1, 0),
kono
parents:
diff changeset
148 m1 = __builtin_add_overflow_p (INT_MAX, INT_MAX, 0)
kono
parents:
diff changeset
149 };
kono
parents:
diff changeset
150
kono
parents:
diff changeset
151 Assert (m0 == 0);
kono
parents:
diff changeset
152 Assert (m1 == 1);
kono
parents:
diff changeset
153
kono
parents:
diff changeset
154 } // namespace Enum
kono
parents:
diff changeset
155
kono
parents:
diff changeset
156 namespace TemplateArg {
kono
parents:
diff changeset
157
kono
parents:
diff changeset
158 template <class T, class U, class V,
kono
parents:
diff changeset
159 T x, U y, bool v, bool z = __builtin_add_overflow_p (x, y, V ())>
kono
parents:
diff changeset
160 struct Add {
kono
parents:
diff changeset
161 Assert (z == v);
kono
parents:
diff changeset
162 };
kono
parents:
diff changeset
163
kono
parents:
diff changeset
164 template <class T, class U, class V,
kono
parents:
diff changeset
165 T x, U y, bool v, bool z = __builtin_sub_overflow_p (x, y, V ())>
kono
parents:
diff changeset
166 struct Sub {
kono
parents:
diff changeset
167 Assert (z == v);
kono
parents:
diff changeset
168 };
kono
parents:
diff changeset
169
kono
parents:
diff changeset
170 template <class T, class U, class V,
kono
parents:
diff changeset
171 T x, U y, bool v, bool z = __builtin_mul_overflow_p (x, y, V ())>
kono
parents:
diff changeset
172 struct Mul {
kono
parents:
diff changeset
173 Assert (z == v);
kono
parents:
diff changeset
174 };
kono
parents:
diff changeset
175
kono
parents:
diff changeset
176 template struct Add<int, int, int, 1, 1, false>;
kono
parents:
diff changeset
177 template struct Add<int, int, int, 1, INT_MAX, true>;
kono
parents:
diff changeset
178
kono
parents:
diff changeset
179 template struct Sub<int, int, int, 1, 1, false>;
kono
parents:
diff changeset
180 template struct Sub<int, int, int, -2, INT_MAX, true>;
kono
parents:
diff changeset
181
kono
parents:
diff changeset
182 template struct Mul<int, int, int, 1, 1, false>;
kono
parents:
diff changeset
183 template struct Mul<int, int, int, 2, INT_MAX / 2 + 1, true>;
kono
parents:
diff changeset
184
kono
parents:
diff changeset
185 } // namespace TemplateArg
kono
parents:
diff changeset
186
kono
parents:
diff changeset
187 #if __cplusplus >= 201402L
kono
parents:
diff changeset
188
kono
parents:
diff changeset
189 namespace Initializer {
kono
parents:
diff changeset
190
kono
parents:
diff changeset
191 struct Result {
kono
parents:
diff changeset
192 int res;
kono
parents:
diff changeset
193 bool vflow;
kono
parents:
diff changeset
194 };
kono
parents:
diff changeset
195
kono
parents:
diff changeset
196 constexpr Result
kono
parents:
diff changeset
197 add_vflow (int a, int b)
kono
parents:
diff changeset
198 {
kono
parents:
diff changeset
199 #if 1
kono
parents:
diff changeset
200 Result res = { a + b, __builtin_add_overflow_p (a, b, int ()) };
kono
parents:
diff changeset
201 #else
kono
parents:
diff changeset
202 // The following fails to compile because of c++/71391 - error
kono
parents:
diff changeset
203 // on aggregate initialization with side-effects in a constexpr
kono
parents:
diff changeset
204 // function
kono
parents:
diff changeset
205 int c = 0;
kono
parents:
diff changeset
206 Result res = { 0, __builtin_add_overflow (a, b, &c) };
kono
parents:
diff changeset
207 res.c = c;
kono
parents:
diff changeset
208 #endif
kono
parents:
diff changeset
209 return res;
kono
parents:
diff changeset
210 }
kono
parents:
diff changeset
211
kono
parents:
diff changeset
212 constexpr Result sum = add_vflow (123, 456);
kono
parents:
diff changeset
213 Assert (sum.res == 123 + 456);
kono
parents:
diff changeset
214 Assert (!sum.vflow);
kono
parents:
diff changeset
215
kono
parents:
diff changeset
216 } // namespace Initializer
kono
parents:
diff changeset
217
kono
parents:
diff changeset
218 #endif // __cplusplus >= 201402L