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" }
6 
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__
12 
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)
18 
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)
24 
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)
30 
31 // Helper macros.
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))
50 
51 // Result object.
52 template <class T>
53 struct Res
54 {
ResRes55   constexpr Res (T a, bool v): z (a), v (v) { }
56   T z; bool v;
57 };
58 
59 template <class T>
60 constexpr bool operator== (Res<T> a, Res<T> b)
61 {
62   return a.z == b.z && a.v == b.v;
63 }
64 
65 #define StaticAssert(expr) static_assert ((expr), #expr)
66 
67 #define CONCAT(a, b)   a ## b
68 #define CAT(a, b)      CONCAT (a, b)
69 
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; };
77 
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)				\
85   {									\
86     ResType<T>::type c = 0;						\
87     bool v = __builtin_ ## op ## _overflow (a, b, &c);			\
88     return Res<T>(c, v);						\
89   }									\
90   StaticAssert (vflow ? CAT (op, __LINE__)(x, y).v			\
91 		: CAT (op, __LINE__)(x, y) == Res<T>(op (x, y), vflow))
92 
93 /* If short and int are the same size we will overflow in some additional cases
94    when testing short.  */
95 #define INT_EQ_SHORT __SIZEOF_INT__ == __SIZEOF_SHORT__
96 
97 /* Signed int addition.  */
98 TEST (sadd,   signed char,    0,         0,         0);
99 TEST (sadd,   signed char,    0,         SCHAR_MAX, 0);
100 TEST (sadd,   signed char,    1,         SCHAR_MAX, 0);
101 TEST (sadd,   signed char,    SCHAR_MAX, SCHAR_MAX, 0);
102 TEST (sadd,   signed char,    0,         SCHAR_MIN, 0);
103 TEST (sadd,   signed char,   -1,         SCHAR_MIN, 0);
104 
105 TEST (sadd,   short,          0,         0,         0);
106 TEST (sadd,   short,          0,         SHRT_MAX,  0);
107 TEST (sadd,   short,          1,         SHRT_MAX,  INT_EQ_SHORT);
108 TEST (sadd,   short,          SHRT_MAX,  SHRT_MAX,  INT_EQ_SHORT);
109 TEST (sadd,   short,          0,         SHRT_MIN,  0);
110 TEST (sadd,   short,         -1,         SHRT_MIN,  INT_EQ_SHORT);
111 TEST (sadd,   short,          SHRT_MIN,  SHRT_MIN,  INT_EQ_SHORT);
112 
113 TEST (sadd,   int,            0,         0,         0);
114 TEST (sadd,   int,            0,         INT_MAX,   0);
115 TEST (sadd,   int,            1,         INT_MAX,   1);
116 TEST (sadd,   int,            INT_MAX,   INT_MAX,   1);
117 TEST (sadd,   int,            0,         INT_MIN,   0);
118 TEST (sadd,   int,           -1,         INT_MIN,   1);
119 TEST (sadd,   int,            INT_MIN,   INT_MIN,   1);
120 
121 /* Signed long addition.  */
122 TEST (saddl,  long,           0L,        0L,        0);
123 TEST (saddl,  long,           0L,        LONG_MAX,  0);
124 TEST (saddl,  long,           1L,        LONG_MAX,  1);
125 TEST (saddl,  long,           LONG_MAX,  LONG_MAX,  1);
126 TEST (saddl,  long,           0L,        LONG_MIN,  0);
127 TEST (saddl,  long,          -1L,        LONG_MIN,  1);
128 TEST (saddl,  long,           LONG_MIN,  LONG_MIN,  1);
129 
130 TEST (saddll, long long,      0LL,       0LL,        0);
131 TEST (saddll, long long,      0LL,       LLONG_MAX,  0);
132 TEST (saddll, long long,      1LL,       LLONG_MAX,  1);
133 TEST (saddll, long long,      LLONG_MAX, LLONG_MAX,  1);
134 TEST (saddll, long long,      0LL,       LLONG_MIN,  0);
135 TEST (saddll, long long,     -1LL,       LLONG_MIN,  1);
136 TEST (saddll, long long,      LLONG_MIN, LLONG_MIN,  1);
137 
138 /* Unsigned int addition.  */
139 TEST (uadd,   unsigned char,  0U,        0U,         0);
140 TEST (uadd,   unsigned char,  0U,        UCHAR_MAX, 0);
141 TEST (uadd,   unsigned char,  1U,        UCHAR_MAX, 0);
142 TEST (uadd,   unsigned char,  UCHAR_MAX, UCHAR_MAX, 0);
143 
144 TEST (uadd,   unsigned short, 0U,        0U,         0);
145 TEST (uadd,   unsigned short, 0U,        USHRT_MAX,  0);
146 TEST (uadd,   unsigned short, 1U,        USHRT_MAX,  INT_EQ_SHORT);
147 TEST (uadd,   unsigned short, USHRT_MAX, USHRT_MAX,  INT_EQ_SHORT);
148 
149 TEST (uadd,   unsigned,       0U,        0U,         0);
150 TEST (uadd,   unsigned,       0U,        UINT_MAX,   0);
151 TEST (uadd,   unsigned,       1U,        UINT_MAX,   1);
152 TEST (uadd,   unsigned,       UINT_MAX,  UINT_MAX,   1);
153 
154 /* Unsigned long addition.  */
155 TEST (uaddl,  unsigned long,  0UL,       0UL,       0);
156 TEST (uaddl,  unsigned long,  0UL,       ULONG_MAX, 0);
157 TEST (uaddl,  unsigned long,  1UL,       ULONG_MAX, 1);
158 TEST (uaddl,  unsigned long,  ULONG_MAX, ULONG_MAX, 1);
159 
160 TEST (uaddll, unsigned long long, 0ULL,       0ULL,       0);
161 TEST (uaddll, unsigned long long, 0ULL,       ULLONG_MAX, 0);
162 TEST (uaddll, unsigned long long, 1ULL,       ULLONG_MAX, 1);
163 TEST (uaddll, unsigned long long, ULLONG_MAX, ULLONG_MAX, 1);
164 
165 /* Signed int subtraction.  */
166 TEST (ssub,   signed char,    0,         0,          0);
167 TEST (ssub,   signed char,    0,         SCHAR_MAX,  0);
168 TEST (ssub,   signed char,    1,         SCHAR_MAX,  0);
169 TEST (ssub,   signed char,    SCHAR_MAX, SCHAR_MAX,  0);
170 TEST (ssub,   signed char,    0,         SCHAR_MIN,  0);
171 TEST (ssub,   signed char,   -1,         SCHAR_MIN,  0);
172 
173 TEST (ssub,   short,          0,         0,          0);
174 TEST (ssub,   short,          0,         SHRT_MAX,   0);
175 TEST (ssub,   short,          1,         SHRT_MAX,   0);
176 TEST (ssub,   short,          SHRT_MAX,  SHRT_MAX,   0);
177 TEST (ssub,   short,          0,         SHRT_MIN,   INT_EQ_SHORT);
178 TEST (ssub,   short,         -1,         SHRT_MIN,   0);
179 TEST (ssub,   short,          SHRT_MIN,  SHRT_MIN,   0);
180 
181 TEST (ssub,   int,            0,         0,          0);
182 TEST (ssub,   int,            0,         INT_MAX,    0);
183 TEST (ssub,   int,            1,         INT_MAX,    0);
184 TEST (ssub,   int,            INT_MAX,   INT_MAX,    0);
185 TEST (ssub,   int,            0,         INT_MIN,    1);
186 TEST (ssub,   int,           -1,         INT_MIN,    0);
187 TEST (ssub,   int,            INT_MIN,   INT_MIN,    0);
188 
189 /* Signed long subtraction.  */
190 TEST (ssubl,  long,           0L,        0L,         0);
191 TEST (ssubl,  long,           0L,        LONG_MAX,   0);
192 TEST (ssubl,  long,           1L,        LONG_MAX,   0);
193 TEST (ssubl,  long,           LONG_MAX,  LONG_MAX,   0);
194 TEST (ssubl,  long,           0L,        LONG_MIN,   1);
195 TEST (ssubl,  long,          -1L,        LONG_MIN,   0);
196 TEST (ssubl,  long,           LONG_MIN,  LONG_MIN,   0);
197 
198 /* Signed long long subtraction.  */
199 TEST (ssubll, long long,      0LL,       0LL,        0);
200 TEST (ssubll, long long,      0LL,       LLONG_MAX,  0);
201 TEST (ssubll, long long,      1LL,       LLONG_MAX,  0);
202 TEST (ssubll, long long,      LLONG_MAX, LLONG_MAX,  0);
203 TEST (ssubll, long long,      0LL,       LLONG_MIN,  1);
204 TEST (ssubll, long long,     -1LL,       LLONG_MIN,  0);
205 TEST (ssubll, long long,      LLONG_MIN, LLONG_MIN,  0);
206 
207 /* Unsigned int subtraction.  */
208 TEST (usub,   unsigned char,  0U,        0U,         0);
209 TEST (usub,   unsigned char,  0U,        UCHAR_MAX,  1);
210 TEST (usub,   unsigned char,  1U,        UCHAR_MAX,  1);
211 TEST (usub,   unsigned char,  UCHAR_MAX, UCHAR_MAX,  0);
212 
213 TEST (usub,   unsigned short, 0U,        0U,         0);
214 TEST (usub,   unsigned short, 0U,        USHRT_MAX,  1);
215 TEST (usub,   unsigned short, 1U,        USHRT_MAX,  1);
216 TEST (usub,   unsigned short, USHRT_MAX, USHRT_MAX,  0);
217 
218 TEST (usub,   unsigned,       0U,        0U,         0);
219 TEST (usub,   unsigned,       0U,        UINT_MAX,   1);
220 TEST (usub,   unsigned,       1U,        UINT_MAX,   1);
221 TEST (usub,   unsigned,       UINT_MAX,  UINT_MAX,   0);
222 
223 /* Unsigned long subtraction.  */
224 TEST (usubl,  unsigned long,  0UL,       0UL,       0);
225 TEST (usubl,  unsigned long,  0UL,       ULONG_MAX, 1);
226 TEST (usubl,  unsigned long,  1UL,       ULONG_MAX, 1);
227 TEST (usubl,  unsigned long,  ULONG_MAX, ULONG_MAX, 0);
228 
229 /* Unsigned long long subtraction.  */
230 TEST (usubll, unsigned long long,  0ULL,       0ULL,       0);
231 TEST (usubll, unsigned long long,  0ULL,       ULLONG_MAX, 1);
232 TEST (usubll, unsigned long long,  1ULL,       ULLONG_MAX, 1);
233 TEST (usubll, unsigned long long,  ULLONG_MAX, ULLONG_MAX, 0);
234