Line data Source code
1 : /* C-family attributes handling.
2 : Copyright (C) 1992-2026 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 "attr-handlers.h"
39 : #include "varasm.h"
40 : #include "trans-mem.h"
41 : #include "c-objc.h"
42 : #include "common/common-target.h"
43 : #include "langhooks.h"
44 : #include "tree-inline.h"
45 : #include "ipa-strub.h"
46 : #include "toplev.h"
47 : #include "tree-iterator.h"
48 : #include "opts.h"
49 : #include "gimplify.h"
50 : #include "tree-pretty-print.h"
51 : #include "gcc-rich-location.h"
52 : #include "gcc-urlifier.h"
53 : #include "attr-callback.h"
54 :
55 : static tree handle_packed_attribute (tree *, tree, tree, int, bool *);
56 : static tree handle_nocommon_attribute (tree *, tree, tree, int, bool *);
57 : static tree handle_common_attribute (tree *, tree, tree, int, bool *);
58 : static tree handle_hot_attribute (tree *, tree, tree, int, bool *);
59 : static tree handle_cold_attribute (tree *, tree, tree, int, bool *);
60 : static tree handle_no_sanitize_attribute (tree *, tree, tree, int, bool *);
61 : static tree handle_no_sanitize_address_attribute (tree *, tree, tree,
62 : int, bool *);
63 : static tree handle_no_sanitize_thread_attribute (tree *, tree, tree,
64 : int, bool *);
65 : static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree,
66 : int, bool *);
67 : static tree handle_no_sanitize_undefined_attribute (tree *, tree, tree, int,
68 : bool *);
69 : static tree handle_no_sanitize_coverage_attribute (tree *, tree, tree, int,
70 : bool *);
71 : static tree handle_asan_odr_indicator_attribute (tree *, tree, tree, int,
72 : bool *);
73 : static tree handle_stack_protect_attribute (tree *, tree, tree, int, bool *);
74 : static tree handle_no_stack_protector_function_attribute (tree *, tree,
75 : tree, int, bool *);
76 : static tree handle_strub_attribute (tree *, tree, tree, int, bool *);
77 : static tree handle_noclone_attribute (tree *, tree, tree, int, bool *);
78 : static tree handle_nocf_check_attribute (tree *, tree, tree, int, bool *);
79 : static tree handle_symver_attribute (tree *, tree, tree, int, bool *);
80 : static tree handle_noicf_attribute (tree *, tree, tree, int, bool *);
81 : static tree handle_noipa_attribute (tree *, tree, tree, int, bool *);
82 : static tree handle_gnu_inline_attribute (tree *, tree, tree, int, bool *);
83 : static tree handle_artificial_attribute (tree *, tree, tree, int, bool *);
84 : static tree handle_flatten_attribute (tree *, tree, tree, int, bool *);
85 : static tree handle_error_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_transparent_union_attribute (tree *, tree, tree,
92 : int, bool *);
93 : static tree handle_scalar_storage_order_attribute (tree *, tree, tree,
94 : int, bool *);
95 : static tree handle_constructor_attribute (tree *, tree, tree, int, bool *);
96 : static tree handle_destructor_attribute (tree *, tree, tree, int, bool *);
97 : static tree handle_mode_attribute (tree *, tree, tree, int, bool *);
98 : static tree handle_special_var_sec_attribute (tree *, tree, tree, int, bool *);
99 : static tree handle_warn_if_not_aligned_attribute (tree *, tree, tree,
100 : int, bool *);
101 : static tree handle_strict_flex_array_attribute (tree *, tree, tree,
102 : int, bool *);
103 : static tree handle_counted_by_attribute (tree *, tree, tree,
104 : int, bool *);
105 : static tree handle_noplt_attribute (tree *, tree, tree, int, bool *) ;
106 : static tree handle_ifunc_attribute (tree *, tree, tree, int, bool *);
107 : static tree handle_weakref_attribute (tree *, tree, tree, int, bool *) ;
108 : static tree handle_tls_model_attribute (tree *, tree, tree, int,
109 : bool *);
110 : static tree handle_no_instrument_function_attribute (tree *, tree,
111 : tree, int, bool *);
112 : static tree handle_no_profile_instrument_function_attribute (tree *, tree,
113 : tree, int, bool *);
114 : static tree handle_malloc_attribute (tree *, tree, tree, int, bool *);
115 : static tree handle_dealloc_attribute (tree *, tree, tree, int, bool *);
116 : static tree handle_tainted_args_attribute (tree *, tree, tree, int, bool *);
117 : static tree handle_no_limit_stack_attribute (tree *, tree, tree, int,
118 : bool *);
119 : static tree handle_tm_attribute (tree *, tree, tree, int, bool *);
120 : static tree handle_tm_wrap_attribute (tree *, tree, tree, int, bool *);
121 : static tree handle_callback_only_attribute (tree *, tree, tree, int, bool *);
122 : static tree handle_unavailable_attribute (tree *, tree, tree, int,
123 : bool *);
124 : static tree handle_vector_size_attribute (tree *, tree, tree, int,
125 : bool *) ATTRIBUTE_NONNULL(3);
126 : static tree handle_vector_mask_attribute (tree *, tree, tree, int,
127 : bool *) ATTRIBUTE_NONNULL(3);
128 : static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
129 : static tree handle_nonnull_if_nonzero_attribute (tree *, tree, tree, int,
130 : bool *);
131 : static tree handle_nonstring_attribute (tree *, tree, tree, int, bool *);
132 : static tree handle_expected_throw_attribute (tree *, tree, tree, int, bool *);
133 : static tree handle_cleanup_attribute (tree *, tree, tree, int, bool *);
134 : static tree handle_warn_unused_result_attribute (tree *, tree, tree, int,
135 : bool *);
136 : static tree handle_access_attribute (tree *, tree, tree, int, bool *);
137 :
138 : static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *);
139 : static tree handle_alloc_size_attribute (tree *, tree, tree, int, bool *);
140 : static tree handle_alloc_align_attribute (tree *, tree, tree, int, bool *);
141 : static tree handle_assume_aligned_attribute (tree *, tree, tree, int, bool *);
142 : static tree handle_assume_attribute (tree *, tree, tree, int, bool *);
143 : static tree handle_target_version_attribute (tree *, tree, tree, int, bool *);
144 : static tree handle_target_clones_attribute (tree *, tree, tree, int, bool *);
145 : static tree handle_optimize_attribute (tree *, tree, tree, int, bool *);
146 : static tree handle_no_split_stack_attribute (tree *, tree, tree, int, bool *);
147 : static tree handle_zero_call_used_regs_attribute (tree *, tree, tree, int,
148 : bool *);
149 : static tree handle_argspec_attribute (tree *, tree, tree, int, bool *);
150 : static tree handle_warn_unused_attribute (tree *, tree, tree, int, bool *);
151 : static tree handle_returns_nonnull_attribute (tree *, tree, tree, int, bool *);
152 : static tree handle_omp_declare_simd_attribute (tree *, tree, tree, int,
153 : bool *);
154 : static tree handle_omp_declare_variant_attribute (tree *, tree, tree, int,
155 : bool *);
156 : static tree handle_simd_attribute (tree *, tree, tree, int, bool *);
157 : static tree handle_omp_declare_target_attribute (tree *, tree, tree, int,
158 : bool *);
159 : static tree handle_non_overlapping_attribute (tree *, tree, tree, int, bool *);
160 : static tree handle_designated_init_attribute (tree *, tree, tree, int, bool *);
161 : static tree handle_patchable_function_entry_attribute (tree *, tree, tree,
162 : int, bool *);
163 : static tree handle_copy_attribute (tree *, tree, tree, int, bool *);
164 : static tree handle_nsobject_attribute (tree *, tree, tree, int, bool *);
165 : static tree handle_objc_root_class_attribute (tree *, tree, tree, int, bool *);
166 : static tree handle_objc_nullability_attribute (tree *, tree, tree, int, bool *);
167 : static tree handle_signed_bool_precision_attribute (tree *, tree, tree, int,
168 : bool *);
169 : static tree handle_hardbool_attribute (tree *, tree, tree, int, bool *);
170 : static tree handle_fd_arg_attribute (tree *, tree, tree, int, bool *);
171 : static tree handle_flag_enum_attribute (tree *, tree, tree, int, bool *);
172 : static tree handle_null_terminated_string_arg_attribute (tree *, tree, tree, int, bool *);
173 :
174 : static tree handle_btf_decl_tag_attribute (tree *, tree, tree, int, bool *);
175 : static tree handle_btf_type_tag_attribute (tree *, tree, tree, int, bool *);
176 :
177 : static tree handle_suppress_coverage_attribute (tree *, tree, tree, int,
178 : bool *);
179 :
180 : /* Helper to define attribute exclusions. */
181 : #define ATTR_EXCL(name, function, type, variable) \
182 : { name, function, type, variable }
183 :
184 : /* Define attributes that are mutually exclusive with one another. */
185 : extern const struct attribute_spec::exclusions attr_aligned_exclusions[] =
186 : {
187 : /* Attribute name exclusion applies to:
188 : function, type, variable */
189 : ATTR_EXCL ("aligned", true, false, false),
190 : ATTR_EXCL ("packed", true, false, false),
191 : ATTR_EXCL (NULL, false, false, false)
192 : };
193 :
194 : static const struct attribute_spec::exclusions attr_common_exclusions[] =
195 : {
196 : ATTR_EXCL ("common", true, true, true),
197 : ATTR_EXCL ("nocommon", true, true, true),
198 : ATTR_EXCL (NULL, false, false, false),
199 : };
200 :
201 : static const struct attribute_spec::exclusions attr_inline_exclusions[] =
202 : {
203 : ATTR_EXCL ("noinline", true, true, true),
204 : ATTR_EXCL (NULL, false, false, false),
205 : };
206 :
207 : static const struct attribute_spec::exclusions attr_target_clones_exclusions[] =
208 : {
209 : ATTR_EXCL ("always_inline", true, true, true),
210 : ATTR_EXCL ("target", TARGET_HAS_FMV_TARGET_ATTRIBUTE,
211 : TARGET_HAS_FMV_TARGET_ATTRIBUTE, TARGET_HAS_FMV_TARGET_ATTRIBUTE),
212 : ATTR_EXCL ("omp declare simd", true, true, true),
213 : ATTR_EXCL ("simd", true, true, true),
214 : ATTR_EXCL (NULL, false, false, false),
215 : };
216 :
217 : static const struct attribute_spec::exclusions attr_target_version_exclusions[] =
218 : {
219 : ATTR_EXCL ("omp declare simd", true, true, true),
220 : ATTR_EXCL ("simd", true, true, true),
221 : ATTR_EXCL (NULL, false, false, false),
222 : };
223 :
224 : static const struct attribute_spec::exclusions attr_omp_declare_simd_exclusions[] =
225 : {
226 : ATTR_EXCL ("target_version", true, true, true),
227 : ATTR_EXCL ("target_clones", true, true, true),
228 : ATTR_EXCL (NULL, false, false, false),
229 : };
230 :
231 : static const struct attribute_spec::exclusions attr_simd_exclusions[] =
232 : {
233 : ATTR_EXCL ("target_version", true, true, true),
234 : ATTR_EXCL ("target_clones", true, true, true),
235 : ATTR_EXCL (NULL, false, false, false),
236 : };
237 :
238 : static const struct attribute_spec::exclusions
239 : attr_warn_unused_result_exclusions[] =
240 : {
241 : ATTR_EXCL ("noreturn", true, true, true),
242 : ATTR_EXCL ("warn_unused_result", true, true, true),
243 : ATTR_EXCL (NULL, false, false, false),
244 : };
245 :
246 : static const struct attribute_spec::exclusions attr_stack_protect_exclusions[] =
247 : {
248 : ATTR_EXCL ("stack_protect", true, false, false),
249 : ATTR_EXCL ("no_stack_protector", true, false, false),
250 : ATTR_EXCL (NULL, false, false, false),
251 : };
252 :
253 :
254 : /* Table of machine-independent attributes common to all C-like languages.
255 :
256 : Current list of processed common attributes: nonnull. */
257 : const struct attribute_spec c_common_gnu_attributes[] =
258 : {
259 : /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
260 : affects_type_identity, handler, exclude } */
261 : { "signed_bool_precision", 1, 1, false, true, false, true,
262 : handle_signed_bool_precision_attribute, NULL },
263 : { "hardbool", 0, 2, false, true, false, true,
264 : handle_hardbool_attribute, NULL },
265 : { "packed", 0, 0, false, false, false, false,
266 : handle_packed_attribute,
267 : attr_aligned_exclusions },
268 : { "nocommon", 0, 0, true, false, false, false,
269 : handle_nocommon_attribute,
270 : attr_common_exclusions },
271 : { "common", 0, 0, true, false, false, false,
272 : handle_common_attribute,
273 : attr_common_exclusions },
274 : { "musttail", 0, 0, false, false, false,
275 : false, handle_musttail_attribute, NULL },
276 : /* FIXME: logically, noreturn attributes should be listed as
277 : "false, true, true" and apply to function types. But implementing this
278 : would require all the places in the compiler that use TREE_THIS_VOLATILE
279 : on a decl to identify non-returning functions to be located and fixed
280 : to check the function type instead. */
281 : { "noreturn", 0, 0, true, false, false, false,
282 : handle_noreturn_attribute,
283 : attr_noreturn_exclusions },
284 : { "volatile", 0, 0, true, false, false, false,
285 : handle_noreturn_attribute, NULL },
286 : { "stack_protect", 0, 0, true, false, false, false,
287 : handle_stack_protect_attribute,
288 : attr_stack_protect_exclusions },
289 : { "no_stack_protector", 0, 0, true, false, false, false,
290 : handle_no_stack_protector_function_attribute,
291 : attr_stack_protect_exclusions },
292 : { "strub", 0, 1, false, true, false, true,
293 : handle_strub_attribute, NULL },
294 : { "noinline", 0, 0, true, false, false, false,
295 : handle_noinline_attribute,
296 : attr_noinline_exclusions },
297 : { "noclone", 0, 0, true, false, false, false,
298 : handle_noclone_attribute, NULL },
299 : { "no_icf", 0, 0, true, false, false, false,
300 : handle_noicf_attribute, NULL },
301 : { "noipa", 0, 0, true, false, false, false,
302 : handle_noipa_attribute, NULL },
303 : { "leaf", 0, 0, true, false, false, false,
304 : handle_leaf_attribute, NULL },
305 : { "always_inline", 0, 0, true, false, false, false,
306 : handle_always_inline_attribute,
307 : attr_always_inline_exclusions },
308 : { "gnu_inline", 0, 0, true, false, false, false,
309 : handle_gnu_inline_attribute,
310 : attr_inline_exclusions },
311 : { "artificial", 0, 0, true, false, false, false,
312 : handle_artificial_attribute, NULL },
313 : { "flatten", 0, 0, true, false, false, false,
314 : handle_flatten_attribute, NULL },
315 : { "used", 0, 0, true, false, false, false,
316 : handle_used_attribute, NULL },
317 : { "unused", 0, 0, false, false, false, false,
318 : handle_unused_attribute, NULL },
319 : { "uninitialized", 0, 0, true, false, false, false,
320 : handle_uninitialized_attribute, NULL },
321 : { "retain", 0, 0, true, false, false, false,
322 : handle_retain_attribute, NULL },
323 : { "externally_visible", 0, 0, true, false, false, false,
324 : handle_externally_visible_attribute, NULL },
325 : { "no_reorder", 0, 0, true, false, false, false,
326 : handle_no_reorder_attribute, NULL },
327 : /* The same comments as for noreturn attributes apply to const ones. */
328 : { "const", 0, 0, true, false, false, false,
329 : handle_const_attribute,
330 : attr_const_pure_exclusions },
331 : { "scalar_storage_order", 1, 1, false, false, false, false,
332 : handle_scalar_storage_order_attribute, NULL },
333 : { "transparent_union", 0, 0, false, false, false, false,
334 : handle_transparent_union_attribute, NULL },
335 : { "constructor", 0, 1, true, false, false, false,
336 : handle_constructor_attribute, NULL },
337 : { "destructor", 0, 1, true, false, false, false,
338 : handle_destructor_attribute, NULL },
339 : { "mode", 1, 1, false, true, false, false,
340 : handle_mode_attribute, NULL },
341 : { "section", 1, 1, true, false, false, false,
342 : handle_section_attribute, attr_section_exclusions },
343 : { "aligned", 0, 1, false, false, false, false,
344 : handle_aligned_attribute,
345 : attr_aligned_exclusions },
346 : { "warn_if_not_aligned", 0, 1, false, false, false, false,
347 : handle_warn_if_not_aligned_attribute, NULL },
348 : { "strict_flex_array", 1, 1, true, false, false, false,
349 : handle_strict_flex_array_attribute, NULL },
350 : { "counted_by", 1, 1, true, false, false, false,
351 : handle_counted_by_attribute, NULL },
352 : { "weak", 0, 0, true, false, false, false,
353 : handle_weak_attribute, NULL },
354 : { "noplt", 0, 0, true, false, false, false,
355 : handle_noplt_attribute, NULL },
356 : { "ifunc", 1, 1, true, false, false, false,
357 : handle_ifunc_attribute, NULL },
358 : { "alias", 1, 1, true, false, false, false,
359 : handle_alias_attribute, NULL },
360 : { "weakref", 0, 1, true, false, false, false,
361 : handle_weakref_attribute, NULL },
362 : { "no_instrument_function", 0, 0, true, false, false, false,
363 : handle_no_instrument_function_attribute,
364 : NULL },
365 : { "no_profile_instrument_function", 0, 0, true, false, false, false,
366 : handle_no_profile_instrument_function_attribute,
367 : NULL },
368 : { "malloc", 0, 2, true, false, false, false,
369 : handle_malloc_attribute, attr_alloc_exclusions },
370 : { "returns_twice", 0, 0, true, false, false, false,
371 : handle_returns_twice_attribute,
372 : attr_returns_twice_exclusions },
373 : { "no_stack_limit", 0, 0, true, false, false, false,
374 : handle_no_limit_stack_attribute, NULL },
375 : { "pure", 0, 0, true, false, false, false,
376 : handle_pure_attribute,
377 : attr_const_pure_exclusions },
378 : { "reproducible", 0, 0, false, true, true, false,
379 : handle_reproducible_attribute, NULL },
380 : { "unsequenced", 0, 0, false, true, true, false,
381 : handle_unsequenced_attribute, NULL },
382 : { "reproducible noptr", 0, 0, false, true, true, false,
383 : handle_reproducible_attribute, NULL },
384 : { "unsequenced noptr", 0, 0, false, true, true, false,
385 : handle_unsequenced_attribute, NULL },
386 : { "transaction_callable", 0, 0, false, true, false, false,
387 : handle_tm_attribute, NULL },
388 : { "transaction_unsafe", 0, 0, false, true, false, true,
389 : handle_tm_attribute, NULL },
390 : { "transaction_safe", 0, 0, false, true, false, true,
391 : handle_tm_attribute, NULL },
392 : { "transaction_safe_dynamic", 0, 0, true, false, false, false,
393 : handle_tm_attribute, NULL },
394 : { "transaction_may_cancel_outer", 0, 0, false, true, false, false,
395 : handle_tm_attribute, NULL },
396 : { "callback_only", 1, -1, true, false, false, false,
397 : handle_callback_only_attribute, NULL },
398 : /* ??? These two attributes didn't make the transition from the
399 : Intel language document to the multi-vendor language document. */
400 : { "transaction_pure", 0, 0, false, true, false, false,
401 : handle_tm_attribute, NULL },
402 : { "transaction_wrap", 1, 1, true, false, false, false,
403 : handle_tm_wrap_attribute, NULL },
404 : /* For internal use (marking of builtins) only. The name contains space
405 : to prevent its usage in source code. */
406 : { "no vops", 0, 0, true, false, false, false,
407 : handle_novops_attribute, NULL },
408 : { "deprecated", 0, 1, false, false, false, false,
409 : handle_deprecated_attribute, NULL },
410 : { "unavailable", 0, 1, false, false, false, false,
411 : handle_unavailable_attribute, NULL },
412 : { "vector_size", 1, 1, false, true, false, true,
413 : handle_vector_size_attribute, NULL },
414 : { "vector_mask", 0, 0, false, true, false, true,
415 : handle_vector_mask_attribute, NULL },
416 : { "visibility", 1, 1, false, false, false, false,
417 : handle_visibility_attribute, NULL },
418 : { "tls_model", 1, 1, true, false, false, false,
419 : handle_tls_model_attribute, NULL },
420 : { "nonnull", 0, -1, false, true, true, false,
421 : handle_nonnull_attribute, NULL },
422 : { "nonnull_if_nonzero", 2, 3, false, true, true, false,
423 : handle_nonnull_if_nonzero_attribute, NULL },
424 : { "nonstring", 0, 0, true, false, false, false,
425 : handle_nonstring_attribute, NULL },
426 : { "nothrow", 0, 0, true, false, false, false,
427 : handle_nothrow_attribute, NULL },
428 : { "expected_throw", 0, 0, true, false, false, false,
429 : handle_expected_throw_attribute, NULL },
430 : { "may_alias", 0, 0, false, true, false, false, NULL, NULL },
431 : { "cleanup", 1, 1, true, false, false, false,
432 : handle_cleanup_attribute, NULL },
433 : { "warn_unused_result", 0, 0, false, true, true, false,
434 : handle_warn_unused_result_attribute,
435 : attr_warn_unused_result_exclusions },
436 : { "sentinel", 0, 1, false, true, true, false,
437 : handle_sentinel_attribute, NULL },
438 : /* For internal use (marking of builtins) only. The name contains space
439 : to prevent its usage in source code. */
440 : { "type generic", 0, 0, false, true, true, false,
441 : handle_type_generic_attribute, NULL },
442 : { "alloc_size", 1, 2, false, true, true, false,
443 : handle_alloc_size_attribute,
444 : attr_alloc_exclusions },
445 : { "cold", 0, 0, false, false, false, false,
446 : handle_cold_attribute,
447 : attr_cold_hot_exclusions },
448 : { "hot", 0, 0, false, false, false, false,
449 : handle_hot_attribute,
450 : attr_cold_hot_exclusions },
451 : { "no_address_safety_analysis",
452 : 0, 0, true, false, false, false,
453 : handle_no_address_safety_analysis_attribute,
454 : NULL },
455 : { "no_sanitize", 1, -1, true, false, false, false,
456 : handle_no_sanitize_attribute, NULL },
457 : { "no_sanitize_address", 0, 0, true, false, false, false,
458 : handle_no_sanitize_address_attribute, NULL },
459 : { "no_sanitize_thread", 0, 0, true, false, false, false,
460 : handle_no_sanitize_thread_attribute, NULL },
461 : { "no_sanitize_undefined", 0, 0, true, false, false, false,
462 : handle_no_sanitize_undefined_attribute, NULL },
463 : { "no_sanitize_coverage", 0, 0, true, false, false, false,
464 : handle_no_sanitize_coverage_attribute, NULL },
465 : { "asan odr indicator", 0, 0, true, false, false, false,
466 : handle_asan_odr_indicator_attribute, NULL },
467 : { "warning", 1, 1, true, false, false, false,
468 : handle_error_attribute, NULL },
469 : { "error", 1, 1, true, false, false, false,
470 : handle_error_attribute, NULL },
471 : { "target", 1, -1, true, false, false, false,
472 : handle_target_attribute,
473 : attr_target_exclusions },
474 : { "target_version", 1, 1, true, false, false, false,
475 : handle_target_version_attribute,
476 : attr_target_version_exclusions},
477 : { "target_clones", 1, -1, true, false, false, false,
478 : handle_target_clones_attribute,
479 : attr_target_clones_exclusions },
480 : { "optimize", 1, -1, true, false, false, false,
481 : handle_optimize_attribute, NULL },
482 : /* For internal use only. The leading '*' both prevents its usage in
483 : source code and signals that it may be overridden by machine tables. */
484 : { "*tm regparm", 0, 0, false, true, true, false,
485 : ignore_attribute, NULL },
486 : { "no_split_stack", 0, 0, true, false, false, false,
487 : handle_no_split_stack_attribute, NULL },
488 : { "zero_call_used_regs", 1, 1, true, false, false, false,
489 : handle_zero_call_used_regs_attribute, NULL },
490 : /* For internal use only (marking of function arguments).
491 : The name contains a space to prevent its usage in source code. */
492 : { "arg spec", 1, -1, true, false, false, false,
493 : handle_argspec_attribute, NULL },
494 : /* For internal use (marking of builtins and runtime functions) only.
495 : The name contains space to prevent its usage in source code. */
496 : { "fn spec", 1, 1, false, true, true, false,
497 : handle_fnspec_attribute, NULL },
498 : { "warn_unused", 0, 0, false, false, false, false,
499 : handle_warn_unused_attribute, NULL },
500 : { "returns_nonnull", 0, 0, false, true, true, false,
501 : handle_returns_nonnull_attribute, NULL },
502 : { "omp declare simd", 0, -1, true, false, false, false,
503 : handle_omp_declare_simd_attribute,
504 : attr_omp_declare_simd_exclusions },
505 : { "omp declare variant base", 0, -1, true, false, false, false,
506 : handle_omp_declare_variant_attribute, NULL },
507 : { "omp declare variant variant", 0, -1, true, false, false, false,
508 : handle_omp_declare_variant_attribute, NULL },
509 : { "omp declare variant variant args", 0, -1, true, false,
510 : false, false,
511 : handle_omp_declare_variant_attribute, NULL },
512 : { "simd", 0, 1, true, false, false, false,
513 : handle_simd_attribute, attr_simd_exclusions },
514 : { "omp declare target", 0, -1, true, false, false, false,
515 : handle_omp_declare_target_attribute, NULL },
516 : { "omp declare target link", 0, 0, true, false, false, false,
517 : handle_omp_declare_target_attribute, NULL },
518 : { "omp declare target implicit", 0, 0, true, false, false, false,
519 : handle_omp_declare_target_attribute, NULL },
520 : { "omp declare target indirect", 0, 0, true, false, false, false,
521 : handle_omp_declare_target_attribute, NULL },
522 : { "omp declare target host", 0, 0, true, false, false, false,
523 : handle_omp_declare_target_attribute, NULL },
524 : { "omp declare target nohost", 0, 0, true, false, false, false,
525 : handle_omp_declare_target_attribute, NULL },
526 : { "omp groupprivate", 0, 0, true, false, false, false,
527 : handle_omp_declare_target_attribute, NULL },
528 : { "non overlapping", 0, 0, true, false, false, false,
529 : handle_non_overlapping_attribute, NULL },
530 : { "alloc_align", 1, 1, false, true, true, false,
531 : handle_alloc_align_attribute,
532 : attr_alloc_exclusions },
533 : { "assume_aligned", 1, 2, false, true, true, false,
534 : handle_assume_aligned_attribute, NULL },
535 : { "designated_init", 0, 0, false, true, false, false,
536 : handle_designated_init_attribute, NULL },
537 : { "fallthrough", 0, 0, false, false, false, false,
538 : handle_fallthrough_attribute, NULL },
539 : { "assume", 1, 1, false, false, false, false,
540 : handle_assume_attribute, NULL },
541 : { "patchable_function_entry", 1, 2, true, false, false, false,
542 : handle_patchable_function_entry_attribute,
543 : NULL },
544 : { "nocf_check", 0, 0, false, true, true, true,
545 : handle_nocf_check_attribute, NULL },
546 : { "symver", 1, -1, true, false, false, false,
547 : handle_symver_attribute, NULL},
548 : { "copy", 1, 1, false, false, false, false,
549 : handle_copy_attribute, NULL },
550 : { "noinit", 0, 0, true, false, false, false,
551 : handle_special_var_sec_attribute, attr_section_exclusions },
552 : { "persistent", 0, 0, true, false, false, false,
553 : handle_special_var_sec_attribute, attr_section_exclusions },
554 : { "access", 1, 3, false, true, true, false,
555 : handle_access_attribute, NULL },
556 : { "suppress_coverage", 0, 0, true, false, false, false,
557 : handle_suppress_coverage_attribute, NULL },
558 : /* Attributes used by Objective-C. */
559 : { "NSObject", 0, 0, true, false, false, false,
560 : handle_nsobject_attribute, NULL },
561 : { "objc_root_class", 0, 0, true, false, false, false,
562 : handle_objc_root_class_attribute, NULL },
563 : { "objc_nullability", 1, 1, true, false, false, false,
564 : handle_objc_nullability_attribute, NULL },
565 : { "*dealloc", 1, 2, true, false, false, false,
566 : handle_dealloc_attribute, NULL },
567 : { "tainted_args", 0, 0, true, false, false, false,
568 : handle_tainted_args_attribute, NULL },
569 : { "fd_arg", 1, 1, false, true, true, false,
570 : handle_fd_arg_attribute, NULL},
571 : { "fd_arg_read", 1, 1, false, true, true, false,
572 : handle_fd_arg_attribute, NULL},
573 : { "fd_arg_write", 1, 1, false, true, true, false,
574 : handle_fd_arg_attribute, NULL},
575 : { "flag_enum", 0, 0, false, true, false, false,
576 : handle_flag_enum_attribute, NULL },
577 : { "null_terminated_string_arg", 1, 1, false, true, true, false,
578 : handle_null_terminated_string_arg_attribute, NULL},
579 : { "btf_type_tag", 1, 1, false, true, false, false,
580 : handle_btf_type_tag_attribute, NULL},
581 : { "btf_decl_tag", 1, 1, true, false, false, false,
582 : handle_btf_decl_tag_attribute, NULL}
583 : };
584 :
585 : const struct scoped_attribute_specs c_common_gnu_attribute_table =
586 : {
587 : "gnu", { c_common_gnu_attributes }
588 : };
589 :
590 : /* Attributes also recognized in the clang:: namespace. */
591 : const struct attribute_spec c_common_clang_attributes[] = {
592 : { "flag_enum", 0, 0, false, true, false, false,
593 : handle_flag_enum_attribute, NULL },
594 : { "musttail", 0, 0, false, false, false,
595 : false, handle_musttail_attribute, NULL }
596 : };
597 :
598 : const struct scoped_attribute_specs c_common_clang_attribute_table =
599 : {
600 : "clang", { c_common_clang_attributes }
601 : };
602 :
603 : /* Give the specifications for the format attributes, used by C and all
604 : descendants.
605 :
606 : Current list of processed format attributes: format, format_arg. */
607 : const struct attribute_spec c_common_format_attributes[] =
608 : {
609 : /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
610 : affects_type_identity, handler, exclude } */
611 : { "format", 3, 3, false, true, true, false,
612 : handle_format_attribute, NULL },
613 : { "format_arg", 1, 1, false, true, true, false,
614 : handle_format_arg_attribute, NULL }
615 : };
616 :
617 : const struct scoped_attribute_specs c_common_format_attribute_table =
618 : {
619 : "gnu", { c_common_format_attributes }
620 : };
621 :
622 : /* Returns TRUE iff the attribute indicated by ATTR_ID takes a plain
623 : identifier as an argument, so the front end shouldn't look it up. */
624 :
625 : bool
626 17398489 : attribute_takes_identifier_p (const_tree attr_id)
627 : {
628 17398489 : const struct attribute_spec *spec = lookup_attribute_spec (attr_id);
629 17398489 : if (spec == NULL)
630 : {
631 : /* Unknown attribute that we'll end up ignoring, return true so we
632 : don't complain about an identifier argument. Except C++
633 : annotations. */
634 36 : if (c_dialect_cxx () && id_equal (attr_id, "annotation "))
635 : return false;
636 36 : return true;
637 : }
638 17398453 : else if (!strcmp ("mode", spec->name)
639 17342656 : || !strcmp ("format", spec->name)
640 16933360 : || !strcmp ("cleanup", spec->name)
641 16933030 : || !strcmp ("access", spec->name)
642 16090633 : || !strcmp ("counted_by", spec->name)
643 16090207 : || !strcmp ("old parm name", spec->name))
644 : return true;
645 : else
646 16090207 : return targetm.attribute_takes_identifier_p (attr_id);
647 : }
648 :
649 : /* Set a musttail attribute MUSTTAIL_P on return expression RETVAL
650 : at LOC. */
651 :
652 : void
653 145579144 : set_musttail_on_return (tree retval, location_t loc, bool musttail_p)
654 : {
655 145579144 : if (retval && musttail_p)
656 : {
657 849 : tree t = retval;
658 849 : if (TREE_CODE (t) == TARGET_EXPR)
659 20 : t = TARGET_EXPR_INITIAL (t);
660 849 : if (TREE_CODE (t) != CALL_EXPR)
661 12 : error_at (loc, "cannot tail-call: return value must be a call");
662 : else
663 837 : CALL_EXPR_MUST_TAIL_CALL (t) = 1;
664 : }
665 145578295 : else if (musttail_p && !retval)
666 8 : error_at (loc, "cannot tail-call: return value must be a call");
667 145579144 : }
668 :
669 : /* Verify that argument value POS at position ARGNO to attribute NAME
670 : applied to function FN (which is either a function declaration or function
671 : type) refers to a function parameter at position POS and the expected type
672 : CODE. Treat CODE == INTEGER_TYPE as matching all C integral types except
673 : bool. If successful, return POS after default conversions (and possibly
674 : adjusted by ADJUST_POS). Otherwise, issue appropriate warnings and return
675 : null. A non-zero 1-based ARGNO should be passed in by callers only for
676 : attributes with more than one argument.
677 :
678 : N.B. This function modifies POS. */
679 :
680 : tree
681 86272916 : positional_argument (const_tree fn, const_tree atname, tree &pos,
682 : tree_code code, int argno /* = 0 */,
683 : int flags /* = posargflags () */)
684 : {
685 86272916 : auto_urlify_attributes sentinel;
686 :
687 86272916 : const_tree fndecl = TYPE_P (fn) ? NULL_TREE : fn;
688 86272916 : const_tree fntype = TYPE_P (fn) ? fn : TREE_TYPE (fn);
689 86272916 : if (pos && TREE_CODE (pos) != IDENTIFIER_NODE
690 86272916 : && TREE_CODE (pos) != FUNCTION_DECL)
691 86272892 : pos = default_conversion (pos);
692 :
693 86272916 : tree postype = TREE_TYPE (pos);
694 86272916 : if (pos == error_mark_node || !postype)
695 : {
696 : /* Only mention the positional argument number when it's non-zero. */
697 20 : if (argno < 1)
698 9 : warning (OPT_Wattributes,
699 : "%qE attribute argument is invalid", atname);
700 : else
701 11 : warning (OPT_Wattributes,
702 : "%qE attribute argument %i is invalid", atname, argno);
703 :
704 : return NULL_TREE;
705 : }
706 :
707 86272896 : if (!INTEGRAL_TYPE_P (postype))
708 : {
709 : /* Handle this case specially to avoid mentioning the value
710 : of pointer constants in diagnostics. Only mention
711 : the positional argument number when it's non-zero. */
712 43 : if (argno < 1)
713 31 : warning (OPT_Wattributes,
714 : "%qE attribute argument has type %qT",
715 : atname, postype);
716 : else
717 12 : warning (OPT_Wattributes,
718 : "%qE attribute argument %i has type %qT",
719 : atname, argno, postype);
720 :
721 : return NULL_TREE;
722 : }
723 :
724 86272853 : if (TREE_CODE (pos) != INTEGER_CST)
725 : {
726 : /* Only mention the argument number when it's non-zero. */
727 9 : if (argno < 1)
728 3 : warning (OPT_Wattributes,
729 : "%qE attribute argument value %qE is not an integer "
730 : "constant",
731 : atname, pos);
732 : else
733 6 : warning (OPT_Wattributes,
734 : "%qE attribute argument %i value %qE is not an integer "
735 : "constant",
736 : atname, argno, pos);
737 :
738 : return NULL_TREE;
739 : }
740 :
741 : /* Argument positions are 1-based. */
742 86272844 : if (integer_zerop (pos))
743 : {
744 5108597 : if (flags & POSARG_ZERO)
745 : /* Zero is explicitly allowed. */
746 5108584 : return pos;
747 :
748 13 : if (argno < 1)
749 12 : warning (OPT_Wattributes,
750 : "%qE attribute argument value %qE does not refer to "
751 : "a function parameter",
752 : atname, pos);
753 : else
754 1 : warning (OPT_Wattributes,
755 : "%qE attribute argument %i value %qE does not refer to "
756 : "a function parameter",
757 : atname, argno, pos);
758 :
759 : return NULL_TREE;
760 : }
761 :
762 81164247 : if (!prototype_p (fntype))
763 123 : return pos;
764 :
765 : /* ADJUST_POS is non-zero in C++ when the function type has invisible
766 : parameters generated by the compiler, such as the in-charge or VTT
767 : parameters. */
768 81164124 : const int adjust_pos = maybe_adjust_arg_pos_for_attribute (fndecl);
769 :
770 : /* Verify that the argument position does not exceed the number
771 : of formal arguments to the function. When POSARG_ELLIPSIS
772 : is set, ARGNO may be beyond the last argument of a vararg
773 : function. */
774 81164124 : unsigned nargs = type_num_arguments (fntype);
775 81164124 : if (!nargs
776 81164118 : || !tree_fits_uhwi_p (pos)
777 81164115 : || ((flags & POSARG_ELLIPSIS) == 0
778 75402560 : && !IN_RANGE (tree_to_uhwi (pos) + adjust_pos, 1, nargs)))
779 : {
780 :
781 34 : if (argno < 1)
782 16 : warning (OPT_Wattributes,
783 : "%qE attribute argument value %qE exceeds the number "
784 : "of function parameters %u",
785 : atname, pos, nargs);
786 : else
787 18 : warning (OPT_Wattributes,
788 : "%qE attribute argument %i value %qE exceeds the number "
789 : "of function parameters %u",
790 : atname, argno, pos, nargs);
791 : return NULL_TREE;
792 : }
793 :
794 : /* Verify that the type of the referenced formal argument matches
795 : the expected type. Invisible parameters may have been added by
796 : the compiler, so adjust the position accordingly. */
797 81164090 : unsigned HOST_WIDE_INT ipos = tree_to_uhwi (pos) + adjust_pos;
798 :
799 : /* Zero was handled above. */
800 81164090 : gcc_assert (ipos != 0);
801 :
802 81164090 : if (tree argtype = type_argument_type (fntype, ipos))
803 : {
804 75402537 : if (argtype == error_mark_node)
805 : return NULL_TREE;
806 :
807 75402534 : if (flags & POSARG_ELLIPSIS)
808 : {
809 2 : if (argno < 1)
810 0 : error ("%qE attribute argument value %qE does not refer to "
811 : "a variable argument list",
812 : atname, pos);
813 : else
814 2 : error ("%qE attribute argument %i value %qE does not refer to "
815 : "a variable argument list",
816 : atname, argno, pos);
817 : return NULL_TREE;
818 : }
819 :
820 : /* Where the expected code is STRING_CST accept any pointer
821 : expected by attribute format (this includes possibly qualified
822 : char pointers and, for targets like Darwin, also pointers to
823 : struct CFString). */
824 75402532 : bool type_match;
825 75402532 : if (code == STRING_CST)
826 12088792 : type_match = valid_format_string_type_p (argtype);
827 63313740 : else if (code == INTEGER_TYPE)
828 : /* For integers, accept enums, wide characters and other types
829 : that match INTEGRAL_TYPE_P except for bool. */
830 19346261 : type_match = (INTEGRAL_TYPE_P (argtype)
831 19346261 : && TREE_CODE (argtype) != BOOLEAN_TYPE);
832 : else
833 43967479 : type_match = TREE_CODE (argtype) == code;
834 :
835 56056271 : if (!type_match)
836 : {
837 76 : if (code == STRING_CST)
838 : {
839 : /* Reject invalid format strings with an error. */
840 24 : if (argno < 1)
841 6 : error ("%qE attribute argument value %qE refers to "
842 : "parameter type %qT",
843 : atname, pos, argtype);
844 : else
845 18 : error ("%qE attribute argument %i value %qE refers to "
846 : "parameter type %qT",
847 : atname, argno, pos, argtype);
848 :
849 : return NULL_TREE;
850 : }
851 :
852 52 : if (argno < 1)
853 42 : warning (OPT_Wattributes,
854 : "%qE attribute argument value %qE refers to "
855 : "parameter type %qT",
856 : atname, pos, argtype);
857 : else
858 10 : warning (OPT_Wattributes,
859 : "%qE attribute argument %i value %qE refers to "
860 : "parameter type %qT",
861 : atname, argno, pos, argtype);
862 : return NULL_TREE;
863 : }
864 : }
865 5761553 : else if (!(flags & POSARG_ELLIPSIS))
866 : {
867 0 : if (argno < 1)
868 0 : warning (OPT_Wattributes,
869 : "%qE attribute argument value %qE refers to "
870 : "a variadic function parameter of unknown type",
871 : atname, pos);
872 : else
873 0 : warning (OPT_Wattributes,
874 : "%qE attribute argument %i value %qE refers to "
875 : "a variadic function parameter of unknown type",
876 : atname, argno, pos);
877 : return NULL_TREE;
878 : }
879 :
880 81164009 : return build_int_cst (TREE_TYPE (pos), ipos);
881 86272916 : }
882 :
883 : /* Attribute handlers common to C front ends. */
884 :
885 : /* Handle a "signed_bool_precision" attribute; arguments as in
886 : struct attribute_spec.handler. */
887 :
888 : static tree
889 4 : handle_signed_bool_precision_attribute (tree *node, tree name, tree args,
890 : int, bool *no_add_attrs)
891 : {
892 4 : *no_add_attrs = true;
893 4 : if (!flag_gimple)
894 : {
895 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
896 0 : return NULL_TREE;
897 : }
898 :
899 4 : if (!TYPE_P (*node) || TREE_CODE (*node) != BOOLEAN_TYPE)
900 : {
901 0 : warning (OPT_Wattributes, "%qE attribute only supported on "
902 : "boolean types", name);
903 0 : return NULL_TREE;
904 : }
905 :
906 4 : unsigned HOST_WIDE_INT prec = HOST_WIDE_INT_M1U;
907 4 : if (tree_fits_uhwi_p (TREE_VALUE (args)))
908 4 : prec = tree_to_uhwi (TREE_VALUE (args));
909 8 : if (prec > MAX_FIXED_MODE_SIZE)
910 : {
911 0 : warning (OPT_Wattributes, "%qE attribute with unsupported boolean "
912 : "precision", name);
913 0 : return NULL_TREE;
914 : }
915 :
916 4 : tree new_type = build_nonstandard_boolean_type (prec);
917 4 : *node = lang_hooks.types.reconstruct_complex_type (*node, new_type);
918 :
919 4 : return NULL_TREE;
920 : }
921 :
922 : /* Handle a "hardbool" attribute; arguments as in struct
923 : attribute_spec.handler. */
924 :
925 : static tree
926 492 : handle_hardbool_attribute (tree *node, tree name, tree args,
927 : int /* flags */, bool *no_add_attrs)
928 : {
929 492 : if (c_language != clk_c)
930 : {
931 0 : error ("%qE attribute only supported in C", name);
932 0 : *no_add_attrs = TRUE;
933 0 : return NULL_TREE;
934 : }
935 :
936 492 : if (!TYPE_P (*node) || TREE_CODE (*node) != INTEGER_TYPE)
937 : {
938 5 : error ("%qE attribute only supported on "
939 : "integral types", name);
940 5 : *no_add_attrs = TRUE;
941 5 : return NULL_TREE;
942 : }
943 :
944 487 : tree orig = *node;
945 : /* Drop qualifiers from the base type. Keep attributes, so that, in the odd
946 : chance attributes are applicable and relevant to the base type, if they
947 : are specified first, or through a typedef, they wouldn't be dropped on the
948 : floor here. */
949 487 : tree unqual = build_qualified_type (orig, TYPE_UNQUALIFIED);
950 487 : *node = build_distinct_type_copy (unqual);
951 :
952 487 : TREE_SET_CODE (*node, ENUMERAL_TYPE);
953 487 : ENUM_UNDERLYING_TYPE (*node) = unqual;
954 487 : SET_TYPE_STRUCTURAL_EQUALITY (*node);
955 :
956 487 : tree false_value;
957 487 : if (args)
958 481 : false_value = fold_convert (*node, TREE_VALUE (args));
959 : else
960 6 : false_value = fold_convert (*node, integer_zero_node);
961 :
962 487 : if (TREE_OVERFLOW_P (false_value))
963 : {
964 114 : warning (OPT_Wattributes,
965 : "overflows in conversion from %qT to %qT "
966 : "changes value from %qE to %qE",
967 57 : TREE_TYPE (TREE_VALUE (args)), *node,
968 57 : TREE_VALUE (args), false_value);
969 57 : TREE_OVERFLOW (false_value) = false;
970 : }
971 :
972 487 : tree true_value;
973 487 : if (args && TREE_CHAIN (args))
974 480 : true_value = fold_convert (*node, TREE_VALUE (TREE_CHAIN (args)));
975 : else
976 7 : true_value = fold_build1 (BIT_NOT_EXPR, *node, false_value);
977 :
978 487 : if (TREE_OVERFLOW_P (true_value))
979 : {
980 57 : warning (OPT_Wattributes,
981 : "overflows in conversion from %qT to %qT "
982 : "changes value from %qE to %qE",
983 57 : TREE_TYPE (TREE_VALUE (TREE_CHAIN (args))), *node,
984 57 : TREE_VALUE (TREE_CHAIN (args)), true_value);
985 57 : TREE_OVERFLOW (true_value) = false;
986 : }
987 :
988 487 : if (tree_int_cst_compare (false_value, true_value) == 0)
989 : {
990 2 : error ("%qE attribute requires different values for"
991 : " %<false%> and %<true%> for type %qT",
992 : name, *node);
993 2 : *no_add_attrs = TRUE;
994 2 : return NULL_TREE;
995 : }
996 :
997 485 : tree values = build_tree_list (get_identifier ("false"),
998 : false_value);
999 485 : TREE_CHAIN (values) = build_tree_list (get_identifier ("true"),
1000 : true_value);
1001 :
1002 : /* Do *not* set TYPE_MIN_VALUE, TYPE_MAX_VALUE, nor TYPE_PRECISION according
1003 : to the false and true values. That might cause the constants to be the
1004 : only acceptable values, which would drop the very hardening checks this
1005 : attribute is supposed to add. */
1006 :
1007 485 : TYPE_ATTRIBUTES (*node) = tree_cons (name, args,
1008 485 : TYPE_ATTRIBUTES (*node));
1009 485 : *no_add_attrs = TRUE;
1010 :
1011 485 : gcc_checking_assert (!TYPE_CACHED_VALUES_P (*node));
1012 485 : TYPE_VALUES (*node) = values;
1013 :
1014 485 : if (TYPE_QUALS (orig) != TYPE_QUALS (*node))
1015 14 : *node = build_qualified_type (*node, TYPE_QUALS (orig));
1016 :
1017 485 : if (TREE_CODE (orig) == TYPE_DECL)
1018 0 : TYPE_NAME (*node) = TYPE_NAME (orig);
1019 : else
1020 485 : TYPE_NAME (*node) = NULL_TREE;
1021 :
1022 : return NULL_TREE;
1023 : }
1024 :
1025 : /* Handle a "packed" attribute; arguments as in
1026 : struct attribute_spec.handler. */
1027 :
1028 : static tree
1029 5455 : handle_packed_attribute (tree *node, tree name, tree ARG_UNUSED (args),
1030 : int flags, bool *no_add_attrs)
1031 : {
1032 5455 : if (TYPE_P (*node))
1033 : {
1034 2539 : if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
1035 : {
1036 68 : warning (OPT_Wattributes,
1037 : "%qE attribute ignored for type %qT", name, *node);
1038 68 : *no_add_attrs = true;
1039 : }
1040 : else
1041 2471 : TYPE_PACKED (*node) = 1;
1042 : }
1043 2916 : else if (TREE_CODE (*node) == FIELD_DECL)
1044 : {
1045 2904 : if (TYPE_ALIGN (TREE_TYPE (*node)) <= BITS_PER_UNIT
1046 : /* Still pack bitfields. */
1047 2904 : && ! DECL_C_BIT_FIELD (*node))
1048 448 : warning (OPT_Wattributes,
1049 : "%qE attribute ignored for field of type %qT",
1050 448 : name, TREE_TYPE (*node));
1051 : else
1052 2456 : DECL_PACKED (*node) = 1;
1053 : }
1054 : /* We can't set DECL_PACKED for a VAR_DECL, because the bit is
1055 : used for DECL_REGISTER. It wouldn't mean anything anyway.
1056 : We can't set DECL_PACKED on the type of a TYPE_DECL, because
1057 : that changes what the typedef is typing. */
1058 : else
1059 : {
1060 12 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1061 12 : *no_add_attrs = true;
1062 : }
1063 :
1064 5455 : return NULL_TREE;
1065 : }
1066 :
1067 : /* Handle a "nocommon" attribute; arguments as in
1068 : struct attribute_spec.handler. */
1069 :
1070 : static tree
1071 11 : handle_nocommon_attribute (tree *node, tree name,
1072 : tree ARG_UNUSED (args),
1073 : int ARG_UNUSED (flags), bool *no_add_attrs)
1074 : {
1075 11 : if (VAR_P (*node))
1076 11 : DECL_COMMON (*node) = 0;
1077 : else
1078 : {
1079 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1080 0 : *no_add_attrs = true;
1081 : }
1082 :
1083 11 : return NULL_TREE;
1084 : }
1085 :
1086 : /* Handle a "common" attribute; arguments as in
1087 : struct attribute_spec.handler. */
1088 :
1089 : static tree
1090 41 : handle_common_attribute (tree *node, tree name, tree ARG_UNUSED (args),
1091 : int ARG_UNUSED (flags), bool *no_add_attrs)
1092 : {
1093 41 : if (VAR_P (*node))
1094 37 : DECL_COMMON (*node) = 1;
1095 : else
1096 : {
1097 4 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1098 4 : *no_add_attrs = true;
1099 : }
1100 :
1101 41 : return NULL_TREE;
1102 : }
1103 :
1104 : /* Handle a "musttail" attribute; arguments as in
1105 : struct attribute_spec.handler. */
1106 :
1107 : tree
1108 3 : handle_musttail_attribute (tree ARG_UNUSED (*node), tree name, tree ARG_UNUSED (args),
1109 : int ARG_UNUSED (flags), bool *no_add_attrs)
1110 : {
1111 : /* Currently only a statement attribute, handled directly in parser. */
1112 3 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1113 3 : *no_add_attrs = true;
1114 3 : return NULL_TREE;
1115 : }
1116 :
1117 : /* Handle a "noreturn" attribute; arguments as in
1118 : struct attribute_spec.handler. */
1119 :
1120 : tree
1121 4106734 : handle_noreturn_attribute (tree *node, tree name, tree ARG_UNUSED (args),
1122 : int ARG_UNUSED (flags), bool *no_add_attrs)
1123 : {
1124 4106734 : tree type = TREE_TYPE (*node);
1125 :
1126 : /* See FIXME comment in c_common_attribute_table. */
1127 4106734 : if (TREE_CODE (*node) == FUNCTION_DECL
1128 4106734 : || objc_method_decl (TREE_CODE (*node)))
1129 4106577 : TREE_THIS_VOLATILE (*node) = 1;
1130 157 : else if (TREE_CODE (type) == POINTER_TYPE
1131 157 : && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
1132 47 : TREE_TYPE (*node)
1133 47 : = (build_qualified_type
1134 47 : (build_pointer_type
1135 94 : (build_type_variant (TREE_TYPE (type),
1136 : TYPE_READONLY (TREE_TYPE (type)), 1)),
1137 47 : TYPE_QUALS (type)));
1138 : else
1139 : {
1140 110 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1141 110 : *no_add_attrs = true;
1142 : }
1143 :
1144 4106734 : return NULL_TREE;
1145 : }
1146 :
1147 : /* Handle a "hot" and attribute; arguments as in
1148 : struct attribute_spec.handler. */
1149 :
1150 : static tree
1151 162 : handle_hot_attribute (tree *node, tree name, tree ARG_UNUSED (args),
1152 : int ARG_UNUSED (flags), bool *no_add_attrs)
1153 : {
1154 162 : if (TREE_CODE (*node) == FUNCTION_DECL
1155 162 : || TREE_CODE (*node) == LABEL_DECL)
1156 : {
1157 : /* Attribute hot processing is done later with lookup_attribute. */
1158 : }
1159 9 : else if ((TREE_CODE (*node) == RECORD_TYPE
1160 9 : || TREE_CODE (*node) == UNION_TYPE)
1161 6 : && c_dialect_cxx ()
1162 6 : && (flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
1163 : {
1164 : /* Check conflict here as decl_attributes will otherwise only catch
1165 : it late at the function when the attribute is used on a class. */
1166 6 : tree cold_attr = lookup_attribute ("cold", TYPE_ATTRIBUTES (*node));
1167 6 : if (cold_attr)
1168 : {
1169 0 : warning (OPT_Wattributes, "ignoring attribute %qE because it "
1170 : "conflicts with attribute %qs", name, "cold");
1171 0 : *no_add_attrs = true;
1172 : }
1173 : }
1174 3 : else if (flags & ((int) ATTR_FLAG_FUNCTION_NEXT
1175 : | (int) ATTR_FLAG_DECL_NEXT))
1176 : {
1177 : /* Avoid applying the attribute to a function return type when
1178 : used as: void __attribute ((hot)) foo (void). It will be
1179 : passed to the function. */
1180 3 : *no_add_attrs = true;
1181 : }
1182 : else
1183 : {
1184 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1185 0 : *no_add_attrs = true;
1186 : }
1187 :
1188 162 : return NULL_TREE;
1189 : }
1190 :
1191 : /* Handle a "cold" and attribute; arguments as in
1192 : struct attribute_spec.handler. */
1193 :
1194 : static tree
1195 1902815 : handle_cold_attribute (tree *node, tree name, tree ARG_UNUSED (args),
1196 : int ARG_UNUSED (flags), bool *no_add_attrs)
1197 : {
1198 1902815 : if (TREE_CODE (*node) == FUNCTION_DECL
1199 1902815 : || TREE_CODE (*node) == LABEL_DECL)
1200 : {
1201 : /* Attribute cold processing is done later with lookup_attribute. */
1202 : }
1203 28 : else if ((TREE_CODE (*node) == RECORD_TYPE
1204 28 : || TREE_CODE (*node) == UNION_TYPE)
1205 6 : && c_dialect_cxx ()
1206 6 : && (flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
1207 : {
1208 : /* Check conflict here as decl_attributes will otherwise only catch
1209 : it late at the function when the attribute is used on a class. */
1210 6 : tree hot_attr = lookup_attribute ("hot", TYPE_ATTRIBUTES (*node));
1211 6 : if (hot_attr)
1212 : {
1213 0 : warning (OPT_Wattributes, "ignoring attribute %qE because it "
1214 : "conflicts with attribute %qs", name, "hot");
1215 0 : *no_add_attrs = true;
1216 : }
1217 : }
1218 22 : else if (flags & ((int) ATTR_FLAG_FUNCTION_NEXT
1219 : | (int) ATTR_FLAG_DECL_NEXT))
1220 : {
1221 : /* Avoid applying the attribute to a function return type when
1222 : used as: void __attribute ((cold)) foo (void). It will be
1223 : passed to the function. */
1224 0 : *no_add_attrs = true;
1225 : }
1226 : else
1227 : {
1228 22 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1229 22 : *no_add_attrs = true;
1230 : }
1231 :
1232 1902815 : return NULL_TREE;
1233 : }
1234 :
1235 : /* Add FLAGS for a function NODE to no_sanitize_flags in DECL_ATTRIBUTES. */
1236 :
1237 : void
1238 582 : add_no_sanitize_value (tree node, sanitize_code_type flags)
1239 : {
1240 582 : tree attr = lookup_attribute ("no_sanitize", DECL_ATTRIBUTES (node));
1241 582 : if (attr)
1242 : {
1243 21 : sanitize_code_type old_value =
1244 21 : tree_to_sanitize_code_type (TREE_VALUE (attr));
1245 21 : flags |= old_value;
1246 :
1247 21 : if (flags == old_value)
1248 : return;
1249 :
1250 7 : TREE_VALUE (attr) = build_int_cst (uint64_type_node, flags);
1251 : }
1252 : else
1253 561 : DECL_ATTRIBUTES (node)
1254 1122 : = tree_cons (get_identifier ("no_sanitize"),
1255 561 : build_int_cst (uint64_type_node, flags),
1256 561 : DECL_ATTRIBUTES (node));
1257 : }
1258 :
1259 : /* Handle a "no_sanitize" attribute; arguments as in
1260 : struct attribute_spec.handler. */
1261 :
1262 : static tree
1263 220 : handle_no_sanitize_attribute (tree *node, tree name, tree args, int,
1264 : bool *no_add_attrs)
1265 : {
1266 220 : sanitize_code_type flags = 0;
1267 220 : *no_add_attrs = true;
1268 220 : if (TREE_CODE (*node) != FUNCTION_DECL)
1269 : {
1270 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1271 0 : return NULL_TREE;
1272 : }
1273 :
1274 500 : for (; args; args = TREE_CHAIN (args))
1275 : {
1276 280 : tree id = TREE_VALUE (args);
1277 280 : if (TREE_CODE (id) != STRING_CST)
1278 : {
1279 0 : error ("%qE argument not a string", name);
1280 0 : return NULL_TREE;
1281 : }
1282 :
1283 280 : char *string = ASTRDUP (TREE_STRING_POINTER (id));
1284 280 : flags |= parse_no_sanitize_attribute (string);
1285 : }
1286 :
1287 220 : add_no_sanitize_value (*node, flags);
1288 :
1289 220 : return NULL_TREE;
1290 : }
1291 :
1292 : /* Handle a "no_sanitize_address" attribute; arguments as in
1293 : struct attribute_spec.handler. */
1294 :
1295 : static tree
1296 156 : handle_no_sanitize_address_attribute (tree *node, tree name, tree, int,
1297 : bool *no_add_attrs)
1298 : {
1299 156 : *no_add_attrs = true;
1300 156 : if (TREE_CODE (*node) != FUNCTION_DECL)
1301 14 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1302 : else
1303 142 : add_no_sanitize_value (*node, (sanitize_code_type) SANITIZE_ADDRESS);
1304 :
1305 156 : return NULL_TREE;
1306 : }
1307 :
1308 : /* Handle a "no_sanitize_thread" attribute; arguments as in
1309 : struct attribute_spec.handler. */
1310 :
1311 : static tree
1312 24 : handle_no_sanitize_thread_attribute (tree *node, tree name, tree, int,
1313 : bool *no_add_attrs)
1314 : {
1315 24 : *no_add_attrs = true;
1316 24 : if (TREE_CODE (*node) != FUNCTION_DECL)
1317 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1318 : else
1319 24 : add_no_sanitize_value (*node, (sanitize_code_type) SANITIZE_THREAD);
1320 :
1321 24 : return NULL_TREE;
1322 : }
1323 :
1324 :
1325 : /* Handle a "no_address_safety_analysis" attribute; arguments as in
1326 : struct attribute_spec.handler. */
1327 :
1328 : static tree
1329 28 : handle_no_address_safety_analysis_attribute (tree *node, tree name, tree, int,
1330 : bool *no_add_attrs)
1331 : {
1332 28 : *no_add_attrs = true;
1333 28 : if (TREE_CODE (*node) != FUNCTION_DECL)
1334 14 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1335 : else
1336 14 : add_no_sanitize_value (*node, (sanitize_code_type) SANITIZE_ADDRESS);
1337 :
1338 28 : return NULL_TREE;
1339 : }
1340 :
1341 : /* Handle a "no_sanitize_undefined" attribute; arguments as in
1342 : struct attribute_spec.handler. */
1343 :
1344 : static tree
1345 145 : handle_no_sanitize_undefined_attribute (tree *node, tree name, tree, int,
1346 : bool *no_add_attrs)
1347 : {
1348 145 : *no_add_attrs = true;
1349 145 : if (TREE_CODE (*node) != FUNCTION_DECL)
1350 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1351 : else
1352 145 : add_no_sanitize_value (*node,
1353 : SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT);
1354 :
1355 145 : return NULL_TREE;
1356 : }
1357 :
1358 : /* Handle a "no_sanitize_coverage" attribute; arguments as in
1359 : struct attribute_spec.handler. */
1360 :
1361 : static tree
1362 16 : handle_no_sanitize_coverage_attribute (tree *node, tree name, tree, int,
1363 : bool *no_add_attrs)
1364 : {
1365 16 : if (TREE_CODE (*node) != FUNCTION_DECL)
1366 : {
1367 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1368 0 : *no_add_attrs = true;
1369 : }
1370 :
1371 16 : return NULL_TREE;
1372 : }
1373 :
1374 : /* Handle an "asan odr indicator" attribute; arguments as in
1375 : struct attribute_spec.handler. */
1376 :
1377 : static tree
1378 0 : handle_asan_odr_indicator_attribute (tree *, tree, tree, int, bool *)
1379 : {
1380 0 : return NULL_TREE;
1381 : }
1382 :
1383 : /* Handle a "stack_protect" attribute; arguments as in
1384 : struct attribute_spec.handler. */
1385 :
1386 : static tree
1387 10 : handle_stack_protect_attribute (tree *node, tree name, tree, int,
1388 : bool *no_add_attrs)
1389 : {
1390 10 : if (TREE_CODE (*node) != FUNCTION_DECL)
1391 : {
1392 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1393 0 : *no_add_attrs = true;
1394 : }
1395 :
1396 10 : return NULL_TREE;
1397 : }
1398 :
1399 : /* Handle a "no_stack_protector" attribute; arguments as in
1400 : struct attribute_spec.handler. */
1401 :
1402 : static tree
1403 9 : handle_no_stack_protector_function_attribute (tree *node, tree name, tree,
1404 : int, bool *no_add_attrs)
1405 : {
1406 9 : if (TREE_CODE (*node) != FUNCTION_DECL)
1407 : {
1408 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1409 0 : *no_add_attrs = true;
1410 : }
1411 :
1412 9 : return NULL_TREE;
1413 : }
1414 :
1415 : /* Handle a "noipa" attribute; arguments as in
1416 : struct attribute_spec.handler. */
1417 :
1418 : static tree
1419 21055 : handle_noipa_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
1420 : {
1421 21055 : if (TREE_CODE (*node) != FUNCTION_DECL)
1422 : {
1423 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1424 0 : *no_add_attrs = true;
1425 : }
1426 :
1427 21055 : return NULL_TREE;
1428 : }
1429 :
1430 : /* Handle a "strub" attribute; arguments as in
1431 : struct attribute_spec.handler. */
1432 :
1433 : static tree
1434 2851 : handle_strub_attribute (tree *node, tree name,
1435 : tree args,
1436 : int ARG_UNUSED (flags), bool *no_add_attrs)
1437 : {
1438 2851 : bool enable = true;
1439 :
1440 2851 : if (args && FUNCTION_POINTER_TYPE_P (*node))
1441 134 : *node = TREE_TYPE (*node);
1442 :
1443 2851 : if (args && FUNC_OR_METHOD_TYPE_P (*node))
1444 : {
1445 2186 : switch (strub_validate_fn_attr_parm (TREE_VALUE (args)))
1446 : {
1447 : case 1:
1448 : case 2:
1449 : enable = true;
1450 : break;
1451 :
1452 0 : case 0:
1453 0 : warning (OPT_Wattributes,
1454 : "%qE attribute ignored because of argument %qE",
1455 0 : name, TREE_VALUE (args));
1456 0 : *no_add_attrs = true;
1457 0 : enable = false;
1458 0 : break;
1459 :
1460 : case -1:
1461 : case -2:
1462 1034 : enable = false;
1463 : break;
1464 :
1465 0 : default:
1466 0 : gcc_unreachable ();
1467 : }
1468 :
1469 2186 : args = TREE_CHAIN (args);
1470 : }
1471 :
1472 2186 : if (args)
1473 : {
1474 0 : warning (OPT_Wattributes,
1475 : "ignoring attribute %qE because of excess arguments"
1476 : " starting at %qE",
1477 0 : name, TREE_VALUE (args));
1478 0 : *no_add_attrs = true;
1479 0 : enable = false;
1480 : }
1481 :
1482 : /* Warn about unmet expectations that the strub attribute works like a
1483 : qualifier. ??? Could/should we extend it to the element/field types
1484 : here? */
1485 2851 : if (TREE_CODE (*node) == ARRAY_TYPE
1486 : || VECTOR_TYPE_P (*node)
1487 2851 : || TREE_CODE (*node) == COMPLEX_TYPE)
1488 8 : warning (OPT_Wattributes,
1489 : "attribute %qE does not apply to elements"
1490 : " of non-scalar type %qT",
1491 : name, *node);
1492 2843 : else if (RECORD_OR_UNION_TYPE_P (*node))
1493 4 : warning (OPT_Wattributes,
1494 : "attribute %qE does not apply to fields"
1495 : " of aggregate type %qT",
1496 : name, *node);
1497 :
1498 : /* If we see a strub-enabling attribute, and we're at the default setting,
1499 : implicitly or explicitly, note that the attribute was seen, so that we can
1500 : reduce the compile-time overhead to nearly zero when the strub feature is
1501 : not used. */
1502 2851 : if (enable && flag_strub < -2)
1503 593 : flag_strub += 2;
1504 :
1505 2851 : return NULL_TREE;
1506 : }
1507 :
1508 : /* Handle a "noclone" attribute; arguments as in
1509 : struct attribute_spec.handler. */
1510 :
1511 : static tree
1512 152411 : handle_noclone_attribute (tree *node, tree name,
1513 : tree ARG_UNUSED (args),
1514 : int ARG_UNUSED (flags), bool *no_add_attrs)
1515 : {
1516 152411 : if (TREE_CODE (*node) != FUNCTION_DECL)
1517 : {
1518 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1519 0 : *no_add_attrs = true;
1520 : }
1521 :
1522 152411 : return NULL_TREE;
1523 : }
1524 :
1525 : /* Handle a "nocf_check" attribute; arguments as in
1526 : struct attribute_spec.handler. */
1527 :
1528 : static tree
1529 99 : handle_nocf_check_attribute (tree *node, tree name,
1530 : tree ARG_UNUSED (args),
1531 : int ARG_UNUSED (flags), bool *no_add_attrs)
1532 : {
1533 99 : if (TREE_CODE (*node) != FUNCTION_TYPE
1534 99 : && TREE_CODE (*node) != METHOD_TYPE)
1535 : {
1536 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1537 0 : *no_add_attrs = true;
1538 : }
1539 99 : else if (!(flag_cf_protection & CF_BRANCH))
1540 : {
1541 34 : warning (OPT_Wattributes, "%qE attribute ignored. Use "
1542 : "%<-fcf-protection%> option to enable it",
1543 : name);
1544 34 : *no_add_attrs = true;
1545 : }
1546 :
1547 99 : return NULL_TREE;
1548 : }
1549 :
1550 : /* Handle a "no_icf" attribute; arguments as in
1551 : struct attribute_spec.handler. */
1552 :
1553 : static tree
1554 21070 : handle_noicf_attribute (tree *node, tree name,
1555 : tree ARG_UNUSED (args),
1556 : int ARG_UNUSED (flags), bool *no_add_attrs)
1557 : {
1558 21070 : if (TREE_CODE (*node) != FUNCTION_DECL
1559 21070 : && (TREE_CODE (*node) != VAR_DECL || !is_global_var (*node)))
1560 : {
1561 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1562 0 : *no_add_attrs = true;
1563 : }
1564 :
1565 21070 : return NULL_TREE;
1566 : }
1567 :
1568 : /* Handle a "gnu_inline" attribute; arguments as in
1569 : struct attribute_spec.handler. */
1570 :
1571 : static tree
1572 38559568 : handle_gnu_inline_attribute (tree *node, tree name,
1573 : tree ARG_UNUSED (args),
1574 : int ARG_UNUSED (flags),
1575 : bool *no_add_attrs)
1576 : {
1577 38559568 : if (TREE_CODE (*node) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (*node))
1578 : {
1579 : /* Do nothing else, just set the attribute. We'll get at
1580 : it later with lookup_attribute. */
1581 : }
1582 : else
1583 : {
1584 68938 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1585 68938 : *no_add_attrs = true;
1586 : }
1587 :
1588 38559568 : return NULL_TREE;
1589 : }
1590 :
1591 : /* Handle an "artificial" attribute; arguments as in
1592 : struct attribute_spec.handler. */
1593 :
1594 : static tree
1595 37900497 : handle_artificial_attribute (tree *node, tree name,
1596 : tree ARG_UNUSED (args),
1597 : int ARG_UNUSED (flags),
1598 : bool *no_add_attrs)
1599 : {
1600 37900497 : if (TREE_CODE (*node) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (*node))
1601 : {
1602 : /* Do nothing else, just set the attribute. We'll get at
1603 : it later with lookup_attribute. */
1604 : }
1605 : else
1606 : {
1607 68938 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1608 68938 : *no_add_attrs = true;
1609 : }
1610 :
1611 37900497 : return NULL_TREE;
1612 : }
1613 :
1614 : /* Handle a "flatten" attribute; arguments as in
1615 : struct attribute_spec.handler. */
1616 :
1617 : static tree
1618 159 : handle_flatten_attribute (tree *node, tree name,
1619 : tree args ATTRIBUTE_UNUSED,
1620 : int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
1621 : {
1622 159 : if (TREE_CODE (*node) == FUNCTION_DECL)
1623 : /* Do nothing else, just set the attribute. We'll get at
1624 : it later with lookup_attribute. */
1625 : ;
1626 : else
1627 : {
1628 4 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1629 4 : *no_add_attrs = true;
1630 : }
1631 :
1632 159 : return NULL_TREE;
1633 : }
1634 :
1635 : /* Handle a "warning" or "error" attribute; arguments as in
1636 : struct attribute_spec.handler. */
1637 :
1638 : static tree
1639 108 : handle_error_attribute (tree *node, tree name, tree args,
1640 : int ARG_UNUSED (flags), bool *no_add_attrs)
1641 : {
1642 108 : if (TREE_CODE (*node) == FUNCTION_DECL
1643 215 : && TREE_CODE (TREE_VALUE (args)) == STRING_CST)
1644 : /* Do nothing else, just set the attribute. We'll get at
1645 : it later with lookup_attribute. */
1646 : ;
1647 : else
1648 : {
1649 3 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1650 3 : *no_add_attrs = true;
1651 : }
1652 :
1653 108 : return NULL_TREE;
1654 : }
1655 :
1656 : /* Handle a "unused" attribute; arguments as in
1657 : struct attribute_spec.handler. */
1658 :
1659 : tree
1660 817451 : handle_unused_attribute (tree *node, tree name, tree ARG_UNUSED (args),
1661 : int flags, bool *no_add_attrs)
1662 : {
1663 817451 : if (DECL_P (*node))
1664 : {
1665 817297 : tree decl = *node;
1666 :
1667 817297 : if (TREE_CODE (decl) == PARM_DECL
1668 519223 : || VAR_OR_FUNCTION_DECL_P (decl)
1669 127483 : || TREE_CODE (decl) == LABEL_DECL
1670 127402 : || TREE_CODE (decl) == CONST_DECL
1671 281 : || TREE_CODE (decl) == FIELD_DECL
1672 260 : || TREE_CODE (decl) == TYPE_DECL)
1673 : {
1674 817296 : TREE_USED (decl) = 1;
1675 817296 : if (VAR_P (decl) || TREE_CODE (decl) == PARM_DECL)
1676 534559 : DECL_READ_P (decl) = 1;
1677 : }
1678 : else
1679 : {
1680 1 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1681 1 : *no_add_attrs = true;
1682 : }
1683 : }
1684 : else
1685 : {
1686 154 : if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
1687 85 : *node = build_variant_type_copy (*node);
1688 154 : TREE_USED (*node) = 1;
1689 : }
1690 :
1691 817451 : return NULL_TREE;
1692 : }
1693 :
1694 : /* Handle an "uninitialized" attribute; arguments as in
1695 : struct attribute_spec.handler. */
1696 :
1697 : static tree
1698 16789 : handle_uninitialized_attribute (tree *node, tree name, tree ARG_UNUSED (args),
1699 : int ARG_UNUSED (flags), bool *no_add_attrs)
1700 : {
1701 16789 : tree decl = *node;
1702 16789 : if (!VAR_P (decl))
1703 : {
1704 8 : warning (OPT_Wattributes, "%qE attribute ignored because %qD "
1705 : "is not a variable", name, decl);
1706 8 : *no_add_attrs = true;
1707 : }
1708 16781 : else if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
1709 : {
1710 24 : warning (OPT_Wattributes, "%qE attribute ignored because %qD "
1711 : "is not a local variable", name, decl);
1712 24 : *no_add_attrs = true;
1713 : }
1714 :
1715 16789 : return NULL_TREE;
1716 : }
1717 :
1718 : /* Handle a "externally_visible" attribute; arguments as in
1719 : struct attribute_spec.handler. */
1720 :
1721 : static tree
1722 291248 : handle_externally_visible_attribute (tree *pnode, tree name,
1723 : tree ARG_UNUSED (args),
1724 : int ARG_UNUSED (flags),
1725 : bool *no_add_attrs)
1726 : {
1727 291248 : tree node = *pnode;
1728 :
1729 291248 : if (VAR_OR_FUNCTION_DECL_P (node))
1730 : {
1731 291206 : if ((!TREE_STATIC (node) && TREE_CODE (node) != FUNCTION_DECL
1732 582450 : && !DECL_EXTERNAL (node)) || !TREE_PUBLIC (node))
1733 : {
1734 17 : warning (OPT_Wattributes,
1735 : "%qE attribute have effect only on public objects", name);
1736 17 : *no_add_attrs = true;
1737 : }
1738 : }
1739 : else
1740 : {
1741 4 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1742 4 : *no_add_attrs = true;
1743 : }
1744 :
1745 291248 : return NULL_TREE;
1746 : }
1747 :
1748 : /* Handle the "no_reorder" attribute. Arguments as in
1749 : struct attribute_spec.handler. */
1750 :
1751 : static tree
1752 17 : handle_no_reorder_attribute (tree *pnode,
1753 : tree name,
1754 : tree,
1755 : int,
1756 : bool *no_add_attrs)
1757 : {
1758 17 : tree node = *pnode;
1759 :
1760 15 : if (!VAR_OR_FUNCTION_DECL_P (node)
1761 17 : && !(TREE_STATIC (node) || DECL_EXTERNAL (node)))
1762 : {
1763 0 : warning (OPT_Wattributes,
1764 : "%qE attribute only affects top level objects",
1765 : name);
1766 0 : *no_add_attrs = true;
1767 : }
1768 :
1769 17 : return NULL_TREE;
1770 : }
1771 :
1772 : /* Handle a "scalar_storage_order" attribute; arguments as in
1773 : struct attribute_spec.handler. */
1774 :
1775 : static tree
1776 948 : handle_scalar_storage_order_attribute (tree *node, tree name, tree args,
1777 : int flags, bool *no_add_attrs)
1778 : {
1779 948 : tree id = TREE_VALUE (args);
1780 948 : tree type;
1781 :
1782 948 : if (TREE_CODE (*node) == TYPE_DECL
1783 3 : && ! (flags & ATTR_FLAG_CXX11))
1784 3 : node = &TREE_TYPE (*node);
1785 948 : type = *node;
1786 :
1787 948 : if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
1788 : {
1789 : error ("%qE attribute is not supported because endianness is not uniform",
1790 : name);
1791 : return NULL_TREE;
1792 : }
1793 :
1794 948 : if (RECORD_OR_UNION_TYPE_P (type) && !c_dialect_cxx ())
1795 : {
1796 945 : bool reverse = false;
1797 :
1798 945 : if (TREE_CODE (id) == STRING_CST
1799 945 : && strcmp (TREE_STRING_POINTER (id), "big-endian") == 0)
1800 : reverse = !BYTES_BIG_ENDIAN;
1801 452 : else if (TREE_CODE (id) == STRING_CST
1802 452 : && strcmp (TREE_STRING_POINTER (id), "little-endian") == 0)
1803 : reverse = BYTES_BIG_ENDIAN;
1804 : else
1805 : {
1806 3 : error ("attribute %qE argument must be one of %qs or %qs",
1807 : name, "big-endian", "little-endian");
1808 3 : return NULL_TREE;
1809 : }
1810 :
1811 942 : if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
1812 : {
1813 2 : if (reverse)
1814 : /* A type variant isn't good enough, since we don't want a cast
1815 : to such a type to be removed as a no-op. */
1816 1 : *node = type = build_duplicate_type (type);
1817 : }
1818 :
1819 942 : TYPE_REVERSE_STORAGE_ORDER (type) = reverse;
1820 942 : return NULL_TREE;
1821 : }
1822 :
1823 3 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1824 3 : *no_add_attrs = true;
1825 3 : return NULL_TREE;
1826 : }
1827 :
1828 : /* Handle a "transparent_union" attribute; arguments as in
1829 : struct attribute_spec.handler. */
1830 :
1831 : static tree
1832 150 : handle_transparent_union_attribute (tree *node, tree name,
1833 : tree ARG_UNUSED (args), int flags,
1834 : bool *no_add_attrs)
1835 : {
1836 150 : tree type;
1837 :
1838 150 : *no_add_attrs = true;
1839 :
1840 150 : if (TREE_CODE (*node) == TYPE_DECL
1841 89 : && ! (flags & ATTR_FLAG_CXX11))
1842 83 : node = &TREE_TYPE (*node);
1843 150 : type = *node;
1844 :
1845 150 : if (TREE_CODE (type) == UNION_TYPE)
1846 : {
1847 : /* Make sure that the first field will work for a transparent union.
1848 : If the type isn't complete yet, leave the check to the code in
1849 : finish_struct. */
1850 144 : if (TYPE_SIZE (type))
1851 : {
1852 83 : tree first = first_field (type);
1853 83 : if (first == NULL_TREE
1854 71 : || DECL_ARTIFICIAL (first)
1855 154 : || TYPE_MODE (type) != DECL_MODE (first))
1856 12 : goto ignored;
1857 : }
1858 :
1859 132 : if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
1860 : {
1861 : /* If the type isn't complete yet, setting the flag
1862 : on a variant wouldn't ever be checked. */
1863 65 : if (!TYPE_SIZE (type))
1864 0 : goto ignored;
1865 :
1866 : /* build_duplicate_type doesn't work for C++. */
1867 65 : if (c_dialect_cxx ())
1868 3 : goto ignored;
1869 :
1870 : /* A type variant isn't good enough, since we don't want a cast
1871 : to such a type to be removed as a no-op. */
1872 62 : *node = type = build_duplicate_type (type);
1873 : }
1874 :
1875 275 : for (tree t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
1876 146 : TYPE_TRANSPARENT_AGGR (t) = 1;
1877 : return NULL_TREE;
1878 : }
1879 :
1880 6 : ignored:
1881 21 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1882 21 : return NULL_TREE;
1883 : }
1884 :
1885 : /* Subroutine of handle_{con,de}structor_attribute. Evaluate ARGS to
1886 : get the requested priority for a constructor or destructor,
1887 : possibly issuing diagnostics for invalid or reserved
1888 : priorities. */
1889 :
1890 : static priority_type
1891 691 : get_priority (tree args, bool is_destructor)
1892 : {
1893 691 : HOST_WIDE_INT pri;
1894 691 : tree arg;
1895 :
1896 691 : if (!args)
1897 : return DEFAULT_INIT_PRIORITY;
1898 :
1899 271 : if (!SUPPORTS_INIT_PRIORITY)
1900 : {
1901 : if (is_destructor)
1902 : error ("destructor priorities are not supported");
1903 : else
1904 : error ("constructor priorities are not supported");
1905 : return DEFAULT_INIT_PRIORITY;
1906 : }
1907 :
1908 271 : arg = TREE_VALUE (args);
1909 271 : if (TREE_CODE (arg) == IDENTIFIER_NODE || TREE_CODE (arg) == FUNCTION_DECL)
1910 8 : goto invalid;
1911 263 : if (arg == error_mark_node)
1912 : return DEFAULT_INIT_PRIORITY;
1913 259 : arg = default_conversion (arg);
1914 259 : if (!tree_fits_shwi_p (arg)
1915 259 : || !INTEGRAL_TYPE_P (TREE_TYPE (arg)))
1916 11 : goto invalid;
1917 :
1918 248 : pri = tree_to_shwi (arg);
1919 248 : if (pri < 0 || pri > MAX_INIT_PRIORITY)
1920 8 : goto invalid;
1921 :
1922 240 : if (pri <= MAX_RESERVED_INIT_PRIORITY)
1923 : {
1924 24 : if (is_destructor)
1925 8 : warning (OPT_Wprio_ctor_dtor,
1926 : "destructor priorities from 0 to %d are reserved "
1927 : "for the implementation",
1928 : MAX_RESERVED_INIT_PRIORITY);
1929 : else
1930 16 : warning (OPT_Wprio_ctor_dtor,
1931 : "constructor priorities from 0 to %d are reserved "
1932 : "for the implementation",
1933 : MAX_RESERVED_INIT_PRIORITY);
1934 : }
1935 240 : return pri;
1936 :
1937 27 : invalid:
1938 27 : if (is_destructor)
1939 12 : error ("destructor priorities must be integers from 0 to %d inclusive",
1940 : MAX_INIT_PRIORITY);
1941 : else
1942 15 : error ("constructor priorities must be integers from 0 to %d inclusive",
1943 : MAX_INIT_PRIORITY);
1944 : return DEFAULT_INIT_PRIORITY;
1945 : }
1946 :
1947 : /* Handle a "constructor" attribute; arguments as in
1948 : struct attribute_spec.handler. */
1949 :
1950 : static tree
1951 504 : handle_constructor_attribute (tree *node, tree name, tree args,
1952 : int ARG_UNUSED (flags),
1953 : bool *no_add_attrs)
1954 : {
1955 504 : tree decl = *node;
1956 504 : tree type = TREE_TYPE (decl);
1957 :
1958 504 : if (TREE_CODE (decl) == FUNCTION_DECL
1959 504 : && TREE_CODE (type) == FUNCTION_TYPE
1960 1008 : && decl_function_context (decl) == 0)
1961 : {
1962 504 : priority_type priority;
1963 504 : DECL_STATIC_CONSTRUCTOR (decl) = 1;
1964 504 : priority = get_priority (args, /*is_destructor=*/false);
1965 504 : SET_DECL_INIT_PRIORITY (decl, priority);
1966 504 : TREE_USED (decl) = 1;
1967 : }
1968 : else
1969 : {
1970 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
1971 0 : *no_add_attrs = true;
1972 : }
1973 :
1974 504 : return NULL_TREE;
1975 : }
1976 :
1977 : /* Handle a "destructor" attribute; arguments as in
1978 : struct attribute_spec.handler. */
1979 :
1980 : static tree
1981 187 : handle_destructor_attribute (tree *node, tree name, tree args,
1982 : int ARG_UNUSED (flags),
1983 : bool *no_add_attrs)
1984 : {
1985 187 : tree decl = *node;
1986 187 : tree type = TREE_TYPE (decl);
1987 :
1988 187 : if (TREE_CODE (decl) == FUNCTION_DECL
1989 187 : && TREE_CODE (type) == FUNCTION_TYPE
1990 374 : && decl_function_context (decl) == 0)
1991 : {
1992 187 : priority_type priority;
1993 187 : DECL_STATIC_DESTRUCTOR (decl) = 1;
1994 187 : priority = get_priority (args, /*is_destructor=*/true);
1995 187 : SET_DECL_FINI_PRIORITY (decl, priority);
1996 187 : TREE_USED (decl) = 1;
1997 : }
1998 : else
1999 : {
2000 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
2001 0 : *no_add_attrs = true;
2002 : }
2003 :
2004 187 : return NULL_TREE;
2005 : }
2006 :
2007 : /* Nonzero if the mode is a valid vector mode for this architecture.
2008 : This returns nonzero even if there is no hardware support for the
2009 : vector mode, but we can emulate with narrower modes. */
2010 :
2011 : static bool
2012 0 : vector_mode_valid_p (machine_mode mode)
2013 : {
2014 0 : enum mode_class mclass = GET_MODE_CLASS (mode);
2015 :
2016 : /* Doh! What's going on? */
2017 0 : if (mclass != MODE_VECTOR_INT
2018 0 : && mclass != MODE_VECTOR_FLOAT
2019 : && mclass != MODE_VECTOR_FRACT
2020 0 : && mclass != MODE_VECTOR_UFRACT
2021 : && mclass != MODE_VECTOR_ACCUM
2022 0 : && mclass != MODE_VECTOR_UACCUM)
2023 : return false;
2024 :
2025 : /* Hardware support. Woo hoo! */
2026 0 : if (targetm.vector_mode_supported_p (mode))
2027 : return true;
2028 :
2029 : /* We should probably return 1 if requesting V4DI and we have no DI,
2030 : but we have V2DI, but this is probably very unlikely. */
2031 :
2032 : /* If we have support for the inner mode, we can safely emulate it.
2033 : We may not have V2DI, but me can emulate with a pair of DIs. */
2034 0 : return targetm.scalar_mode_supported_p (GET_MODE_INNER (mode));
2035 : }
2036 :
2037 :
2038 : /* Handle a "mode" attribute; arguments as in
2039 : struct attribute_spec.handler. */
2040 :
2041 : static tree
2042 55769 : handle_mode_attribute (tree *node, tree name, tree args,
2043 : int ARG_UNUSED (flags), bool *no_add_attrs)
2044 : {
2045 55769 : tree type = *node;
2046 55769 : tree ident = TREE_VALUE (args);
2047 :
2048 55769 : *no_add_attrs = true;
2049 :
2050 55769 : if (TREE_CODE (ident) != IDENTIFIER_NODE)
2051 2 : warning (OPT_Wattributes, "%qE attribute ignored", name);
2052 : else
2053 : {
2054 55767 : const char *p = IDENTIFIER_POINTER (ident);
2055 55767 : int len = strlen (p);
2056 55767 : machine_mode mode = VOIDmode;
2057 55767 : tree typefm;
2058 55767 : bool valid_mode;
2059 :
2060 55767 : if (len > 4 && p[0] == '_' && p[1] == '_'
2061 36223 : && p[len - 1] == '_' && p[len - 2] == '_')
2062 : {
2063 36223 : char *newp = (char *) alloca (len - 1);
2064 :
2065 36223 : strcpy (newp, &p[2]);
2066 36223 : newp[len - 4] = '\0';
2067 36223 : p = newp;
2068 : }
2069 :
2070 : /* Change this type to have a type with the specified mode.
2071 : First check for the special modes. */
2072 55767 : if (!strcmp (p, "byte"))
2073 82 : mode = byte_mode;
2074 55685 : else if (!strcmp (p, "word"))
2075 33828 : mode = word_mode;
2076 21857 : else if (!strcmp (p, "pointer"))
2077 767 : mode = ptr_mode;
2078 21090 : else if (!strcmp (p, "libgcc_cmp_return"))
2079 814 : mode = targetm.libgcc_cmp_return_mode ();
2080 20276 : else if (!strcmp (p, "libgcc_shift_count"))
2081 308 : mode = targetm.libgcc_shift_count_mode ();
2082 19968 : else if (!strcmp (p, "unwind_word"))
2083 410 : mode = targetm.unwind_word_mode ();
2084 : else
2085 19558 : parse_machine_mode (p, &mode);
2086 :
2087 55767 : if (mode == VOIDmode)
2088 : {
2089 2 : error ("unknown machine mode %qE", ident);
2090 10 : return NULL_TREE;
2091 : }
2092 :
2093 : /* Allow the target a chance to translate MODE into something supported.
2094 : See PR86324. */
2095 55765 : mode = targetm.translate_mode_attribute (mode);
2096 :
2097 55765 : valid_mode = false;
2098 55765 : switch (GET_MODE_CLASS (mode))
2099 : {
2100 53755 : case MODE_INT:
2101 53755 : case MODE_PARTIAL_INT:
2102 53755 : case MODE_FLOAT:
2103 53755 : case MODE_DECIMAL_FLOAT:
2104 53755 : case MODE_FRACT:
2105 53755 : case MODE_UFRACT:
2106 53755 : case MODE_ACCUM:
2107 53755 : case MODE_UACCUM:
2108 53755 : valid_mode
2109 53755 : = targetm.scalar_mode_supported_p (as_a <scalar_mode> (mode));
2110 53755 : break;
2111 :
2112 2010 : case MODE_COMPLEX_INT:
2113 2010 : case MODE_COMPLEX_FLOAT:
2114 2010 : valid_mode = targetm.scalar_mode_supported_p (GET_MODE_INNER (mode));
2115 2010 : break;
2116 :
2117 0 : case MODE_VECTOR_INT:
2118 0 : case MODE_VECTOR_FLOAT:
2119 0 : case MODE_VECTOR_FRACT:
2120 0 : case MODE_VECTOR_UFRACT:
2121 0 : case MODE_VECTOR_ACCUM:
2122 0 : case MODE_VECTOR_UACCUM:
2123 0 : warning (OPT_Wattributes, "specifying vector types with "
2124 : "%<__attribute__ ((mode))%> is deprecated");
2125 0 : inform (input_location,
2126 : "use %<__attribute__ ((vector_size))%> instead");
2127 0 : valid_mode = vector_mode_valid_p (mode);
2128 0 : break;
2129 :
2130 : default:
2131 : break;
2132 : }
2133 55765 : if (!valid_mode)
2134 : {
2135 7 : error ("unable to emulate %qs", p);
2136 7 : return NULL_TREE;
2137 : }
2138 :
2139 55758 : if (POINTER_TYPE_P (type))
2140 : {
2141 0 : scalar_int_mode addr_mode;
2142 0 : addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (type));
2143 0 : tree (*fn)(tree, machine_mode, bool);
2144 :
2145 0 : if (!is_a <scalar_int_mode> (mode, &addr_mode)
2146 0 : || !targetm.addr_space.valid_pointer_mode (addr_mode, as))
2147 : {
2148 0 : error ("invalid pointer mode %qs", p);
2149 0 : return NULL_TREE;
2150 : }
2151 :
2152 0 : if (TREE_CODE (type) == POINTER_TYPE)
2153 : fn = build_pointer_type_for_mode;
2154 : else
2155 0 : fn = build_reference_type_for_mode;
2156 0 : typefm = fn (TREE_TYPE (type), addr_mode, false);
2157 : }
2158 : else
2159 : {
2160 : /* For fixed-point modes, we need to test if the signness of type
2161 : and the machine mode are consistent. */
2162 55758 : if (ALL_FIXED_POINT_MODE_P (mode)
2163 55758 : && TYPE_UNSIGNED (type) != UNSIGNED_FIXED_POINT_MODE_P (mode))
2164 : {
2165 0 : error ("signedness of type and machine mode %qs don%'t match", p);
2166 0 : return NULL_TREE;
2167 : }
2168 : /* For fixed-point modes, we need to pass saturating info. */
2169 111516 : typefm = lang_hooks.types.type_for_mode (mode,
2170 55758 : ALL_FIXED_POINT_MODE_P (mode) ? TYPE_SATURATING (type)
2171 55758 : : TYPE_UNSIGNED (type));
2172 : }
2173 :
2174 55758 : if (typefm == NULL_TREE)
2175 : {
2176 0 : error ("no data type for mode %qs", p);
2177 0 : return NULL_TREE;
2178 : }
2179 55758 : else if (TREE_CODE (type) == ENUMERAL_TYPE)
2180 : {
2181 : /* For enumeral types, copy the precision from the integer
2182 : type returned above. If not an INTEGER_TYPE, we can't use
2183 : this mode for this type. */
2184 108 : if (TREE_CODE (typefm) != INTEGER_TYPE)
2185 : {
2186 0 : error ("cannot use mode %qs for enumerated types", p);
2187 0 : return NULL_TREE;
2188 : }
2189 :
2190 108 : if (flags & ATTR_FLAG_TYPE_IN_PLACE)
2191 : {
2192 34 : TYPE_PRECISION (type) = TYPE_PRECISION (typefm);
2193 34 : typefm = type;
2194 : }
2195 : else
2196 : {
2197 : /* We cannot build a type variant, as there's code that assumes
2198 : that TYPE_MAIN_VARIANT has the same mode. This includes the
2199 : debug generators. Instead, create a subrange type. This
2200 : results in all of the enumeral values being emitted only once
2201 : in the original, and the subtype gets them by reference. */
2202 74 : if (TYPE_UNSIGNED (type))
2203 74 : typefm = make_unsigned_type (TYPE_PRECISION (typefm));
2204 : else
2205 0 : typefm = make_signed_type (TYPE_PRECISION (typefm));
2206 74 : TREE_TYPE (typefm) = type;
2207 : }
2208 108 : *no_add_attrs = false;
2209 : }
2210 111300 : else if (VECTOR_MODE_P (mode)
2211 55650 : ? TREE_CODE (type) != TREE_CODE (TREE_TYPE (typefm))
2212 55650 : : TREE_CODE (type) != TREE_CODE (typefm))
2213 : {
2214 1 : error ("mode %qs applied to inappropriate type", p);
2215 1 : return NULL_TREE;
2216 : }
2217 :
2218 : /* Copy any quals and attributes to the new type. */
2219 55757 : *node = build_type_attribute_qual_variant (typefm, TYPE_ATTRIBUTES (type),
2220 55757 : TYPE_QUALS (type));
2221 55757 : if (TYPE_USER_ALIGN (type))
2222 4 : *node = build_aligned_type (*node, TYPE_ALIGN (type));
2223 : }
2224 :
2225 : return NULL_TREE;
2226 : }
2227 :
2228 : /* Common codes shared by handle_warn_if_not_aligned_attribute and
2229 : handle_aligned_attribute. */
2230 :
2231 : static tree
2232 663457 : common_handle_aligned_attribute (tree *node, tree name, tree args, int flags,
2233 : bool *no_add_attrs,
2234 : bool warn_if_not_aligned_p)
2235 : {
2236 663457 : tree decl = NULL_TREE;
2237 663457 : tree *type = NULL;
2238 663457 : bool is_type = false;
2239 663457 : tree align_expr;
2240 :
2241 : /* The last (already pushed) declaration with all validated attributes
2242 : merged in or the current about-to-be-pushed one if one hasn't been
2243 : yet. */
2244 663457 : tree last_decl = node[1] ? node[1] : *node;
2245 :
2246 663457 : if (args)
2247 : {
2248 622527 : align_expr = TREE_VALUE (args);
2249 622527 : if (align_expr && TREE_CODE (align_expr) != IDENTIFIER_NODE
2250 622527 : && TREE_CODE (align_expr) != FUNCTION_DECL)
2251 622519 : align_expr = default_conversion (align_expr);
2252 : }
2253 : else
2254 81860 : align_expr = size_int (ATTRIBUTE_ALIGNED_VALUE / BITS_PER_UNIT);
2255 :
2256 663457 : if (DECL_P (*node))
2257 : {
2258 633690 : decl = *node;
2259 633690 : type = &TREE_TYPE (decl);
2260 633690 : is_type = TREE_CODE (*node) == TYPE_DECL;
2261 : }
2262 29767 : else if (TYPE_P (*node))
2263 29767 : type = node, is_type = true;
2264 :
2265 : /* True to consider invalid alignments greater than MAX_OFILE_ALIGNMENT. */
2266 1326914 : bool objfile = (TREE_CODE (*node) == FUNCTION_DECL
2267 663457 : || (VAR_P (*node) && TREE_STATIC (*node)));
2268 : /* Log2 of specified alignment. */
2269 663457 : int pow2align = check_user_alignment (align_expr, objfile,
2270 : /* warn_zero = */ true);
2271 663457 : if (pow2align == -1)
2272 : {
2273 158 : *no_add_attrs = true;
2274 158 : return NULL_TREE;
2275 : }
2276 :
2277 : /* The alignment in bits corresponding to the specified alignment. */
2278 663299 : unsigned bitalign = (1U << pow2align) * BITS_PER_UNIT;
2279 :
2280 : /* The alignment of the current declaration and that of the last
2281 : pushed declaration, determined on demand below. */
2282 663299 : unsigned curalign = 0;
2283 663299 : unsigned lastalign = 0;
2284 :
2285 : /* True when SET_DECL_ALIGN() should be called for the decl when
2286 : *NO_ADD_ATTRS is false. */
2287 663299 : bool set_align = true;
2288 663299 : if (is_type)
2289 : {
2290 276915 : if ((flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
2291 : /* OK, modify the type in place. */;
2292 : /* If we have a TYPE_DECL, then copy the type, so that we
2293 : don't accidentally modify a builtin type. See pushdecl. */
2294 235006 : else if (decl && TREE_TYPE (decl) != error_mark_node
2295 470499 : && DECL_ORIGINAL_TYPE (decl) == NULL_TREE)
2296 : {
2297 234907 : tree tt = TREE_TYPE (decl);
2298 234907 : *type = build_variant_type_copy (*type);
2299 234907 : DECL_ORIGINAL_TYPE (decl) = tt;
2300 234907 : TYPE_NAME (*type) = decl;
2301 234907 : TREE_USED (*type) = TREE_USED (decl);
2302 234907 : TREE_TYPE (decl) = *type;
2303 : }
2304 : else
2305 586 : *type = build_variant_type_copy (*type);
2306 :
2307 276915 : if (warn_if_not_aligned_p)
2308 : {
2309 72 : SET_TYPE_WARN_IF_NOT_ALIGN (*type, bitalign);
2310 72 : warn_if_not_aligned_p = false;
2311 : }
2312 : else
2313 : {
2314 276843 : SET_TYPE_ALIGN (*type, bitalign);
2315 276843 : TYPE_USER_ALIGN (*type) = 1;
2316 : }
2317 : }
2318 386384 : else if (! VAR_OR_FUNCTION_DECL_P (decl)
2319 348831 : && TREE_CODE (decl) != FIELD_DECL)
2320 : {
2321 55 : error ("alignment may not be specified for %q+D", decl);
2322 55 : *no_add_attrs = true;
2323 : }
2324 386329 : else if (TREE_CODE (decl) == FUNCTION_DECL
2325 386329 : && (((curalign = DECL_ALIGN (decl)) > bitalign)
2326 319 : | ((lastalign = DECL_ALIGN (last_decl)) > bitalign)))
2327 : {
2328 : /* Either a prior attribute on the same declaration or one
2329 : on a prior declaration of the same function specifies
2330 : stricter alignment than this attribute. */
2331 50 : bool note = (lastalign > curalign
2332 50 : || (lastalign == curalign
2333 15 : && (DECL_USER_ALIGN (last_decl)
2334 15 : > DECL_USER_ALIGN (decl))));
2335 : if (note)
2336 : curalign = lastalign;
2337 :
2338 50 : curalign /= BITS_PER_UNIT;
2339 50 : unsigned newalign = bitalign / BITS_PER_UNIT;
2340 :
2341 50 : auto_diagnostic_group d;
2342 50 : if ((DECL_USER_ALIGN (decl)
2343 50 : || DECL_USER_ALIGN (last_decl)))
2344 : {
2345 65 : if (warning (OPT_Wattributes,
2346 : "ignoring attribute %<%E (%u)%> because it conflicts "
2347 : "with attribute %<%E (%u)%>",
2348 : name, newalign, name, curalign)
2349 50 : && note)
2350 35 : inform (DECL_SOURCE_LOCATION (last_decl),
2351 : "previous declaration here");
2352 : /* Only reject attempts to relax/override an alignment
2353 : explicitly specified previously and accept declarations
2354 : that appear to relax the implicit function alignment for
2355 : the target. Both increasing and increasing the alignment
2356 : set by -falign-functions setting is permitted. */
2357 50 : *no_add_attrs = true;
2358 : }
2359 0 : else if (!warn_if_not_aligned_p)
2360 : {
2361 : /* Do not fail for attribute warn_if_not_aligned. Otherwise,
2362 : silently avoid applying the alignment to the declaration
2363 : because it's implicitly satisfied by the target. Apply
2364 : the attribute nevertheless so it can be retrieved by
2365 : __builtin_has_attribute. */
2366 50 : set_align = false;
2367 : }
2368 50 : }
2369 386279 : else if (DECL_USER_ALIGN (decl)
2370 386279 : && DECL_ALIGN (decl) > bitalign)
2371 : /* C++-11 [dcl.align/4]:
2372 :
2373 : When multiple alignment-specifiers are specified for an
2374 : entity, the alignment requirement shall be set to the
2375 : strictest specified alignment.
2376 :
2377 : This formally comes from the c++11 specification but we are
2378 : doing it for the GNU attribute syntax as well. */
2379 3 : *no_add_attrs = true;
2380 386276 : else if (warn_if_not_aligned_p
2381 52 : && TREE_CODE (decl) == FIELD_DECL
2382 386320 : && !DECL_C_BIT_FIELD (decl))
2383 : {
2384 40 : SET_DECL_WARN_IF_NOT_ALIGN (decl, bitalign);
2385 40 : warn_if_not_aligned_p = false;
2386 40 : set_align = false;
2387 : }
2388 :
2389 663299 : if (warn_if_not_aligned_p)
2390 : {
2391 12 : error ("%<warn_if_not_aligned%> may not be specified for %q+D",
2392 : decl);
2393 12 : *no_add_attrs = true;
2394 : }
2395 663287 : else if (!is_type && !*no_add_attrs && set_align)
2396 : {
2397 386224 : SET_DECL_ALIGN (decl, bitalign);
2398 386224 : DECL_USER_ALIGN (decl) = 1;
2399 : }
2400 :
2401 : return NULL_TREE;
2402 : }
2403 :
2404 : /* Handle a "aligned" attribute; arguments as in
2405 : struct attribute_spec.handler. */
2406 :
2407 : tree
2408 663333 : handle_aligned_attribute (tree *node, tree name, tree args,
2409 : int flags, bool *no_add_attrs)
2410 : {
2411 663333 : return common_handle_aligned_attribute (node, name, args, flags,
2412 663333 : no_add_attrs, false);
2413 : }
2414 :
2415 : /* Handle a "warn_if_not_aligned" attribute; arguments as in
2416 : struct attribute_spec.handler. */
2417 :
2418 : static tree
2419 124 : handle_warn_if_not_aligned_attribute (tree *node, tree name,
2420 : tree args, int flags,
2421 : bool *no_add_attrs)
2422 : {
2423 124 : return common_handle_aligned_attribute (node, name, args, flags,
2424 124 : no_add_attrs, true);
2425 : }
2426 :
2427 : /* Handle a "strict_flex_array" attribute; arguments as in
2428 : struct attribute_spec.handler. */
2429 :
2430 : static tree
2431 22 : handle_strict_flex_array_attribute (tree *node, tree name,
2432 : tree args, int ARG_UNUSED (flags),
2433 : bool *no_add_attrs)
2434 : {
2435 22 : tree decl = *node;
2436 22 : tree argval = TREE_VALUE (args);
2437 :
2438 : /* This attribute only applies to field decls of a structure. */
2439 22 : if (TREE_CODE (decl) != FIELD_DECL)
2440 : {
2441 4 : error_at (DECL_SOURCE_LOCATION (decl),
2442 : "%qE attribute may not be specified for %q+D", name, decl);
2443 4 : *no_add_attrs = true;
2444 : }
2445 : /* This attribute only applies to field with array type. */
2446 18 : else if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
2447 : {
2448 4 : error_at (DECL_SOURCE_LOCATION (decl),
2449 : "%qE attribute may not be specified for a non-array field",
2450 : name);
2451 4 : *no_add_attrs = true;
2452 : }
2453 14 : else if (TREE_CODE (argval) != INTEGER_CST)
2454 : {
2455 4 : error_at (DECL_SOURCE_LOCATION (decl),
2456 : "%qE attribute argument not an integer", name);
2457 4 : *no_add_attrs = true;
2458 : }
2459 10 : else if (!tree_fits_uhwi_p (argval) || tree_to_uhwi (argval) > 3)
2460 : {
2461 4 : error_at (DECL_SOURCE_LOCATION (decl),
2462 : "%qE attribute argument %qE is not an integer constant"
2463 : " between 0 and 3", name, argval);
2464 4 : *no_add_attrs = true;
2465 : }
2466 :
2467 22 : return NULL_TREE;
2468 : }
2469 :
2470 : /* Handle a "counted_by" attribute; arguments as in
2471 : struct attribute_spec.handler. */
2472 :
2473 : static tree
2474 426 : handle_counted_by_attribute (tree *node, tree name,
2475 : tree args, int ARG_UNUSED (flags),
2476 : bool *no_add_attrs)
2477 : {
2478 426 : tree decl = *node;
2479 426 : tree argval = TREE_VALUE (args);
2480 426 : tree old_counted_by = lookup_attribute ("counted_by", DECL_ATTRIBUTES (decl));
2481 :
2482 : /* This attribute is not supported in C++. */
2483 426 : if (c_dialect_cxx ())
2484 : {
2485 12 : warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
2486 : "%qE attribute is not supported for C++ for now, ignored",
2487 : name);
2488 12 : *no_add_attrs = true;
2489 : }
2490 : /* This attribute only applies to field decls of a structure. */
2491 414 : else if (TREE_CODE (decl) != FIELD_DECL)
2492 : {
2493 2 : error_at (DECL_SOURCE_LOCATION (decl),
2494 : "%qE attribute is not allowed for a non-field"
2495 : " declaration %q+D", name, decl);
2496 2 : *no_add_attrs = true;
2497 : }
2498 : /* This attribute only applies to a field with array type or pointer type. */
2499 412 : else if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE
2500 412 : && TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE)
2501 : {
2502 2 : error_at (DECL_SOURCE_LOCATION (decl),
2503 : "%qE attribute is not allowed for a non-array"
2504 : " or non-pointer field", name);
2505 2 : *no_add_attrs = true;
2506 : }
2507 : /* This attribute only applies to a C99 flexible array member type. */
2508 410 : else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
2509 410 : && !flexible_array_member_type_p (TREE_TYPE (decl)))
2510 : {
2511 1 : error_at (DECL_SOURCE_LOCATION (decl),
2512 : "%qE attribute is not allowed for a non-flexible"
2513 : " array member field", name);
2514 1 : *no_add_attrs = true;
2515 : }
2516 : /* This attribute can be applied to a pointer to void type, but issue
2517 : warning when -Wpointer-arith is presenting. */
2518 409 : else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
2519 409 : && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == VOID_TYPE)
2520 : {
2521 11 : if (warn_pointer_arith)
2522 1 : warning_at (DECL_SOURCE_LOCATION (decl),
2523 1 : OPT_Wpointer_arith,
2524 : "%qE attribute is used for a pointer to void",
2525 : name);
2526 : }
2527 : /* This attribute cannot be applied to a pointer to function type. */
2528 398 : else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
2529 398 : && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == FUNCTION_TYPE)
2530 : {
2531 1 : error_at (DECL_SOURCE_LOCATION (decl),
2532 : "%qE attribute is not allowed for a pointer to"
2533 : " function", name);
2534 1 : *no_add_attrs = true;
2535 : }
2536 : /* This attribute cannot be applied to a pointer to structure or union
2537 : with flexible array member. */
2538 397 : else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
2539 259 : && RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (decl)))
2540 449 : && TYPE_INCLUDES_FLEXARRAY (TREE_TYPE (TREE_TYPE (decl))))
2541 : {
2542 1 : error_at (DECL_SOURCE_LOCATION (decl),
2543 : "%qE attribute is not allowed for a pointer to"
2544 : " structure or union with flexible array member", name);
2545 1 : *no_add_attrs = true;
2546 : }
2547 : /* The argument should be an identifier. */
2548 396 : else if (TREE_CODE (argval) != IDENTIFIER_NODE)
2549 : {
2550 2 : error_at (DECL_SOURCE_LOCATION (decl),
2551 : "%<counted_by%> argument is not an identifier");
2552 2 : *no_add_attrs = true;
2553 : }
2554 : /* Issue error when there is a counted_by attribute with a different
2555 : field as the argument for the same flexible array member or
2556 : pointer field. */
2557 394 : else if (old_counted_by != NULL_TREE)
2558 : {
2559 5 : tree old_fieldname = TREE_VALUE (TREE_VALUE (old_counted_by));
2560 5 : if (strcmp (IDENTIFIER_POINTER (old_fieldname),
2561 5 : IDENTIFIER_POINTER (argval)) != 0)
2562 : {
2563 3 : error_at (DECL_SOURCE_LOCATION (decl),
2564 : "%<counted_by%> argument %qE conflicts with"
2565 : " previous declaration %qE", argval, old_fieldname);
2566 3 : *no_add_attrs = true;
2567 : }
2568 : }
2569 :
2570 426 : return NULL_TREE;
2571 : }
2572 :
2573 : /* Handle a "noinit" or "persistent" attribute; arguments as in
2574 : struct attribute_spec.handler.
2575 : This generic handler is used for "special variable sections" that allow the
2576 : section name to be set using a dedicated attribute. Additional validation
2577 : is performed for the specific properties of the section corresponding to the
2578 : attribute.
2579 : The ".noinit" section *is not* loaded by the program loader, and is not
2580 : initialized by the runtime startup code.
2581 : The ".persistent" section *is* loaded by the program loader, but is not
2582 : initialized by the runtime startup code. */
2583 : static tree
2584 0 : handle_special_var_sec_attribute (tree *node, tree name, tree args,
2585 : int flags, bool *no_add_attrs)
2586 : {
2587 0 : tree decl = *node;
2588 0 : tree res = NULL_TREE;
2589 :
2590 : /* First perform generic validation common to "noinit" and "persistent"
2591 : attributes. */
2592 0 : if (!targetm_common.have_named_sections)
2593 : {
2594 0 : error_at (DECL_SOURCE_LOCATION (decl),
2595 : "section attributes are not supported for this target");
2596 0 : goto fail;
2597 : }
2598 :
2599 0 : if (!VAR_P (decl))
2600 : {
2601 0 : warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
2602 : "ignoring %qE attribute not set on a variable",
2603 : name);
2604 0 : goto fail;
2605 : }
2606 :
2607 0 : if (VAR_P (decl)
2608 0 : && current_function_decl != NULL_TREE
2609 0 : && !TREE_STATIC (decl))
2610 : {
2611 0 : error_at (DECL_SOURCE_LOCATION (decl),
2612 : "%qE attribute cannot be specified for local variables",
2613 : name);
2614 0 : goto fail;
2615 : }
2616 :
2617 0 : if (VAR_P (decl)
2618 0 : && !targetm.have_tls && targetm.emutls.tmpl_section
2619 0 : && DECL_THREAD_LOCAL_P (decl))
2620 : {
2621 0 : error ("section of %q+D cannot be overridden", decl);
2622 0 : goto fail;
2623 : }
2624 :
2625 0 : if (!targetm.have_switchable_bss_sections)
2626 : {
2627 0 : error ("%qE attribute is specific to ELF targets", name);
2628 0 : goto fail;
2629 : }
2630 :
2631 0 : if (TREE_READONLY (decl))
2632 : {
2633 0 : warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
2634 : "ignoring %qE attribute set on const variable",
2635 : name);
2636 0 : goto fail;
2637 : }
2638 :
2639 : /* Now validate noinit/persistent individually. */
2640 0 : if (strcmp (IDENTIFIER_POINTER (name), "noinit") == 0)
2641 : {
2642 0 : if (DECL_INITIAL (decl))
2643 : {
2644 0 : warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
2645 : "ignoring %qE attribute set on initialized variable",
2646 : name);
2647 0 : goto fail;
2648 : }
2649 : /* If this var is thought to be common, then change this. "noinit"
2650 : variables must be placed in an explicit ".noinit" section. */
2651 0 : DECL_COMMON (decl) = 0;
2652 : }
2653 0 : else if (strcmp (IDENTIFIER_POINTER (name), "persistent") == 0)
2654 : {
2655 0 : if (DECL_COMMON (decl) || DECL_INITIAL (decl) == NULL_TREE)
2656 : {
2657 0 : warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
2658 : "ignoring %qE attribute set on uninitialized variable",
2659 : name);
2660 0 : goto fail;
2661 : }
2662 : }
2663 : else
2664 0 : gcc_unreachable ();
2665 :
2666 0 : res = targetm.handle_generic_attribute (node, name, args, flags,
2667 : no_add_attrs);
2668 :
2669 : /* If the back end confirms the attribute can be added then continue onto
2670 : final processing. */
2671 0 : if (!(*no_add_attrs))
2672 : return res;
2673 :
2674 0 : fail:
2675 0 : *no_add_attrs = true;
2676 0 : return res;
2677 : }
2678 :
2679 : /* Handle a "noplt" attribute; arguments as in
2680 : struct attribute_spec.handler. */
2681 :
2682 : static tree
2683 7 : handle_noplt_attribute (tree *node, tree name,
2684 : tree ARG_UNUSED (args),
2685 : int ARG_UNUSED (flags),
2686 : bool * ARG_UNUSED (no_add_attrs))
2687 : {
2688 7 : if (TREE_CODE (*node) != FUNCTION_DECL)
2689 : {
2690 0 : warning (OPT_Wattributes,
2691 : "%qE attribute is only applicable on functions", name);
2692 0 : *no_add_attrs = true;
2693 0 : return NULL_TREE;
2694 : }
2695 : return NULL_TREE;
2696 : }
2697 :
2698 : /* Handle a "symver" attribute. */
2699 :
2700 : static tree
2701 2 : handle_symver_attribute (tree *node, tree ARG_UNUSED (name), tree args,
2702 : int ARG_UNUSED (flags), bool *no_add_attrs)
2703 : {
2704 2 : tree symver;
2705 2 : const char *symver_str;
2706 :
2707 2 : if (TREE_CODE (*node) != FUNCTION_DECL && TREE_CODE (*node) != VAR_DECL)
2708 : {
2709 0 : warning (OPT_Wattributes,
2710 : "%<symver%> attribute only applies to functions and variables");
2711 0 : *no_add_attrs = true;
2712 0 : return NULL_TREE;
2713 : }
2714 :
2715 2 : if (!decl_in_symtab_p (*node))
2716 : {
2717 0 : warning (OPT_Wattributes,
2718 : "%<symver%> attribute is only applicable to symbols");
2719 0 : *no_add_attrs = true;
2720 0 : return NULL_TREE;
2721 : }
2722 :
2723 4 : for (; args; args = TREE_CHAIN (args))
2724 : {
2725 2 : symver = TREE_VALUE (args);
2726 2 : if (TREE_CODE (symver) != STRING_CST)
2727 : {
2728 0 : error ("%<symver%> attribute argument not a string constant");
2729 0 : *no_add_attrs = true;
2730 0 : return NULL_TREE;
2731 : }
2732 :
2733 2 : symver_str = TREE_STRING_POINTER (symver);
2734 :
2735 2 : int ats = 0;
2736 22 : for (int n = 0; (int)n < TREE_STRING_LENGTH (symver); n++)
2737 20 : if (symver_str[n] == '@')
2738 2 : ats++;
2739 :
2740 2 : if (ats != 1 && ats != 2)
2741 : {
2742 0 : error ("symver attribute argument must have format %<name@nodename%>");
2743 0 : error ("%<symver%> attribute argument %qs must contain one or two "
2744 : "%<@%>", symver_str);
2745 0 : *no_add_attrs = true;
2746 0 : return NULL_TREE;
2747 : }
2748 : }
2749 :
2750 : return NULL_TREE;
2751 : }
2752 :
2753 : /* Handle an "alias" or "ifunc" attribute; arguments as in
2754 : struct attribute_spec.handler. */
2755 :
2756 : static tree
2757 118 : handle_ifunc_attribute (tree *node, tree name, tree args,
2758 : int ARG_UNUSED (flags), bool *no_add_attrs)
2759 : {
2760 118 : return handle_alias_ifunc_attribute (false, node, name, args, no_add_attrs);
2761 : }
2762 :
2763 : /* Handle the "copy" attribute NAME by copying the set of attributes
2764 : from the symbol referenced by ARGS to the declaration of *NODE. */
2765 :
2766 : static tree
2767 1103 : handle_copy_attribute (tree *node, tree name, tree args,
2768 : int flags, bool *no_add_attrs)
2769 : {
2770 : /* Do not apply the copy attribute itself. It serves no purpose
2771 : other than to copy other attributes. */
2772 1103 : *no_add_attrs = true;
2773 :
2774 1103 : tree decl = *node;
2775 :
2776 1103 : tree ref = TREE_VALUE (args);
2777 1103 : if (ref == error_mark_node)
2778 : return NULL_TREE;
2779 :
2780 1102 : location_t loc = input_location;
2781 1102 : if (DECL_P (decl))
2782 1099 : loc = DECL_SOURCE_LOCATION (decl);
2783 1102 : if (TREE_CODE (ref) == STRING_CST)
2784 : {
2785 : /* Explicitly handle this case since using a string literal
2786 : as an argument is a likely mistake. */
2787 2 : error_at (loc, "%qE attribute argument cannot be a string", name);
2788 2 : return NULL_TREE;
2789 : }
2790 :
2791 1100 : if (CONSTANT_CLASS_P (ref)
2792 1100 : && (INTEGRAL_TYPE_P (TREE_TYPE (ref))
2793 15 : || FLOAT_TYPE_P (TREE_TYPE (ref))))
2794 : {
2795 : /* Similar to the string case, since some function attributes
2796 : accept literal numbers as arguments (e.g., alloc_size or
2797 : nonnull) using one here is a likely mistake. */
2798 1 : error_at (loc, "%qE attribute argument cannot be a constant arithmetic "
2799 : "expression", name);
2800 1 : return NULL_TREE;
2801 : }
2802 :
2803 1099 : if (ref == node[1])
2804 : {
2805 : /* Another possible mistake (but indirect self-references aren't
2806 : and diagnosed and shouldn't be). */
2807 9 : if (warning_at (loc, OPT_Wattributes,
2808 : "%qE attribute ignored on a redeclaration "
2809 : "of the referenced symbol", name)
2810 9 : && DECL_P (node[1]))
2811 9 : inform (DECL_SOURCE_LOCATION (node[1]), "previous declaration here");
2812 : return NULL_TREE;
2813 : }
2814 :
2815 : /* Consider address-of expressions in the attribute argument
2816 : as requests to copy from the referenced entity. */
2817 1090 : if (TREE_CODE (ref) == ADDR_EXPR)
2818 18 : ref = TREE_OPERAND (ref, 0);
2819 :
2820 1133 : do
2821 : {
2822 : /* Drill down into references to find the referenced decl. */
2823 1133 : tree_code refcode = TREE_CODE (ref);
2824 1133 : if (refcode == ARRAY_REF
2825 1133 : || refcode == INDIRECT_REF)
2826 51 : ref = TREE_OPERAND (ref, 0);
2827 1082 : else if (refcode == COMPONENT_REF)
2828 70 : ref = TREE_OPERAND (ref, 1);
2829 : else
2830 : break;
2831 : }
2832 121 : while (!DECL_P (ref));
2833 :
2834 : /* For object pointer expressions, consider those to be requests
2835 : to copy from their type, such as in:
2836 : struct __attribute__ (copy ((struct T *)0)) U { ... };
2837 : which copies type attributes from struct T to the declaration
2838 : of struct U. */
2839 1067 : if ((CONSTANT_CLASS_P (ref) || EXPR_P (ref))
2840 72 : && POINTER_TYPE_P (TREE_TYPE (ref))
2841 1145 : && !FUNCTION_POINTER_TYPE_P (TREE_TYPE (ref)))
2842 44 : ref = TREE_TYPE (ref);
2843 :
2844 1090 : tree reftype = TYPE_P (ref) ? ref : TREE_TYPE (ref);
2845 :
2846 1090 : if (DECL_P (decl))
2847 : {
2848 1088 : if ((VAR_P (decl)
2849 21 : && (TREE_CODE (ref) == FUNCTION_DECL
2850 20 : || (EXPR_P (ref)
2851 1 : && POINTER_TYPE_P (reftype)
2852 1 : && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (reftype)))))
2853 1107 : || (TREE_CODE (decl) == FUNCTION_DECL
2854 930 : && (VAR_P (ref)
2855 929 : || (EXPR_P (ref)
2856 17 : && !FUNC_OR_METHOD_TYPE_P (reftype)
2857 11 : && (!POINTER_TYPE_P (reftype)
2858 10 : || !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (reftype)))))))
2859 : {
2860 : /* It makes no sense to try to copy function attributes
2861 : to a variable, or variable attributes to a function. */
2862 6 : if (warning (OPT_Wattributes,
2863 : "%qE attribute ignored on a declaration of "
2864 : "a different kind than referenced symbol", name)
2865 4 : && DECL_P (ref))
2866 2 : inform (DECL_SOURCE_LOCATION (ref),
2867 : "symbol %qD referenced by %qD declared here", ref, decl);
2868 : return NULL_TREE;
2869 : }
2870 :
2871 1084 : tree attrs = NULL_TREE;
2872 1084 : if (DECL_P (ref))
2873 1016 : attrs = DECL_ATTRIBUTES (ref);
2874 68 : else if (TYPE_P (ref))
2875 42 : attrs = TYPE_ATTRIBUTES (ref);
2876 :
2877 : /* Copy decl attributes from REF to DECL. */
2878 1854 : for (tree at = attrs; at; at = TREE_CHAIN (at))
2879 : {
2880 : /* Avoid copying attributes that affect a symbol linkage,
2881 : inlining, or visibility since those in all likelihood
2882 : only apply to the target.
2883 : FIXME: make it possible to specify which attributes to
2884 : copy or not to copy in the copy attribute itself. */
2885 770 : tree atname = get_attribute_name (at);
2886 770 : if (is_attribute_p ("alias", atname)
2887 769 : || is_attribute_p ("always_inline", atname)
2888 767 : || is_attribute_p ("gnu_inline", atname)
2889 758 : || is_attribute_p ("ifunc", atname)
2890 758 : || is_attribute_p ("noinline", atname)
2891 746 : || is_attribute_p ("visibility", atname)
2892 509 : || is_attribute_p ("weak", atname)
2893 509 : || is_attribute_p ("weakref", atname)
2894 1279 : || is_attribute_p ("target_clones", atname))
2895 262 : continue;
2896 :
2897 : /* Attribute leaf only applies to extern functions.
2898 : Avoid copying it to static ones. */
2899 529 : if (!TREE_PUBLIC (decl)
2900 508 : && is_attribute_p ("leaf", atname))
2901 21 : continue;
2902 :
2903 487 : tree atargs = TREE_VALUE (at);
2904 : /* Create a copy of just the one attribute ar AT, including
2905 : its argumentsm and add it to DECL. */
2906 487 : tree attr = tree_cons (atname, copy_list (atargs), NULL_TREE);
2907 487 : decl_attributes (node, attr, flags, EXPR_P (ref) ? NULL_TREE : ref);
2908 : }
2909 :
2910 : /* Proceed to copy type attributes below. */
2911 : }
2912 2 : else if (!TYPE_P (decl))
2913 : {
2914 0 : error_at (loc, "%qE attribute must apply to a declaration", name);
2915 0 : return NULL_TREE;
2916 : }
2917 :
2918 : /* A function declared with attribute nothrow has the attribute
2919 : attached to it, but a C++ throw() function does not. */
2920 1086 : if (TREE_NOTHROW (ref))
2921 559 : TREE_NOTHROW (decl) = true;
2922 :
2923 : /* Similarly, a function declared with attribute noreturn has it
2924 : attached on to it, but a C11 _Noreturn function does not. */
2925 1086 : if (DECL_P (ref)
2926 1016 : && TREE_THIS_VOLATILE (ref)
2927 33 : && FUNC_OR_METHOD_TYPE_P (reftype))
2928 32 : TREE_THIS_VOLATILE (decl) = true;
2929 :
2930 1086 : if (POINTER_TYPE_P (reftype))
2931 96 : reftype = TREE_TYPE (reftype);
2932 :
2933 1086 : if (!TYPE_P (reftype))
2934 : return NULL_TREE;
2935 :
2936 1086 : tree attrs = TYPE_ATTRIBUTES (reftype);
2937 :
2938 : /* Copy type attributes from REF to DECL. Pass in REF if it's a DECL
2939 : or a type but not if it's an expression. Set ATTR_FLAG_INTERNAL
2940 : since the attributes' arguments may be in their internal form. */
2941 1425 : for (tree at = attrs; at; at = TREE_CHAIN (at))
2942 339 : decl_attributes (node, at, flags | ATTR_FLAG_INTERNAL,
2943 339 : EXPR_P (ref) ? NULL_TREE : ref);
2944 :
2945 : return NULL_TREE;
2946 : }
2947 :
2948 : /* Handle a "weakref" attribute; arguments as in struct
2949 : attribute_spec.handler. */
2950 :
2951 : static tree
2952 917 : handle_weakref_attribute (tree *node, tree name, tree args,
2953 : int flags, bool *no_add_attrs)
2954 : {
2955 917 : tree attr = NULL_TREE;
2956 :
2957 : /* We must ignore the attribute when it is associated with
2958 : local-scoped decls, since attribute alias is ignored and many
2959 : such symbols do not even have a DECL_WEAK field. */
2960 917 : if (decl_function_context (*node)
2961 917 : || current_function_decl
2962 1834 : || !VAR_OR_FUNCTION_DECL_P (*node))
2963 : {
2964 2 : warning (OPT_Wattributes, "%qE attribute ignored", name);
2965 2 : *no_add_attrs = true;
2966 2 : return NULL_TREE;
2967 : }
2968 :
2969 915 : if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (*node)))
2970 : {
2971 0 : error ("indirect function %q+D cannot be declared %qE",
2972 : *node, name);
2973 0 : *no_add_attrs = true;
2974 0 : return NULL_TREE;
2975 : }
2976 :
2977 : /* The idea here is that `weakref("name")' mutates into `weakref,
2978 : alias("name")', and weakref without arguments, in turn,
2979 : implicitly adds weak. */
2980 :
2981 915 : if (args)
2982 : {
2983 455 : attr = tree_cons (get_identifier ("alias"), args, attr);
2984 455 : attr = tree_cons (get_identifier ("weakref"), NULL_TREE, attr);
2985 :
2986 455 : *no_add_attrs = true;
2987 :
2988 455 : decl_attributes (node, attr, flags);
2989 : }
2990 : else
2991 : {
2992 460 : if (lookup_attribute ("alias", DECL_ATTRIBUTES (*node)))
2993 0 : error_at (DECL_SOURCE_LOCATION (*node),
2994 : "%qE attribute must appear before %qs attribute",
2995 : name, "alias");
2996 :
2997 : /* Can't call declare_weak because it wants this to be TREE_PUBLIC,
2998 : and that isn't supported; and because it wants to add it to
2999 : the list of weak decls, which isn't helpful. */
3000 460 : DECL_WEAK (*node) = 1;
3001 : }
3002 :
3003 915 : if (decl_in_symtab_p (*node))
3004 : {
3005 915 : struct symtab_node *n = symtab_node::get (*node);
3006 915 : if (n && n->refuse_visibility_changes)
3007 0 : error ("%+qD declared %qE after being used", *node, name);
3008 : }
3009 :
3010 : return NULL_TREE;
3011 : }
3012 :
3013 : /* Handle an "tls_model" attribute; arguments as in
3014 : struct attribute_spec.handler. */
3015 :
3016 : static tree
3017 323 : handle_tls_model_attribute (tree *node, tree name, tree args,
3018 : int ARG_UNUSED (flags),
3019 : bool *ARG_UNUSED (no_add_attrs))
3020 : {
3021 323 : tree id;
3022 323 : tree decl = *node;
3023 323 : enum tls_model kind;
3024 :
3025 323 : if (!VAR_P (decl))
3026 : {
3027 2 : warning (OPT_Wattributes, "%qE attribute ignored because %qD "
3028 : "is not a variable",
3029 : name, decl);
3030 2 : return NULL_TREE;
3031 : }
3032 :
3033 321 : if (!DECL_THREAD_LOCAL_P (decl))
3034 : {
3035 2 : warning (OPT_Wattributes, "%qE attribute ignored because %qD does "
3036 : "not have thread storage duration", name, decl);
3037 2 : return NULL_TREE;
3038 : }
3039 :
3040 319 : kind = DECL_TLS_MODEL (decl);
3041 319 : id = TREE_VALUE (args);
3042 319 : if (TREE_CODE (id) != STRING_CST)
3043 : {
3044 1 : error ("%qE argument not a string", name);
3045 1 : return NULL_TREE;
3046 : }
3047 :
3048 318 : if (!strcmp (TREE_STRING_POINTER (id), "local-exec"))
3049 : kind = TLS_MODEL_LOCAL_EXEC;
3050 287 : else if (!strcmp (TREE_STRING_POINTER (id), "initial-exec"))
3051 : kind = TLS_MODEL_INITIAL_EXEC;
3052 188 : else if (!strcmp (TREE_STRING_POINTER (id), "local-dynamic"))
3053 187 : kind = optimize ? TLS_MODEL_LOCAL_DYNAMIC : TLS_MODEL_GLOBAL_DYNAMIC;
3054 134 : else if (!strcmp (TREE_STRING_POINTER (id), "global-dynamic"))
3055 : kind = TLS_MODEL_GLOBAL_DYNAMIC;
3056 : else
3057 1 : error ("%qE argument must be one of %qs, %qs, %qs, or %qs",
3058 : name,
3059 : "local-exec", "initial-exec", "local-dynamic", "global-dynamic");
3060 :
3061 318 : set_decl_tls_model (decl, kind);
3062 318 : return NULL_TREE;
3063 : }
3064 :
3065 : /* Handle a "no_instrument_function" attribute; arguments as in
3066 : struct attribute_spec.handler. */
3067 :
3068 : static tree
3069 76 : handle_no_instrument_function_attribute (tree *node, tree name,
3070 : tree ARG_UNUSED (args),
3071 : int ARG_UNUSED (flags),
3072 : bool *no_add_attrs)
3073 : {
3074 76 : tree decl = *node;
3075 :
3076 76 : if (TREE_CODE (decl) != FUNCTION_DECL)
3077 : {
3078 0 : error_at (DECL_SOURCE_LOCATION (decl),
3079 : "%qE attribute applies only to functions", name);
3080 0 : *no_add_attrs = true;
3081 : }
3082 : else
3083 76 : DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
3084 :
3085 76 : return NULL_TREE;
3086 : }
3087 :
3088 : /* Handle a "no_profile_instrument_function" attribute; arguments as in
3089 : struct attribute_spec.handler. */
3090 :
3091 : static tree
3092 3 : handle_no_profile_instrument_function_attribute (tree *node, tree name, tree,
3093 : int, bool *no_add_attrs)
3094 : {
3095 3 : if (TREE_CODE (*node) != FUNCTION_DECL)
3096 : {
3097 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
3098 0 : *no_add_attrs = true;
3099 : }
3100 :
3101 3 : return NULL_TREE;
3102 : }
3103 :
3104 : /* If ALLOC_DECL and DEALLOC_DECL are a pair of user-defined functions,
3105 : if they are declared inline issue warnings and return null. Otherwise
3106 : create attribute noinline, install it in ALLOC_DECL, and return it.
3107 : Otherwise return null. */
3108 :
3109 : static tree
3110 364118 : maybe_add_noinline (tree name, tree alloc_decl, tree dealloc_decl,
3111 : bool *no_add_attrs)
3112 : {
3113 364118 : if (fndecl_built_in_p (alloc_decl) || fndecl_built_in_p (dealloc_decl))
3114 : return NULL_TREE;
3115 :
3116 : /* When inlining (or optimization) is enabled and the allocator and
3117 : deallocator are not built-in functions, ignore the attribute on
3118 : functions declared inline since it could lead to false positives
3119 : when inlining one or the other call would wind up calling
3120 : a mismatched allocator or deallocator. */
3121 231505 : if ((optimize && DECL_DECLARED_INLINE_P (alloc_decl))
3122 502166 : || lookup_attribute ("always_inline", DECL_ATTRIBUTES (alloc_decl)))
3123 : {
3124 4 : warning (OPT_Wattributes,
3125 : "%<%E (%E)%> attribute ignored on functions "
3126 4 : "declared %qs", name, DECL_NAME (dealloc_decl), "inline");
3127 4 : *no_add_attrs = true;
3128 4 : return NULL_TREE;
3129 : }
3130 :
3131 231501 : if ((optimize && DECL_DECLARED_INLINE_P (dealloc_decl))
3132 502154 : || lookup_attribute ("always_inline", DECL_ATTRIBUTES (dealloc_decl)))
3133 : {
3134 12 : warning (OPT_Wattributes,
3135 : "%<%E (%E)%> attribute ignored with deallocation "
3136 : "functions declared %qs",
3137 12 : name, DECL_NAME (dealloc_decl), "inline");
3138 12 : inform (DECL_SOURCE_LOCATION (dealloc_decl),
3139 : "deallocation function declared here" );
3140 12 : *no_add_attrs = true;
3141 12 : return NULL_TREE;
3142 : }
3143 :
3144 : /* Disable inlining for non-standard deallocators to avoid false
3145 : positives due to mismatches between the inlined implementation
3146 : of one and not the other pair of functions. */
3147 270649 : tree attr = tree_cons (get_identifier ("noinline"), NULL_TREE, NULL_TREE);
3148 270649 : decl_attributes (&alloc_decl, attr, 0);
3149 270649 : return attr;
3150 : }
3151 :
3152 : /* Handle the "malloc" attribute. */
3153 :
3154 : static tree
3155 3374573 : handle_malloc_attribute (tree *node, tree name, tree args, int flags,
3156 : bool *no_add_attrs)
3157 : {
3158 3374573 : if (flags & ATTR_FLAG_INTERNAL)
3159 : /* Recursive call. */
3160 : return NULL_TREE;
3161 :
3162 : /* The argument-less form (declaring the function malloc-like) is shared
3163 : with libgccjit; the deallocator-argument form below is
3164 : specific to the C family. */
3165 3374573 : if (!args)
3166 3010410 : return handle_malloc_common (node, name, args, flags, no_add_attrs);
3167 :
3168 364163 : tree fndecl = *node;
3169 :
3170 364163 : if (TREE_CODE (*node) != FUNCTION_DECL)
3171 : {
3172 4 : warning (OPT_Wattributes, "%qE attribute ignored; valid only "
3173 : "for functions",
3174 : name);
3175 4 : *no_add_attrs = true;
3176 4 : return NULL_TREE;
3177 : }
3178 :
3179 364159 : tree rettype = TREE_TYPE (TREE_TYPE (*node));
3180 364159 : if (!POINTER_TYPE_P (rettype))
3181 : {
3182 4 : warning (OPT_Wattributes, "%qE attribute ignored on functions "
3183 : "returning %qT; valid only for pointer return types",
3184 : name, rettype);
3185 4 : *no_add_attrs = true;
3186 4 : return NULL_TREE;
3187 : }
3188 :
3189 364155 : if (!args)
3190 : {
3191 : /* Only the form of the attribute with no arguments declares
3192 : a function malloc-like. */
3193 : DECL_IS_MALLOC (*node) = 1;
3194 : return NULL_TREE;
3195 : }
3196 :
3197 364155 : tree dealloc = TREE_VALUE (args);
3198 364155 : if (error_operand_p (dealloc))
3199 : {
3200 : /* If the argument is in error it will have already been diagnosed.
3201 : Avoid issuing redundant errors here. */
3202 1 : *no_add_attrs = true;
3203 1 : return NULL_TREE;
3204 : }
3205 :
3206 364154 : STRIP_NOPS (dealloc);
3207 364154 : if (TREE_CODE (dealloc) == ADDR_EXPR)
3208 : {
3209 : /* In C++ the argument may be wrapped in a cast to disambiguate
3210 : one of a number of overloads (such as operator delete). To
3211 : make things interesting, the cast looks different between
3212 : different C++ versions. Strip it and install the attribute
3213 : with the disambiguated function. */
3214 16 : dealloc = TREE_OPERAND (dealloc, 0);
3215 :
3216 16 : *no_add_attrs = true;
3217 16 : tree attr = tree_cons (NULL_TREE, dealloc, TREE_CHAIN (args));
3218 16 : attr = build_tree_list (name, attr);
3219 16 : return decl_attributes (node, attr, 0);
3220 : }
3221 :
3222 364138 : if (TREE_CODE (dealloc) != FUNCTION_DECL)
3223 : {
3224 7 : if (TREE_CODE (dealloc) == OVERLOAD)
3225 : {
3226 : /* Handle specially the common case of specifying one of a number
3227 : of overloads, such as operator delete. */
3228 4 : error ("%qE attribute argument 1 is ambiguous", name);
3229 4 : inform (input_location,
3230 : "use a cast to the expected type to disambiguate");
3231 4 : *no_add_attrs = true;
3232 4 : return NULL_TREE;
3233 : }
3234 :
3235 3 : error ("%qE attribute argument 1 does not name a function", name);
3236 3 : if (DECL_P (dealloc))
3237 1 : inform (DECL_SOURCE_LOCATION (dealloc),
3238 : "argument references a symbol declared here");
3239 3 : *no_add_attrs = true;
3240 3 : return NULL_TREE;
3241 : }
3242 :
3243 : /* Mentioning the deallocation function qualifies as its use. */
3244 364131 : TREE_USED (dealloc) = 1;
3245 :
3246 364131 : tree fntype = TREE_TYPE (dealloc);
3247 364131 : tree argpos = TREE_CHAIN (args) ? TREE_VALUE (TREE_CHAIN (args)) : NULL_TREE;
3248 364131 : if (!argpos)
3249 : {
3250 5195 : tree argtypes = TYPE_ARG_TYPES (fntype);
3251 5195 : if (!argtypes)
3252 : {
3253 : /* Reject functions without a prototype. */
3254 0 : error ("%qE attribute argument 1 must take a pointer "
3255 : "type as its first argument", name);
3256 0 : inform (DECL_SOURCE_LOCATION (dealloc),
3257 : "referenced symbol declared here");
3258 0 : *no_add_attrs = true;
3259 0 : return NULL_TREE;
3260 : }
3261 :
3262 5195 : tree argtype = TREE_VALUE (argtypes);
3263 5195 : if (TREE_CODE (argtype) != POINTER_TYPE)
3264 : {
3265 : /* Reject functions that don't take a pointer as their first
3266 : argument. */
3267 13 : error ("%qE attribute argument 1 must take a pointer type "
3268 : "as its first argument; have %qT", name, argtype);
3269 13 : inform (DECL_SOURCE_LOCATION (dealloc),
3270 : "referenced symbol declared here");
3271 13 : *no_add_attrs = true;
3272 13 : return NULL_TREE;
3273 : }
3274 :
3275 : /* Disable inlining for non-standard deallocators to avoid false
3276 : positives (or warn if either function is explicitly inline). */
3277 5182 : tree at_noinline =
3278 5182 : maybe_add_noinline (name, fndecl, dealloc, no_add_attrs);
3279 5182 : if (*no_add_attrs)
3280 : return NULL_TREE;
3281 :
3282 : /* Add attribute *dealloc to the deallocator function associating
3283 : it with this one. Ideally, the attribute would reference
3284 : the DECL of the deallocator but since that changes for each
3285 : redeclaration, use DECL_NAME instead. (DECL_ASSEMBLER_NAME
3286 : need not be set at this point and setting it here is too early. */
3287 5174 : tree attrs = build_tree_list (NULL_TREE, DECL_NAME (fndecl));
3288 5174 : attrs = tree_cons (get_identifier ("*dealloc"), attrs, at_noinline);
3289 5174 : decl_attributes (&dealloc, attrs, 0);
3290 5174 : return NULL_TREE;
3291 : }
3292 :
3293 : /* Validate the positional argument. */
3294 358936 : argpos = positional_argument (fntype, name, argpos, POINTER_TYPE);
3295 358936 : if (!argpos)
3296 : {
3297 0 : *no_add_attrs = true;
3298 0 : return NULL_TREE;
3299 : }
3300 :
3301 : /* As above, disable inlining for non-standard deallocators to avoid
3302 : false positives (or warn). */
3303 358936 : tree at_noinline =
3304 358936 : maybe_add_noinline (name, fndecl, dealloc, no_add_attrs);
3305 358936 : if (*no_add_attrs)
3306 : return NULL_TREE;
3307 :
3308 : /* It's valid to declare the same function with multiple instances
3309 : of attribute malloc, each naming the same or different deallocator
3310 : functions, and each referencing either the same or a different
3311 : positional argument. */
3312 358928 : tree attrs = tree_cons (NULL_TREE, argpos, NULL_TREE);
3313 358928 : attrs = tree_cons (NULL_TREE, DECL_NAME (fndecl), attrs);
3314 358928 : attrs = tree_cons (get_identifier ("*dealloc"), attrs, at_noinline);
3315 358928 : decl_attributes (&dealloc, attrs, 0);
3316 358928 : return NULL_TREE;
3317 : }
3318 :
3319 : /* Handle the internal "*dealloc" attribute added for functions declared
3320 : with the one- and two-argument forms of attribute malloc. Add it
3321 : to *NODE unless it's already there with the same arguments. */
3322 :
3323 : static tree
3324 364126 : handle_dealloc_attribute (tree *node, tree name, tree args, int,
3325 : bool *no_add_attrs)
3326 : {
3327 364126 : tree fndecl = *node;
3328 :
3329 364126 : tree attrs = DECL_ATTRIBUTES (fndecl);
3330 364126 : if (!attrs)
3331 : return NULL_TREE;
3332 :
3333 311522 : tree arg = TREE_VALUE (args);
3334 311522 : args = TREE_CHAIN (args);
3335 618227 : tree arg_pos = args ? TREE_VALUE (args) : integer_zero_node;
3336 :
3337 311522 : gcc_checking_assert ((DECL_P (arg)
3338 : && fndecl_built_in_p (arg, BUILT_IN_NORMAL))
3339 : || TREE_CODE (arg) == IDENTIFIER_NODE);
3340 :
3341 311522 : const char* const namestr = IDENTIFIER_POINTER (name);
3342 1159257 : for (tree at = attrs; (at = lookup_attribute (namestr, at));
3343 847735 : at = TREE_CHAIN (at))
3344 : {
3345 848088 : tree alloc = TREE_VALUE (at);
3346 848088 : if (!alloc)
3347 0 : continue;
3348 :
3349 848088 : tree pos = TREE_CHAIN (alloc);
3350 848088 : alloc = TREE_VALUE (alloc);
3351 1685934 : pos = pos ? TREE_VALUE (pos) : integer_zero_node;
3352 848088 : gcc_checking_assert ((DECL_P (alloc)
3353 : && fndecl_built_in_p (alloc, BUILT_IN_NORMAL))
3354 : || TREE_CODE (alloc) == IDENTIFIER_NODE);
3355 :
3356 848088 : if (alloc == arg && tree_int_cst_equal (pos, arg_pos))
3357 : {
3358 : /* The function already has the attribute either without any
3359 : arguments or with the same arguments as the attribute that's
3360 : being added. Return without adding another copy. */
3361 353 : *no_add_attrs = true;
3362 353 : return NULL_TREE;
3363 : }
3364 : }
3365 :
3366 : return NULL_TREE;
3367 : }
3368 :
3369 : /* Handle the "alloc_size (argpos1 [, argpos2])" function type attribute.
3370 : *NODE is the type of the function the attribute is being applied to. */
3371 :
3372 : static tree
3373 2393385 : handle_alloc_size_attribute (tree *node, tree name, tree args,
3374 : int ARG_UNUSED (flags), bool *no_add_attrs)
3375 : {
3376 2393385 : tree fntype = *node;
3377 2393385 : tree rettype = TREE_TYPE (fntype);
3378 2393385 : if (!POINTER_TYPE_P (rettype))
3379 : {
3380 39 : warning (OPT_Wattributes,
3381 : "%qE attribute ignored on a function returning %qT",
3382 : name, rettype);
3383 39 : *no_add_attrs = true;
3384 39 : return NULL_TREE;
3385 : }
3386 :
3387 2393346 : tree newargs[2] = { NULL_TREE, NULL_TREE };
3388 5281937 : for (int i = 1; args; ++i)
3389 : {
3390 2888627 : tree pos = TREE_VALUE (args);
3391 : /* NEXT is null when the attribute includes just one argument.
3392 : That's used to tell positional_argument to avoid mentioning
3393 : the argument number in diagnostics (since there's just one
3394 : mentioning it is unnecessary and coule be confusing). */
3395 2888627 : tree next = TREE_CHAIN (args);
3396 2888627 : if (tree val = positional_argument (fntype, name, pos, INTEGER_TYPE,
3397 2888627 : next || i > 1 ? i : 0))
3398 : {
3399 2888591 : TREE_VALUE (args) = val;
3400 2888591 : newargs[i - 1] = val;
3401 : }
3402 : else
3403 : {
3404 36 : *no_add_attrs = true;
3405 36 : return NULL_TREE;
3406 : }
3407 :
3408 2888591 : args = next;
3409 : }
3410 :
3411 2393310 : if (!validate_attr_args (node, name, newargs))
3412 39 : *no_add_attrs = true;
3413 :
3414 : return NULL_TREE;
3415 : }
3416 :
3417 :
3418 : /* Handle an "alloc_align (argpos)" attribute. */
3419 :
3420 : static tree
3421 104497 : handle_alloc_align_attribute (tree *node, tree name, tree args, int,
3422 : bool *no_add_attrs)
3423 : {
3424 104497 : tree fntype = *node;
3425 104497 : tree rettype = TREE_TYPE (fntype);
3426 104497 : if (!POINTER_TYPE_P (rettype))
3427 : {
3428 11 : warning (OPT_Wattributes,
3429 : "%qE attribute ignored on a function returning %qT",
3430 : name, rettype);
3431 11 : *no_add_attrs = true;
3432 11 : return NULL_TREE;
3433 : }
3434 :
3435 104486 : if (tree val = positional_argument (*node, name, TREE_VALUE (args),
3436 : INTEGER_TYPE))
3437 104454 : if (validate_attr_arg (node, name, val))
3438 : return NULL_TREE;
3439 :
3440 40 : *no_add_attrs = true;
3441 40 : return NULL_TREE;
3442 : }
3443 :
3444 : /* Handle a "assume_aligned" attribute; arguments as in
3445 : struct attribute_spec.handler. */
3446 :
3447 : static tree
3448 58 : handle_assume_aligned_attribute (tree *node, tree name, tree args, int,
3449 : bool *no_add_attrs)
3450 : {
3451 58 : tree decl = *node;
3452 58 : tree rettype = TREE_TYPE (decl);
3453 58 : if (TREE_CODE (rettype) != POINTER_TYPE)
3454 : {
3455 6 : warning (OPT_Wattributes,
3456 : "%qE attribute ignored on a function returning %qT",
3457 : name, rettype);
3458 6 : *no_add_attrs = true;
3459 6 : return NULL_TREE;
3460 : }
3461 :
3462 : /* The alignment specified by the first argument. */
3463 : tree align = NULL_TREE;
3464 :
3465 102 : for (; args; args = TREE_CHAIN (args))
3466 : {
3467 69 : tree val = TREE_VALUE (args);
3468 69 : if (val && TREE_CODE (val) != IDENTIFIER_NODE
3469 69 : && TREE_CODE (val) != FUNCTION_DECL)
3470 65 : val = default_conversion (val);
3471 :
3472 69 : if (!tree_fits_shwi_p (val))
3473 : {
3474 5 : warning (OPT_Wattributes,
3475 : "%qE attribute argument %E is not an integer constant",
3476 : name, val);
3477 5 : *no_add_attrs = true;
3478 5 : return NULL_TREE;
3479 : }
3480 64 : else if (tree_int_cst_sgn (val) < 0)
3481 : {
3482 8 : warning (OPT_Wattributes,
3483 : "%qE attribute argument %E is not positive", name, val);
3484 8 : *no_add_attrs = true;
3485 8 : return NULL_TREE;
3486 : }
3487 :
3488 56 : if (!align)
3489 : {
3490 : /* Validate and save the alignment. */
3491 40 : if (!integer_pow2p (val))
3492 : {
3493 5 : warning (OPT_Wattributes,
3494 : "%qE attribute argument %E is not a power of 2",
3495 : name, val);
3496 5 : *no_add_attrs = true;
3497 5 : return NULL_TREE;
3498 : }
3499 :
3500 : align = val;
3501 : }
3502 16 : else if (tree_int_cst_le (align, val))
3503 : {
3504 : /* The misalignment specified by the second argument
3505 : must be non-negative and less than the alignment. */
3506 2 : warning (OPT_Wattributes,
3507 : "%qE attribute argument %E is not in the range [0, %wu]",
3508 1 : name, val, tree_to_uhwi (align) - 1);
3509 1 : *no_add_attrs = true;
3510 1 : return NULL_TREE;
3511 : }
3512 : }
3513 : return NULL_TREE;
3514 : }
3515 :
3516 : /* Handle the internal-only "arg spec" attribute. */
3517 :
3518 : static tree
3519 439665 : handle_argspec_attribute (tree *, tree, tree args, int, bool *)
3520 : {
3521 : /* Verify the attribute has one or two arguments and their kind. */
3522 879330 : gcc_assert (args && TREE_CODE (TREE_VALUE (args)) == STRING_CST);
3523 439665 : if (TREE_CHAIN (args))
3524 : {
3525 439665 : tree val = TREE_VALUE (TREE_CHAIN (args));
3526 439665 : gcc_assert (!TREE_CHAIN (TREE_CHAIN (args)));
3527 439665 : gcc_assert (TYPE_P (val));
3528 : }
3529 439665 : return NULL_TREE;
3530 : }
3531 :
3532 : /* Handle a "warn_unused" attribute; arguments as in
3533 : struct attribute_spec.handler. */
3534 :
3535 : static tree
3536 3 : handle_warn_unused_attribute (tree *node, tree name,
3537 : tree args ATTRIBUTE_UNUSED,
3538 : int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
3539 : {
3540 3 : if (TYPE_P (*node))
3541 : /* Do nothing else, just set the attribute. We'll get at
3542 : it later with lookup_attribute. */
3543 : ;
3544 : else
3545 : {
3546 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
3547 0 : *no_add_attrs = true;
3548 : }
3549 :
3550 3 : return NULL_TREE;
3551 : }
3552 :
3553 : /* Handle an "omp declare simd" attribute; arguments as in
3554 : struct attribute_spec.handler. */
3555 :
3556 : static tree
3557 1090 : handle_omp_declare_simd_attribute (tree *, tree, tree, int, bool *)
3558 : {
3559 1090 : return NULL_TREE;
3560 : }
3561 :
3562 : /* Handle an "omp declare variant {base,variant}" attribute; arguments as in
3563 : struct attribute_spec.handler. */
3564 :
3565 : static tree
3566 1535 : handle_omp_declare_variant_attribute (tree *, tree, tree, int, bool *)
3567 : {
3568 1535 : return NULL_TREE;
3569 : }
3570 :
3571 : /* Handle a "simd" attribute. */
3572 :
3573 : static tree
3574 9014 : handle_simd_attribute (tree *node, tree name, tree args, int, bool *no_add_attrs)
3575 : {
3576 9014 : if (TREE_CODE (*node) == FUNCTION_DECL)
3577 : {
3578 9014 : tree t = get_identifier ("omp declare simd");
3579 9014 : tree attr = NULL_TREE;
3580 9014 : if (args)
3581 : {
3582 8889 : tree id = TREE_VALUE (args);
3583 :
3584 8889 : if (TREE_CODE (id) != STRING_CST)
3585 : {
3586 0 : error ("attribute %qE argument not a string", name);
3587 0 : *no_add_attrs = true;
3588 0 : return NULL_TREE;
3589 : }
3590 :
3591 8889 : if (strcmp (TREE_STRING_POINTER (id), "notinbranch") == 0)
3592 8881 : attr = build_omp_clause (DECL_SOURCE_LOCATION (*node),
3593 : OMP_CLAUSE_NOTINBRANCH);
3594 8 : else if (strcmp (TREE_STRING_POINTER (id), "inbranch") == 0)
3595 4 : attr = build_omp_clause (DECL_SOURCE_LOCATION (*node),
3596 : OMP_CLAUSE_INBRANCH);
3597 : else
3598 : {
3599 4 : error ("only %<inbranch%> and %<notinbranch%> flags are "
3600 : "allowed for %<__simd__%> attribute");
3601 4 : *no_add_attrs = true;
3602 4 : return NULL_TREE;
3603 : }
3604 : }
3605 :
3606 9010 : DECL_ATTRIBUTES (*node)
3607 18020 : = tree_cons (t, build_tree_list (NULL_TREE, attr),
3608 9010 : DECL_ATTRIBUTES (*node));
3609 : }
3610 : else
3611 : {
3612 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
3613 0 : *no_add_attrs = true;
3614 : }
3615 :
3616 : return NULL_TREE;
3617 : }
3618 :
3619 : /* Handle an "omp declare target" attribute; arguments as in
3620 : struct attribute_spec.handler. */
3621 :
3622 : static tree
3623 2875 : handle_omp_declare_target_attribute (tree *, tree, tree, int, bool *)
3624 : {
3625 2875 : return NULL_TREE;
3626 : }
3627 :
3628 : /* Handle an "non overlapping" attribute; arguments as in
3629 : struct attribute_spec.handler. */
3630 :
3631 : static tree
3632 0 : handle_non_overlapping_attribute (tree *, tree, tree, int, bool *)
3633 : {
3634 0 : return NULL_TREE;
3635 : }
3636 :
3637 : /* Handle a "no_limit_stack" attribute; arguments as in
3638 : struct attribute_spec.handler. */
3639 :
3640 : static tree
3641 0 : handle_no_limit_stack_attribute (tree *node, tree name,
3642 : tree ARG_UNUSED (args),
3643 : int ARG_UNUSED (flags),
3644 : bool *no_add_attrs)
3645 : {
3646 0 : tree decl = *node;
3647 :
3648 0 : if (TREE_CODE (decl) != FUNCTION_DECL)
3649 : {
3650 0 : error_at (DECL_SOURCE_LOCATION (decl),
3651 : "%qE attribute applies only to functions", name);
3652 0 : *no_add_attrs = true;
3653 : }
3654 0 : else if (DECL_INITIAL (decl))
3655 : {
3656 0 : error_at (DECL_SOURCE_LOCATION (decl),
3657 : "cannot set %qE attribute after definition", name);
3658 0 : *no_add_attrs = true;
3659 : }
3660 : else
3661 0 : DECL_NO_LIMIT_STACK (decl) = 1;
3662 :
3663 0 : return NULL_TREE;
3664 : }
3665 :
3666 : /* Handle an "unsequenced" attribute; arguments as in
3667 : struct attribute_spec.handler. */
3668 :
3669 : tree
3670 311 : handle_unsequenced_attribute (tree *node, tree name, tree ARG_UNUSED (args),
3671 : int flags, bool *no_add_attrs)
3672 : {
3673 311 : tree fntype = *node;
3674 779 : for (tree argtype = TYPE_ARG_TYPES (fntype); argtype;
3675 468 : argtype = TREE_CHAIN (argtype))
3676 : /* If any of the arguments have pointer or reference type, just
3677 : add the attribute alone. */
3678 507 : if (POINTER_TYPE_P (TREE_VALUE (argtype)))
3679 : return NULL_TREE;
3680 :
3681 272 : if (VOID_TYPE_P (TREE_TYPE (fntype)))
3682 5 : warning (OPT_Wattributes, "%qE attribute on function type "
3683 : "without pointer arguments returning %<void%>", name);
3684 272 : const char *name2;
3685 272 : if (IDENTIFIER_LENGTH (name) == sizeof ("unsequenced") - 1)
3686 : name2 = "unsequenced noptr";
3687 : else
3688 130 : name2 = "reproducible noptr";
3689 272 : if (!lookup_attribute (name2, TYPE_ATTRIBUTES (fntype)))
3690 : {
3691 252 : *no_add_attrs = true;
3692 252 : gcc_assert ((flags & (int) ATTR_FLAG_TYPE_IN_PLACE) == 0);
3693 252 : tree attr = tree_cons (get_identifier (name2), NULL_TREE,
3694 252 : TYPE_ATTRIBUTES (fntype));
3695 252 : if (!lookup_attribute (IDENTIFIER_POINTER (name),
3696 252 : TYPE_ATTRIBUTES (fntype)))
3697 252 : attr = tree_cons (name, NULL_TREE, attr);
3698 252 : *node = build_type_attribute_variant (*node, attr);
3699 : }
3700 : return NULL_TREE;
3701 : }
3702 :
3703 : /* Handle a "reproducible" attribute; arguments as in
3704 : struct attribute_spec.handler. */
3705 :
3706 : tree
3707 118 : handle_reproducible_attribute (tree *node, tree name, tree args, int flags,
3708 : bool *no_add_attrs)
3709 : {
3710 118 : return handle_unsequenced_attribute (node, name, args, flags, no_add_attrs);
3711 : }
3712 :
3713 : /* Digest an attribute list destined for a transactional memory statement.
3714 : ALLOWED is the set of attributes that are allowed for this statement;
3715 : return the attribute we parsed. Multiple attributes are never allowed. */
3716 :
3717 : int
3718 46 : parse_tm_stmt_attr (tree attrs, int allowed)
3719 : {
3720 46 : tree a_seen = NULL;
3721 46 : int m_seen = 0;
3722 :
3723 93 : for ( ; attrs ; attrs = TREE_CHAIN (attrs))
3724 : {
3725 47 : tree a = get_attribute_name (attrs);
3726 47 : tree ns = get_attribute_namespace (attrs);
3727 47 : int m = 0;
3728 :
3729 47 : if (is_attribute_p ("outer", a)
3730 76 : && (ns == NULL_TREE || strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0))
3731 43 : m = TM_STMT_ATTR_OUTER;
3732 :
3733 43 : if ((m & allowed) == 0)
3734 : {
3735 4 : warning (OPT_Wattributes, "%qE attribute directive ignored", a);
3736 4 : continue;
3737 : }
3738 :
3739 43 : if (m_seen == 0)
3740 : {
3741 : a_seen = a;
3742 : m_seen = m;
3743 : }
3744 1 : else if (m_seen == m)
3745 1 : warning (OPT_Wattributes, "%qE attribute duplicated", a);
3746 : else
3747 : warning (OPT_Wattributes, "%qE attribute follows %qE", a, a_seen);
3748 : }
3749 :
3750 46 : return m_seen;
3751 : }
3752 :
3753 : /* Transform a TM attribute name into a maskable integer and back.
3754 : Note that NULL (i.e. no attribute) is mapped to UNKNOWN, corresponding
3755 : to how the lack of an attribute is treated. */
3756 :
3757 : int
3758 18165975 : tm_attr_to_mask (tree attr)
3759 : {
3760 18165975 : if (attr == NULL)
3761 : return 0;
3762 18165695 : if (is_attribute_p ("transaction_safe", attr))
3763 : return TM_ATTR_SAFE;
3764 18165568 : if (is_attribute_p ("transaction_callable", attr))
3765 : return TM_ATTR_CALLABLE;
3766 18165467 : if (is_attribute_p ("transaction_pure", attr))
3767 : return TM_ATTR_PURE;
3768 18165449 : if (is_attribute_p ("transaction_unsafe", attr))
3769 : return TM_ATTR_IRREVOCABLE;
3770 18165440 : if (is_attribute_p ("transaction_may_cancel_outer", attr))
3771 0 : return TM_ATTR_MAY_CANCEL_OUTER;
3772 : return 0;
3773 : }
3774 :
3775 : tree
3776 41 : tm_mask_to_attr (int mask)
3777 : {
3778 41 : const char *str;
3779 41 : switch (mask)
3780 : {
3781 : case TM_ATTR_SAFE:
3782 : str = "transaction_safe";
3783 : break;
3784 9 : case TM_ATTR_CALLABLE:
3785 9 : str = "transaction_callable";
3786 9 : break;
3787 9 : case TM_ATTR_PURE:
3788 9 : str = "transaction_pure";
3789 9 : break;
3790 0 : case TM_ATTR_IRREVOCABLE:
3791 0 : str = "transaction_unsafe";
3792 0 : break;
3793 0 : case TM_ATTR_MAY_CANCEL_OUTER:
3794 0 : str = "transaction_may_cancel_outer";
3795 0 : break;
3796 0 : default:
3797 0 : gcc_unreachable ();
3798 : }
3799 41 : return get_identifier (str);
3800 : }
3801 :
3802 : /* Return the first TM attribute seen in LIST. */
3803 :
3804 : tree
3805 1375116 : find_tm_attribute (tree list)
3806 : {
3807 1379419 : for (; list ; list = TREE_CHAIN (list))
3808 : {
3809 4451 : tree name = get_attribute_name (list);
3810 4451 : if (tm_attr_to_mask (name) != 0)
3811 : return name;
3812 : }
3813 : return NULL_TREE;
3814 : }
3815 :
3816 : /* Handle the TM attributes; arguments as in struct attribute_spec.handler.
3817 : Here we accept only function types, and verify that none of the other
3818 : function TM attributes are also applied. */
3819 : /* ??? We need to accept class types for C++, but not C. This greatly
3820 : complicates this function, since we can no longer rely on the extra
3821 : processing given by function_type_required. */
3822 :
3823 : static tree
3824 1368428 : handle_tm_attribute (tree *node, tree name, tree args,
3825 : int flags, bool *no_add_attrs)
3826 : {
3827 : /* Only one path adds the attribute; others don't. */
3828 1368428 : *no_add_attrs = true;
3829 :
3830 1368428 : switch (TREE_CODE (*node))
3831 : {
3832 16 : case RECORD_TYPE:
3833 16 : case UNION_TYPE:
3834 : /* Only tm_callable and tm_safe apply to classes. */
3835 16 : if (tm_attr_to_mask (name) & ~(TM_ATTR_SAFE | TM_ATTR_CALLABLE))
3836 0 : goto ignored;
3837 : /* FALLTHRU */
3838 :
3839 1368329 : case FUNCTION_TYPE:
3840 1368329 : case METHOD_TYPE:
3841 1368329 : {
3842 1368329 : tree old_name = find_tm_attribute (TYPE_ATTRIBUTES (*node));
3843 1368329 : if (old_name == name)
3844 : ;
3845 1368329 : else if (old_name != NULL_TREE)
3846 12 : error ("type was previously declared %qE", old_name);
3847 : else
3848 1368317 : *no_add_attrs = false;
3849 : }
3850 : break;
3851 :
3852 29 : case FUNCTION_DECL:
3853 29 : {
3854 : /* transaction_safe_dynamic goes on the FUNCTION_DECL, but we also
3855 : want to set transaction_safe on the type. */
3856 29 : gcc_assert (is_attribute_p ("transaction_safe_dynamic", name));
3857 29 : if (!TYPE_P (DECL_CONTEXT (*node)))
3858 1 : error_at (DECL_SOURCE_LOCATION (*node),
3859 : "%<transaction_safe_dynamic%> may only be specified for "
3860 : "a virtual function");
3861 29 : *no_add_attrs = false;
3862 29 : decl_attributes (&TREE_TYPE (*node),
3863 : build_tree_list (get_identifier ("transaction_safe"),
3864 : NULL_TREE),
3865 : 0);
3866 29 : break;
3867 : }
3868 :
3869 62 : case POINTER_TYPE:
3870 62 : {
3871 62 : enum tree_code subcode = TREE_CODE (TREE_TYPE (*node));
3872 62 : if (subcode == FUNCTION_TYPE || subcode == METHOD_TYPE)
3873 : {
3874 62 : tree fn_tmp = TREE_TYPE (*node);
3875 62 : decl_attributes (&fn_tmp, tree_cons (name, args, NULL), 0);
3876 62 : *node = build_pointer_type (fn_tmp);
3877 62 : break;
3878 : }
3879 : }
3880 : /* FALLTHRU */
3881 :
3882 8 : default:
3883 : /* If a function is next, pass it on to be tried next. */
3884 8 : if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
3885 0 : return tree_cons (name, args, NULL);
3886 :
3887 8 : ignored:
3888 8 : warning (OPT_Wattributes, "%qE attribute ignored", name);
3889 8 : break;
3890 : }
3891 :
3892 : return NULL_TREE;
3893 : }
3894 :
3895 : /* Handle the TM_WRAP attribute; arguments as in
3896 : struct attribute_spec.handler. */
3897 :
3898 : static tree
3899 36 : handle_tm_wrap_attribute (tree *node, tree name, tree args,
3900 : int ARG_UNUSED (flags), bool *no_add_attrs)
3901 : {
3902 36 : tree decl = *node;
3903 :
3904 : /* We don't need the attribute even on success, since we
3905 : record the entry in an external table. */
3906 36 : *no_add_attrs = true;
3907 :
3908 36 : if (TREE_CODE (decl) != FUNCTION_DECL)
3909 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
3910 : else
3911 : {
3912 36 : tree wrap_decl = TREE_VALUE (args);
3913 36 : if (error_operand_p (wrap_decl))
3914 : ;
3915 32 : else if (TREE_CODE (wrap_decl) != IDENTIFIER_NODE
3916 : && !VAR_OR_FUNCTION_DECL_P (wrap_decl))
3917 8 : error ("%qE argument not an identifier", name);
3918 : else
3919 : {
3920 24 : if (TREE_CODE (wrap_decl) == IDENTIFIER_NODE)
3921 0 : wrap_decl = lookup_name (wrap_decl);
3922 24 : if (wrap_decl && TREE_CODE (wrap_decl) == FUNCTION_DECL)
3923 : {
3924 20 : if (lang_hooks.types_compatible_p (TREE_TYPE (decl),
3925 20 : TREE_TYPE (wrap_decl)))
3926 12 : record_tm_replacement (wrap_decl, decl);
3927 : else
3928 8 : error ("%qD is not compatible with %qD", wrap_decl, decl);
3929 : }
3930 : else
3931 4 : error ("%qE argument is not a function", name);
3932 : }
3933 : }
3934 :
3935 36 : return NULL_TREE;
3936 : }
3937 :
3938 : /* Handle a "callback_only" attribute; arguments as in
3939 : struct attribute_spec.handler. */
3940 : tree
3941 100942 : handle_callback_only_attribute (tree *node, tree name, tree args,
3942 : int ARG_UNUSED (flags), bool *no_add_attrs)
3943 : {
3944 100942 : tree decl = *node;
3945 100942 : if (TREE_CODE (decl) != FUNCTION_DECL)
3946 : {
3947 1 : warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
3948 : "%qE attribute can only be used on functions", name);
3949 1 : *no_add_attrs = true;
3950 1 : return NULL_TREE;
3951 : }
3952 :
3953 100941 : tree decl_type = TREE_TYPE (decl);
3954 100941 : if (!prototype_p (decl_type))
3955 : {
3956 2 : warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
3957 : "%qE attribute requires a prototype", name);
3958 2 : *no_add_attrs = true;
3959 2 : return NULL_TREE;
3960 : }
3961 100939 : else if (stdarg_p (decl_type))
3962 : {
3963 1 : warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
3964 : "%qE attribute cannot be used on variadic functions", name);
3965 1 : *no_add_attrs = true;
3966 1 : return NULL_TREE;
3967 : }
3968 :
3969 100938 : tree val = positional_argument (decl, name, TREE_VALUE (args), POINTER_TYPE,
3970 : 1, POSARG_ZERO);
3971 100938 : if (!val)
3972 : {
3973 7 : *no_add_attrs = true;
3974 7 : return NULL_TREE;
3975 : }
3976 100931 : TREE_VALUE (args) = val;
3977 :
3978 : /* We have to use the function type for validation, as
3979 : DECL_ARGUMENTS returns NULL at this point. */
3980 100931 : int callback_fn_idx = TREE_INT_CST_LOW (val);
3981 100931 : tree decl_type_args = TYPE_ARG_TYPES (decl_type);
3982 :
3983 100931 : if (callback_fn_idx == CB_UNKNOWN_POS)
3984 : {
3985 1 : warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
3986 : "callback function position cannot be marked as unknown");
3987 1 : *no_add_attrs = true;
3988 1 : return NULL_TREE;
3989 : }
3990 :
3991 100930 : --callback_fn_idx;
3992 :
3993 : /* Search for the type of the callback function in parameters of the original
3994 : function. We know it's there because it's been validated by
3995 : positional_argument. */
3996 100930 : tree cfn = chain_index (callback_fn_idx, decl_type_args);
3997 100930 : gcc_checking_assert (cfn != NULL_TREE);
3998 100930 : cfn = TREE_VALUE (cfn);
3999 100930 : tree cfn_pointee_type = TREE_TYPE (cfn);
4000 100930 : if (TREE_CODE (cfn) != POINTER_TYPE
4001 100930 : || TREE_CODE (cfn_pointee_type) != FUNCTION_TYPE)
4002 : {
4003 0 : warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
4004 : "argument no. %d is not an address of a function",
4005 : callback_fn_idx + 1);
4006 0 : *no_add_attrs = true;
4007 0 : return NULL_TREE;
4008 : }
4009 :
4010 100930 : tree type_args = TYPE_ARG_TYPES (cfn_pointee_type);
4011 :
4012 100930 : if (!prototype_p (cfn_pointee_type))
4013 : {
4014 1 : warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
4015 : "%qE callback function must have a prototype", name);
4016 1 : *no_add_attrs = true;
4017 1 : return NULL_TREE;
4018 : }
4019 100929 : else if (stdarg_p (cfn_pointee_type))
4020 : {
4021 1 : warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
4022 : "%qE callback function cannot be variadic", name);
4023 1 : *no_add_attrs = true;
4024 1 : return NULL_TREE;
4025 : }
4026 :
4027 : /* Compare the length of the list of argument indices
4028 : and the real number of parameters the callback takes. */
4029 100928 : unsigned cfn_nargs = list_length (TREE_CHAIN (args));
4030 100928 : unsigned type_nargs = list_length (type_args) - 1;
4031 100928 : if (cfn_nargs != type_nargs)
4032 : {
4033 3 : warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
4034 : "argument number mismatch, %d expected, got %d", type_nargs,
4035 : cfn_nargs);
4036 3 : *no_add_attrs = true;
4037 3 : return NULL_TREE;
4038 : }
4039 :
4040 100925 : unsigned curr = 0;
4041 100925 : tree it, cfn_it;
4042 : /* Validate type compatibility of the arguments passed
4043 : from caller function to callback. "it" is used to step
4044 : through the parameters of the caller, "cfn_it" is
4045 : stepping through the parameters of the callback. */
4046 201851 : for (it = type_args, cfn_it = TREE_CHAIN (args); curr < type_nargs;
4047 100926 : it = TREE_CHAIN (it), cfn_it = TREE_CHAIN (cfn_it), curr++)
4048 : {
4049 100930 : if (TREE_CODE (TREE_VALUE (cfn_it)) != INTEGER_CST)
4050 : {
4051 1 : warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
4052 : "argument no. %d is not an integer constant", curr + 1);
4053 1 : *no_add_attrs = true;
4054 1 : continue;
4055 : }
4056 :
4057 100929 : tree expected_type = TREE_VALUE (it);
4058 201858 : tree arg_val = positional_argument (decl, name, TREE_VALUE (cfn_it),
4059 100929 : TREE_CODE (expected_type), curr + 1,
4060 : POSARG_ZERO);
4061 100929 : if (!arg_val)
4062 : {
4063 4 : *no_add_attrs = true;
4064 4 : return NULL_TREE;
4065 : }
4066 :
4067 100925 : TREE_VALUE (cfn_it) = arg_val;
4068 100925 : int arg_idx = TREE_INT_CST_LOW (TREE_VALUE (cfn_it));
4069 :
4070 : /* No need to check for type compatibility,
4071 : if we don't know what we are passing. */
4072 100925 : if (arg_idx == CB_UNKNOWN_POS)
4073 2 : continue;
4074 :
4075 100923 : arg_idx -= 1;
4076 100923 : tree arg_type = chain_index (arg_idx, decl_type_args);
4077 100923 : gcc_checking_assert (arg_type != NULL_TREE);
4078 100923 : arg_type = TREE_VALUE (arg_type);
4079 : /* Check the type of the value we are about to pass ("arg_type")
4080 : for compatibility with the actual type the callback function
4081 : expects ("expected_type"). */
4082 100923 : if (!types_compatible_p (expected_type, arg_type))
4083 : {
4084 0 : warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
4085 : "argument type at index %d is not compatible with "
4086 : "callback argument type at index %d",
4087 : arg_idx + 1, curr + 1);
4088 0 : *no_add_attrs = true;
4089 0 : continue;
4090 : }
4091 : }
4092 :
4093 : /* Check that the decl does not already have a callback attribute describing
4094 : the same argument. */
4095 100921 : it = lookup_attribute ("callback_only", DECL_ATTRIBUTES (decl));
4096 201844 : for (; it; it = lookup_attribute ("callback_only", TREE_CHAIN (it)))
4097 3 : if (callback_get_fn_index (it) == callback_fn_idx)
4098 : {
4099 1 : warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
4100 : "function declaration has multiple callback attributes "
4101 : "describing argument no. %d",
4102 : callback_fn_idx + 1);
4103 1 : *no_add_attrs = true;
4104 1 : break;
4105 : }
4106 :
4107 : return NULL_TREE;
4108 : }
4109 :
4110 : /* Handle a "deprecated" attribute; arguments as in
4111 : struct attribute_spec.handler. */
4112 :
4113 : tree
4114 1421201 : handle_deprecated_attribute (tree *node, tree name,
4115 : tree args, int flags,
4116 : bool *no_add_attrs)
4117 : {
4118 1421201 : tree type = NULL_TREE;
4119 1421201 : int warn = 0;
4120 1421201 : tree what = NULL_TREE;
4121 :
4122 1421201 : if (!args)
4123 642793 : *no_add_attrs = true;
4124 778408 : else if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
4125 : {
4126 7 : error ("deprecated message is not a string");
4127 7 : *no_add_attrs = true;
4128 : }
4129 :
4130 1421201 : if (DECL_P (*node))
4131 : {
4132 1033147 : tree decl = *node;
4133 1033147 : type = TREE_TYPE (decl);
4134 :
4135 1033147 : if (TREE_CODE (decl) == TYPE_DECL
4136 1033147 : || TREE_CODE (decl) == PARM_DECL
4137 : || VAR_OR_FUNCTION_DECL_P (decl)
4138 : || TREE_CODE (decl) == FIELD_DECL
4139 : || TREE_CODE (decl) == CONST_DECL
4140 29 : || objc_method_decl (TREE_CODE (decl))
4141 29 : || TREE_CODE (decl) == CONCEPT_DECL)
4142 1033132 : TREE_DEPRECATED (decl) = 1;
4143 15 : else if (TREE_CODE (decl) == LABEL_DECL)
4144 : {
4145 15 : pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
4146 : name);
4147 15 : *no_add_attrs = true;
4148 15 : return NULL_TREE;
4149 : }
4150 : else
4151 : warn = 1;
4152 : }
4153 388054 : else if (TYPE_P (*node))
4154 : {
4155 388054 : if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
4156 10582 : *node = build_variant_type_copy (*node);
4157 388054 : TREE_DEPRECATED (*node) = 1;
4158 388054 : type = *node;
4159 : }
4160 : else
4161 : warn = 1;
4162 :
4163 1421186 : if (warn)
4164 : {
4165 0 : *no_add_attrs = true;
4166 0 : if (type && TYPE_NAME (type))
4167 : {
4168 0 : if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
4169 0 : what = TYPE_NAME (type);
4170 0 : else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
4171 0 : && DECL_NAME (TYPE_NAME (type)))
4172 0 : what = DECL_NAME (TYPE_NAME (type));
4173 : }
4174 0 : if (what)
4175 0 : warning (OPT_Wattributes, "%qE attribute ignored for %qE", name, what);
4176 : else
4177 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
4178 : }
4179 :
4180 : return NULL_TREE;
4181 : }
4182 :
4183 : /* Handle a "unavailable" attribute; arguments as in
4184 : struct attribute_spec.handler. */
4185 :
4186 : static tree
4187 256 : handle_unavailable_attribute (tree *node, tree name,
4188 : tree args, int flags,
4189 : bool *no_add_attrs)
4190 : {
4191 256 : tree type = NULL_TREE;
4192 256 : int warn = 0;
4193 256 : tree what = NULL_TREE;
4194 :
4195 256 : if (!args)
4196 161 : *no_add_attrs = true;
4197 95 : else if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
4198 : {
4199 0 : error ("the message attached to %<unavailable%> is not a string");
4200 0 : *no_add_attrs = true;
4201 : }
4202 :
4203 256 : if (DECL_P (*node))
4204 : {
4205 217 : tree decl = *node;
4206 217 : type = TREE_TYPE (decl);
4207 :
4208 217 : if (TREE_CODE (decl) == TYPE_DECL
4209 217 : || TREE_CODE (decl) == PARM_DECL
4210 : || VAR_OR_FUNCTION_DECL_P (decl)
4211 : || TREE_CODE (decl) == FIELD_DECL
4212 : || TREE_CODE (decl) == CONST_DECL
4213 0 : || objc_method_decl (TREE_CODE (decl)))
4214 217 : TREE_UNAVAILABLE (decl) = 1;
4215 : else
4216 : warn = 1;
4217 : }
4218 39 : else if (TYPE_P (*node))
4219 : {
4220 39 : if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
4221 0 : *node = build_variant_type_copy (*node);
4222 39 : TREE_UNAVAILABLE (*node) = 1;
4223 39 : type = *node;
4224 : }
4225 : else
4226 : warn = 1;
4227 :
4228 256 : if (warn)
4229 : {
4230 0 : *no_add_attrs = true;
4231 0 : if (type && TYPE_NAME (type))
4232 : {
4233 0 : if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
4234 0 : what = TYPE_NAME (*node);
4235 0 : else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
4236 0 : && DECL_NAME (TYPE_NAME (type)))
4237 0 : what = DECL_NAME (TYPE_NAME (type));
4238 : }
4239 0 : if (what)
4240 0 : warning (OPT_Wattributes, "%qE attribute ignored for %qE", name, what);
4241 : else
4242 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
4243 : }
4244 :
4245 256 : return NULL_TREE;
4246 : }
4247 :
4248 : /* Return the "base" type from TYPE that is suitable to apply attribute
4249 : vector_size to by stripping arrays, function types, etc. */
4250 : static tree
4251 529468 : type_for_vector_size (tree type)
4252 : {
4253 : /* We need to provide for vector pointers, vector arrays, and
4254 : functions returning vectors. For example:
4255 :
4256 : __attribute__((vector_size(16))) short *foo;
4257 :
4258 : In this case, the mode is SI, but the type being modified is
4259 : HI, so we need to look further. */
4260 :
4261 529468 : while (POINTER_TYPE_P (type)
4262 : || TREE_CODE (type) == FUNCTION_TYPE
4263 : || TREE_CODE (type) == METHOD_TYPE
4264 : || TREE_CODE (type) == ARRAY_TYPE
4265 529950 : || TREE_CODE (type) == OFFSET_TYPE)
4266 482 : type = TREE_TYPE (type);
4267 :
4268 529468 : return type;
4269 : }
4270 :
4271 : /* Given TYPE, return the base type to which the vector_size attribute
4272 : ATNAME with ARGS, when non-null, can be applied, if one exists.
4273 : On success and when both ARGS and PTRNUNITS are non-null, set
4274 : *PTRNUNINTS to the number of vector units. When PTRNUNITS is not
4275 : null, issue a warning when the attribute argument is not constant
4276 : and an error if there is no such type. Otherwise issue a warning
4277 : in the latter case and return null. */
4278 :
4279 : static tree
4280 529466 : type_valid_for_vector_size (tree type, tree atname, tree args,
4281 : unsigned HOST_WIDE_INT *ptrnunits)
4282 : {
4283 529466 : bool hardbool_p = c_hardbool_type_attr (type);
4284 529466 : bool error_p = ptrnunits != NULL || hardbool_p;
4285 :
4286 : /* Get the mode of the type being modified. */
4287 529466 : machine_mode orig_mode = TYPE_MODE (type);
4288 :
4289 529466 : if ((!INTEGRAL_TYPE_P (type)
4290 529466 : && !SCALAR_FLOAT_TYPE_P (type)
4291 1 : && !FIXED_POINT_TYPE_P (type))
4292 529465 : || (!SCALAR_FLOAT_MODE_P (orig_mode)
4293 340224 : && GET_MODE_CLASS (orig_mode) != MODE_INT
4294 2 : && !ALL_SCALAR_FIXED_POINT_MODE_P (orig_mode))
4295 529463 : || !tree_fits_uhwi_p (TYPE_SIZE_UNIT (type))
4296 529463 : || TREE_CODE (type) == BOOLEAN_TYPE
4297 529456 : || hardbool_p
4298 1058921 : || BITINT_TYPE_P (type))
4299 : {
4300 13 : if (error_p)
4301 13 : error ("invalid vector type for attribute %qE", atname);
4302 : else
4303 0 : warning (OPT_Wattributes, "invalid vector type for attribute %qE",
4304 : atname);
4305 : return NULL_TREE;
4306 : }
4307 :
4308 : /* When no argument has been provided this is just a request to validate
4309 : the type above. Return TYPE to indicate success. */
4310 529453 : if (!args)
4311 : return type;
4312 :
4313 529453 : tree size = TREE_VALUE (args);
4314 : /* Erroneous arguments have already been diagnosed. */
4315 529453 : if (size == error_mark_node)
4316 : return NULL_TREE;
4317 :
4318 529449 : if (size && TREE_CODE (size) != IDENTIFIER_NODE
4319 529449 : && TREE_CODE (size) != FUNCTION_DECL)
4320 529441 : size = default_conversion (size);
4321 :
4322 529449 : if (TREE_CODE (size) != INTEGER_CST)
4323 : {
4324 8 : if (error_p)
4325 8 : error ("%qE attribute argument value %qE is not an integer constant",
4326 : atname, size);
4327 : else
4328 0 : warning (OPT_Wattributes,
4329 : "%qE attribute argument value %qE is not an integer constant",
4330 : atname, size);
4331 : return NULL_TREE;
4332 : }
4333 :
4334 529441 : if (!TYPE_UNSIGNED (TREE_TYPE (size))
4335 529441 : && tree_int_cst_sgn (size) < 0)
4336 : {
4337 1 : if (error_p)
4338 1 : error ("%qE attribute argument value %qE is negative",
4339 : atname, size);
4340 : else
4341 0 : warning (OPT_Wattributes,
4342 : "%qE attribute argument value %qE is negative",
4343 : atname, size);
4344 : return NULL_TREE;
4345 : }
4346 :
4347 : /* The attribute argument value is constrained by the maximum bit
4348 : alignment representable in unsigned int on the host. */
4349 529440 : unsigned HOST_WIDE_INT vecsize;
4350 529440 : unsigned HOST_WIDE_INT maxsize = tree_to_uhwi (max_object_size ());
4351 529440 : if (!tree_fits_uhwi_p (size)
4352 529440 : || (vecsize = tree_to_uhwi (size)) > maxsize)
4353 : {
4354 2 : if (error_p)
4355 2 : error ("%qE attribute argument value %qE exceeds %wu",
4356 : atname, size, maxsize);
4357 : else
4358 0 : warning (OPT_Wattributes,
4359 : "%qE attribute argument value %qE exceeds %wu",
4360 : atname, size, maxsize);
4361 : return NULL_TREE;
4362 : }
4363 :
4364 529438 : if (vecsize % tree_to_uhwi (TYPE_SIZE_UNIT (type)))
4365 : {
4366 54 : if (error_p)
4367 2 : error ("vector size not an integral multiple of component size");
4368 : return NULL_TREE;
4369 : }
4370 :
4371 529384 : if (vecsize == 0)
4372 : {
4373 1 : error ("zero vector size");
4374 1 : return NULL;
4375 : }
4376 :
4377 : /* Calculate how many units fit in the vector. */
4378 529383 : unsigned HOST_WIDE_INT nunits = vecsize / tree_to_uhwi (TYPE_SIZE_UNIT (type));
4379 529383 : if (nunits & (nunits - 1))
4380 : {
4381 0 : if (error_p)
4382 0 : error ("number of vector components %wu not a power of two", nunits);
4383 : else
4384 0 : warning (OPT_Wattributes,
4385 : "number of vector components %wu not a power of two", nunits);
4386 : return NULL_TREE;
4387 : }
4388 :
4389 529383 : if (nunits >= (unsigned HOST_WIDE_INT)INT_MAX)
4390 : {
4391 1 : if (error_p)
4392 1 : error ("number of vector components %wu exceeds %d",
4393 : nunits, INT_MAX - 1);
4394 : else
4395 0 : warning (OPT_Wattributes,
4396 : "number of vector components %wu exceeds %d",
4397 : nunits, INT_MAX - 1);
4398 : return NULL_TREE;
4399 : }
4400 :
4401 529382 : if (ptrnunits)
4402 529258 : *ptrnunits = nunits;
4403 :
4404 : return type;
4405 : }
4406 :
4407 : /* Handle a "vector_size" attribute; arguments as in
4408 : struct attribute_spec.handler. */
4409 :
4410 : static tree
4411 529290 : handle_vector_size_attribute (tree *node, tree name, tree args,
4412 : int ARG_UNUSED (flags),
4413 : bool *no_add_attrs)
4414 : {
4415 529290 : *no_add_attrs = true;
4416 :
4417 : /* Determine the "base" type to apply the attribute to. */
4418 529290 : tree type = type_for_vector_size (*node);
4419 :
4420 : /* Get the vector size (in bytes) and let the function compute
4421 : the number of vector units. */
4422 529290 : unsigned HOST_WIDE_INT nunits;
4423 529290 : type = type_valid_for_vector_size (type, name, args, &nunits);
4424 529290 : if (!type)
4425 : return NULL_TREE;
4426 :
4427 529258 : gcc_checking_assert (args != NULL);
4428 :
4429 529258 : tree new_type = build_vector_type (type, nunits);
4430 :
4431 : /* Build back pointers if needed. */
4432 529258 : *node = lang_hooks.types.reconstruct_complex_type (*node, new_type);
4433 :
4434 529258 : return NULL_TREE;
4435 : }
4436 :
4437 : /* Handle a "vector_mask" attribute; arguments as in
4438 : struct attribute_spec.handler. */
4439 :
4440 : static tree
4441 2 : handle_vector_mask_attribute (tree *node, tree name, tree,
4442 : int ARG_UNUSED (flags),
4443 : bool *no_add_attrs)
4444 : {
4445 2 : *no_add_attrs = true;
4446 2 : if (!flag_gimple)
4447 : {
4448 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
4449 0 : return NULL_TREE;
4450 : }
4451 :
4452 : /* Determine the "base" type to apply the attribute to. */
4453 2 : tree type = type_for_vector_size (*node);
4454 2 : if (!VECTOR_TYPE_P (type) || VECTOR_BOOLEAN_TYPE_P (type))
4455 : {
4456 0 : warning (OPT_Wattributes, "%qE attribute only supported on "
4457 : "non-mask vector types", name);
4458 0 : return NULL_TREE;
4459 : }
4460 :
4461 2 : tree new_type = truth_type_for (type);
4462 :
4463 : /* Build back pointers if needed. */
4464 2 : *node = lang_hooks.types.reconstruct_complex_type (*node, new_type);
4465 :
4466 2 : return NULL_TREE;
4467 : }
4468 :
4469 : /* Handle the "nonnull" attribute. */
4470 :
4471 : static tree
4472 46792226 : handle_nonnull_attribute (tree *node, tree name,
4473 : tree args, int ARG_UNUSED (flags),
4474 : bool *no_add_attrs)
4475 : {
4476 46792226 : tree type = *node;
4477 :
4478 : /* If no arguments are specified, all pointer arguments should be
4479 : non-null. Verify a full prototype is given so that the arguments
4480 : will have the correct types when we actually check them later.
4481 : Avoid diagnosing type-generic built-ins since those have no
4482 : prototype. */
4483 46792226 : if (!args)
4484 : {
4485 25470656 : if (!prototype_p (type)
4486 25470656 : && (!TYPE_ATTRIBUTES (type)
4487 858068 : || !lookup_attribute ("type generic", TYPE_ATTRIBUTES (type))))
4488 : {
4489 1 : error ("%qE attribute without arguments on a non-prototype",
4490 : name);
4491 1 : *no_add_attrs = true;
4492 : }
4493 : return NULL_TREE;
4494 : }
4495 :
4496 49171062 : for (int i = 1; args; ++i)
4497 : {
4498 27849518 : tree pos = TREE_VALUE (args);
4499 : /* NEXT is null when the attribute includes just one argument.
4500 : That's used to tell positional_argument to avoid mentioning
4501 : the argument number in diagnostics (since there's just one
4502 : mentioning it is unnecessary and could be confusing). */
4503 27849518 : tree next = TREE_CHAIN (args);
4504 27849518 : if (tree val = positional_argument (type, name, pos, POINTER_TYPE,
4505 27849518 : next || i > 1 ? i : 0))
4506 27849492 : TREE_VALUE (args) = val;
4507 : else
4508 : {
4509 26 : *no_add_attrs = true;
4510 26 : break;
4511 : }
4512 27849492 : args = next;
4513 : }
4514 :
4515 : return NULL_TREE;
4516 : }
4517 :
4518 : /* Handle the "nonnull_if_nonzero" attribute. */
4519 :
4520 : static tree
4521 15557144 : handle_nonnull_if_nonzero_attribute (tree *node, tree name,
4522 : tree args, int ARG_UNUSED (flags),
4523 : bool *no_add_attrs)
4524 : {
4525 15557144 : tree type = *node;
4526 15557144 : tree pos = TREE_VALUE (args);
4527 15557144 : tree pos2 = TREE_VALUE (TREE_CHAIN (args));
4528 15557144 : tree chain2 = TREE_CHAIN (TREE_CHAIN (args));
4529 15557144 : tree pos3 = NULL_TREE;
4530 15557144 : if (chain2)
4531 796036 : pos3 = TREE_VALUE (chain2);
4532 15557144 : tree val = positional_argument (type, name, pos, POINTER_TYPE, 1);
4533 15557144 : tree val2 = positional_argument (type, name, pos2, INTEGER_TYPE, 2);
4534 15557144 : tree val3 = NULL_TREE;
4535 15557144 : if (chain2)
4536 796036 : val3 = positional_argument (type, name, pos3, INTEGER_TYPE, 3);
4537 15557144 : if (val && val2 && (!chain2 || val3))
4538 : {
4539 15557131 : TREE_VALUE (args) = val;
4540 15557131 : TREE_VALUE (TREE_CHAIN (args)) = val2;
4541 15557131 : if (chain2)
4542 796031 : TREE_VALUE (chain2) = val3;
4543 : }
4544 : else
4545 13 : *no_add_attrs = true;
4546 :
4547 15557144 : return NULL_TREE;
4548 : }
4549 :
4550 : /* Handle the "fd_arg", "fd_arg_read" and "fd_arg_write" attributes */
4551 :
4552 : static tree
4553 32 : handle_fd_arg_attribute (tree *node, tree name, tree args,
4554 : int ARG_UNUSED (flags), bool *no_add_attrs)
4555 : {
4556 32 : tree type = *node;
4557 32 : if (!args)
4558 : {
4559 0 : if (!prototype_p (type))
4560 : {
4561 0 : error ("%qE attribute without arguments on a non-prototype", name);
4562 0 : *no_add_attrs = true;
4563 : }
4564 : return NULL_TREE;
4565 : }
4566 :
4567 32 : if (positional_argument (*node, name, TREE_VALUE (args), INTEGER_TYPE))
4568 : return NULL_TREE;
4569 :
4570 20 : *no_add_attrs = true;
4571 20 : return NULL_TREE;
4572 : }
4573 :
4574 : /* Handle the "flag_enum" attribute. */
4575 :
4576 : static tree
4577 44437 : handle_flag_enum_attribute (tree *node, tree ARG_UNUSED (name),
4578 : tree ARG_UNUSED (args), int ARG_UNUSED (flags),
4579 : bool *no_add_attrs)
4580 : {
4581 44437 : if (TREE_CODE (*node) != ENUMERAL_TYPE)
4582 : {
4583 0 : warning (OPT_Wattributes, "%qE attribute ignored on non-enum", name);
4584 0 : *no_add_attrs = true;
4585 : }
4586 :
4587 44437 : return NULL_TREE;
4588 : }
4589 :
4590 : /* Handle the "null_terminated_string_arg" attribute. */
4591 :
4592 : static tree
4593 64 : handle_null_terminated_string_arg_attribute (tree *node, tree name, tree args,
4594 : int ARG_UNUSED (flags),
4595 : bool *no_add_attrs)
4596 : {
4597 64 : if (positional_argument (*node, name, TREE_VALUE (args), POINTER_TYPE))
4598 : return NULL_TREE;
4599 :
4600 20 : *no_add_attrs = true;
4601 20 : return NULL_TREE;
4602 : }
4603 :
4604 : /* Common argument checking for btf_type_tag and btf_decl_tag.
4605 : Return true if the ARGS are valid, otherwise emit an error and
4606 : return false. */
4607 :
4608 : static bool
4609 113 : btf_tag_args_ok (tree name, tree args)
4610 : {
4611 113 : if (!args) /* Correct number of args (1) is checked for us. */
4612 : return false;
4613 113 : else if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
4614 : {
4615 2 : error ("%qE attribute requires a string argument", name);
4616 2 : return false;
4617 : }
4618 :
4619 : /* Only narrow character strings are accepted. */
4620 111 : tree argtype = TREE_TYPE (TREE_TYPE (TREE_VALUE (args)));
4621 111 : if (!(argtype == char_type_node
4622 6 : || argtype == char8_type_node
4623 6 : || argtype == signed_char_type_node
4624 6 : || argtype == unsigned_char_type_node))
4625 : {
4626 6 : error ("unsupported wide string type argument in %qE attribute", name);
4627 6 : return false;
4628 : }
4629 :
4630 : return true;
4631 : }
4632 :
4633 : /* Handle the "btf_decl_tag" attribute. */
4634 :
4635 : static tree
4636 52 : handle_btf_decl_tag_attribute (tree * ARG_UNUSED (node), tree name, tree args,
4637 : int ARG_UNUSED (flags), bool *no_add_attrs)
4638 : {
4639 52 : if (!btf_tag_args_ok (name, args))
4640 4 : *no_add_attrs = true;
4641 :
4642 52 : return NULL_TREE;
4643 : }
4644 :
4645 : /* Handle the "btf_type_tag" attribute. */
4646 :
4647 : static tree
4648 61 : handle_btf_type_tag_attribute (tree *node, tree name, tree args,
4649 : int flags, bool *no_add_attrs)
4650 : {
4651 61 : if (!btf_tag_args_ok (name, args))
4652 : {
4653 4 : *no_add_attrs = true;
4654 4 : return NULL_TREE;
4655 : }
4656 :
4657 57 : if (TREE_CODE (*node) == FUNCTION_TYPE || TREE_CODE (*node) == METHOD_TYPE)
4658 : {
4659 3 : warning (OPT_Wattributes,
4660 : "%qE attribute does not apply to functions", name);
4661 3 : *no_add_attrs = true;
4662 3 : return NULL_TREE;
4663 : }
4664 :
4665 : /* Ensure a variant type is always created to hold the type_tag,
4666 : unless ATTR_FLAG_IN_PLACE is set. Same logic as in
4667 : common_handle_aligned_attribute. */
4668 54 : tree decl = NULL_TREE;
4669 54 : tree *type = NULL;
4670 54 : bool is_type = false;
4671 :
4672 54 : if (DECL_P (*node))
4673 : {
4674 0 : decl = *node;
4675 0 : type = &TREE_TYPE (decl);
4676 0 : is_type = TREE_CODE (*node) == TYPE_DECL;
4677 : }
4678 54 : else if (TYPE_P (*node))
4679 : type = node, is_type = true;
4680 :
4681 0 : if (is_type)
4682 : {
4683 54 : if ((flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
4684 : /* OK, modify the type in place. */;
4685 :
4686 : /* If we have a TYPE_DECL, then copy the type, so that we
4687 : don't accidentally modify a builtin type. See pushdecl. */
4688 0 : else if (decl && TREE_TYPE (decl) != error_mark_node
4689 50 : && DECL_ORIGINAL_TYPE (decl) == NULL_TREE)
4690 : {
4691 0 : tree tt = TREE_TYPE (decl);
4692 0 : *type = build_variant_type_copy (*type);
4693 0 : DECL_ORIGINAL_TYPE (decl) = tt;
4694 0 : TYPE_NAME (*type) = decl;
4695 0 : TREE_USED (*type) = TREE_USED (decl);
4696 0 : TREE_TYPE (decl) = *type;
4697 : }
4698 : else
4699 50 : *type = build_variant_type_copy (*type);
4700 : }
4701 :
4702 : return NULL_TREE;
4703 : }
4704 :
4705 : /* Handle the "nonstring" variable attribute. */
4706 :
4707 : static tree
4708 894 : handle_nonstring_attribute (tree *node, tree name, tree ARG_UNUSED (args),
4709 : int ARG_UNUSED (flags), bool *no_add_attrs)
4710 : {
4711 894 : gcc_assert (!args);
4712 894 : tree_code code = TREE_CODE (*node);
4713 :
4714 894 : if (VAR_P (*node)
4715 409 : || code == FIELD_DECL
4716 409 : || code == PARM_DECL)
4717 : {
4718 886 : tree type = TREE_TYPE (*node);
4719 :
4720 886 : if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
4721 : {
4722 : /* Accept the attribute on arrays and pointers to all three
4723 : narrow character types, including multi-dimensional arrays
4724 : or pointers to them. */
4725 878 : tree eltype = strip_array_types (TREE_TYPE (type));
4726 878 : eltype = TYPE_MAIN_VARIANT (eltype);
4727 878 : if (eltype == char_type_node
4728 136 : || eltype == signed_char_type_node
4729 72 : || eltype == unsigned_char_type_node)
4730 : return NULL_TREE;
4731 : }
4732 :
4733 16 : warning (OPT_Wattributes,
4734 : "%qE attribute ignored on objects of type %qT",
4735 : name, type);
4736 16 : *no_add_attrs = true;
4737 16 : return NULL_TREE;
4738 : }
4739 :
4740 8 : if (code == FUNCTION_DECL)
4741 4 : warning (OPT_Wattributes,
4742 : "%qE attribute does not apply to functions", name);
4743 4 : else if (code == TYPE_DECL)
4744 4 : warning (OPT_Wattributes,
4745 : "%qE attribute does not apply to types", name);
4746 : else
4747 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
4748 :
4749 8 : *no_add_attrs = true;
4750 8 : return NULL_TREE;
4751 : }
4752 :
4753 : /* Handle the "suppress_coverge" attribute. We don't really do anything here,
4754 : just check later if it is set. */
4755 : static tree
4756 18 : handle_suppress_coverage_attribute (tree *node, tree name,
4757 : tree ARG_UNUSED (args),
4758 : int ARG_UNUSED (flags), bool *no_add_attrs)
4759 : {
4760 18 : if (TREE_CODE (*node) != FUNCTION_DECL)
4761 : {
4762 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
4763 0 : *no_add_attrs = true;
4764 : }
4765 :
4766 18 : return NULL_TREE;
4767 : }
4768 :
4769 : /* Given a function type FUNCTYPE, returns the type of the parameter
4770 : ARGNO or null if ARGNO exceeds the number of parameters. On failure
4771 : set *NARGS to the number of function parameters. */
4772 :
4773 : static tree
4774 1384471 : get_argument_type (tree functype, unsigned argno, unsigned *nargs)
4775 : {
4776 1384471 : function_args_iterator iter;
4777 1384471 : function_args_iter_init (&iter, functype);
4778 :
4779 1384471 : unsigned count = 0;
4780 :
4781 4215488 : for ( ; iter.next; ++count, function_args_iter_next (&iter))
4782 : {
4783 2831011 : if (count + 1 == argno)
4784 : {
4785 1384465 : tree argtype = function_args_iter_cond (&iter);
4786 1384465 : if (VOID_TYPE_P (argtype))
4787 : break;
4788 1384462 : if (argtype != error_mark_node)
4789 : return argtype;
4790 : }
4791 : }
4792 :
4793 9 : *nargs = count;
4794 9 : return NULL_TREE;
4795 : }
4796 :
4797 : /* Given a function FNDECL return the function argument at the zero-
4798 : based position ARGNO or null if it can't be found. */
4799 :
4800 : static tree
4801 6 : get_argument (tree fndecl, unsigned argno)
4802 : {
4803 6 : if (!DECL_P (fndecl))
4804 : return NULL_TREE;
4805 :
4806 6 : unsigned i = 0;
4807 10 : for (tree arg = DECL_ARGUMENTS (fndecl); arg; arg = TREE_CHAIN (arg))
4808 8 : if (i++ == argno)
4809 : return arg;
4810 :
4811 : return NULL_TREE;
4812 : }
4813 :
4814 : /* Attempt to append attribute access specification ATTRSPEC, optionally
4815 : described by the human-readable string ATTRSTR, for type T, to one in
4816 : ATTRS. VBLIST is an optional list of bounds of variable length array
4817 : parameters described by ATTRSTR.
4818 : Issue warning for conflicts and return null if any are found.
4819 : Return the concatenated access string on success. */
4820 :
4821 : static tree
4822 1170228 : append_access_attr (tree node[3], tree attrs, const char *attrstr,
4823 : const char *attrspec, tree vblist = NULL_TREE)
4824 : {
4825 1170228 : tree argstr = build_string (strlen (attrspec) + 1, attrspec);
4826 1170228 : tree ataccess = tree_cons (NULL_TREE, argstr, vblist);
4827 1170228 : ataccess = tree_cons (get_identifier ("access"), ataccess, NULL_TREE);
4828 :
4829 : /* The access specification being applied. This may be an implicit
4830 : access spec synthesized for array (or VLA) parameters even for
4831 : a declaration with an explicit access spec already applied, if
4832 : this call corresponds to the first declaration of the function. */
4833 1170228 : rdwr_map new_idxs;
4834 1170228 : init_attr_rdwr_indices (&new_idxs, ataccess);
4835 :
4836 : /* The current access specification already applied. */
4837 1170228 : rdwr_map cur_idxs;
4838 1170228 : init_attr_rdwr_indices (&cur_idxs, attrs);
4839 :
4840 1170228 : tree args = TYPE_ARG_TYPES (node[0]);
4841 1170228 : int argpos = 0;
4842 1170228 : std::string spec;
4843 5453648 : for (tree arg = args; arg; arg = TREE_CHAIN (arg), argpos++)
4844 : {
4845 4283420 : const attr_access* const newa = new_idxs.get (argpos);
4846 :
4847 4283420 : if (!newa)
4848 4283337 : continue;
4849 :
4850 : /* The map has two equal entries for each pointer argument that
4851 : has an associated size argument. Process just the entry for
4852 : the former. */
4853 1824435 : if ((unsigned)argpos != newa->ptrarg)
4854 619765 : continue;
4855 :
4856 1204670 : const attr_access* const cura = cur_idxs.get (argpos);
4857 1204670 : if (!cura)
4858 : {
4859 : /* The new attribute needs to be added. */
4860 1198125 : tree str = newa->to_internal_string ();
4861 1198125 : spec += TREE_STRING_POINTER (str);
4862 1198125 : continue;
4863 1198125 : }
4864 :
4865 : /* The new access spec refers to an array/pointer argument for
4866 : which an access spec already exists. Check and diagnose any
4867 : conflicts. If no conflicts are found, merge the two. */
4868 :
4869 6545 : if (!attrstr)
4870 : {
4871 6351 : tree str = NULL_TREE;
4872 6351 : if (newa->mode != access_deferred)
4873 0 : str = newa->to_external_string ();
4874 6351 : else if (cura->mode != access_deferred)
4875 2144 : str = cura->to_external_string ();
4876 2144 : if (str)
4877 2144 : attrstr = TREE_STRING_POINTER (str);
4878 : }
4879 :
4880 6545 : location_t curloc = input_location;
4881 6545 : if (node[2] && DECL_P (node[2]))
4882 6545 : curloc = DECL_SOURCE_LOCATION (node[2]);
4883 :
4884 6545 : location_t prevloc = UNKNOWN_LOCATION;
4885 6545 : if (node[1] && DECL_P (node[1]))
4886 3714 : prevloc = DECL_SOURCE_LOCATION (node[1]);
4887 :
4888 6545 : if (newa->mode != cura->mode
4889 2166 : && newa->mode != access_deferred
4890 22 : && cura->mode != access_deferred
4891 10 : && newa->internal_p == cura->internal_p)
4892 : {
4893 : /* Mismatch in access mode. */
4894 10 : auto_diagnostic_group d;
4895 0 : if (warning_at (curloc, OPT_Wattributes,
4896 : "attribute %qs mismatch with mode %qs",
4897 10 : attrstr, cura->mode_names[cura->mode])
4898 10 : && prevloc != UNKNOWN_LOCATION)
4899 10 : inform (prevloc, "previous declaration here");
4900 10 : continue;
4901 10 : }
4902 :
4903 : /* Set if PTRARG refers to a VLA with an unspecified bound (T[*]).
4904 : Be prepared for either CURA or NEWA to refer to it, depending
4905 : on which happens to come first in the declaration. */
4906 13070 : const bool cur_vla_ub = (cura->internal_p
4907 4242 : && cura->sizarg == UINT_MAX
4908 10671 : && cura->minsize == HOST_WIDE_INT_M1U);
4909 13070 : const bool new_vla_ub = (newa->internal_p
4910 6351 : && newa->sizarg == UINT_MAX
4911 12776 : && newa->minsize == HOST_WIDE_INT_M1U);
4912 :
4913 6535 : if (newa->sizarg != cura->sizarg
4914 2095 : && attrstr
4915 2091 : && (!(cur_vla_ub ^ new_vla_ub)
4916 19 : || (!cura->internal_p && !newa->internal_p)))
4917 : {
4918 : /* Avoid diagnosing redeclarations of functions with no explicit
4919 : attribute access that add one. */
4920 2072 : if (newa->mode == access_deferred
4921 2062 : && cura->mode != access_deferred
4922 2062 : && newa->sizarg == UINT_MAX
4923 2058 : && cura->sizarg != UINT_MAX)
4924 2058 : continue;
4925 :
4926 14 : if (cura->mode == access_deferred
4927 4 : && newa->mode != access_deferred
4928 4 : && cura->sizarg == UINT_MAX
4929 3 : && newa->sizarg != UINT_MAX)
4930 3 : continue;
4931 :
4932 : /* The two specs designate different size arguments. It's okay
4933 : for the explicit spec to specify a size where none is provided
4934 : by the implicit (VLA) one, as in:
4935 : __attribute__ ((access (read_write, 1, 2)))
4936 : void f (int*, int);
4937 : but not for two explicit access attributes to do that. */
4938 11 : bool warned = false;
4939 :
4940 11 : auto_diagnostic_group d;
4941 :
4942 11 : if (newa->sizarg == UINT_MAX)
4943 : /* Mismatch in the presence of the size argument. */
4944 2 : warned = warning_at (curloc, OPT_Wattributes,
4945 : "attribute %qs missing positional argument 2 "
4946 : "provided in previous designation by argument "
4947 2 : "%u", attrstr, cura->sizarg + 1);
4948 9 : else if (cura->sizarg == UINT_MAX)
4949 : /* Mismatch in the presence of the size argument. */
4950 3 : warned = warning_at (curloc, OPT_Wattributes,
4951 : "attribute %qs positional argument 2 "
4952 : "missing in previous designation",
4953 : attrstr);
4954 6 : else if (newa->internal_p || cura->internal_p)
4955 : /* Mismatch in the value of the size argument and a VLA bound. */
4956 4 : warned = warning_at (curloc, OPT_Wattributes,
4957 : "attribute %qs positional argument 2 "
4958 : "conflicts with previous designation "
4959 : "by argument %u",
4960 : attrstr, cura->sizarg + 1);
4961 : else
4962 : /* Mismatch in the value of the size argument between two
4963 : explicit access attributes. */
4964 2 : warned = warning_at (curloc, OPT_Wattributes,
4965 : "attribute %qs mismatched positional argument "
4966 : "values %i and %i",
4967 : attrstr, newa->sizarg + 1, cura->sizarg + 1);
4968 :
4969 11 : if (warned)
4970 : {
4971 : /* If the previous declaration is a function (as opposed
4972 : to a typedef of one), find the location of the array
4973 : or pointer argument that uses the conflicting VLA bound
4974 : and point to it in the note. */
4975 11 : const attr_access* const pa = cura->size ? cura : newa;
4976 11 : tree size = pa->size ? TREE_VALUE (pa->size) : NULL_TREE;
4977 6 : if (size && DECL_P (size))
4978 : {
4979 6 : location_t argloc = UNKNOWN_LOCATION;
4980 6 : if (tree arg = get_argument (node[2], pa->ptrarg))
4981 4 : argloc = DECL_SOURCE_LOCATION (arg);
4982 :
4983 6 : gcc_rich_location richloc (DECL_SOURCE_LOCATION (size));
4984 6 : if (argloc != UNKNOWN_LOCATION)
4985 4 : richloc.add_range (argloc);
4986 :
4987 6 : inform (&richloc, "designating the bound of variable "
4988 : "length array argument %u",
4989 6 : pa->ptrarg + 1);
4990 6 : }
4991 5 : else if (prevloc != UNKNOWN_LOCATION)
4992 3 : inform (prevloc, "previous declaration here");
4993 : }
4994 :
4995 11 : continue;
4996 11 : }
4997 :
4998 4463 : if (newa->internal_p == cura->internal_p)
4999 4380 : continue;
5000 :
5001 : /* Merge the CURA and NEWA. */
5002 83 : attr_access merged = *newa;
5003 :
5004 : /* VLA seen in a declaration takes precedence. */
5005 83 : if (cura->minsize == HOST_WIDE_INT_M1U)
5006 17 : merged.minsize = HOST_WIDE_INT_M1U;
5007 :
5008 : /* Use the explicitly specified size positional argument. */
5009 83 : if (cura->sizarg != UINT_MAX)
5010 25 : merged.sizarg = cura->sizarg;
5011 :
5012 : /* Use the explicitly specified mode. */
5013 83 : if (merged.mode == access_deferred)
5014 68 : merged.mode = cura->mode;
5015 :
5016 83 : tree str = merged.to_internal_string ();
5017 83 : spec += TREE_STRING_POINTER (str);
5018 : }
5019 :
5020 1170228 : if (!spec.length ())
5021 : return NULL_TREE;
5022 :
5023 1166084 : return build_string (spec.length (), spec.c_str ());
5024 1170228 : }
5025 :
5026 : /* Convenience wrapper for the above. */
5027 :
5028 : static tree
5029 765168 : append_access_attr_idxs (tree node[3], tree attrs, const char *attrstr,
5030 : char code, HOST_WIDE_INT idxs[2])
5031 : {
5032 765168 : char attrspec[80];
5033 765168 : int n = sprintf (attrspec, "%c%u", code, (unsigned) idxs[0] - 1);
5034 765168 : if (idxs[1])
5035 619528 : n += sprintf (attrspec + n, ",%u", (unsigned) idxs[1] - 1);
5036 :
5037 765168 : return append_access_attr (node, attrs, attrstr, attrspec);
5038 : }
5039 :
5040 : /* Handle the access attribute for function type NODE[0], with the function
5041 : DECL optionally in NODE[1]. The handler is called both in response to
5042 : an explicit attribute access on a declaration with a mode and one or two
5043 : positional arguments, and for internally synthesized access specifications
5044 : with a string argument optionally followed by a DECL or expression
5045 : representing a VLA bound. To speed up parsing, the handler transforms
5046 : the attribute and its arguments into a string. */
5047 :
5048 : static tree
5049 2335912 : handle_access_attribute (tree node[3], tree name, tree args, int flags,
5050 : bool *no_add_attrs)
5051 : {
5052 2335912 : tree attrs = TYPE_ATTRIBUTES (*node);
5053 2335912 : tree type = *node;
5054 2335912 : if (POINTER_TYPE_P (type))
5055 : {
5056 0 : tree ptype = TREE_TYPE (type);
5057 0 : if (FUNC_OR_METHOD_TYPE_P (ptype))
5058 2335912 : type = ptype;
5059 : }
5060 :
5061 2335912 : *no_add_attrs = true;
5062 :
5063 : /* Verify a full prototype is provided so that the argument types
5064 : can be validated. Avoid diagnosing type-generic built-ins since
5065 : those have no prototype. */
5066 2335912 : if (!args
5067 0 : && !prototype_p (type)
5068 2335912 : && (!attrs || !lookup_attribute ("type generic", attrs)))
5069 : {
5070 0 : error ("attribute %qE without arguments on a non-prototype", name);
5071 0 : return NULL_TREE;
5072 : }
5073 :
5074 2335912 : tree access_mode = TREE_VALUE (args);
5075 2335912 : if (TREE_CODE (access_mode) == STRING_CST)
5076 : {
5077 1570919 : const char* const str = TREE_STRING_POINTER (access_mode);
5078 1570919 : if (*str == '+')
5079 : {
5080 : /* This is a request to merge an internal specification for
5081 : a function declaration involving arrays but no explicit
5082 : attribute access. */
5083 405060 : tree vblist = TREE_CHAIN (args);
5084 405060 : tree axstr = append_access_attr (node, attrs, NULL, str + 1,
5085 : vblist);
5086 405060 : if (!axstr)
5087 : return NULL_TREE;
5088 :
5089 : /* Replace any existing access attribute specification with
5090 : the concatenation above. */
5091 401095 : tree axsat = tree_cons (NULL_TREE, axstr, vblist);
5092 401095 : axsat = tree_cons (name, axsat, NULL_TREE);
5093 :
5094 : /* Recursively call self to "replace" the documented/external
5095 : form of the attribute with the condensend internal form. */
5096 401095 : decl_attributes (node, axsat, flags | ATTR_FLAG_INTERNAL);
5097 401095 : return NULL_TREE;
5098 : }
5099 :
5100 1165859 : if (flags & ATTR_FLAG_INTERNAL)
5101 : {
5102 : /* This is a recursive call to handle the condensed internal
5103 : form of the attribute (see below). Since all validation
5104 : has been done simply return here, accepting the attribute
5105 : as is. */
5106 1165857 : *no_add_attrs = false;
5107 1165857 : return NULL_TREE;
5108 : }
5109 : }
5110 :
5111 : /* Set to true when the access mode has the form of a function call
5112 : as in 'attribute (read_only (1, 2))'. That's an easy mistake to
5113 : make and so worth a special diagnostic. */
5114 764995 : bool funcall = false;
5115 764995 : if (TREE_CODE (access_mode) == CALL_EXPR)
5116 : {
5117 6 : access_mode = CALL_EXPR_FN (access_mode);
5118 6 : if (TREE_CODE (access_mode) != ADDR_EXPR)
5119 : {
5120 0 : error ("attribute %qE invalid mode", name);
5121 0 : return NULL_TREE;
5122 : }
5123 6 : access_mode = TREE_OPERAND (access_mode, 0);
5124 6 : access_mode = DECL_NAME (access_mode);
5125 6 : funcall = true;
5126 : }
5127 764989 : else if (TREE_CODE (access_mode) != IDENTIFIER_NODE)
5128 : {
5129 5 : error ("attribute %qE mode %qE is not an identifier; expected one of "
5130 : "%qs, %qs, %qs, or %qs", name, access_mode,
5131 : "read_only", "read_write", "write_only", "none");
5132 5 : return NULL_TREE;
5133 : }
5134 :
5135 764990 : const char* const access_str = IDENTIFIER_POINTER (access_mode);
5136 764990 : const char *ps = access_str;
5137 764990 : if (ps[0] == '_' && ps[1] == '_')
5138 : {
5139 764448 : size_t len = strlen (ps);
5140 764448 : if (ps[len - 1] == '_' && ps[len - 2] == '_')
5141 764448 : ps += 2;
5142 : }
5143 :
5144 764990 : int imode;
5145 :
5146 764990 : {
5147 764990 : const int nmodes = ARRAY_SIZE (attr_access::mode_names);
5148 :
5149 2064828 : for (imode = 0; imode != nmodes; ++imode)
5150 2064810 : if (!strncmp (ps, attr_access::mode_names[imode],
5151 2064810 : strlen (attr_access::mode_names[imode])))
5152 : break;
5153 :
5154 764990 : if (imode == nmodes)
5155 : {
5156 18 : error ("attribute %qE invalid mode %qs; expected one of "
5157 : "%qs, %qs, %qs, or %qs", name, access_str,
5158 : "read_only", "read_write", "write_only", "none");
5159 18 : return NULL_TREE;
5160 : }
5161 : }
5162 :
5163 764972 : const ::access_mode mode = static_cast<::access_mode>(imode);
5164 :
5165 764972 : if (funcall)
5166 : {
5167 3 : error ("attribute %qE unexpected %<(%> after mode %qs; expected "
5168 : "a positional argument or %<)%>",
5169 : name, access_str);
5170 3 : return NULL_TREE;
5171 : }
5172 :
5173 764969 : args = TREE_CHAIN (args);
5174 764969 : if (!args)
5175 : {
5176 : /* The first positional argument is required. It may be worth
5177 : dropping the requirement at some point and having read_only
5178 : apply to all const-qualified pointers and read_write or
5179 : write_only to the rest. */
5180 4 : error ("attribute %<%E(%s)%> missing an argument",
5181 : name, access_str);
5182 4 : return NULL_TREE;
5183 : }
5184 :
5185 : /* One or more positional arguments have been specified. Validate
5186 : them. */
5187 764965 : tree idxnodes[2] = { NULL_TREE, NULL_TREE };
5188 764965 : tree argtypes[2] = { NULL_TREE, NULL_TREE };
5189 : /* 1-based attribute positional arguments or zero if not specified.
5190 : Invalid negative or excessive values are also stored but used
5191 : only in diagnostics. */
5192 764965 : HOST_WIDE_INT idxs[2] = { 0, 0 };
5193 :
5194 : /* Number of function formal arguments (used in diagnostics). */
5195 764965 : unsigned nfuncargs = 0;
5196 : /* Number of (optional) attribute positional arguments. */
5197 764965 : unsigned nattrargs = 0;
5198 :
5199 2149442 : for (unsigned i = 0; i != 2; ++i, args = TREE_CHAIN (args), ++nattrargs)
5200 : {
5201 1529930 : if (!args)
5202 : break;
5203 :
5204 1384477 : idxnodes[i] = TREE_VALUE (args);
5205 :
5206 1384477 : if (TREE_CODE (idxnodes[i]) != IDENTIFIER_NODE
5207 1384477 : && TREE_CODE (idxnodes[i]) != FUNCTION_DECL)
5208 1384477 : idxnodes[i] = default_conversion (idxnodes[i]);
5209 :
5210 1384477 : if (tree_fits_shwi_p (idxnodes[i]))
5211 : {
5212 1384471 : idxs[i] = tree_to_shwi (idxnodes[i]);
5213 1384471 : argtypes[i] = get_argument_type (type, idxs[i], &nfuncargs);
5214 : }
5215 : }
5216 :
5217 764965 : if ((nattrargs == 1 && !idxs[0])
5218 764962 : || (nattrargs == 2 && (!idxs[0] || !idxs[1])))
5219 : {
5220 6 : if (idxnodes[1])
5221 3 : error ("attribute %<%E(%s, %E, %E)%> invalid positional argument %i",
5222 3 : name, access_str, idxnodes[0], idxnodes[1], idxs[0] ? 2 : 1);
5223 : else
5224 3 : error ("attribute %<%E(%s, %E)%> invalid positional argument %i",
5225 3 : name, access_str, idxnodes[0], idxs[0] ? 2 : 1);
5226 : return NULL_TREE;
5227 : }
5228 :
5229 : /* Format the attribute specification to include in diagnostics. */
5230 764959 : char attrstr[80];
5231 764959 : if (idxnodes[1])
5232 1239018 : snprintf (attrstr, sizeof attrstr, "%s(%s, %lli, %lli)",
5233 619509 : IDENTIFIER_POINTER (name), access_str,
5234 619509 : (long long) idxs[0], (long long) idxs[1]);
5235 145450 : else if (idxnodes[0])
5236 290900 : snprintf (attrstr, sizeof attrstr, "%s(%s, %lli)",
5237 145450 : IDENTIFIER_POINTER (name), access_str,
5238 145450 : (long long) idxs[0]);
5239 : else
5240 0 : snprintf (attrstr, sizeof attrstr, "%s(%s)",
5241 0 : IDENTIFIER_POINTER (name), access_str);
5242 :
5243 : /* Verify the positional argument values are in range. */
5244 764959 : if (!argtypes[0] || (idxnodes[1] && !argtypes[1]))
5245 : {
5246 9 : if (idxnodes[0])
5247 : {
5248 9 : if (idxs[0] < 0 || idxs[1] < 0)
5249 9 : error ("attribute %qs positional argument %i invalid value %wi",
5250 : attrstr, idxs[0] < 0 ? 1 : 2,
5251 : idxs[0] < 0 ? idxs[0] : idxs[1]);
5252 : else
5253 3 : error ("attribute %qs positional argument %i value %wi exceeds "
5254 : "number of function arguments %u",
5255 : attrstr, idxs[0] ? 1 : 2,
5256 : idxs[0] ? idxs[0] : idxs[1],
5257 : nfuncargs);
5258 : }
5259 : else
5260 0 : error ("attribute %qs invalid positional argument", attrstr);
5261 :
5262 : return NULL_TREE;
5263 : }
5264 :
5265 764950 : if (!POINTER_TYPE_P (argtypes[0]))
5266 : {
5267 : /* The first argument must have a pointer or reference type. */
5268 4 : error ("attribute %qs positional argument 1 references "
5269 : "non-pointer argument type %qT",
5270 : attrstr, argtypes[0]);
5271 4 : return NULL_TREE;
5272 : }
5273 :
5274 764946 : {
5275 : /* Pointers to functions are not allowed. */
5276 764946 : tree ptrtype = TREE_TYPE (argtypes[0]);
5277 764946 : if (FUNC_OR_METHOD_TYPE_P (ptrtype))
5278 : {
5279 3 : error ("attribute %qs positional argument 1 references "
5280 : "argument of function type %qT",
5281 : attrstr, ptrtype);
5282 3 : return NULL_TREE;
5283 : }
5284 : }
5285 :
5286 764943 : if (mode == access_read_write || mode == access_write_only)
5287 : {
5288 : /* Read_write and write_only modes must reference non-const
5289 : arguments. */
5290 511439 : if (TYPE_READONLY (TREE_TYPE (argtypes[0])))
5291 : {
5292 3 : error ("attribute %qs positional argument 1 references "
5293 : "%qs-qualified argument type %qT",
5294 : attrstr, "const", argtypes[0]);
5295 3 : return NULL_TREE;
5296 : }
5297 : }
5298 253504 : else if (!TYPE_READONLY (TREE_TYPE (argtypes[0])))
5299 : {
5300 : /* A read_only mode should ideally reference const-qualified
5301 : arguments but it's not diagnosed error if one doesn't.
5302 : This makes it possible to annotate legacy, const-incorrect
5303 : APIs. It might be worth a diagnostic along the lines of
5304 : -Wsuggest-const. */
5305 253504 : ;
5306 : }
5307 :
5308 764940 : if (argtypes[1] && !INTEGRAL_TYPE_P (argtypes[1]))
5309 : {
5310 12 : error ("attribute %qs positional argument 2 references "
5311 : "non-integer argument type %qT",
5312 : attrstr, argtypes[1]);
5313 12 : return NULL_TREE;
5314 : }
5315 :
5316 : /* Verify that the new attribute doesn't conflict with any existing
5317 : attributes specified on previous declarations of the same type
5318 : and if not, concatenate the two. */
5319 764928 : const char code = attr_access::mode_chars[mode];
5320 764928 : tree new_attrs = append_access_attr_idxs (node, attrs, attrstr, code, idxs);
5321 764928 : if (!new_attrs)
5322 : return NULL_TREE;
5323 :
5324 : /* Replace any existing access attribute specification with
5325 : the concatenation above. */
5326 764913 : new_attrs = tree_cons (NULL_TREE, new_attrs, NULL_TREE);
5327 764913 : new_attrs = tree_cons (name, new_attrs, NULL_TREE);
5328 :
5329 764913 : if (node[1])
5330 : {
5331 : /* Repeat for the previously declared type. */
5332 240 : attrs = TYPE_ATTRIBUTES (TREE_TYPE (node[1]));
5333 240 : new_attrs = append_access_attr_idxs (node, attrs, attrstr, code, idxs);
5334 240 : if (!new_attrs)
5335 : return NULL_TREE;
5336 :
5337 76 : new_attrs = tree_cons (NULL_TREE, new_attrs, NULL_TREE);
5338 76 : new_attrs = tree_cons (name, new_attrs, NULL_TREE);
5339 : }
5340 :
5341 : /* Recursively call self to "replace" the documented/external form
5342 : of the attribute with the condensed internal form. */
5343 764749 : decl_attributes (node, new_attrs, flags | ATTR_FLAG_INTERNAL);
5344 764749 : return NULL_TREE;
5345 : }
5346 :
5347 :
5348 : /* This function builds a string which is concatenated to SPEC and returns
5349 : list of variably bounds corresponding to an array/VLA parameter with
5350 : type TYPE. The string consists of one dollar symbol for each specified
5351 : variable bound, one asterisk for each unspecified variable bound,
5352 : a space for an array of unknown size (only possibly for the outermost),
5353 : and a zero for a zero-sized array.
5354 :
5355 : The chainof variable bounds starts with the most significant bound.
5356 : For example, the TYPE T[2][m][3][n] will produce "$$" and (m, (n, nil)). */
5357 :
5358 : static tree
5359 980107 : build_arg_spec (tree type, std::string *spec)
5360 : {
5361 998758 : while (POINTER_TYPE_P (type))
5362 18651 : type = TREE_TYPE (type);
5363 :
5364 980107 : if (TREE_CODE (type) != ARRAY_TYPE)
5365 : return NULL_TREE;
5366 :
5367 499150 : tree list = build_arg_spec (TREE_TYPE (type), spec);
5368 :
5369 499150 : if (!COMPLETE_TYPE_P (type))
5370 : {
5371 65178 : (*spec) += ' ';
5372 65178 : return list;
5373 : }
5374 :
5375 433972 : tree mval = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
5376 :
5377 433972 : if (!mval)
5378 : {
5379 56 : (*spec) += '0';
5380 56 : return list;
5381 : }
5382 :
5383 433916 : if (TREE_CODE (mval) == COMPOUND_EXPR
5384 156 : && integer_zerop (TREE_OPERAND (mval, 0))
5385 434072 : && integer_zerop (TREE_OPERAND (mval, 1)))
5386 : {
5387 146 : (*spec) += '*';
5388 146 : return list;
5389 : }
5390 :
5391 433770 : if (TREE_CODE (mval) == INTEGER_CST)
5392 : return list;
5393 :
5394 : /* A variable bound. */
5395 13977 : (*spec) += '$';
5396 :
5397 13977 : mval = array_type_nelts_top (type);
5398 :
5399 : /* Remove NOP_EXPR and SAVE_EXPR to uncover possible PARM_DECLS. */
5400 13977 : if (TREE_CODE (mval) == NOP_EXPR)
5401 13967 : mval = TREE_OPERAND (mval, 0);
5402 13977 : if (TREE_CODE (mval) == SAVE_EXPR)
5403 : {
5404 13942 : mval = TREE_OPERAND (mval, 0);
5405 13942 : if (TREE_CODE (mval) == NOP_EXPR)
5406 0 : mval = TREE_OPERAND (mval, 0);
5407 : }
5408 :
5409 13977 : return tree_cons (NULL_TREE, mval, list);
5410 : }
5411 :
5412 : /* Extract attribute "arg spec" from each FNDECL argument that has it,
5413 : build a single attribute access corresponding to all the arguments,
5414 : and return the result. SKIP_VOIDPTR set to ignore void* parameters
5415 : (used for user-defined functions for which, unlike in for built-ins,
5416 : void* cannot be relied on to determine anything about the access
5417 : through it or whether it even takes place).
5418 :
5419 : For example, the parameters in the declaration:
5420 :
5421 : void f (int x, int y, char [x][1][y][3], char [y][2][y][5]);
5422 :
5423 : result in the following attribute access:
5424 :
5425 : value: "+^2[*],$0$1^3[*],$1$1"
5426 : list: < <0, x> <1, y> >
5427 :
5428 : where the list has a single value which itself is a list, each
5429 : of whose <node>s corresponds to one VLA bound for each of the two
5430 : parameters. */
5431 :
5432 : tree
5433 53520854 : build_attr_access_from_parms (tree parms, bool skip_voidptr)
5434 : {
5435 : /* Maps each named integral argument DECL seen so far to its position
5436 : in the argument list; used to associate VLA sizes with arguments. */
5437 53520854 : hash_map<tree, unsigned> arg2pos;
5438 :
5439 : /* The string representation of the access specification for all
5440 : arguments. */
5441 53520854 : std::string spec;
5442 53520854 : unsigned argpos = 0;
5443 :
5444 : /* A TREE_LIST of VLA bounds. */
5445 53520854 : tree vblist = NULL_TREE;
5446 :
5447 183213374 : for (tree arg = parms; arg; arg = TREE_CHAIN (arg), ++argpos)
5448 : {
5449 129692520 : if (!DECL_P (arg))
5450 34274 : continue;
5451 :
5452 129658246 : tree argtype = TREE_TYPE (arg);
5453 129658246 : if (DECL_NAME (arg) && INTEGRAL_TYPE_P (argtype))
5454 38540715 : arg2pos.put (arg, argpos);
5455 : }
5456 :
5457 53520854 : tree nnlist = NULL_TREE;
5458 53520854 : argpos = 0;
5459 183213374 : for (tree arg = parms; arg; arg = TREE_CHAIN (arg), ++argpos)
5460 : {
5461 129692520 : if (!DECL_P (arg))
5462 34274 : continue;
5463 :
5464 129658246 : tree argtype = TREE_TYPE (arg);
5465 :
5466 129658246 : tree argspec = DECL_ATTRIBUTES (arg);
5467 129658246 : if (!argspec)
5468 129158200 : continue;
5469 :
5470 500046 : if (POINTER_TYPE_P (argtype))
5471 : {
5472 : /* void* arguments in user-defined functions could point to
5473 : anything; skip them. */
5474 482851 : tree reftype = TREE_TYPE (argtype);
5475 482851 : if (skip_voidptr && VOID_TYPE_P (reftype))
5476 8 : continue;
5477 : }
5478 :
5479 : /* Each parameter should have at most one "arg spec" attribute. */
5480 500038 : argspec = lookup_attribute ("arg spec", argspec);
5481 500038 : if (!argspec)
5482 19081 : continue;
5483 :
5484 : /* Attribute arg spec should have one or two arguments. */
5485 480957 : argspec = TREE_VALUE (argspec);
5486 :
5487 : /* The attribute arg spec string. */
5488 480957 : const char *s = TREE_STRING_POINTER (TREE_VALUE (argspec));
5489 480957 : bool static_p = s && (0 == strcmp("static", s));
5490 :
5491 : /* Collect the list of nonnull arguments which use "[static ..]". */
5492 138 : if (static_p)
5493 138 : nnlist = tree_cons (NULL_TREE, build_int_cst (integer_type_node,
5494 138 : argpos + 1), nnlist);
5495 :
5496 480957 : tree argvbs;
5497 : /* Create the attribute access string from the arg spec data,
5498 : optionally followed by position of the VLA bound argument if
5499 : it is one. */
5500 480957 : {
5501 480957 : size_t specend = spec.length ();
5502 480957 : if (!specend)
5503 : {
5504 444193 : spec = '+';
5505 444193 : specend = 1;
5506 : }
5507 :
5508 480957 : spec += attr_access::mode_chars[access_deferred];
5509 961914 : spec += std::to_string (argpos);
5510 480957 : spec += '[';
5511 480957 : tree type = TREE_VALUE (TREE_CHAIN (argspec));
5512 480957 : argvbs = build_arg_spec (type, &spec);
5513 :
5514 : /* Postprocess the string to bring it in the format expected
5515 : by the code handling the access attribute. First, we
5516 : add 's' if the array was declared as [static ...]. */
5517 480957 : if (static_p)
5518 : {
5519 138 : size_t send = spec.length();
5520 :
5521 138 : if (spec[send - 1] == '[')
5522 : {
5523 111 : spec += 's';
5524 : }
5525 : else
5526 : {
5527 : /* If there is a symbol, we need to swap the order. */
5528 27 : spec += spec[send - 1];
5529 27 : spec[send - 1] = 's';
5530 : }
5531 : }
5532 :
5533 : /* If the outermost bound is an integer constant, we need to write
5534 : the size if it is constant. */
5535 961914 : if (type && TYPE_DOMAIN (type))
5536 : {
5537 415779 : tree mval = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
5538 415779 : if (mval && TREE_CODE (mval) == INTEGER_CST)
5539 : {
5540 414413 : char buf[40];
5541 414413 : unsigned HOST_WIDE_INT n = tree_to_uhwi (mval) + 1;
5542 414413 : sprintf (buf, HOST_WIDE_INT_PRINT_UNSIGNED, n);
5543 414413 : spec += buf;
5544 : }
5545 : }
5546 480957 : spec += ']';
5547 :
5548 : /* Trim the trailing NUL. */
5549 480957 : spec.resize (spec.length ());
5550 : }
5551 :
5552 : /* The (optional) list of expressions denoting the VLA bounds
5553 : N in ARGTYPE <arg>[Ni]...[Nj]...[Nk]. */
5554 480957 : if (argvbs)
5555 : {
5556 1485 : spec += ',';
5557 : /* Add ARGVBS to the list. Their presence is indicated by
5558 : appending a comma followed by the dollar sign and, when
5559 : it corresponds to a function parameter, the position of
5560 : each bound Ni, so it can be distinguished from
5561 : an unspecified bound (as in T[*]). The list is in reverse
5562 : order of arguments and needs to be reversed to access in
5563 : order. */
5564 1485 : vblist = tree_cons (NULL_TREE, argvbs, vblist);
5565 :
5566 16947 : for (tree vb = argvbs; vb; vb = TREE_CHAIN (vb))
5567 : {
5568 13977 : tree bound = TREE_VALUE (vb);
5569 13977 : if (const unsigned *psizpos = arg2pos.get (bound))
5570 : {
5571 : /* BOUND previously seen in the parameter list. */
5572 413 : TREE_PURPOSE (vb) = size_int (*psizpos);
5573 : /* Format the position string in place. */
5574 413 : int len = snprintf (NULL, 0, "$%u", *psizpos);
5575 413 : size_t specend = spec.length ();
5576 413 : spec.resize (specend + len + 1);
5577 413 : sprintf (&spec[specend], "$%u", *psizpos);
5578 : /* Trim the trailing NUL. */
5579 413 : spec.resize (specend + len);
5580 : }
5581 : else
5582 : {
5583 : /* BOUND doesn't name a parameter (it could be a global
5584 : variable or an expression such as a function call). */
5585 13564 : spec += '$';
5586 : }
5587 : }
5588 : }
5589 : }
5590 :
5591 53520854 : if (!spec.length ())
5592 : return NULL_TREE;
5593 :
5594 : /* If we have nonnull arguments, synthesize an attribute. */
5595 444193 : if (nnlist != NULL_TREE)
5596 130 : nnlist = build_tree_list (get_identifier ("nonnull"), nnlist);
5597 :
5598 : /* Attribute access takes a two or three arguments. Wrap VBLIST in
5599 : another list in case it has more nodes than would otherwise fit. */
5600 444193 : vblist = build_tree_list (NULL_TREE, vblist);
5601 :
5602 : /* Build a single attribute access with the string describing all
5603 : array arguments and an optional list of any non-parameter VLA
5604 : bounds in order. */
5605 444193 : tree str = build_string (spec.length (), spec.c_str ());
5606 444193 : tree attrargs = tree_cons (NULL_TREE, str, vblist);
5607 444193 : tree name = get_identifier ("access");
5608 444193 : return tree_cons (name, attrargs, nnlist);
5609 53520854 : }
5610 :
5611 :
5612 : /* Handle a "nothrow" attribute; arguments as in
5613 : struct attribute_spec.handler. */
5614 :
5615 : static tree
5616 14 : handle_expected_throw_attribute (tree *node, tree name, tree ARG_UNUSED (args),
5617 : int ARG_UNUSED (flags), bool *no_add_attrs)
5618 : {
5619 14 : if (TREE_CODE (*node) == FUNCTION_DECL)
5620 : /* No flag to set here. */;
5621 : /* ??? TODO: Support types. */
5622 : else
5623 : {
5624 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
5625 0 : *no_add_attrs = true;
5626 : }
5627 :
5628 14 : return NULL_TREE;
5629 : }
5630 :
5631 : /* Handle a "cleanup" attribute; arguments as in
5632 : struct attribute_spec.handler. */
5633 :
5634 : static tree
5635 322 : handle_cleanup_attribute (tree *node, tree name, tree args,
5636 : int ARG_UNUSED (flags), bool *no_add_attrs)
5637 : {
5638 322 : tree decl = *node;
5639 322 : tree cleanup_id, cleanup_decl;
5640 :
5641 : /* ??? Could perhaps support cleanups on TREE_STATIC, much like we do
5642 : for global destructors in C++. This requires infrastructure that
5643 : we don't have generically at the moment. It's also not a feature
5644 : we'd be missing too much, since we do have attribute constructor. */
5645 322 : if (!VAR_P (decl) || TREE_STATIC (decl))
5646 : {
5647 12 : warning (OPT_Wattributes, "%qE attribute ignored", name);
5648 12 : *no_add_attrs = true;
5649 12 : return NULL_TREE;
5650 : }
5651 :
5652 : /* Verify that the argument is a function in scope. */
5653 : /* ??? We could support pointers to functions here as well, if
5654 : that was considered desirable. */
5655 310 : cleanup_id = TREE_VALUE (args);
5656 310 : if (TREE_CODE (cleanup_id) != IDENTIFIER_NODE)
5657 : {
5658 4 : error ("cleanup argument not an identifier");
5659 4 : *no_add_attrs = true;
5660 4 : return NULL_TREE;
5661 : }
5662 306 : cleanup_decl = lookup_name (cleanup_id);
5663 306 : if (!cleanup_decl || TREE_CODE (cleanup_decl) != FUNCTION_DECL)
5664 : {
5665 8 : error ("cleanup argument not a function");
5666 8 : *no_add_attrs = true;
5667 8 : return NULL_TREE;
5668 : }
5669 :
5670 : /* That the function has proper type is checked with the
5671 : eventual call to build_function_call. */
5672 :
5673 : return NULL_TREE;
5674 : }
5675 :
5676 : /* Handle a "warn_unused_result" attribute. No special handling. */
5677 :
5678 : static tree
5679 2897529 : handle_warn_unused_result_attribute (tree *node, tree name,
5680 : tree ARG_UNUSED (args),
5681 : int ARG_UNUSED (flags), bool *no_add_attrs)
5682 : {
5683 : /* Ignore the attribute for functions not returning any value. */
5684 2897529 : if (VOID_TYPE_P (TREE_TYPE (*node)))
5685 : {
5686 9 : warning (OPT_Wattributes, "%qE attribute ignored", name);
5687 9 : *no_add_attrs = true;
5688 : }
5689 :
5690 2897529 : return NULL_TREE;
5691 : }
5692 :
5693 : /* Handle a "sentinel" attribute. */
5694 :
5695 : static tree
5696 1103222 : handle_sentinel_attribute (tree *node, tree name, tree args,
5697 : int ARG_UNUSED (flags), bool *no_add_attrs)
5698 : {
5699 1103222 : if (!prototype_p (*node))
5700 : {
5701 2 : warning (OPT_Wattributes,
5702 : "%qE attribute requires prototypes with named arguments", name);
5703 2 : *no_add_attrs = true;
5704 : }
5705 : else
5706 : {
5707 1103220 : if (!stdarg_p (*node))
5708 : {
5709 2 : warning (OPT_Wattributes,
5710 : "%qE attribute only applies to variadic functions", name);
5711 2 : *no_add_attrs = true;
5712 : }
5713 : }
5714 :
5715 1103222 : if (args)
5716 : {
5717 367729 : tree position = TREE_VALUE (args);
5718 367729 : if (position && TREE_CODE (position) != IDENTIFIER_NODE
5719 367729 : && TREE_CODE (position) != FUNCTION_DECL)
5720 367725 : position = default_conversion (position);
5721 :
5722 367729 : if (TREE_CODE (position) != INTEGER_CST
5723 367729 : || !INTEGRAL_TYPE_P (TREE_TYPE (position)))
5724 : {
5725 6 : warning (OPT_Wattributes,
5726 : "requested position is not an integer constant");
5727 6 : *no_add_attrs = true;
5728 : }
5729 : else
5730 : {
5731 367723 : if (tree_int_cst_lt (position, integer_zero_node))
5732 : {
5733 2 : warning (OPT_Wattributes,
5734 : "requested position is less than zero");
5735 2 : *no_add_attrs = true;
5736 : }
5737 : }
5738 : }
5739 :
5740 1103222 : return NULL_TREE;
5741 : }
5742 :
5743 : /* Handle a "target_version" attribute. */
5744 :
5745 : static tree
5746 0 : handle_target_version_attribute (tree *node, tree name, tree args, int flags,
5747 : bool *no_add_attrs)
5748 : {
5749 : /* Ensure we have a function declaration. */
5750 0 : if (TREE_CODE (*node) != FUNCTION_DECL)
5751 : {
5752 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
5753 0 : *no_add_attrs = true;
5754 : }
5755 0 : else if (!targetm.target_option.valid_version_attribute_p (*node, name, args,
5756 : flags))
5757 0 : *no_add_attrs = true;
5758 :
5759 0 : return NULL_TREE;
5760 : }
5761 :
5762 : /* Handle a "target_clones" attribute. */
5763 :
5764 : static tree
5765 115 : handle_target_clones_attribute (tree *node, tree name, tree ARG_UNUSED (args),
5766 : int ARG_UNUSED (flags), bool *no_add_attrs)
5767 : {
5768 : /* Ensure we have a function declaration. */
5769 115 : if (TREE_CODE (*node) == FUNCTION_DECL)
5770 : {
5771 418 : for (tree t = args; t != NULL_TREE; t = TREE_CHAIN (t))
5772 : {
5773 305 : tree value = TREE_VALUE (t);
5774 305 : if (TREE_CODE (value) != STRING_CST)
5775 : {
5776 2 : error ("%qE attribute argument not a string constant", name);
5777 2 : *no_add_attrs = true;
5778 2 : return NULL_TREE;
5779 : }
5780 : }
5781 :
5782 113 : int num_defaults = 0;
5783 113 : auto_vec<string_slice> versions = get_clone_attr_versions
5784 : (args,
5785 : &num_defaults,
5786 113 : false);
5787 :
5788 655 : for (auto v : versions)
5789 316 : targetm.check_target_clone_version
5790 316 : (v, &DECL_SOURCE_LOCATION (*node));
5791 :
5792 : /* Lone target_clones version is always ignored for target attr semantics.
5793 : Only ignore under target_version semantics if it is a default
5794 : version. */
5795 113 : if (versions.length () == 1
5796 : && (TARGET_HAS_FMV_TARGET_ATTRIBUTE || num_defaults == 1))
5797 : {
5798 1 : if (TARGET_HAS_FMV_TARGET_ATTRIBUTE)
5799 1 : warning (OPT_Wattributes,
5800 : "single %<target_clones%> attribute is ignored");
5801 1 : *no_add_attrs = true;
5802 : }
5803 : else
5804 : /* Do not inline functions with multiple clone targets. */
5805 112 : DECL_UNINLINABLE (*node) = 1;
5806 113 : }
5807 : else
5808 : {
5809 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
5810 0 : *no_add_attrs = true;
5811 : }
5812 : return NULL_TREE;
5813 : }
5814 :
5815 : /* For handling "optimize" attribute. arguments as in
5816 : struct attribute_spec.handler. */
5817 :
5818 : static tree
5819 346963 : handle_optimize_attribute (tree *node, tree name, tree args,
5820 : int ARG_UNUSED (flags), bool *no_add_attrs)
5821 : {
5822 : /* Ensure we have a function type. */
5823 346963 : if (TREE_CODE (*node) != FUNCTION_DECL)
5824 : {
5825 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
5826 0 : *no_add_attrs = true;
5827 : }
5828 : else
5829 : {
5830 346963 : struct cl_optimization cur_opts;
5831 346963 : struct cl_target_option cur_target;
5832 346963 : tree old_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node);
5833 346963 : tree old_target = DECL_FUNCTION_SPECIFIC_TARGET (*node);
5834 :
5835 : /* Save current options. */
5836 346963 : cl_optimization_save (&cur_opts, &global_options, &global_options_set);
5837 346963 : cl_target_option_save (&cur_target, &global_options, &global_options_set);
5838 :
5839 346963 : tree prev_target_node
5840 : = old_target
5841 346963 : ? old_target
5842 328240 : : build_target_option_node (&global_options, &global_options_set);
5843 :
5844 : /* If we previously had some optimization options, use them as the
5845 : default. */
5846 346963 : gcc_options *saved_global_options = NULL;
5847 :
5848 : /* When #pragma GCC optimize pragma is used, it modifies global_options
5849 : without calling targetm.override_options_after_change. That can leave
5850 : target flags inconsistent for comparison. */
5851 346963 : if (flag_checking && optimization_current_node == optimization_default_node)
5852 : {
5853 290085 : saved_global_options = XNEW (gcc_options);
5854 290085 : *saved_global_options = global_options;
5855 : }
5856 :
5857 346963 : if (old_opts)
5858 65796 : cl_optimization_restore (&global_options, &global_options_set,
5859 65796 : TREE_OPTIMIZATION (old_opts));
5860 :
5861 346963 : if (old_target)
5862 18723 : cl_target_option_restore (&global_options, &global_options_set,
5863 18723 : TREE_TARGET_OPTION (old_target));
5864 :
5865 : /* Parse options, and update the vector. */
5866 346963 : parse_optimize_options (args, true);
5867 346963 : DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node)
5868 346963 : = build_optimization_node (&global_options, &global_options_set);
5869 346963 : tree target_node = build_target_option_node (&global_options,
5870 : &global_options_set);
5871 346963 : if (prev_target_node != target_node)
5872 0 : DECL_FUNCTION_SPECIFIC_TARGET (*node) = target_node;
5873 :
5874 : /* Also update the cgraph_node, if it's already built. */
5875 346963 : if (cgraph_node *cn = cgraph_node::get (*node))
5876 12 : cn->semantic_interposition = flag_semantic_interposition;
5877 :
5878 : /* Restore current options. */
5879 346963 : cl_optimization_restore (&global_options, &global_options_set,
5880 : &cur_opts);
5881 346963 : cl_target_option_restore (&global_options, &global_options_set,
5882 : &cur_target);
5883 :
5884 346963 : if (saved_global_options != NULL)
5885 : {
5886 290085 : if (!seen_error ())
5887 290078 : cl_optimization_compare (saved_global_options, &global_options);
5888 290085 : free (saved_global_options);
5889 : }
5890 : }
5891 :
5892 346963 : return NULL_TREE;
5893 : }
5894 :
5895 : /* Handle a "no_split_stack" attribute. */
5896 :
5897 : static tree
5898 488 : handle_no_split_stack_attribute (tree *node, tree name,
5899 : tree ARG_UNUSED (args),
5900 : int ARG_UNUSED (flags),
5901 : bool *no_add_attrs)
5902 : {
5903 488 : tree decl = *node;
5904 :
5905 488 : if (TREE_CODE (decl) != FUNCTION_DECL)
5906 : {
5907 0 : error_at (DECL_SOURCE_LOCATION (decl),
5908 : "%qE attribute applies only to functions", name);
5909 0 : *no_add_attrs = true;
5910 : }
5911 488 : else if (DECL_INITIAL (decl))
5912 : {
5913 0 : error_at (DECL_SOURCE_LOCATION (decl),
5914 : "cannot set %qE attribute after definition", name);
5915 0 : *no_add_attrs = true;
5916 : }
5917 :
5918 488 : return NULL_TREE;
5919 : }
5920 :
5921 : /* Handle a "zero_call_used_regs" attribute; arguments as in
5922 : struct attribute_spec.handler. */
5923 :
5924 : static tree
5925 100 : handle_zero_call_used_regs_attribute (tree *node, tree name, tree args,
5926 : int ARG_UNUSED (flags),
5927 : bool *no_add_attrs)
5928 : {
5929 100 : tree decl = *node;
5930 100 : tree id = TREE_VALUE (args);
5931 :
5932 100 : if (TREE_CODE (decl) != FUNCTION_DECL)
5933 : {
5934 4 : error_at (DECL_SOURCE_LOCATION (decl),
5935 : "%qE attribute applies only to functions", name);
5936 4 : *no_add_attrs = true;
5937 4 : return NULL_TREE;
5938 : }
5939 :
5940 96 : if (TREE_CODE (id) != STRING_CST)
5941 : {
5942 4 : error_at (DECL_SOURCE_LOCATION (decl),
5943 : "%qE argument not a string", name);
5944 4 : *no_add_attrs = true;
5945 4 : return NULL_TREE;
5946 : }
5947 :
5948 552 : bool found = false;
5949 552 : for (unsigned int i = 0; zero_call_used_regs_opts[i].name != NULL; ++i)
5950 548 : if (strcmp (TREE_STRING_POINTER (id),
5951 548 : zero_call_used_regs_opts[i].name) == 0)
5952 : {
5953 : found = true;
5954 : break;
5955 : }
5956 :
5957 92 : if (!found)
5958 : {
5959 4 : error_at (DECL_SOURCE_LOCATION (decl),
5960 : "unrecognized %qE attribute argument %qs",
5961 4 : name, TREE_STRING_POINTER (id));
5962 4 : *no_add_attrs = true;
5963 : }
5964 :
5965 : return NULL_TREE;
5966 : }
5967 :
5968 : /* Handle a "returns_nonnull" attribute; arguments as in
5969 : struct attribute_spec.handler. */
5970 :
5971 : static tree
5972 1234826 : handle_returns_nonnull_attribute (tree *node, tree name, tree, int,
5973 : bool *no_add_attrs)
5974 : {
5975 : // Even without a prototype we still have a return type we can check.
5976 1234826 : if (TREE_CODE (TREE_TYPE (*node)) != POINTER_TYPE)
5977 : {
5978 4 : error ("%qE attribute on a function not returning a pointer", name);
5979 4 : *no_add_attrs = true;
5980 : }
5981 1234826 : return NULL_TREE;
5982 : }
5983 :
5984 : /* Handle a "designated_init" attribute; arguments as in
5985 : struct attribute_spec.handler. */
5986 :
5987 : static tree
5988 19 : handle_designated_init_attribute (tree *node, tree name, tree, int,
5989 : bool *no_add_attrs)
5990 : {
5991 19 : if (TREE_CODE (*node) != RECORD_TYPE)
5992 : {
5993 3 : error ("%qE attribute is only valid on %<struct%> type", name);
5994 3 : *no_add_attrs = true;
5995 : }
5996 19 : return NULL_TREE;
5997 : }
5998 :
5999 :
6000 : /* Handle a "fallthrough" attribute; arguments as in struct
6001 : attribute_spec.handler. */
6002 :
6003 : tree
6004 193 : handle_fallthrough_attribute (tree *, tree name, tree, int,
6005 : bool *no_add_attrs)
6006 : {
6007 193 : pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored", name);
6008 193 : *no_add_attrs = true;
6009 193 : return NULL_TREE;
6010 : }
6011 :
6012 : /* Handle a "assume" attribute; arguments as in struct
6013 : attribute_spec.handler. */
6014 :
6015 : tree
6016 203 : handle_assume_attribute (tree *, tree name, tree, int,
6017 : bool *no_add_attrs)
6018 : {
6019 203 : pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored", name);
6020 203 : *no_add_attrs = true;
6021 203 : return NULL_TREE;
6022 : }
6023 :
6024 : /* Handle a "patchable_function_entry" attributes; arguments as in
6025 : struct attribute_spec.handler. */
6026 :
6027 : static tree
6028 44 : handle_patchable_function_entry_attribute (tree *, tree name, tree args,
6029 : int, bool *no_add_attrs)
6030 : {
6031 76 : for (; args; args = TREE_CHAIN (args))
6032 : {
6033 60 : tree val = TREE_VALUE (args);
6034 60 : if (val && TREE_CODE (val) != IDENTIFIER_NODE
6035 60 : && TREE_CODE (val) != FUNCTION_DECL)
6036 60 : val = default_conversion (val);
6037 :
6038 60 : if (!tree_fits_uhwi_p (val))
6039 : {
6040 16 : warning (OPT_Wattributes,
6041 : "%qE attribute argument %qE is not an integer constant",
6042 : name, val);
6043 16 : *no_add_attrs = true;
6044 16 : return NULL_TREE;
6045 : }
6046 :
6047 44 : if (tree_to_uhwi (val) > USHRT_MAX)
6048 : {
6049 12 : warning (OPT_Wattributes,
6050 : "%qE attribute argument %qE exceeds %u",
6051 : name, val, USHRT_MAX);
6052 12 : *no_add_attrs = true;
6053 12 : return NULL_TREE;
6054 : }
6055 : }
6056 : return NULL_TREE;
6057 : }
6058 :
6059 : /* Handle a "NSObject" attributes; arguments as in
6060 : struct attribute_spec.handler. */
6061 :
6062 : static tree
6063 0 : handle_nsobject_attribute (tree *node, tree name, tree args,
6064 : int /*flags*/, bool *no_add_attrs)
6065 : {
6066 0 : *no_add_attrs = true;
6067 :
6068 : /* This attribute only applies to typedefs (or field decls for properties),
6069 : we drop it otherwise - but warn about this if enabled. */
6070 0 : if (TREE_CODE (*node) != TYPE_DECL && TREE_CODE (*node) != FIELD_DECL)
6071 : {
6072 0 : warning (OPT_WNSObject_attribute, "%qE attribute may be put on a"
6073 : " typedef only; attribute is ignored", name);
6074 0 : return NULL_TREE;
6075 : }
6076 :
6077 : /* The original implementation only allowed pointers to records, however
6078 : recent implementations also allow void *. */
6079 0 : tree type = TREE_TYPE (*node);
6080 0 : if (!type || !POINTER_TYPE_P (type)
6081 0 : || (TREE_CODE (TREE_TYPE (type)) != RECORD_TYPE
6082 0 : && !VOID_TYPE_P (TREE_TYPE (type))))
6083 : {
6084 0 : error ("%qE attribute is for pointer types only", name);
6085 0 : return NULL_TREE;
6086 : }
6087 :
6088 0 : tree t = tree_cons (name, args, TYPE_ATTRIBUTES (type));
6089 0 : TREE_TYPE (*node) = build_type_attribute_variant (type, t);
6090 :
6091 0 : return NULL_TREE;
6092 : }
6093 :
6094 : /* Handle a "objc_root_class" attributes; arguments as in
6095 : struct attribute_spec.handler. */
6096 :
6097 : static tree
6098 0 : handle_objc_root_class_attribute (tree */*node*/, tree name, tree /*args*/,
6099 : int /*flags*/, bool *no_add_attrs)
6100 : {
6101 : /* This has no meaning outside Objective-C. */
6102 0 : if (!c_dialect_objc())
6103 0 : warning (OPT_Wattributes, "%qE is only applicable to Objective-C"
6104 : " class interfaces, attribute ignored", name);
6105 :
6106 0 : *no_add_attrs = true;
6107 0 : return NULL_TREE;
6108 : }
6109 :
6110 : /* Handle an "objc_nullability" attribute; arguments as in
6111 : struct attribute_spec.handler. */
6112 :
6113 : static tree
6114 0 : handle_objc_nullability_attribute (tree *node, tree name, tree args,
6115 : int /*flags*/,
6116 : bool *no_add_attrs)
6117 : {
6118 0 : *no_add_attrs = true;
6119 :
6120 0 : tree type = TREE_TYPE (*node);
6121 0 : if (TREE_CODE (*node) == FUNCTION_DECL)
6122 0 : type = TREE_TYPE (type);
6123 :
6124 0 : if (type && !POINTER_TYPE_P (type))
6125 : {
6126 0 : error ("%qE cannot be applied to non-pointer type %qT", name, type);
6127 0 : return NULL_TREE;
6128 : }
6129 :
6130 : /* We accept objc_nullability() with a single argument.
6131 : string: "unspecified", "nullable", "nonnull" or "resettable"
6132 : integer: 0 and 3 where the values have the same meaning as
6133 : the strings. */
6134 0 : tree val = TREE_VALUE (args);
6135 0 : if (TREE_CODE (val) == INTEGER_CST)
6136 : {
6137 0 : val = default_conversion (val);
6138 0 : if (!tree_fits_uhwi_p (val) || tree_to_uhwi (val) > 3)
6139 0 : error ("%qE attribute argument %qE is not an integer constant"
6140 : " between 0 and 3", name, val);
6141 : else
6142 0 : *no_add_attrs = false; /* OK */
6143 : }
6144 0 : else if (TREE_CODE (val) == STRING_CST
6145 0 : && (strcmp (TREE_STRING_POINTER (val), "nullable") == 0
6146 0 : || strcmp (TREE_STRING_POINTER (val), "nonnull") == 0
6147 0 : || strcmp (TREE_STRING_POINTER (val), "unspecified") == 0
6148 0 : || strcmp (TREE_STRING_POINTER (val), "resettable") == 0))
6149 0 : *no_add_attrs = false; /* OK */
6150 0 : else if (val != error_mark_node)
6151 0 : error ("%qE attribute argument %qE is not recognized", name, val);
6152 :
6153 : return NULL_TREE;
6154 : }
6155 :
6156 : /* Handle a "tainted_args" attribute; arguments as in
6157 : struct attribute_spec.handler. */
6158 :
6159 : static tree
6160 188 : handle_tainted_args_attribute (tree *node, tree name, tree, int,
6161 : bool *no_add_attrs)
6162 : {
6163 188 : if (TREE_CODE (*node) != FUNCTION_DECL
6164 14 : && TREE_CODE (*node) != FIELD_DECL)
6165 : {
6166 4 : warning (OPT_Wattributes, "%qE attribute ignored; valid only "
6167 : "for functions and function pointer fields",
6168 : name);
6169 4 : *no_add_attrs = true;
6170 4 : return NULL_TREE;
6171 : }
6172 :
6173 184 : if (TREE_CODE (*node) == FIELD_DECL
6174 184 : && !(TREE_CODE (TREE_TYPE (*node)) == POINTER_TYPE
6175 6 : && TREE_CODE (TREE_TYPE (TREE_TYPE (*node))) == FUNCTION_TYPE))
6176 : {
6177 4 : warning (OPT_Wattributes, "%qE attribute ignored;"
6178 : " field must be a function pointer",
6179 : name);
6180 4 : *no_add_attrs = true;
6181 4 : return NULL_TREE;
6182 : }
6183 :
6184 180 : *no_add_attrs = false; /* OK */
6185 :
6186 180 : return NULL_TREE;
6187 : }
6188 :
6189 : /* Attempt to partially validate a single attribute ATTR as if
6190 : it were to be applied to an entity OPER. */
6191 :
6192 : static bool
6193 2833 : validate_attribute (location_t atloc, tree oper, tree attr)
6194 : {
6195 : /* Determine whether the name of the attribute is valid
6196 : and fail with an error if not. */
6197 2833 : tree atname = get_attribute_name (attr);
6198 2833 : if (!lookup_attribute_spec (atname))
6199 : {
6200 8 : if (atloc != UNKNOWN_LOCATION)
6201 8 : error_at (atloc, "unknown attribute %qE", atname);
6202 : return false;
6203 : }
6204 :
6205 2825 : tree args = TREE_VALUE (attr);
6206 2825 : if (!args)
6207 : return true;
6208 :
6209 : /* FIXME: Do some validation. */
6210 1639 : const char *atstr = IDENTIFIER_POINTER (atname);
6211 1639 : if (!strcmp (atstr, "format"))
6212 : return true;
6213 :
6214 : /* Only when attribute arguments have been provided try to validate
6215 : the whole thing. decl_attributes doesn't return an indication of
6216 : success or failure so proceed regardless. */
6217 1631 : const char tmpname[] = "__builtin_has_attribute_tmp.";
6218 1631 : tree tmpid = get_identifier (tmpname);
6219 1631 : tree tmpdecl;
6220 1631 : if (!strcmp (atstr, "vector_size"))
6221 : {
6222 176 : tree type = TYPE_P (oper) ? oper : TREE_TYPE (oper);
6223 : /* Check for function type here since type_for_vector_size
6224 : strips it while looking for a function's return type. */
6225 176 : if (FUNC_OR_METHOD_TYPE_P (type))
6226 : {
6227 0 : warning_at (atloc, OPT_Wattributes,
6228 : "invalid operand type %qT for %qs", type, atstr);
6229 0 : return false;
6230 : }
6231 :
6232 176 : type = type_for_vector_size (type);
6233 176 : if (VECTOR_TYPE_P (type))
6234 164 : type = TREE_TYPE (type);
6235 : /* Avoid trying to apply attribute vector_size to OPER since
6236 : it's overly restrictive. Simply make sure it has the right
6237 : type. */
6238 176 : return type_valid_for_vector_size (type, atname, args, NULL);
6239 : }
6240 :
6241 1455 : if (TYPE_P (oper))
6242 308 : tmpdecl = build_decl (atloc, TYPE_DECL, tmpid, oper);
6243 1147 : else if (DECL_P (oper))
6244 564 : tmpdecl = build_decl (atloc, TREE_CODE (oper), tmpid, TREE_TYPE (oper));
6245 583 : else if (EXPR_P (oper))
6246 583 : tmpdecl = build_decl (atloc, TYPE_DECL, tmpid, TREE_TYPE (oper));
6247 : else
6248 : return false;
6249 :
6250 : /* Temporarily clear CURRENT_FUNCTION_DECL to make decl_attributes
6251 : believe the DECL declared above is at file scope. (See bug 87526.) */
6252 1455 : tree save_curfunc = current_function_decl;
6253 1455 : current_function_decl = NULL_TREE;
6254 1455 : if (DECL_P (tmpdecl))
6255 : {
6256 1455 : if (DECL_P (oper))
6257 : /* An alias cannot be a definition so declare the symbol extern. */
6258 564 : DECL_EXTERNAL (tmpdecl) = true;
6259 : /* Attribute visibility only applies to symbols visible from other
6260 : translation units so make it "public." */
6261 1455 : TREE_PUBLIC (tmpdecl) = TREE_PUBLIC (oper);
6262 : }
6263 1455 : decl_attributes (&tmpdecl, attr, 0);
6264 1455 : current_function_decl = save_curfunc;
6265 :
6266 : /* FIXME: Change decl_attributes to indicate success or failure (and
6267 : parameterize it to avoid failing with errors). */
6268 1455 : return true;
6269 : }
6270 :
6271 : /* Return true if the DECL, EXPR, or TYPE t has been declared with
6272 : attribute ATTR. For DECL, consider also its type. For EXPR,
6273 : consider just its type. */
6274 :
6275 : bool
6276 2834 : has_attribute (location_t atloc, tree t, tree attr, tree (*convert)(tree))
6277 : {
6278 2834 : if (!attr || !t || t == error_mark_node)
6279 : return false;
6280 :
6281 2833 : if (!validate_attribute (atloc, t, attr))
6282 : return false;
6283 :
6284 2773 : tree type = NULL_TREE;
6285 2773 : tree expr = NULL_TREE;
6286 2773 : if (TYPE_P (t))
6287 : type = t;
6288 : else
6289 : {
6290 2403 : do
6291 : {
6292 : /* Determine the array element/member declaration from
6293 : a COMPONENT_REF and an INDIRECT_REF involving a refeence. */
6294 2403 : STRIP_NOPS (t);
6295 2403 : tree_code code = TREE_CODE (t);
6296 2403 : if (code == INDIRECT_REF)
6297 : {
6298 439 : tree op0 = TREE_OPERAND (t, 0);
6299 439 : if (TREE_CODE (TREE_TYPE (op0)) == REFERENCE_TYPE)
6300 : t = op0;
6301 : else
6302 : break;
6303 : }
6304 1964 : else if (code == COMPONENT_REF)
6305 160 : t = TREE_OPERAND (t, 1);
6306 : else
6307 : break;
6308 : } while (true);
6309 : expr = t;
6310 : }
6311 :
6312 : /* Set to true when an attribute is found in the referenced entity
6313 : that matches the specified attribute. */
6314 2773 : bool found_match = false;
6315 :
6316 2773 : tree atname = get_attribute_name (attr);
6317 2773 : const char *namestr = IDENTIFIER_POINTER (atname);
6318 :
6319 : /* Iterate once for a type and twice for a function or variable
6320 : declaration: once for the DECL and the second time for its
6321 : TYPE. */
6322 5472 : for (bool done = false; !found_match && !done; )
6323 : {
6324 3542 : tree atlist;
6325 3542 : if (type)
6326 : {
6327 1317 : if (type == error_mark_node)
6328 : {
6329 : /* This could be a label. FIXME: add support for labels. */
6330 0 : warning_at (atloc, OPT_Wattributes,
6331 0 : (TYPE_P (t)
6332 : ? G_("%qs attribute not supported for %qT "
6333 : "in %<__builtin_has_attribute%>")
6334 : : G_("%qs attribute not supported for %qE "
6335 : "in %<__builtin_has_attribute%>")),
6336 : namestr, t);
6337 0 : return false;
6338 : }
6339 :
6340 : /* Clear EXPR to prevent considering it again below. */
6341 1317 : atlist = TYPE_ATTRIBUTES (type);
6342 1317 : expr = NULL_TREE;
6343 1317 : done = true;
6344 : }
6345 2225 : else if (DECL_P (expr))
6346 : {
6347 : /* Set TYPE to the DECL's type to process it on the next
6348 : iteration. */
6349 1306 : atlist = DECL_ATTRIBUTES (expr);
6350 1306 : type = TREE_TYPE (expr);
6351 : }
6352 : else
6353 : {
6354 919 : type = TREE_TYPE (expr);
6355 919 : atlist = TYPE_ATTRIBUTES (type);
6356 919 : done = true;
6357 : }
6358 :
6359 : /* True when an attribute with the sought name (though not necessarily
6360 : with the sought attributes) has been found on the attribute chain. */
6361 3542 : bool found_attr = false;
6362 :
6363 : /* When clear, the first mismatched attribute argument results
6364 : in failure. Otherwise, the first matched attribute argument
6365 : results in success. */
6366 3542 : bool attr_nonnull = !strcmp ("nonnull", namestr);
6367 3542 : bool ignore_mismatches = attr_nonnull;
6368 :
6369 : /* Iterate over the instances of the sought attribute on the DECL or
6370 : TYPE (there may be multiple instances with different arguments). */
6371 3895 : for (; (atlist = lookup_attribute (namestr, atlist));
6372 353 : found_attr = true, atlist = TREE_CHAIN (atlist))
6373 : {
6374 : /* If there are no arguments to match the result is true except
6375 : for nonnull where the attribute with no arguments must match. */
6376 992 : if (!TREE_VALUE (attr))
6377 449 : return attr_nonnull ? !TREE_VALUE (atlist) : true;
6378 :
6379 : /* Attribute nonnull with no arguments subsumes all values of
6380 : the attribute. FIXME: This is overly broad since it only
6381 : applies to pointer arguments, but querying non-pointer
6382 : arguments is diagnosed. */
6383 551 : if (!TREE_VALUE (atlist) && attr_nonnull)
6384 : return true;
6385 :
6386 : /* Iterate over the DECL or TYPE attribute argument's values. */
6387 871 : for (tree val = TREE_VALUE (atlist); val; val = TREE_CHAIN (val))
6388 : {
6389 : /* Iterate over the arguments in the sought attribute comparing
6390 : their values to those specified for the DECL or TYPE. */
6391 538 : for (tree arg = TREE_VALUE (attr); arg; arg = TREE_CHAIN (arg))
6392 : {
6393 518 : tree v1 = TREE_VALUE (val);
6394 518 : tree v2 = TREE_VALUE (arg);
6395 518 : if (v1 == v2)
6396 : return true;
6397 :
6398 394 : if (!v1 || !v2)
6399 : break;
6400 :
6401 394 : if (TREE_CODE (v1) == IDENTIFIER_NODE
6402 390 : || TREE_CODE (v2) == IDENTIFIER_NODE)
6403 : /* Two identifiers are the same if their values are
6404 : equal (that's handled above). Otherwise they are
6405 : either not the same or oneis not an identifier. */
6406 : return false;
6407 :
6408 : /* Convert to make them equality-comparable. */
6409 390 : v1 = convert (v1);
6410 390 : v2 = convert (v2);
6411 :
6412 : /* A positive value indicates equality, negative means
6413 : "don't know." */
6414 390 : if (simple_cst_equal (v1, v2) == 1)
6415 : return true;
6416 :
6417 332 : if (!ignore_mismatches)
6418 : break;
6419 : }
6420 : }
6421 : }
6422 :
6423 2903 : if (!found_attr)
6424 : {
6425 : /* Some attributes are encoded directly in the tree node. */
6426 2572 : if (!strcmp ("aligned", namestr))
6427 : {
6428 1344 : if (tree arg = TREE_VALUE (attr))
6429 : {
6430 996 : arg = convert (TREE_VALUE (arg));
6431 996 : if (!tree_fits_uhwi_p (arg))
6432 : /* Invalid argument. */;
6433 624 : else if (expr && DECL_P (expr)
6434 1048 : && DECL_USER_ALIGN (expr))
6435 0 : found_match = DECL_ALIGN_UNIT (expr) == tree_to_uhwi (arg);
6436 992 : else if (type && TYPE_USER_ALIGN (type))
6437 608 : found_match = TYPE_ALIGN_UNIT (type) == tree_to_uhwi (arg);
6438 : }
6439 348 : else if (expr && DECL_P (expr))
6440 14 : found_match = DECL_USER_ALIGN (expr);
6441 334 : else if (type)
6442 334 : found_match = TYPE_USER_ALIGN (type);
6443 : }
6444 1228 : else if (!strcmp ("const", namestr))
6445 : {
6446 24 : if (expr && DECL_P (expr))
6447 12 : found_match = TREE_READONLY (expr);
6448 : }
6449 1204 : else if (!strcmp ("noreturn", namestr))
6450 : {
6451 : /* C11 _Noreturn sets the volatile bit without attaching
6452 : an attribute to the decl. */
6453 9 : if (expr
6454 1 : && DECL_P (expr)
6455 10 : && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (expr)))
6456 1 : found_match = TREE_THIS_VOLATILE (expr);
6457 : }
6458 1195 : else if (!strcmp ("pure", namestr))
6459 : {
6460 24 : if (expr && DECL_P (expr))
6461 12 : found_match = DECL_PURE_P (expr);
6462 : }
6463 1171 : else if (!strcmp ("deprecated", namestr))
6464 : {
6465 0 : found_match = TREE_DEPRECATED (expr ? expr : type);
6466 0 : if (found_match)
6467 : return true;
6468 : }
6469 1171 : else if (!strcmp ("vector_size", namestr))
6470 : {
6471 200 : if (!type || !VECTOR_TYPE_P (type))
6472 : return false;
6473 :
6474 120 : if (tree arg = TREE_VALUE (attr))
6475 : {
6476 : /* Compare the vector size argument for equality. */
6477 88 : arg = convert (TREE_VALUE (arg));
6478 88 : return tree_int_cst_equal (arg, TYPE_SIZE_UNIT (type)) == 1;
6479 : }
6480 : else
6481 : return true;
6482 : }
6483 971 : else if (!strcmp ("warn_if_not_aligned", namestr))
6484 : {
6485 24 : if (tree arg = TREE_VALUE (attr))
6486 : {
6487 24 : arg = convert (TREE_VALUE (arg));
6488 24 : if (expr && DECL_P (expr))
6489 0 : found_match = (DECL_WARN_IF_NOT_ALIGN (expr)
6490 0 : == tree_to_uhwi (arg) * BITS_PER_UNIT);
6491 24 : else if (type)
6492 24 : found_match = (TYPE_WARN_IF_NOT_ALIGN (type)
6493 24 : == tree_to_uhwi (arg) * BITS_PER_UNIT);
6494 : }
6495 0 : else if (expr && DECL_P (expr))
6496 0 : found_match = DECL_WARN_IF_NOT_ALIGN (expr);
6497 0 : else if (type)
6498 0 : found_match = TYPE_WARN_IF_NOT_ALIGN (type);
6499 : }
6500 947 : else if (!strcmp ("transparent_union", namestr))
6501 : {
6502 20 : if (type)
6503 20 : found_match = TYPE_TRANSPARENT_AGGR (type) != 0;
6504 : }
6505 927 : else if (!strcmp ("mode", namestr))
6506 : {
6507 : /* Finally issue a warning for attributes that cannot
6508 : be supported in this context. Attribute mode is not
6509 : added to a symbol and cannot be determined from it. */
6510 4 : warning_at (atloc, OPT_Wattributes,
6511 : "%qs attribute not supported in "
6512 : "%<__builtin_has_attribute%>", namestr);
6513 4 : break;
6514 : }
6515 : }
6516 : }
6517 : return found_match;
6518 : }
|