111
|
1 /* PR 71831 - __builtin_object_size poor results with no optimization
|
|
2 Verify that even without optimization __builtin_object_size result
|
|
3 is folded into a constant and dead code that depends on it is
|
|
4 eliminated. */
|
|
5 /* { dg-do compile } */
|
|
6 /* { dg-options "-O0 -fdump-tree-ssa" } */
|
|
7
|
|
8 #define concat(a, b) a ## b
|
|
9 #define CAT(a, b) concat (a, b)
|
|
10
|
|
11 /* Create a symbol name unique to each tes and object size type. */
|
|
12 #define SYM(type) CAT (CAT (CAT (failure_on_line_, __LINE__), _type_), type)
|
|
13
|
|
14 /* References to the following undefined symbol which is unique for each
|
|
15 test case are expected to be eliminated. */
|
|
16 #define TEST_FAILURE(type) \
|
|
17 do { \
|
|
18 extern void SYM (type)(void); \
|
|
19 SYM (type)(); \
|
|
20 } while (0)
|
|
21
|
|
22 #define bos(obj, type) __builtin_object_size (obj, type)
|
|
23 #define size(obj, n) ((size_t)n == X ? sizeof *obj : (size_t)n)
|
|
24
|
|
25 #define test(expect, type, obj) \
|
|
26 do { \
|
|
27 if (bos (obj, type) != size (obj, expect)) \
|
|
28 TEST_FAILURE (type); \
|
|
29 } while (0)
|
|
30
|
|
31 #define FOLD_ALL(r0, r1, r2, r3, obj) \
|
|
32 do { \
|
|
33 test (r0, 0, obj); \
|
|
34 test (r1, 1, obj); \
|
|
35 test (r2, 2, obj); \
|
|
36 test (r3, 3, obj); \
|
|
37 } while (0)
|
|
38
|
|
39 #define FOLD_0_2(r0, r1, r2, r3, obj) \
|
|
40 do { \
|
|
41 test (r0, 0, obj); \
|
|
42 test (r2, 2, obj); \
|
|
43 } while (0)
|
|
44
|
|
45 /* For convenience. Substitute for 'sizeof object' in test cases where
|
|
46 the size can vary from target to target. */
|
|
47 #define X (size_t)0xdeadbeef
|
|
48
|
|
49 typedef __SIZE_TYPE__ size_t;
|
|
50
|
|
51 extern char ax[];
|
|
52 char ax2[]; /* { dg-warning "assumed to have one element" } */
|
|
53
|
|
54 extern char a0[0];
|
|
55 static char a1[1];
|
|
56 static char a2[2];
|
|
57 static char a9[9];
|
|
58
|
|
59 #if __SIZEOF_SHORT__ == 4
|
|
60 extern short ia0[0];
|
|
61 static short ia1[1];
|
|
62 static short ia9[9];
|
|
63 #elif __SIZEOF_INT__ == 4
|
|
64 extern int ia0[0];
|
|
65 static int ia1[1];
|
|
66 static int ia9[9];
|
|
67 #elif __SIZEOF_LONG__ == 4
|
|
68 extern long ia0[0];
|
|
69 static long ia1[1];
|
|
70 static long ia9[9];
|
|
71 #endif
|
|
72
|
|
73 static char a2x2[2][2];
|
|
74 static char a3x5[3][5];
|
|
75
|
|
76 struct Sx { char n, a[]; } sx;
|
|
77 struct S0 { char n, a[0]; } s0;
|
|
78 struct S1 { char n, a[1]; } s1;
|
|
79 struct S2 { char n, a[2]; } s2;
|
|
80 struct S9 { char n, a[9]; } s9;
|
|
81
|
|
82 struct S2x2 { char n, a[2][2]; } s2x2;
|
|
83 struct S3x5 { char n, a[3][5]; } s3x5;
|
|
84
|
|
85 static __attribute__ ((noclone, noinline)) void
|
|
86 test_arrays ()
|
|
87 {
|
|
88 FOLD_ALL ( 1, 1, 1, 1, ax2);
|
|
89
|
|
90 FOLD_ALL ( 1, 1, 1, 1, a1);
|
|
91 FOLD_ALL ( 2, 2, 2, 2, a2);
|
|
92 FOLD_ALL ( 9, 9, 9, 9, a9);
|
|
93
|
|
94 FOLD_ALL ( 0, 0, 0, 0, a0);
|
|
95 FOLD_ALL ( 1, 1, 1, 1, ax2);
|
|
96
|
|
97 FOLD_ALL ( 0, 0, 0, 0, ia0);
|
|
98 FOLD_ALL ( 4, 4, 4, 4, ia1);
|
|
99 FOLD_ALL ( 36, 36, 36, 36, ia9);
|
|
100
|
|
101 /* Not all results for multidimensional arrays make sense (see
|
|
102 bug 77293). The expected results below simply reflect those
|
|
103 obtained at -O2 (modulo the known limitations at -O1). */
|
|
104 FOLD_ALL ( 4, 4, 4, 4, a2x2);
|
|
105 FOLD_ALL ( 4, 4, 4, 4, &a2x2[0]);
|
|
106 FOLD_ALL ( 4, 2, 4, 2, &a2x2[0][0]);
|
|
107 FOLD_0_2 ( 0, F1 (0), 0, 0, &a2x2 + 1);
|
|
108 FOLD_0_2 ( 2, F1 ( 2), 2, F3 ( 2), &a2x2[0] + 1);
|
|
109 FOLD_0_2 ( 3, F1 ( 1), 3, F3 ( 3), &a2x2[0][0] + 1);
|
|
110
|
|
111 FOLD_ALL ( 15, 15, 15, 15, a3x5);
|
|
112 FOLD_ALL ( 15, 5, 15, 5, &a3x5[0][0] + 0);
|
|
113 FOLD_0_2 ( 14, F1 ( 4), 14, F3 (14), &a3x5[0][0] + 1);
|
|
114
|
|
115 FOLD_ALL ( 1, 1, 1, 1, a1 + 0);
|
|
116 FOLD_0_2 ( 0, F1 ( 0), 0, 0, &a1 + 1);
|
|
117 FOLD_ALL ( 2, 2, 2, 2, a2 + 0);
|
|
118 FOLD_0_2 ( 1, F1 ( 1), 1, F3 ( 1), a2 + 1);
|
|
119 FOLD_0_2 ( 0, F1 ( 0), 0, 0, a2 + 2);
|
|
120 }
|
|
121
|
|
122 static __attribute__ ((noclone, noinline)) void
|
|
123 test_structs (void)
|
|
124 {
|
|
125 /* The expected size of a declared object with a flexible array member
|
|
126 is sizeof sx in all __builtin_object_size types. */
|
|
127 FOLD_ALL ( X, X, X, X, &sx);
|
|
128
|
|
129 /* The expected size of a flexible array member of a declared object
|
|
130 is zero. */
|
|
131 FOLD_ALL ( 0, 0, 0, 0, sx.a);
|
|
132
|
|
133 /* The expected size of a declared object with a zero-length array member
|
|
134 is sizeof sx in all __builtin_object_size types. */
|
|
135 FOLD_ALL ( X, X, X, X, &s0);
|
|
136
|
|
137 /* The expected size of a zero-length array member of a declared object
|
|
138 is zero. */
|
|
139 FOLD_ALL ( 0, 0, 0, 0, s0.a);
|
|
140
|
|
141 FOLD_ALL ( X, X, X, X, &s1);
|
|
142 FOLD_ALL ( 1, 1, 1, 1, s1.a);
|
|
143 FOLD_0_2 ( 0, F1 (0), 0, 0, s1.a + 1);
|
|
144
|
|
145 FOLD_ALL ( X, X, X, X, &s9);
|
|
146 FOLD_ALL ( 9, 9, 9, 9, s9.a);
|
|
147 FOLD_ALL ( 9, 9, 9, 9, s9.a + 0);
|
|
148 FOLD_0_2 ( 8, F1 ( 8), 8, F3 ( 8), s9.a + 1);
|
|
149 FOLD_0_2 ( 7, F1 ( 7), 7, F3 ( 7), s9.a + 2);
|
|
150 FOLD_0_2 ( 0, F1 ( 0), 0, F3 ( 0), s9.a + 9);
|
|
151 }
|
|
152
|
|
153 int
|
|
154 main()
|
|
155 {
|
|
156 test_arrays ();
|
|
157 test_structs ();
|
|
158
|
|
159 return 0;
|
|
160 }
|
|
161
|
|
162 /* { dg-final { scan-tree-dump-not "failure_on_line" "ssa" } } */
|