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 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
/* PR 71831 - __builtin_object_size poor results with no optimization
Verify that even without optimization __builtin_object_size result
is folded into a constant and dead code that depends on it is
eliminated. */
/* { dg-do compile } */
/* { dg-options "-O0 -fdump-tree-ssa" } */
#define concat(a, b) a ## b
#define CAT(a, b) concat (a, b)
/* Create a symbol name unique to each tes and object size type. */
#define SYM(type) CAT (CAT (CAT (failure_on_line_, __LINE__), _type_), type)
/* References to the following undefined symbol which is unique for each
test case are expected to be eliminated. */
#define TEST_FAILURE(type) \
do { \
extern void SYM (type)(void); \
SYM (type)(); \
} while (0)
#define bos(obj, type) __builtin_object_size (obj, type)
#define size(obj, n) ((size_t)n == X ? sizeof *obj : (size_t)n)
#define test(expect, type, obj) \
do { \
if (bos (obj, type) != size (obj, expect)) \
TEST_FAILURE (type); \
} while (0)
#define FOLD_ALL(r0, r1, r2, r3, obj) \
do { \
test (r0, 0, obj); \
test (r1, 1, obj); \
test (r2, 2, obj); \
test (r3, 3, obj); \
} while (0)
#define FOLD_0_2(r0, r1, r2, r3, obj) \
do { \
test (r0, 0, obj); \
test (r2, 2, obj); \
} while (0)
/* For convenience. Substitute for 'sizeof object' in test cases where
the size can vary from target to target. */
#define X (size_t)0xdeadbeef
typedef __SIZE_TYPE__ size_t;
extern char ax[];
char ax2[]; /* { dg-warning "assumed to have one element" } */
extern char a0[0];
static char a1[1];
static char a2[2];
static char a9[9];
#if __SIZEOF_SHORT__ == 4
extern short ia0[0];
static short ia1[1];
static short ia9[9];
#elif __SIZEOF_INT__ == 4
extern int ia0[0];
static int ia1[1];
static int ia9[9];
#elif __SIZEOF_LONG__ == 4
extern long ia0[0];
static long ia1[1];
static long ia9[9];
#endif
static char a2x2[2][2];
static char a3x5[3][5];
struct Sx { char n, a[]; } sx;
struct S0 { char n, a[0]; } s0;
struct S1 { char n, a[1]; } s1;
struct S2 { char n, a[2]; } s2;
struct S9 { char n, a[9]; } s9;
struct S2x2 { char n, a[2][2]; } s2x2;
struct S3x5 { char n, a[3][5]; } s3x5;
static __attribute__ ((noclone, noinline)) void
test_arrays ()
{
FOLD_ALL ( 1, 1, 1, 1, ax2);
FOLD_ALL ( 1, 1, 1, 1, a1);
FOLD_ALL ( 2, 2, 2, 2, a2);
FOLD_ALL ( 9, 9, 9, 9, a9);
FOLD_ALL ( 0, 0, 0, 0, a0);
FOLD_ALL ( 1, 1, 1, 1, ax2);
FOLD_ALL ( 0, 0, 0, 0, ia0);
FOLD_ALL ( 4, 4, 4, 4, ia1);
FOLD_ALL ( 36, 36, 36, 36, ia9);
/* Not all results for multidimensional arrays make sense (see
bug 77293). The expected results below simply reflect those
obtained at -O2 (modulo the known limitations at -O1). */
FOLD_ALL ( 4, 4, 4, 4, a2x2);
FOLD_ALL ( 4, 4, 4, 4, &a2x2[0]);
FOLD_ALL ( 4, 2, 4, 2, &a2x2[0][0]);
FOLD_0_2 ( 0, F1 (0), 0, 0, &a2x2 + 1);
FOLD_0_2 ( 2, F1 ( 2), 2, F3 ( 2), &a2x2[0] + 1);
FOLD_0_2 ( 3, F1 ( 1), 3, F3 ( 3), &a2x2[0][0] + 1);
FOLD_ALL ( 15, 15, 15, 15, a3x5);
FOLD_ALL ( 15, 5, 15, 5, &a3x5[0][0] + 0);
FOLD_0_2 ( 14, F1 ( 4), 14, F3 (14), &a3x5[0][0] + 1);
FOLD_ALL ( 1, 1, 1, 1, a1 + 0);
FOLD_0_2 ( 0, F1 ( 0), 0, 0, &a1 + 1);
FOLD_ALL ( 2, 2, 2, 2, a2 + 0);
FOLD_0_2 ( 1, F1 ( 1), 1, F3 ( 1), a2 + 1);
FOLD_0_2 ( 0, F1 ( 0), 0, 0, a2 + 2);
}
static __attribute__ ((noclone, noinline)) void
test_structs (void)
{
/* The expected size of a declared object with a flexible array member
is sizeof sx in all __builtin_object_size types. */
FOLD_ALL ( X, X, X, X, &sx);
/* The expected size of a flexible array member of a declared object
is zero. */
FOLD_ALL ( 0, 0, 0, 0, sx.a);
/* The expected size of a declared object with a zero-length array member
is sizeof sx in all __builtin_object_size types. */
FOLD_ALL ( X, X, X, X, &s0);
/* The expected size of a zero-length array member of a declared object
is zero. */
FOLD_ALL ( 0, 0, 0, 0, s0.a);
FOLD_ALL ( X, X, X, X, &s1);
FOLD_ALL ( 1, 1, 1, 1, s1.a);
FOLD_0_2 ( 0, F1 (0), 0, 0, s1.a + 1);
FOLD_ALL ( X, X, X, X, &s9);
FOLD_ALL ( 9, 9, 9, 9, s9.a);
FOLD_ALL ( 9, 9, 9, 9, s9.a + 0);
FOLD_0_2 ( 8, F1 ( 8), 8, F3 ( 8), s9.a + 1);
FOLD_0_2 ( 7, F1 ( 7), 7, F3 ( 7), s9.a + 2);
FOLD_0_2 ( 0, F1 ( 0), 0, F3 ( 0), s9.a + 9);
}
int
main()
{
test_arrays ();
test_structs ();
return 0;
}
/* { dg-final { scan-tree-dump-not "failure_on_line" "ssa" } } */
|