1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
extern void abort (void);
/* { dg-options "-O2" } */
/* { dg-do run } */
/* { dg-require-effective-target int32plus } */
#define TYPE_MAX(type, sign) \
((!sign) ? ((1 << (sizeof (type) * 8 - 1)) - 1) : \
((1 << (sizeof (type) * 8)) - 1))
#define TYPE_MIN(type, sign) \
((!sign) ? -(1 << (sizeof (type) * 8 - 1)) : 0)
#define TEST_FN(NAME, ARG_TYPE, RET_TYPE, CAST_TYPE, VAL, VR_MIN, VR_MAX)\
__attribute__((noinline, noclone)) RET_TYPE \
NAME (ARG_TYPE arg){ \
RET_TYPE ret = VAL; \
if (arg + 1 < VR_MIN || arg + 1 > VR_MAX) return ret; \
/* Value Range of arg at this point will be [VR_min, VR_max]. */\
arg = arg + VAL; \
ret = (CAST_TYPE)arg; \
return arg; \
}
/* Signed to signed conversion with value in-range. */
TEST_FN (foo1, short, short, char, 1, TYPE_MIN (char, 0), TYPE_MAX (char, 0));
TEST_FN (foo2, short, short, char, 1, TYPE_MIN (char, 0) + 1,\
TYPE_MAX (char, 0) - 1);
/* Signed to signed conversion with value not in-range. */
TEST_FN (foo3, short, short, char, -1, TYPE_MIN (short, 0) + 1, 100);
TEST_FN (foo4, short, short, char, 1, 12, TYPE_MAX (short, 0) + 1);
/* Unsigned to unsigned conversion with value in-range. */
TEST_FN (foo5, unsigned short, unsigned short, unsigned char, 1,\
TYPE_MIN (char, 1) + 1, TYPE_MAX (char, 1) - 1);
TEST_FN (foo6, unsigned short, unsigned short, unsigned char, 1,\
TYPE_MIN (char, 1), TYPE_MAX (char, 1));
/* Unsigned to unsigned conversion with value not in-range. */
TEST_FN (foo7, unsigned short, unsigned short, unsigned char, 1,\
TYPE_MIN (short, 1) + 1, TYPE_MAX (short, 1) - 1);
TEST_FN (foo8, unsigned short, unsigned short, unsigned char, 1,\
TYPE_MIN (short, 1), TYPE_MAX (short, 1));
/* Signed to unsigned conversion with value range positive. */
TEST_FN (foo9, short, short, unsigned char, -1, 1,\
TYPE_MAX (char, 1) - 1);
TEST_FN (foo10, short, short, unsigned char, 1, 0,\
TYPE_MAX (char, 1));
/* Signed to unsigned conversion with value range negative. */
TEST_FN (foo11, short, short, unsigned char, 1,\
TYPE_MIN (char, 0) + 1, TYPE_MAX (char, 0) - 1);
TEST_FN (foo12, short, short, unsigned char, 1,\
TYPE_MIN (char, 0), TYPE_MAX (char, 0));
/* Unsigned to Signed conversion with value range in signed equiv range. */
TEST_FN (foo13, unsigned short, unsigned short, char, 1,\
TYPE_MIN (char, 1) + 1, TYPE_MAX (char, 0) - 1);
TEST_FN (foo14, unsigned short, unsigned short, char, 1,\
TYPE_MIN (char, 1), TYPE_MAX (char, 0));
/* Unsigned to Signed conversion with value range not-in signed range. */
TEST_FN (foo15, unsigned short, unsigned short, char, 1,\
TYPE_MIN (char, 1) + 1, TYPE_MAX (char, 1) - 1);
TEST_FN (foo16, unsigned short, unsigned short, char, 1,\
TYPE_MIN (char, 1), TYPE_MAX (char, 1));
int main ()
{
/* Signed to signed conversion with value in-range. */
/* arg + 1. */
if (foo1 (-32) != -31)
abort ();
/* arg + 1. */
if (foo2 (32) != 33)
abort ();
/* Signed to signed conversion with value not in-range. */
/* arg - 1. */
if (foo3 (-512) != -513)
abort ();
/* arg + 1. */
if (foo4 (512) != 513)
abort ();
/* Unsigned to unsigned conversion with value in-range. */
/* arg + 1. */
if (foo5 (64) != 65)
abort ();
/* arg + 1. */
if (foo6 (64) != 65)
abort ();
/* Unsigned to unsigned conversion with value not in-range. */
/* arg + 1. */
if (foo7 (512) != 513)
abort ();
/* arg + 1. */
if (foo8 (512) != 513)
abort ();
/* Signed to unsigned conversion with value range positive. */
/* arg - 1. */
if (foo9 (2) != 1)
abort ();
/* arg + 1. */
if (foo10 (2) != 3)
abort ();
/* Signed to unsigned conversion with value range negative. */
/* arg + 1. */
if (foo11 (-125) != -124)
abort ();
/* arg + 1. */
if (foo12 (-125) != -124)
abort ();
/* Unsigned to Signed conversion with value range in signed equiv range. */
/* arg + 1. */
if (foo13 (125) != 126)
abort ();
/* arg + 1. */
if (foo14 (125) != 126)
abort ();
/* Unsigned to Signed conversion with value range not-in signed range. */
/* arg + 1. */
if (foo15 (250) != 251)
abort ();
/* arg + 1. */
if (foo16 (250) != 251)
abort ();
return 0;
}
|