1  /* { dg-do run } */
       2  /* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O2" } } */
       3  /* { dg-options "-fsanitize=float-cast-overflow -fno-sanitize-recover=float-cast-overflow" } */
       4  /* FIXME: When _DecimalXX <-> {signed, unsigned} __int128 conversions are
       5     supported, -DBROKEN_DECIMAL_INT128 can be removed.  */
       6  /* { dg-additional-options "-DUSE_DFP -DBROKEN_DECIMAL_INT128" { target dfp } } */
       7  
       8  #define USE_FLT_DBL_LDBL
       9  #ifdef __SIZEOF_INT128__
      10  #define USE_INT128
      11  #endif
      12  #ifdef __SIZEOF_FLOAT80__
      13  #define USE_FLOAT80
      14  #endif
      15  #ifdef __SIZEOF_FLOAT128__
      16  #define USE_FLOAT128
      17  #endif
      18  
      19  #include "float-cast-overflow-7.h"
      20  
      21  #define TEST(type1, type2) \
      22    if (cvt_##type1##_##type2 (-0.5f) != 0) abort ();		\
      23    if (cvt_##type1##_##type2 (0.5f) != 0) abort ();		\
      24    if (cvt_##type1##_##type2 (-0.75f) != 0) abort ();		\
      25    if (cvt_##type1##_##type2 (0.75f) != 0) abort ();		\
      26    if (type1##_MIN)						\
      27      {								\
      28        /* For RADIX 2 type1##_MIN should be always */		\
      29        /* exactly representable in type2.  */			\
      30        if (type2##_RADIX == 2					\
      31  	  || type1##_MAX <= type2##_MAX)			\
      32  	{							\
      33  	  if (cvt_##type1##_##type2 (type1##_MIN)		\
      34  	      != type1##_MIN) abort ();				\
      35  	  volatile type2 tem = ((type2) -0.75f) + type1##_MIN;	\
      36  	  volatile type2 tem2 = ((type2) -1.0f) + type1##_MIN;	\
      37  	  if (tem != tem2					\
      38  	      && cvt_##type1##_##type2 ((type2) -0.75f		\
      39  					+ type1##_MIN)		\
      40  		 != type1##_MIN) abort ();			\
      41  	}							\
      42        else							\
      43  	{							\
      44  	  type2 min = type1##_MIN;				\
      45  	  /* tem could be below minimum here due to */		\
      46  	  /* rounding.  */					\
      47  	  MAXT add = 1;						\
      48  	  while (add)						\
      49  	    {							\
      50  	      volatile type2 tem = type1##_MIN + (type1) add;	\
      51  	      if (tem != min)					\
      52  		break;						\
      53  	      MAXT newadd = add * type2##_RADIX;		\
      54  	      if (newadd < add || newadd > type1##_MAX)		\
      55  		add = 0;					\
      56  	      else						\
      57  		add = newadd;					\
      58  	    }							\
      59  	  if (add)						\
      60  	    {							\
      61  	      MAXT newadd					\
      62  		= (-(type1##_MIN + (type1) add)) % add;		\
      63  	      volatile type2 tem = type1##_MIN + (type1) newadd;\
      64  	      volatile type2 tem2 = type1##_MIN + (type1) add;	\
      65  	      if (tem == tem2)					\
      66  		add = newadd;					\
      67  	      else						\
      68  		{						\
      69  		  newadd += add;				\
      70  		  if (newadd < add || newadd > type1##_MAX)	\
      71  		    add = 0;					\
      72  		  else						\
      73  		    {						\
      74  		      tem = type1##_MIN + (type1) newadd;	\
      75  		      if (tem == tem2)				\
      76  			add = newadd;				\
      77  		      else					\
      78  			add = 0;				\
      79  		    }						\
      80  		}						\
      81  	    }							\
      82  	  if (add						\
      83  	      && cvt_##type1##_##type2 (type1##_MIN		\
      84  					+ (type1) add)		\
      85  		 != type1##_MIN + (type1) add) abort ();	\
      86  	}							\
      87      }								\
      88    if (type1##_MAX <= type2##_MAX)				\
      89      {								\
      90        if (cvt_##type1##_##type2 (type1##_MAX) != type1##_MAX)	\
      91  	abort ();						\
      92        volatile type2 tem = ((type2) 0.75f) + type1##_MAX;	\
      93        volatile type2 tem2 = ((type2) 1.0f) + type1##_MAX;	\
      94        if (tem < tem2						\
      95  	  && cvt_##type1##_##type2 ((type2) 0.75f + type1##_MAX)\
      96  	     != type1##_MAX) abort ();				\
      97      }								\
      98    else								\
      99      {								\
     100        type2 max = type1##_MAX;					\
     101        /* tem could be above maximum here due to rounding.  */	\
     102        MAXT sub = 1;						\
     103        while (sub)						\
     104  	{							\
     105  	  volatile type2 tem = type1##_MAX - sub;		\
     106  	  if (tem != max)					\
     107  	    break;						\
     108  	  MAXT newsub = sub * type2##_RADIX;			\
     109  	  if (newsub < sub || newsub > type1##_MAX)		\
     110  	    sub = 0;						\
     111  	  else							\
     112  	    sub = newsub;					\
     113  	}							\
     114        if (sub)							\
     115  	{							\
     116  	  MAXT newsub = ((type1##_MAX - sub) % sub);		\
     117  	  volatile type2 tem = type1##_MAX - newsub;		\
     118  	  volatile type2 tem2 = type1##_MAX - sub;		\
     119  	  if (tem == tem2)					\
     120  	    sub = newsub;					\
     121  	  else							\
     122  	    {							\
     123  	      newsub += sub;					\
     124  	      if (newsub < sub || newsub > type1##_MAX)		\
     125  		sub = 0;					\
     126  	      else						\
     127  		{						\
     128  		  tem = type1##_MAX - newsub;			\
     129  		  if (tem == tem2)				\
     130  		    sub = newsub;				\
     131  		  else						\
     132  		    sub = 0;					\
     133  		}						\
     134  	    }							\
     135  	}							\
     136        if (sub							\
     137  	  && cvt_##type1##_##type2 (type1##_MAX - sub)		\
     138  	     != type1##_MAX - sub) abort ();			\
     139      }
     140  
     141  
     142  #ifdef si128_MAX
     143  # define TESTS128(type2) TEST (si128, type2) TEST (ui128, type2)
     144  #else
     145  # define TESTS128(type2)
     146  #endif
     147  
     148  #define TESTS(type2) \
     149    TEST (sc, type2) TEST (c, type2) TEST (uc, type2)	\
     150    TEST (ss, type2) TEST (us, type2)			\
     151    TEST (si, type2) TEST (ui, type2)			\
     152    TEST (sl, type2) TEST (ul, type2)			\
     153    TEST (sll, type2) TEST (ull, type2)			\
     154    TESTS128 (type2)
     155  
     156  int
     157  main ()
     158  {
     159  #ifdef f_MAX
     160    TESTS (f)
     161  #endif
     162  #ifdef d_MAX
     163    TESTS (d)
     164  #endif
     165  #ifdef ld_MAX
     166    TESTS (ld)
     167  #endif
     168  #ifdef f80_MAX
     169    TESTS (f80)
     170  #endif
     171  #ifdef f128_MAX
     172    TESTS (f128)
     173  #endif
     174  #ifdef BROKEN_DECIMAL_INT128
     175  # undef TESTS128
     176  # define TESTS128(type2)
     177  # undef TWO
     178  # undef M1U
     179  # undef MAXS
     180  # undef MAXT
     181  # define TWO 2ULL
     182  # define M1U -1ULL
     183  # define MAXS (__CHAR_BIT__ * __SIZEOF_LONG_LONG__)
     184  # define MAXT unsigned long long
     185  #endif
     186  #ifdef d32_MAX
     187    TESTS (d32)
     188  #endif
     189  #ifdef d64_MAX
     190    TESTS (d64)
     191  #endif
     192  #ifdef d128_MAX
     193    TESTS (d128)
     194  #endif
     195    return 0;
     196  }