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 /* 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); 100 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); 108 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); 116 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); 125 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); 133 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); 139 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); 144 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); 149 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); 155 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); 160 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); 168 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); 176 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); 184 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); 193 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); 202 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); 208 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); 213 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); 218 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); 224 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); 230