/* { dg-do run } */ /* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O2" } } */ /* { dg-options "-fsanitize=float-cast-overflow -fno-sanitize-recover=float-cast-overflow" } */ /* FIXME: When _DecimalXX <-> {signed, unsigned} __int128 conversions are supported, -DBROKEN_DECIMAL_INT128 can be removed. */ /* { dg-additional-options "-DUSE_DFP -DBROKEN_DECIMAL_INT128" { target dfp } } */ #define USE_FLT_DBL_LDBL #ifdef __SIZEOF_INT128__ #define USE_INT128 #endif #ifdef __SIZEOF_FLOAT80__ #define USE_FLOAT80 #endif #ifdef __SIZEOF_FLOAT128__ #define USE_FLOAT128 #endif #include "float-cast-overflow-7.h" #define TEST(type1, type2) \ if (cvt_##type1##_##type2 (-0.5f) != 0) abort (); \ if (cvt_##type1##_##type2 (0.5f) != 0) abort (); \ if (cvt_##type1##_##type2 (-0.75f) != 0) abort (); \ if (cvt_##type1##_##type2 (0.75f) != 0) abort (); \ if (type1##_MIN) \ { \ /* For RADIX 2 type1##_MIN should be always */ \ /* exactly representable in type2. */ \ if (type2##_RADIX == 2 \ || type1##_MAX <= type2##_MAX) \ { \ if (cvt_##type1##_##type2 (type1##_MIN) \ != type1##_MIN) abort (); \ volatile type2 tem = ((type2) -0.75f) + type1##_MIN; \ volatile type2 tem2 = ((type2) -1.0f) + type1##_MIN; \ if (tem != tem2 \ && cvt_##type1##_##type2 ((type2) -0.75f \ + type1##_MIN) \ != type1##_MIN) abort (); \ } \ else \ { \ type2 min = type1##_MIN; \ /* tem could be below minimum here due to */ \ /* rounding. */ \ MAXT add = 1; \ while (add) \ { \ volatile type2 tem = type1##_MIN + (type1) add; \ if (tem != min) \ break; \ MAXT newadd = add * type2##_RADIX; \ if (newadd < add || newadd > type1##_MAX) \ add = 0; \ else \ add = newadd; \ } \ if (add) \ { \ MAXT newadd \ = (-(type1##_MIN + (type1) add)) % add; \ volatile type2 tem = type1##_MIN + (type1) newadd;\ volatile type2 tem2 = type1##_MIN + (type1) add; \ if (tem == tem2) \ add = newadd; \ else \ { \ newadd += add; \ if (newadd < add || newadd > type1##_MAX) \ add = 0; \ else \ { \ tem = type1##_MIN + (type1) newadd; \ if (tem == tem2) \ add = newadd; \ else \ add = 0; \ } \ } \ } \ if (add \ && cvt_##type1##_##type2 (type1##_MIN \ + (type1) add) \ != type1##_MIN + (type1) add) abort (); \ } \ } \ if (type1##_MAX <= type2##_MAX) \ { \ if (cvt_##type1##_##type2 (type1##_MAX) != type1##_MAX) \ abort (); \ volatile type2 tem = ((type2) 0.75f) + type1##_MAX; \ volatile type2 tem2 = ((type2) 1.0f) + type1##_MAX; \ if (tem < tem2 \ && cvt_##type1##_##type2 ((type2) 0.75f + type1##_MAX)\ != type1##_MAX) abort (); \ } \ else \ { \ type2 max = type1##_MAX; \ /* tem could be above maximum here due to rounding. */ \ MAXT sub = 1; \ while (sub) \ { \ volatile type2 tem = type1##_MAX - sub; \ if (tem != max) \ break; \ MAXT newsub = sub * type2##_RADIX; \ if (newsub < sub || newsub > type1##_MAX) \ sub = 0; \ else \ sub = newsub; \ } \ if (sub) \ { \ MAXT newsub = ((type1##_MAX - sub) % sub); \ volatile type2 tem = type1##_MAX - newsub; \ volatile type2 tem2 = type1##_MAX - sub; \ if (tem == tem2) \ sub = newsub; \ else \ { \ newsub += sub; \ if (newsub < sub || newsub > type1##_MAX) \ sub = 0; \ else \ { \ tem = type1##_MAX - newsub; \ if (tem == tem2) \ sub = newsub; \ else \ sub = 0; \ } \ } \ } \ if (sub \ && cvt_##type1##_##type2 (type1##_MAX - sub) \ != type1##_MAX - sub) abort (); \ } #ifdef si128_MAX # define TESTS128(type2) TEST (si128, type2) TEST (ui128, type2) #else # define TESTS128(type2) #endif #define TESTS(type2) \ TEST (sc, type2) TEST (c, type2) TEST (uc, type2) \ TEST (ss, type2) TEST (us, type2) \ TEST (si, type2) TEST (ui, type2) \ TEST (sl, type2) TEST (ul, type2) \ TEST (sll, type2) TEST (ull, type2) \ TESTS128 (type2) int main () { #ifdef f_MAX TESTS (f) #endif #ifdef d_MAX TESTS (d) #endif #ifdef ld_MAX TESTS (ld) #endif #ifdef f80_MAX TESTS (f80) #endif #ifdef f128_MAX TESTS (f128) #endif #ifdef BROKEN_DECIMAL_INT128 # undef TESTS128 # define TESTS128(type2) # undef TWO # undef M1U # undef MAXS # undef MAXT # define TWO 2ULL # define M1U -1ULL # define MAXS (__CHAR_BIT__ * __SIZEOF_LONG_LONG__) # define MAXT unsigned long long #endif #ifdef d32_MAX TESTS (d32) #endif #ifdef d64_MAX TESTS (d64) #endif #ifdef d128_MAX TESTS (d128) #endif return 0; }