File: | build/gcc/c-family/c-attribs.cc |
Warning: | line 4926, column 5 Value stored to 'n' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* C-family attributes handling. |
2 | Copyright (C) 1992-2023 Free Software Foundation, Inc. |
3 | |
4 | This file is part of GCC. |
5 | |
6 | GCC is free software; you can redistribute it and/or modify it under |
7 | the terms of the GNU General Public License as published by the Free |
8 | Software Foundation; either version 3, or (at your option) any later |
9 | version. |
10 | |
11 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
12 | WARRANTY; without even the implied warranty of MERCHANTABILITY or |
13 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
14 | for more details. |
15 | |
16 | You should have received a copy of the GNU General Public License |
17 | along with GCC; see the file COPYING3. If not see |
18 | <http://www.gnu.org/licenses/>. */ |
19 | |
20 | #define INCLUDE_STRING |
21 | #include "config.h" |
22 | #include "system.h" |
23 | #include "coretypes.h" |
24 | #include "target.h" |
25 | #include "function.h" |
26 | #include "tree.h" |
27 | #include "memmodel.h" |
28 | #include "c-common.h" |
29 | #include "gimple-expr.h" |
30 | #include "tm_p.h" |
31 | #include "stringpool.h" |
32 | #include "cgraph.h" |
33 | #include "diagnostic.h" |
34 | #include "intl.h" |
35 | #include "stor-layout.h" |
36 | #include "calls.h" |
37 | #include "attribs.h" |
38 | #include "varasm.h" |
39 | #include "trans-mem.h" |
40 | #include "c-objc.h" |
41 | #include "common/common-target.h" |
42 | #include "langhooks.h" |
43 | #include "tree-inline.h" |
44 | #include "toplev.h" |
45 | #include "tree-iterator.h" |
46 | #include "opts.h" |
47 | #include "gimplify.h" |
48 | #include "tree-pretty-print.h" |
49 | #include "gcc-rich-location.h" |
50 | |
51 | static tree handle_packed_attribute (tree *, tree, tree, int, bool *); |
52 | static tree handle_nocommon_attribute (tree *, tree, tree, int, bool *); |
53 | static tree handle_common_attribute (tree *, tree, tree, int, bool *); |
54 | static tree handle_hot_attribute (tree *, tree, tree, int, bool *); |
55 | static tree handle_cold_attribute (tree *, tree, tree, int, bool *); |
56 | static tree handle_no_sanitize_attribute (tree *, tree, tree, int, bool *); |
57 | static tree handle_no_sanitize_address_attribute (tree *, tree, tree, |
58 | int, bool *); |
59 | static tree handle_no_sanitize_thread_attribute (tree *, tree, tree, |
60 | int, bool *); |
61 | static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree, |
62 | int, bool *); |
63 | static tree handle_no_sanitize_undefined_attribute (tree *, tree, tree, int, |
64 | bool *); |
65 | static tree handle_no_sanitize_coverage_attribute (tree *, tree, tree, int, |
66 | bool *); |
67 | static tree handle_asan_odr_indicator_attribute (tree *, tree, tree, int, |
68 | bool *); |
69 | static tree handle_stack_protect_attribute (tree *, tree, tree, int, bool *); |
70 | static tree handle_no_stack_protector_function_attribute (tree *, tree, |
71 | tree, int, bool *); |
72 | static tree handle_noinline_attribute (tree *, tree, tree, int, bool *); |
73 | static tree handle_noclone_attribute (tree *, tree, tree, int, bool *); |
74 | static tree handle_nocf_check_attribute (tree *, tree, tree, int, bool *); |
75 | static tree handle_symver_attribute (tree *, tree, tree, int, bool *); |
76 | static tree handle_noicf_attribute (tree *, tree, tree, int, bool *); |
77 | static tree handle_noipa_attribute (tree *, tree, tree, int, bool *); |
78 | static tree handle_leaf_attribute (tree *, tree, tree, int, bool *); |
79 | static tree handle_always_inline_attribute (tree *, tree, tree, int, |
80 | bool *); |
81 | static tree handle_gnu_inline_attribute (tree *, tree, tree, int, bool *); |
82 | static tree handle_artificial_attribute (tree *, tree, tree, int, bool *); |
83 | static tree handle_flatten_attribute (tree *, tree, tree, int, bool *); |
84 | static tree handle_error_attribute (tree *, tree, tree, int, bool *); |
85 | static tree handle_used_attribute (tree *, tree, tree, int, bool *); |
86 | static tree handle_uninitialized_attribute (tree *, tree, tree, int, bool *); |
87 | static tree handle_externally_visible_attribute (tree *, tree, tree, int, |
88 | bool *); |
89 | static tree handle_no_reorder_attribute (tree *, tree, tree, int, |
90 | bool *); |
91 | static tree handle_const_attribute (tree *, tree, tree, int, bool *); |
92 | static tree handle_transparent_union_attribute (tree *, tree, tree, |
93 | int, bool *); |
94 | static tree handle_scalar_storage_order_attribute (tree *, tree, tree, |
95 | int, bool *); |
96 | static tree handle_constructor_attribute (tree *, tree, tree, int, bool *); |
97 | static tree handle_destructor_attribute (tree *, tree, tree, int, bool *); |
98 | static tree handle_mode_attribute (tree *, tree, tree, int, bool *); |
99 | static tree handle_section_attribute (tree *, tree, tree, int, bool *); |
100 | static tree handle_special_var_sec_attribute (tree *, tree, tree, int, bool *); |
101 | static tree handle_aligned_attribute (tree *, tree, tree, int, bool *); |
102 | static tree handle_warn_if_not_aligned_attribute (tree *, tree, tree, |
103 | int, bool *); |
104 | static tree handle_strict_flex_array_attribute (tree *, tree, tree, |
105 | int, bool *); |
106 | static tree handle_weak_attribute (tree *, tree, tree, int, bool *) ; |
107 | static tree handle_noplt_attribute (tree *, tree, tree, int, bool *) ; |
108 | static tree handle_alias_ifunc_attribute (bool, tree *, tree, tree, bool *); |
109 | static tree handle_ifunc_attribute (tree *, tree, tree, int, bool *); |
110 | static tree handle_alias_attribute (tree *, tree, tree, int, bool *); |
111 | static tree handle_weakref_attribute (tree *, tree, tree, int, bool *) ; |
112 | static tree handle_visibility_attribute (tree *, tree, tree, int, |
113 | bool *); |
114 | static tree handle_tls_model_attribute (tree *, tree, tree, int, |
115 | bool *); |
116 | static tree handle_no_instrument_function_attribute (tree *, tree, |
117 | tree, int, bool *); |
118 | static tree handle_no_profile_instrument_function_attribute (tree *, tree, |
119 | tree, int, bool *); |
120 | static tree handle_malloc_attribute (tree *, tree, tree, int, bool *); |
121 | static tree handle_dealloc_attribute (tree *, tree, tree, int, bool *); |
122 | static tree handle_tainted_args_attribute (tree *, tree, tree, int, bool *); |
123 | static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *); |
124 | static tree handle_no_limit_stack_attribute (tree *, tree, tree, int, |
125 | bool *); |
126 | static tree handle_pure_attribute (tree *, tree, tree, int, bool *); |
127 | static tree handle_tm_attribute (tree *, tree, tree, int, bool *); |
128 | static tree handle_tm_wrap_attribute (tree *, tree, tree, int, bool *); |
129 | static tree handle_novops_attribute (tree *, tree, tree, int, bool *); |
130 | static tree handle_unavailable_attribute (tree *, tree, tree, int, |
131 | bool *); |
132 | static tree handle_vector_size_attribute (tree *, tree, tree, int, |
133 | bool *) ATTRIBUTE_NONNULL(3)__attribute__ ((__nonnull__ (3))); |
134 | static tree handle_vector_mask_attribute (tree *, tree, tree, int, |
135 | bool *) ATTRIBUTE_NONNULL(3)__attribute__ ((__nonnull__ (3))); |
136 | static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *); |
137 | static tree handle_nonstring_attribute (tree *, tree, tree, int, bool *); |
138 | static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *); |
139 | static tree handle_cleanup_attribute (tree *, tree, tree, int, bool *); |
140 | static tree handle_warn_unused_result_attribute (tree *, tree, tree, int, |
141 | bool *); |
142 | static tree handle_access_attribute (tree *, tree, tree, int, bool *); |
143 | |
144 | static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *); |
145 | static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *); |
146 | static tree handle_alloc_size_attribute (tree *, tree, tree, int, bool *); |
147 | static tree handle_alloc_align_attribute (tree *, tree, tree, int, bool *); |
148 | static tree handle_assume_aligned_attribute (tree *, tree, tree, int, bool *); |
149 | static tree handle_assume_attribute (tree *, tree, tree, int, bool *); |
150 | static tree handle_target_attribute (tree *, tree, tree, int, bool *); |
151 | static tree handle_target_clones_attribute (tree *, tree, tree, int, bool *); |
152 | static tree handle_optimize_attribute (tree *, tree, tree, int, bool *); |
153 | static tree ignore_attribute (tree *, tree, tree, int, bool *); |
154 | static tree handle_no_split_stack_attribute (tree *, tree, tree, int, bool *); |
155 | static tree handle_zero_call_used_regs_attribute (tree *, tree, tree, int, |
156 | bool *); |
157 | static tree handle_argspec_attribute (tree *, tree, tree, int, bool *); |
158 | static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *); |
159 | static tree handle_warn_unused_attribute (tree *, tree, tree, int, bool *); |
160 | static tree handle_returns_nonnull_attribute (tree *, tree, tree, int, bool *); |
161 | static tree handle_omp_declare_simd_attribute (tree *, tree, tree, int, |
162 | bool *); |
163 | static tree handle_omp_declare_variant_attribute (tree *, tree, tree, int, |
164 | bool *); |
165 | static tree handle_simd_attribute (tree *, tree, tree, int, bool *); |
166 | static tree handle_omp_declare_target_attribute (tree *, tree, tree, int, |
167 | bool *); |
168 | static tree handle_non_overlapping_attribute (tree *, tree, tree, int, bool *); |
169 | static tree handle_designated_init_attribute (tree *, tree, tree, int, bool *); |
170 | static tree handle_patchable_function_entry_attribute (tree *, tree, tree, |
171 | int, bool *); |
172 | static tree handle_copy_attribute (tree *, tree, tree, int, bool *); |
173 | static tree handle_nsobject_attribute (tree *, tree, tree, int, bool *); |
174 | static tree handle_objc_root_class_attribute (tree *, tree, tree, int, bool *); |
175 | static tree handle_objc_nullability_attribute (tree *, tree, tree, int, bool *); |
176 | static tree handle_signed_bool_precision_attribute (tree *, tree, tree, int, |
177 | bool *); |
178 | static tree handle_retain_attribute (tree *, tree, tree, int, bool *); |
179 | static tree handle_fd_arg_attribute (tree *, tree, tree, int, bool *); |
180 | |
181 | /* Helper to define attribute exclusions. */ |
182 | #define ATTR_EXCL(name, function, type, variable){ name, function, type, variable } \ |
183 | { name, function, type, variable } |
184 | |
185 | /* Define attributes that are mutually exclusive with one another. */ |
186 | static const struct attribute_spec::exclusions attr_aligned_exclusions[] = |
187 | { |
188 | /* Attribute name exclusion applies to: |
189 | function, type, variable */ |
190 | ATTR_EXCL ("aligned", true, false, false){ "aligned", true, false, false }, |
191 | ATTR_EXCL ("packed", true, false, false){ "packed", true, false, false }, |
192 | ATTR_EXCL (NULL, false, false, false){ nullptr, false, false, false } |
193 | }; |
194 | |
195 | extern const struct attribute_spec::exclusions attr_cold_hot_exclusions[] = |
196 | { |
197 | ATTR_EXCL ("cold", true, true, true){ "cold", true, true, true }, |
198 | ATTR_EXCL ("hot", true, true, true){ "hot", true, true, true }, |
199 | ATTR_EXCL (NULL, false, false, false){ nullptr, false, false, false } |
200 | }; |
201 | |
202 | static const struct attribute_spec::exclusions attr_common_exclusions[] = |
203 | { |
204 | ATTR_EXCL ("common", true, true, true){ "common", true, true, true }, |
205 | ATTR_EXCL ("nocommon", true, true, true){ "nocommon", true, true, true }, |
206 | ATTR_EXCL (NULL, false, false, false){ nullptr, false, false, false }, |
207 | }; |
208 | |
209 | static const struct attribute_spec::exclusions attr_inline_exclusions[] = |
210 | { |
211 | ATTR_EXCL ("noinline", true, true, true){ "noinline", true, true, true }, |
212 | ATTR_EXCL (NULL, false, false, false){ nullptr, false, false, false }, |
213 | }; |
214 | |
215 | static const struct attribute_spec::exclusions attr_noinline_exclusions[] = |
216 | { |
217 | ATTR_EXCL ("always_inline", true, true, true){ "always_inline", true, true, true }, |
218 | ATTR_EXCL ("gnu_inline", true, true, true){ "gnu_inline", true, true, true }, |
219 | ATTR_EXCL (NULL, false, false, false){ nullptr, false, false, false }, |
220 | }; |
221 | |
222 | extern const struct attribute_spec::exclusions attr_noreturn_exclusions[] = |
223 | { |
224 | ATTR_EXCL ("alloc_align", true, true, true){ "alloc_align", true, true, true }, |
225 | ATTR_EXCL ("alloc_size", true, true, true){ "alloc_size", true, true, true }, |
226 | ATTR_EXCL ("const", true, true, true){ "const", true, true, true }, |
227 | ATTR_EXCL ("malloc", true, true, true){ "malloc", true, true, true }, |
228 | ATTR_EXCL ("pure", true, true, true){ "pure", true, true, true }, |
229 | ATTR_EXCL ("returns_twice", true, true, true){ "returns_twice", true, true, true }, |
230 | ATTR_EXCL ("warn_unused_result", true, true, true){ "warn_unused_result", true, true, true }, |
231 | ATTR_EXCL (NULL, false, false, false){ nullptr, false, false, false }, |
232 | }; |
233 | |
234 | static const struct attribute_spec::exclusions |
235 | attr_warn_unused_result_exclusions[] = |
236 | { |
237 | ATTR_EXCL ("noreturn", true, true, true){ "noreturn", true, true, true }, |
238 | ATTR_EXCL ("warn_unused_result", true, true, true){ "warn_unused_result", true, true, true }, |
239 | ATTR_EXCL (NULL, false, false, false){ nullptr, false, false, false }, |
240 | }; |
241 | |
242 | static const struct attribute_spec::exclusions attr_returns_twice_exclusions[] = |
243 | { |
244 | ATTR_EXCL ("noreturn", true, true, true){ "noreturn", true, true, true }, |
245 | ATTR_EXCL (NULL, false, false, false){ nullptr, false, false, false }, |
246 | }; |
247 | |
248 | /* Exclusions that apply to attribute alloc_align, alloc_size, and malloc. */ |
249 | static const struct attribute_spec::exclusions attr_alloc_exclusions[] = |
250 | { |
251 | ATTR_EXCL ("const", true, true, true){ "const", true, true, true }, |
252 | ATTR_EXCL ("noreturn", true, true, true){ "noreturn", true, true, true }, |
253 | ATTR_EXCL ("pure", true, true, true){ "pure", true, true, true }, |
254 | ATTR_EXCL (NULL, false, false, false){ nullptr, false, false, false }, |
255 | }; |
256 | |
257 | static const struct attribute_spec::exclusions attr_const_pure_exclusions[] = |
258 | { |
259 | ATTR_EXCL ("const", true, true, true){ "const", true, true, true }, |
260 | ATTR_EXCL ("alloc_align", true, true, true){ "alloc_align", true, true, true }, |
261 | ATTR_EXCL ("alloc_size", true, true, true){ "alloc_size", true, true, true }, |
262 | ATTR_EXCL ("malloc", true, true, true){ "malloc", true, true, true }, |
263 | ATTR_EXCL ("noreturn", true, true, true){ "noreturn", true, true, true }, |
264 | ATTR_EXCL ("pure", true, true, true){ "pure", true, true, true }, |
265 | ATTR_EXCL (NULL, false, false, false){ nullptr, false, false, false } |
266 | }; |
267 | |
268 | /* Exclusions that apply to attributes that put declarations in specific |
269 | sections. */ |
270 | static const struct attribute_spec::exclusions attr_section_exclusions[] = |
271 | { |
272 | ATTR_EXCL ("noinit", true, true, true){ "noinit", true, true, true }, |
273 | ATTR_EXCL ("persistent", true, true, true){ "persistent", true, true, true }, |
274 | ATTR_EXCL ("section", true, true, true){ "section", true, true, true }, |
275 | ATTR_EXCL (NULL, false, false, false){ nullptr, false, false, false }, |
276 | }; |
277 | |
278 | static const struct attribute_spec::exclusions attr_stack_protect_exclusions[] = |
279 | { |
280 | ATTR_EXCL ("stack_protect", true, false, false){ "stack_protect", true, false, false }, |
281 | ATTR_EXCL ("no_stack_protector", true, false, false){ "no_stack_protector", true, false, false }, |
282 | ATTR_EXCL (NULL, false, false, false){ nullptr, false, false, false }, |
283 | }; |
284 | |
285 | |
286 | /* Table of machine-independent attributes common to all C-like languages. |
287 | |
288 | Current list of processed common attributes: nonnull. */ |
289 | const struct attribute_spec c_common_attribute_table[] = |
290 | { |
291 | /* { name, min_len, max_len, decl_req, type_req, fn_type_req, |
292 | affects_type_identity, handler, exclude } */ |
293 | { "signed_bool_precision", 1, 1, false, true, false, true, |
294 | handle_signed_bool_precision_attribute, NULLnullptr }, |
295 | { "packed", 0, 0, false, false, false, false, |
296 | handle_packed_attribute, |
297 | attr_aligned_exclusions }, |
298 | { "nocommon", 0, 0, true, false, false, false, |
299 | handle_nocommon_attribute, |
300 | attr_common_exclusions }, |
301 | { "common", 0, 0, true, false, false, false, |
302 | handle_common_attribute, |
303 | attr_common_exclusions }, |
304 | /* FIXME: logically, noreturn attributes should be listed as |
305 | "false, true, true" and apply to function types. But implementing this |
306 | would require all the places in the compiler that use TREE_THIS_VOLATILE |
307 | on a decl to identify non-returning functions to be located and fixed |
308 | to check the function type instead. */ |
309 | { "noreturn", 0, 0, true, false, false, false, |
310 | handle_noreturn_attribute, |
311 | attr_noreturn_exclusions }, |
312 | { "volatile", 0, 0, true, false, false, false, |
313 | handle_noreturn_attribute, NULLnullptr }, |
314 | { "stack_protect", 0, 0, true, false, false, false, |
315 | handle_stack_protect_attribute, |
316 | attr_stack_protect_exclusions }, |
317 | { "no_stack_protector", 0, 0, true, false, false, false, |
318 | handle_no_stack_protector_function_attribute, |
319 | attr_stack_protect_exclusions }, |
320 | { "noinline", 0, 0, true, false, false, false, |
321 | handle_noinline_attribute, |
322 | attr_noinline_exclusions }, |
323 | { "noclone", 0, 0, true, false, false, false, |
324 | handle_noclone_attribute, NULLnullptr }, |
325 | { "no_icf", 0, 0, true, false, false, false, |
326 | handle_noicf_attribute, NULLnullptr }, |
327 | { "noipa", 0, 0, true, false, false, false, |
328 | handle_noipa_attribute, NULLnullptr }, |
329 | { "leaf", 0, 0, true, false, false, false, |
330 | handle_leaf_attribute, NULLnullptr }, |
331 | { "always_inline", 0, 0, true, false, false, false, |
332 | handle_always_inline_attribute, |
333 | attr_inline_exclusions }, |
334 | { "gnu_inline", 0, 0, true, false, false, false, |
335 | handle_gnu_inline_attribute, |
336 | attr_inline_exclusions }, |
337 | { "artificial", 0, 0, true, false, false, false, |
338 | handle_artificial_attribute, NULLnullptr }, |
339 | { "flatten", 0, 0, true, false, false, false, |
340 | handle_flatten_attribute, NULLnullptr }, |
341 | { "used", 0, 0, true, false, false, false, |
342 | handle_used_attribute, NULLnullptr }, |
343 | { "unused", 0, 0, false, false, false, false, |
344 | handle_unused_attribute, NULLnullptr }, |
345 | { "uninitialized", 0, 0, true, false, false, false, |
346 | handle_uninitialized_attribute, NULLnullptr }, |
347 | { "retain", 0, 0, true, false, false, false, |
348 | handle_retain_attribute, NULLnullptr }, |
349 | { "externally_visible", 0, 0, true, false, false, false, |
350 | handle_externally_visible_attribute, NULLnullptr }, |
351 | { "no_reorder", 0, 0, true, false, false, false, |
352 | handle_no_reorder_attribute, NULLnullptr }, |
353 | /* The same comments as for noreturn attributes apply to const ones. */ |
354 | { "const", 0, 0, true, false, false, false, |
355 | handle_const_attribute, |
356 | attr_const_pure_exclusions }, |
357 | { "scalar_storage_order", 1, 1, false, false, false, false, |
358 | handle_scalar_storage_order_attribute, NULLnullptr }, |
359 | { "transparent_union", 0, 0, false, false, false, false, |
360 | handle_transparent_union_attribute, NULLnullptr }, |
361 | { "constructor", 0, 1, true, false, false, false, |
362 | handle_constructor_attribute, NULLnullptr }, |
363 | { "destructor", 0, 1, true, false, false, false, |
364 | handle_destructor_attribute, NULLnullptr }, |
365 | { "mode", 1, 1, false, true, false, false, |
366 | handle_mode_attribute, NULLnullptr }, |
367 | { "section", 1, 1, true, false, false, false, |
368 | handle_section_attribute, attr_section_exclusions }, |
369 | { "aligned", 0, 1, false, false, false, false, |
370 | handle_aligned_attribute, |
371 | attr_aligned_exclusions }, |
372 | { "warn_if_not_aligned", 0, 1, false, false, false, false, |
373 | handle_warn_if_not_aligned_attribute, NULLnullptr }, |
374 | { "strict_flex_array", 1, 1, true, false, false, false, |
375 | handle_strict_flex_array_attribute, NULLnullptr }, |
376 | { "weak", 0, 0, true, false, false, false, |
377 | handle_weak_attribute, NULLnullptr }, |
378 | { "noplt", 0, 0, true, false, false, false, |
379 | handle_noplt_attribute, NULLnullptr }, |
380 | { "ifunc", 1, 1, true, false, false, false, |
381 | handle_ifunc_attribute, NULLnullptr }, |
382 | { "alias", 1, 1, true, false, false, false, |
383 | handle_alias_attribute, NULLnullptr }, |
384 | { "weakref", 0, 1, true, false, false, false, |
385 | handle_weakref_attribute, NULLnullptr }, |
386 | { "no_instrument_function", 0, 0, true, false, false, false, |
387 | handle_no_instrument_function_attribute, |
388 | NULLnullptr }, |
389 | { "no_profile_instrument_function", 0, 0, true, false, false, false, |
390 | handle_no_profile_instrument_function_attribute, |
391 | NULLnullptr }, |
392 | { "malloc", 0, 2, true, false, false, false, |
393 | handle_malloc_attribute, attr_alloc_exclusions }, |
394 | { "returns_twice", 0, 0, true, false, false, false, |
395 | handle_returns_twice_attribute, |
396 | attr_returns_twice_exclusions }, |
397 | { "no_stack_limit", 0, 0, true, false, false, false, |
398 | handle_no_limit_stack_attribute, NULLnullptr }, |
399 | { "pure", 0, 0, true, false, false, false, |
400 | handle_pure_attribute, |
401 | attr_const_pure_exclusions }, |
402 | { "transaction_callable", 0, 0, false, true, false, false, |
403 | handle_tm_attribute, NULLnullptr }, |
404 | { "transaction_unsafe", 0, 0, false, true, false, true, |
405 | handle_tm_attribute, NULLnullptr }, |
406 | { "transaction_safe", 0, 0, false, true, false, true, |
407 | handle_tm_attribute, NULLnullptr }, |
408 | { "transaction_safe_dynamic", 0, 0, true, false, false, false, |
409 | handle_tm_attribute, NULLnullptr }, |
410 | { "transaction_may_cancel_outer", 0, 0, false, true, false, false, |
411 | handle_tm_attribute, NULLnullptr }, |
412 | /* ??? These two attributes didn't make the transition from the |
413 | Intel language document to the multi-vendor language document. */ |
414 | { "transaction_pure", 0, 0, false, true, false, false, |
415 | handle_tm_attribute, NULLnullptr }, |
416 | { "transaction_wrap", 1, 1, true, false, false, false, |
417 | handle_tm_wrap_attribute, NULLnullptr }, |
418 | /* For internal use (marking of builtins) only. The name contains space |
419 | to prevent its usage in source code. */ |
420 | { "no vops", 0, 0, true, false, false, false, |
421 | handle_novops_attribute, NULLnullptr }, |
422 | { "deprecated", 0, 1, false, false, false, false, |
423 | handle_deprecated_attribute, NULLnullptr }, |
424 | { "unavailable", 0, 1, false, false, false, false, |
425 | handle_unavailable_attribute, NULLnullptr }, |
426 | { "vector_size", 1, 1, false, true, false, true, |
427 | handle_vector_size_attribute, NULLnullptr }, |
428 | { "vector_mask", 0, 0, false, true, false, true, |
429 | handle_vector_mask_attribute, NULLnullptr }, |
430 | { "visibility", 1, 1, false, false, false, false, |
431 | handle_visibility_attribute, NULLnullptr }, |
432 | { "tls_model", 1, 1, true, false, false, false, |
433 | handle_tls_model_attribute, NULLnullptr }, |
434 | { "nonnull", 0, -1, false, true, true, false, |
435 | handle_nonnull_attribute, NULLnullptr }, |
436 | { "nonstring", 0, 0, true, false, false, false, |
437 | handle_nonstring_attribute, NULLnullptr }, |
438 | { "nothrow", 0, 0, true, false, false, false, |
439 | handle_nothrow_attribute, NULLnullptr }, |
440 | { "may_alias", 0, 0, false, true, false, false, NULLnullptr, NULLnullptr }, |
441 | { "cleanup", 1, 1, true, false, false, false, |
442 | handle_cleanup_attribute, NULLnullptr }, |
443 | { "warn_unused_result", 0, 0, false, true, true, false, |
444 | handle_warn_unused_result_attribute, |
445 | attr_warn_unused_result_exclusions }, |
446 | { "sentinel", 0, 1, false, true, true, false, |
447 | handle_sentinel_attribute, NULLnullptr }, |
448 | /* For internal use (marking of builtins) only. The name contains space |
449 | to prevent its usage in source code. */ |
450 | { "type generic", 0, 0, false, true, true, false, |
451 | handle_type_generic_attribute, NULLnullptr }, |
452 | { "alloc_size", 1, 2, false, true, true, false, |
453 | handle_alloc_size_attribute, |
454 | attr_alloc_exclusions }, |
455 | { "cold", 0, 0, true, false, false, false, |
456 | handle_cold_attribute, |
457 | attr_cold_hot_exclusions }, |
458 | { "hot", 0, 0, true, false, false, false, |
459 | handle_hot_attribute, |
460 | attr_cold_hot_exclusions }, |
461 | { "no_address_safety_analysis", |
462 | 0, 0, true, false, false, false, |
463 | handle_no_address_safety_analysis_attribute, |
464 | NULLnullptr }, |
465 | { "no_sanitize", 1, -1, true, false, false, false, |
466 | handle_no_sanitize_attribute, NULLnullptr }, |
467 | { "no_sanitize_address", 0, 0, true, false, false, false, |
468 | handle_no_sanitize_address_attribute, NULLnullptr }, |
469 | { "no_sanitize_thread", 0, 0, true, false, false, false, |
470 | handle_no_sanitize_thread_attribute, NULLnullptr }, |
471 | { "no_sanitize_undefined", 0, 0, true, false, false, false, |
472 | handle_no_sanitize_undefined_attribute, NULLnullptr }, |
473 | { "no_sanitize_coverage", 0, 0, true, false, false, false, |
474 | handle_no_sanitize_coverage_attribute, NULLnullptr }, |
475 | { "asan odr indicator", 0, 0, true, false, false, false, |
476 | handle_asan_odr_indicator_attribute, NULLnullptr }, |
477 | { "warning", 1, 1, true, false, false, false, |
478 | handle_error_attribute, NULLnullptr }, |
479 | { "error", 1, 1, true, false, false, false, |
480 | handle_error_attribute, NULLnullptr }, |
481 | { "target", 1, -1, true, false, false, false, |
482 | handle_target_attribute, NULLnullptr }, |
483 | { "target_clones", 1, -1, true, false, false, false, |
484 | handle_target_clones_attribute, NULLnullptr }, |
485 | { "optimize", 1, -1, true, false, false, false, |
486 | handle_optimize_attribute, NULLnullptr }, |
487 | /* For internal use only. The leading '*' both prevents its usage in |
488 | source code and signals that it may be overridden by machine tables. */ |
489 | { "*tm regparm", 0, 0, false, true, true, false, |
490 | ignore_attribute, NULLnullptr }, |
491 | { "no_split_stack", 0, 0, true, false, false, false, |
492 | handle_no_split_stack_attribute, NULLnullptr }, |
493 | { "zero_call_used_regs", 1, 1, true, false, false, false, |
494 | handle_zero_call_used_regs_attribute, NULLnullptr }, |
495 | /* For internal use only (marking of function arguments). |
496 | The name contains a space to prevent its usage in source code. */ |
497 | { "arg spec", 1, -1, true, false, false, false, |
498 | handle_argspec_attribute, NULLnullptr }, |
499 | /* For internal use (marking of builtins and runtime functions) only. |
500 | The name contains space to prevent its usage in source code. */ |
501 | { "fn spec", 1, 1, false, true, true, false, |
502 | handle_fnspec_attribute, NULLnullptr }, |
503 | { "warn_unused", 0, 0, false, false, false, false, |
504 | handle_warn_unused_attribute, NULLnullptr }, |
505 | { "returns_nonnull", 0, 0, false, true, true, false, |
506 | handle_returns_nonnull_attribute, NULLnullptr }, |
507 | { "omp declare simd", 0, -1, true, false, false, false, |
508 | handle_omp_declare_simd_attribute, NULLnullptr }, |
509 | { "omp declare variant base", 0, -1, true, false, false, false, |
510 | handle_omp_declare_variant_attribute, NULLnullptr }, |
511 | { "omp declare variant variant", 0, -1, true, false, false, false, |
512 | handle_omp_declare_variant_attribute, NULLnullptr }, |
513 | { "simd", 0, 1, true, false, false, false, |
514 | handle_simd_attribute, NULLnullptr }, |
515 | { "omp declare target", 0, -1, true, false, false, false, |
516 | handle_omp_declare_target_attribute, NULLnullptr }, |
517 | { "omp declare target link", 0, 0, true, false, false, false, |
518 | handle_omp_declare_target_attribute, NULLnullptr }, |
519 | { "omp declare target implicit", 0, 0, true, false, false, false, |
520 | handle_omp_declare_target_attribute, NULLnullptr }, |
521 | { "omp declare target host", 0, 0, true, false, false, false, |
522 | handle_omp_declare_target_attribute, NULLnullptr }, |
523 | { "omp declare target nohost", 0, 0, true, false, false, false, |
524 | handle_omp_declare_target_attribute, NULLnullptr }, |
525 | { "omp declare target block", 0, 0, true, false, false, false, |
526 | handle_omp_declare_target_attribute, NULLnullptr }, |
527 | { "non overlapping", 0, 0, true, false, false, false, |
528 | handle_non_overlapping_attribute, NULLnullptr }, |
529 | { "alloc_align", 1, 1, false, true, true, false, |
530 | handle_alloc_align_attribute, |
531 | attr_alloc_exclusions }, |
532 | { "assume_aligned", 1, 2, false, true, true, false, |
533 | handle_assume_aligned_attribute, NULLnullptr }, |
534 | { "designated_init", 0, 0, false, true, false, false, |
535 | handle_designated_init_attribute, NULLnullptr }, |
536 | { "fallthrough", 0, 0, false, false, false, false, |
537 | handle_fallthrough_attribute, NULLnullptr }, |
538 | { "assume", 1, 1, false, false, false, false, |
539 | handle_assume_attribute, NULLnullptr }, |
540 | { "patchable_function_entry", 1, 2, true, false, false, false, |
541 | handle_patchable_function_entry_attribute, |
542 | NULLnullptr }, |
543 | { "nocf_check", 0, 0, false, true, true, true, |
544 | handle_nocf_check_attribute, NULLnullptr }, |
545 | { "symver", 1, -1, true, false, false, false, |
546 | handle_symver_attribute, NULLnullptr}, |
547 | { "copy", 1, 1, false, false, false, false, |
548 | handle_copy_attribute, NULLnullptr }, |
549 | { "noinit", 0, 0, true, false, false, false, |
550 | handle_special_var_sec_attribute, attr_section_exclusions }, |
551 | { "persistent", 0, 0, true, false, false, false, |
552 | handle_special_var_sec_attribute, attr_section_exclusions }, |
553 | { "access", 1, 3, false, true, true, false, |
554 | handle_access_attribute, NULLnullptr }, |
555 | /* Attributes used by Objective-C. */ |
556 | { "NSObject", 0, 0, true, false, false, false, |
557 | handle_nsobject_attribute, NULLnullptr }, |
558 | { "objc_root_class", 0, 0, true, false, false, false, |
559 | handle_objc_root_class_attribute, NULLnullptr }, |
560 | { "objc_nullability", 1, 1, true, false, false, false, |
561 | handle_objc_nullability_attribute, NULLnullptr }, |
562 | { "*dealloc", 1, 2, true, false, false, false, |
563 | handle_dealloc_attribute, NULLnullptr }, |
564 | { "tainted_args", 0, 0, true, false, false, false, |
565 | handle_tainted_args_attribute, NULLnullptr }, |
566 | { "fd_arg", 1, 1, false, true, true, false, |
567 | handle_fd_arg_attribute, NULLnullptr}, |
568 | { "fd_arg_read", 1, 1, false, true, true, false, |
569 | handle_fd_arg_attribute, NULLnullptr}, |
570 | { "fd_arg_write", 1, 1, false, true, true, false, |
571 | handle_fd_arg_attribute, NULLnullptr}, |
572 | { NULLnullptr, 0, 0, false, false, false, false, NULLnullptr, NULLnullptr } |
573 | }; |
574 | |
575 | /* Give the specifications for the format attributes, used by C and all |
576 | descendants. |
577 | |
578 | Current list of processed format attributes: format, format_arg. */ |
579 | const struct attribute_spec c_common_format_attribute_table[] = |
580 | { |
581 | /* { name, min_len, max_len, decl_req, type_req, fn_type_req, |
582 | affects_type_identity, handler, exclude } */ |
583 | { "format", 3, 3, false, true, true, false, |
584 | handle_format_attribute, NULLnullptr }, |
585 | { "format_arg", 1, 1, false, true, true, false, |
586 | handle_format_arg_attribute, NULLnullptr }, |
587 | { NULLnullptr, 0, 0, false, false, false, false, NULLnullptr, NULLnullptr } |
588 | }; |
589 | |
590 | /* Returns TRUE iff the attribute indicated by ATTR_ID takes a plain |
591 | identifier as an argument, so the front end shouldn't look it up. */ |
592 | |
593 | bool |
594 | attribute_takes_identifier_p (const_tree attr_id) |
595 | { |
596 | const struct attribute_spec *spec = lookup_attribute_spec (attr_id); |
597 | if (spec == NULLnullptr) |
598 | /* Unknown attribute that we'll end up ignoring, return true so we |
599 | don't complain about an identifier argument. */ |
600 | return true; |
601 | else if (!strcmp ("mode", spec->name) |
602 | || !strcmp ("format", spec->name) |
603 | || !strcmp ("cleanup", spec->name) |
604 | || !strcmp ("access", spec->name)) |
605 | return true; |
606 | else |
607 | return targetm.attribute_takes_identifier_p (attr_id); |
608 | } |
609 | |
610 | /* Verify that argument value POS at position ARGNO to attribute NAME |
611 | applied to function FN (which is either a function declaration or function |
612 | type) refers to a function parameter at position POS and the expected type |
613 | CODE. Treat CODE == INTEGER_TYPE as matching all C integral types except |
614 | bool. If successful, return POS after default conversions (and possibly |
615 | adjusted by ADJUST_POS). Otherwise, issue appropriate warnings and return |
616 | null. A non-zero 1-based ARGNO should be passed in by callers only for |
617 | attributes with more than one argument. |
618 | |
619 | N.B. This function modifies POS. */ |
620 | |
621 | tree |
622 | positional_argument (const_tree fn, const_tree atname, tree &pos, |
623 | tree_code code, int argno /* = 0 */, |
624 | int flags /* = posargflags () */) |
625 | { |
626 | const_tree fndecl = TYPE_P (fn)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (fn)->base.code))] == tcc_type) ? NULL_TREE(tree) nullptr : fn; |
627 | const_tree fntype = TYPE_P (fn)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (fn)->base.code))] == tcc_type) ? fn : TREE_TYPE (fn)((contains_struct_check ((fn), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 627, __FUNCTION__))->typed.type); |
628 | if (pos && TREE_CODE (pos)((enum tree_code) (pos)->base.code) != IDENTIFIER_NODE |
629 | && TREE_CODE (pos)((enum tree_code) (pos)->base.code) != FUNCTION_DECL) |
630 | pos = default_conversion (pos); |
631 | |
632 | tree postype = TREE_TYPE (pos)((contains_struct_check ((pos), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 632, __FUNCTION__))->typed.type); |
633 | if (pos == error_mark_nodeglobal_trees[TI_ERROR_MARK] || !postype) |
634 | { |
635 | /* Only mention the positional argument number when it's non-zero. */ |
636 | if (argno < 1) |
637 | warning (OPT_Wattributes, |
638 | "%qE attribute argument is invalid", atname); |
639 | else |
640 | warning (OPT_Wattributes, |
641 | "%qE attribute argument %i is invalid", atname, argno); |
642 | |
643 | return NULL_TREE(tree) nullptr; |
644 | } |
645 | |
646 | if (!INTEGRAL_TYPE_P (postype)(((enum tree_code) (postype)->base.code) == ENUMERAL_TYPE || ((enum tree_code) (postype)->base.code) == BOOLEAN_TYPE || ((enum tree_code) (postype)->base.code) == INTEGER_TYPE)) |
647 | { |
648 | /* Handle this case specially to avoid mentioning the value |
649 | of pointer constants in diagnostics. Only mention |
650 | the positional argument number when it's non-zero. */ |
651 | if (argno < 1) |
652 | warning (OPT_Wattributes, |
653 | "%qE attribute argument has type %qT", |
654 | atname, postype); |
655 | else |
656 | warning (OPT_Wattributes, |
657 | "%qE attribute argument %i has type %qT", |
658 | atname, argno, postype); |
659 | |
660 | return NULL_TREE(tree) nullptr; |
661 | } |
662 | |
663 | if (TREE_CODE (pos)((enum tree_code) (pos)->base.code) != INTEGER_CST) |
664 | { |
665 | /* Only mention the argument number when it's non-zero. */ |
666 | if (argno < 1) |
667 | warning (OPT_Wattributes, |
668 | "%qE attribute argument value %qE is not an integer " |
669 | "constant", |
670 | atname, pos); |
671 | else |
672 | warning (OPT_Wattributes, |
673 | "%qE attribute argument %i value %qE is not an integer " |
674 | "constant", |
675 | atname, argno, pos); |
676 | |
677 | return NULL_TREE(tree) nullptr; |
678 | } |
679 | |
680 | /* Argument positions are 1-based. */ |
681 | if (integer_zerop (pos)) |
682 | { |
683 | if (flags & POSARG_ZERO) |
684 | /* Zero is explicitly allowed. */ |
685 | return pos; |
686 | |
687 | if (argno < 1) |
688 | warning (OPT_Wattributes, |
689 | "%qE attribute argument value %qE does not refer to " |
690 | "a function parameter", |
691 | atname, pos); |
692 | else |
693 | warning (OPT_Wattributes, |
694 | "%qE attribute argument %i value %qE does not refer to " |
695 | "a function parameter", |
696 | atname, argno, pos); |
697 | |
698 | return NULL_TREE(tree) nullptr; |
699 | } |
700 | |
701 | if (!prototype_p (fntype)) |
702 | return pos; |
703 | |
704 | /* ADJUST_POS is non-zero in C++ when the function type has invisible |
705 | parameters generated by the compiler, such as the in-charge or VTT |
706 | parameters. */ |
707 | const int adjust_pos = maybe_adjust_arg_pos_for_attribute (fndecl); |
708 | |
709 | /* Verify that the argument position does not exceed the number |
710 | of formal arguments to the function. When POSARG_ELLIPSIS |
711 | is set, ARGNO may be beyond the last argument of a vararg |
712 | function. */ |
713 | unsigned nargs = type_num_arguments (fntype); |
714 | if (!nargs |
715 | || !tree_fits_uhwi_p (pos) |
716 | || ((flags & POSARG_ELLIPSIS) == 0 |
717 | && !IN_RANGE (tree_to_uhwi (pos) + adjust_pos, 1, nargs)((unsigned long) (tree_to_uhwi (pos) + adjust_pos) - (unsigned long) (1) <= (unsigned long) (nargs) - (unsigned long) (1 )))) |
718 | { |
719 | |
720 | if (argno < 1) |
721 | warning (OPT_Wattributes, |
722 | "%qE attribute argument value %qE exceeds the number " |
723 | "of function parameters %u", |
724 | atname, pos, nargs); |
725 | else |
726 | warning (OPT_Wattributes, |
727 | "%qE attribute argument %i value %qE exceeds the number " |
728 | "of function parameters %u", |
729 | atname, argno, pos, nargs); |
730 | return NULL_TREE(tree) nullptr; |
731 | } |
732 | |
733 | /* Verify that the type of the referenced formal argument matches |
734 | the expected type. Invisible parameters may have been added by |
735 | the compiler, so adjust the position accordingly. */ |
736 | unsigned HOST_WIDE_INTlong ipos = tree_to_uhwi (pos) + adjust_pos; |
737 | |
738 | /* Zero was handled above. */ |
739 | gcc_assert (ipos != 0)((void)(!(ipos != 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 739, __FUNCTION__), 0 : 0)); |
740 | |
741 | if (tree argtype = type_argument_type (fntype, ipos)) |
742 | { |
743 | if (argtype == error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
744 | return NULL_TREE(tree) nullptr; |
745 | |
746 | if (flags & POSARG_ELLIPSIS) |
747 | { |
748 | if (argno < 1) |
749 | error ("%qE attribute argument value %qE does not refer to " |
750 | "a variable argument list", |
751 | atname, pos); |
752 | else |
753 | error ("%qE attribute argument %i value %qE does not refer to " |
754 | "a variable argument list", |
755 | atname, argno, pos); |
756 | return NULL_TREE(tree) nullptr; |
757 | } |
758 | |
759 | /* Where the expected code is STRING_CST accept any pointer |
760 | expected by attribute format (this includes possibly qualified |
761 | char pointers and, for targets like Darwin, also pointers to |
762 | struct CFString). */ |
763 | bool type_match; |
764 | if (code == STRING_CST) |
765 | type_match = valid_format_string_type_p (argtype); |
766 | else if (code == INTEGER_TYPE) |
767 | /* For integers, accept enums, wide characters and other types |
768 | that match INTEGRAL_TYPE_P except for bool. */ |
769 | type_match = (INTEGRAL_TYPE_P (argtype)(((enum tree_code) (argtype)->base.code) == ENUMERAL_TYPE || ((enum tree_code) (argtype)->base.code) == BOOLEAN_TYPE || ((enum tree_code) (argtype)->base.code) == INTEGER_TYPE) |
770 | && TREE_CODE (argtype)((enum tree_code) (argtype)->base.code) != BOOLEAN_TYPE); |
771 | else |
772 | type_match = TREE_CODE (argtype)((enum tree_code) (argtype)->base.code) == code; |
773 | |
774 | if (!type_match) |
775 | { |
776 | if (code == STRING_CST) |
777 | { |
778 | /* Reject invalid format strings with an error. */ |
779 | if (argno < 1) |
780 | error ("%qE attribute argument value %qE refers to " |
781 | "parameter type %qT", |
782 | atname, pos, argtype); |
783 | else |
784 | error ("%qE attribute argument %i value %qE refers to " |
785 | "parameter type %qT", |
786 | atname, argno, pos, argtype); |
787 | |
788 | return NULL_TREE(tree) nullptr; |
789 | } |
790 | |
791 | if (argno < 1) |
792 | warning (OPT_Wattributes, |
793 | "%qE attribute argument value %qE refers to " |
794 | "parameter type %qT", |
795 | atname, pos, argtype); |
796 | else |
797 | warning (OPT_Wattributes, |
798 | "%qE attribute argument %i value %qE refers to " |
799 | "parameter type %qT", |
800 | atname, argno, pos, argtype); |
801 | return NULL_TREE(tree) nullptr; |
802 | } |
803 | } |
804 | else if (!(flags & POSARG_ELLIPSIS)) |
805 | { |
806 | if (argno < 1) |
807 | warning (OPT_Wattributes, |
808 | "%qE attribute argument value %qE refers to " |
809 | "a variadic function parameter of unknown type", |
810 | atname, pos); |
811 | else |
812 | warning (OPT_Wattributes, |
813 | "%qE attribute argument %i value %qE refers to " |
814 | "a variadic function parameter of unknown type", |
815 | atname, argno, pos); |
816 | return NULL_TREE(tree) nullptr; |
817 | } |
818 | |
819 | return build_int_cst (TREE_TYPE (pos)((contains_struct_check ((pos), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 819, __FUNCTION__))->typed.type), ipos); |
820 | } |
821 | |
822 | /* Return the first of DECL or TYPE attributes installed in NODE if it's |
823 | a DECL, or TYPE attributes if it's a TYPE, or null otherwise. */ |
824 | |
825 | static tree |
826 | decl_or_type_attrs (tree node) |
827 | { |
828 | if (DECL_P (node)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (node)->base.code))] == tcc_declaration)) |
829 | { |
830 | if (tree attrs = DECL_ATTRIBUTES (node)((contains_struct_check ((node), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 830, __FUNCTION__))->decl_common.attributes)) |
831 | return attrs; |
832 | |
833 | tree type = TREE_TYPE (node)((contains_struct_check ((node), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 833, __FUNCTION__))->typed.type); |
834 | if (type == error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
835 | return NULL_TREE(tree) nullptr; |
836 | return TYPE_ATTRIBUTES (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 836, __FUNCTION__))->type_common.attributes); |
837 | } |
838 | |
839 | if (TYPE_P (node)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (node)->base.code))] == tcc_type)) |
840 | return TYPE_ATTRIBUTES (node)((tree_class_check ((node), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 840, __FUNCTION__))->type_common.attributes); |
841 | |
842 | return NULL_TREE(tree) nullptr; |
843 | } |
844 | |
845 | /* Given a pair of NODEs for arbitrary DECLs or TYPEs, validate one or |
846 | two integral or string attribute arguments NEWARGS to be applied to |
847 | NODE[0] for the absence of conflicts with the same attribute arguments |
848 | already applied to NODE[1]. Issue a warning for conflicts and return |
849 | false. Otherwise, when no conflicts are found, return true. */ |
850 | |
851 | static bool |
852 | validate_attr_args (tree node[2], tree name, tree newargs[2]) |
853 | { |
854 | /* First validate the arguments against those already applied to |
855 | the same declaration (or type). */ |
856 | tree self[2] = { node[0], node[0] }; |
857 | if (node[0] != node[1] && !validate_attr_args (self, name, newargs)) |
858 | return false; |
859 | |
860 | if (!node[1]) |
861 | return true; |
862 | |
863 | /* Extract the same attribute from the previous declaration or type. */ |
864 | tree prevattr = decl_or_type_attrs (node[1]); |
865 | const char* const namestr = IDENTIFIER_POINTER (name)((const char *) (tree_check ((name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 865, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ); |
866 | prevattr = lookup_attribute (namestr, prevattr); |
867 | if (!prevattr) |
868 | return true; |
869 | |
870 | /* Extract one or both attribute arguments. */ |
871 | tree prevargs[2]; |
872 | prevargs[0] = TREE_VALUE (TREE_VALUE (prevattr))((tree_check ((((tree_check ((prevattr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 872, __FUNCTION__, (TREE_LIST)))->list.value)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 872, __FUNCTION__, (TREE_LIST)))->list.value); |
873 | prevargs[1] = TREE_CHAIN (TREE_VALUE (prevattr))((contains_struct_check ((((tree_check ((prevattr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 873, __FUNCTION__, (TREE_LIST)))->list.value)), (TS_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 873, __FUNCTION__))->common.chain); |
874 | if (prevargs[1]) |
875 | prevargs[1] = TREE_VALUE (prevargs[1])((tree_check ((prevargs[1]), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 875, __FUNCTION__, (TREE_LIST)))->list.value); |
876 | |
877 | /* Both arguments must be equal or, for the second pair, neither must |
878 | be provided to succeed. */ |
879 | bool arg1eq, arg2eq; |
880 | if (TREE_CODE (newargs[0])((enum tree_code) (newargs[0])->base.code) == INTEGER_CST) |
881 | { |
882 | arg1eq = tree_int_cst_equal (newargs[0], prevargs[0]); |
883 | if (newargs[1] && prevargs[1]) |
884 | arg2eq = tree_int_cst_equal (newargs[1], prevargs[1]); |
885 | else |
886 | arg2eq = newargs[1] == prevargs[1]; |
887 | } |
888 | else if (TREE_CODE (newargs[0])((enum tree_code) (newargs[0])->base.code) == STRING_CST) |
889 | { |
890 | const char *s0 = TREE_STRING_POINTER (newargs[0])((const char *)((tree_check ((newargs[0]), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 890, __FUNCTION__, (STRING_CST)))->string.str)); |
891 | const char *s1 = TREE_STRING_POINTER (prevargs[0])((const char *)((tree_check ((prevargs[0]), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 891, __FUNCTION__, (STRING_CST)))->string.str)); |
892 | arg1eq = strcmp (s0, s1) == 0; |
893 | if (newargs[1] && prevargs[1]) |
894 | { |
895 | s0 = TREE_STRING_POINTER (newargs[1])((const char *)((tree_check ((newargs[1]), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 895, __FUNCTION__, (STRING_CST)))->string.str)); |
896 | s1 = TREE_STRING_POINTER (prevargs[1])((const char *)((tree_check ((prevargs[1]), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 896, __FUNCTION__, (STRING_CST)))->string.str)); |
897 | arg2eq = strcmp (s0, s1) == 0; |
898 | } |
899 | else |
900 | arg2eq = newargs[1] == prevargs[1]; |
901 | } |
902 | else |
903 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 903, __FUNCTION__)); |
904 | |
905 | if (arg1eq && arg2eq) |
906 | return true; |
907 | |
908 | /* If the two locations are different print a note pointing to |
909 | the previous one. */ |
910 | const location_t curloc = input_location; |
911 | const location_t prevloc = |
912 | DECL_P (node[1])(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (node[1])->base.code))] == tcc_declaration) ? DECL_SOURCE_LOCATION (node[1])((contains_struct_check ((node[1]), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 912, __FUNCTION__))->decl_minimal.locus) : curloc; |
913 | |
914 | /* Format the attribute specification for convenience. */ |
915 | char newspec[80], prevspec[80]; |
916 | if (newargs[1]) |
917 | snprintf (newspec, sizeof newspec, "%s (%s, %s)", namestr, |
918 | print_generic_expr_to_str (newargs[0]), |
919 | print_generic_expr_to_str (newargs[1])); |
920 | else |
921 | snprintf (newspec, sizeof newspec, "%s (%s)", namestr, |
922 | print_generic_expr_to_str (newargs[0])); |
923 | |
924 | if (prevargs[1]) |
925 | snprintf (prevspec, sizeof prevspec, "%s (%s, %s)", namestr, |
926 | print_generic_expr_to_str (prevargs[0]), |
927 | print_generic_expr_to_str (prevargs[1])); |
928 | else |
929 | snprintf (prevspec, sizeof prevspec, "%s (%s)", namestr, |
930 | print_generic_expr_to_str (prevargs[0])); |
931 | |
932 | if (warning_at (curloc, OPT_Wattributes, |
933 | "ignoring attribute %qs because it conflicts " |
934 | "with previous %qs", |
935 | newspec, prevspec) |
936 | && curloc != prevloc) |
937 | inform (prevloc, "previous declaration here"); |
938 | |
939 | return false; |
940 | } |
941 | |
942 | /* Convenience wrapper for validate_attr_args to validate a single |
943 | attribute argument. Used by handlers for attributes that take |
944 | just a single argument. */ |
945 | |
946 | static bool |
947 | validate_attr_arg (tree node[2], tree name, tree newarg) |
948 | { |
949 | tree argarray[2] = { newarg, NULL_TREE(tree) nullptr }; |
950 | return validate_attr_args (node, name, argarray); |
951 | } |
952 | |
953 | /* Attribute handlers common to C front ends. */ |
954 | |
955 | /* Handle a "signed_bool_precision" attribute; arguments as in |
956 | struct attribute_spec.handler. */ |
957 | |
958 | static tree |
959 | handle_signed_bool_precision_attribute (tree *node, tree name, tree args, |
960 | int, bool *no_add_attrs) |
961 | { |
962 | *no_add_attrs = true; |
963 | if (!flag_gimpleglobal_options.x_flag_gimple) |
964 | { |
965 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
966 | return NULL_TREE(tree) nullptr; |
967 | } |
968 | |
969 | if (!TYPE_P (*node)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (*node)->base.code))] == tcc_type) || TREE_CODE (*node)((enum tree_code) (*node)->base.code) != BOOLEAN_TYPE) |
970 | { |
971 | warning (OPT_Wattributes, "%qE attribute only supported on " |
972 | "boolean types", name); |
973 | return NULL_TREE(tree) nullptr; |
974 | } |
975 | |
976 | unsigned HOST_WIDE_INTlong prec = HOST_WIDE_INT_M1U-1UL; |
977 | if (tree_fits_uhwi_p (TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 977, __FUNCTION__, (TREE_LIST)))->list.value))) |
978 | prec = tree_to_uhwi (TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 978, __FUNCTION__, (TREE_LIST)))->list.value)); |
979 | if (prec > MAX_FIXED_MODE_SIZEGET_MODE_BITSIZE (((global_options.x_ix86_isa_flags & (1UL << 1)) != 0) ? (scalar_int_mode ((scalar_int_mode::from_int ) E_TImode)) : (scalar_int_mode ((scalar_int_mode::from_int) E_DImode )))) |
980 | { |
981 | warning (OPT_Wattributes, "%qE attribute with unsupported boolean " |
982 | "precision", name); |
983 | return NULL_TREE(tree) nullptr; |
984 | } |
985 | |
986 | tree new_type = build_nonstandard_boolean_type (prec); |
987 | *node = lang_hooks.types.reconstruct_complex_type (*node, new_type); |
988 | |
989 | return NULL_TREE(tree) nullptr; |
990 | } |
991 | |
992 | /* Handle a "packed" attribute; arguments as in |
993 | struct attribute_spec.handler. */ |
994 | |
995 | static tree |
996 | handle_packed_attribute (tree *node, tree name, tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
997 | int flags, bool *no_add_attrs) |
998 | { |
999 | if (TYPE_P (*node)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (*node)->base.code))] == tcc_type)) |
1000 | { |
1001 | if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) |
1002 | { |
1003 | warning (OPT_Wattributes, |
1004 | "%qE attribute ignored for type %qT", name, *node); |
1005 | *no_add_attrs = true; |
1006 | } |
1007 | else |
1008 | TYPE_PACKED (*node)((tree_class_check ((*node), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1008, __FUNCTION__))->base.u.bits.packed_flag) = 1; |
1009 | } |
1010 | else if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) == FIELD_DECL) |
1011 | { |
1012 | if (TYPE_ALIGN (TREE_TYPE (*node))(((tree_class_check ((((contains_struct_check ((*node), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1012, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1012, __FUNCTION__))->type_common.align) ? ((unsigned)1) << (((tree_class_check ((((contains_struct_check ((*node ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1012, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1012, __FUNCTION__))->type_common.align) - 1) : 0) <= BITS_PER_UNIT(8) |
1013 | /* Still pack bitfields. */ |
1014 | && ! DECL_C_BIT_FIELD (*node)(((contains_struct_check (((tree_check ((*node), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1014, __FUNCTION__, (FIELD_DECL)))), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1014, __FUNCTION__))->decl_common.lang_flag_4) == 1)) |
1015 | warning (OPT_Wattributes, |
1016 | "%qE attribute ignored for field of type %qT", |
1017 | name, TREE_TYPE (*node)((contains_struct_check ((*node), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1017, __FUNCTION__))->typed.type)); |
1018 | else |
1019 | DECL_PACKED (*node)((tree_check ((*node), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1019, __FUNCTION__, (FIELD_DECL)))->base.u.bits.packed_flag ) = 1; |
1020 | } |
1021 | /* We can't set DECL_PACKED for a VAR_DECL, because the bit is |
1022 | used for DECL_REGISTER. It wouldn't mean anything anyway. |
1023 | We can't set DECL_PACKED on the type of a TYPE_DECL, because |
1024 | that changes what the typedef is typing. */ |
1025 | else |
1026 | { |
1027 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1028 | *no_add_attrs = true; |
1029 | } |
1030 | |
1031 | return NULL_TREE(tree) nullptr; |
1032 | } |
1033 | |
1034 | /* Handle a "nocommon" attribute; arguments as in |
1035 | struct attribute_spec.handler. */ |
1036 | |
1037 | static tree |
1038 | handle_nocommon_attribute (tree *node, tree name, |
1039 | tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
1040 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), bool *no_add_attrs) |
1041 | { |
1042 | if (VAR_P (*node)(((enum tree_code) (*node)->base.code) == VAR_DECL)) |
1043 | DECL_COMMON (*node)((contains_struct_check ((*node), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1043, __FUNCTION__))->decl_with_vis.common_flag) = 0; |
1044 | else |
1045 | { |
1046 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1047 | *no_add_attrs = true; |
1048 | } |
1049 | |
1050 | return NULL_TREE(tree) nullptr; |
1051 | } |
1052 | |
1053 | /* Handle a "common" attribute; arguments as in |
1054 | struct attribute_spec.handler. */ |
1055 | |
1056 | static tree |
1057 | handle_common_attribute (tree *node, tree name, tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
1058 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), bool *no_add_attrs) |
1059 | { |
1060 | if (VAR_P (*node)(((enum tree_code) (*node)->base.code) == VAR_DECL)) |
1061 | DECL_COMMON (*node)((contains_struct_check ((*node), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1061, __FUNCTION__))->decl_with_vis.common_flag) = 1; |
1062 | else |
1063 | { |
1064 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1065 | *no_add_attrs = true; |
1066 | } |
1067 | |
1068 | return NULL_TREE(tree) nullptr; |
1069 | } |
1070 | |
1071 | /* Handle a "noreturn" attribute; arguments as in |
1072 | struct attribute_spec.handler. */ |
1073 | |
1074 | tree |
1075 | handle_noreturn_attribute (tree *node, tree name, tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
1076 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), bool *no_add_attrs) |
1077 | { |
1078 | tree type = TREE_TYPE (*node)((contains_struct_check ((*node), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1078, __FUNCTION__))->typed.type); |
1079 | |
1080 | /* See FIXME comment in c_common_attribute_table. */ |
1081 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) == FUNCTION_DECL |
1082 | || objc_method_decl (TREE_CODE (*node)((enum tree_code) (*node)->base.code))) |
1083 | TREE_THIS_VOLATILE (*node)((*node)->base.volatile_flag) = 1; |
1084 | else if (TREE_CODE (type)((enum tree_code) (type)->base.code) == POINTER_TYPE |
1085 | && TREE_CODE (TREE_TYPE (type))((enum tree_code) (((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1085, __FUNCTION__))->typed.type))->base.code) == FUNCTION_TYPE) |
1086 | TREE_TYPE (*node)((contains_struct_check ((*node), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1086, __FUNCTION__))->typed.type) |
1087 | = (build_qualified_type |
1088 | (build_pointer_type |
1089 | (build_type_variant (TREE_TYPE (type),build_qualified_type ((((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1089, __FUNCTION__))->typed.type)), ((((tree_class_check ((((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1090, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1090, __FUNCTION__))->base.readonly_flag)) ? TYPE_QUAL_CONST : 0) | ((1) ? TYPE_QUAL_VOLATILE : 0)) |
1090 | TYPE_READONLY (TREE_TYPE (type)), 1)build_qualified_type ((((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1089, __FUNCTION__))->typed.type)), ((((tree_class_check ((((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1090, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1090, __FUNCTION__))->base.readonly_flag)) ? TYPE_QUAL_CONST : 0) | ((1) ? TYPE_QUAL_VOLATILE : 0))), |
1091 | TYPE_QUALS (type)((int) ((((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1091, __FUNCTION__))->base.readonly_flag) * TYPE_QUAL_CONST ) | (((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1091, __FUNCTION__))->base.volatile_flag) * TYPE_QUAL_VOLATILE ) | (((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1091, __FUNCTION__))->base.u.bits.atomic_flag) * TYPE_QUAL_ATOMIC ) | (((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1091, __FUNCTION__))->type_common.restrict_flag) * TYPE_QUAL_RESTRICT ) | (((((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1091, __FUNCTION__))->base.u.bits.address_space) & 0xFF ) << 8)))))); |
1092 | else |
1093 | { |
1094 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1095 | *no_add_attrs = true; |
1096 | } |
1097 | |
1098 | return NULL_TREE(tree) nullptr; |
1099 | } |
1100 | |
1101 | /* Handle a "hot" and attribute; arguments as in |
1102 | struct attribute_spec.handler. */ |
1103 | |
1104 | static tree |
1105 | handle_hot_attribute (tree *node, tree name, tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
1106 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), bool *no_add_attrs) |
1107 | { |
1108 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) == FUNCTION_DECL |
1109 | || TREE_CODE (*node)((enum tree_code) (*node)->base.code) == LABEL_DECL) |
1110 | { |
1111 | /* Attribute hot processing is done later with lookup_attribute. */ |
1112 | } |
1113 | else |
1114 | { |
1115 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1116 | *no_add_attrs = true; |
1117 | } |
1118 | |
1119 | return NULL_TREE(tree) nullptr; |
1120 | } |
1121 | |
1122 | /* Handle a "cold" and attribute; arguments as in |
1123 | struct attribute_spec.handler. */ |
1124 | |
1125 | static tree |
1126 | handle_cold_attribute (tree *node, tree name, tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
1127 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), bool *no_add_attrs) |
1128 | { |
1129 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) == FUNCTION_DECL |
1130 | || TREE_CODE (*node)((enum tree_code) (*node)->base.code) == LABEL_DECL) |
1131 | { |
1132 | /* Attribute cold processing is done later with lookup_attribute. */ |
1133 | } |
1134 | else |
1135 | { |
1136 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1137 | *no_add_attrs = true; |
1138 | } |
1139 | |
1140 | return NULL_TREE(tree) nullptr; |
1141 | } |
1142 | |
1143 | /* Add FLAGS for a function NODE to no_sanitize_flags in DECL_ATTRIBUTES. */ |
1144 | |
1145 | void |
1146 | add_no_sanitize_value (tree node, unsigned int flags) |
1147 | { |
1148 | tree attr = lookup_attribute ("no_sanitize", DECL_ATTRIBUTES (node)((contains_struct_check ((node), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1148, __FUNCTION__))->decl_common.attributes)); |
1149 | if (attr) |
1150 | { |
1151 | unsigned int old_value = tree_to_uhwi (TREE_VALUE (attr)((tree_check ((attr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1151, __FUNCTION__, (TREE_LIST)))->list.value)); |
1152 | flags |= old_value; |
1153 | |
1154 | if (flags == old_value) |
1155 | return; |
1156 | |
1157 | TREE_VALUE (attr)((tree_check ((attr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1157, __FUNCTION__, (TREE_LIST)))->list.value) = build_int_cst (unsigned_type_nodeinteger_types[itk_unsigned_int], flags); |
1158 | } |
1159 | else |
1160 | DECL_ATTRIBUTES (node)((contains_struct_check ((node), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1160, __FUNCTION__))->decl_common.attributes) |
1161 | = tree_cons (get_identifier ("no_sanitize")(__builtin_constant_p ("no_sanitize") ? get_identifier_with_length (("no_sanitize"), strlen ("no_sanitize")) : get_identifier ( "no_sanitize")), |
1162 | build_int_cst (unsigned_type_nodeinteger_types[itk_unsigned_int], flags), |
1163 | DECL_ATTRIBUTES (node)((contains_struct_check ((node), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1163, __FUNCTION__))->decl_common.attributes)); |
1164 | } |
1165 | |
1166 | /* Handle a "no_sanitize" attribute; arguments as in |
1167 | struct attribute_spec.handler. */ |
1168 | |
1169 | static tree |
1170 | handle_no_sanitize_attribute (tree *node, tree name, tree args, int, |
1171 | bool *no_add_attrs) |
1172 | { |
1173 | unsigned int flags = 0; |
1174 | *no_add_attrs = true; |
1175 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) != FUNCTION_DECL) |
1176 | { |
1177 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1178 | return NULL_TREE(tree) nullptr; |
1179 | } |
1180 | |
1181 | for (; args; args = TREE_CHAIN (args)((contains_struct_check ((args), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1181, __FUNCTION__))->common.chain)) |
1182 | { |
1183 | tree id = TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1183, __FUNCTION__, (TREE_LIST)))->list.value); |
1184 | if (TREE_CODE (id)((enum tree_code) (id)->base.code) != STRING_CST) |
1185 | { |
1186 | error ("%qE argument not a string", name); |
1187 | return NULL_TREE(tree) nullptr; |
1188 | } |
1189 | |
1190 | char *string = ASTRDUP (TREE_STRING_POINTER (id))(__extension__ ({ const char *const libiberty_optr = (((const char *)((tree_check ((id), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1190, __FUNCTION__, (STRING_CST)))->string.str))); const unsigned long libiberty_len = strlen (libiberty_optr) + 1; char *const libiberty_nptr = (char *) __builtin_alloca(libiberty_len ); (char *) memcpy (libiberty_nptr, libiberty_optr, libiberty_len ); })); |
1191 | flags |= parse_no_sanitize_attribute (string); |
1192 | } |
1193 | |
1194 | add_no_sanitize_value (*node, flags); |
1195 | |
1196 | return NULL_TREE(tree) nullptr; |
1197 | } |
1198 | |
1199 | /* Handle a "no_sanitize_address" attribute; arguments as in |
1200 | struct attribute_spec.handler. */ |
1201 | |
1202 | static tree |
1203 | handle_no_sanitize_address_attribute (tree *node, tree name, tree, int, |
1204 | bool *no_add_attrs) |
1205 | { |
1206 | *no_add_attrs = true; |
1207 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) != FUNCTION_DECL) |
1208 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1209 | else |
1210 | add_no_sanitize_value (*node, SANITIZE_ADDRESS); |
1211 | |
1212 | return NULL_TREE(tree) nullptr; |
1213 | } |
1214 | |
1215 | /* Handle a "no_sanitize_thread" attribute; arguments as in |
1216 | struct attribute_spec.handler. */ |
1217 | |
1218 | static tree |
1219 | handle_no_sanitize_thread_attribute (tree *node, tree name, tree, int, |
1220 | bool *no_add_attrs) |
1221 | { |
1222 | *no_add_attrs = true; |
1223 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) != FUNCTION_DECL) |
1224 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1225 | else |
1226 | add_no_sanitize_value (*node, SANITIZE_THREAD); |
1227 | |
1228 | return NULL_TREE(tree) nullptr; |
1229 | } |
1230 | |
1231 | |
1232 | /* Handle a "no_address_safety_analysis" attribute; arguments as in |
1233 | struct attribute_spec.handler. */ |
1234 | |
1235 | static tree |
1236 | handle_no_address_safety_analysis_attribute (tree *node, tree name, tree, int, |
1237 | bool *no_add_attrs) |
1238 | { |
1239 | *no_add_attrs = true; |
1240 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) != FUNCTION_DECL) |
1241 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1242 | else |
1243 | add_no_sanitize_value (*node, SANITIZE_ADDRESS); |
1244 | |
1245 | return NULL_TREE(tree) nullptr; |
1246 | } |
1247 | |
1248 | /* Handle a "no_sanitize_undefined" attribute; arguments as in |
1249 | struct attribute_spec.handler. */ |
1250 | |
1251 | static tree |
1252 | handle_no_sanitize_undefined_attribute (tree *node, tree name, tree, int, |
1253 | bool *no_add_attrs) |
1254 | { |
1255 | *no_add_attrs = true; |
1256 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) != FUNCTION_DECL) |
1257 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1258 | else |
1259 | add_no_sanitize_value (*node, |
1260 | SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT); |
1261 | |
1262 | return NULL_TREE(tree) nullptr; |
1263 | } |
1264 | |
1265 | /* Handle a "no_sanitize_coverage" attribute; arguments as in |
1266 | struct attribute_spec.handler. */ |
1267 | |
1268 | static tree |
1269 | handle_no_sanitize_coverage_attribute (tree *node, tree name, tree, int, |
1270 | bool *no_add_attrs) |
1271 | { |
1272 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) != FUNCTION_DECL) |
1273 | { |
1274 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1275 | *no_add_attrs = true; |
1276 | } |
1277 | |
1278 | return NULL_TREE(tree) nullptr; |
1279 | } |
1280 | |
1281 | /* Handle an "asan odr indicator" attribute; arguments as in |
1282 | struct attribute_spec.handler. */ |
1283 | |
1284 | static tree |
1285 | handle_asan_odr_indicator_attribute (tree *, tree, tree, int, bool *) |
1286 | { |
1287 | return NULL_TREE(tree) nullptr; |
1288 | } |
1289 | |
1290 | /* Handle a "stack_protect" attribute; arguments as in |
1291 | struct attribute_spec.handler. */ |
1292 | |
1293 | static tree |
1294 | handle_stack_protect_attribute (tree *node, tree name, tree, int, |
1295 | bool *no_add_attrs) |
1296 | { |
1297 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) != FUNCTION_DECL) |
1298 | { |
1299 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1300 | *no_add_attrs = true; |
1301 | } |
1302 | |
1303 | return NULL_TREE(tree) nullptr; |
1304 | } |
1305 | |
1306 | /* Handle a "no_stack_protector" attribute; arguments as in |
1307 | struct attribute_spec.handler. */ |
1308 | |
1309 | static tree |
1310 | handle_no_stack_protector_function_attribute (tree *node, tree name, tree, |
1311 | int, bool *no_add_attrs) |
1312 | { |
1313 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) != FUNCTION_DECL) |
1314 | { |
1315 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1316 | *no_add_attrs = true; |
1317 | } |
1318 | |
1319 | return NULL_TREE(tree) nullptr; |
1320 | } |
1321 | |
1322 | /* Handle a "noipa" attribute; arguments as in |
1323 | struct attribute_spec.handler. */ |
1324 | |
1325 | static tree |
1326 | handle_noipa_attribute (tree *node, tree name, tree, int, bool *no_add_attrs) |
1327 | { |
1328 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) != FUNCTION_DECL) |
1329 | { |
1330 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1331 | *no_add_attrs = true; |
1332 | } |
1333 | |
1334 | return NULL_TREE(tree) nullptr; |
1335 | } |
1336 | |
1337 | /* Handle a "noinline" attribute; arguments as in |
1338 | struct attribute_spec.handler. */ |
1339 | |
1340 | static tree |
1341 | handle_noinline_attribute (tree *node, tree name, |
1342 | tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
1343 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), bool *no_add_attrs) |
1344 | { |
1345 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) == FUNCTION_DECL) |
1346 | { |
1347 | if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (*node)((contains_struct_check ((*node), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1347, __FUNCTION__))->decl_common.attributes))) |
1348 | { |
1349 | warning (OPT_Wattributes, "%qE attribute ignored due to conflict " |
1350 | "with attribute %qs", name, "always_inline"); |
1351 | *no_add_attrs = true; |
1352 | } |
1353 | else |
1354 | DECL_UNINLINABLE (*node)((tree_check ((*node), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1354, __FUNCTION__, (FUNCTION_DECL)))->function_decl.uninlinable ) = 1; |
1355 | } |
1356 | else |
1357 | { |
1358 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1359 | *no_add_attrs = true; |
1360 | } |
1361 | |
1362 | return NULL_TREE(tree) nullptr; |
1363 | } |
1364 | |
1365 | /* Handle a "noclone" attribute; arguments as in |
1366 | struct attribute_spec.handler. */ |
1367 | |
1368 | static tree |
1369 | handle_noclone_attribute (tree *node, tree name, |
1370 | tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
1371 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), bool *no_add_attrs) |
1372 | { |
1373 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) != FUNCTION_DECL) |
1374 | { |
1375 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1376 | *no_add_attrs = true; |
1377 | } |
1378 | |
1379 | return NULL_TREE(tree) nullptr; |
1380 | } |
1381 | |
1382 | /* Handle a "nocf_check" attribute; arguments as in |
1383 | struct attribute_spec.handler. */ |
1384 | |
1385 | static tree |
1386 | handle_nocf_check_attribute (tree *node, tree name, |
1387 | tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
1388 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), bool *no_add_attrs) |
1389 | { |
1390 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) != FUNCTION_TYPE |
1391 | && TREE_CODE (*node)((enum tree_code) (*node)->base.code) != METHOD_TYPE) |
1392 | { |
1393 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1394 | *no_add_attrs = true; |
1395 | } |
1396 | else if (!(flag_cf_protectionglobal_options.x_flag_cf_protection & CF_BRANCH)) |
1397 | { |
1398 | warning (OPT_Wattributes, "%qE attribute ignored. Use " |
1399 | "%<-fcf-protection%> option to enable it", |
1400 | name); |
1401 | *no_add_attrs = true; |
1402 | } |
1403 | |
1404 | return NULL_TREE(tree) nullptr; |
1405 | } |
1406 | |
1407 | /* Handle a "no_icf" attribute; arguments as in |
1408 | struct attribute_spec.handler. */ |
1409 | |
1410 | static tree |
1411 | handle_noicf_attribute (tree *node, tree name, |
1412 | tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
1413 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), bool *no_add_attrs) |
1414 | { |
1415 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) != FUNCTION_DECL) |
1416 | { |
1417 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1418 | *no_add_attrs = true; |
1419 | } |
1420 | |
1421 | return NULL_TREE(tree) nullptr; |
1422 | } |
1423 | |
1424 | |
1425 | /* Handle a "always_inline" attribute; arguments as in |
1426 | struct attribute_spec.handler. */ |
1427 | |
1428 | static tree |
1429 | handle_always_inline_attribute (tree *node, tree name, |
1430 | tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
1431 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), |
1432 | bool *no_add_attrs) |
1433 | { |
1434 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) == FUNCTION_DECL) |
1435 | { |
1436 | if (lookup_attribute ("noinline", DECL_ATTRIBUTES (*node)((contains_struct_check ((*node), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1436, __FUNCTION__))->decl_common.attributes))) |
1437 | { |
1438 | warning (OPT_Wattributes, "%qE attribute ignored due to conflict " |
1439 | "with %qs attribute", name, "noinline"); |
1440 | *no_add_attrs = true; |
1441 | } |
1442 | else if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (*node)((contains_struct_check ((*node), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1442, __FUNCTION__))->decl_common.attributes))) |
1443 | { |
1444 | warning (OPT_Wattributes, "%qE attribute ignored due to conflict " |
1445 | "with %qs attribute", name, "target_clones"); |
1446 | *no_add_attrs = true; |
1447 | } |
1448 | else |
1449 | /* Set the attribute and mark it for disregarding inline |
1450 | limits. */ |
1451 | DECL_DISREGARD_INLINE_LIMITS (*node)((tree_check ((*node), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1451, __FUNCTION__, (FUNCTION_DECL)))->function_decl.disregard_inline_limits ) = 1; |
1452 | } |
1453 | else |
1454 | { |
1455 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1456 | *no_add_attrs = true; |
1457 | } |
1458 | |
1459 | return NULL_TREE(tree) nullptr; |
1460 | } |
1461 | |
1462 | /* Handle a "gnu_inline" attribute; arguments as in |
1463 | struct attribute_spec.handler. */ |
1464 | |
1465 | static tree |
1466 | handle_gnu_inline_attribute (tree *node, tree name, |
1467 | tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
1468 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), |
1469 | bool *no_add_attrs) |
1470 | { |
1471 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (*node)((tree_check ((*node), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1471, __FUNCTION__, (FUNCTION_DECL)))->function_decl.declared_inline_flag )) |
1472 | { |
1473 | /* Do nothing else, just set the attribute. We'll get at |
1474 | it later with lookup_attribute. */ |
1475 | } |
1476 | else |
1477 | { |
1478 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1479 | *no_add_attrs = true; |
1480 | } |
1481 | |
1482 | return NULL_TREE(tree) nullptr; |
1483 | } |
1484 | |
1485 | /* Handle a "leaf" attribute; arguments as in |
1486 | struct attribute_spec.handler. */ |
1487 | |
1488 | static tree |
1489 | handle_leaf_attribute (tree *node, tree name, |
1490 | tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
1491 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), bool *no_add_attrs) |
1492 | { |
1493 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) != FUNCTION_DECL) |
1494 | { |
1495 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1496 | *no_add_attrs = true; |
1497 | } |
1498 | if (!TREE_PUBLIC (*node)((*node)->base.public_flag)) |
1499 | { |
1500 | warning (OPT_Wattributes, "%qE attribute has no effect on unit local " |
1501 | "functions", name); |
1502 | *no_add_attrs = true; |
1503 | } |
1504 | |
1505 | return NULL_TREE(tree) nullptr; |
1506 | } |
1507 | |
1508 | /* Handle an "artificial" attribute; arguments as in |
1509 | struct attribute_spec.handler. */ |
1510 | |
1511 | static tree |
1512 | handle_artificial_attribute (tree *node, tree name, |
1513 | tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
1514 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), |
1515 | bool *no_add_attrs) |
1516 | { |
1517 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (*node)((tree_check ((*node), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1517, __FUNCTION__, (FUNCTION_DECL)))->function_decl.declared_inline_flag )) |
1518 | { |
1519 | /* Do nothing else, just set the attribute. We'll get at |
1520 | it later with lookup_attribute. */ |
1521 | } |
1522 | else |
1523 | { |
1524 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1525 | *no_add_attrs = true; |
1526 | } |
1527 | |
1528 | return NULL_TREE(tree) nullptr; |
1529 | } |
1530 | |
1531 | /* Handle a "flatten" attribute; arguments as in |
1532 | struct attribute_spec.handler. */ |
1533 | |
1534 | static tree |
1535 | handle_flatten_attribute (tree *node, tree name, |
1536 | tree args ATTRIBUTE_UNUSED__attribute__ ((__unused__)), |
1537 | int flags ATTRIBUTE_UNUSED__attribute__ ((__unused__)), bool *no_add_attrs) |
1538 | { |
1539 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) == FUNCTION_DECL) |
1540 | /* Do nothing else, just set the attribute. We'll get at |
1541 | it later with lookup_attribute. */ |
1542 | ; |
1543 | else |
1544 | { |
1545 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1546 | *no_add_attrs = true; |
1547 | } |
1548 | |
1549 | return NULL_TREE(tree) nullptr; |
1550 | } |
1551 | |
1552 | /* Handle a "warning" or "error" attribute; arguments as in |
1553 | struct attribute_spec.handler. */ |
1554 | |
1555 | static tree |
1556 | handle_error_attribute (tree *node, tree name, tree args, |
1557 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), bool *no_add_attrs) |
1558 | { |
1559 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) == FUNCTION_DECL |
1560 | && TREE_CODE (TREE_VALUE (args))((enum tree_code) (((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1560, __FUNCTION__, (TREE_LIST)))->list.value))->base .code) == STRING_CST) |
1561 | /* Do nothing else, just set the attribute. We'll get at |
1562 | it later with lookup_attribute. */ |
1563 | ; |
1564 | else |
1565 | { |
1566 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1567 | *no_add_attrs = true; |
1568 | } |
1569 | |
1570 | return NULL_TREE(tree) nullptr; |
1571 | } |
1572 | |
1573 | /* Handle a "used" attribute; arguments as in |
1574 | struct attribute_spec.handler. */ |
1575 | |
1576 | static tree |
1577 | handle_used_attribute (tree *pnode, tree name, tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
1578 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), bool *no_add_attrs) |
1579 | { |
1580 | tree node = *pnode; |
1581 | |
1582 | if (TREE_CODE (node)((enum tree_code) (node)->base.code) == FUNCTION_DECL |
1583 | || (VAR_P (node)(((enum tree_code) (node)->base.code) == VAR_DECL) && TREE_STATIC (node)((node)->base.static_flag)) |
1584 | || (TREE_CODE (node)((enum tree_code) (node)->base.code) == TYPE_DECL)) |
1585 | { |
1586 | TREE_USED (node)((node)->base.used_flag) = 1; |
1587 | DECL_PRESERVE_P (node)(contains_struct_check ((node), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1587, __FUNCTION__))->decl_common.preserve_flag = 1; |
1588 | if (VAR_P (node)(((enum tree_code) (node)->base.code) == VAR_DECL)) |
1589 | DECL_READ_P (node)((tree_check2 ((node), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1589, __FUNCTION__, (VAR_DECL), (PARM_DECL)))->decl_common .decl_read_flag) = 1; |
1590 | } |
1591 | else |
1592 | { |
1593 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1594 | *no_add_attrs = true; |
1595 | } |
1596 | |
1597 | return NULL_TREE(tree) nullptr; |
1598 | } |
1599 | |
1600 | /* Handle a "unused" attribute; arguments as in |
1601 | struct attribute_spec.handler. */ |
1602 | |
1603 | tree |
1604 | handle_unused_attribute (tree *node, tree name, tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
1605 | int flags, bool *no_add_attrs) |
1606 | { |
1607 | if (DECL_P (*node)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (*node)->base.code))] == tcc_declaration)) |
1608 | { |
1609 | tree decl = *node; |
1610 | |
1611 | if (TREE_CODE (decl)((enum tree_code) (decl)->base.code) == PARM_DECL |
1612 | || VAR_OR_FUNCTION_DECL_P (decl)(((enum tree_code) (decl)->base.code) == VAR_DECL || ((enum tree_code) (decl)->base.code) == FUNCTION_DECL) |
1613 | || TREE_CODE (decl)((enum tree_code) (decl)->base.code) == LABEL_DECL |
1614 | || TREE_CODE (decl)((enum tree_code) (decl)->base.code) == CONST_DECL |
1615 | || TREE_CODE (decl)((enum tree_code) (decl)->base.code) == FIELD_DECL |
1616 | || TREE_CODE (decl)((enum tree_code) (decl)->base.code) == TYPE_DECL) |
1617 | { |
1618 | TREE_USED (decl)((decl)->base.used_flag) = 1; |
1619 | if (VAR_P (decl)(((enum tree_code) (decl)->base.code) == VAR_DECL) || TREE_CODE (decl)((enum tree_code) (decl)->base.code) == PARM_DECL) |
1620 | DECL_READ_P (decl)((tree_check2 ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1620, __FUNCTION__, (VAR_DECL), (PARM_DECL)))->decl_common .decl_read_flag) = 1; |
1621 | } |
1622 | else |
1623 | { |
1624 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1625 | *no_add_attrs = true; |
1626 | } |
1627 | } |
1628 | else |
1629 | { |
1630 | if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) |
1631 | *node = build_variant_type_copy (*node); |
1632 | TREE_USED (*node)((*node)->base.used_flag) = 1; |
1633 | } |
1634 | |
1635 | return NULL_TREE(tree) nullptr; |
1636 | } |
1637 | |
1638 | /* Handle a "retain" attribute; arguments as in |
1639 | struct attribute_spec.handler. */ |
1640 | |
1641 | static tree |
1642 | handle_retain_attribute (tree *pnode, tree name, tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
1643 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), bool *no_add_attrs) |
1644 | { |
1645 | tree node = *pnode; |
1646 | |
1647 | if (SUPPORTS_SHF_GNU_RETAIN1 |
1648 | && (TREE_CODE (node)((enum tree_code) (node)->base.code) == FUNCTION_DECL |
1649 | || (VAR_P (node)(((enum tree_code) (node)->base.code) == VAR_DECL) && TREE_STATIC (node)((node)->base.static_flag)))) |
1650 | ; |
1651 | else |
1652 | { |
1653 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1654 | *no_add_attrs = true; |
1655 | } |
1656 | |
1657 | return NULL_TREE(tree) nullptr; |
1658 | } |
1659 | |
1660 | /* Handle an "uninitialized" attribute; arguments as in |
1661 | struct attribute_spec.handler. */ |
1662 | |
1663 | static tree |
1664 | handle_uninitialized_attribute (tree *node, tree name, tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
1665 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), bool *no_add_attrs) |
1666 | { |
1667 | tree decl = *node; |
1668 | if (!VAR_P (decl)(((enum tree_code) (decl)->base.code) == VAR_DECL)) |
1669 | { |
1670 | warning (OPT_Wattributes, "%qE attribute ignored because %qD " |
1671 | "is not a variable", name, decl); |
1672 | *no_add_attrs = true; |
1673 | } |
1674 | else if (TREE_STATIC (decl)((decl)->base.static_flag) || DECL_EXTERNAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1674, __FUNCTION__))->decl_common.decl_flag_1)) |
1675 | { |
1676 | warning (OPT_Wattributes, "%qE attribute ignored because %qD " |
1677 | "is not a local variable", name, decl); |
1678 | *no_add_attrs = true; |
1679 | } |
1680 | |
1681 | return NULL_TREE(tree) nullptr; |
1682 | } |
1683 | |
1684 | /* Handle a "externally_visible" attribute; arguments as in |
1685 | struct attribute_spec.handler. */ |
1686 | |
1687 | static tree |
1688 | handle_externally_visible_attribute (tree *pnode, tree name, |
1689 | tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
1690 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), |
1691 | bool *no_add_attrs) |
1692 | { |
1693 | tree node = *pnode; |
1694 | |
1695 | if (VAR_OR_FUNCTION_DECL_P (node)(((enum tree_code) (node)->base.code) == VAR_DECL || ((enum tree_code) (node)->base.code) == FUNCTION_DECL)) |
1696 | { |
1697 | if ((!TREE_STATIC (node)((node)->base.static_flag) && TREE_CODE (node)((enum tree_code) (node)->base.code) != FUNCTION_DECL |
1698 | && !DECL_EXTERNAL (node)((contains_struct_check ((node), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1698, __FUNCTION__))->decl_common.decl_flag_1)) || !TREE_PUBLIC (node)((node)->base.public_flag)) |
1699 | { |
1700 | warning (OPT_Wattributes, |
1701 | "%qE attribute have effect only on public objects", name); |
1702 | *no_add_attrs = true; |
1703 | } |
1704 | } |
1705 | else |
1706 | { |
1707 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1708 | *no_add_attrs = true; |
1709 | } |
1710 | |
1711 | return NULL_TREE(tree) nullptr; |
1712 | } |
1713 | |
1714 | /* Handle the "no_reorder" attribute. Arguments as in |
1715 | struct attribute_spec.handler. */ |
1716 | |
1717 | static tree |
1718 | handle_no_reorder_attribute (tree *pnode, |
1719 | tree name, |
1720 | tree, |
1721 | int, |
1722 | bool *no_add_attrs) |
1723 | { |
1724 | tree node = *pnode; |
1725 | |
1726 | if (!VAR_OR_FUNCTION_DECL_P (node)(((enum tree_code) (node)->base.code) == VAR_DECL || ((enum tree_code) (node)->base.code) == FUNCTION_DECL) |
1727 | && !(TREE_STATIC (node)((node)->base.static_flag) || DECL_EXTERNAL (node)((contains_struct_check ((node), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1727, __FUNCTION__))->decl_common.decl_flag_1))) |
1728 | { |
1729 | warning (OPT_Wattributes, |
1730 | "%qE attribute only affects top level objects", |
1731 | name); |
1732 | *no_add_attrs = true; |
1733 | } |
1734 | |
1735 | return NULL_TREE(tree) nullptr; |
1736 | } |
1737 | |
1738 | /* Handle a "const" attribute; arguments as in |
1739 | struct attribute_spec.handler. */ |
1740 | |
1741 | static tree |
1742 | handle_const_attribute (tree *node, tree name, tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
1743 | int flags, bool *no_add_attrs) |
1744 | { |
1745 | tree type = TREE_TYPE (*node)((contains_struct_check ((*node), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1745, __FUNCTION__))->typed.type); |
1746 | |
1747 | /* See FIXME comment on noreturn in c_common_attribute_table. */ |
1748 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) == FUNCTION_DECL) |
1749 | TREE_READONLY (*node)((non_type_check ((*node), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1749, __FUNCTION__))->base.readonly_flag) = 1; |
1750 | else if (TREE_CODE (type)((enum tree_code) (type)->base.code) == POINTER_TYPE |
1751 | && TREE_CODE (TREE_TYPE (type))((enum tree_code) (((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1751, __FUNCTION__))->typed.type))->base.code) == FUNCTION_TYPE) |
1752 | TREE_TYPE (*node)((contains_struct_check ((*node), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1752, __FUNCTION__))->typed.type) |
1753 | = (build_qualified_type |
1754 | (build_pointer_type |
1755 | (build_type_variant (TREE_TYPE (type), 1,build_qualified_type ((((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1755, __FUNCTION__))->typed.type)), ((1) ? TYPE_QUAL_CONST : 0) | ((((((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1756, __FUNCTION__))->typed.type))->base.volatile_flag )) ? TYPE_QUAL_VOLATILE : 0)) |
1756 | TREE_THIS_VOLATILE (TREE_TYPE (type)))build_qualified_type ((((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1755, __FUNCTION__))->typed.type)), ((1) ? TYPE_QUAL_CONST : 0) | ((((((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1756, __FUNCTION__))->typed.type))->base.volatile_flag )) ? TYPE_QUAL_VOLATILE : 0))), |
1757 | TYPE_QUALS (type)((int) ((((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1757, __FUNCTION__))->base.readonly_flag) * TYPE_QUAL_CONST ) | (((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1757, __FUNCTION__))->base.volatile_flag) * TYPE_QUAL_VOLATILE ) | (((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1757, __FUNCTION__))->base.u.bits.atomic_flag) * TYPE_QUAL_ATOMIC ) | (((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1757, __FUNCTION__))->type_common.restrict_flag) * TYPE_QUAL_RESTRICT ) | (((((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1757, __FUNCTION__))->base.u.bits.address_space) & 0xFF ) << 8)))))); |
1758 | else |
1759 | { |
1760 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1761 | *no_add_attrs = true; |
1762 | } |
1763 | |
1764 | /* void __builtin_unreachable(void) is const. Accept other such |
1765 | built-ins but warn on user-defined functions that return void. */ |
1766 | if (!(flags & ATTR_FLAG_BUILT_IN) |
1767 | && TREE_CODE (*node)((enum tree_code) (*node)->base.code) == FUNCTION_DECL |
1768 | && VOID_TYPE_P (TREE_TYPE (type))(((enum tree_code) (((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1768, __FUNCTION__))->typed.type))->base.code) == VOID_TYPE )) |
1769 | warning (OPT_Wattributes, "%qE attribute on function " |
1770 | "returning %<void%>", name); |
1771 | |
1772 | return NULL_TREE(tree) nullptr; |
1773 | } |
1774 | |
1775 | /* Handle a "scalar_storage_order" attribute; arguments as in |
1776 | struct attribute_spec.handler. */ |
1777 | |
1778 | static tree |
1779 | handle_scalar_storage_order_attribute (tree *node, tree name, tree args, |
1780 | int flags, bool *no_add_attrs) |
1781 | { |
1782 | tree id = TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1782, __FUNCTION__, (TREE_LIST)))->list.value); |
1783 | tree type; |
1784 | |
1785 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) == TYPE_DECL |
1786 | && ! (flags & ATTR_FLAG_CXX11)) |
1787 | node = &TREE_TYPE (*node)((contains_struct_check ((*node), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1787, __FUNCTION__))->typed.type); |
1788 | type = *node; |
1789 | |
1790 | if (BYTES_BIG_ENDIAN0 != WORDS_BIG_ENDIAN0) |
1791 | { |
1792 | error ("%qE attribute is not supported because endianness is not uniform", |
1793 | name); |
1794 | return NULL_TREE(tree) nullptr; |
1795 | } |
1796 | |
1797 | if (RECORD_OR_UNION_TYPE_P (type)(((enum tree_code) (type)->base.code) == RECORD_TYPE || (( enum tree_code) (type)->base.code) == UNION_TYPE || ((enum tree_code) (type)->base.code) == QUAL_UNION_TYPE) && !c_dialect_cxx ()((c_language & clk_cxx) != 0)) |
1798 | { |
1799 | bool reverse = false; |
1800 | |
1801 | if (TREE_CODE (id)((enum tree_code) (id)->base.code) == STRING_CST |
1802 | && strcmp (TREE_STRING_POINTER (id)((const char *)((tree_check ((id), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1802, __FUNCTION__, (STRING_CST)))->string.str)), "big-endian") == 0) |
1803 | reverse = !BYTES_BIG_ENDIAN0; |
1804 | else if (TREE_CODE (id)((enum tree_code) (id)->base.code) == STRING_CST |
1805 | && strcmp (TREE_STRING_POINTER (id)((const char *)((tree_check ((id), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1805, __FUNCTION__, (STRING_CST)))->string.str)), "little-endian") == 0) |
1806 | reverse = BYTES_BIG_ENDIAN0; |
1807 | else |
1808 | { |
1809 | error ("attribute %qE argument must be one of %qs or %qs", |
1810 | name, "big-endian", "little-endian"); |
1811 | return NULL_TREE(tree) nullptr; |
1812 | } |
1813 | |
1814 | if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) |
1815 | { |
1816 | if (reverse) |
1817 | /* A type variant isn't good enough, since we don't want a cast |
1818 | to such a type to be removed as a no-op. */ |
1819 | *node = type = build_duplicate_type (type); |
1820 | } |
1821 | |
1822 | TYPE_REVERSE_STORAGE_ORDER (type)((tree_check4 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1822, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE ), (ARRAY_TYPE)))->base.u.bits.saturating_flag) = reverse; |
1823 | return NULL_TREE(tree) nullptr; |
1824 | } |
1825 | |
1826 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1827 | *no_add_attrs = true; |
1828 | return NULL_TREE(tree) nullptr; |
1829 | } |
1830 | |
1831 | /* Handle a "transparent_union" attribute; arguments as in |
1832 | struct attribute_spec.handler. */ |
1833 | |
1834 | static tree |
1835 | handle_transparent_union_attribute (tree *node, tree name, |
1836 | tree ARG_UNUSED (args)args __attribute__ ((__unused__)), int flags, |
1837 | bool *no_add_attrs) |
1838 | { |
1839 | tree type; |
1840 | |
1841 | *no_add_attrs = true; |
1842 | |
1843 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) == TYPE_DECL |
1844 | && ! (flags & ATTR_FLAG_CXX11)) |
1845 | node = &TREE_TYPE (*node)((contains_struct_check ((*node), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1845, __FUNCTION__))->typed.type); |
1846 | type = *node; |
1847 | |
1848 | if (TREE_CODE (type)((enum tree_code) (type)->base.code) == UNION_TYPE) |
1849 | { |
1850 | /* Make sure that the first field will work for a transparent union. |
1851 | If the type isn't complete yet, leave the check to the code in |
1852 | finish_struct. */ |
1853 | if (TYPE_SIZE (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1853, __FUNCTION__))->type_common.size)) |
1854 | { |
1855 | tree first = first_field (type); |
1856 | if (first == NULL_TREE(tree) nullptr |
1857 | || DECL_ARTIFICIAL (first)((contains_struct_check ((first), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1857, __FUNCTION__))->decl_common.artificial_flag) |
1858 | || TYPE_MODE (type)((((enum tree_code) ((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1858, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (type) : (type)->type_common.mode) != DECL_MODE (first)((contains_struct_check ((first), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1858, __FUNCTION__))->decl_common.mode)) |
1859 | goto ignored; |
1860 | } |
1861 | |
1862 | if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) |
1863 | { |
1864 | /* If the type isn't complete yet, setting the flag |
1865 | on a variant wouldn't ever be checked. */ |
1866 | if (!TYPE_SIZE (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1866, __FUNCTION__))->type_common.size)) |
1867 | goto ignored; |
1868 | |
1869 | /* build_duplicate_type doesn't work for C++. */ |
1870 | if (c_dialect_cxx ()((c_language & clk_cxx) != 0)) |
1871 | goto ignored; |
1872 | |
1873 | /* A type variant isn't good enough, since we don't want a cast |
1874 | to such a type to be removed as a no-op. */ |
1875 | *node = type = build_duplicate_type (type); |
1876 | } |
1877 | |
1878 | for (tree t = TYPE_MAIN_VARIANT (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1878, __FUNCTION__))->type_common.main_variant); t; t = TYPE_NEXT_VARIANT (t)((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1878, __FUNCTION__))->type_common.next_variant)) |
1879 | TYPE_TRANSPARENT_AGGR (t)((tree_check3 ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1879, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_common.transparent_aggr_flag) = 1; |
1880 | return NULL_TREE(tree) nullptr; |
1881 | } |
1882 | |
1883 | ignored: |
1884 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1885 | return NULL_TREE(tree) nullptr; |
1886 | } |
1887 | |
1888 | /* Subroutine of handle_{con,de}structor_attribute. Evaluate ARGS to |
1889 | get the requested priority for a constructor or destructor, |
1890 | possibly issuing diagnostics for invalid or reserved |
1891 | priorities. */ |
1892 | |
1893 | static priority_type |
1894 | get_priority (tree args, bool is_destructor) |
1895 | { |
1896 | HOST_WIDE_INTlong pri; |
1897 | tree arg; |
1898 | |
1899 | if (!args) |
1900 | return DEFAULT_INIT_PRIORITY65535; |
1901 | |
1902 | if (!SUPPORTS_INIT_PRIORITY1) |
1903 | { |
1904 | if (is_destructor) |
1905 | error ("destructor priorities are not supported"); |
1906 | else |
1907 | error ("constructor priorities are not supported"); |
1908 | return DEFAULT_INIT_PRIORITY65535; |
1909 | } |
1910 | |
1911 | arg = TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1911, __FUNCTION__, (TREE_LIST)))->list.value); |
1912 | if (TREE_CODE (arg)((enum tree_code) (arg)->base.code) == IDENTIFIER_NODE || TREE_CODE (arg)((enum tree_code) (arg)->base.code) == FUNCTION_DECL) |
1913 | goto invalid; |
1914 | if (arg == error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
1915 | return DEFAULT_INIT_PRIORITY65535; |
1916 | arg = default_conversion (arg); |
1917 | if (!tree_fits_shwi_p (arg) |
1918 | || !INTEGRAL_TYPE_P (TREE_TYPE (arg))(((enum tree_code) (((contains_struct_check ((arg), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1918, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE || ((enum tree_code) (((contains_struct_check ((arg), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1918, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE || ((enum tree_code) (((contains_struct_check ((arg), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1918, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE )) |
1919 | goto invalid; |
1920 | |
1921 | pri = tree_to_shwi (arg); |
1922 | if (pri < 0 || pri > MAX_INIT_PRIORITY65535) |
1923 | goto invalid; |
1924 | |
1925 | if (pri <= MAX_RESERVED_INIT_PRIORITY100) |
1926 | { |
1927 | if (is_destructor) |
1928 | warning (OPT_Wprio_ctor_dtor, |
1929 | "destructor priorities from 0 to %d are reserved " |
1930 | "for the implementation", |
1931 | MAX_RESERVED_INIT_PRIORITY100); |
1932 | else |
1933 | warning (OPT_Wprio_ctor_dtor, |
1934 | "constructor priorities from 0 to %d are reserved " |
1935 | "for the implementation", |
1936 | MAX_RESERVED_INIT_PRIORITY100); |
1937 | } |
1938 | return pri; |
1939 | |
1940 | invalid: |
1941 | if (is_destructor) |
1942 | error ("destructor priorities must be integers from 0 to %d inclusive", |
1943 | MAX_INIT_PRIORITY65535); |
1944 | else |
1945 | error ("constructor priorities must be integers from 0 to %d inclusive", |
1946 | MAX_INIT_PRIORITY65535); |
1947 | return DEFAULT_INIT_PRIORITY65535; |
1948 | } |
1949 | |
1950 | /* Handle a "constructor" attribute; arguments as in |
1951 | struct attribute_spec.handler. */ |
1952 | |
1953 | static tree |
1954 | handle_constructor_attribute (tree *node, tree name, tree args, |
1955 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), |
1956 | bool *no_add_attrs) |
1957 | { |
1958 | tree decl = *node; |
1959 | tree type = TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1959, __FUNCTION__))->typed.type); |
1960 | |
1961 | if (TREE_CODE (decl)((enum tree_code) (decl)->base.code) == FUNCTION_DECL |
1962 | && TREE_CODE (type)((enum tree_code) (type)->base.code) == FUNCTION_TYPE |
1963 | && decl_function_context (decl) == 0) |
1964 | { |
1965 | priority_type priority; |
1966 | DECL_STATIC_CONSTRUCTOR (decl)((tree_check ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1966, __FUNCTION__, (FUNCTION_DECL)))->function_decl.static_ctor_flag ) = 1; |
1967 | priority = get_priority (args, /*is_destructor=*/false); |
1968 | SET_DECL_INIT_PRIORITY (decl, priority)(decl_init_priority_insert (decl, priority)); |
1969 | TREE_USED (decl)((decl)->base.used_flag) = 1; |
1970 | } |
1971 | else |
1972 | { |
1973 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
1974 | *no_add_attrs = true; |
1975 | } |
1976 | |
1977 | return NULL_TREE(tree) nullptr; |
1978 | } |
1979 | |
1980 | /* Handle a "destructor" attribute; arguments as in |
1981 | struct attribute_spec.handler. */ |
1982 | |
1983 | static tree |
1984 | handle_destructor_attribute (tree *node, tree name, tree args, |
1985 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), |
1986 | bool *no_add_attrs) |
1987 | { |
1988 | tree decl = *node; |
1989 | tree type = TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1989, __FUNCTION__))->typed.type); |
1990 | |
1991 | if (TREE_CODE (decl)((enum tree_code) (decl)->base.code) == FUNCTION_DECL |
1992 | && TREE_CODE (type)((enum tree_code) (type)->base.code) == FUNCTION_TYPE |
1993 | && decl_function_context (decl) == 0) |
1994 | { |
1995 | priority_type priority; |
1996 | DECL_STATIC_DESTRUCTOR (decl)((tree_check ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 1996, __FUNCTION__, (FUNCTION_DECL)))->function_decl.static_dtor_flag ) = 1; |
1997 | priority = get_priority (args, /*is_destructor=*/true); |
1998 | SET_DECL_FINI_PRIORITY (decl, priority)(decl_fini_priority_insert (decl, priority)); |
1999 | TREE_USED (decl)((decl)->base.used_flag) = 1; |
2000 | } |
2001 | else |
2002 | { |
2003 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
2004 | *no_add_attrs = true; |
2005 | } |
2006 | |
2007 | return NULL_TREE(tree) nullptr; |
2008 | } |
2009 | |
2010 | /* Nonzero if the mode is a valid vector mode for this architecture. |
2011 | This returns nonzero even if there is no hardware support for the |
2012 | vector mode, but we can emulate with narrower modes. */ |
2013 | |
2014 | static bool |
2015 | vector_mode_valid_p (machine_mode mode) |
2016 | { |
2017 | enum mode_class mclass = GET_MODE_CLASS (mode)((enum mode_class) mode_class[mode]); |
2018 | |
2019 | /* Doh! What's going on? */ |
2020 | if (mclass != MODE_VECTOR_INT |
2021 | && mclass != MODE_VECTOR_FLOAT |
2022 | && mclass != MODE_VECTOR_FRACT |
2023 | && mclass != MODE_VECTOR_UFRACT |
2024 | && mclass != MODE_VECTOR_ACCUM |
2025 | && mclass != MODE_VECTOR_UACCUM) |
2026 | return false; |
2027 | |
2028 | /* Hardware support. Woo hoo! */ |
2029 | if (targetm.vector_mode_supported_p (mode)) |
2030 | return true; |
2031 | |
2032 | /* We should probably return 1 if requesting V4DI and we have no DI, |
2033 | but we have V2DI, but this is probably very unlikely. */ |
2034 | |
2035 | /* If we have support for the inner mode, we can safely emulate it. |
2036 | We may not have V2DI, but me can emulate with a pair of DIs. */ |
2037 | return targetm.scalar_mode_supported_p (GET_MODE_INNER (mode)(mode_to_inner (mode))); |
2038 | } |
2039 | |
2040 | |
2041 | /* Handle a "mode" attribute; arguments as in |
2042 | struct attribute_spec.handler. */ |
2043 | |
2044 | static tree |
2045 | handle_mode_attribute (tree *node, tree name, tree args, |
2046 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), bool *no_add_attrs) |
2047 | { |
2048 | tree type = *node; |
2049 | tree ident = TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2049, __FUNCTION__, (TREE_LIST)))->list.value); |
2050 | |
2051 | *no_add_attrs = true; |
2052 | |
2053 | if (TREE_CODE (ident)((enum tree_code) (ident)->base.code) != IDENTIFIER_NODE) |
2054 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
2055 | else |
2056 | { |
2057 | int j; |
2058 | const char *p = IDENTIFIER_POINTER (ident)((const char *) (tree_check ((ident), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2058, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ); |
2059 | int len = strlen (p); |
2060 | machine_mode mode = VOIDmode((void) 0, E_VOIDmode); |
2061 | tree typefm; |
2062 | bool valid_mode; |
2063 | |
2064 | if (len > 4 && p[0] == '_' && p[1] == '_' |
2065 | && p[len - 1] == '_' && p[len - 2] == '_') |
2066 | { |
2067 | char *newp = (char *) alloca (len - 1)__builtin_alloca(len - 1); |
2068 | |
2069 | strcpy (newp, &p[2]); |
2070 | newp[len - 4] = '\0'; |
2071 | p = newp; |
2072 | } |
2073 | |
2074 | /* Change this type to have a type with the specified mode. |
2075 | First check for the special modes. */ |
2076 | if (!strcmp (p, "byte")) |
2077 | mode = byte_mode; |
2078 | else if (!strcmp (p, "word")) |
2079 | mode = word_mode; |
2080 | else if (!strcmp (p, "pointer")) |
2081 | mode = ptr_mode; |
2082 | else if (!strcmp (p, "libgcc_cmp_return")) |
2083 | mode = targetm.libgcc_cmp_return_mode (); |
2084 | else if (!strcmp (p, "libgcc_shift_count")) |
2085 | mode = targetm.libgcc_shift_count_mode (); |
2086 | else if (!strcmp (p, "unwind_word")) |
2087 | mode = targetm.unwind_word_mode (); |
2088 | else |
2089 | for (j = 0; j < NUM_MACHINE_MODES; j++) |
2090 | if (!strcmp (p, GET_MODE_NAME (j)mode_name[j])) |
2091 | { |
2092 | mode = (machine_mode) j; |
2093 | break; |
2094 | } |
2095 | |
2096 | if (mode == VOIDmode((void) 0, E_VOIDmode)) |
2097 | { |
2098 | error ("unknown machine mode %qE", ident); |
2099 | return NULL_TREE(tree) nullptr; |
2100 | } |
2101 | |
2102 | /* Allow the target a chance to translate MODE into something supported. |
2103 | See PR86324. */ |
2104 | mode = targetm.translate_mode_attribute (mode); |
2105 | |
2106 | valid_mode = false; |
2107 | switch (GET_MODE_CLASS (mode)((enum mode_class) mode_class[mode])) |
2108 | { |
2109 | case MODE_INT: |
2110 | case MODE_PARTIAL_INT: |
2111 | case MODE_FLOAT: |
2112 | case MODE_DECIMAL_FLOAT: |
2113 | case MODE_FRACT: |
2114 | case MODE_UFRACT: |
2115 | case MODE_ACCUM: |
2116 | case MODE_UACCUM: |
2117 | valid_mode |
2118 | = targetm.scalar_mode_supported_p (as_a <scalar_mode> (mode)); |
2119 | break; |
2120 | |
2121 | case MODE_COMPLEX_INT: |
2122 | case MODE_COMPLEX_FLOAT: |
2123 | valid_mode = targetm.scalar_mode_supported_p (GET_MODE_INNER (mode)(mode_to_inner (mode))); |
2124 | break; |
2125 | |
2126 | case MODE_VECTOR_INT: |
2127 | case MODE_VECTOR_FLOAT: |
2128 | case MODE_VECTOR_FRACT: |
2129 | case MODE_VECTOR_UFRACT: |
2130 | case MODE_VECTOR_ACCUM: |
2131 | case MODE_VECTOR_UACCUM: |
2132 | warning (OPT_Wattributes, "specifying vector types with " |
2133 | "%<__attribute__ ((mode))%> is deprecated"); |
2134 | inform (input_location, |
2135 | "use %<__attribute__ ((vector_size))%> instead"); |
2136 | valid_mode = vector_mode_valid_p (mode); |
2137 | break; |
2138 | |
2139 | default: |
2140 | break; |
2141 | } |
2142 | if (!valid_mode) |
2143 | { |
2144 | error ("unable to emulate %qs", p); |
2145 | return NULL_TREE(tree) nullptr; |
2146 | } |
2147 | |
2148 | if (POINTER_TYPE_P (type)(((enum tree_code) (type)->base.code) == POINTER_TYPE || ( (enum tree_code) (type)->base.code) == REFERENCE_TYPE)) |
2149 | { |
2150 | scalar_int_mode addr_mode; |
2151 | addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (type))((tree_class_check ((((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2151, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2151, __FUNCTION__))->base.u.bits.address_space); |
2152 | tree (*fn)(tree, machine_mode, bool); |
2153 | |
2154 | if (!is_a <scalar_int_mode> (mode, &addr_mode) |
2155 | || !targetm.addr_space.valid_pointer_mode (addr_mode, as)) |
2156 | { |
2157 | error ("invalid pointer mode %qs", p); |
2158 | return NULL_TREE(tree) nullptr; |
2159 | } |
2160 | |
2161 | if (TREE_CODE (type)((enum tree_code) (type)->base.code) == POINTER_TYPE) |
2162 | fn = build_pointer_type_for_mode; |
2163 | else |
2164 | fn = build_reference_type_for_mode; |
2165 | typefm = fn (TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2165, __FUNCTION__))->typed.type), addr_mode, false); |
2166 | } |
2167 | else |
2168 | { |
2169 | /* For fixed-point modes, we need to test if the signness of type |
2170 | and the machine mode are consistent. */ |
2171 | if (ALL_FIXED_POINT_MODE_P (mode)(((((enum mode_class) mode_class[mode]) == MODE_FRACT || ((enum mode_class) mode_class[mode]) == MODE_VECTOR_FRACT) || (((enum mode_class) mode_class[mode]) == MODE_ACCUM || ((enum mode_class ) mode_class[mode]) == MODE_VECTOR_ACCUM)) || ((((enum mode_class ) mode_class[mode]) == MODE_UFRACT || ((enum mode_class) mode_class [mode]) == MODE_VECTOR_UFRACT) || (((enum mode_class) mode_class [mode]) == MODE_UACCUM || ((enum mode_class) mode_class[mode] ) == MODE_VECTOR_UACCUM))) |
2172 | && TYPE_UNSIGNED (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2172, __FUNCTION__))->base.u.bits.unsigned_flag) != UNSIGNED_FIXED_POINT_MODE_P (mode)((((enum mode_class) mode_class[mode]) == MODE_UFRACT || ((enum mode_class) mode_class[mode]) == MODE_VECTOR_UFRACT) || (((enum mode_class) mode_class[mode]) == MODE_UACCUM || ((enum mode_class ) mode_class[mode]) == MODE_VECTOR_UACCUM))) |
2173 | { |
2174 | error ("signedness of type and machine mode %qs don%'t match", p); |
2175 | return NULL_TREE(tree) nullptr; |
2176 | } |
2177 | /* For fixed-point modes, we need to pass saturating info. */ |
2178 | typefm = lang_hooks.types.type_for_mode (mode, |
2179 | ALL_FIXED_POINT_MODE_P (mode)(((((enum mode_class) mode_class[mode]) == MODE_FRACT || ((enum mode_class) mode_class[mode]) == MODE_VECTOR_FRACT) || (((enum mode_class) mode_class[mode]) == MODE_ACCUM || ((enum mode_class ) mode_class[mode]) == MODE_VECTOR_ACCUM)) || ((((enum mode_class ) mode_class[mode]) == MODE_UFRACT || ((enum mode_class) mode_class [mode]) == MODE_VECTOR_UFRACT) || (((enum mode_class) mode_class [mode]) == MODE_UACCUM || ((enum mode_class) mode_class[mode] ) == MODE_VECTOR_UACCUM))) ? TYPE_SATURATING (type)((tree_not_check4 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2179, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE ), (ARRAY_TYPE)))->base.u.bits.saturating_flag) |
2180 | : TYPE_UNSIGNED (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2180, __FUNCTION__))->base.u.bits.unsigned_flag)); |
2181 | } |
2182 | |
2183 | if (typefm == NULL_TREE(tree) nullptr) |
2184 | { |
2185 | error ("no data type for mode %qs", p); |
2186 | return NULL_TREE(tree) nullptr; |
2187 | } |
2188 | else if (TREE_CODE (type)((enum tree_code) (type)->base.code) == ENUMERAL_TYPE) |
2189 | { |
2190 | /* For enumeral types, copy the precision from the integer |
2191 | type returned above. If not an INTEGER_TYPE, we can't use |
2192 | this mode for this type. */ |
2193 | if (TREE_CODE (typefm)((enum tree_code) (typefm)->base.code) != INTEGER_TYPE) |
2194 | { |
2195 | error ("cannot use mode %qs for enumerated types", p); |
2196 | return NULL_TREE(tree) nullptr; |
2197 | } |
2198 | |
2199 | if (flags & ATTR_FLAG_TYPE_IN_PLACE) |
2200 | { |
2201 | TYPE_PRECISION (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2201, __FUNCTION__))->type_common.precision) = TYPE_PRECISION (typefm)((tree_class_check ((typefm), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2201, __FUNCTION__))->type_common.precision); |
2202 | typefm = type; |
2203 | } |
2204 | else |
2205 | { |
2206 | /* We cannot build a type variant, as there's code that assumes |
2207 | that TYPE_MAIN_VARIANT has the same mode. This includes the |
2208 | debug generators. Instead, create a subrange type. This |
2209 | results in all of the enumeral values being emitted only once |
2210 | in the original, and the subtype gets them by reference. */ |
2211 | if (TYPE_UNSIGNED (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2211, __FUNCTION__))->base.u.bits.unsigned_flag)) |
2212 | typefm = make_unsigned_type (TYPE_PRECISION (typefm)((tree_class_check ((typefm), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2212, __FUNCTION__))->type_common.precision)); |
2213 | else |
2214 | typefm = make_signed_type (TYPE_PRECISION (typefm)((tree_class_check ((typefm), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2214, __FUNCTION__))->type_common.precision)); |
2215 | TREE_TYPE (typefm)((contains_struct_check ((typefm), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2215, __FUNCTION__))->typed.type) = type; |
2216 | } |
2217 | *no_add_attrs = false; |
2218 | } |
2219 | else if (VECTOR_MODE_P (mode)(((enum mode_class) mode_class[mode]) == MODE_VECTOR_BOOL || ( (enum mode_class) mode_class[mode]) == MODE_VECTOR_INT || ((enum mode_class) mode_class[mode]) == MODE_VECTOR_FLOAT || ((enum mode_class) mode_class[mode]) == MODE_VECTOR_FRACT || ((enum mode_class) mode_class[mode]) == MODE_VECTOR_UFRACT || ((enum mode_class) mode_class[mode]) == MODE_VECTOR_ACCUM || ((enum mode_class) mode_class[mode]) == MODE_VECTOR_UACCUM) |
2220 | ? TREE_CODE (type)((enum tree_code) (type)->base.code) != TREE_CODE (TREE_TYPE (typefm))((enum tree_code) (((contains_struct_check ((typefm), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2220, __FUNCTION__))->typed.type))->base.code) |
2221 | : TREE_CODE (type)((enum tree_code) (type)->base.code) != TREE_CODE (typefm)((enum tree_code) (typefm)->base.code)) |
2222 | { |
2223 | error ("mode %qs applied to inappropriate type", p); |
2224 | return NULL_TREE(tree) nullptr; |
2225 | } |
2226 | |
2227 | /* Copy any quals and attributes to the new type. */ |
2228 | *node = build_type_attribute_qual_variant (typefm, TYPE_ATTRIBUTES (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2228, __FUNCTION__))->type_common.attributes), |
2229 | TYPE_QUALS (type)((int) ((((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2229, __FUNCTION__))->base.readonly_flag) * TYPE_QUAL_CONST ) | (((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2229, __FUNCTION__))->base.volatile_flag) * TYPE_QUAL_VOLATILE ) | (((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2229, __FUNCTION__))->base.u.bits.atomic_flag) * TYPE_QUAL_ATOMIC ) | (((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2229, __FUNCTION__))->type_common.restrict_flag) * TYPE_QUAL_RESTRICT ) | (((((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2229, __FUNCTION__))->base.u.bits.address_space) & 0xFF ) << 8))))); |
2230 | if (TYPE_USER_ALIGN (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2230, __FUNCTION__))->base.u.bits.user_align)) |
2231 | *node = build_aligned_type (*node, TYPE_ALIGN (type)(((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2231, __FUNCTION__))->type_common.align) ? ((unsigned)1) << (((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2231, __FUNCTION__))->type_common.align) - 1) : 0)); |
2232 | } |
2233 | |
2234 | return NULL_TREE(tree) nullptr; |
2235 | } |
2236 | |
2237 | /* Handle a "section" attribute; arguments as in |
2238 | struct attribute_spec.handler. */ |
2239 | |
2240 | static tree |
2241 | handle_section_attribute (tree *node, tree name, tree args, |
2242 | int flags, bool *no_add_attrs) |
2243 | { |
2244 | tree decl = *node; |
2245 | tree res = NULL_TREE(tree) nullptr; |
2246 | tree argval = TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2246, __FUNCTION__, (TREE_LIST)))->list.value); |
2247 | const char* new_section_name; |
2248 | |
2249 | if (!targetm_common.have_named_sections) |
2250 | { |
2251 | error_at (DECL_SOURCE_LOCATION (*node)((contains_struct_check ((*node), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2251, __FUNCTION__))->decl_minimal.locus), |
2252 | "section attributes are not supported for this target"); |
2253 | goto fail; |
2254 | } |
2255 | |
2256 | if (!VAR_OR_FUNCTION_DECL_P (decl)(((enum tree_code) (decl)->base.code) == VAR_DECL || ((enum tree_code) (decl)->base.code) == FUNCTION_DECL)) |
2257 | { |
2258 | error ("section attribute not allowed for %q+D", *node); |
2259 | goto fail; |
2260 | } |
2261 | |
2262 | if (TREE_CODE (argval)((enum tree_code) (argval)->base.code) != STRING_CST) |
2263 | { |
2264 | error ("section attribute argument not a string constant"); |
2265 | goto fail; |
2266 | } |
2267 | |
2268 | if (VAR_P (decl)(((enum tree_code) (decl)->base.code) == VAR_DECL) |
2269 | && current_function_decl != NULL_TREE(tree) nullptr |
2270 | && !TREE_STATIC (decl)((decl)->base.static_flag)) |
2271 | { |
2272 | error_at (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2272, __FUNCTION__))->decl_minimal.locus), |
2273 | "section attribute cannot be specified for local variables"); |
2274 | goto fail; |
2275 | } |
2276 | |
2277 | new_section_name = TREE_STRING_POINTER (argval)((const char *)((tree_check ((argval), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2277, __FUNCTION__, (STRING_CST)))->string.str)); |
2278 | |
2279 | /* The decl may have already been given a section attribute |
2280 | from a previous declaration. Ensure they match. */ |
2281 | if (const char* const old_section_name = DECL_SECTION_NAME (decl)decl_section_name (decl)) |
2282 | if (strcmp (old_section_name, new_section_name) != 0) |
2283 | { |
2284 | error ("section of %q+D conflicts with previous declaration", |
2285 | *node); |
2286 | goto fail; |
2287 | } |
2288 | |
2289 | if (VAR_P (decl)(((enum tree_code) (decl)->base.code) == VAR_DECL) |
2290 | && !targetm.have_tls && targetm.emutls.tmpl_section |
2291 | && DECL_THREAD_LOCAL_P (decl)((((decl)->base.static_flag) || ((contains_struct_check (( decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2291, __FUNCTION__))->decl_common.decl_flag_1)) && decl_tls_model (decl) >= TLS_MODEL_REAL)) |
2292 | { |
2293 | error ("section of %q+D cannot be overridden", *node); |
2294 | goto fail; |
2295 | } |
2296 | |
2297 | if (!validate_attr_arg (node, name, argval)) |
2298 | goto fail; |
2299 | |
2300 | res = targetm.handle_generic_attribute (node, name, args, flags, |
2301 | no_add_attrs); |
2302 | |
2303 | /* If the back end confirms the attribute can be added then continue onto |
2304 | final processing. */ |
2305 | if (!(*no_add_attrs)) |
2306 | { |
2307 | set_decl_section_name (decl, new_section_name); |
2308 | return res; |
2309 | } |
2310 | |
2311 | fail: |
2312 | *no_add_attrs = true; |
2313 | return res; |
2314 | } |
2315 | |
2316 | /* Common codes shared by handle_warn_if_not_aligned_attribute and |
2317 | handle_aligned_attribute. */ |
2318 | |
2319 | static tree |
2320 | common_handle_aligned_attribute (tree *node, tree name, tree args, int flags, |
2321 | bool *no_add_attrs, |
2322 | bool warn_if_not_aligned_p) |
2323 | { |
2324 | tree decl = NULL_TREE(tree) nullptr; |
2325 | tree *type = NULLnullptr; |
2326 | bool is_type = false; |
2327 | tree align_expr; |
2328 | |
2329 | /* The last (already pushed) declaration with all validated attributes |
2330 | merged in or the current about-to-be-pushed one if one hasn't been |
2331 | yet. */ |
2332 | tree last_decl = node[1] ? node[1] : *node; |
2333 | |
2334 | if (args) |
2335 | { |
2336 | align_expr = TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2336, __FUNCTION__, (TREE_LIST)))->list.value); |
2337 | if (align_expr && TREE_CODE (align_expr)((enum tree_code) (align_expr)->base.code) != IDENTIFIER_NODE |
2338 | && TREE_CODE (align_expr)((enum tree_code) (align_expr)->base.code) != FUNCTION_DECL) |
2339 | align_expr = default_conversion (align_expr); |
2340 | } |
2341 | else |
2342 | align_expr = size_int (ATTRIBUTE_ALIGNED_VALUE / BITS_PER_UNIT)size_int_kind ((((global_options.x_target_flags & (1U << 12)) != 0) ? 32 : 128) / (8), stk_sizetype); |
2343 | |
2344 | if (DECL_P (*node)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (*node)->base.code))] == tcc_declaration)) |
2345 | { |
2346 | decl = *node; |
2347 | type = &TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2347, __FUNCTION__))->typed.type); |
2348 | is_type = TREE_CODE (*node)((enum tree_code) (*node)->base.code) == TYPE_DECL; |
2349 | } |
2350 | else if (TYPE_P (*node)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (*node)->base.code))] == tcc_type)) |
2351 | type = node, is_type = true; |
2352 | |
2353 | /* True to consider invalid alignments greater than MAX_OFILE_ALIGNMENT. */ |
2354 | bool objfile = (TREE_CODE (*node)((enum tree_code) (*node)->base.code) == FUNCTION_DECL |
2355 | || (VAR_P (*node)(((enum tree_code) (*node)->base.code) == VAR_DECL) && TREE_STATIC (*node)((*node)->base.static_flag))); |
2356 | /* Log2 of specified alignment. */ |
2357 | int pow2align = check_user_alignment (align_expr, objfile, |
2358 | /* warn_zero = */ true); |
2359 | if (pow2align == -1) |
2360 | { |
2361 | *no_add_attrs = true; |
2362 | return NULL_TREE(tree) nullptr; |
2363 | } |
2364 | |
2365 | /* The alignment in bits corresponding to the specified alignment. */ |
2366 | unsigned bitalign = (1U << pow2align) * BITS_PER_UNIT(8); |
2367 | |
2368 | /* The alignment of the current declaration and that of the last |
2369 | pushed declaration, determined on demand below. */ |
2370 | unsigned curalign = 0; |
2371 | unsigned lastalign = 0; |
2372 | |
2373 | /* True when SET_DECL_ALIGN() should be called for the decl when |
2374 | *NO_ADD_ATTRS is false. */ |
2375 | bool set_align = true; |
2376 | if (is_type) |
2377 | { |
2378 | if ((flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) |
2379 | /* OK, modify the type in place. */; |
2380 | /* If we have a TYPE_DECL, then copy the type, so that we |
2381 | don't accidentally modify a builtin type. See pushdecl. */ |
2382 | else if (decl && TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2382, __FUNCTION__))->typed.type) != error_mark_nodeglobal_trees[TI_ERROR_MARK] |
2383 | && DECL_ORIGINAL_TYPE (decl)((tree_check ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2383, __FUNCTION__, (TYPE_DECL)))->decl_non_common.result ) == NULL_TREE(tree) nullptr) |
2384 | { |
2385 | tree tt = TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2385, __FUNCTION__))->typed.type); |
2386 | *type = build_variant_type_copy (*type); |
2387 | DECL_ORIGINAL_TYPE (decl)((tree_check ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2387, __FUNCTION__, (TYPE_DECL)))->decl_non_common.result ) = tt; |
2388 | TYPE_NAME (*type)((tree_class_check ((*type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2388, __FUNCTION__))->type_common.name) = decl; |
2389 | TREE_USED (*type)((*type)->base.used_flag) = TREE_USED (decl)((decl)->base.used_flag); |
2390 | TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2390, __FUNCTION__))->typed.type) = *type; |
2391 | } |
2392 | else |
2393 | *type = build_variant_type_copy (*type); |
2394 | |
2395 | if (warn_if_not_aligned_p) |
2396 | { |
2397 | SET_TYPE_WARN_IF_NOT_ALIGN (*type, bitalign)((tree_class_check ((*type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2397, __FUNCTION__))->type_common.warn_if_not_align = ffs_hwi (bitalign)); |
2398 | warn_if_not_aligned_p = false; |
2399 | } |
2400 | else |
2401 | { |
2402 | SET_TYPE_ALIGN (*type, bitalign)((tree_class_check ((*type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2402, __FUNCTION__))->type_common.align = ffs_hwi (bitalign )); |
2403 | TYPE_USER_ALIGN (*type)((tree_class_check ((*type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2403, __FUNCTION__))->base.u.bits.user_align) = 1; |
2404 | } |
2405 | } |
2406 | else if (! VAR_OR_FUNCTION_DECL_P (decl)(((enum tree_code) (decl)->base.code) == VAR_DECL || ((enum tree_code) (decl)->base.code) == FUNCTION_DECL) |
2407 | && TREE_CODE (decl)((enum tree_code) (decl)->base.code) != FIELD_DECL) |
2408 | { |
2409 | error ("alignment may not be specified for %q+D", decl); |
2410 | *no_add_attrs = true; |
2411 | } |
2412 | else if (TREE_CODE (decl)((enum tree_code) (decl)->base.code) == FUNCTION_DECL |
2413 | && (((curalign = DECL_ALIGN (decl)(((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2413, __FUNCTION__))->decl_common.align) ? ((unsigned)1) << (((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2413, __FUNCTION__))->decl_common.align) - 1) : 0)) > bitalign) |
2414 | | ((lastalign = DECL_ALIGN (last_decl)(((contains_struct_check ((last_decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2414, __FUNCTION__))->decl_common.align) ? ((unsigned)1) << (((contains_struct_check ((last_decl), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2414, __FUNCTION__))->decl_common.align) - 1) : 0)) > bitalign))) |
2415 | { |
2416 | /* Either a prior attribute on the same declaration or one |
2417 | on a prior declaration of the same function specifies |
2418 | stricter alignment than this attribute. */ |
2419 | bool note = (lastalign > curalign |
2420 | || (lastalign == curalign |
2421 | && (DECL_USER_ALIGN (last_decl)((contains_struct_check ((last_decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2421, __FUNCTION__))->base.u.bits.user_align) |
2422 | > DECL_USER_ALIGN (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2422, __FUNCTION__))->base.u.bits.user_align)))); |
2423 | if (note) |
2424 | curalign = lastalign; |
2425 | |
2426 | curalign /= BITS_PER_UNIT(8); |
2427 | unsigned newalign = bitalign / BITS_PER_UNIT(8); |
2428 | |
2429 | auto_diagnostic_group d; |
2430 | if ((DECL_USER_ALIGN (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2430, __FUNCTION__))->base.u.bits.user_align) |
2431 | || DECL_USER_ALIGN (last_decl)((contains_struct_check ((last_decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2431, __FUNCTION__))->base.u.bits.user_align))) |
2432 | { |
2433 | if (warning (OPT_Wattributes, |
2434 | "ignoring attribute %<%E (%u)%> because it conflicts " |
2435 | "with attribute %<%E (%u)%>", |
2436 | name, newalign, name, curalign) |
2437 | && note) |
2438 | inform (DECL_SOURCE_LOCATION (last_decl)((contains_struct_check ((last_decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2438, __FUNCTION__))->decl_minimal.locus), |
2439 | "previous declaration here"); |
2440 | /* Only reject attempts to relax/override an alignment |
2441 | explicitly specified previously and accept declarations |
2442 | that appear to relax the implicit function alignment for |
2443 | the target. Both increasing and increasing the alignment |
2444 | set by -falign-functions setting is permitted. */ |
2445 | *no_add_attrs = true; |
2446 | } |
2447 | else if (!warn_if_not_aligned_p) |
2448 | { |
2449 | /* Do not fail for attribute warn_if_not_aligned. Otherwise, |
2450 | silently avoid applying the alignment to the declaration |
2451 | because it's implicitly satisfied by the target. Apply |
2452 | the attribute nevertheless so it can be retrieved by |
2453 | __builtin_has_attribute. */ |
2454 | set_align = false; |
2455 | } |
2456 | } |
2457 | else if (DECL_USER_ALIGN (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2457, __FUNCTION__))->base.u.bits.user_align) |
2458 | && DECL_ALIGN (decl)(((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2458, __FUNCTION__))->decl_common.align) ? ((unsigned)1) << (((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2458, __FUNCTION__))->decl_common.align) - 1) : 0) > bitalign) |
2459 | /* C++-11 [dcl.align/4]: |
2460 | |
2461 | When multiple alignment-specifiers are specified for an |
2462 | entity, the alignment requirement shall be set to the |
2463 | strictest specified alignment. |
2464 | |
2465 | This formally comes from the c++11 specification but we are |
2466 | doing it for the GNU attribute syntax as well. */ |
2467 | *no_add_attrs = true; |
2468 | else if (warn_if_not_aligned_p |
2469 | && TREE_CODE (decl)((enum tree_code) (decl)->base.code) == FIELD_DECL |
2470 | && !DECL_C_BIT_FIELD (decl)(((contains_struct_check (((tree_check ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2470, __FUNCTION__, (FIELD_DECL)))), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2470, __FUNCTION__))->decl_common.lang_flag_4) == 1)) |
2471 | { |
2472 | SET_DECL_WARN_IF_NOT_ALIGN (decl, bitalign)(((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2472, __FUNCTION__))->decl_common.warn_if_not_align) = ffs_hwi (bitalign)); |
2473 | warn_if_not_aligned_p = false; |
2474 | set_align = false; |
2475 | } |
2476 | |
2477 | if (warn_if_not_aligned_p) |
2478 | { |
2479 | error ("%<warn_if_not_aligned%> may not be specified for %q+D", |
2480 | decl); |
2481 | *no_add_attrs = true; |
2482 | } |
2483 | else if (!is_type && !*no_add_attrs && set_align) |
2484 | { |
2485 | SET_DECL_ALIGN (decl, bitalign)(((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2485, __FUNCTION__))->decl_common.align) = ffs_hwi (bitalign )); |
2486 | DECL_USER_ALIGN (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2486, __FUNCTION__))->base.u.bits.user_align) = 1; |
2487 | } |
2488 | |
2489 | return NULL_TREE(tree) nullptr; |
2490 | } |
2491 | |
2492 | /* Handle a "aligned" attribute; arguments as in |
2493 | struct attribute_spec.handler. */ |
2494 | |
2495 | static tree |
2496 | handle_aligned_attribute (tree *node, tree name, tree args, |
2497 | int flags, bool *no_add_attrs) |
2498 | { |
2499 | return common_handle_aligned_attribute (node, name, args, flags, |
2500 | no_add_attrs, false); |
2501 | } |
2502 | |
2503 | /* Handle a "warn_if_not_aligned" attribute; arguments as in |
2504 | struct attribute_spec.handler. */ |
2505 | |
2506 | static tree |
2507 | handle_warn_if_not_aligned_attribute (tree *node, tree name, |
2508 | tree args, int flags, |
2509 | bool *no_add_attrs) |
2510 | { |
2511 | return common_handle_aligned_attribute (node, name, args, flags, |
2512 | no_add_attrs, true); |
2513 | } |
2514 | |
2515 | /* Handle a "strict_flex_array" attribute; arguments as in |
2516 | struct attribute_spec.handler. */ |
2517 | |
2518 | static tree |
2519 | handle_strict_flex_array_attribute (tree *node, tree name, |
2520 | tree args, int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), |
2521 | bool *no_add_attrs) |
2522 | { |
2523 | tree decl = *node; |
2524 | tree argval = TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2524, __FUNCTION__, (TREE_LIST)))->list.value); |
2525 | |
2526 | /* This attribute only applies to field decls of a structure. */ |
2527 | if (TREE_CODE (decl)((enum tree_code) (decl)->base.code) != FIELD_DECL) |
2528 | { |
2529 | error_at (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2529, __FUNCTION__))->decl_minimal.locus), |
2530 | "%qE attribute may not be specified for %q+D", name, decl); |
2531 | *no_add_attrs = true; |
2532 | } |
2533 | /* This attribute only applies to field with array type. */ |
2534 | else if (TREE_CODE (TREE_TYPE (decl))((enum tree_code) (((contains_struct_check ((decl), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2534, __FUNCTION__))->typed.type))->base.code) != ARRAY_TYPE) |
2535 | { |
2536 | error_at (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2536, __FUNCTION__))->decl_minimal.locus), |
2537 | "%qE attribute may not be specified for a non-array field", |
2538 | name); |
2539 | *no_add_attrs = true; |
2540 | } |
2541 | else if (TREE_CODE (argval)((enum tree_code) (argval)->base.code) != INTEGER_CST) |
2542 | { |
2543 | error_at (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2543, __FUNCTION__))->decl_minimal.locus), |
2544 | "%qE attribute argument not an integer", name); |
2545 | *no_add_attrs = true; |
2546 | } |
2547 | else if (!tree_fits_uhwi_p (argval) || tree_to_uhwi (argval) > 3) |
2548 | { |
2549 | error_at (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2549, __FUNCTION__))->decl_minimal.locus), |
2550 | "%qE attribute argument %qE is not an integer constant" |
2551 | " between 0 and 3", name, argval); |
2552 | *no_add_attrs = true; |
2553 | } |
2554 | |
2555 | return NULL_TREE(tree) nullptr; |
2556 | } |
2557 | |
2558 | /* Handle a "weak" attribute; arguments as in |
2559 | struct attribute_spec.handler. */ |
2560 | |
2561 | static tree |
2562 | handle_weak_attribute (tree *node, tree name, |
2563 | tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
2564 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), |
2565 | bool * ARG_UNUSED (no_add_attrs)no_add_attrs __attribute__ ((__unused__))) |
2566 | { |
2567 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) == FUNCTION_DECL |
2568 | && DECL_DECLARED_INLINE_P (*node)((tree_check ((*node), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2568, __FUNCTION__, (FUNCTION_DECL)))->function_decl.declared_inline_flag )) |
2569 | { |
2570 | warning (OPT_Wattributes, "inline function %q+D declared weak", *node); |
2571 | *no_add_attrs = true; |
2572 | } |
2573 | else if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (*node)((contains_struct_check ((*node), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2573, __FUNCTION__))->decl_common.attributes))) |
2574 | { |
2575 | error ("indirect function %q+D cannot be declared weak", *node); |
2576 | *no_add_attrs = true; |
2577 | return NULL_TREE(tree) nullptr; |
2578 | } |
2579 | else if (VAR_OR_FUNCTION_DECL_P (*node)(((enum tree_code) (*node)->base.code) == VAR_DECL || ((enum tree_code) (*node)->base.code) == FUNCTION_DECL)) |
2580 | declare_weak (*node); |
2581 | else |
2582 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
2583 | |
2584 | return NULL_TREE(tree) nullptr; |
2585 | } |
2586 | |
2587 | /* Handle a "noinit" or "persistent" attribute; arguments as in |
2588 | struct attribute_spec.handler. |
2589 | This generic handler is used for "special variable sections" that allow the |
2590 | section name to be set using a dedicated attribute. Additional validation |
2591 | is performed for the specific properties of the section corresponding to the |
2592 | attribute. |
2593 | The ".noinit" section *is not* loaded by the program loader, and is not |
2594 | initialized by the runtime startup code. |
2595 | The ".persistent" section *is* loaded by the program loader, but is not |
2596 | initialized by the runtime startup code. */ |
2597 | static tree |
2598 | handle_special_var_sec_attribute (tree *node, tree name, tree args, |
2599 | int flags, bool *no_add_attrs) |
2600 | { |
2601 | tree decl = *node; |
2602 | tree res = NULL_TREE(tree) nullptr; |
2603 | |
2604 | /* First perform generic validation common to "noinit" and "persistent" |
2605 | attributes. */ |
2606 | if (!targetm_common.have_named_sections) |
2607 | { |
2608 | error_at (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2608, __FUNCTION__))->decl_minimal.locus), |
2609 | "section attributes are not supported for this target"); |
2610 | goto fail; |
2611 | } |
2612 | |
2613 | if (!VAR_P (decl)(((enum tree_code) (decl)->base.code) == VAR_DECL)) |
2614 | { |
2615 | warning_at (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2615, __FUNCTION__))->decl_minimal.locus), OPT_Wattributes, |
2616 | "ignoring %qE attribute not set on a variable", |
2617 | name); |
2618 | goto fail; |
2619 | } |
2620 | |
2621 | if (VAR_P (decl)(((enum tree_code) (decl)->base.code) == VAR_DECL) |
2622 | && current_function_decl != NULL_TREE(tree) nullptr |
2623 | && !TREE_STATIC (decl)((decl)->base.static_flag)) |
2624 | { |
2625 | error_at (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2625, __FUNCTION__))->decl_minimal.locus), |
2626 | "%qE attribute cannot be specified for local variables", |
2627 | name); |
2628 | goto fail; |
2629 | } |
2630 | |
2631 | if (VAR_P (decl)(((enum tree_code) (decl)->base.code) == VAR_DECL) |
2632 | && !targetm.have_tls && targetm.emutls.tmpl_section |
2633 | && DECL_THREAD_LOCAL_P (decl)((((decl)->base.static_flag) || ((contains_struct_check (( decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2633, __FUNCTION__))->decl_common.decl_flag_1)) && decl_tls_model (decl) >= TLS_MODEL_REAL)) |
2634 | { |
2635 | error ("section of %q+D cannot be overridden", decl); |
2636 | goto fail; |
2637 | } |
2638 | |
2639 | if (!targetm.have_switchable_bss_sections) |
2640 | { |
2641 | error ("%qE attribute is specific to ELF targets", name); |
2642 | goto fail; |
2643 | } |
2644 | |
2645 | if (TREE_READONLY (decl)((non_type_check ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2645, __FUNCTION__))->base.readonly_flag)) |
2646 | { |
2647 | warning_at (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2647, __FUNCTION__))->decl_minimal.locus), OPT_Wattributes, |
2648 | "ignoring %qE attribute set on const variable", |
2649 | name); |
2650 | goto fail; |
2651 | } |
2652 | |
2653 | /* Now validate noinit/persistent individually. */ |
2654 | if (strcmp (IDENTIFIER_POINTER (name)((const char *) (tree_check ((name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2654, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), "noinit") == 0) |
2655 | { |
2656 | if (DECL_INITIAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2656, __FUNCTION__))->decl_common.initial)) |
2657 | { |
2658 | warning_at (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2658, __FUNCTION__))->decl_minimal.locus), OPT_Wattributes, |
2659 | "ignoring %qE attribute set on initialized variable", |
2660 | name); |
2661 | goto fail; |
2662 | } |
2663 | /* If this var is thought to be common, then change this. "noinit" |
2664 | variables must be placed in an explicit ".noinit" section. */ |
2665 | DECL_COMMON (decl)((contains_struct_check ((decl), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2665, __FUNCTION__))->decl_with_vis.common_flag) = 0; |
2666 | } |
2667 | else if (strcmp (IDENTIFIER_POINTER (name)((const char *) (tree_check ((name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2667, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), "persistent") == 0) |
2668 | { |
2669 | if (DECL_COMMON (decl)((contains_struct_check ((decl), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2669, __FUNCTION__))->decl_with_vis.common_flag) || DECL_INITIAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2669, __FUNCTION__))->decl_common.initial) == NULL_TREE(tree) nullptr) |
2670 | { |
2671 | warning_at (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2671, __FUNCTION__))->decl_minimal.locus), OPT_Wattributes, |
2672 | "ignoring %qE attribute set on uninitialized variable", |
2673 | name); |
2674 | goto fail; |
2675 | } |
2676 | } |
2677 | else |
2678 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2678, __FUNCTION__)); |
2679 | |
2680 | res = targetm.handle_generic_attribute (node, name, args, flags, |
2681 | no_add_attrs); |
2682 | |
2683 | /* If the back end confirms the attribute can be added then continue onto |
2684 | final processing. */ |
2685 | if (!(*no_add_attrs)) |
2686 | return res; |
2687 | |
2688 | fail: |
2689 | *no_add_attrs = true; |
2690 | return res; |
2691 | } |
2692 | |
2693 | /* Handle a "noplt" attribute; arguments as in |
2694 | struct attribute_spec.handler. */ |
2695 | |
2696 | static tree |
2697 | handle_noplt_attribute (tree *node, tree name, |
2698 | tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
2699 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), |
2700 | bool * ARG_UNUSED (no_add_attrs)no_add_attrs __attribute__ ((__unused__))) |
2701 | { |
2702 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) != FUNCTION_DECL) |
2703 | { |
2704 | warning (OPT_Wattributes, |
2705 | "%qE attribute is only applicable on functions", name); |
2706 | *no_add_attrs = true; |
2707 | return NULL_TREE(tree) nullptr; |
2708 | } |
2709 | return NULL_TREE(tree) nullptr; |
2710 | } |
2711 | |
2712 | /* Handle a "symver" attribute. */ |
2713 | |
2714 | static tree |
2715 | handle_symver_attribute (tree *node, tree ARG_UNUSED (name)name __attribute__ ((__unused__)), tree args, |
2716 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), bool *no_add_attrs) |
2717 | { |
2718 | tree symver; |
2719 | const char *symver_str; |
2720 | |
2721 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) != FUNCTION_DECL && TREE_CODE (*node)((enum tree_code) (*node)->base.code) != VAR_DECL) |
2722 | { |
2723 | warning (OPT_Wattributes, |
2724 | "%<symver%> attribute only applies to functions and variables"); |
2725 | *no_add_attrs = true; |
2726 | return NULL_TREE(tree) nullptr; |
2727 | } |
2728 | |
2729 | if (!decl_in_symtab_p (*node)) |
2730 | { |
2731 | warning (OPT_Wattributes, |
2732 | "%<symver%> attribute is only applicable to symbols"); |
2733 | *no_add_attrs = true; |
2734 | return NULL_TREE(tree) nullptr; |
2735 | } |
2736 | |
2737 | for (; args; args = TREE_CHAIN (args)((contains_struct_check ((args), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2737, __FUNCTION__))->common.chain)) |
2738 | { |
2739 | symver = TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2739, __FUNCTION__, (TREE_LIST)))->list.value); |
2740 | if (TREE_CODE (symver)((enum tree_code) (symver)->base.code) != STRING_CST) |
2741 | { |
2742 | error ("%<symver%> attribute argument not a string constant"); |
2743 | *no_add_attrs = true; |
2744 | return NULL_TREE(tree) nullptr; |
2745 | } |
2746 | |
2747 | symver_str = TREE_STRING_POINTER (symver)((const char *)((tree_check ((symver), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2747, __FUNCTION__, (STRING_CST)))->string.str)); |
2748 | |
2749 | int ats = 0; |
2750 | for (int n = 0; (int)n < TREE_STRING_LENGTH (symver)((tree_check ((symver), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2750, __FUNCTION__, (STRING_CST)))->string.length); n++) |
2751 | if (symver_str[n] == '@') |
2752 | ats++; |
2753 | |
2754 | if (ats != 1 && ats != 2) |
2755 | { |
2756 | error ("symver attribute argument must have format %<name@nodename%>"); |
2757 | error ("%<symver%> attribute argument %qs must contain one or two " |
2758 | "%<@%>", symver_str); |
2759 | *no_add_attrs = true; |
2760 | return NULL_TREE(tree) nullptr; |
2761 | } |
2762 | } |
2763 | |
2764 | return NULL_TREE(tree) nullptr; |
2765 | } |
2766 | |
2767 | |
2768 | /* Handle an "alias" or "ifunc" attribute; arguments as in |
2769 | struct attribute_spec.handler, except that IS_ALIAS tells us |
2770 | whether this is an alias as opposed to ifunc attribute. */ |
2771 | |
2772 | static tree |
2773 | handle_alias_ifunc_attribute (bool is_alias, tree *node, tree name, tree args, |
2774 | bool *no_add_attrs) |
2775 | { |
2776 | tree decl = *node; |
2777 | |
2778 | if (TREE_CODE (decl)((enum tree_code) (decl)->base.code) != FUNCTION_DECL |
2779 | && (!is_alias || !VAR_P (decl)(((enum tree_code) (decl)->base.code) == VAR_DECL))) |
2780 | { |
2781 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
2782 | *no_add_attrs = true; |
2783 | } |
2784 | else if ((TREE_CODE (decl)((enum tree_code) (decl)->base.code) == FUNCTION_DECL && DECL_INITIAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2784, __FUNCTION__))->decl_common.initial)) |
2785 | || (TREE_CODE (decl)((enum tree_code) (decl)->base.code) != FUNCTION_DECL |
2786 | && TREE_PUBLIC (decl)((decl)->base.public_flag) && !DECL_EXTERNAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2786, __FUNCTION__))->decl_common.decl_flag_1)) |
2787 | /* A static variable declaration is always a tentative definition, |
2788 | but the alias is a non-tentative definition which overrides. */ |
2789 | || (TREE_CODE (decl)((enum tree_code) (decl)->base.code) != FUNCTION_DECL |
2790 | && ! TREE_PUBLIC (decl)((decl)->base.public_flag) && DECL_INITIAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2790, __FUNCTION__))->decl_common.initial))) |
2791 | { |
2792 | error ("%q+D defined both normally and as %qE attribute", decl, name); |
2793 | *no_add_attrs = true; |
2794 | return NULL_TREE(tree) nullptr; |
2795 | } |
2796 | else if (!is_alias |
2797 | && (lookup_attribute ("weak", DECL_ATTRIBUTES (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2797, __FUNCTION__))->decl_common.attributes)) |
2798 | || lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2798, __FUNCTION__))->decl_common.attributes)))) |
2799 | { |
2800 | error ("weak %q+D cannot be defined %qE", decl, name); |
2801 | *no_add_attrs = true; |
2802 | return NULL_TREE(tree) nullptr; |
2803 | } |
2804 | |
2805 | /* Note that the very first time we process a nested declaration, |
2806 | decl_function_context will not be set. Indeed, *would* never |
2807 | be set except for the DECL_INITIAL/DECL_EXTERNAL frobbery that |
2808 | we do below. After such frobbery, pushdecl would set the context. |
2809 | In any case, this is never what we want. */ |
2810 | else if (decl_function_context (decl) == 0 && current_function_decl == NULLnullptr) |
2811 | { |
2812 | tree id; |
2813 | |
2814 | id = TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2814, __FUNCTION__, (TREE_LIST)))->list.value); |
2815 | if (TREE_CODE (id)((enum tree_code) (id)->base.code) != STRING_CST) |
2816 | { |
2817 | error ("attribute %qE argument not a string", name); |
2818 | *no_add_attrs = true; |
2819 | return NULL_TREE(tree) nullptr; |
2820 | } |
2821 | id = get_identifier (TREE_STRING_POINTER (id))(__builtin_constant_p (((const char *)((tree_check ((id), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2821, __FUNCTION__, (STRING_CST)))->string.str))) ? get_identifier_with_length ((((const char *)((tree_check ((id), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2821, __FUNCTION__, (STRING_CST)))->string.str))), strlen (((const char *)((tree_check ((id), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2821, __FUNCTION__, (STRING_CST)))->string.str)))) : get_identifier (((const char *)((tree_check ((id), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2821, __FUNCTION__, (STRING_CST)))->string.str)))); |
2822 | /* This counts as a use of the object pointed to. */ |
2823 | TREE_USED (id)((id)->base.used_flag) = 1; |
2824 | |
2825 | if (TREE_CODE (decl)((enum tree_code) (decl)->base.code) == FUNCTION_DECL) |
2826 | DECL_INITIAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2826, __FUNCTION__))->decl_common.initial) = error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
2827 | else |
2828 | TREE_STATIC (decl)((decl)->base.static_flag) = 1; |
2829 | |
2830 | if (!is_alias) |
2831 | { |
2832 | /* ifuncs are also aliases, so set that attribute too. */ |
2833 | DECL_ATTRIBUTES (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2833, __FUNCTION__))->decl_common.attributes) |
2834 | = tree_cons (get_identifier ("alias")(__builtin_constant_p ("alias") ? get_identifier_with_length ( ("alias"), strlen ("alias")) : get_identifier ("alias")), args, |
2835 | DECL_ATTRIBUTES (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2835, __FUNCTION__))->decl_common.attributes)); |
2836 | DECL_ATTRIBUTES (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2836, __FUNCTION__))->decl_common.attributes) = tree_cons (get_identifier ("ifunc")(__builtin_constant_p ("ifunc") ? get_identifier_with_length ( ("ifunc"), strlen ("ifunc")) : get_identifier ("ifunc")), |
2837 | NULLnullptr, DECL_ATTRIBUTES (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2837, __FUNCTION__))->decl_common.attributes)); |
2838 | } |
2839 | } |
2840 | else |
2841 | { |
2842 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
2843 | *no_add_attrs = true; |
2844 | } |
2845 | |
2846 | if (decl_in_symtab_p (*node)) |
2847 | { |
2848 | struct symtab_node *n = symtab_node::get (decl); |
2849 | if (n && n->refuse_visibility_changes) |
2850 | error ("%+qD declared %qs after being used", |
2851 | decl, is_alias ? "alias" : "ifunc"); |
2852 | } |
2853 | |
2854 | |
2855 | return NULL_TREE(tree) nullptr; |
2856 | } |
2857 | |
2858 | /* Handle an "alias" or "ifunc" attribute; arguments as in |
2859 | struct attribute_spec.handler. */ |
2860 | |
2861 | static tree |
2862 | handle_ifunc_attribute (tree *node, tree name, tree args, |
2863 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), bool *no_add_attrs) |
2864 | { |
2865 | return handle_alias_ifunc_attribute (false, node, name, args, no_add_attrs); |
2866 | } |
2867 | |
2868 | /* Handle an "alias" or "ifunc" attribute; arguments as in |
2869 | struct attribute_spec.handler. */ |
2870 | |
2871 | static tree |
2872 | handle_alias_attribute (tree *node, tree name, tree args, |
2873 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), bool *no_add_attrs) |
2874 | { |
2875 | return handle_alias_ifunc_attribute (true, node, name, args, no_add_attrs); |
2876 | } |
2877 | |
2878 | /* Handle the "copy" attribute NAME by copying the set of attributes |
2879 | from the symbol referenced by ARGS to the declaration of *NODE. */ |
2880 | |
2881 | static tree |
2882 | handle_copy_attribute (tree *node, tree name, tree args, |
2883 | int flags, bool *no_add_attrs) |
2884 | { |
2885 | /* Do not apply the copy attribute itself. It serves no purpose |
2886 | other than to copy other attributes. */ |
2887 | *no_add_attrs = true; |
2888 | |
2889 | tree decl = *node; |
2890 | |
2891 | tree ref = TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2891, __FUNCTION__, (TREE_LIST)))->list.value); |
2892 | if (ref == error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
2893 | return NULL_TREE(tree) nullptr; |
2894 | |
2895 | if (TREE_CODE (ref)((enum tree_code) (ref)->base.code) == STRING_CST) |
2896 | { |
2897 | /* Explicitly handle this case since using a string literal |
2898 | as an argument is a likely mistake. */ |
2899 | error_at (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2899, __FUNCTION__))->decl_minimal.locus), |
2900 | "%qE attribute argument cannot be a string", |
2901 | name); |
2902 | return NULL_TREE(tree) nullptr; |
2903 | } |
2904 | |
2905 | if (CONSTANT_CLASS_P (ref)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (ref)->base.code))] == tcc_constant) |
2906 | && (INTEGRAL_TYPE_P (TREE_TYPE (ref))(((enum tree_code) (((contains_struct_check ((ref), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2906, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE || ((enum tree_code) (((contains_struct_check ((ref), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2906, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE || ((enum tree_code) (((contains_struct_check ((ref), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2906, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE ) |
2907 | || FLOAT_TYPE_P (TREE_TYPE (ref))((((enum tree_code) (((contains_struct_check ((ref), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2907, __FUNCTION__))->typed.type))->base.code) == REAL_TYPE ) || ((((enum tree_code) (((contains_struct_check ((ref), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2907, __FUNCTION__))->typed.type))->base.code) == COMPLEX_TYPE || (((enum tree_code) (((contains_struct_check ((ref), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2907, __FUNCTION__))->typed.type))->base.code) == VECTOR_TYPE )) && (((enum tree_code) (((contains_struct_check ((( (contains_struct_check ((ref), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2907, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2907, __FUNCTION__))->typed.type))->base.code) == REAL_TYPE ))))) |
2908 | { |
2909 | /* Similar to the string case, since some function attributes |
2910 | accept literal numbers as arguments (e.g., alloc_size or |
2911 | nonnull) using one here is a likely mistake. */ |
2912 | error_at (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2912, __FUNCTION__))->decl_minimal.locus), |
2913 | "%qE attribute argument cannot be a constant arithmetic " |
2914 | "expression", |
2915 | name); |
2916 | return NULL_TREE(tree) nullptr; |
2917 | } |
2918 | |
2919 | if (ref == node[1]) |
2920 | { |
2921 | /* Another possible mistake (but indirect self-references aren't |
2922 | and diagnosed and shouldn't be). */ |
2923 | if (warning_at (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2923, __FUNCTION__))->decl_minimal.locus), OPT_Wattributes, |
2924 | "%qE attribute ignored on a redeclaration " |
2925 | "of the referenced symbol", |
2926 | name)) |
2927 | inform (DECL_SOURCE_LOCATION (node[1])((contains_struct_check ((node[1]), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2927, __FUNCTION__))->decl_minimal.locus), |
2928 | "previous declaration here"); |
2929 | return NULL_TREE(tree) nullptr; |
2930 | } |
2931 | |
2932 | /* Consider address-of expressions in the attribute argument |
2933 | as requests to copy from the referenced entity. */ |
2934 | if (TREE_CODE (ref)((enum tree_code) (ref)->base.code) == ADDR_EXPR) |
2935 | ref = TREE_OPERAND (ref, 0)(*((const_cast<tree*> (tree_operand_check ((ref), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2935, __FUNCTION__))))); |
2936 | |
2937 | do |
2938 | { |
2939 | /* Drill down into references to find the referenced decl. */ |
2940 | tree_code refcode = TREE_CODE (ref)((enum tree_code) (ref)->base.code); |
2941 | if (refcode == ARRAY_REF |
2942 | || refcode == INDIRECT_REF) |
2943 | ref = TREE_OPERAND (ref, 0)(*((const_cast<tree*> (tree_operand_check ((ref), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2943, __FUNCTION__))))); |
2944 | else if (refcode == COMPONENT_REF) |
2945 | ref = TREE_OPERAND (ref, 1)(*((const_cast<tree*> (tree_operand_check ((ref), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2945, __FUNCTION__))))); |
2946 | else |
2947 | break; |
2948 | } while (!DECL_P (ref)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (ref)->base.code))] == tcc_declaration)); |
2949 | |
2950 | /* For object pointer expressions, consider those to be requests |
2951 | to copy from their type, such as in: |
2952 | struct __attribute__ (copy ((struct T *)0)) U { ... }; |
2953 | which copies type attributes from struct T to the declaration |
2954 | of struct U. */ |
2955 | if ((CONSTANT_CLASS_P (ref)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (ref)->base.code))] == tcc_constant) || EXPR_P (ref)((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (ref)->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (ref)->base.code))]) <= tcc_expression)) |
2956 | && POINTER_TYPE_P (TREE_TYPE (ref))(((enum tree_code) (((contains_struct_check ((ref), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2956, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE || ((enum tree_code) (((contains_struct_check ((ref), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2956, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE ) |
2957 | && !FUNCTION_POINTER_TYPE_P (TREE_TYPE (ref))((((enum tree_code) (((contains_struct_check ((ref), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2957, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE || ((enum tree_code) (((contains_struct_check ((ref), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2957, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE ) && ((enum tree_code) (((contains_struct_check ((((contains_struct_check ((ref), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2957, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2957, __FUNCTION__))->typed.type))->base.code) == FUNCTION_TYPE )) |
2958 | ref = TREE_TYPE (ref)((contains_struct_check ((ref), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2958, __FUNCTION__))->typed.type); |
2959 | |
2960 | tree reftype = TYPE_P (ref)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (ref)->base.code))] == tcc_type) ? ref : TREE_TYPE (ref)((contains_struct_check ((ref), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2960, __FUNCTION__))->typed.type); |
2961 | |
2962 | if (DECL_P (decl)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (decl)->base.code))] == tcc_declaration)) |
2963 | { |
2964 | if ((VAR_P (decl)(((enum tree_code) (decl)->base.code) == VAR_DECL) |
2965 | && (TREE_CODE (ref)((enum tree_code) (ref)->base.code) == FUNCTION_DECL |
2966 | || (EXPR_P (ref)((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (ref)->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (ref)->base.code))]) <= tcc_expression) |
2967 | && POINTER_TYPE_P (reftype)(((enum tree_code) (reftype)->base.code) == POINTER_TYPE || ((enum tree_code) (reftype)->base.code) == REFERENCE_TYPE ) |
2968 | && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (reftype))(((enum tree_code) (((contains_struct_check ((reftype), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2968, __FUNCTION__))->typed.type))->base.code) == FUNCTION_TYPE || ((enum tree_code) (((contains_struct_check ((reftype), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2968, __FUNCTION__))->typed.type))->base.code) == METHOD_TYPE )))) |
2969 | || (TREE_CODE (decl)((enum tree_code) (decl)->base.code) == FUNCTION_DECL |
2970 | && (VAR_P (ref)(((enum tree_code) (ref)->base.code) == VAR_DECL) |
2971 | || (EXPR_P (ref)((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (ref)->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (ref)->base.code))]) <= tcc_expression) |
2972 | && !FUNC_OR_METHOD_TYPE_P (reftype)(((enum tree_code) (reftype)->base.code) == FUNCTION_TYPE || ((enum tree_code) (reftype)->base.code) == METHOD_TYPE) |
2973 | && (!POINTER_TYPE_P (reftype)(((enum tree_code) (reftype)->base.code) == POINTER_TYPE || ((enum tree_code) (reftype)->base.code) == REFERENCE_TYPE ) |
2974 | || !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (reftype))(((enum tree_code) (((contains_struct_check ((reftype), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2974, __FUNCTION__))->typed.type))->base.code) == FUNCTION_TYPE || ((enum tree_code) (((contains_struct_check ((reftype), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2974, __FUNCTION__))->typed.type))->base.code) == METHOD_TYPE )))))) |
2975 | { |
2976 | /* It makes no sense to try to copy function attributes |
2977 | to a variable, or variable attributes to a function. */ |
2978 | if (warning (OPT_Wattributes, |
2979 | "%qE attribute ignored on a declaration of " |
2980 | "a different kind than referenced symbol", |
2981 | name) |
2982 | && DECL_P (ref)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (ref)->base.code))] == tcc_declaration)) |
2983 | inform (DECL_SOURCE_LOCATION (ref)((contains_struct_check ((ref), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2983, __FUNCTION__))->decl_minimal.locus), |
2984 | "symbol %qD referenced by %qD declared here", ref, decl); |
2985 | return NULL_TREE(tree) nullptr; |
2986 | } |
2987 | |
2988 | tree attrs = NULL_TREE(tree) nullptr; |
2989 | if (DECL_P (ref)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (ref)->base.code))] == tcc_declaration)) |
2990 | attrs = DECL_ATTRIBUTES (ref)((contains_struct_check ((ref), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2990, __FUNCTION__))->decl_common.attributes); |
2991 | else if (TYPE_P (ref)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (ref)->base.code))] == tcc_type)) |
2992 | attrs = TYPE_ATTRIBUTES (ref)((tree_class_check ((ref), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2992, __FUNCTION__))->type_common.attributes); |
2993 | |
2994 | /* Copy decl attributes from REF to DECL. */ |
2995 | for (tree at = attrs; at; at = TREE_CHAIN (at)((contains_struct_check ((at), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 2995, __FUNCTION__))->common.chain)) |
2996 | { |
2997 | /* Avoid copying attributes that affect a symbol linkage, |
2998 | inlining, or visibility since those in all likelihood |
2999 | only apply to the target. |
3000 | FIXME: make it possible to specify which attributes to |
3001 | copy or not to copy in the copy attribute itself. */ |
3002 | tree atname = get_attribute_name (at); |
3003 | if (is_attribute_p ("alias", atname) |
3004 | || is_attribute_p ("always_inline", atname) |
3005 | || is_attribute_p ("gnu_inline", atname) |
3006 | || is_attribute_p ("ifunc", atname) |
3007 | || is_attribute_p ("noinline", atname) |
3008 | || is_attribute_p ("visibility", atname) |
3009 | || is_attribute_p ("weak", atname) |
3010 | || is_attribute_p ("weakref", atname) |
3011 | || is_attribute_p ("target_clones", atname)) |
3012 | continue; |
3013 | |
3014 | /* Attribute leaf only applies to extern functions. |
3015 | Avoid copying it to static ones. */ |
3016 | if (!TREE_PUBLIC (decl)((decl)->base.public_flag) |
3017 | && is_attribute_p ("leaf", atname)) |
3018 | continue; |
3019 | |
3020 | tree atargs = TREE_VALUE (at)((tree_check ((at), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3020, __FUNCTION__, (TREE_LIST)))->list.value); |
3021 | /* Create a copy of just the one attribute ar AT, including |
3022 | its argumentsm and add it to DECL. */ |
3023 | tree attr = tree_cons (atname, copy_list (atargs), NULL_TREE(tree) nullptr); |
3024 | decl_attributes (node, attr, flags, EXPR_P (ref)((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (ref)->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (ref)->base.code))]) <= tcc_expression) ? NULL_TREE(tree) nullptr : ref); |
3025 | } |
3026 | |
3027 | /* Proceed to copy type attributes below. */ |
3028 | } |
3029 | else if (!TYPE_P (decl)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (decl)->base.code))] == tcc_type)) |
3030 | { |
3031 | error_at (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3031, __FUNCTION__))->decl_minimal.locus), |
3032 | "%qE attribute must apply to a declaration", |
3033 | name); |
3034 | return NULL_TREE(tree) nullptr; |
3035 | } |
3036 | |
3037 | /* A function declared with attribute nothrow has the attribute |
3038 | attached to it, but a C++ throw() function does not. */ |
3039 | if (TREE_NOTHROW (ref)((ref)->base.nothrow_flag)) |
3040 | TREE_NOTHROW (decl)((decl)->base.nothrow_flag) = true; |
3041 | |
3042 | /* Similarly, a function declared with attribute noreturn has it |
3043 | attached on to it, but a C11 _Noreturn function does not. */ |
3044 | if (DECL_P (ref)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (ref)->base.code))] == tcc_declaration) |
3045 | && TREE_THIS_VOLATILE (ref)((ref)->base.volatile_flag) |
3046 | && FUNC_OR_METHOD_TYPE_P (reftype)(((enum tree_code) (reftype)->base.code) == FUNCTION_TYPE || ((enum tree_code) (reftype)->base.code) == METHOD_TYPE)) |
3047 | TREE_THIS_VOLATILE (decl)((decl)->base.volatile_flag) = true; |
3048 | |
3049 | if (POINTER_TYPE_P (reftype)(((enum tree_code) (reftype)->base.code) == POINTER_TYPE || ((enum tree_code) (reftype)->base.code) == REFERENCE_TYPE )) |
3050 | reftype = TREE_TYPE (reftype)((contains_struct_check ((reftype), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3050, __FUNCTION__))->typed.type); |
3051 | |
3052 | if (!TYPE_P (reftype)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (reftype)->base.code))] == tcc_type)) |
3053 | return NULL_TREE(tree) nullptr; |
3054 | |
3055 | tree attrs = TYPE_ATTRIBUTES (reftype)((tree_class_check ((reftype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3055, __FUNCTION__))->type_common.attributes); |
3056 | |
3057 | /* Copy type attributes from REF to DECL. Pass in REF if it's a DECL |
3058 | or a type but not if it's an expression. Set ATTR_FLAG_INTERNAL |
3059 | since the attributes' arguments may be in their internal form. */ |
3060 | for (tree at = attrs; at; at = TREE_CHAIN (at)((contains_struct_check ((at), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3060, __FUNCTION__))->common.chain)) |
3061 | decl_attributes (node, at, flags | ATTR_FLAG_INTERNAL, |
3062 | EXPR_P (ref)((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (ref)->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (ref)->base.code))]) <= tcc_expression) ? NULL_TREE(tree) nullptr : ref); |
3063 | |
3064 | return NULL_TREE(tree) nullptr; |
3065 | } |
3066 | |
3067 | /* Handle a "weakref" attribute; arguments as in struct |
3068 | attribute_spec.handler. */ |
3069 | |
3070 | static tree |
3071 | handle_weakref_attribute (tree *node, tree name, tree args, |
3072 | int flags, bool *no_add_attrs) |
3073 | { |
3074 | tree attr = NULL_TREE(tree) nullptr; |
3075 | |
3076 | /* We must ignore the attribute when it is associated with |
3077 | local-scoped decls, since attribute alias is ignored and many |
3078 | such symbols do not even have a DECL_WEAK field. */ |
3079 | if (decl_function_context (*node) |
3080 | || current_function_decl |
3081 | || !VAR_OR_FUNCTION_DECL_P (*node)(((enum tree_code) (*node)->base.code) == VAR_DECL || ((enum tree_code) (*node)->base.code) == FUNCTION_DECL)) |
3082 | { |
3083 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
3084 | *no_add_attrs = true; |
3085 | return NULL_TREE(tree) nullptr; |
3086 | } |
3087 | |
3088 | if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (*node)((contains_struct_check ((*node), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3088, __FUNCTION__))->decl_common.attributes))) |
3089 | { |
3090 | error ("indirect function %q+D cannot be declared %qE", |
3091 | *node, name); |
3092 | *no_add_attrs = true; |
3093 | return NULL_TREE(tree) nullptr; |
3094 | } |
3095 | |
3096 | /* The idea here is that `weakref("name")' mutates into `weakref, |
3097 | alias("name")', and weakref without arguments, in turn, |
3098 | implicitly adds weak. */ |
3099 | |
3100 | if (args) |
3101 | { |
3102 | attr = tree_cons (get_identifier ("alias")(__builtin_constant_p ("alias") ? get_identifier_with_length ( ("alias"), strlen ("alias")) : get_identifier ("alias")), args, attr); |
3103 | attr = tree_cons (get_identifier ("weakref")(__builtin_constant_p ("weakref") ? get_identifier_with_length (("weakref"), strlen ("weakref")) : get_identifier ("weakref" )), NULL_TREE(tree) nullptr, attr); |
3104 | |
3105 | *no_add_attrs = true; |
3106 | |
3107 | decl_attributes (node, attr, flags); |
3108 | } |
3109 | else |
3110 | { |
3111 | if (lookup_attribute ("alias", DECL_ATTRIBUTES (*node)((contains_struct_check ((*node), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3111, __FUNCTION__))->decl_common.attributes))) |
3112 | error_at (DECL_SOURCE_LOCATION (*node)((contains_struct_check ((*node), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3112, __FUNCTION__))->decl_minimal.locus), |
3113 | "%qE attribute must appear before %qs attribute", |
3114 | name, "alias"); |
3115 | |
3116 | /* Can't call declare_weak because it wants this to be TREE_PUBLIC, |
3117 | and that isn't supported; and because it wants to add it to |
3118 | the list of weak decls, which isn't helpful. */ |
3119 | DECL_WEAK (*node)((contains_struct_check ((*node), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3119, __FUNCTION__))->decl_with_vis.weak_flag) = 1; |
3120 | } |
3121 | |
3122 | if (decl_in_symtab_p (*node)) |
3123 | { |
3124 | struct symtab_node *n = symtab_node::get (*node); |
3125 | if (n && n->refuse_visibility_changes) |
3126 | error ("%+qD declared %qE after being used", *node, name); |
3127 | } |
3128 | |
3129 | return NULL_TREE(tree) nullptr; |
3130 | } |
3131 | |
3132 | /* Handle an "visibility" attribute; arguments as in |
3133 | struct attribute_spec.handler. */ |
3134 | |
3135 | static tree |
3136 | handle_visibility_attribute (tree *node, tree name, tree args, |
3137 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), |
3138 | bool *ARG_UNUSED (no_add_attrs)no_add_attrs __attribute__ ((__unused__))) |
3139 | { |
3140 | tree decl = *node; |
3141 | tree id = TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3141, __FUNCTION__, (TREE_LIST)))->list.value); |
3142 | enum symbol_visibility vis; |
3143 | |
3144 | if (TYPE_P (*node)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (*node)->base.code))] == tcc_type)) |
3145 | { |
3146 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) == ENUMERAL_TYPE) |
3147 | /* OK */; |
3148 | else if (!RECORD_OR_UNION_TYPE_P (*node)(((enum tree_code) (*node)->base.code) == RECORD_TYPE || ( (enum tree_code) (*node)->base.code) == UNION_TYPE || ((enum tree_code) (*node)->base.code) == QUAL_UNION_TYPE)) |
3149 | { |
3150 | warning (OPT_Wattributes, "%qE attribute ignored on non-class types", |
3151 | name); |
3152 | return NULL_TREE(tree) nullptr; |
3153 | } |
3154 | else if (TYPE_FIELDS (*node)((tree_check3 ((*node), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3154, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.values)) |
3155 | { |
3156 | error ("%qE attribute ignored because %qT is already defined", |
3157 | name, *node); |
3158 | return NULL_TREE(tree) nullptr; |
3159 | } |
3160 | } |
3161 | else if (decl_function_context (decl) != 0 || !TREE_PUBLIC (decl)((decl)->base.public_flag)) |
3162 | { |
3163 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
3164 | return NULL_TREE(tree) nullptr; |
3165 | } |
3166 | |
3167 | if (TREE_CODE (id)((enum tree_code) (id)->base.code) != STRING_CST) |
3168 | { |
3169 | error ("visibility argument not a string"); |
3170 | return NULL_TREE(tree) nullptr; |
3171 | } |
3172 | |
3173 | /* If this is a type, set the visibility on the type decl. */ |
3174 | if (TYPE_P (decl)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (decl)->base.code))] == tcc_type)) |
3175 | { |
3176 | decl = TYPE_NAME (decl)((tree_class_check ((decl), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3176, __FUNCTION__))->type_common.name); |
3177 | if (!decl) |
3178 | return NULL_TREE(tree) nullptr; |
3179 | if (TREE_CODE (decl)((enum tree_code) (decl)->base.code) == IDENTIFIER_NODE) |
3180 | { |
3181 | warning (OPT_Wattributes, "%qE attribute ignored on types", |
3182 | name); |
3183 | return NULL_TREE(tree) nullptr; |
3184 | } |
3185 | } |
3186 | |
3187 | if (strcmp (TREE_STRING_POINTER (id)((const char *)((tree_check ((id), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3187, __FUNCTION__, (STRING_CST)))->string.str)), "default") == 0) |
3188 | vis = VISIBILITY_DEFAULT; |
3189 | else if (strcmp (TREE_STRING_POINTER (id)((const char *)((tree_check ((id), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3189, __FUNCTION__, (STRING_CST)))->string.str)), "internal") == 0) |
3190 | vis = VISIBILITY_INTERNAL; |
3191 | else if (strcmp (TREE_STRING_POINTER (id)((const char *)((tree_check ((id), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3191, __FUNCTION__, (STRING_CST)))->string.str)), "hidden") == 0) |
3192 | vis = VISIBILITY_HIDDEN; |
3193 | else if (strcmp (TREE_STRING_POINTER (id)((const char *)((tree_check ((id), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3193, __FUNCTION__, (STRING_CST)))->string.str)), "protected") == 0) |
3194 | vis = VISIBILITY_PROTECTED; |
3195 | else |
3196 | { |
3197 | error ("attribute %qE argument must be one of %qs, %qs, %qs, or %qs", |
3198 | name, "default", "hidden", "protected", "internal"); |
3199 | vis = VISIBILITY_DEFAULT; |
3200 | } |
3201 | |
3202 | if (DECL_VISIBILITY_SPECIFIED (decl)((contains_struct_check ((decl), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3202, __FUNCTION__))->decl_with_vis.visibility_specified ) |
3203 | && vis != DECL_VISIBILITY (decl)((contains_struct_check ((decl), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3203, __FUNCTION__))->decl_with_vis.visibility)) |
3204 | { |
3205 | tree attributes = (TYPE_P (*node)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (*node)->base.code))] == tcc_type) |
3206 | ? TYPE_ATTRIBUTES (*node)((tree_class_check ((*node), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3206, __FUNCTION__))->type_common.attributes) |
3207 | : DECL_ATTRIBUTES (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3207, __FUNCTION__))->decl_common.attributes)); |
3208 | if (lookup_attribute ("visibility", attributes)) |
3209 | error ("%qD redeclared with different visibility", decl); |
3210 | else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES0 |
3211 | && lookup_attribute ("dllimport", attributes)) |
3212 | error ("%qD was declared %qs which implies default visibility", |
3213 | decl, "dllimport"); |
3214 | else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES0 |
3215 | && lookup_attribute ("dllexport", attributes)) |
3216 | error ("%qD was declared %qs which implies default visibility", |
3217 | decl, "dllexport"); |
3218 | } |
3219 | |
3220 | DECL_VISIBILITY (decl)((contains_struct_check ((decl), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3220, __FUNCTION__))->decl_with_vis.visibility) = vis; |
3221 | DECL_VISIBILITY_SPECIFIED (decl)((contains_struct_check ((decl), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3221, __FUNCTION__))->decl_with_vis.visibility_specified ) = 1; |
3222 | |
3223 | /* Go ahead and attach the attribute to the node as well. This is needed |
3224 | so we can determine whether we have VISIBILITY_DEFAULT because the |
3225 | visibility was not specified, or because it was explicitly overridden |
3226 | from the containing scope. */ |
3227 | |
3228 | return NULL_TREE(tree) nullptr; |
3229 | } |
3230 | |
3231 | /* Handle an "tls_model" attribute; arguments as in |
3232 | struct attribute_spec.handler. */ |
3233 | |
3234 | static tree |
3235 | handle_tls_model_attribute (tree *node, tree name, tree args, |
3236 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), |
3237 | bool *ARG_UNUSED (no_add_attrs)no_add_attrs __attribute__ ((__unused__))) |
3238 | { |
3239 | tree id; |
3240 | tree decl = *node; |
3241 | enum tls_model kind; |
3242 | |
3243 | if (!VAR_P (decl)(((enum tree_code) (decl)->base.code) == VAR_DECL)) |
3244 | { |
3245 | warning (OPT_Wattributes, "%qE attribute ignored because %qD " |
3246 | "is not a variable", |
3247 | name, decl); |
3248 | return NULL_TREE(tree) nullptr; |
3249 | } |
3250 | |
3251 | if (!DECL_THREAD_LOCAL_P (decl)((((decl)->base.static_flag) || ((contains_struct_check (( decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3251, __FUNCTION__))->decl_common.decl_flag_1)) && decl_tls_model (decl) >= TLS_MODEL_REAL)) |
3252 | { |
3253 | warning (OPT_Wattributes, "%qE attribute ignored because %qD does " |
3254 | "not have thread storage duration", name, decl); |
3255 | return NULL_TREE(tree) nullptr; |
3256 | } |
3257 | |
3258 | kind = DECL_TLS_MODEL (decl)decl_tls_model (decl); |
3259 | id = TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3259, __FUNCTION__, (TREE_LIST)))->list.value); |
3260 | if (TREE_CODE (id)((enum tree_code) (id)->base.code) != STRING_CST) |
3261 | { |
3262 | error ("%qE argument not a string", name); |
3263 | return NULL_TREE(tree) nullptr; |
3264 | } |
3265 | |
3266 | if (!strcmp (TREE_STRING_POINTER (id)((const char *)((tree_check ((id), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3266, __FUNCTION__, (STRING_CST)))->string.str)), "local-exec")) |
3267 | kind = TLS_MODEL_LOCAL_EXEC; |
3268 | else if (!strcmp (TREE_STRING_POINTER (id)((const char *)((tree_check ((id), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3268, __FUNCTION__, (STRING_CST)))->string.str)), "initial-exec")) |
3269 | kind = TLS_MODEL_INITIAL_EXEC; |
3270 | else if (!strcmp (TREE_STRING_POINTER (id)((const char *)((tree_check ((id), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3270, __FUNCTION__, (STRING_CST)))->string.str)), "local-dynamic")) |
3271 | kind = optimizeglobal_options.x_optimize ? TLS_MODEL_LOCAL_DYNAMIC : TLS_MODEL_GLOBAL_DYNAMIC; |
3272 | else if (!strcmp (TREE_STRING_POINTER (id)((const char *)((tree_check ((id), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3272, __FUNCTION__, (STRING_CST)))->string.str)), "global-dynamic")) |
3273 | kind = TLS_MODEL_GLOBAL_DYNAMIC; |
3274 | else |
3275 | error ("%qE argument must be one of %qs, %qs, %qs, or %qs", |
3276 | name, |
3277 | "local-exec", "initial-exec", "local-dynamic", "global-dynamic"); |
3278 | |
3279 | set_decl_tls_model (decl, kind); |
3280 | return NULL_TREE(tree) nullptr; |
3281 | } |
3282 | |
3283 | /* Handle a "no_instrument_function" attribute; arguments as in |
3284 | struct attribute_spec.handler. */ |
3285 | |
3286 | static tree |
3287 | handle_no_instrument_function_attribute (tree *node, tree name, |
3288 | tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
3289 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), |
3290 | bool *no_add_attrs) |
3291 | { |
3292 | tree decl = *node; |
3293 | |
3294 | if (TREE_CODE (decl)((enum tree_code) (decl)->base.code) != FUNCTION_DECL) |
3295 | { |
3296 | error_at (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3296, __FUNCTION__))->decl_minimal.locus), |
3297 | "%qE attribute applies only to functions", name); |
3298 | *no_add_attrs = true; |
3299 | } |
3300 | else |
3301 | DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl)((tree_check ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3301, __FUNCTION__, (FUNCTION_DECL)))->function_decl.no_instrument_function_entry_exit ) = 1; |
3302 | |
3303 | return NULL_TREE(tree) nullptr; |
3304 | } |
3305 | |
3306 | /* Handle a "no_profile_instrument_function" attribute; arguments as in |
3307 | struct attribute_spec.handler. */ |
3308 | |
3309 | static tree |
3310 | handle_no_profile_instrument_function_attribute (tree *node, tree name, tree, |
3311 | int, bool *no_add_attrs) |
3312 | { |
3313 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) != FUNCTION_DECL) |
3314 | { |
3315 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
3316 | *no_add_attrs = true; |
3317 | } |
3318 | |
3319 | return NULL_TREE(tree) nullptr; |
3320 | } |
3321 | |
3322 | /* If ALLOC_DECL and DEALLOC_DECL are a pair of user-defined functions, |
3323 | if they are declared inline issue warnings and return null. Otherwise |
3324 | create attribute noinline, install it in ALLOC_DECL, and return it. |
3325 | Otherwise return null. */ |
3326 | |
3327 | static tree |
3328 | maybe_add_noinline (tree name, tree alloc_decl, tree dealloc_decl, |
3329 | bool *no_add_attrs) |
3330 | { |
3331 | if (fndecl_built_in_p (alloc_decl) || fndecl_built_in_p (dealloc_decl)) |
3332 | return NULL_TREE(tree) nullptr; |
3333 | |
3334 | /* When inlining (or optimization) is enabled and the allocator and |
3335 | deallocator are not built-in functions, ignore the attribute on |
3336 | functions declared inline since it could lead to false positives |
3337 | when inlining one or the other call would wind up calling |
3338 | a mismatched allocator or deallocator. */ |
3339 | if ((optimizeglobal_options.x_optimize && DECL_DECLARED_INLINE_P (alloc_decl)((tree_check ((alloc_decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3339, __FUNCTION__, (FUNCTION_DECL)))->function_decl.declared_inline_flag )) |
3340 | || lookup_attribute ("always_inline", DECL_ATTRIBUTES (alloc_decl)((contains_struct_check ((alloc_decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3340, __FUNCTION__))->decl_common.attributes))) |
3341 | { |
3342 | warning (OPT_Wattributes, |
3343 | "%<%E (%E)%> attribute ignored on functions " |
3344 | "declared %qs", name, DECL_NAME (dealloc_decl)((contains_struct_check ((dealloc_decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3344, __FUNCTION__))->decl_minimal.name), "inline"); |
3345 | *no_add_attrs = true; |
3346 | return NULL_TREE(tree) nullptr; |
3347 | } |
3348 | |
3349 | if ((optimizeglobal_options.x_optimize && DECL_DECLARED_INLINE_P (dealloc_decl)((tree_check ((dealloc_decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3349, __FUNCTION__, (FUNCTION_DECL)))->function_decl.declared_inline_flag )) |
3350 | || lookup_attribute ("always_inline", DECL_ATTRIBUTES (dealloc_decl)((contains_struct_check ((dealloc_decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3350, __FUNCTION__))->decl_common.attributes))) |
3351 | { |
3352 | warning (OPT_Wattributes, |
3353 | "%<%E (%E)%> attribute ignored with deallocation " |
3354 | "functions declared %qs", |
3355 | name, DECL_NAME (dealloc_decl)((contains_struct_check ((dealloc_decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3355, __FUNCTION__))->decl_minimal.name), "inline"); |
3356 | inform (DECL_SOURCE_LOCATION (dealloc_decl)((contains_struct_check ((dealloc_decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3356, __FUNCTION__))->decl_minimal.locus), |
3357 | "deallocation function declared here" ); |
3358 | *no_add_attrs = true; |
3359 | return NULL_TREE(tree) nullptr; |
3360 | } |
3361 | |
3362 | /* Disable inlining for non-standard deallocators to avoid false |
3363 | positives due to mismatches between the inlined implementation |
3364 | of one and not the other pair of functions. */ |
3365 | tree attr = tree_cons (get_identifier ("noinline")(__builtin_constant_p ("noinline") ? get_identifier_with_length (("noinline"), strlen ("noinline")) : get_identifier ("noinline" )), NULL_TREE(tree) nullptr, NULL_TREE(tree) nullptr); |
3366 | decl_attributes (&alloc_decl, attr, 0); |
3367 | return attr; |
3368 | } |
3369 | |
3370 | /* Handle the "malloc" attribute. */ |
3371 | |
3372 | static tree |
3373 | handle_malloc_attribute (tree *node, tree name, tree args, int flags, |
3374 | bool *no_add_attrs) |
3375 | { |
3376 | if (flags & ATTR_FLAG_INTERNAL) |
3377 | /* Recursive call. */ |
3378 | return NULL_TREE(tree) nullptr; |
3379 | |
3380 | tree fndecl = *node; |
3381 | |
3382 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) != FUNCTION_DECL) |
3383 | { |
3384 | warning (OPT_Wattributes, "%qE attribute ignored; valid only " |
3385 | "for functions", |
3386 | name); |
3387 | *no_add_attrs = true; |
3388 | return NULL_TREE(tree) nullptr; |
3389 | } |
3390 | |
3391 | tree rettype = TREE_TYPE (TREE_TYPE (*node))((contains_struct_check ((((contains_struct_check ((*node), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3391, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3391, __FUNCTION__))->typed.type); |
3392 | if (!POINTER_TYPE_P (rettype)(((enum tree_code) (rettype)->base.code) == POINTER_TYPE || ((enum tree_code) (rettype)->base.code) == REFERENCE_TYPE )) |
3393 | { |
3394 | warning (OPT_Wattributes, "%qE attribute ignored on functions " |
3395 | "returning %qT; valid only for pointer return types", |
3396 | name, rettype); |
3397 | *no_add_attrs = true; |
3398 | return NULL_TREE(tree) nullptr; |
3399 | } |
3400 | |
3401 | if (!args) |
3402 | { |
3403 | /* Only the form of the attribute with no arguments declares |
3404 | a function malloc-like. */ |
3405 | DECL_IS_MALLOC (*node)((tree_check ((*node), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3405, __FUNCTION__, (FUNCTION_DECL)))->function_decl.malloc_flag ) = 1; |
3406 | return NULL_TREE(tree) nullptr; |
3407 | } |
3408 | |
3409 | tree dealloc = TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3409, __FUNCTION__, (TREE_LIST)))->list.value); |
3410 | if (error_operand_p (dealloc)) |
3411 | { |
3412 | /* If the argument is in error it will have already been diagnosed. |
3413 | Avoid issuing redundant errors here. */ |
3414 | *no_add_attrs = true; |
3415 | return NULL_TREE(tree) nullptr; |
3416 | } |
3417 | |
3418 | STRIP_NOPS (dealloc)(dealloc) = tree_strip_nop_conversions ((const_cast<union tree_node *> (((dealloc))))); |
3419 | if (TREE_CODE (dealloc)((enum tree_code) (dealloc)->base.code) == ADDR_EXPR) |
3420 | { |
3421 | /* In C++ the argument may be wrapped in a cast to disambiguate |
3422 | one of a number of overloads (such as operator delete). To |
3423 | make things interesting, the cast looks different between |
3424 | different C++ versions. Strip it and install the attribute |
3425 | with the disambiguated function. */ |
3426 | dealloc = TREE_OPERAND (dealloc, 0)(*((const_cast<tree*> (tree_operand_check ((dealloc), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3426, __FUNCTION__))))); |
3427 | |
3428 | *no_add_attrs = true; |
3429 | tree attr = tree_cons (NULL_TREE(tree) nullptr, dealloc, TREE_CHAIN (args)((contains_struct_check ((args), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3429, __FUNCTION__))->common.chain)); |
3430 | attr = build_tree_list (name, attr); |
3431 | return decl_attributes (node, attr, 0); |
3432 | } |
3433 | |
3434 | if (TREE_CODE (dealloc)((enum tree_code) (dealloc)->base.code) != FUNCTION_DECL) |
3435 | { |
3436 | if (TREE_CODE (dealloc)((enum tree_code) (dealloc)->base.code) == OVERLOAD) |
3437 | { |
3438 | /* Handle specially the common case of specifying one of a number |
3439 | of overloads, such as operator delete. */ |
3440 | error ("%qE attribute argument 1 is ambiguous", name); |
3441 | inform (input_location, |
3442 | "use a cast to the expected type to disambiguate"); |
3443 | *no_add_attrs = true; |
3444 | return NULL_TREE(tree) nullptr; |
3445 | } |
3446 | |
3447 | error ("%qE attribute argument 1 does not name a function", name); |
3448 | if (DECL_P (dealloc)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (dealloc)->base.code))] == tcc_declaration)) |
3449 | inform (DECL_SOURCE_LOCATION (dealloc)((contains_struct_check ((dealloc), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3449, __FUNCTION__))->decl_minimal.locus), |
3450 | "argument references a symbol declared here"); |
3451 | *no_add_attrs = true; |
3452 | return NULL_TREE(tree) nullptr; |
3453 | } |
3454 | |
3455 | /* Mentioning the deallocation function qualifies as its use. */ |
3456 | TREE_USED (dealloc)((dealloc)->base.used_flag) = 1; |
3457 | |
3458 | tree fntype = TREE_TYPE (dealloc)((contains_struct_check ((dealloc), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3458, __FUNCTION__))->typed.type); |
3459 | tree argpos = TREE_CHAIN (args)((contains_struct_check ((args), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3459, __FUNCTION__))->common.chain) ? TREE_VALUE (TREE_CHAIN (args))((tree_check ((((contains_struct_check ((args), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3459, __FUNCTION__))->common.chain)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3459, __FUNCTION__, (TREE_LIST)))->list.value) : NULL_TREE(tree) nullptr; |
3460 | if (!argpos) |
3461 | { |
3462 | tree argtypes = TYPE_ARG_TYPES (fntype)((tree_check2 ((fntype), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3462, __FUNCTION__, (FUNCTION_TYPE), (METHOD_TYPE)))->type_non_common .values); |
3463 | if (!argtypes) |
3464 | { |
3465 | /* Reject functions without a prototype. */ |
3466 | error ("%qE attribute argument 1 must take a pointer " |
3467 | "type as its first argument", name); |
3468 | inform (DECL_SOURCE_LOCATION (dealloc)((contains_struct_check ((dealloc), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3468, __FUNCTION__))->decl_minimal.locus), |
3469 | "referenced symbol declared here"); |
3470 | *no_add_attrs = true; |
3471 | return NULL_TREE(tree) nullptr; |
3472 | } |
3473 | |
3474 | tree argtype = TREE_VALUE (argtypes)((tree_check ((argtypes), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3474, __FUNCTION__, (TREE_LIST)))->list.value); |
3475 | if (TREE_CODE (argtype)((enum tree_code) (argtype)->base.code) != POINTER_TYPE) |
3476 | { |
3477 | /* Reject functions that don't take a pointer as their first |
3478 | argument. */ |
3479 | error ("%qE attribute argument 1 must take a pointer type " |
3480 | "as its first argument; have %qT", name, argtype); |
3481 | inform (DECL_SOURCE_LOCATION (dealloc)((contains_struct_check ((dealloc), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3481, __FUNCTION__))->decl_minimal.locus), |
3482 | "referenced symbol declared here"); |
3483 | *no_add_attrs = true; |
3484 | return NULL_TREE(tree) nullptr; |
3485 | } |
3486 | |
3487 | /* Disable inlining for non-standard deallocators to avoid false |
3488 | positives (or warn if either function is explicitly inline). */ |
3489 | tree at_noinline = |
3490 | maybe_add_noinline (name, fndecl, dealloc, no_add_attrs); |
3491 | if (*no_add_attrs) |
3492 | return NULL_TREE(tree) nullptr; |
3493 | |
3494 | /* Add attribute *dealloc to the deallocator function associating |
3495 | it with this one. Ideally, the attribute would reference |
3496 | the DECL of the deallocator but since that changes for each |
3497 | redeclaration, use DECL_NAME instead. (DECL_ASSEMBLER_NAME |
3498 | need not be set at this point and setting it here is too early. */ |
3499 | tree attrs = build_tree_list (NULL_TREE(tree) nullptr, DECL_NAME (fndecl)((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3499, __FUNCTION__))->decl_minimal.name)); |
3500 | attrs = tree_cons (get_identifier ("*dealloc")(__builtin_constant_p ("*dealloc") ? get_identifier_with_length (("*dealloc"), strlen ("*dealloc")) : get_identifier ("*dealloc" )), attrs, at_noinline); |
3501 | decl_attributes (&dealloc, attrs, 0); |
3502 | return NULL_TREE(tree) nullptr; |
3503 | } |
3504 | |
3505 | /* Validate the positional argument. */ |
3506 | argpos = positional_argument (fntype, name, argpos, POINTER_TYPE); |
3507 | if (!argpos) |
3508 | { |
3509 | *no_add_attrs = true; |
3510 | return NULL_TREE(tree) nullptr; |
3511 | } |
3512 | |
3513 | /* As above, disable inlining for non-standard deallocators to avoid |
3514 | false positives (or warn). */ |
3515 | tree at_noinline = |
3516 | maybe_add_noinline (name, fndecl, dealloc, no_add_attrs); |
3517 | if (*no_add_attrs) |
3518 | return NULL_TREE(tree) nullptr; |
3519 | |
3520 | /* It's valid to declare the same function with multiple instances |
3521 | of attribute malloc, each naming the same or different deallocator |
3522 | functions, and each referencing either the same or a different |
3523 | positional argument. */ |
3524 | tree attrs = tree_cons (NULL_TREE(tree) nullptr, argpos, NULL_TREE(tree) nullptr); |
3525 | attrs = tree_cons (NULL_TREE(tree) nullptr, DECL_NAME (fndecl)((contains_struct_check ((fndecl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3525, __FUNCTION__))->decl_minimal.name), attrs); |
3526 | attrs = tree_cons (get_identifier ("*dealloc")(__builtin_constant_p ("*dealloc") ? get_identifier_with_length (("*dealloc"), strlen ("*dealloc")) : get_identifier ("*dealloc" )), attrs, at_noinline); |
3527 | decl_attributes (&dealloc, attrs, 0); |
3528 | return NULL_TREE(tree) nullptr; |
3529 | } |
3530 | |
3531 | /* Handle the internal "*dealloc" attribute added for functions declared |
3532 | with the one- and two-argument forms of attribute malloc. Add it |
3533 | to *NODE unless it's already there with the same arguments. */ |
3534 | |
3535 | static tree |
3536 | handle_dealloc_attribute (tree *node, tree name, tree args, int, |
3537 | bool *no_add_attrs) |
3538 | { |
3539 | tree fndecl = *node; |
3540 | |
3541 | tree attrs = DECL_ATTRIBUTES (fndecl)((contains_struct_check ((fndecl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3541, __FUNCTION__))->decl_common.attributes); |
3542 | if (!attrs) |
3543 | return NULL_TREE(tree) nullptr; |
3544 | |
3545 | tree arg = TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3545, __FUNCTION__, (TREE_LIST)))->list.value); |
3546 | args = TREE_CHAIN (args)((contains_struct_check ((args), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3546, __FUNCTION__))->common.chain); |
3547 | tree arg_pos = args ? TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3547, __FUNCTION__, (TREE_LIST)))->list.value) : integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]; |
3548 | |
3549 | gcc_checking_assert ((DECL_P (arg)((void)(!(((tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) (arg)->base.code))] == tcc_declaration ) && fndecl_built_in_p (arg, BUILT_IN_NORMAL)) || ((enum tree_code) (arg)->base.code) == IDENTIFIER_NODE) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3551, __FUNCTION__), 0 : 0)) |
3550 | && fndecl_built_in_p (arg, BUILT_IN_NORMAL))((void)(!(((tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) (arg)->base.code))] == tcc_declaration ) && fndecl_built_in_p (arg, BUILT_IN_NORMAL)) || ((enum tree_code) (arg)->base.code) == IDENTIFIER_NODE) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3551, __FUNCTION__), 0 : 0)) |
3551 | || TREE_CODE (arg) == IDENTIFIER_NODE)((void)(!(((tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) (arg)->base.code))] == tcc_declaration ) && fndecl_built_in_p (arg, BUILT_IN_NORMAL)) || ((enum tree_code) (arg)->base.code) == IDENTIFIER_NODE) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3551, __FUNCTION__), 0 : 0)); |
3552 | |
3553 | const char* const namestr = IDENTIFIER_POINTER (name)((const char *) (tree_check ((name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3553, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ); |
3554 | for (tree at = attrs; (at = lookup_attribute (namestr, at)); |
3555 | at = TREE_CHAIN (at)((contains_struct_check ((at), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3555, __FUNCTION__))->common.chain)) |
3556 | { |
3557 | tree alloc = TREE_VALUE (at)((tree_check ((at), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3557, __FUNCTION__, (TREE_LIST)))->list.value); |
3558 | if (!alloc) |
3559 | continue; |
3560 | |
3561 | tree pos = TREE_CHAIN (alloc)((contains_struct_check ((alloc), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3561, __FUNCTION__))->common.chain); |
3562 | alloc = TREE_VALUE (alloc)((tree_check ((alloc), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3562, __FUNCTION__, (TREE_LIST)))->list.value); |
3563 | pos = pos ? TREE_VALUE (pos)((tree_check ((pos), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3563, __FUNCTION__, (TREE_LIST)))->list.value) : integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]; |
3564 | gcc_checking_assert ((DECL_P (alloc)((void)(!(((tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) (alloc)->base.code))] == tcc_declaration ) && fndecl_built_in_p (alloc, BUILT_IN_NORMAL)) || ( (enum tree_code) (alloc)->base.code) == IDENTIFIER_NODE) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3566, __FUNCTION__), 0 : 0)) |
3565 | && fndecl_built_in_p (alloc, BUILT_IN_NORMAL))((void)(!(((tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) (alloc)->base.code))] == tcc_declaration ) && fndecl_built_in_p (alloc, BUILT_IN_NORMAL)) || ( (enum tree_code) (alloc)->base.code) == IDENTIFIER_NODE) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3566, __FUNCTION__), 0 : 0)) |
3566 | || TREE_CODE (alloc) == IDENTIFIER_NODE)((void)(!(((tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) (alloc)->base.code))] == tcc_declaration ) && fndecl_built_in_p (alloc, BUILT_IN_NORMAL)) || ( (enum tree_code) (alloc)->base.code) == IDENTIFIER_NODE) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3566, __FUNCTION__), 0 : 0)); |
3567 | |
3568 | if (alloc == arg && tree_int_cst_equal (pos, arg_pos)) |
3569 | { |
3570 | /* The function already has the attribute either without any |
3571 | arguments or with the same arguments as the attribute that's |
3572 | being added. Return without adding another copy. */ |
3573 | *no_add_attrs = true; |
3574 | return NULL_TREE(tree) nullptr; |
3575 | } |
3576 | } |
3577 | |
3578 | return NULL_TREE(tree) nullptr; |
3579 | } |
3580 | |
3581 | /* Handle the "alloc_size (argpos1 [, argpos2])" function type attribute. |
3582 | *NODE is the type of the function the attribute is being applied to. */ |
3583 | |
3584 | static tree |
3585 | handle_alloc_size_attribute (tree *node, tree name, tree args, |
3586 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), bool *no_add_attrs) |
3587 | { |
3588 | tree fntype = *node; |
3589 | tree rettype = TREE_TYPE (fntype)((contains_struct_check ((fntype), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3589, __FUNCTION__))->typed.type); |
3590 | if (!POINTER_TYPE_P (rettype)(((enum tree_code) (rettype)->base.code) == POINTER_TYPE || ((enum tree_code) (rettype)->base.code) == REFERENCE_TYPE )) |
3591 | { |
3592 | warning (OPT_Wattributes, |
3593 | "%qE attribute ignored on a function returning %qT", |
3594 | name, rettype); |
3595 | *no_add_attrs = true; |
3596 | return NULL_TREE(tree) nullptr; |
3597 | } |
3598 | |
3599 | tree newargs[2] = { NULL_TREE(tree) nullptr, NULL_TREE(tree) nullptr }; |
3600 | for (int i = 1; args; ++i) |
3601 | { |
3602 | tree pos = TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3602, __FUNCTION__, (TREE_LIST)))->list.value); |
3603 | /* NEXT is null when the attribute includes just one argument. |
3604 | That's used to tell positional_argument to avoid mentioning |
3605 | the argument number in diagnostics (since there's just one |
3606 | mentioning it is unnecessary and coule be confusing). */ |
3607 | tree next = TREE_CHAIN (args)((contains_struct_check ((args), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3607, __FUNCTION__))->common.chain); |
3608 | if (tree val = positional_argument (fntype, name, pos, INTEGER_TYPE, |
3609 | next || i > 1 ? i : 0)) |
3610 | { |
3611 | TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3611, __FUNCTION__, (TREE_LIST)))->list.value) = val; |
3612 | newargs[i - 1] = val; |
3613 | } |
3614 | else |
3615 | { |
3616 | *no_add_attrs = true; |
3617 | return NULL_TREE(tree) nullptr; |
3618 | } |
3619 | |
3620 | args = next; |
3621 | } |
3622 | |
3623 | if (!validate_attr_args (node, name, newargs)) |
3624 | *no_add_attrs = true; |
3625 | |
3626 | return NULL_TREE(tree) nullptr; |
3627 | } |
3628 | |
3629 | |
3630 | /* Handle an "alloc_align (argpos)" attribute. */ |
3631 | |
3632 | static tree |
3633 | handle_alloc_align_attribute (tree *node, tree name, tree args, int, |
3634 | bool *no_add_attrs) |
3635 | { |
3636 | tree fntype = *node; |
3637 | tree rettype = TREE_TYPE (fntype)((contains_struct_check ((fntype), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3637, __FUNCTION__))->typed.type); |
3638 | if (!POINTER_TYPE_P (rettype)(((enum tree_code) (rettype)->base.code) == POINTER_TYPE || ((enum tree_code) (rettype)->base.code) == REFERENCE_TYPE )) |
3639 | { |
3640 | warning (OPT_Wattributes, |
3641 | "%qE attribute ignored on a function returning %qT", |
3642 | name, rettype); |
3643 | *no_add_attrs = true; |
3644 | return NULL_TREE(tree) nullptr; |
3645 | } |
3646 | |
3647 | if (tree val = positional_argument (*node, name, TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3647, __FUNCTION__, (TREE_LIST)))->list.value), |
3648 | INTEGER_TYPE)) |
3649 | if (validate_attr_arg (node, name, val)) |
3650 | return NULL_TREE(tree) nullptr; |
3651 | |
3652 | *no_add_attrs = true; |
3653 | return NULL_TREE(tree) nullptr; |
3654 | } |
3655 | |
3656 | /* Handle a "assume_aligned" attribute; arguments as in |
3657 | struct attribute_spec.handler. */ |
3658 | |
3659 | static tree |
3660 | handle_assume_aligned_attribute (tree *node, tree name, tree args, int, |
3661 | bool *no_add_attrs) |
3662 | { |
3663 | tree decl = *node; |
3664 | tree rettype = TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3664, __FUNCTION__))->typed.type); |
3665 | if (TREE_CODE (rettype)((enum tree_code) (rettype)->base.code) != POINTER_TYPE) |
3666 | { |
3667 | warning (OPT_Wattributes, |
3668 | "%qE attribute ignored on a function returning %qT", |
3669 | name, rettype); |
3670 | *no_add_attrs = true; |
3671 | return NULL_TREE(tree) nullptr; |
3672 | } |
3673 | |
3674 | /* The alignment specified by the first argument. */ |
3675 | tree align = NULL_TREE(tree) nullptr; |
3676 | |
3677 | for (; args; args = TREE_CHAIN (args)((contains_struct_check ((args), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3677, __FUNCTION__))->common.chain)) |
3678 | { |
3679 | tree val = TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3679, __FUNCTION__, (TREE_LIST)))->list.value); |
3680 | if (val && TREE_CODE (val)((enum tree_code) (val)->base.code) != IDENTIFIER_NODE |
3681 | && TREE_CODE (val)((enum tree_code) (val)->base.code) != FUNCTION_DECL) |
3682 | val = default_conversion (val); |
3683 | |
3684 | if (!tree_fits_shwi_p (val)) |
3685 | { |
3686 | warning (OPT_Wattributes, |
3687 | "%qE attribute argument %E is not an integer constant", |
3688 | name, val); |
3689 | *no_add_attrs = true; |
3690 | return NULL_TREE(tree) nullptr; |
3691 | } |
3692 | else if (tree_int_cst_sgn (val) < 0) |
3693 | { |
3694 | warning (OPT_Wattributes, |
3695 | "%qE attribute argument %E is not positive", name, val); |
3696 | *no_add_attrs = true; |
3697 | return NULL_TREE(tree) nullptr; |
3698 | } |
3699 | |
3700 | if (!align) |
3701 | { |
3702 | /* Validate and save the alignment. */ |
3703 | if (!integer_pow2p (val)) |
3704 | { |
3705 | warning (OPT_Wattributes, |
3706 | "%qE attribute argument %E is not a power of 2", |
3707 | name, val); |
3708 | *no_add_attrs = true; |
3709 | return NULL_TREE(tree) nullptr; |
3710 | } |
3711 | |
3712 | align = val; |
3713 | } |
3714 | else if (tree_int_cst_le (align, val)) |
3715 | { |
3716 | /* The misalignment specified by the second argument |
3717 | must be non-negative and less than the alignment. */ |
3718 | warning (OPT_Wattributes, |
3719 | "%qE attribute argument %E is not in the range [0, %wu]", |
3720 | name, val, tree_to_uhwi (align) - 1); |
3721 | *no_add_attrs = true; |
3722 | return NULL_TREE(tree) nullptr; |
3723 | } |
3724 | } |
3725 | return NULL_TREE(tree) nullptr; |
3726 | } |
3727 | |
3728 | /* Handle the internal-only "arg spec" attribute. */ |
3729 | |
3730 | static tree |
3731 | handle_argspec_attribute (tree *, tree, tree args, int, bool *) |
3732 | { |
3733 | /* Verify the attribute has one or two arguments and their kind. */ |
3734 | gcc_assert (args && TREE_CODE (TREE_VALUE (args)) == STRING_CST)((void)(!(args && ((enum tree_code) (((tree_check ((args ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3734, __FUNCTION__, (TREE_LIST)))->list.value))->base .code) == STRING_CST) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3734, __FUNCTION__), 0 : 0)); |
3735 | for (tree next = TREE_CHAIN (args)((contains_struct_check ((args), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3735, __FUNCTION__))->common.chain); next; next = TREE_CHAIN (next)((contains_struct_check ((next), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3735, __FUNCTION__))->common.chain)) |
3736 | { |
3737 | tree val = TREE_VALUE (next)((tree_check ((next), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3737, __FUNCTION__, (TREE_LIST)))->list.value); |
3738 | gcc_assert (DECL_P (val) || EXPR_P (val))((void)(!((tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) (val)->base.code))] == tcc_declaration ) || ((tree_code_type_tmpl <0>::tree_code_type[(int) (( (enum tree_code) (val)->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (val)->base.code))]) <= tcc_expression)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3738, __FUNCTION__), 0 : 0)); |
3739 | } |
3740 | return NULL_TREE(tree) nullptr; |
3741 | } |
3742 | |
3743 | /* Handle the internal-only "fn spec" attribute. */ |
3744 | |
3745 | static tree |
3746 | handle_fnspec_attribute (tree *node ATTRIBUTE_UNUSED__attribute__ ((__unused__)), tree ARG_UNUSED (name)name __attribute__ ((__unused__)), |
3747 | tree args, int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), |
3748 | bool *no_add_attrs ATTRIBUTE_UNUSED__attribute__ ((__unused__))) |
3749 | { |
3750 | gcc_assert (args((void)(!(args && ((enum tree_code) (((tree_check ((args ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3751, __FUNCTION__, (TREE_LIST)))->list.value))->base .code) == STRING_CST && !((contains_struct_check ((args ), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3752, __FUNCTION__))->common.chain)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3752, __FUNCTION__), 0 : 0)) |
3751 | && TREE_CODE (TREE_VALUE (args)) == STRING_CST((void)(!(args && ((enum tree_code) (((tree_check ((args ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3751, __FUNCTION__, (TREE_LIST)))->list.value))->base .code) == STRING_CST && !((contains_struct_check ((args ), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3752, __FUNCTION__))->common.chain)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3752, __FUNCTION__), 0 : 0)) |
3752 | && !TREE_CHAIN (args))((void)(!(args && ((enum tree_code) (((tree_check ((args ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3751, __FUNCTION__, (TREE_LIST)))->list.value))->base .code) == STRING_CST && !((contains_struct_check ((args ), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3752, __FUNCTION__))->common.chain)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3752, __FUNCTION__), 0 : 0)); |
3753 | return NULL_TREE(tree) nullptr; |
3754 | } |
3755 | |
3756 | /* Handle a "warn_unused" attribute; arguments as in |
3757 | struct attribute_spec.handler. */ |
3758 | |
3759 | static tree |
3760 | handle_warn_unused_attribute (tree *node, tree name, |
3761 | tree args ATTRIBUTE_UNUSED__attribute__ ((__unused__)), |
3762 | int flags ATTRIBUTE_UNUSED__attribute__ ((__unused__)), bool *no_add_attrs) |
3763 | { |
3764 | if (TYPE_P (*node)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (*node)->base.code))] == tcc_type)) |
3765 | /* Do nothing else, just set the attribute. We'll get at |
3766 | it later with lookup_attribute. */ |
3767 | ; |
3768 | else |
3769 | { |
3770 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
3771 | *no_add_attrs = true; |
3772 | } |
3773 | |
3774 | return NULL_TREE(tree) nullptr; |
3775 | } |
3776 | |
3777 | /* Handle an "omp declare simd" attribute; arguments as in |
3778 | struct attribute_spec.handler. */ |
3779 | |
3780 | static tree |
3781 | handle_omp_declare_simd_attribute (tree *, tree, tree, int, bool *) |
3782 | { |
3783 | return NULL_TREE(tree) nullptr; |
3784 | } |
3785 | |
3786 | /* Handle an "omp declare variant {base,variant}" attribute; arguments as in |
3787 | struct attribute_spec.handler. */ |
3788 | |
3789 | static tree |
3790 | handle_omp_declare_variant_attribute (tree *, tree, tree, int, bool *) |
3791 | { |
3792 | return NULL_TREE(tree) nullptr; |
3793 | } |
3794 | |
3795 | /* Handle a "simd" attribute. */ |
3796 | |
3797 | static tree |
3798 | handle_simd_attribute (tree *node, tree name, tree args, int, bool *no_add_attrs) |
3799 | { |
3800 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) == FUNCTION_DECL) |
3801 | { |
3802 | tree t = get_identifier ("omp declare simd")(__builtin_constant_p ("omp declare simd") ? get_identifier_with_length (("omp declare simd"), strlen ("omp declare simd")) : get_identifier ("omp declare simd")); |
3803 | tree attr = NULL_TREE(tree) nullptr; |
3804 | if (args) |
3805 | { |
3806 | tree id = TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3806, __FUNCTION__, (TREE_LIST)))->list.value); |
3807 | |
3808 | if (TREE_CODE (id)((enum tree_code) (id)->base.code) != STRING_CST) |
3809 | { |
3810 | error ("attribute %qE argument not a string", name); |
3811 | *no_add_attrs = true; |
3812 | return NULL_TREE(tree) nullptr; |
3813 | } |
3814 | |
3815 | if (strcmp (TREE_STRING_POINTER (id)((const char *)((tree_check ((id), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3815, __FUNCTION__, (STRING_CST)))->string.str)), "notinbranch") == 0) |
3816 | attr = build_omp_clause (DECL_SOURCE_LOCATION (*node)((contains_struct_check ((*node), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3816, __FUNCTION__))->decl_minimal.locus), |
3817 | OMP_CLAUSE_NOTINBRANCH); |
3818 | else if (strcmp (TREE_STRING_POINTER (id)((const char *)((tree_check ((id), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3818, __FUNCTION__, (STRING_CST)))->string.str)), "inbranch") == 0) |
3819 | attr = build_omp_clause (DECL_SOURCE_LOCATION (*node)((contains_struct_check ((*node), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3819, __FUNCTION__))->decl_minimal.locus), |
3820 | OMP_CLAUSE_INBRANCH); |
3821 | else |
3822 | { |
3823 | error ("only %<inbranch%> and %<notinbranch%> flags are " |
3824 | "allowed for %<__simd__%> attribute"); |
3825 | *no_add_attrs = true; |
3826 | return NULL_TREE(tree) nullptr; |
3827 | } |
3828 | } |
3829 | |
3830 | DECL_ATTRIBUTES (*node)((contains_struct_check ((*node), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3830, __FUNCTION__))->decl_common.attributes) |
3831 | = tree_cons (t, build_tree_list (NULL_TREE(tree) nullptr, attr), |
3832 | DECL_ATTRIBUTES (*node)((contains_struct_check ((*node), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3832, __FUNCTION__))->decl_common.attributes)); |
3833 | } |
3834 | else |
3835 | { |
3836 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
3837 | *no_add_attrs = true; |
3838 | } |
3839 | |
3840 | return NULL_TREE(tree) nullptr; |
3841 | } |
3842 | |
3843 | /* Handle an "omp declare target" attribute; arguments as in |
3844 | struct attribute_spec.handler. */ |
3845 | |
3846 | static tree |
3847 | handle_omp_declare_target_attribute (tree *, tree, tree, int, bool *) |
3848 | { |
3849 | return NULL_TREE(tree) nullptr; |
3850 | } |
3851 | |
3852 | /* Handle an "non overlapping" attribute; arguments as in |
3853 | struct attribute_spec.handler. */ |
3854 | |
3855 | static tree |
3856 | handle_non_overlapping_attribute (tree *, tree, tree, int, bool *) |
3857 | { |
3858 | return NULL_TREE(tree) nullptr; |
3859 | } |
3860 | |
3861 | /* Handle a "returns_twice" attribute; arguments as in |
3862 | struct attribute_spec.handler. */ |
3863 | |
3864 | static tree |
3865 | handle_returns_twice_attribute (tree *node, tree name, tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
3866 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), bool *no_add_attrs) |
3867 | { |
3868 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) == FUNCTION_DECL) |
3869 | DECL_IS_RETURNS_TWICE (*node)((tree_check ((*node), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3869, __FUNCTION__, (FUNCTION_DECL)))->function_decl.returns_twice_flag ) = 1; |
3870 | else |
3871 | { |
3872 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
3873 | *no_add_attrs = true; |
3874 | } |
3875 | |
3876 | return NULL_TREE(tree) nullptr; |
3877 | } |
3878 | |
3879 | /* Handle a "no_limit_stack" attribute; arguments as in |
3880 | struct attribute_spec.handler. */ |
3881 | |
3882 | static tree |
3883 | handle_no_limit_stack_attribute (tree *node, tree name, |
3884 | tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
3885 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), |
3886 | bool *no_add_attrs) |
3887 | { |
3888 | tree decl = *node; |
3889 | |
3890 | if (TREE_CODE (decl)((enum tree_code) (decl)->base.code) != FUNCTION_DECL) |
3891 | { |
3892 | error_at (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3892, __FUNCTION__))->decl_minimal.locus), |
3893 | "%qE attribute applies only to functions", name); |
3894 | *no_add_attrs = true; |
3895 | } |
3896 | else if (DECL_INITIAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3896, __FUNCTION__))->decl_common.initial)) |
3897 | { |
3898 | error_at (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3898, __FUNCTION__))->decl_minimal.locus), |
3899 | "cannot set %qE attribute after definition", name); |
3900 | *no_add_attrs = true; |
3901 | } |
3902 | else |
3903 | DECL_NO_LIMIT_STACK (decl)((tree_check ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3903, __FUNCTION__, (FUNCTION_DECL)))->function_decl.no_limit_stack ) = 1; |
3904 | |
3905 | return NULL_TREE(tree) nullptr; |
3906 | } |
3907 | |
3908 | /* Handle a "pure" attribute; arguments as in |
3909 | struct attribute_spec.handler. */ |
3910 | |
3911 | static tree |
3912 | handle_pure_attribute (tree *node, tree name, tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
3913 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), bool *no_add_attrs) |
3914 | { |
3915 | if (TREE_CODE (*node)((enum tree_code) (*node)->base.code) == FUNCTION_DECL) |
3916 | { |
3917 | tree type = TREE_TYPE (*node)((contains_struct_check ((*node), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3917, __FUNCTION__))->typed.type); |
3918 | if (VOID_TYPE_P (TREE_TYPE (type))(((enum tree_code) (((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3918, __FUNCTION__))->typed.type))->base.code) == VOID_TYPE )) |
3919 | warning (OPT_Wattributes, "%qE attribute on function " |
3920 | "returning %<void%>", name); |
3921 | |
3922 | DECL_PURE_P (*node)((tree_check ((*node), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3922, __FUNCTION__, (FUNCTION_DECL)))->function_decl.pure_flag ) = 1; |
3923 | /* ??? TODO: Support types. */ |
3924 | } |
3925 | else |
3926 | { |
3927 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
3928 | *no_add_attrs = true; |
3929 | } |
3930 | |
3931 | return NULL_TREE(tree) nullptr; |
3932 | } |
3933 | |
3934 | /* Digest an attribute list destined for a transactional memory statement. |
3935 | ALLOWED is the set of attributes that are allowed for this statement; |
3936 | return the attribute we parsed. Multiple attributes are never allowed. */ |
3937 | |
3938 | int |
3939 | parse_tm_stmt_attr (tree attrs, int allowed) |
3940 | { |
3941 | tree a_seen = NULLnullptr; |
3942 | int m_seen = 0; |
3943 | |
3944 | for ( ; attrs ; attrs = TREE_CHAIN (attrs)((contains_struct_check ((attrs), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3944, __FUNCTION__))->common.chain)) |
3945 | { |
3946 | tree a = get_attribute_name (attrs); |
3947 | tree ns = get_attribute_namespace (attrs); |
3948 | int m = 0; |
3949 | |
3950 | if (is_attribute_p ("outer", a) |
3951 | && (ns == NULL_TREE(tree) nullptr || strcmp (IDENTIFIER_POINTER (ns)((const char *) (tree_check ((ns), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 3951, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), "gnu") == 0)) |
3952 | m = TM_STMT_ATTR_OUTER2; |
3953 | |
3954 | if ((m & allowed) == 0) |
3955 | { |
3956 | warning (OPT_Wattributes, "%qE attribute directive ignored", a); |
3957 | continue; |
3958 | } |
3959 | |
3960 | if (m_seen == 0) |
3961 | { |
3962 | a_seen = a; |
3963 | m_seen = m; |
3964 | } |
3965 | else if (m_seen == m) |
3966 | warning (OPT_Wattributes, "%qE attribute duplicated", a); |
3967 | else |
3968 | warning (OPT_Wattributes, "%qE attribute follows %qE", a, a_seen); |
3969 | } |
3970 | |
3971 | return m_seen; |
3972 | } |
3973 | |
3974 | /* Transform a TM attribute name into a maskable integer and back. |
3975 | Note that NULL (i.e. no attribute) is mapped to UNKNOWN, corresponding |
3976 | to how the lack of an attribute is treated. */ |
3977 | |
3978 | int |
3979 | tm_attr_to_mask (tree attr) |
3980 | { |
3981 | if (attr == NULLnullptr) |
3982 | return 0; |
3983 | if (is_attribute_p ("transaction_safe", attr)) |
3984 | return TM_ATTR_SAFE1; |
3985 | if (is_attribute_p ("transaction_callable", attr)) |
3986 | return TM_ATTR_CALLABLE2; |
3987 | if (is_attribute_p ("transaction_pure", attr)) |
3988 | return TM_ATTR_PURE4; |
3989 | if (is_attribute_p ("transaction_unsafe", attr)) |
3990 | return TM_ATTR_IRREVOCABLE8; |
3991 | if (is_attribute_p ("transaction_may_cancel_outer", attr)) |
3992 | return TM_ATTR_MAY_CANCEL_OUTER16; |
3993 | return 0; |
3994 | } |
3995 | |
3996 | tree |
3997 | tm_mask_to_attr (int mask) |
3998 | { |
3999 | const char *str; |
4000 | switch (mask) |
4001 | { |
4002 | case TM_ATTR_SAFE1: |
4003 | str = "transaction_safe"; |
4004 | break; |
4005 | case TM_ATTR_CALLABLE2: |
4006 | str = "transaction_callable"; |
4007 | break; |
4008 | case TM_ATTR_PURE4: |
4009 | str = "transaction_pure"; |
4010 | break; |
4011 | case TM_ATTR_IRREVOCABLE8: |
4012 | str = "transaction_unsafe"; |
4013 | break; |
4014 | case TM_ATTR_MAY_CANCEL_OUTER16: |
4015 | str = "transaction_may_cancel_outer"; |
4016 | break; |
4017 | default: |
4018 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4018, __FUNCTION__)); |
4019 | } |
4020 | return get_identifier (str)(__builtin_constant_p (str) ? get_identifier_with_length ((str ), strlen (str)) : get_identifier (str)); |
4021 | } |
4022 | |
4023 | /* Return the first TM attribute seen in LIST. */ |
4024 | |
4025 | tree |
4026 | find_tm_attribute (tree list) |
4027 | { |
4028 | for (; list ; list = TREE_CHAIN (list)((contains_struct_check ((list), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4028, __FUNCTION__))->common.chain)) |
4029 | { |
4030 | tree name = get_attribute_name (list); |
4031 | if (tm_attr_to_mask (name) != 0) |
4032 | return name; |
4033 | } |
4034 | return NULL_TREE(tree) nullptr; |
4035 | } |
4036 | |
4037 | /* Handle the TM attributes; arguments as in struct attribute_spec.handler. |
4038 | Here we accept only function types, and verify that none of the other |
4039 | function TM attributes are also applied. */ |
4040 | /* ??? We need to accept class types for C++, but not C. This greatly |
4041 | complicates this function, since we can no longer rely on the extra |
4042 | processing given by function_type_required. */ |
4043 | |
4044 | static tree |
4045 | handle_tm_attribute (tree *node, tree name, tree args, |
4046 | int flags, bool *no_add_attrs) |
4047 | { |
4048 | /* Only one path adds the attribute; others don't. */ |
4049 | *no_add_attrs = true; |
4050 | |
4051 | switch (TREE_CODE (*node)((enum tree_code) (*node)->base.code)) |
4052 | { |
4053 | case RECORD_TYPE: |
4054 | case UNION_TYPE: |
4055 | /* Only tm_callable and tm_safe apply to classes. */ |
4056 | if (tm_attr_to_mask (name) & ~(TM_ATTR_SAFE1 | TM_ATTR_CALLABLE2)) |
4057 | goto ignored; |
4058 | /* FALLTHRU */ |
4059 | |
4060 | case FUNCTION_TYPE: |
4061 | case METHOD_TYPE: |
4062 | { |
4063 | tree old_name = find_tm_attribute (TYPE_ATTRIBUTES (*node)((tree_class_check ((*node), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4063, __FUNCTION__))->type_common.attributes)); |
4064 | if (old_name == name) |
4065 | ; |
4066 | else if (old_name != NULL_TREE(tree) nullptr) |
4067 | error ("type was previously declared %qE", old_name); |
4068 | else |
4069 | *no_add_attrs = false; |
4070 | } |
4071 | break; |
4072 | |
4073 | case FUNCTION_DECL: |
4074 | { |
4075 | /* transaction_safe_dynamic goes on the FUNCTION_DECL, but we also |
4076 | want to set transaction_safe on the type. */ |
4077 | gcc_assert (is_attribute_p ("transaction_safe_dynamic", name))((void)(!(is_attribute_p ("transaction_safe_dynamic", name)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4077, __FUNCTION__), 0 : 0)); |
4078 | if (!TYPE_P (DECL_CONTEXT (*node))(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (((contains_struct_check ((*node), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4078, __FUNCTION__))->decl_minimal.context))->base.code ))] == tcc_type)) |
4079 | error_at (DECL_SOURCE_LOCATION (*node)((contains_struct_check ((*node), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4079, __FUNCTION__))->decl_minimal.locus), |
4080 | "%<transaction_safe_dynamic%> may only be specified for " |
4081 | "a virtual function"); |
4082 | *no_add_attrs = false; |
4083 | decl_attributes (&TREE_TYPE (*node)((contains_struct_check ((*node), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4083, __FUNCTION__))->typed.type), |
4084 | build_tree_list (get_identifier ("transaction_safe")(__builtin_constant_p ("transaction_safe") ? get_identifier_with_length (("transaction_safe"), strlen ("transaction_safe")) : get_identifier ("transaction_safe")), |
4085 | NULL_TREE(tree) nullptr), |
4086 | 0); |
4087 | break; |
4088 | } |
4089 | |
4090 | case POINTER_TYPE: |
4091 | { |
4092 | enum tree_code subcode = TREE_CODE (TREE_TYPE (*node))((enum tree_code) (((contains_struct_check ((*node), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4092, __FUNCTION__))->typed.type))->base.code); |
4093 | if (subcode == FUNCTION_TYPE || subcode == METHOD_TYPE) |
4094 | { |
4095 | tree fn_tmp = TREE_TYPE (*node)((contains_struct_check ((*node), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4095, __FUNCTION__))->typed.type); |
4096 | decl_attributes (&fn_tmp, tree_cons (name, args, NULLnullptr), 0); |
4097 | *node = build_pointer_type (fn_tmp); |
4098 | break; |
4099 | } |
4100 | } |
4101 | /* FALLTHRU */ |
4102 | |
4103 | default: |
4104 | /* If a function is next, pass it on to be tried next. */ |
4105 | if (flags & (int) ATTR_FLAG_FUNCTION_NEXT) |
4106 | return tree_cons (name, args, NULLnullptr); |
4107 | |
4108 | ignored: |
4109 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
4110 | break; |
4111 | } |
4112 | |
4113 | return NULL_TREE(tree) nullptr; |
4114 | } |
4115 | |
4116 | /* Handle the TM_WRAP attribute; arguments as in |
4117 | struct attribute_spec.handler. */ |
4118 | |
4119 | static tree |
4120 | handle_tm_wrap_attribute (tree *node, tree name, tree args, |
4121 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), bool *no_add_attrs) |
4122 | { |
4123 | tree decl = *node; |
4124 | |
4125 | /* We don't need the attribute even on success, since we |
4126 | record the entry in an external table. */ |
4127 | *no_add_attrs = true; |
4128 | |
4129 | if (TREE_CODE (decl)((enum tree_code) (decl)->base.code) != FUNCTION_DECL) |
4130 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
4131 | else |
4132 | { |
4133 | tree wrap_decl = TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4133, __FUNCTION__, (TREE_LIST)))->list.value); |
4134 | if (error_operand_p (wrap_decl)) |
4135 | ; |
4136 | else if (TREE_CODE (wrap_decl)((enum tree_code) (wrap_decl)->base.code) != IDENTIFIER_NODE |
4137 | && !VAR_OR_FUNCTION_DECL_P (wrap_decl)(((enum tree_code) (wrap_decl)->base.code) == VAR_DECL || ( (enum tree_code) (wrap_decl)->base.code) == FUNCTION_DECL)) |
4138 | error ("%qE argument not an identifier", name); |
4139 | else |
4140 | { |
4141 | if (TREE_CODE (wrap_decl)((enum tree_code) (wrap_decl)->base.code) == IDENTIFIER_NODE) |
4142 | wrap_decl = lookup_name (wrap_decl); |
4143 | if (wrap_decl && TREE_CODE (wrap_decl)((enum tree_code) (wrap_decl)->base.code) == FUNCTION_DECL) |
4144 | { |
4145 | if (lang_hooks.types_compatible_p (TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4145, __FUNCTION__))->typed.type), |
4146 | TREE_TYPE (wrap_decl)((contains_struct_check ((wrap_decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4146, __FUNCTION__))->typed.type))) |
4147 | record_tm_replacement (wrap_decl, decl); |
4148 | else |
4149 | error ("%qD is not compatible with %qD", wrap_decl, decl); |
4150 | } |
4151 | else |
4152 | error ("%qE argument is not a function", name); |
4153 | } |
4154 | } |
4155 | |
4156 | return NULL_TREE(tree) nullptr; |
4157 | } |
4158 | |
4159 | /* Ignore the given attribute. Used when this attribute may be usefully |
4160 | overridden by the target, but is not used generically. */ |
4161 | |
4162 | static tree |
4163 | ignore_attribute (tree * ARG_UNUSED (node)node __attribute__ ((__unused__)), tree ARG_UNUSED (name)name __attribute__ ((__unused__)), |
4164 | tree ARG_UNUSED (args)args __attribute__ ((__unused__)), int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), |
4165 | bool *no_add_attrs) |
4166 | { |
4167 | *no_add_attrs = true; |
4168 | return NULL_TREE(tree) nullptr; |
4169 | } |
4170 | |
4171 | /* Handle a "no vops" attribute; arguments as in |
4172 | struct attribute_spec.handler. */ |
4173 | |
4174 | static tree |
4175 | handle_novops_attribute (tree *node, tree ARG_UNUSED (name)name __attribute__ ((__unused__)), |
4176 | tree ARG_UNUSED (args)args __attribute__ ((__unused__)), int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), |
4177 | bool *ARG_UNUSED (no_add_attrs)no_add_attrs __attribute__ ((__unused__))) |
4178 | { |
4179 | gcc_assert (TREE_CODE (*node) == FUNCTION_DECL)((void)(!(((enum tree_code) (*node)->base.code) == FUNCTION_DECL ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4179, __FUNCTION__), 0 : 0)); |
4180 | DECL_IS_NOVOPS (*node)((tree_check ((*node), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4180, __FUNCTION__, (FUNCTION_DECL)))->function_decl.novops_flag ) = 1; |
4181 | return NULL_TREE(tree) nullptr; |
4182 | } |
4183 | |
4184 | /* Handle a "deprecated" attribute; arguments as in |
4185 | struct attribute_spec.handler. */ |
4186 | |
4187 | tree |
4188 | handle_deprecated_attribute (tree *node, tree name, |
4189 | tree args, int flags, |
4190 | bool *no_add_attrs) |
4191 | { |
4192 | tree type = NULL_TREE(tree) nullptr; |
4193 | int warn = 0; |
4194 | tree what = NULL_TREE(tree) nullptr; |
4195 | |
4196 | if (!args) |
4197 | *no_add_attrs = true; |
4198 | else if (TREE_CODE (TREE_VALUE (args))((enum tree_code) (((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4198, __FUNCTION__, (TREE_LIST)))->list.value))->base .code) != STRING_CST) |
4199 | { |
4200 | error ("deprecated message is not a string"); |
4201 | *no_add_attrs = true; |
4202 | } |
4203 | |
4204 | if (DECL_P (*node)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (*node)->base.code))] == tcc_declaration)) |
4205 | { |
4206 | tree decl = *node; |
4207 | type = TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4207, __FUNCTION__))->typed.type); |
4208 | |
4209 | if (TREE_CODE (decl)((enum tree_code) (decl)->base.code) == TYPE_DECL |
4210 | || TREE_CODE (decl)((enum tree_code) (decl)->base.code) == PARM_DECL |
4211 | || VAR_OR_FUNCTION_DECL_P (decl)(((enum tree_code) (decl)->base.code) == VAR_DECL || ((enum tree_code) (decl)->base.code) == FUNCTION_DECL) |
4212 | || TREE_CODE (decl)((enum tree_code) (decl)->base.code) == FIELD_DECL |
4213 | || TREE_CODE (decl)((enum tree_code) (decl)->base.code) == CONST_DECL |
4214 | || objc_method_decl (TREE_CODE (decl)((enum tree_code) (decl)->base.code)) |
4215 | || TREE_CODE (decl)((enum tree_code) (decl)->base.code) == CONCEPT_DECL) |
4216 | TREE_DEPRECATED (decl)((decl)->base.deprecated_flag) = 1; |
4217 | else if (TREE_CODE (decl)((enum tree_code) (decl)->base.code) == LABEL_DECL) |
4218 | { |
4219 | pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored", |
4220 | name); |
4221 | *no_add_attrs = true; |
4222 | return NULL_TREE(tree) nullptr; |
4223 | } |
4224 | else |
4225 | warn = 1; |
4226 | } |
4227 | else if (TYPE_P (*node)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (*node)->base.code))] == tcc_type)) |
4228 | { |
4229 | if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) |
4230 | *node = build_variant_type_copy (*node); |
4231 | TREE_DEPRECATED (*node)((*node)->base.deprecated_flag) = 1; |
4232 | type = *node; |
4233 | } |
4234 | else |
4235 | warn = 1; |
4236 | |
4237 | if (warn) |
4238 | { |
4239 | *no_add_attrs = true; |
4240 | if (type && TYPE_NAME (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4240, __FUNCTION__))->type_common.name)) |
4241 | { |
4242 | if (TREE_CODE (TYPE_NAME (type))((enum tree_code) (((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4242, __FUNCTION__))->type_common.name))->base.code) == IDENTIFIER_NODE) |
4243 | what = TYPE_NAME (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4243, __FUNCTION__))->type_common.name); |
4244 | else if (TREE_CODE (TYPE_NAME (type))((enum tree_code) (((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4244, __FUNCTION__))->type_common.name))->base.code) == TYPE_DECL |
4245 | && DECL_NAME (TYPE_NAME (type))((contains_struct_check ((((tree_class_check ((type), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4245, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4245, __FUNCTION__))->decl_minimal.name)) |
4246 | what = DECL_NAME (TYPE_NAME (type))((contains_struct_check ((((tree_class_check ((type), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4246, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4246, __FUNCTION__))->decl_minimal.name); |
4247 | } |
4248 | if (what) |
4249 | warning (OPT_Wattributes, "%qE attribute ignored for %qE", name, what); |
4250 | else |
4251 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
4252 | } |
4253 | |
4254 | return NULL_TREE(tree) nullptr; |
4255 | } |
4256 | |
4257 | /* Handle a "unavailable" attribute; arguments as in |
4258 | struct attribute_spec.handler. */ |
4259 | |
4260 | static tree |
4261 | handle_unavailable_attribute (tree *node, tree name, |
4262 | tree args, int flags, |
4263 | bool *no_add_attrs) |
4264 | { |
4265 | tree type = NULL_TREE(tree) nullptr; |
4266 | int warn = 0; |
4267 | tree what = NULL_TREE(tree) nullptr; |
4268 | |
4269 | if (!args) |
4270 | *no_add_attrs = true; |
4271 | else if (TREE_CODE (TREE_VALUE (args))((enum tree_code) (((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4271, __FUNCTION__, (TREE_LIST)))->list.value))->base .code) != STRING_CST) |
4272 | { |
4273 | error ("the message attached to %<unavailable%> is not a string"); |
4274 | *no_add_attrs = true; |
4275 | } |
4276 | |
4277 | if (DECL_P (*node)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (*node)->base.code))] == tcc_declaration)) |
4278 | { |
4279 | tree decl = *node; |
4280 | type = TREE_TYPE (decl)((contains_struct_check ((decl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4280, __FUNCTION__))->typed.type); |
4281 | |
4282 | if (TREE_CODE (decl)((enum tree_code) (decl)->base.code) == TYPE_DECL |
4283 | || TREE_CODE (decl)((enum tree_code) (decl)->base.code) == PARM_DECL |
4284 | || VAR_OR_FUNCTION_DECL_P (decl)(((enum tree_code) (decl)->base.code) == VAR_DECL || ((enum tree_code) (decl)->base.code) == FUNCTION_DECL) |
4285 | || TREE_CODE (decl)((enum tree_code) (decl)->base.code) == FIELD_DECL |
4286 | || TREE_CODE (decl)((enum tree_code) (decl)->base.code) == CONST_DECL |
4287 | || objc_method_decl (TREE_CODE (decl)((enum tree_code) (decl)->base.code))) |
4288 | TREE_UNAVAILABLE (decl)((decl)->base.u.bits.unavailable_flag) = 1; |
4289 | else |
4290 | warn = 1; |
4291 | } |
4292 | else if (TYPE_P (*node)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (*node)->base.code))] == tcc_type)) |
4293 | { |
4294 | if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) |
4295 | *node = build_variant_type_copy (*node); |
4296 | TREE_UNAVAILABLE (*node)((*node)->base.u.bits.unavailable_flag) = 1; |
4297 | type = *node; |
4298 | } |
4299 | else |
4300 | warn = 1; |
4301 | |
4302 | if (warn) |
4303 | { |
4304 | *no_add_attrs = true; |
4305 | if (type && TYPE_NAME (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4305, __FUNCTION__))->type_common.name)) |
4306 | { |
4307 | if (TREE_CODE (TYPE_NAME (type))((enum tree_code) (((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4307, __FUNCTION__))->type_common.name))->base.code) == IDENTIFIER_NODE) |
4308 | what = TYPE_NAME (*node)((tree_class_check ((*node), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4308, __FUNCTION__))->type_common.name); |
4309 | else if (TREE_CODE (TYPE_NAME (type))((enum tree_code) (((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4309, __FUNCTION__))->type_common.name))->base.code) == TYPE_DECL |
4310 | && DECL_NAME (TYPE_NAME (type))((contains_struct_check ((((tree_class_check ((type), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4310, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4310, __FUNCTION__))->decl_minimal.name)) |
4311 | what = DECL_NAME (TYPE_NAME (type))((contains_struct_check ((((tree_class_check ((type), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4311, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4311, __FUNCTION__))->decl_minimal.name); |
4312 | } |
4313 | if (what) |
4314 | warning (OPT_Wattributes, "%qE attribute ignored for %qE", name, what); |
4315 | else |
4316 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
4317 | } |
4318 | |
4319 | return NULL_TREE(tree) nullptr; |
4320 | } |
4321 | |
4322 | /* Return the "base" type from TYPE that is suitable to apply attribute |
4323 | vector_size to by stripping arrays, function types, etc. */ |
4324 | static tree |
4325 | type_for_vector_size (tree type) |
4326 | { |
4327 | /* We need to provide for vector pointers, vector arrays, and |
4328 | functions returning vectors. For example: |
4329 | |
4330 | __attribute__((vector_size(16))) short *foo; |
4331 | |
4332 | In this case, the mode is SI, but the type being modified is |
4333 | HI, so we need to look further. */ |
4334 | |
4335 | while (POINTER_TYPE_P (type)(((enum tree_code) (type)->base.code) == POINTER_TYPE || ( (enum tree_code) (type)->base.code) == REFERENCE_TYPE) |
4336 | || TREE_CODE (type)((enum tree_code) (type)->base.code) == FUNCTION_TYPE |
4337 | || TREE_CODE (type)((enum tree_code) (type)->base.code) == METHOD_TYPE |
4338 | || TREE_CODE (type)((enum tree_code) (type)->base.code) == ARRAY_TYPE |
4339 | || TREE_CODE (type)((enum tree_code) (type)->base.code) == OFFSET_TYPE) |
4340 | type = TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4340, __FUNCTION__))->typed.type); |
4341 | |
4342 | return type; |
4343 | } |
4344 | |
4345 | /* Given TYPE, return the base type to which the vector_size attribute |
4346 | ATNAME with ARGS, when non-null, can be applied, if one exists. |
4347 | On success and when both ARGS and PTRNUNITS are non-null, set |
4348 | *PTRNUNINTS to the number of vector units. When PTRNUNITS is not |
4349 | null, issue a warning when the attribute argument is not constant |
4350 | and an error if there is no such type. Otherwise issue a warning |
4351 | in the latter case and return null. */ |
4352 | |
4353 | static tree |
4354 | type_valid_for_vector_size (tree type, tree atname, tree args, |
4355 | unsigned HOST_WIDE_INTlong *ptrnunits) |
4356 | { |
4357 | bool error_p = ptrnunits != NULLnullptr; |
4358 | |
4359 | /* Get the mode of the type being modified. */ |
4360 | machine_mode orig_mode = TYPE_MODE (type)((((enum tree_code) ((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4360, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (type) : (type)->type_common.mode); |
4361 | |
4362 | if ((!INTEGRAL_TYPE_P (type)(((enum tree_code) (type)->base.code) == ENUMERAL_TYPE || ( (enum tree_code) (type)->base.code) == BOOLEAN_TYPE || ((enum tree_code) (type)->base.code) == INTEGER_TYPE) |
4363 | && !SCALAR_FLOAT_TYPE_P (type)(((enum tree_code) (type)->base.code) == REAL_TYPE) |
4364 | && !FIXED_POINT_TYPE_P (type)(((enum tree_code) (type)->base.code) == FIXED_POINT_TYPE)) |
4365 | || (!SCALAR_FLOAT_MODE_P (orig_mode)(((enum mode_class) mode_class[orig_mode]) == MODE_FLOAT || ( (enum mode_class) mode_class[orig_mode]) == MODE_DECIMAL_FLOAT ) |
4366 | && GET_MODE_CLASS (orig_mode)((enum mode_class) mode_class[orig_mode]) != MODE_INT |
4367 | && !ALL_SCALAR_FIXED_POINT_MODE_P (orig_mode)(((((enum mode_class) mode_class[orig_mode]) == MODE_FRACT) || (((enum mode_class) mode_class[orig_mode]) == MODE_ACCUM)) || ((((enum mode_class) mode_class[orig_mode]) == MODE_UFRACT) || (((enum mode_class) mode_class[orig_mode]) == MODE_UACCUM)))) |
4368 | || !tree_fits_uhwi_p (TYPE_SIZE_UNIT (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4368, __FUNCTION__))->type_common.size_unit)) |
4369 | || TREE_CODE (type)((enum tree_code) (type)->base.code) == BOOLEAN_TYPE) |
4370 | { |
4371 | if (error_p) |
4372 | error ("invalid vector type for attribute %qE", atname); |
4373 | else |
4374 | warning (OPT_Wattributes, "invalid vector type for attribute %qE", |
4375 | atname); |
4376 | return NULL_TREE(tree) nullptr; |
4377 | } |
4378 | |
4379 | /* When no argument has been provided this is just a request to validate |
4380 | the type above. Return TYPE to indicate success. */ |
4381 | if (!args) |
4382 | return type; |
4383 | |
4384 | tree size = TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4384, __FUNCTION__, (TREE_LIST)))->list.value); |
4385 | /* Erroneous arguments have already been diagnosed. */ |
4386 | if (size == error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
4387 | return NULL_TREE(tree) nullptr; |
4388 | |
4389 | if (size && TREE_CODE (size)((enum tree_code) (size)->base.code) != IDENTIFIER_NODE |
4390 | && TREE_CODE (size)((enum tree_code) (size)->base.code) != FUNCTION_DECL) |
4391 | size = default_conversion (size); |
4392 | |
4393 | if (TREE_CODE (size)((enum tree_code) (size)->base.code) != INTEGER_CST) |
4394 | { |
4395 | if (error_p) |
4396 | error ("%qE attribute argument value %qE is not an integer constant", |
4397 | atname, size); |
4398 | else |
4399 | warning (OPT_Wattributes, |
4400 | "%qE attribute argument value %qE is not an integer constant", |
4401 | atname, size); |
4402 | return NULL_TREE(tree) nullptr; |
4403 | } |
4404 | |
4405 | if (!TYPE_UNSIGNED (TREE_TYPE (size))((tree_class_check ((((contains_struct_check ((size), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4405, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4405, __FUNCTION__))->base.u.bits.unsigned_flag) |
4406 | && tree_int_cst_sgn (size) < 0) |
4407 | { |
4408 | if (error_p) |
4409 | error ("%qE attribute argument value %qE is negative", |
4410 | atname, size); |
4411 | else |
4412 | warning (OPT_Wattributes, |
4413 | "%qE attribute argument value %qE is negative", |
4414 | atname, size); |
4415 | return NULL_TREE(tree) nullptr; |
4416 | } |
4417 | |
4418 | /* The attribute argument value is constrained by the maximum bit |
4419 | alignment representable in unsigned int on the host. */ |
4420 | unsigned HOST_WIDE_INTlong vecsize; |
4421 | unsigned HOST_WIDE_INTlong maxsize = tree_to_uhwi (max_object_size ()); |
4422 | if (!tree_fits_uhwi_p (size) |
4423 | || (vecsize = tree_to_uhwi (size)) > maxsize) |
4424 | { |
4425 | if (error_p) |
4426 | error ("%qE attribute argument value %qE exceeds %wu", |
4427 | atname, size, maxsize); |
4428 | else |
4429 | warning (OPT_Wattributes, |
4430 | "%qE attribute argument value %qE exceeds %wu", |
4431 | atname, size, maxsize); |
4432 | return NULL_TREE(tree) nullptr; |
4433 | } |
4434 | |
4435 | if (vecsize % tree_to_uhwi (TYPE_SIZE_UNIT (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4435, __FUNCTION__))->type_common.size_unit))) |
4436 | { |
4437 | if (error_p) |
4438 | error ("vector size not an integral multiple of component size"); |
4439 | return NULL_TREE(tree) nullptr; |
4440 | } |
4441 | |
4442 | if (vecsize == 0) |
4443 | { |
4444 | error ("zero vector size"); |
4445 | return NULLnullptr; |
4446 | } |
4447 | |
4448 | /* Calculate how many units fit in the vector. */ |
4449 | unsigned HOST_WIDE_INTlong nunits = vecsize / tree_to_uhwi (TYPE_SIZE_UNIT (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4449, __FUNCTION__))->type_common.size_unit)); |
4450 | if (nunits & (nunits - 1)) |
4451 | { |
4452 | if (error_p) |
4453 | error ("number of vector components %wu not a power of two", nunits); |
4454 | else |
4455 | warning (OPT_Wattributes, |
4456 | "number of vector components %wu not a power of two", nunits); |
4457 | return NULL_TREE(tree) nullptr; |
4458 | } |
4459 | |
4460 | if (nunits >= (unsigned HOST_WIDE_INTlong)INT_MAX2147483647) |
4461 | { |
4462 | if (error_p) |
4463 | error ("number of vector components %wu exceeds %d", |
4464 | nunits, INT_MAX2147483647 - 1); |
4465 | else |
4466 | warning (OPT_Wattributes, |
4467 | "number of vector components %wu exceeds %d", |
4468 | nunits, INT_MAX2147483647 - 1); |
4469 | return NULL_TREE(tree) nullptr; |
4470 | } |
4471 | |
4472 | if (ptrnunits) |
4473 | *ptrnunits = nunits; |
4474 | |
4475 | return type; |
4476 | } |
4477 | |
4478 | /* Handle a "vector_size" attribute; arguments as in |
4479 | struct attribute_spec.handler. */ |
4480 | |
4481 | static tree |
4482 | handle_vector_size_attribute (tree *node, tree name, tree args, |
4483 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), |
4484 | bool *no_add_attrs) |
4485 | { |
4486 | *no_add_attrs = true; |
4487 | |
4488 | /* Determine the "base" type to apply the attribute to. */ |
4489 | tree type = type_for_vector_size (*node); |
4490 | |
4491 | /* Get the vector size (in bytes) and let the function compute |
4492 | the number of vector units. */ |
4493 | unsigned HOST_WIDE_INTlong nunits; |
4494 | type = type_valid_for_vector_size (type, name, args, &nunits); |
4495 | if (!type) |
4496 | return NULL_TREE(tree) nullptr; |
4497 | |
4498 | gcc_checking_assert (args != NULL)((void)(!(args != nullptr) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4498, __FUNCTION__), 0 : 0)); |
4499 | |
4500 | tree new_type = build_vector_type (type, nunits); |
4501 | |
4502 | /* Build back pointers if needed. */ |
4503 | *node = lang_hooks.types.reconstruct_complex_type (*node, new_type); |
4504 | |
4505 | return NULL_TREE(tree) nullptr; |
4506 | } |
4507 | |
4508 | /* Handle a "vector_mask" attribute; arguments as in |
4509 | struct attribute_spec.handler. */ |
4510 | |
4511 | static tree |
4512 | handle_vector_mask_attribute (tree *node, tree name, tree, |
4513 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), |
4514 | bool *no_add_attrs) |
4515 | { |
4516 | *no_add_attrs = true; |
4517 | if (!flag_gimpleglobal_options.x_flag_gimple) |
4518 | { |
4519 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
4520 | return NULL_TREE(tree) nullptr; |
4521 | } |
4522 | |
4523 | /* Determine the "base" type to apply the attribute to. */ |
4524 | tree type = type_for_vector_size (*node); |
4525 | if (!VECTOR_TYPE_P (type)(((enum tree_code) (type)->base.code) == VECTOR_TYPE) || VECTOR_BOOLEAN_TYPE_P (type)(((enum tree_code) (type)->base.code) == VECTOR_TYPE && ((enum tree_code) (((contains_struct_check ((type), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4525, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE )) |
4526 | { |
4527 | warning (OPT_Wattributes, "%qE attribute only supported on " |
4528 | "non-mask vector types", name); |
4529 | return NULL_TREE(tree) nullptr; |
4530 | } |
4531 | |
4532 | tree new_type = truth_type_for (type); |
4533 | |
4534 | /* Build back pointers if needed. */ |
4535 | *node = lang_hooks.types.reconstruct_complex_type (*node, new_type); |
4536 | |
4537 | return NULL_TREE(tree) nullptr; |
4538 | } |
4539 | |
4540 | /* Handle the "nonnull" attribute. */ |
4541 | |
4542 | static tree |
4543 | handle_nonnull_attribute (tree *node, tree name, |
4544 | tree args, int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), |
4545 | bool *no_add_attrs) |
4546 | { |
4547 | tree type = *node; |
4548 | |
4549 | /* If no arguments are specified, all pointer arguments should be |
4550 | non-null. Verify a full prototype is given so that the arguments |
4551 | will have the correct types when we actually check them later. |
4552 | Avoid diagnosing type-generic built-ins since those have no |
4553 | prototype. */ |
4554 | if (!args) |
4555 | { |
4556 | if (!prototype_p (type) |
4557 | && (!TYPE_ATTRIBUTES (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4557, __FUNCTION__))->type_common.attributes) |
4558 | || !lookup_attribute ("type generic", TYPE_ATTRIBUTES (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4558, __FUNCTION__))->type_common.attributes)))) |
4559 | { |
4560 | error ("%qE attribute without arguments on a non-prototype", |
4561 | name); |
4562 | *no_add_attrs = true; |
4563 | } |
4564 | return NULL_TREE(tree) nullptr; |
4565 | } |
4566 | |
4567 | for (int i = 1; args; ++i) |
4568 | { |
4569 | tree pos = TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4569, __FUNCTION__, (TREE_LIST)))->list.value); |
4570 | /* NEXT is null when the attribute includes just one argument. |
4571 | That's used to tell positional_argument to avoid mentioning |
4572 | the argument number in diagnostics (since there's just one |
4573 | mentioning it is unnecessary and coule be confusing). */ |
4574 | tree next = TREE_CHAIN (args)((contains_struct_check ((args), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4574, __FUNCTION__))->common.chain); |
4575 | if (tree val = positional_argument (type, name, pos, POINTER_TYPE, |
4576 | next || i > 1 ? i : 0)) |
4577 | TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4577, __FUNCTION__, (TREE_LIST)))->list.value) = val; |
4578 | else |
4579 | { |
4580 | *no_add_attrs = true; |
4581 | break; |
4582 | } |
4583 | args = next; |
4584 | } |
4585 | |
4586 | return NULL_TREE(tree) nullptr; |
4587 | } |
4588 | |
4589 | /* Handle the "fd_arg", "fd_arg_read" and "fd_arg_write" attributes */ |
4590 | |
4591 | static tree |
4592 | handle_fd_arg_attribute (tree *node, tree name, tree args, |
4593 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), bool *no_add_attrs) |
4594 | { |
4595 | tree type = *node; |
4596 | if (!args) |
4597 | { |
4598 | if (!prototype_p (type)) |
4599 | { |
4600 | error ("%qE attribute without arguments on a non-prototype", name); |
4601 | *no_add_attrs = true; |
4602 | } |
4603 | return NULL_TREE(tree) nullptr; |
4604 | } |
4605 | |
4606 | if (positional_argument (*node, name, TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4606, __FUNCTION__, (TREE_LIST)))->list.value), INTEGER_TYPE)) |
4607 | return NULL_TREE(tree) nullptr; |
4608 | |
4609 | *no_add_attrs = true; |
4610 | return NULL_TREE(tree) nullptr; |
4611 | } |
4612 | |
4613 | /* Handle the "nonstring" variable attribute. */ |
4614 | |
4615 | static tree |
4616 | handle_nonstring_attribute (tree *node, tree name, tree ARG_UNUSED (args)args __attribute__ ((__unused__)), |
4617 | int ARG_UNUSED (flags)flags __attribute__ ((__unused__)), bool *no_add_attrs) |
4618 | { |
4619 | gcc_assert (!args)((void)(!(!args) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4619, __FUNCTION__), 0 : 0)); |
4620 | tree_code code = TREE_CODE (*node)((enum tree_code) (*node)->base.code); |
4621 | |
4622 | if (VAR_P (*node)(((enum tree_code) (*node)->base.code) == VAR_DECL) |
4623 | || code == FIELD_DECL |
4624 | || code == PARM_DECL) |
4625 | { |
4626 | tree type = TREE_TYPE (*node)((contains_struct_check ((*node), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4626, __FUNCTION__))->typed.type); |
4627 | |
4628 | if (POINTER_TYPE_P (type)(((enum tree_code) (type)->base.code) == POINTER_TYPE || ( (enum tree_code) (type)->base.code) == REFERENCE_TYPE) || TREE_CODE (type)((enum tree_code) (type)->base.code) == ARRAY_TYPE) |
4629 | { |
4630 | /* Accept the attribute on arrays and pointers to all three |
4631 | narrow character types. */ |
4632 | tree eltype = TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4632, __FUNCTION__))->typed.type); |
4633 | eltype = TYPE_MAIN_VARIANT (eltype)((tree_class_check ((eltype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4633, __FUNCTION__))->type_common.main_variant); |
4634 | if (eltype == char_type_nodeinteger_types[itk_char] |
4635 | || eltype == signed_char_type_nodeinteger_types[itk_signed_char] |
4636 | || eltype == unsigned_char_type_nodeinteger_types[itk_unsigned_char]) |
4637 | return NULL_TREE(tree) nullptr; |
4638 | } |
4639 | |
4640 | warning (OPT_Wattributes, |
4641 | "%qE attribute ignored on objects of type %qT", |
4642 | name, type); |
4643 | *no_add_attrs = true; |
4644 | return NULL_TREE(tree) nullptr; |
4645 | } |
4646 | |
4647 | if (code == FUNCTION_DECL) |
4648 | warning (OPT_Wattributes, |
4649 | "%qE attribute does not apply to functions", name); |
4650 | else if (code == TYPE_DECL) |
4651 | warning (OPT_Wattributes, |
4652 | "%qE attribute does not apply to types", name); |
4653 | else |
4654 | warning (OPT_Wattributes, "%qE attribute ignored", name); |
4655 | |
4656 | *no_add_attrs = true; |
4657 | return NULL_TREE(tree) nullptr; |
4658 | } |
4659 | |
4660 | /* Given a function type FUNCTYPE, returns the type of the parameter |
4661 | ARGNO or null if ARGNO exceeds the number of parameters. On failure |
4662 | set *NARGS to the number of function parameters. */ |
4663 | |
4664 | static tree |
4665 | get_argument_type (tree functype, unsigned argno, unsigned *nargs) |
4666 | { |
4667 | function_args_iterator iter; |
4668 | function_args_iter_init (&iter, functype); |
4669 | |
4670 | unsigned count = 0; |
4671 | |
4672 | for ( ; iter.next; ++count, function_args_iter_next (&iter)) |
4673 | { |
4674 | if (count + 1 == argno) |
4675 | { |
4676 | tree argtype = function_args_iter_cond (&iter); |
4677 | if (VOID_TYPE_P (argtype)(((enum tree_code) (argtype)->base.code) == VOID_TYPE)) |
4678 | break; |
4679 | if (argtype != error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
4680 | return argtype; |
4681 | } |
4682 | } |
4683 | |
4684 | *nargs = count; |
4685 | return NULL_TREE(tree) nullptr; |
4686 | } |
4687 | |
4688 | /* Given a function FNDECL return the function argument at the zero- |
4689 | based position ARGNO or null if it can't be found. */ |
4690 | |
4691 | static tree |
4692 | get_argument (tree fndecl, unsigned argno) |
4693 | { |
4694 | if (!DECL_P (fndecl)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (fndecl)->base.code))] == tcc_declaration)) |
4695 | return NULL_TREE(tree) nullptr; |
4696 | |
4697 | unsigned i = 0; |
4698 | for (tree arg = DECL_ARGUMENTS (fndecl)((tree_check ((fndecl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4698, __FUNCTION__, (FUNCTION_DECL)))->function_decl.arguments ); arg; arg = TREE_CHAIN (arg)((contains_struct_check ((arg), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4698, __FUNCTION__))->common.chain)) |
4699 | if (i++ == argno) |
4700 | return arg; |
4701 | |
4702 | return NULL_TREE(tree) nullptr; |
4703 | } |
4704 | |
4705 | /* Attempt to append attribute access specification ATTRSPEC, optionally |
4706 | described by the human-readable string ATTRSTR, for type T, to one in |
4707 | ATTRS. VBLIST is an optional list of bounds of variable length array |
4708 | parameters described by ATTRSTR. |
4709 | Issue warning for conflicts and return null if any are found. |
4710 | Return the concatenated access string on success. */ |
4711 | |
4712 | static tree |
4713 | append_access_attr (tree node[3], tree attrs, const char *attrstr, |
4714 | const char *attrspec, tree vblist = NULL_TREE(tree) nullptr) |
4715 | { |
4716 | tree argstr = build_string (strlen (attrspec) + 1, attrspec); |
4717 | tree ataccess = tree_cons (NULL_TREE(tree) nullptr, argstr, vblist); |
4718 | ataccess = tree_cons (get_identifier ("access")(__builtin_constant_p ("access") ? get_identifier_with_length (("access"), strlen ("access")) : get_identifier ("access")), ataccess, NULL_TREE(tree) nullptr); |
4719 | |
4720 | /* The access specification being applied. This may be an implicit |
4721 | access spec synthesized for array (or VLA) parameters even for |
4722 | a declaration with an explicit access spec already applied, if |
4723 | this call corresponds to the first declaration of the function. */ |
4724 | rdwr_map new_idxs; |
4725 | init_attr_rdwr_indices (&new_idxs, ataccess); |
4726 | |
4727 | /* The current access specification alrady applied. */ |
4728 | rdwr_map cur_idxs; |
4729 | init_attr_rdwr_indices (&cur_idxs, attrs); |
4730 | |
4731 | tree args = TYPE_ARG_TYPES (node[0])((tree_check2 ((node[0]), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4731, __FUNCTION__, (FUNCTION_TYPE), (METHOD_TYPE)))->type_non_common .values); |
4732 | int argpos = 0; |
4733 | std::string spec; |
4734 | for (tree arg = args; arg; arg = TREE_CHAIN (arg)((contains_struct_check ((arg), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4734, __FUNCTION__))->common.chain), argpos++) |
4735 | { |
4736 | const attr_access* const newa = new_idxs.get (argpos); |
4737 | |
4738 | if (!newa) |
4739 | continue; |
4740 | |
4741 | /* The map has two equal entries for each pointer argument that |
4742 | has an associated size argument. Process just the entry for |
4743 | the former. */ |
4744 | if ((unsigned)argpos != newa->ptrarg) |
4745 | continue; |
4746 | |
4747 | const attr_access* const cura = cur_idxs.get (argpos); |
4748 | if (!cura) |
4749 | { |
4750 | /* The new attribute needs to be added. */ |
4751 | tree str = newa->to_internal_string (); |
4752 | spec += TREE_STRING_POINTER (str)((const char *)((tree_check ((str), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4752, __FUNCTION__, (STRING_CST)))->string.str)); |
4753 | continue; |
4754 | } |
4755 | |
4756 | /* The new access spec refers to an array/pointer argument for |
4757 | which an access spec already exists. Check and diagnose any |
4758 | conflicts. If no conflicts are found, merge the two. */ |
4759 | |
4760 | if (!attrstr) |
4761 | { |
4762 | tree str = NULL_TREE(tree) nullptr; |
4763 | if (newa->mode != access_deferred) |
4764 | str = newa->to_external_string (); |
4765 | else if (cura->mode != access_deferred) |
4766 | str = cura->to_external_string (); |
4767 | if (str) |
4768 | attrstr = TREE_STRING_POINTER (str)((const char *)((tree_check ((str), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4768, __FUNCTION__, (STRING_CST)))->string.str)); |
4769 | } |
4770 | |
4771 | location_t curloc = input_location; |
4772 | if (node[2] && DECL_P (node[2])(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (node[2])->base.code))] == tcc_declaration)) |
4773 | curloc = DECL_SOURCE_LOCATION (node[2])((contains_struct_check ((node[2]), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4773, __FUNCTION__))->decl_minimal.locus); |
4774 | |
4775 | location_t prevloc = UNKNOWN_LOCATION((location_t) 0); |
4776 | if (node[1] && DECL_P (node[1])(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (node[1])->base.code))] == tcc_declaration)) |
4777 | prevloc = DECL_SOURCE_LOCATION (node[1])((contains_struct_check ((node[1]), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4777, __FUNCTION__))->decl_minimal.locus); |
4778 | |
4779 | if (newa->mode != cura->mode |
4780 | && newa->mode != access_deferred |
4781 | && cura->mode != access_deferred |
4782 | && newa->internal_p == cura->internal_p) |
4783 | { |
4784 | /* Mismatch in access mode. */ |
4785 | auto_diagnostic_group d; |
4786 | if (warning_at (curloc, OPT_Wattributes, |
4787 | "attribute %qs mismatch with mode %qs", |
4788 | attrstr, cura->mode_names[cura->mode]) |
4789 | && prevloc != UNKNOWN_LOCATION((location_t) 0)) |
4790 | inform (prevloc, "previous declaration here"); |
4791 | continue; |
4792 | } |
4793 | |
4794 | /* Set if PTRARG refers to a VLA with an unspecified bound (T[*]). |
4795 | Be prepared for either CURA or NEWA to refer to it, depending |
4796 | on which happens to come first in the declaration. */ |
4797 | const bool cur_vla_ub = (cura->internal_p |
4798 | && cura->sizarg == UINT_MAX(2147483647 *2U +1U) |
4799 | && cura->minsize == HOST_WIDE_INT_M1U-1UL); |
4800 | const bool new_vla_ub = (newa->internal_p |
4801 | && newa->sizarg == UINT_MAX(2147483647 *2U +1U) |
4802 | && newa->minsize == HOST_WIDE_INT_M1U-1UL); |
4803 | |
4804 | if (newa->sizarg != cura->sizarg |
4805 | && attrstr |
4806 | && (!(cur_vla_ub ^ new_vla_ub) |
4807 | || (!cura->internal_p && !newa->internal_p))) |
4808 | { |
4809 | /* Avoid diagnosing redeclarations of functions with no explicit |
4810 | attribute access that add one. */ |
4811 | if (newa->mode == access_deferred |
4812 | && cura->mode != access_deferred |
4813 | && newa->sizarg == UINT_MAX(2147483647 *2U +1U) |
4814 | && cura->sizarg != UINT_MAX(2147483647 *2U +1U)) |
4815 | continue; |
4816 | |
4817 | if (cura->mode == access_deferred |
4818 | && newa->mode != access_deferred |
4819 | && cura->sizarg == UINT_MAX(2147483647 *2U +1U) |
4820 | && newa->sizarg != UINT_MAX(2147483647 *2U +1U)) |
4821 | continue; |
4822 | |
4823 | /* The two specs designate different size arguments. It's okay |
4824 | for the explicit spec to specify a size where none is provided |
4825 | by the implicit (VLA) one, as in: |
4826 | __attribute__ ((access (read_write, 1, 2))) |
4827 | void f (int*, int); |
4828 | but not for two explicit access attributes to do that. */ |
4829 | bool warned = false; |
4830 | |
4831 | auto_diagnostic_group d; |
4832 | |
4833 | if (newa->sizarg == UINT_MAX(2147483647 *2U +1U)) |
4834 | /* Mismatch in the presence of the size argument. */ |
4835 | warned = warning_at (curloc, OPT_Wattributes, |
4836 | "attribute %qs missing positional argument 2 " |
4837 | "provided in previous designation by argument " |
4838 | "%u", attrstr, cura->sizarg + 1); |
4839 | else if (cura->sizarg == UINT_MAX(2147483647 *2U +1U)) |
4840 | /* Mismatch in the presence of the size argument. */ |
4841 | warned = warning_at (curloc, OPT_Wattributes, |
4842 | "attribute %qs positional argument 2 " |
4843 | "missing in previous designation", |
4844 | attrstr); |
4845 | else if (newa->internal_p || cura->internal_p) |
4846 | /* Mismatch in the value of the size argument and a VLA bound. */ |
4847 | warned = warning_at (curloc, OPT_Wattributes, |
4848 | "attribute %qs positional argument 2 " |
4849 | "conflicts with previous designation " |
4850 | "by argument %u", |
4851 | attrstr, cura->sizarg + 1); |
4852 | else |
4853 | /* Mismatch in the value of the size argument between two |
4854 | explicit access attributes. */ |
4855 | warned = warning_at (curloc, OPT_Wattributes, |
4856 | "attribute %qs mismatched positional argument " |
4857 | "values %i and %i", |
4858 | attrstr, newa->sizarg + 1, cura->sizarg + 1); |
4859 | |
4860 | if (warned) |
4861 | { |
4862 | /* If the previous declaration is a function (as opposed |
4863 | to a typedef of one), find the location of the array |
4864 | or pointer argument that uses the conflicting VLA bound |
4865 | and point to it in the note. */ |
4866 | const attr_access* const pa = cura->size ? cura : newa; |
4867 | tree size = pa->size ? TREE_VALUE (pa->size)((tree_check ((pa->size), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4867, __FUNCTION__, (TREE_LIST)))->list.value) : NULL_TREE(tree) nullptr; |
4868 | if (size && DECL_P (size)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (size)->base.code))] == tcc_declaration)) |
4869 | { |
4870 | location_t argloc = UNKNOWN_LOCATION((location_t) 0); |
4871 | if (tree arg = get_argument (node[2], pa->ptrarg)) |
4872 | argloc = DECL_SOURCE_LOCATION (arg)((contains_struct_check ((arg), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4872, __FUNCTION__))->decl_minimal.locus); |
4873 | |
4874 | gcc_rich_location richloc (DECL_SOURCE_LOCATION (size)((contains_struct_check ((size), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4874, __FUNCTION__))->decl_minimal.locus)); |
4875 | if (argloc != UNKNOWN_LOCATION((location_t) 0)) |
4876 | richloc.add_range (argloc); |
4877 | |
4878 | inform (&richloc, "designating the bound of variable " |
4879 | "length array argument %u", |
4880 | pa->ptrarg + 1); |
4881 | } |
4882 | else if (prevloc != UNKNOWN_LOCATION((location_t) 0)) |
4883 | inform (prevloc, "previous declaration here"); |
4884 | } |
4885 | |
4886 | continue; |
4887 | } |
4888 | |
4889 | if (newa->internal_p == cura->internal_p) |
4890 | continue; |
4891 | |
4892 | /* Merge the CURA and NEWA. */ |
4893 | attr_access merged = *newa; |
4894 | |
4895 | /* VLA seen in a declaration takes precedence. */ |
4896 | if (cura->minsize == HOST_WIDE_INT_M1U-1UL) |
4897 | merged.minsize = HOST_WIDE_INT_M1U-1UL; |
4898 | |
4899 | /* Use the explicitly specified size positional argument. */ |
4900 | if (cura->sizarg != UINT_MAX(2147483647 *2U +1U)) |
4901 | merged.sizarg = cura->sizarg; |
4902 | |
4903 | /* Use the explicitly specified mode. */ |
4904 | if (merged.mode == access_deferred) |
4905 | merged.mode = cura->mode; |
4906 | |
4907 | tree str = merged.to_internal_string (); |
4908 | spec += TREE_STRING_POINTER (str)((const char *)((tree_check ((str), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4908, __FUNCTION__, (STRING_CST)))->string.str)); |
4909 | } |
4910 | |
4911 | if (!spec.length ()) |
4912 | return NULL_TREE(tree) nullptr; |
4913 | |
4914 | return build_string (spec.length (), spec.c_str ()); |
4915 | } |
4916 | |
4917 | /* Convenience wrapper for the above. */ |
4918 | |
4919 | static tree |
4920 | append_access_attr_idxs (tree node[3], tree attrs, const char *attrstr, |
4921 | char code, HOST_WIDE_INTlong idxs[2]) |
4922 | { |
4923 | char attrspec[80]; |
4924 | int n = sprintf (attrspec, "%c%u", code, (unsigned) idxs[0] - 1); |
4925 | if (idxs[1]) |
4926 | n += sprintf (attrspec + n, ",%u", (unsigned) idxs[1] - 1); |
Value stored to 'n' is never read | |
4927 | |
4928 | return append_access_attr (node, attrs, attrstr, attrspec); |
4929 | } |
4930 | |
4931 | /* Handle the access attribute for function type NODE[0], with the function |
4932 | DECL optionally in NODE[1]. The handler is called both in response to |
4933 | an explict attribute access on a declaration with a mode and one or two |
4934 | positional arguments, and for internally synthesized access specifications |
4935 | with a string argument optionally followd by a DECL or expression |
4936 | representing a VLA bound. To speed up parsing, the handler transforms |
4937 | the attribute and its arguments into a string. */ |
4938 | |
4939 | static tree |
4940 | handle_access_attribute (tree node[3], tree name, tree args, int flags, |
4941 | bool *no_add_attrs) |
4942 | { |
4943 | tree attrs = TYPE_ATTRIBUTES (*node)((tree_class_check ((*node), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4943, __FUNCTION__))->type_common.attributes); |
4944 | tree type = *node; |
4945 | if (POINTER_TYPE_P (type)(((enum tree_code) (type)->base.code) == POINTER_TYPE || ( (enum tree_code) (type)->base.code) == REFERENCE_TYPE)) |
4946 | { |
4947 | tree ptype = TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4947, __FUNCTION__))->typed.type); |
4948 | if (FUNC_OR_METHOD_TYPE_P (ptype)(((enum tree_code) (ptype)->base.code) == FUNCTION_TYPE || ((enum tree_code) (ptype)->base.code) == METHOD_TYPE)) |
4949 | type = ptype; |
4950 | } |
4951 | |
4952 | *no_add_attrs = true; |
4953 | |
4954 | /* Verify a full prototype is provided so that the argument types |
4955 | can be validated. Avoid diagnosing type-generic built-ins since |
4956 | those have no prototype. */ |
4957 | if (!args |
4958 | && !prototype_p (type) |
4959 | && (!attrs || !lookup_attribute ("type generic", attrs))) |
4960 | { |
4961 | error ("attribute %qE without arguments on a non-prototype", name); |
4962 | return NULL_TREE(tree) nullptr; |
4963 | } |
4964 | |
4965 | tree access_mode = TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4965, __FUNCTION__, (TREE_LIST)))->list.value); |
4966 | if (TREE_CODE (access_mode)((enum tree_code) (access_mode)->base.code) == STRING_CST) |
4967 | { |
4968 | const char* const str = TREE_STRING_POINTER (access_mode)((const char *)((tree_check ((access_mode), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4968, __FUNCTION__, (STRING_CST)))->string.str)); |
4969 | if (*str == '+') |
4970 | { |
4971 | /* This is a request to merge an internal specification for |
4972 | a function declaration involving arrays but no explicit |
4973 | attribute access. */ |
4974 | tree vblist = TREE_CHAIN (args)((contains_struct_check ((args), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 4974, __FUNCTION__))->common.chain); |
4975 | tree axstr = append_access_attr (node, attrs, NULLnullptr, str + 1, |
4976 | vblist); |
4977 | if (!axstr) |
4978 | return NULL_TREE(tree) nullptr; |
4979 | |
4980 | /* Replace any existing access attribute specification with |
4981 | the concatenation above. */ |
4982 | tree axsat = tree_cons (NULL_TREE(tree) nullptr, axstr, vblist); |
4983 | axsat = tree_cons (name, axsat, NULL_TREE(tree) nullptr); |
4984 | |
4985 | /* Recursively call self to "replace" the documented/external |
4986 | form of the attribute with the condensend internal form. */ |
4987 | decl_attributes (node, axsat, flags | ATTR_FLAG_INTERNAL); |
4988 | return NULL_TREE(tree) nullptr; |
4989 | } |
4990 | |
4991 | if (flags & ATTR_FLAG_INTERNAL) |
4992 | { |
4993 | /* This is a recursive call to handle the condensed internal |
4994 | form of the attribute (see below). Since all validation |
4995 | has been done simply return here, accepting the attribute |
4996 | as is. */ |
4997 | *no_add_attrs = false; |
4998 | return NULL_TREE(tree) nullptr; |
4999 | } |
5000 | } |
5001 | |
5002 | /* Set to true when the access mode has the form of a function call |
5003 | as in 'attribute (read_only (1, 2))'. That's an easy mistake to |
5004 | make and so worth a special diagnostic. */ |
5005 | bool funcall = false; |
5006 | if (TREE_CODE (access_mode)((enum tree_code) (access_mode)->base.code) == CALL_EXPR) |
5007 | { |
5008 | access_mode = CALL_EXPR_FN (access_mode)(*((const_cast<tree*> (tree_operand_check (((tree_check ((access_mode), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 5008, __FUNCTION__, (CALL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 5008, __FUNCTION__))))); |
5009 | if (TREE_CODE (access_mode)((enum tree_code) (access_mode)->base.code) != ADDR_EXPR) |
5010 | { |
5011 | error ("attribute %qE invalid mode", name); |
5012 | return NULL_TREE(tree) nullptr; |
5013 | } |
5014 | access_mode = TREE_OPERAND (access_mode, 0)(*((const_cast<tree*> (tree_operand_check ((access_mode ), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 5014, __FUNCTION__))))); |
5015 | access_mode = DECL_NAME (access_mode)((contains_struct_check ((access_mode), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 5015, __FUNCTION__))->decl_minimal.name); |
5016 | funcall = true; |
5017 | } |
5018 | else if (TREE_CODE (access_mode)((enum tree_code) (access_mode)->base.code) != IDENTIFIER_NODE) |
5019 | { |
5020 | error ("attribute %qE mode %qE is not an identifier; expected one of " |
5021 | "%qs, %qs, %qs, or %qs", name, access_mode, |
5022 | "read_only", "read_write", "write_only", "none"); |
5023 | return NULL_TREE(tree) nullptr; |
5024 | } |
5025 | |
5026 | const char* const access_str = IDENTIFIER_POINTER (access_mode)((const char *) (tree_check ((access_mode), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 5026, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ); |
5027 | const char *ps = access_str; |
5028 | if (ps[0] == '_' && ps[1] == '_') |
5029 | { |
5030 | size_t len = strlen (ps); |
5031 | if (ps[len - 1] == '_' && ps[len - 2] == '_') |
5032 | ps += 2; |
5033 | } |
5034 | |
5035 | int imode; |
5036 | |
5037 | { |
5038 | const int nmodes = ARRAY_SIZE (attr_access::mode_names)(sizeof (attr_access::mode_names) / sizeof ((attr_access::mode_names )[0])); |
5039 | |
5040 | for (imode = 0; imode != nmodes; ++imode) |
5041 | if (!strncmp (ps, attr_access::mode_names[imode], |
5042 | strlen (attr_access::mode_names[imode]))) |
5043 | break; |
5044 | |
5045 | if (imode == nmodes) |
5046 | { |
5047 | error ("attribute %qE invalid mode %qs; expected one of " |
5048 | "%qs, %qs, %qs, or %qs", name, access_str, |
5049 | "read_only", "read_write", "write_only", "none"); |
5050 | return NULL_TREE(tree) nullptr; |
5051 | } |
5052 | } |
5053 | |
5054 | const ::access_mode mode = static_cast<::access_mode>(imode); |
5055 | |
5056 | if (funcall) |
5057 | { |
5058 | error ("attribute %qE unexpected %<(%> after mode %qs; expected " |
5059 | "a positional argument or %<)%>", |
5060 | name, access_str); |
5061 | return NULL_TREE(tree) nullptr; |
5062 | } |
5063 | |
5064 | args = TREE_CHAIN (args)((contains_struct_check ((args), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 5064, __FUNCTION__))->common.chain); |
5065 | if (!args) |
5066 | { |
5067 | /* The first positional argument is required. It may be worth |
5068 | dropping the requirement at some point and having read_only |
5069 | apply to all const-qualified pointers and read_write or |
5070 | write_only to the rest. */ |
5071 | error ("attribute %<%E(%s)%> missing an argument", |
5072 | name, access_str); |
5073 | return NULL_TREE(tree) nullptr; |
5074 | } |
5075 | |
5076 | /* One or more positional arguments have been specified. Validate |
5077 | them. */ |
5078 | tree idxnodes[2] = { NULL_TREE(tree) nullptr, NULL_TREE(tree) nullptr }; |
5079 | tree argtypes[2] = { NULL_TREE(tree) nullptr, NULL_TREE(tree) nullptr }; |
5080 | /* 1-based attribute positional arguments or zero if not specified. |
5081 | Invalid negative or excessive values are also stored but used |
5082 | only in diagnostics. */ |
5083 | HOST_WIDE_INTlong idxs[2] = { 0, 0 }; |
5084 | |
5085 | /* Number of function formal arguments (used in diagnostics). */ |
5086 | unsigned nfuncargs = 0; |
5087 | /* Number of (optional) attribute positional arguments. */ |
5088 | unsigned nattrargs = 0; |
5089 | |
5090 | for (unsigned i = 0; i != 2; ++i, args = TREE_CHAIN (args)((contains_struct_check ((args), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 5090, __FUNCTION__))->common.chain), ++nattrargs) |
5091 | { |
5092 | if (!args) |
5093 | break; |
5094 | |
5095 | idxnodes[i] = TREE_VALUE (args)((tree_check ((args), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 5095, __FUNCTION__, (TREE_LIST)))->list.value); |
5096 | |
5097 | if (TREE_CODE (idxnodes[i])((enum tree_code) (idxnodes[i])->base.code) != IDENTIFIER_NODE |
5098 | && TREE_CODE (idxnodes[i])((enum tree_code) (idxnodes[i])->base.code) != FUNCTION_DECL) |
5099 | idxnodes[i] = default_conversion (idxnodes[i]); |
5100 | |
5101 | if (tree_fits_shwi_p (idxnodes[i])) |
5102 | { |
5103 | idxs[i] = tree_to_shwi (idxnodes[i]); |
5104 | argtypes[i] = get_argument_type (type, idxs[i], &nfuncargs); |
5105 | } |
5106 | } |
5107 | |
5108 | if ((nattrargs == 1 && !idxs[0]) |
5109 | || (nattrargs == 2 && (!idxs[0] || !idxs[1]))) |
5110 | { |
5111 | if (idxnodes[1]) |
5112 | error ("attribute %<%E(%s, %E, %E)%> invalid positional argument %i", |
5113 | name, access_str, idxnodes[0], idxnodes[1], idxs[0] ? 2 : 1); |
5114 | else |
5115 | error ("attribute %<%E(%s, %E)%> invalid positional argument %i", |
5116 | name, access_str, idxnodes[0], idxs[0] ? 2 : 1); |
5117 | return NULL_TREE(tree) nullptr; |
5118 | } |
5119 | |
5120 | /* Format the attribute specification to include in diagnostics. */ |
5121 | char attrstr[80]; |
5122 | if (idxnodes[1]) |
5123 | snprintf (attrstr, sizeof attrstr, "%s(%s, %lli, %lli)", |
5124 | IDENTIFIER_POINTER (name)((const char *) (tree_check ((name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 5124, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), access_str, |
5125 | (long long) idxs[0], (long long) idxs[1]); |
5126 | else if (idxnodes[0]) |
5127 | snprintf (attrstr, sizeof attrstr, "%s(%s, %lli)", |
5128 | IDENTIFIER_POINTER (name)((const char *) (tree_check ((name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 5128, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), access_str, |
5129 | (long long) idxs[0]); |
5130 | else |
5131 | snprintf (attrstr, sizeof attrstr, "%s(%s)", |
5132 | IDENTIFIER_POINTER (name)((const char *) (tree_check ((name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 5132, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), access_str); |
5133 | |
5134 | /* Verify the positional argument values are in range. */ |
5135 | if (!argtypes[0] || (idxnodes[1] && !argtypes[1])) |
5136 | { |
5137 | if (idxnodes[0]) |
5138 | { |
5139 | if (idxs[0] < 0 || idxs[1] < 0) |
5140 | error ("attribute %qs positional argument %i invalid value %wi", |
5141 | attrstr, idxs[0] < 0 ? 1 : 2, |
5142 | idxs[0] < 0 ? idxs[0] : idxs[1]); |
5143 | else |
5144 | error ("attribute %qs positional argument %i value %wi exceeds " |
5145 | "number of function arguments %u", |
5146 | attrstr, idxs[0] ? 1 : 2, |
5147 | idxs[0] ? idxs[0] : idxs[1], |
5148 | nfuncargs); |
5149 | } |
5150 | else |
5151 | error ("attribute %qs invalid positional argument", attrstr); |
5152 | |
5153 | return NULL_TREE(tree) nullptr; |
5154 | } |
5155 | |
5156 | if (!POINTER_TYPE_P (argtypes[0])(((enum tree_code) (argtypes[0])->base.code) == POINTER_TYPE || ((enum tree_code) (argtypes[0])->base.code) == REFERENCE_TYPE )) |
5157 | { |
5158 | /* The first argument must have a pointer or reference type. */ |
5159 | error ("attribute %qs positional argument 1 references " |
5160 | "non-pointer argument type %qT", |
5161 | attrstr, argtypes[0]); |
5162 | return NULL_TREE(tree) nullptr; |
5163 | } |
5164 | |
5165 | { |
5166 | /* Pointers to functions are not allowed. */ |
5167 | tree ptrtype = TREE_TYPE (argtypes[0])((contains_struct_check ((argtypes[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 5167, __FUNCTION__))->typed.type); |
5168 | if (FUNC_OR_METHOD_TYPE_P (ptrtype)(((enum tree_code) (ptrtype)->base.code) == FUNCTION_TYPE || ((enum tree_code) (ptrtype)->base.code) == METHOD_TYPE)) |
5169 | { |
5170 | error ("attribute %qs positional argument 1 references " |
5171 | "argument of function type %qT", |
5172 | attrstr, ptrtype); |
5173 | return NULL_TREE(tree) nullptr; |
5174 | } |
5175 | } |
5176 | |
5177 | if (mode == access_read_write || mode == access_write_only) |
5178 | { |
5179 | /* Read_write and write_only modes must reference non-const |
5180 | arguments. */ |
5181 | if (TYPE_READONLY (TREE_TYPE (argtypes[0]))((tree_class_check ((((contains_struct_check ((argtypes[0]), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 5181, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 5181, __FUNCTION__))->base.readonly_flag)) |
5182 | { |
5183 | error ("attribute %qs positional argument 1 references " |
5184 | "%qs-qualified argument type %qT", |
5185 | attrstr, "const", argtypes[0]); |
5186 | return NULL_TREE(tree) nullptr; |
5187 | } |
5188 | } |
5189 | else if (!TYPE_READONLY (TREE_TYPE (argtypes[0]))((tree_class_check ((((contains_struct_check ((argtypes[0]), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 5189, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/c-family/c-attribs.cc" , 5189, __FUNCTION__))->base.readonly_flag)) |
5190 | { |
5191 | /* A read_only mode should ideally reference const-qualified |
5192 | arguments but it's not diagnosed error if one doesn't. |
5193 | This makes it possible to annotate legacy, const-incorrect |
5194 | APIs. It might be worth a diagnostic along the lines of |
5195 | -Wsuggest-const. */ |
5196 | ; |
5197 | } |
5198 | |
5199 | if (argtypes[1] && !INTEGRAL_TYPE_P (argtypes[1])(((enum tree_code) (argtypes[1])->base.code) == ENUMERAL_TYPE || ((enum tree_code) (argtypes[1])->base.code) == BOOLEAN_TYPE || ((enum tree_code) (argtypes[1])->base.code) == INTEGER_TYPE )) |
5200 | { |
5201 | error ("attribute %qs positional argument 2 references " |
5202 | "non-integer argument type %qT", |
5203 | attrstr, argtypes[1]); |