1 // Test to exercise that the type-specific integer arithmetic built-ins
2 // with overflow checking can be used in C++ 14 constant expressions.
3 // -Woverflow is disabled to prevent (bogus?) G++ warnings.
4 // { dg-do compile { target c++14 } }
5 // { dg-additional-options "-Wno-overflow" }
7 #define SCHAR_MAX __SCHAR_MAX__
8 #define SHRT_MAX __SHRT_MAX__
9 #define INT_MAX __INT_MAX__
10 #define LONG_MAX __LONG_MAX__
11 #define LLONG_MAX __LONG_LONG_MAX__
13 #define SCHAR_MIN (-__SCHAR_MAX__ - 1)
14 #define SHRT_MIN (-__SHRT_MAX__ - 1)
15 #define INT_MIN (-__INT_MAX__ - 1)
16 #define LONG_MIN (-__LONG_MAX__ - 1)
17 #define LLONG_MIN (-__LONG_LONG_MAX__ - 1)
19 #define UCHAR_MAX (SCHAR_MAX * 2U + 1)
20 #define USHRT_MAX (SHRT_MAX * 2U + 1)
21 #define UINT_MAX (INT_MAX * 2U + 1)
22 #define ULONG_MAX (LONG_MAX * 2LU + 1)
23 #define ULLONG_MAX (LLONG_MAX * 2LLU + 1)
25 #define USCHAR_MIN (-__USCHAR_MAX__ - 1)
26 #define USHRT_MIN (-__USHRT_MAX__ - 1)
27 #define UINT_MIN (-__UINT_MAX__ - 1)
28 #define ULONG_MIN (-__ULONG_MAX__ - 1)
29 #define ULLONG_MIN (-__ULONG_LONG_MAX__ - 1)
32 #define sadd(x, y) ((x) + (y))
33 #define saddl(x, y) ((x) + (y))
34 #define saddll(x, y) ((x) + (y))
35 #define uadd(x, y) ((x) + (y))
36 #define uaddl(x, y) ((x) + (y))
37 #define uaddll(x, y) ((x) + (y))
38 #define ssub(x, y) ((x) - (y))
39 #define ssubl(x, y) ((x) - (y))
40 #define ssubll(x, y) ((x) - (y))
41 #define usub(x, y) ((x) - (y))
42 #define usubl(x, y) ((x) - (y))
43 #define usubll(x, y) ((x) - (y))
44 #define smul(x, y) ((x) * (y))
45 #define smull(x, y) ((x) * (y))
46 #define smulll(x, y) ((x) * (y))
47 #define umul(x, y) ((x) * (y))
48 #define umull(x, y) ((x) * (y))
49 #define umulll(x, y) ((x) * (y))
55 constexpr Res (T a, bool v): z (a), v (v) { }
60 constexpr bool operator== (Res<T> a, Res<T> b)
62 return a.z == b.z && a.v == b.v;
65 #define StaticAssert(expr) static_assert ((expr), #expr)
67 #define CONCAT(a, b) a ## b
68 #define CAT(a, b) CONCAT (a, b)
70 // Helper to determine the type of the result of the arithmetic
71 // as specified by the built-ins.
72 template <class T> struct ResType { typedef T type; };
73 template <> struct ResType<signed char> { typedef int type; };
74 template <> struct ResType<unsigned char> { typedef unsigned type; };
75 template <> struct ResType<signed short> { typedef int type; };
76 template <> struct ResType<unsigned short> { typedef unsigned type; };
78 // Macro to define a single test case verifying that integer overflow
79 // is detected when expected, and when not, that the result matches
80 // the result computed using ordinary arithmetic. The result cannot
81 // be tested in the presence of overflow since it's not a core
82 // constant expression.
83 #define TEST(op, T, x, y, vflow) \
84 constexpr Res<T> CAT (op, __LINE__)(T a, T b) \
86 ResType<T>::type c = 0; \
87 bool v = __builtin_ ## op ## _overflow (a, b, &c); \
88 return Res<T>(c, v); \
90 StaticAssert (vflow ? CAT (op, __LINE__)(x, y).v \
91 : CAT (op, __LINE__)(x, y) == Res<T>(op (x, y), vflow))
93 /* Signed int addition. */
94 TEST (sadd, signed char, 0, 0, 0);
95 TEST (sadd, signed char, 0, SCHAR_MAX, 0);
96 TEST (sadd, signed char, 1, SCHAR_MAX, 0);
97 TEST (sadd, signed char, SCHAR_MAX, SCHAR_MAX, 0);
98 TEST (sadd, signed char, 0, SCHAR_MIN, 0);
99 TEST (sadd, signed char, -1, SCHAR_MIN, 0);
101 TEST (sadd, short, 0, 0, 0);
102 TEST (sadd, short, 0, SHRT_MAX, 0);
103 TEST (sadd, short, 1, SHRT_MAX, 0);
104 TEST (sadd, short, SHRT_MAX, SHRT_MAX, 0);
105 TEST (sadd, short, 0, SHRT_MIN, 0);
106 TEST (sadd, short, -1, SHRT_MIN, 0);
107 TEST (sadd, short, SHRT_MIN, SHRT_MIN, 0);
109 TEST (sadd, int, 0, 0, 0);
110 TEST (sadd, int, 0, INT_MAX, 0);
111 TEST (sadd, int, 1, INT_MAX, 1);
112 TEST (sadd, int, INT_MAX, INT_MAX, 1);
113 TEST (sadd, int, 0, INT_MIN, 0);
114 TEST (sadd, int, -1, INT_MIN, 1);
115 TEST (sadd, int, INT_MIN, INT_MIN, 1);
117 /* Signed long addition. */
118 TEST (saddl, long, 0L, 0L, 0);
119 TEST (saddl, long, 0L, LONG_MAX, 0);
120 TEST (saddl, long, 1L, LONG_MAX, 1);
121 TEST (saddl, long, LONG_MAX, LONG_MAX, 1);
122 TEST (saddl, long, 0L, LONG_MIN, 0);
123 TEST (saddl, long, -1L, LONG_MIN, 1);
124 TEST (saddl, long, LONG_MIN, LONG_MIN, 1);
126 TEST (saddll, long long, 0LL, 0LL, 0);
127 TEST (saddll, long long, 0LL, LLONG_MAX, 0);
128 TEST (saddll, long long, 1LL, LLONG_MAX, 1);
129 TEST (saddll, long long, LLONG_MAX, LLONG_MAX, 1);
130 TEST (saddll, long long, 0LL, LLONG_MIN, 0);
131 TEST (saddll, long long, -1LL, LLONG_MIN, 1);
132 TEST (saddll, long long, LLONG_MIN, LLONG_MIN, 1);
134 /* Unsigned int addition. */
135 TEST (uadd, unsigned char, 0U, 0U, 0);
136 TEST (uadd, unsigned char, 0U, UCHAR_MAX, 0);
137 TEST (uadd, unsigned char, 1U, UCHAR_MAX, 0);
138 TEST (uadd, unsigned char, UCHAR_MAX, UCHAR_MAX, 0);
140 TEST (uadd, unsigned short, 0U, 0U, 0);
141 TEST (uadd, unsigned short, 0U, USHRT_MAX, 0);
142 TEST (uadd, unsigned short, 1U, USHRT_MAX, 0);
143 TEST (uadd, unsigned short, USHRT_MAX, USHRT_MAX, 0);
145 TEST (uadd, unsigned, 0U, 0U, 0);
146 TEST (uadd, unsigned, 0U, UINT_MAX, 0);
147 TEST (uadd, unsigned, 1U, UINT_MAX, 1);
148 TEST (uadd, unsigned, UINT_MAX, UINT_MAX, 1);
150 /* Unsigned long addition. */
151 TEST (uaddl, unsigned long, 0UL, 0UL, 0);
152 TEST (uaddl, unsigned long, 0UL, ULONG_MAX, 0);
153 TEST (uaddl, unsigned long, 1UL, ULONG_MAX, 1);
154 TEST (uaddl, unsigned long, ULONG_MAX, ULONG_MAX, 1);
156 TEST (uaddll, unsigned long long, 0ULL, 0ULL, 0);
157 TEST (uaddll, unsigned long long, 0ULL, ULLONG_MAX, 0);
158 TEST (uaddll, unsigned long long, 1ULL, ULLONG_MAX, 1);
159 TEST (uaddll, unsigned long long, ULLONG_MAX, ULLONG_MAX, 1);
161 /* Signed int subtraction. */
162 TEST (ssub, signed char, 0, 0, 0);
163 TEST (ssub, signed char, 0, SCHAR_MAX, 0);
164 TEST (ssub, signed char, 1, SCHAR_MAX, 0);
165 TEST (ssub, signed char, SCHAR_MAX, SCHAR_MAX, 0);
166 TEST (ssub, signed char, 0, SCHAR_MIN, 0);
167 TEST (ssub, signed char, -1, SCHAR_MIN, 0);
169 TEST (ssub, short, 0, 0, 0);
170 TEST (ssub, short, 0, SHRT_MAX, 0);
171 TEST (ssub, short, 1, SHRT_MAX, 0);
172 TEST (ssub, short, SHRT_MAX, SHRT_MAX, 0);
173 TEST (ssub, short, 0, SHRT_MIN, 0);
174 TEST (ssub, short, -1, SHRT_MIN, 0);
175 TEST (ssub, short, SHRT_MIN, SHRT_MIN, 0);
177 TEST (ssub, int, 0, 0, 0);
178 TEST (ssub, int, 0, INT_MAX, 0);
179 TEST (ssub, int, 1, INT_MAX, 0);
180 TEST (ssub, int, INT_MAX, INT_MAX, 0);
181 TEST (ssub, int, 0, INT_MIN, 1);
182 TEST (ssub, int, -1, INT_MIN, 0);
183 TEST (ssub, int, INT_MIN, INT_MIN, 0);
185 /* Signed long subtraction. */
186 TEST (ssubl, long, 0L, 0L, 0);
187 TEST (ssubl, long, 0L, LONG_MAX, 0);
188 TEST (ssubl, long, 1L, LONG_MAX, 0);
189 TEST (ssubl, long, LONG_MAX, LONG_MAX, 0);
190 TEST (ssubl, long, 0L, LONG_MIN, 1);
191 TEST (ssubl, long, -1L, LONG_MIN, 0);
192 TEST (ssubl, long, LONG_MIN, LONG_MIN, 0);
194 /* Signed long long subtraction. */
195 TEST (ssubll, long long, 0LL, 0LL, 0);
196 TEST (ssubll, long long, 0LL, LLONG_MAX, 0);
197 TEST (ssubll, long long, 1LL, LLONG_MAX, 0);
198 TEST (ssubll, long long, LLONG_MAX, LLONG_MAX, 0);
199 TEST (ssubll, long long, 0LL, LLONG_MIN, 1);
200 TEST (ssubll, long long, -1LL, LLONG_MIN, 0);
201 TEST (ssubll, long long, LLONG_MIN, LLONG_MIN, 0);
203 /* Unsigned int subtraction. */
204 TEST (usub, unsigned char, 0U, 0U, 0);
205 TEST (usub, unsigned char, 0U, UCHAR_MAX, 1);
206 TEST (usub, unsigned char, 1U, UCHAR_MAX, 1);
207 TEST (usub, unsigned char, UCHAR_MAX, UCHAR_MAX, 0);
209 TEST (usub, unsigned short, 0U, 0U, 0);
210 TEST (usub, unsigned short, 0U, USHRT_MAX, 1);
211 TEST (usub, unsigned short, 1U, USHRT_MAX, 1);
212 TEST (usub, unsigned short, USHRT_MAX, USHRT_MAX, 0);
214 TEST (usub, unsigned, 0U, 0U, 0);
215 TEST (usub, unsigned, 0U, UINT_MAX, 1);
216 TEST (usub, unsigned, 1U, UINT_MAX, 1);
217 TEST (usub, unsigned, UINT_MAX, UINT_MAX, 0);
219 /* Unsigned long subtraction. */
220 TEST (usubl, unsigned long, 0UL, 0UL, 0);
221 TEST (usubl, unsigned long, 0UL, ULONG_MAX, 1);
222 TEST (usubl, unsigned long, 1UL, ULONG_MAX, 1);
223 TEST (usubl, unsigned long, ULONG_MAX, ULONG_MAX, 0);
225 /* Unsigned long long subtraction. */
226 TEST (usubll, unsigned long long, 0ULL, 0ULL, 0);
227 TEST (usubll, unsigned long long, 0ULL, ULLONG_MAX, 1);
228 TEST (usubll, unsigned long long, 1ULL, ULLONG_MAX, 1);
229 TEST (usubll, unsigned long long, ULLONG_MAX, ULLONG_MAX, 0);