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