1 /* PR 71831 - __builtin_object_size poor results with no optimization
2 Verify that even without optimization __builtin_object_size returns
3 a meaningful result for a subset of simple expressins. In cases
4 where the result could not easily be made to match the one obtained
5 with optimization the built-in was made to fail instead. */
7 /* { dg-options "-O0" } */
11 #define TEST_FAILURE(line, obj, type, expect, result) \
12 __builtin_printf ("FAIL: line %i: __builtin_object_size(" \
13 #obj ", %i) == %zu, got %zu\n", \
14 line, type, expect, result), ++nfails
16 #define bos(obj, type) __builtin_object_size (obj, type)
17 #define size(obj, n) ((size_t)n == X ? sizeof *obj : (size_t)n)
19 #define test(expect, type, obj) \
21 if (bos (obj, type) != size (obj, expect)) \
22 TEST_FAILURE (__LINE__, obj, type, size (obj, expect), bos (obj, type)); \
25 #define T(r0, r1, r2, r3, obj) \
33 /* For convenience. Substitute for 'sizeof object' in test cases where
34 the size can vary from target to target. */
35 #define X (size_t)0xdeadbeef
37 /* __builtin_object_size checking results are inconsistent for equivalent
38 expressions (see bug 71831). To avoid having duplicate the inconsistency
39 at -O0 the built-in simply fails. The results hardcoded in this test
40 are those obtained with optimization (for easy comparison) but without
41 optimization the macros below turn them into expected failures . */
54 typedef __SIZE_TYPE__
size_t;
57 char ax2
[]; /* { dg-warning "assumed to have one element" } */
64 #if __SIZEOF_SHORT__ == 4
68 #elif __SIZEOF_INT__ == 4
72 #elif __SIZEOF_LONG__ == 4
78 static char a2x2
[2][2];
79 static char a3x5
[3][5];
81 struct Sx
{ char n
, a
[]; } sx
;
82 struct S0
{ char n
, a
[0]; } s0
;
83 struct S1
{ char n
, a
[1]; } s1
;
84 struct S2
{ char n
, a
[2]; } s2
;
85 struct S9
{ char n
, a
[9]; } s9
;
87 struct S2x2
{ char n
, a
[2][2]; } s2x2
;
88 struct S3x5
{ char n
, a
[3][5]; } s3x5
;
90 static __attribute__ ((noclone
, noinline
)) void
93 T ( -1, -1, 0, 0, ax
);
103 T ( 1, 1, 1, 1, ax2
);
105 T ( 0, 0, 0, 0, ia0
);
106 T ( 4, 4, 4, 4, ia1
);
107 T ( 36, 36, 36, 36, ia9
);
109 /* Not all results for multidimensional arrays make sense (see
110 bug 77293). The expected results below simply reflect those
111 obtained at -O2 (modulo the known limitations at -O1). */
112 T ( 4, 4, 4, 4, a2x2
);
113 T ( 4, 4, 4, 4, &a2x2
[0]);
114 T ( 4, 2, 4, 2, &a2x2
[0][0]);
115 T ( 0, F1 (0), 0, 0, &a2x2
+ 1);
116 T ( 2, F1 ( 2), 2, F3 ( 2), &a2x2
[0] + 1);
117 T ( 3, F1 ( 1), 3, F3 ( 3), &a2x2
[0][0] + 1);
119 T ( 15, 15, 15, 15, a3x5
);
120 T ( 15, 5, 15, 5, &a3x5
[0][0] + 0);
121 T ( 14, F1 ( 4), 14, F3 (14), &a3x5
[0][0] + 1);
123 T ( 1, 1, 1, 1, a1
+ 0);
124 T ( 0, F1 (0), 0, 0, a1
+ 1);
125 T ( 0, F1 ( 0), 0, 0, &a1
+ 1);
126 /* In the following the offset is out of bounds which makes
127 the expression undefined. Still, verify that the returned
128 size is zero (and not some large number). */
129 T ( 0, F1 (0), 0, 0, a1
+ 2);
131 T ( 2, 2, 2, 2, a2
+ 0);
132 T ( 1, F1 ( 1), 1, F3 ( 1), a2
+ 1);
133 T ( 0, F1 ( 0), 0, 0, a2
+ 2);
136 static __attribute__ ((noclone
, noinline
)) void
137 test_structs (struct Sx
*psx
, struct S0
*ps0
, struct S1
*ps1
, struct S9
*ps9
)
139 /* The expected size of a declared object with a flexible array member
140 is sizeof sx in all __builtin_object_size types. */
141 T ( X
, X
, X
, X
, &sx
);
143 /* The expected size of an unknown object with a flexible array member
144 is unknown in all __builtin_object_size types. */
145 T ( -1, -1, 0, 0, psx
);
147 /* The expected size of a flexible array member of a declared object
149 T ( 0, 0, 0, 0, sx
.a
);
151 /* The expected size of a flexible array member of an unknown object
153 T ( -1, -1, 0, 0, psx
->a
);
155 /* The expected size of a declared object with a zero-length array member
156 is sizeof sx in all __builtin_object_size types. */
157 T ( X
, X
, X
, X
, &s0
);
159 /* The expected size of an unknown object with a zero-length array member
160 is unknown in all __builtin_object_size types. */
161 T ( -1, -1, 0, 0, ps0
);
163 /* The expected size of a zero-length array member of a declared object
165 T ( 0, 0, 0, 0, s0
.a
);
167 /* The expected size of a zero-length array member of an unknown object
169 T ( -1, -1, 0, 0, ps0
->a
);
171 T ( X
, X
, X
, X
, &s1
);
172 T ( 1, 1, 1, 1, s1
.a
);
173 T ( 0, F1 (0), 0, 0, s1
.a
+ 1);
175 /* GCC treats arrays of all sizes that are the last member of a struct
176 as flexible array members. */
177 T ( -1, -1, 0, 0, ps1
);
178 T ( -1, -1, 0, 0, ps1
->a
);
179 T ( -1, -1, 0, 0, ps1
->a
+ 1);
181 T ( X
, X
, X
, X
, &s9
);
182 T ( 9, 9, 9, 9, s9
.a
);
183 T ( 9, 9, 9, 9, s9
.a
+ 0);
184 T ( 8, F1 ( 8), 8, F3 ( 8), s9
.a
+ 1);
185 T ( 7, F1 ( 7), 7, F3 ( 7), s9
.a
+ 2);
186 T ( 0, F1 ( 0), 0, F3 ( 0), s9
.a
+ 9);
188 /* The following make little sense but see bug 77301. */
189 T ( -1, -1, 0, 0, ps9
);
190 T ( -1, -1, 0, 0, ps9
->a
);
191 T ( -1, -1, 0, 0, ps9
->a
+ 1);
199 test_structs (&sx
, &s0
, &s1
, &s9
);