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" } } */
|