PR rtl-optimization/88470
[official-gcc.git] / gcc / c-family / c-attribs.c
blob1454e2f3640945641487b65c3fdea7162d6067a5
1 /* C-family attributes handling.
2 Copyright (C) 1992-2018 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "target.h"
24 #include "function.h"
25 #include "tree.h"
26 #include "memmodel.h"
27 #include "c-common.h"
28 #include "gimple-expr.h"
29 #include "tm_p.h"
30 #include "stringpool.h"
31 #include "cgraph.h"
32 #include "diagnostic.h"
33 #include "intl.h"
34 #include "stor-layout.h"
35 #include "calls.h"
36 #include "attribs.h"
37 #include "varasm.h"
38 #include "trans-mem.h"
39 #include "c-objc.h"
40 #include "common/common-target.h"
41 #include "langhooks.h"
42 #include "tree-inline.h"
43 #include "toplev.h"
44 #include "tree-iterator.h"
45 #include "opts.h"
46 #include "gimplify.h"
47 #include "tree-pretty-print.h"
49 static tree handle_packed_attribute (tree *, tree, tree, int, bool *);
50 static tree handle_nocommon_attribute (tree *, tree, tree, int, bool *);
51 static tree handle_common_attribute (tree *, tree, tree, int, bool *);
52 static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
53 static tree handle_hot_attribute (tree *, tree, tree, int, bool *);
54 static tree handle_cold_attribute (tree *, tree, tree, int, bool *);
55 static tree handle_no_sanitize_attribute (tree *, tree, tree, int, bool *);
56 static tree handle_no_sanitize_address_attribute (tree *, tree, tree,
57 int, bool *);
58 static tree handle_no_sanitize_thread_attribute (tree *, tree, tree,
59 int, bool *);
60 static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree,
61 int, bool *);
62 static tree handle_no_sanitize_undefined_attribute (tree *, tree, tree, int,
63 bool *);
64 static tree handle_asan_odr_indicator_attribute (tree *, tree, tree, int,
65 bool *);
66 static tree handle_stack_protect_attribute (tree *, tree, tree, int, bool *);
67 static tree handle_noinline_attribute (tree *, tree, tree, int, bool *);
68 static tree handle_noclone_attribute (tree *, tree, tree, int, bool *);
69 static tree handle_nocf_check_attribute (tree *, tree, tree, int, bool *);
70 static tree handle_noicf_attribute (tree *, tree, tree, int, bool *);
71 static tree handle_noipa_attribute (tree *, tree, tree, int, bool *);
72 static tree handle_leaf_attribute (tree *, tree, tree, int, bool *);
73 static tree handle_always_inline_attribute (tree *, tree, tree, int,
74 bool *);
75 static tree handle_gnu_inline_attribute (tree *, tree, tree, int, bool *);
76 static tree handle_artificial_attribute (tree *, tree, tree, int, bool *);
77 static tree handle_flatten_attribute (tree *, tree, tree, int, bool *);
78 static tree handle_error_attribute (tree *, tree, tree, int, bool *);
79 static tree handle_used_attribute (tree *, tree, tree, int, bool *);
80 static tree handle_externally_visible_attribute (tree *, tree, tree, int,
81 bool *);
82 static tree handle_no_reorder_attribute (tree *, tree, tree, int,
83 bool *);
84 static tree handle_const_attribute (tree *, tree, tree, int, bool *);
85 static tree handle_transparent_union_attribute (tree *, tree, tree,
86 int, bool *);
87 static tree handle_scalar_storage_order_attribute (tree *, tree, tree,
88 int, bool *);
89 static tree handle_constructor_attribute (tree *, tree, tree, int, bool *);
90 static tree handle_destructor_attribute (tree *, tree, tree, int, bool *);
91 static tree handle_mode_attribute (tree *, tree, tree, int, bool *);
92 static tree handle_section_attribute (tree *, tree, tree, int, bool *);
93 static tree handle_aligned_attribute (tree *, tree, tree, int, bool *);
94 static tree handle_warn_if_not_aligned_attribute (tree *, tree, tree,
95 int, bool *);
96 static tree handle_weak_attribute (tree *, tree, tree, int, bool *) ;
97 static tree handle_noplt_attribute (tree *, tree, tree, int, bool *) ;
98 static tree handle_alias_ifunc_attribute (bool, tree *, tree, tree, bool *);
99 static tree handle_ifunc_attribute (tree *, tree, tree, int, bool *);
100 static tree handle_alias_attribute (tree *, tree, tree, int, bool *);
101 static tree handle_weakref_attribute (tree *, tree, tree, int, bool *) ;
102 static tree handle_visibility_attribute (tree *, tree, tree, int,
103 bool *);
104 static tree handle_tls_model_attribute (tree *, tree, tree, int,
105 bool *);
106 static tree handle_no_instrument_function_attribute (tree *, tree,
107 tree, int, bool *);
108 static tree handle_no_profile_instrument_function_attribute (tree *, tree,
109 tree, int, bool *);
110 static tree handle_malloc_attribute (tree *, tree, tree, int, bool *);
111 static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *);
112 static tree handle_no_limit_stack_attribute (tree *, tree, tree, int,
113 bool *);
114 static tree handle_pure_attribute (tree *, tree, tree, int, bool *);
115 static tree handle_tm_attribute (tree *, tree, tree, int, bool *);
116 static tree handle_tm_wrap_attribute (tree *, tree, tree, int, bool *);
117 static tree handle_novops_attribute (tree *, tree, tree, int, bool *);
118 static tree handle_deprecated_attribute (tree *, tree, tree, int,
119 bool *);
120 static tree handle_vector_size_attribute (tree *, tree, tree, int,
121 bool *);
122 static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
123 static tree handle_nonstring_attribute (tree *, tree, tree, int, bool *);
124 static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *);
125 static tree handle_cleanup_attribute (tree *, tree, tree, int, bool *);
126 static tree handle_warn_unused_result_attribute (tree *, tree, tree, int,
127 bool *);
128 static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *);
129 static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
130 static tree handle_alloc_size_attribute (tree *, tree, tree, int, bool *);
131 static tree handle_alloc_align_attribute (tree *, tree, tree, int, bool *);
132 static tree handle_assume_aligned_attribute (tree *, tree, tree, int, bool *);
133 static tree handle_target_attribute (tree *, tree, tree, int, bool *);
134 static tree handle_target_clones_attribute (tree *, tree, tree, int, bool *);
135 static tree handle_optimize_attribute (tree *, tree, tree, int, bool *);
136 static tree ignore_attribute (tree *, tree, tree, int, bool *);
137 static tree handle_no_split_stack_attribute (tree *, tree, tree, int, bool *);
138 static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *);
139 static tree handle_warn_unused_attribute (tree *, tree, tree, int, bool *);
140 static tree handle_returns_nonnull_attribute (tree *, tree, tree, int, bool *);
141 static tree handle_omp_declare_simd_attribute (tree *, tree, tree, int,
142 bool *);
143 static tree handle_simd_attribute (tree *, tree, tree, int, bool *);
144 static tree handle_omp_declare_target_attribute (tree *, tree, tree, int,
145 bool *);
146 static tree handle_designated_init_attribute (tree *, tree, tree, int, bool *);
147 static tree handle_fallthrough_attribute (tree *, tree, tree, int, bool *);
148 static tree handle_patchable_function_entry_attribute (tree *, tree, tree,
149 int, bool *);
150 static tree handle_copy_attribute (tree *, tree, tree, int, bool *);
152 /* Helper to define attribute exclusions. */
153 #define ATTR_EXCL(name, function, type, variable) \
154 { name, function, type, variable }
156 /* Define attributes that are mutually exclusive with one another. */
157 static const struct attribute_spec::exclusions attr_aligned_exclusions[] =
159 /* Attribute name exclusion applies to:
160 function, type, variable */
161 ATTR_EXCL ("aligned", true, false, false),
162 ATTR_EXCL ("packed", true, false, false),
163 ATTR_EXCL (NULL, false, false, false)
166 extern const struct attribute_spec::exclusions attr_cold_hot_exclusions[] =
168 ATTR_EXCL ("cold", true, true, true),
169 ATTR_EXCL ("hot", true, true, true),
170 ATTR_EXCL (NULL, false, false, false)
173 static const struct attribute_spec::exclusions attr_common_exclusions[] =
175 ATTR_EXCL ("common", true, true, true),
176 ATTR_EXCL ("nocommon", true, true, true),
177 ATTR_EXCL (NULL, false, false, false),
180 static const struct attribute_spec::exclusions attr_inline_exclusions[] =
182 ATTR_EXCL ("noinline", true, true, true),
183 ATTR_EXCL (NULL, false, false, false),
186 static const struct attribute_spec::exclusions attr_noinline_exclusions[] =
188 ATTR_EXCL ("always_inline", true, true, true),
189 ATTR_EXCL ("gnu_inline", true, true, true),
190 ATTR_EXCL (NULL, false, false, false),
193 static const struct attribute_spec::exclusions attr_noreturn_exclusions[] =
195 ATTR_EXCL ("alloc_align", true, true, true),
196 ATTR_EXCL ("alloc_size", true, true, true),
197 ATTR_EXCL ("const", true, true, true),
198 ATTR_EXCL ("malloc", true, true, true),
199 ATTR_EXCL ("pure", true, true, true),
200 ATTR_EXCL ("returns_twice", true, true, true),
201 ATTR_EXCL ("warn_unused_result", true, true, true),
202 ATTR_EXCL (NULL, false, false, false),
205 static const struct attribute_spec::exclusions
206 attr_warn_unused_result_exclusions[] =
208 ATTR_EXCL ("noreturn", true, true, true),
209 ATTR_EXCL ("warn_unused_result", true, true, true),
210 ATTR_EXCL (NULL, false, false, false),
213 static const struct attribute_spec::exclusions attr_returns_twice_exclusions[] =
215 ATTR_EXCL ("noreturn", true, true, true),
216 ATTR_EXCL (NULL, false, false, false),
219 /* Exclusions that apply to attribute alloc_align, alloc_size, and malloc. */
220 static const struct attribute_spec::exclusions attr_alloc_exclusions[] =
222 ATTR_EXCL ("const", true, true, true),
223 ATTR_EXCL ("noreturn", true, true, true),
224 ATTR_EXCL ("pure", true, true, true),
225 ATTR_EXCL (NULL, false, false, false),
228 static const struct attribute_spec::exclusions attr_const_pure_exclusions[] =
230 ATTR_EXCL ("const", true, true, true),
231 ATTR_EXCL ("alloc_align", true, true, true),
232 ATTR_EXCL ("alloc_size", true, true, true),
233 ATTR_EXCL ("malloc", true, true, true),
234 ATTR_EXCL ("noreturn", true, true, true),
235 ATTR_EXCL ("pure", true, true, true),
236 ATTR_EXCL (NULL, false, false, false)
239 /* Table of machine-independent attributes common to all C-like languages.
241 Current list of processed common attributes: nonnull. */
242 const struct attribute_spec c_common_attribute_table[] =
244 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
245 affects_type_identity, handler, exclude } */
246 { "packed", 0, 0, false, false, false, false,
247 handle_packed_attribute,
248 attr_aligned_exclusions },
249 { "nocommon", 0, 0, true, false, false, false,
250 handle_nocommon_attribute,
251 attr_common_exclusions },
252 { "common", 0, 0, true, false, false, false,
253 handle_common_attribute,
254 attr_common_exclusions },
255 /* FIXME: logically, noreturn attributes should be listed as
256 "false, true, true" and apply to function types. But implementing this
257 would require all the places in the compiler that use TREE_THIS_VOLATILE
258 on a decl to identify non-returning functions to be located and fixed
259 to check the function type instead. */
260 { "noreturn", 0, 0, true, false, false, false,
261 handle_noreturn_attribute,
262 attr_noreturn_exclusions },
263 { "volatile", 0, 0, true, false, false, false,
264 handle_noreturn_attribute, NULL },
265 { "stack_protect", 0, 0, true, false, false, false,
266 handle_stack_protect_attribute, NULL },
267 { "noinline", 0, 0, true, false, false, false,
268 handle_noinline_attribute,
269 attr_noinline_exclusions },
270 { "noclone", 0, 0, true, false, false, false,
271 handle_noclone_attribute, NULL },
272 { "no_icf", 0, 0, true, false, false, false,
273 handle_noicf_attribute, NULL },
274 { "noipa", 0, 0, true, false, false, false,
275 handle_noipa_attribute, NULL },
276 { "leaf", 0, 0, true, false, false, false,
277 handle_leaf_attribute, NULL },
278 { "always_inline", 0, 0, true, false, false, false,
279 handle_always_inline_attribute,
280 attr_inline_exclusions },
281 { "gnu_inline", 0, 0, true, false, false, false,
282 handle_gnu_inline_attribute,
283 attr_inline_exclusions },
284 { "artificial", 0, 0, true, false, false, false,
285 handle_artificial_attribute, NULL },
286 { "flatten", 0, 0, true, false, false, false,
287 handle_flatten_attribute, NULL },
288 { "used", 0, 0, true, false, false, false,
289 handle_used_attribute, NULL },
290 { "unused", 0, 0, false, false, false, false,
291 handle_unused_attribute, NULL },
292 { "externally_visible", 0, 0, true, false, false, false,
293 handle_externally_visible_attribute, NULL },
294 { "no_reorder", 0, 0, true, false, false, false,
295 handle_no_reorder_attribute, NULL },
296 /* The same comments as for noreturn attributes apply to const ones. */
297 { "const", 0, 0, true, false, false, false,
298 handle_const_attribute,
299 attr_const_pure_exclusions },
300 { "scalar_storage_order", 1, 1, false, false, false, false,
301 handle_scalar_storage_order_attribute, NULL },
302 { "transparent_union", 0, 0, false, false, false, false,
303 handle_transparent_union_attribute, NULL },
304 { "constructor", 0, 1, true, false, false, false,
305 handle_constructor_attribute, NULL },
306 { "destructor", 0, 1, true, false, false, false,
307 handle_destructor_attribute, NULL },
308 { "mode", 1, 1, false, true, false, false,
309 handle_mode_attribute, NULL },
310 { "section", 1, 1, true, false, false, false,
311 handle_section_attribute, NULL },
312 { "aligned", 0, 1, false, false, false, false,
313 handle_aligned_attribute,
314 attr_aligned_exclusions },
315 { "warn_if_not_aligned", 0, 1, false, false, false, false,
316 handle_warn_if_not_aligned_attribute, NULL },
317 { "weak", 0, 0, true, false, false, false,
318 handle_weak_attribute, NULL },
319 { "noplt", 0, 0, true, false, false, false,
320 handle_noplt_attribute, NULL },
321 { "ifunc", 1, 1, true, false, false, false,
322 handle_ifunc_attribute, NULL },
323 { "alias", 1, 1, true, false, false, false,
324 handle_alias_attribute, NULL },
325 { "weakref", 0, 1, true, false, false, false,
326 handle_weakref_attribute, NULL },
327 { "no_instrument_function", 0, 0, true, false, false, false,
328 handle_no_instrument_function_attribute,
329 NULL },
330 { "no_profile_instrument_function", 0, 0, true, false, false, false,
331 handle_no_profile_instrument_function_attribute,
332 NULL },
333 { "malloc", 0, 0, true, false, false, false,
334 handle_malloc_attribute, attr_alloc_exclusions },
335 { "returns_twice", 0, 0, true, false, false, false,
336 handle_returns_twice_attribute,
337 attr_returns_twice_exclusions },
338 { "no_stack_limit", 0, 0, true, false, false, false,
339 handle_no_limit_stack_attribute, NULL },
340 { "pure", 0, 0, true, false, false, false,
341 handle_pure_attribute,
342 attr_const_pure_exclusions },
343 { "transaction_callable", 0, 0, false, true, false, false,
344 handle_tm_attribute, NULL },
345 { "transaction_unsafe", 0, 0, false, true, false, true,
346 handle_tm_attribute, NULL },
347 { "transaction_safe", 0, 0, false, true, false, true,
348 handle_tm_attribute, NULL },
349 { "transaction_safe_dynamic", 0, 0, true, false, false, false,
350 handle_tm_attribute, NULL },
351 { "transaction_may_cancel_outer", 0, 0, false, true, false, false,
352 handle_tm_attribute, NULL },
353 /* ??? These two attributes didn't make the transition from the
354 Intel language document to the multi-vendor language document. */
355 { "transaction_pure", 0, 0, false, true, false, false,
356 handle_tm_attribute, NULL },
357 { "transaction_wrap", 1, 1, true, false, false, false,
358 handle_tm_wrap_attribute, NULL },
359 /* For internal use (marking of builtins) only. The name contains space
360 to prevent its usage in source code. */
361 { "no vops", 0, 0, true, false, false, false,
362 handle_novops_attribute, NULL },
363 { "deprecated", 0, 1, false, false, false, false,
364 handle_deprecated_attribute, NULL },
365 { "vector_size", 1, 1, false, true, false, true,
366 handle_vector_size_attribute, NULL },
367 { "visibility", 1, 1, false, false, false, false,
368 handle_visibility_attribute, NULL },
369 { "tls_model", 1, 1, true, false, false, false,
370 handle_tls_model_attribute, NULL },
371 { "nonnull", 0, -1, false, true, true, false,
372 handle_nonnull_attribute, NULL },
373 { "nonstring", 0, 0, true, false, false, false,
374 handle_nonstring_attribute, NULL },
375 { "nothrow", 0, 0, true, false, false, false,
376 handle_nothrow_attribute, NULL },
377 { "may_alias", 0, 0, false, true, false, false, NULL, NULL },
378 { "cleanup", 1, 1, true, false, false, false,
379 handle_cleanup_attribute, NULL },
380 { "warn_unused_result", 0, 0, false, true, true, false,
381 handle_warn_unused_result_attribute,
382 attr_warn_unused_result_exclusions },
383 { "sentinel", 0, 1, false, true, true, false,
384 handle_sentinel_attribute, NULL },
385 /* For internal use (marking of builtins) only. The name contains space
386 to prevent its usage in source code. */
387 { "type generic", 0, 0, false, true, true, false,
388 handle_type_generic_attribute, NULL },
389 { "alloc_size", 1, 2, false, true, true, false,
390 handle_alloc_size_attribute,
391 attr_alloc_exclusions },
392 { "cold", 0, 0, true, false, false, false,
393 handle_cold_attribute,
394 attr_cold_hot_exclusions },
395 { "hot", 0, 0, true, false, false, false,
396 handle_hot_attribute,
397 attr_cold_hot_exclusions },
398 { "no_address_safety_analysis",
399 0, 0, true, false, false, false,
400 handle_no_address_safety_analysis_attribute,
401 NULL },
402 { "no_sanitize", 1, -1, true, false, false, false,
403 handle_no_sanitize_attribute, NULL },
404 { "no_sanitize_address", 0, 0, true, false, false, false,
405 handle_no_sanitize_address_attribute, NULL },
406 { "no_sanitize_thread", 0, 0, true, false, false, false,
407 handle_no_sanitize_thread_attribute, NULL },
408 { "no_sanitize_undefined", 0, 0, true, false, false, false,
409 handle_no_sanitize_undefined_attribute, NULL },
410 { "asan odr indicator", 0, 0, true, false, false, false,
411 handle_asan_odr_indicator_attribute, NULL },
412 { "warning", 1, 1, true, false, false, false,
413 handle_error_attribute, NULL },
414 { "error", 1, 1, true, false, false, false,
415 handle_error_attribute, NULL },
416 { "target", 1, -1, true, false, false, false,
417 handle_target_attribute, NULL },
418 { "target_clones", 1, -1, true, false, false, false,
419 handle_target_clones_attribute, NULL },
420 { "optimize", 1, -1, true, false, false, false,
421 handle_optimize_attribute, NULL },
422 /* For internal use only. The leading '*' both prevents its usage in
423 source code and signals that it may be overridden by machine tables. */
424 { "*tm regparm", 0, 0, false, true, true, false,
425 ignore_attribute, NULL },
426 { "no_split_stack", 0, 0, true, false, false, false,
427 handle_no_split_stack_attribute, NULL },
428 /* For internal use (marking of builtins and runtime functions) only.
429 The name contains space to prevent its usage in source code. */
430 { "fn spec", 1, 1, false, true, true, false,
431 handle_fnspec_attribute, NULL },
432 { "warn_unused", 0, 0, false, false, false, false,
433 handle_warn_unused_attribute, NULL },
434 { "returns_nonnull", 0, 0, false, true, true, false,
435 handle_returns_nonnull_attribute, NULL },
436 { "omp declare simd", 0, -1, true, false, false, false,
437 handle_omp_declare_simd_attribute, NULL },
438 { "simd", 0, 1, true, false, false, false,
439 handle_simd_attribute, NULL },
440 { "omp declare target", 0, 0, true, false, false, false,
441 handle_omp_declare_target_attribute, NULL },
442 { "omp declare target link", 0, 0, true, false, false, false,
443 handle_omp_declare_target_attribute, NULL },
444 { "omp declare target implicit", 0, 0, true, false, false, false,
445 handle_omp_declare_target_attribute, NULL },
446 { "alloc_align", 1, 1, false, true, true, false,
447 handle_alloc_align_attribute,
448 attr_alloc_exclusions },
449 { "assume_aligned", 1, 2, false, true, true, false,
450 handle_assume_aligned_attribute, NULL },
451 { "designated_init", 0, 0, false, true, false, false,
452 handle_designated_init_attribute, NULL },
453 { "fallthrough", 0, 0, false, false, false, false,
454 handle_fallthrough_attribute, NULL },
455 { "patchable_function_entry", 1, 2, true, false, false, false,
456 handle_patchable_function_entry_attribute,
457 NULL },
458 { "nocf_check", 0, 0, false, true, true, true,
459 handle_nocf_check_attribute, NULL },
460 { "copy", 1, 1, false, false, false, false,
461 handle_copy_attribute, NULL },
462 { NULL, 0, 0, false, false, false, false, NULL, NULL }
465 /* Give the specifications for the format attributes, used by C and all
466 descendants.
468 Current list of processed format attributes: format, format_arg. */
469 const struct attribute_spec c_common_format_attribute_table[] =
471 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
472 affects_type_identity, handler, exclude } */
473 { "format", 3, 3, false, true, true, false,
474 handle_format_attribute, NULL },
475 { "format_arg", 1, 1, false, true, true, false,
476 handle_format_arg_attribute, NULL },
477 { NULL, 0, 0, false, false, false, false, NULL, NULL }
480 /* Returns TRUE iff the attribute indicated by ATTR_ID takes a plain
481 identifier as an argument, so the front end shouldn't look it up. */
483 bool
484 attribute_takes_identifier_p (const_tree attr_id)
486 const struct attribute_spec *spec = lookup_attribute_spec (attr_id);
487 if (spec == NULL)
488 /* Unknown attribute that we'll end up ignoring, return true so we
489 don't complain about an identifier argument. */
490 return true;
491 else if (!strcmp ("mode", spec->name)
492 || !strcmp ("format", spec->name)
493 || !strcmp ("cleanup", spec->name))
494 return true;
495 else
496 return targetm.attribute_takes_identifier_p (attr_id);
499 /* Verify that argument value POS at position ARGNO to attribute NAME
500 applied to function TYPE refers to a function parameter at position
501 POS and the expected type CODE. If so, return POS after default
502 conversions, if any. Otherwise, issue appropriate warnings and
503 return null. A non-zero 1-based ARGNO should be passed ib by
504 callers only for attributes with more than one argument. */
506 tree
507 positional_argument (const_tree fntype, const_tree atname, tree pos,
508 tree_code code, int argno /* = 0 */,
509 int flags /* = posargflags () */)
511 if (pos && TREE_CODE (pos) != IDENTIFIER_NODE
512 && TREE_CODE (pos) != FUNCTION_DECL)
513 pos = default_conversion (pos);
515 tree postype = TREE_TYPE (pos);
516 if (pos == error_mark_node || !postype)
518 /* Only mention the positional argument number when it's non-zero. */
519 if (argno < 1)
520 warning (OPT_Wattributes,
521 "%qE attribute argument is invalid", atname);
522 else
523 warning (OPT_Wattributes,
524 "%qE attribute argument %i is invalid", atname, argno);
526 return NULL_TREE;
529 if (!INTEGRAL_TYPE_P (postype))
531 /* Handle this case specially to avoid mentioning the value
532 of pointer constants in diagnostics. Only mention
533 the positional argument number when it's non-zero. */
534 if (argno < 1)
535 warning (OPT_Wattributes,
536 "%qE attribute argument has type %qT",
537 atname, postype);
538 else
539 warning (OPT_Wattributes,
540 "%qE attribute argument %i has type %qT",
541 atname, argno, postype);
543 return NULL_TREE;
546 if (TREE_CODE (pos) != INTEGER_CST)
548 /* Only mention the argument number when it's non-zero. */
549 if (argno < 1)
550 warning (OPT_Wattributes,
551 "%qE attribute argument value %qE is not an integer "
552 "constant",
553 atname, pos);
554 else
555 warning (OPT_Wattributes,
556 "%qE attribute argument %i value %qE is not an integer "
557 "constant",
558 atname, argno, pos);
560 return NULL_TREE;
563 /* Argument positions are 1-based. */
564 if (integer_zerop (pos))
566 if (flags & POSARG_ZERO)
567 /* Zero is explicitly allowed. */
568 return pos;
570 if (argno < 1)
571 warning (OPT_Wattributes,
572 "%qE attribute argument value %qE does not refer to "
573 "a function parameter",
574 atname, pos);
575 else
576 warning (OPT_Wattributes,
577 "%qE attribute argument %i value %qE does not refer to "
578 "a function parameter",
579 atname, argno, pos);
581 return NULL_TREE;
584 if (!prototype_p (fntype))
585 return pos;
587 /* Verify that the argument position does not exceed the number
588 of formal arguments to the function. When POSARG_ELLIPSIS
589 is set, ARGNO may be beyond the last argument of a vararg
590 function. */
591 unsigned nargs = type_num_arguments (fntype);
592 if (!nargs
593 || !tree_fits_uhwi_p (pos)
594 || ((flags & POSARG_ELLIPSIS) == 0
595 && !IN_RANGE (tree_to_uhwi (pos), 1, nargs)))
598 if (argno < 1)
599 warning (OPT_Wattributes,
600 "%qE attribute argument value %qE exceeds the number "
601 "of function parameters %u",
602 atname, pos, nargs);
603 else
604 warning (OPT_Wattributes,
605 "%qE attribute argument %i value %qE exceeds the number "
606 "of function parameters %u",
607 atname, argno, pos, nargs);
608 return NULL_TREE;
611 /* Verify that the type of the referenced formal argument matches
612 the expected type. */
613 unsigned HOST_WIDE_INT ipos = tree_to_uhwi (pos);
615 /* Zero was handled above. */
616 gcc_assert (ipos != 0);
618 if (tree argtype = type_argument_type (fntype, ipos))
620 if (flags & POSARG_ELLIPSIS)
622 if (argno < 1)
623 error ("%qE attribute argument value %qE does not refer to "
624 "a variable argument list",
625 atname, pos);
626 else
627 error ("%qE attribute argument %i value %qE does not refer to "
628 "a variable argument list",
629 atname, argno, pos);
630 return NULL_TREE;
633 /* Where the expected code is STRING_CST accept any pointer
634 to a narrow character type, qualified or otherwise. */
635 bool type_match;
636 if (code == STRING_CST && POINTER_TYPE_P (argtype))
638 tree type = TREE_TYPE (argtype);
639 type = TYPE_MAIN_VARIANT (type);
640 type_match = (type == char_type_node
641 || type == signed_char_type_node
642 || type == unsigned_char_type_node);
644 else
645 type_match = TREE_CODE (argtype) == code;
647 if (!type_match)
649 if (argno < 1)
650 warning (OPT_Wattributes,
651 "%qE attribute argument value %qE refers to "
652 "parameter type %qT",
653 atname, pos, argtype);
654 else
655 warning (OPT_Wattributes,
656 "%qE attribute argument %i value %qE refers to "
657 "parameter type %qT",
658 atname, argno, pos, argtype);
659 return NULL_TREE;
662 else if (!(flags & POSARG_ELLIPSIS))
664 if (argno < 1)
665 warning (OPT_Wattributes,
666 "%qE attribute argument value %qE refers to "
667 "a variadic function parameter of unknown type",
668 atname, pos);
669 else
670 warning (OPT_Wattributes,
671 "%qE attribute argument %i value %qE refers to "
672 "a variadic function parameter of unknown type",
673 atname, argno, pos);
674 return NULL_TREE;
677 return pos;
681 /* Attribute handlers common to C front ends. */
683 /* Handle a "packed" attribute; arguments as in
684 struct attribute_spec.handler. */
686 static tree
687 handle_packed_attribute (tree *node, tree name, tree ARG_UNUSED (args),
688 int flags, bool *no_add_attrs)
690 if (TYPE_P (*node))
692 if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
694 warning (OPT_Wattributes,
695 "%qE attribute ignored for type %qT", name, *node);
696 *no_add_attrs = true;
698 else
699 TYPE_PACKED (*node) = 1;
701 else if (TREE_CODE (*node) == FIELD_DECL)
703 if (TYPE_ALIGN (TREE_TYPE (*node)) <= BITS_PER_UNIT
704 /* Still pack bitfields. */
705 && ! DECL_C_BIT_FIELD (*node))
706 warning (OPT_Wattributes,
707 "%qE attribute ignored for field of type %qT",
708 name, TREE_TYPE (*node));
709 else
710 DECL_PACKED (*node) = 1;
712 /* We can't set DECL_PACKED for a VAR_DECL, because the bit is
713 used for DECL_REGISTER. It wouldn't mean anything anyway.
714 We can't set DECL_PACKED on the type of a TYPE_DECL, because
715 that changes what the typedef is typing. */
716 else
718 warning (OPT_Wattributes, "%qE attribute ignored", name);
719 *no_add_attrs = true;
722 return NULL_TREE;
725 /* Handle a "nocommon" attribute; arguments as in
726 struct attribute_spec.handler. */
728 static tree
729 handle_nocommon_attribute (tree *node, tree name,
730 tree ARG_UNUSED (args),
731 int ARG_UNUSED (flags), bool *no_add_attrs)
733 if (VAR_P (*node))
734 DECL_COMMON (*node) = 0;
735 else
737 warning (OPT_Wattributes, "%qE attribute ignored", name);
738 *no_add_attrs = true;
741 return NULL_TREE;
744 /* Handle a "common" attribute; arguments as in
745 struct attribute_spec.handler. */
747 static tree
748 handle_common_attribute (tree *node, tree name, tree ARG_UNUSED (args),
749 int ARG_UNUSED (flags), bool *no_add_attrs)
751 if (VAR_P (*node))
752 DECL_COMMON (*node) = 1;
753 else
755 warning (OPT_Wattributes, "%qE attribute ignored", name);
756 *no_add_attrs = true;
759 return NULL_TREE;
762 /* Handle a "noreturn" attribute; arguments as in
763 struct attribute_spec.handler. */
765 static tree
766 handle_noreturn_attribute (tree *node, tree name, tree ARG_UNUSED (args),
767 int ARG_UNUSED (flags), bool *no_add_attrs)
769 tree type = TREE_TYPE (*node);
771 /* See FIXME comment in c_common_attribute_table. */
772 if (TREE_CODE (*node) == FUNCTION_DECL
773 || objc_method_decl (TREE_CODE (*node)))
774 TREE_THIS_VOLATILE (*node) = 1;
775 else if (TREE_CODE (type) == POINTER_TYPE
776 && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
777 TREE_TYPE (*node)
778 = (build_qualified_type
779 (build_pointer_type
780 (build_type_variant (TREE_TYPE (type),
781 TYPE_READONLY (TREE_TYPE (type)), 1)),
782 TYPE_QUALS (type)));
783 else
785 warning (OPT_Wattributes, "%qE attribute ignored", name);
786 *no_add_attrs = true;
789 return NULL_TREE;
792 /* Handle a "hot" and attribute; arguments as in
793 struct attribute_spec.handler. */
795 static tree
796 handle_hot_attribute (tree *node, tree name, tree ARG_UNUSED (args),
797 int ARG_UNUSED (flags), bool *no_add_attrs)
799 if (TREE_CODE (*node) == FUNCTION_DECL
800 || TREE_CODE (*node) == LABEL_DECL)
802 /* Attribute hot processing is done later with lookup_attribute. */
804 else
806 warning (OPT_Wattributes, "%qE attribute ignored", name);
807 *no_add_attrs = true;
810 return NULL_TREE;
813 /* Handle a "cold" and attribute; arguments as in
814 struct attribute_spec.handler. */
816 static tree
817 handle_cold_attribute (tree *node, tree name, tree ARG_UNUSED (args),
818 int ARG_UNUSED (flags), bool *no_add_attrs)
820 if (TREE_CODE (*node) == FUNCTION_DECL
821 || TREE_CODE (*node) == LABEL_DECL)
823 /* Attribute cold processing is done later with lookup_attribute. */
825 else
827 warning (OPT_Wattributes, "%qE attribute ignored", name);
828 *no_add_attrs = true;
831 return NULL_TREE;
834 /* Add FLAGS for a function NODE to no_sanitize_flags in DECL_ATTRIBUTES. */
836 void
837 add_no_sanitize_value (tree node, unsigned int flags)
839 tree attr = lookup_attribute ("no_sanitize", DECL_ATTRIBUTES (node));
840 if (attr)
842 unsigned int old_value = tree_to_uhwi (TREE_VALUE (attr));
843 flags |= old_value;
845 if (flags == old_value)
846 return;
848 TREE_VALUE (attr) = build_int_cst (unsigned_type_node, flags);
850 else
851 DECL_ATTRIBUTES (node)
852 = tree_cons (get_identifier ("no_sanitize"),
853 build_int_cst (unsigned_type_node, flags),
854 DECL_ATTRIBUTES (node));
857 /* Handle a "no_sanitize" attribute; arguments as in
858 struct attribute_spec.handler. */
860 static tree
861 handle_no_sanitize_attribute (tree *node, tree name, tree args, int,
862 bool *no_add_attrs)
864 unsigned int flags = 0;
865 *no_add_attrs = true;
866 if (TREE_CODE (*node) != FUNCTION_DECL)
868 warning (OPT_Wattributes, "%qE attribute ignored", name);
869 return NULL_TREE;
872 for (; args; args = TREE_CHAIN (args))
874 tree id = TREE_VALUE (args);
875 if (TREE_CODE (id) != STRING_CST)
877 error ("no_sanitize argument not a string");
878 return NULL_TREE;
881 char *string = ASTRDUP (TREE_STRING_POINTER (id));
882 flags |= parse_no_sanitize_attribute (string);
885 add_no_sanitize_value (*node, flags);
887 return NULL_TREE;
890 /* Handle a "no_sanitize_address" attribute; arguments as in
891 struct attribute_spec.handler. */
893 static tree
894 handle_no_sanitize_address_attribute (tree *node, tree name, tree, int,
895 bool *no_add_attrs)
897 *no_add_attrs = true;
898 if (TREE_CODE (*node) != FUNCTION_DECL)
899 warning (OPT_Wattributes, "%qE attribute ignored", name);
900 else
901 add_no_sanitize_value (*node, SANITIZE_ADDRESS);
903 return NULL_TREE;
906 /* Handle a "no_sanitize_thread" attribute; arguments as in
907 struct attribute_spec.handler. */
909 static tree
910 handle_no_sanitize_thread_attribute (tree *node, tree name, tree, int,
911 bool *no_add_attrs)
913 *no_add_attrs = true;
914 if (TREE_CODE (*node) != FUNCTION_DECL)
915 warning (OPT_Wattributes, "%qE attribute ignored", name);
916 else
917 add_no_sanitize_value (*node, SANITIZE_THREAD);
919 return NULL_TREE;
923 /* Handle a "no_address_safety_analysis" attribute; arguments as in
924 struct attribute_spec.handler. */
926 static tree
927 handle_no_address_safety_analysis_attribute (tree *node, tree name, tree, int,
928 bool *no_add_attrs)
930 *no_add_attrs = true;
931 if (TREE_CODE (*node) != FUNCTION_DECL)
932 warning (OPT_Wattributes, "%qE attribute ignored", name);
933 else
934 add_no_sanitize_value (*node, SANITIZE_ADDRESS);
936 return NULL_TREE;
939 /* Handle a "no_sanitize_undefined" attribute; arguments as in
940 struct attribute_spec.handler. */
942 static tree
943 handle_no_sanitize_undefined_attribute (tree *node, tree name, tree, int,
944 bool *no_add_attrs)
946 *no_add_attrs = true;
947 if (TREE_CODE (*node) != FUNCTION_DECL)
948 warning (OPT_Wattributes, "%qE attribute ignored", name);
949 else
950 add_no_sanitize_value (*node,
951 SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT);
953 return NULL_TREE;
956 /* Handle an "asan odr indicator" attribute; arguments as in
957 struct attribute_spec.handler. */
959 static tree
960 handle_asan_odr_indicator_attribute (tree *, tree, tree, int, bool *)
962 return NULL_TREE;
965 /* Handle a "stack_protect" attribute; arguments as in
966 struct attribute_spec.handler. */
968 static tree
969 handle_stack_protect_attribute (tree *node, tree name, tree, int,
970 bool *no_add_attrs)
972 if (TREE_CODE (*node) != FUNCTION_DECL)
974 warning (OPT_Wattributes, "%qE attribute ignored", name);
975 *no_add_attrs = true;
978 return NULL_TREE;
981 /* Handle a "noipa" attribute; arguments as in
982 struct attribute_spec.handler. */
984 static tree
985 handle_noipa_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
987 if (TREE_CODE (*node) != FUNCTION_DECL)
989 warning (OPT_Wattributes, "%qE attribute ignored", name);
990 *no_add_attrs = true;
993 return NULL_TREE;
996 /* Handle a "noinline" attribute; arguments as in
997 struct attribute_spec.handler. */
999 static tree
1000 handle_noinline_attribute (tree *node, tree name,
1001 tree ARG_UNUSED (args),
1002 int ARG_UNUSED (flags), bool *no_add_attrs)
1004 if (TREE_CODE (*node) == FUNCTION_DECL)
1006 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (*node)))
1008 warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
1009 "with attribute %qs", name, "always_inline");
1010 *no_add_attrs = true;
1012 else
1013 DECL_UNINLINABLE (*node) = 1;
1015 else
1017 warning (OPT_Wattributes, "%qE attribute ignored", name);
1018 *no_add_attrs = true;
1021 return NULL_TREE;
1024 /* Handle a "noclone" attribute; arguments as in
1025 struct attribute_spec.handler. */
1027 static tree
1028 handle_noclone_attribute (tree *node, tree name,
1029 tree ARG_UNUSED (args),
1030 int ARG_UNUSED (flags), bool *no_add_attrs)
1032 if (TREE_CODE (*node) != FUNCTION_DECL)
1034 warning (OPT_Wattributes, "%qE attribute ignored", name);
1035 *no_add_attrs = true;
1038 return NULL_TREE;
1041 /* Handle a "nocf_check" attribute; arguments as in
1042 struct attribute_spec.handler. */
1044 static tree
1045 handle_nocf_check_attribute (tree *node, tree name,
1046 tree ARG_UNUSED (args),
1047 int ARG_UNUSED (flags), bool *no_add_attrs)
1049 if (TREE_CODE (*node) != FUNCTION_TYPE
1050 && TREE_CODE (*node) != METHOD_TYPE)
1052 warning (OPT_Wattributes, "%qE attribute ignored", name);
1053 *no_add_attrs = true;
1055 else if (!(flag_cf_protection & CF_BRANCH))
1057 warning (OPT_Wattributes, "%qE attribute ignored. Use "
1058 "-fcf-protection option to enable it", name);
1059 *no_add_attrs = true;
1062 return NULL_TREE;
1065 /* Handle a "no_icf" attribute; arguments as in
1066 struct attribute_spec.handler. */
1068 static tree
1069 handle_noicf_attribute (tree *node, tree name,
1070 tree ARG_UNUSED (args),
1071 int ARG_UNUSED (flags), bool *no_add_attrs)
1073 if (TREE_CODE (*node) != FUNCTION_DECL)
1075 warning (OPT_Wattributes, "%qE attribute ignored", name);
1076 *no_add_attrs = true;
1079 return NULL_TREE;
1083 /* Handle a "always_inline" attribute; arguments as in
1084 struct attribute_spec.handler. */
1086 static tree
1087 handle_always_inline_attribute (tree *node, tree name,
1088 tree ARG_UNUSED (args),
1089 int ARG_UNUSED (flags),
1090 bool *no_add_attrs)
1092 if (TREE_CODE (*node) == FUNCTION_DECL)
1094 if (lookup_attribute ("noinline", DECL_ATTRIBUTES (*node)))
1096 warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
1097 "with %qs attribute", name, "noinline");
1098 *no_add_attrs = true;
1100 else if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (*node)))
1102 warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
1103 "with %qs attribute", name, "target_clones");
1104 *no_add_attrs = true;
1106 else
1107 /* Set the attribute and mark it for disregarding inline
1108 limits. */
1109 DECL_DISREGARD_INLINE_LIMITS (*node) = 1;
1111 else
1113 warning (OPT_Wattributes, "%qE attribute ignored", name);
1114 *no_add_attrs = true;
1117 return NULL_TREE;
1120 /* Handle a "gnu_inline" attribute; arguments as in
1121 struct attribute_spec.handler. */
1123 static tree
1124 handle_gnu_inline_attribute (tree *node, tree name,
1125 tree ARG_UNUSED (args),
1126 int ARG_UNUSED (flags),
1127 bool *no_add_attrs)
1129 if (TREE_CODE (*node) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (*node))
1131 /* Do nothing else, just set the attribute. We'll get at
1132 it later with lookup_attribute. */
1134 else
1136 warning (OPT_Wattributes, "%qE attribute ignored", name);
1137 *no_add_attrs = true;
1140 return NULL_TREE;
1143 /* Handle a "leaf" attribute; arguments as in
1144 struct attribute_spec.handler. */
1146 static tree
1147 handle_leaf_attribute (tree *node, tree name,
1148 tree ARG_UNUSED (args),
1149 int ARG_UNUSED (flags), bool *no_add_attrs)
1151 if (TREE_CODE (*node) != FUNCTION_DECL)
1153 warning (OPT_Wattributes, "%qE attribute ignored", name);
1154 *no_add_attrs = true;
1156 if (!TREE_PUBLIC (*node))
1158 warning (OPT_Wattributes, "%qE attribute has no effect on unit local "
1159 "functions", name);
1160 *no_add_attrs = true;
1163 return NULL_TREE;
1166 /* Handle an "artificial" attribute; arguments as in
1167 struct attribute_spec.handler. */
1169 static tree
1170 handle_artificial_attribute (tree *node, tree name,
1171 tree ARG_UNUSED (args),
1172 int ARG_UNUSED (flags),
1173 bool *no_add_attrs)
1175 if (TREE_CODE (*node) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (*node))
1177 /* Do nothing else, just set the attribute. We'll get at
1178 it later with lookup_attribute. */
1180 else
1182 warning (OPT_Wattributes, "%qE attribute ignored", name);
1183 *no_add_attrs = true;
1186 return NULL_TREE;
1189 /* Handle a "flatten" attribute; arguments as in
1190 struct attribute_spec.handler. */
1192 static tree
1193 handle_flatten_attribute (tree *node, tree name,
1194 tree args ATTRIBUTE_UNUSED,
1195 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
1197 if (TREE_CODE (*node) == FUNCTION_DECL)
1198 /* Do nothing else, just set the attribute. We'll get at
1199 it later with lookup_attribute. */
1201 else
1203 warning (OPT_Wattributes, "%qE attribute ignored", name);
1204 *no_add_attrs = true;
1207 return NULL_TREE;
1210 /* Handle a "warning" or "error" attribute; arguments as in
1211 struct attribute_spec.handler. */
1213 static tree
1214 handle_error_attribute (tree *node, tree name, tree args,
1215 int ARG_UNUSED (flags), bool *no_add_attrs)
1217 if (TREE_CODE (*node) == FUNCTION_DECL
1218 && TREE_CODE (TREE_VALUE (args)) == STRING_CST)
1219 /* Do nothing else, just set the attribute. We'll get at
1220 it later with lookup_attribute. */
1222 else
1224 warning (OPT_Wattributes, "%qE attribute ignored", name);
1225 *no_add_attrs = true;
1228 return NULL_TREE;
1231 /* Handle a "used" attribute; arguments as in
1232 struct attribute_spec.handler. */
1234 static tree
1235 handle_used_attribute (tree *pnode, tree name, tree ARG_UNUSED (args),
1236 int ARG_UNUSED (flags), bool *no_add_attrs)
1238 tree node = *pnode;
1240 if (TREE_CODE (node) == FUNCTION_DECL
1241 || (VAR_P (node) && TREE_STATIC (node))
1242 || (TREE_CODE (node) == TYPE_DECL))
1244 TREE_USED (node) = 1;
1245 DECL_PRESERVE_P (node) = 1;
1246 if (VAR_P (node))
1247 DECL_READ_P (node) = 1;
1249 else
1251 warning (OPT_Wattributes, "%qE attribute ignored", name);
1252 *no_add_attrs = true;
1255 return NULL_TREE;
1258 /* Handle a "unused" attribute; arguments as in
1259 struct attribute_spec.handler. */
1261 tree
1262 handle_unused_attribute (tree *node, tree name, tree ARG_UNUSED (args),
1263 int flags, bool *no_add_attrs)
1265 if (DECL_P (*node))
1267 tree decl = *node;
1269 if (TREE_CODE (decl) == PARM_DECL
1270 || VAR_OR_FUNCTION_DECL_P (decl)
1271 || TREE_CODE (decl) == LABEL_DECL
1272 || TREE_CODE (decl) == CONST_DECL
1273 || TREE_CODE (decl) == TYPE_DECL)
1275 TREE_USED (decl) = 1;
1276 if (VAR_P (decl) || TREE_CODE (decl) == PARM_DECL)
1277 DECL_READ_P (decl) = 1;
1279 else
1281 warning (OPT_Wattributes, "%qE attribute ignored", name);
1282 *no_add_attrs = true;
1285 else
1287 if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
1288 *node = build_variant_type_copy (*node);
1289 TREE_USED (*node) = 1;
1292 return NULL_TREE;
1295 /* Handle a "externally_visible" attribute; arguments as in
1296 struct attribute_spec.handler. */
1298 static tree
1299 handle_externally_visible_attribute (tree *pnode, tree name,
1300 tree ARG_UNUSED (args),
1301 int ARG_UNUSED (flags),
1302 bool *no_add_attrs)
1304 tree node = *pnode;
1306 if (VAR_OR_FUNCTION_DECL_P (node))
1308 if ((!TREE_STATIC (node) && TREE_CODE (node) != FUNCTION_DECL
1309 && !DECL_EXTERNAL (node)) || !TREE_PUBLIC (node))
1311 warning (OPT_Wattributes,
1312 "%qE attribute have effect only on public objects", name);
1313 *no_add_attrs = true;
1316 else
1318 warning (OPT_Wattributes, "%qE attribute ignored", name);
1319 *no_add_attrs = true;
1322 return NULL_TREE;
1325 /* Handle the "no_reorder" attribute. Arguments as in
1326 struct attribute_spec.handler. */
1328 static tree
1329 handle_no_reorder_attribute (tree *pnode,
1330 tree name,
1331 tree,
1332 int,
1333 bool *no_add_attrs)
1335 tree node = *pnode;
1337 if (!VAR_OR_FUNCTION_DECL_P (node)
1338 && !(TREE_STATIC (node) || DECL_EXTERNAL (node)))
1340 warning (OPT_Wattributes,
1341 "%qE attribute only affects top level objects",
1342 name);
1343 *no_add_attrs = true;
1346 return NULL_TREE;
1349 /* Handle a "const" attribute; arguments as in
1350 struct attribute_spec.handler. */
1352 static tree
1353 handle_const_attribute (tree *node, tree name, tree ARG_UNUSED (args),
1354 int flags, bool *no_add_attrs)
1356 tree type = TREE_TYPE (*node);
1358 /* See FIXME comment on noreturn in c_common_attribute_table. */
1359 if (TREE_CODE (*node) == FUNCTION_DECL)
1360 TREE_READONLY (*node) = 1;
1361 else if (TREE_CODE (type) == POINTER_TYPE
1362 && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
1363 TREE_TYPE (*node)
1364 = (build_qualified_type
1365 (build_pointer_type
1366 (build_type_variant (TREE_TYPE (type), 1,
1367 TREE_THIS_VOLATILE (TREE_TYPE (type)))),
1368 TYPE_QUALS (type)));
1369 else
1371 warning (OPT_Wattributes, "%qE attribute ignored", name);
1372 *no_add_attrs = true;
1375 /* void __builtin_unreachable(void) is const. Accept other such
1376 built-ins but warn on user-defined functions that return void. */
1377 if (!(flags & ATTR_FLAG_BUILT_IN)
1378 && TREE_CODE (*node) == FUNCTION_DECL
1379 && VOID_TYPE_P (TREE_TYPE (type)))
1380 warning (OPT_Wattributes, "%qE attribute on function "
1381 "returning %<void%>", name);
1383 return NULL_TREE;
1386 /* Handle a "scalar_storage_order" attribute; arguments as in
1387 struct attribute_spec.handler. */
1389 static tree
1390 handle_scalar_storage_order_attribute (tree *node, tree name, tree args,
1391 int flags, bool *no_add_attrs)
1393 tree id = TREE_VALUE (args);
1394 tree type;
1396 if (TREE_CODE (*node) == TYPE_DECL
1397 && ! (flags & ATTR_FLAG_CXX11))
1398 node = &TREE_TYPE (*node);
1399 type = *node;
1401 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
1403 error ("scalar_storage_order is not supported because endianness "
1404 "is not uniform");
1405 return NULL_TREE;
1408 if (RECORD_OR_UNION_TYPE_P (type) && !c_dialect_cxx ())
1410 bool reverse = false;
1412 if (TREE_CODE (id) == STRING_CST
1413 && strcmp (TREE_STRING_POINTER (id), "big-endian") == 0)
1414 reverse = !BYTES_BIG_ENDIAN;
1415 else if (TREE_CODE (id) == STRING_CST
1416 && strcmp (TREE_STRING_POINTER (id), "little-endian") == 0)
1417 reverse = BYTES_BIG_ENDIAN;
1418 else
1420 error ("scalar_storage_order argument must be one of \"big-endian\""
1421 " or \"little-endian\"");
1422 return NULL_TREE;
1425 if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
1427 if (reverse)
1428 /* A type variant isn't good enough, since we don't want a cast
1429 to such a type to be removed as a no-op. */
1430 *node = type = build_duplicate_type (type);
1433 TYPE_REVERSE_STORAGE_ORDER (type) = reverse;
1434 return NULL_TREE;
1437 warning (OPT_Wattributes, "%qE attribute ignored", name);
1438 *no_add_attrs = true;
1439 return NULL_TREE;
1442 /* Handle a "transparent_union" attribute; arguments as in
1443 struct attribute_spec.handler. */
1445 static tree
1446 handle_transparent_union_attribute (tree *node, tree name,
1447 tree ARG_UNUSED (args), int flags,
1448 bool *no_add_attrs)
1450 tree type;
1452 *no_add_attrs = true;
1454 if (TREE_CODE (*node) == TYPE_DECL
1455 && ! (flags & ATTR_FLAG_CXX11))
1456 node = &TREE_TYPE (*node);
1457 type = *node;
1459 if (TREE_CODE (type) == UNION_TYPE)
1461 /* Make sure that the first field will work for a transparent union.
1462 If the type isn't complete yet, leave the check to the code in
1463 finish_struct. */
1464 if (TYPE_SIZE (type))
1466 tree first = first_field (type);
1467 if (first == NULL_TREE
1468 || DECL_ARTIFICIAL (first)
1469 || TYPE_MODE (type) != DECL_MODE (first))
1470 goto ignored;
1473 if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
1475 /* If the type isn't complete yet, setting the flag
1476 on a variant wouldn't ever be checked. */
1477 if (!TYPE_SIZE (type))
1478 goto ignored;
1480 /* build_duplicate_type doesn't work for C++. */
1481 if (c_dialect_cxx ())
1482 goto ignored;
1484 /* A type variant isn't good enough, since we don't want a cast
1485 to such a type to be removed as a no-op. */
1486 *node = type = build_duplicate_type (type);
1489 for (tree t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
1490 TYPE_TRANSPARENT_AGGR (t) = 1;
1491 return NULL_TREE;
1494 ignored:
1495 warning (OPT_Wattributes, "%qE attribute ignored", name);
1496 return NULL_TREE;
1499 /* Subroutine of handle_{con,de}structor_attribute. Evaluate ARGS to
1500 get the requested priority for a constructor or destructor,
1501 possibly issuing diagnostics for invalid or reserved
1502 priorities. */
1504 static priority_type
1505 get_priority (tree args, bool is_destructor)
1507 HOST_WIDE_INT pri;
1508 tree arg;
1510 if (!args)
1511 return DEFAULT_INIT_PRIORITY;
1513 if (!SUPPORTS_INIT_PRIORITY)
1515 if (is_destructor)
1516 error ("destructor priorities are not supported");
1517 else
1518 error ("constructor priorities are not supported");
1519 return DEFAULT_INIT_PRIORITY;
1522 arg = TREE_VALUE (args);
1523 if (TREE_CODE (arg) == IDENTIFIER_NODE)
1524 goto invalid;
1525 if (arg == error_mark_node)
1526 return DEFAULT_INIT_PRIORITY;
1527 arg = default_conversion (arg);
1528 if (!tree_fits_shwi_p (arg)
1529 || !INTEGRAL_TYPE_P (TREE_TYPE (arg)))
1530 goto invalid;
1532 pri = tree_to_shwi (arg);
1533 if (pri < 0 || pri > MAX_INIT_PRIORITY)
1534 goto invalid;
1536 if (pri <= MAX_RESERVED_INIT_PRIORITY)
1538 if (is_destructor)
1539 warning (OPT_Wprio_ctor_dtor,
1540 "destructor priorities from 0 to %d are reserved "
1541 "for the implementation",
1542 MAX_RESERVED_INIT_PRIORITY);
1543 else
1544 warning (OPT_Wprio_ctor_dtor,
1545 "constructor priorities from 0 to %d are reserved "
1546 "for the implementation",
1547 MAX_RESERVED_INIT_PRIORITY);
1549 return pri;
1551 invalid:
1552 if (is_destructor)
1553 error ("destructor priorities must be integers from 0 to %d inclusive",
1554 MAX_INIT_PRIORITY);
1555 else
1556 error ("constructor priorities must be integers from 0 to %d inclusive",
1557 MAX_INIT_PRIORITY);
1558 return DEFAULT_INIT_PRIORITY;
1561 /* Handle a "constructor" attribute; arguments as in
1562 struct attribute_spec.handler. */
1564 static tree
1565 handle_constructor_attribute (tree *node, tree name, tree args,
1566 int ARG_UNUSED (flags),
1567 bool *no_add_attrs)
1569 tree decl = *node;
1570 tree type = TREE_TYPE (decl);
1572 if (TREE_CODE (decl) == FUNCTION_DECL
1573 && TREE_CODE (type) == FUNCTION_TYPE
1574 && decl_function_context (decl) == 0)
1576 priority_type priority;
1577 DECL_STATIC_CONSTRUCTOR (decl) = 1;
1578 priority = get_priority (args, /*is_destructor=*/false);
1579 SET_DECL_INIT_PRIORITY (decl, priority);
1580 TREE_USED (decl) = 1;
1582 else
1584 warning (OPT_Wattributes, "%qE attribute ignored", name);
1585 *no_add_attrs = true;
1588 return NULL_TREE;
1591 /* Handle a "destructor" attribute; arguments as in
1592 struct attribute_spec.handler. */
1594 static tree
1595 handle_destructor_attribute (tree *node, tree name, tree args,
1596 int ARG_UNUSED (flags),
1597 bool *no_add_attrs)
1599 tree decl = *node;
1600 tree type = TREE_TYPE (decl);
1602 if (TREE_CODE (decl) == FUNCTION_DECL
1603 && TREE_CODE (type) == FUNCTION_TYPE
1604 && decl_function_context (decl) == 0)
1606 priority_type priority;
1607 DECL_STATIC_DESTRUCTOR (decl) = 1;
1608 priority = get_priority (args, /*is_destructor=*/true);
1609 SET_DECL_FINI_PRIORITY (decl, priority);
1610 TREE_USED (decl) = 1;
1612 else
1614 warning (OPT_Wattributes, "%qE attribute ignored", name);
1615 *no_add_attrs = true;
1618 return NULL_TREE;
1621 /* Nonzero if the mode is a valid vector mode for this architecture.
1622 This returns nonzero even if there is no hardware support for the
1623 vector mode, but we can emulate with narrower modes. */
1625 static bool
1626 vector_mode_valid_p (machine_mode mode)
1628 enum mode_class mclass = GET_MODE_CLASS (mode);
1630 /* Doh! What's going on? */
1631 if (mclass != MODE_VECTOR_INT
1632 && mclass != MODE_VECTOR_FLOAT
1633 && mclass != MODE_VECTOR_FRACT
1634 && mclass != MODE_VECTOR_UFRACT
1635 && mclass != MODE_VECTOR_ACCUM
1636 && mclass != MODE_VECTOR_UACCUM)
1637 return false;
1639 /* Hardware support. Woo hoo! */
1640 if (targetm.vector_mode_supported_p (mode))
1641 return true;
1643 /* We should probably return 1 if requesting V4DI and we have no DI,
1644 but we have V2DI, but this is probably very unlikely. */
1646 /* If we have support for the inner mode, we can safely emulate it.
1647 We may not have V2DI, but me can emulate with a pair of DIs. */
1648 return targetm.scalar_mode_supported_p (GET_MODE_INNER (mode));
1652 /* Handle a "mode" attribute; arguments as in
1653 struct attribute_spec.handler. */
1655 static tree
1656 handle_mode_attribute (tree *node, tree name, tree args,
1657 int ARG_UNUSED (flags), bool *no_add_attrs)
1659 tree type = *node;
1660 tree ident = TREE_VALUE (args);
1662 *no_add_attrs = true;
1664 if (TREE_CODE (ident) != IDENTIFIER_NODE)
1665 warning (OPT_Wattributes, "%qE attribute ignored", name);
1666 else
1668 int j;
1669 const char *p = IDENTIFIER_POINTER (ident);
1670 int len = strlen (p);
1671 machine_mode mode = VOIDmode;
1672 tree typefm;
1673 bool valid_mode;
1675 if (len > 4 && p[0] == '_' && p[1] == '_'
1676 && p[len - 1] == '_' && p[len - 2] == '_')
1678 char *newp = (char *) alloca (len - 1);
1680 strcpy (newp, &p[2]);
1681 newp[len - 4] = '\0';
1682 p = newp;
1685 /* Change this type to have a type with the specified mode.
1686 First check for the special modes. */
1687 if (!strcmp (p, "byte"))
1688 mode = byte_mode;
1689 else if (!strcmp (p, "word"))
1690 mode = word_mode;
1691 else if (!strcmp (p, "pointer"))
1692 mode = ptr_mode;
1693 else if (!strcmp (p, "libgcc_cmp_return"))
1694 mode = targetm.libgcc_cmp_return_mode ();
1695 else if (!strcmp (p, "libgcc_shift_count"))
1696 mode = targetm.libgcc_shift_count_mode ();
1697 else if (!strcmp (p, "unwind_word"))
1698 mode = targetm.unwind_word_mode ();
1699 else
1700 for (j = 0; j < NUM_MACHINE_MODES; j++)
1701 if (!strcmp (p, GET_MODE_NAME (j)))
1703 mode = (machine_mode) j;
1704 break;
1707 if (mode == VOIDmode)
1709 error ("unknown machine mode %qE", ident);
1710 return NULL_TREE;
1713 /* Allow the target a chance to translate MODE into something supported.
1714 See PR86324. */
1715 mode = targetm.translate_mode_attribute (mode);
1717 valid_mode = false;
1718 switch (GET_MODE_CLASS (mode))
1720 case MODE_INT:
1721 case MODE_PARTIAL_INT:
1722 case MODE_FLOAT:
1723 case MODE_DECIMAL_FLOAT:
1724 case MODE_FRACT:
1725 case MODE_UFRACT:
1726 case MODE_ACCUM:
1727 case MODE_UACCUM:
1728 valid_mode
1729 = targetm.scalar_mode_supported_p (as_a <scalar_mode> (mode));
1730 break;
1732 case MODE_COMPLEX_INT:
1733 case MODE_COMPLEX_FLOAT:
1734 valid_mode = targetm.scalar_mode_supported_p (GET_MODE_INNER (mode));
1735 break;
1737 case MODE_VECTOR_INT:
1738 case MODE_VECTOR_FLOAT:
1739 case MODE_VECTOR_FRACT:
1740 case MODE_VECTOR_UFRACT:
1741 case MODE_VECTOR_ACCUM:
1742 case MODE_VECTOR_UACCUM:
1743 warning (OPT_Wattributes, "specifying vector types with "
1744 "__attribute__ ((mode)) is deprecated");
1745 warning (OPT_Wattributes,
1746 "use __attribute__ ((vector_size)) instead");
1747 valid_mode = vector_mode_valid_p (mode);
1748 break;
1750 default:
1751 break;
1753 if (!valid_mode)
1755 error ("unable to emulate %qs", p);
1756 return NULL_TREE;
1759 if (POINTER_TYPE_P (type))
1761 scalar_int_mode addr_mode;
1762 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (type));
1763 tree (*fn)(tree, machine_mode, bool);
1765 if (!is_a <scalar_int_mode> (mode, &addr_mode)
1766 || !targetm.addr_space.valid_pointer_mode (addr_mode, as))
1768 error ("invalid pointer mode %qs", p);
1769 return NULL_TREE;
1772 if (TREE_CODE (type) == POINTER_TYPE)
1773 fn = build_pointer_type_for_mode;
1774 else
1775 fn = build_reference_type_for_mode;
1776 typefm = fn (TREE_TYPE (type), addr_mode, false);
1778 else
1780 /* For fixed-point modes, we need to test if the signness of type
1781 and the machine mode are consistent. */
1782 if (ALL_FIXED_POINT_MODE_P (mode)
1783 && TYPE_UNSIGNED (type) != UNSIGNED_FIXED_POINT_MODE_P (mode))
1785 error ("signedness of type and machine mode %qs don%'t match", p);
1786 return NULL_TREE;
1788 /* For fixed-point modes, we need to pass saturating info. */
1789 typefm = lang_hooks.types.type_for_mode (mode,
1790 ALL_FIXED_POINT_MODE_P (mode) ? TYPE_SATURATING (type)
1791 : TYPE_UNSIGNED (type));
1794 if (typefm == NULL_TREE)
1796 error ("no data type for mode %qs", p);
1797 return NULL_TREE;
1799 else if (TREE_CODE (type) == ENUMERAL_TYPE)
1801 /* For enumeral types, copy the precision from the integer
1802 type returned above. If not an INTEGER_TYPE, we can't use
1803 this mode for this type. */
1804 if (TREE_CODE (typefm) != INTEGER_TYPE)
1806 error ("cannot use mode %qs for enumeral types", p);
1807 return NULL_TREE;
1810 if (flags & ATTR_FLAG_TYPE_IN_PLACE)
1812 TYPE_PRECISION (type) = TYPE_PRECISION (typefm);
1813 typefm = type;
1815 else
1817 /* We cannot build a type variant, as there's code that assumes
1818 that TYPE_MAIN_VARIANT has the same mode. This includes the
1819 debug generators. Instead, create a subrange type. This
1820 results in all of the enumeral values being emitted only once
1821 in the original, and the subtype gets them by reference. */
1822 if (TYPE_UNSIGNED (type))
1823 typefm = make_unsigned_type (TYPE_PRECISION (typefm));
1824 else
1825 typefm = make_signed_type (TYPE_PRECISION (typefm));
1826 TREE_TYPE (typefm) = type;
1829 else if (VECTOR_MODE_P (mode)
1830 ? TREE_CODE (type) != TREE_CODE (TREE_TYPE (typefm))
1831 : TREE_CODE (type) != TREE_CODE (typefm))
1833 error ("mode %qs applied to inappropriate type", p);
1834 return NULL_TREE;
1837 *node = build_qualified_type (typefm, TYPE_QUALS (type));
1840 return NULL_TREE;
1843 /* Handle a "section" attribute; arguments as in
1844 struct attribute_spec.handler. */
1846 static tree
1847 handle_section_attribute (tree *node, tree ARG_UNUSED (name), tree args,
1848 int ARG_UNUSED (flags), bool *no_add_attrs)
1850 tree decl = *node;
1852 if (!targetm_common.have_named_sections)
1854 error_at (DECL_SOURCE_LOCATION (*node),
1855 "section attributes are not supported for this target");
1856 goto fail;
1859 if (!VAR_OR_FUNCTION_DECL_P (decl))
1861 error ("section attribute not allowed for %q+D", *node);
1862 goto fail;
1865 if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
1867 error ("section attribute argument not a string constant");
1868 goto fail;
1871 if (VAR_P (decl)
1872 && current_function_decl != NULL_TREE
1873 && !TREE_STATIC (decl))
1875 error_at (DECL_SOURCE_LOCATION (decl),
1876 "section attribute cannot be specified for local variables");
1877 goto fail;
1880 /* The decl may have already been given a section attribute
1881 from a previous declaration. Ensure they match. */
1882 if (DECL_SECTION_NAME (decl) != NULL
1883 && strcmp (DECL_SECTION_NAME (decl),
1884 TREE_STRING_POINTER (TREE_VALUE (args))) != 0)
1886 error ("section of %q+D conflicts with previous declaration", *node);
1887 goto fail;
1890 if (VAR_P (decl)
1891 && !targetm.have_tls && targetm.emutls.tmpl_section
1892 && DECL_THREAD_LOCAL_P (decl))
1894 error ("section of %q+D cannot be overridden", *node);
1895 goto fail;
1898 set_decl_section_name (decl, TREE_STRING_POINTER (TREE_VALUE (args)));
1899 return NULL_TREE;
1901 fail:
1902 *no_add_attrs = true;
1903 return NULL_TREE;
1906 /* If in c++-11, check if the c++-11 alignment constraint with respect
1907 to fundamental alignment (in [dcl.align]) are satisfied. If not in
1908 c++-11 mode, does nothing.
1910 [dcl.align]2/ says:
1912 [* if the constant expression evaluates to a fundamental alignment,
1913 the alignment requirement of the declared entity shall be the
1914 specified fundamental alignment.
1916 * if the constant expression evaluates to an extended alignment
1917 and the implementation supports that alignment in the context
1918 of the declaration, the alignment of the declared entity shall
1919 be that alignment
1921 * if the constant expression evaluates to an extended alignment
1922 and the implementation does not support that alignment in the
1923 context of the declaration, the program is ill-formed]. */
1925 static bool
1926 check_cxx_fundamental_alignment_constraints (tree node,
1927 unsigned align_log,
1928 int flags)
1930 bool alignment_too_large_p = false;
1931 unsigned requested_alignment = (1U << align_log) * BITS_PER_UNIT;
1932 unsigned max_align = 0;
1934 if ((!(flags & ATTR_FLAG_CXX11) && !warn_cxx_compat)
1935 || (node == NULL_TREE || node == error_mark_node))
1936 return true;
1938 if (cxx_fundamental_alignment_p (requested_alignment))
1939 return true;
1941 if (VAR_P (node))
1943 if (TREE_STATIC (node) || DECL_EXTERNAL (node))
1944 /* For file scope variables and static members, the target supports
1945 alignments that are at most MAX_OFILE_ALIGNMENT. */
1946 max_align = MAX_OFILE_ALIGNMENT;
1947 else
1948 /* For stack variables, the target supports at most
1949 MAX_STACK_ALIGNMENT. */
1950 max_align = MAX_STACK_ALIGNMENT;
1951 if (requested_alignment > max_align)
1952 alignment_too_large_p = true;
1954 /* Let's be liberal for types and fields; don't limit their alignment any
1955 more than check_user_alignment already did. */
1957 if (alignment_too_large_p)
1958 pedwarn (input_location, OPT_Wattributes,
1959 "requested alignment %d is larger than %d",
1960 requested_alignment / BITS_PER_UNIT, max_align / BITS_PER_UNIT);
1962 return !alignment_too_large_p;
1965 /* Common codes shared by handle_warn_if_not_aligned_attribute and
1966 handle_aligned_attribute. */
1968 static tree
1969 common_handle_aligned_attribute (tree *node, tree name, tree args, int flags,
1970 bool *no_add_attrs,
1971 bool warn_if_not_aligned_p)
1973 tree decl = NULL_TREE;
1974 tree *type = NULL;
1975 bool is_type = false;
1976 tree align_expr;
1978 /* The last (already pushed) declaration with all validated attributes
1979 merged in or the current about-to-be-pushed one if one hasn't been
1980 yet. */
1981 tree last_decl = node[1] ? node[1] : *node;
1983 if (args)
1985 align_expr = TREE_VALUE (args);
1986 if (align_expr && TREE_CODE (align_expr) != IDENTIFIER_NODE
1987 && TREE_CODE (align_expr) != FUNCTION_DECL)
1988 align_expr = default_conversion (align_expr);
1990 else
1991 align_expr = size_int (ATTRIBUTE_ALIGNED_VALUE / BITS_PER_UNIT);
1993 if (DECL_P (*node))
1995 decl = *node;
1996 type = &TREE_TYPE (decl);
1997 is_type = TREE_CODE (*node) == TYPE_DECL;
1999 else if (TYPE_P (*node))
2000 type = node, is_type = true;
2002 /* True to consider invalid alignments greater than MAX_OFILE_ALIGNMENT. */
2003 bool objfile = (TREE_CODE (*node) == FUNCTION_DECL
2004 || (VAR_P (*node) && TREE_STATIC (*node)));
2005 /* Log2 of specified alignment. */
2006 int pow2align = check_user_alignment (align_expr, objfile,
2007 /* warn_zero = */ true);
2008 if (pow2align == -1
2009 || !check_cxx_fundamental_alignment_constraints (*node, pow2align, flags))
2011 *no_add_attrs = true;
2012 return NULL_TREE;
2015 /* The alignment in bits corresponding to the specified alignment. */
2016 unsigned bitalign = (1U << pow2align) * BITS_PER_UNIT;
2018 /* The alignment of the current declaration and that of the last
2019 pushed declaration, determined on demand below. */
2020 unsigned curalign = 0;
2021 unsigned lastalign = 0;
2023 /* True when SET_DECL_ALIGN() should be called for the decl when
2024 *NO_ADD_ATTRS is false. */
2025 bool set_align = true;
2026 if (is_type)
2028 if ((flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
2029 /* OK, modify the type in place. */;
2030 /* If we have a TYPE_DECL, then copy the type, so that we
2031 don't accidentally modify a builtin type. See pushdecl. */
2032 else if (decl && TREE_TYPE (decl) != error_mark_node
2033 && DECL_ORIGINAL_TYPE (decl) == NULL_TREE)
2035 tree tt = TREE_TYPE (decl);
2036 *type = build_variant_type_copy (*type);
2037 DECL_ORIGINAL_TYPE (decl) = tt;
2038 TYPE_NAME (*type) = decl;
2039 TREE_USED (*type) = TREE_USED (decl);
2040 TREE_TYPE (decl) = *type;
2042 else
2043 *type = build_variant_type_copy (*type);
2045 if (warn_if_not_aligned_p)
2047 SET_TYPE_WARN_IF_NOT_ALIGN (*type, bitalign);
2048 warn_if_not_aligned_p = false;
2050 else
2052 SET_TYPE_ALIGN (*type, bitalign);
2053 TYPE_USER_ALIGN (*type) = 1;
2056 else if (! VAR_OR_FUNCTION_DECL_P (decl)
2057 && TREE_CODE (decl) != FIELD_DECL)
2059 error ("alignment may not be specified for %q+D", decl);
2060 *no_add_attrs = true;
2062 else if (TREE_CODE (decl) == FUNCTION_DECL
2063 && ((curalign = DECL_ALIGN (decl)) > bitalign
2064 || ((lastalign = DECL_ALIGN (last_decl)) > bitalign)))
2066 /* Either a prior attribute on the same declaration or one
2067 on a prior declaration of the same function specifies
2068 stricter alignment than this attribute. */
2069 bool note = lastalign != 0;
2070 if (lastalign)
2071 curalign = lastalign;
2073 curalign /= BITS_PER_UNIT;
2074 unsigned newalign = bitalign / BITS_PER_UNIT;
2076 auto_diagnostic_group d;
2077 if ((DECL_USER_ALIGN (decl)
2078 || DECL_USER_ALIGN (last_decl)))
2080 if (warning (OPT_Wattributes,
2081 "ignoring attribute %<%E (%u)%> because it conflicts "
2082 "with attribute %<%E (%u)%>",
2083 name, newalign, name, curalign)
2084 && note)
2085 inform (DECL_SOURCE_LOCATION (last_decl),
2086 "previous declaration here");
2087 /* Only reject attempts to relax/override an alignment
2088 explicitly specified previously and accept declarations
2089 that appear to relax the implicit function alignment for
2090 the target. Both increasing and increasing the alignment
2091 set by -falign-functions setting is permitted. */
2092 *no_add_attrs = true;
2094 else if (!warn_if_not_aligned_p)
2096 /* Do not fail for attribute warn_if_not_aligned. Otherwise,
2097 silently avoid applying the alignment to the declaration
2098 because it's implicitly satisfied by the target. Apply
2099 the attribute nevertheless so it can be retrieved by
2100 __builtin_has_attribute. */
2101 set_align = false;
2104 else if (DECL_USER_ALIGN (decl)
2105 && DECL_ALIGN (decl) > bitalign)
2106 /* C++-11 [dcl.align/4]:
2108 When multiple alignment-specifiers are specified for an
2109 entity, the alignment requirement shall be set to the
2110 strictest specified alignment.
2112 This formally comes from the c++11 specification but we are
2113 doing it for the GNU attribute syntax as well. */
2114 *no_add_attrs = true;
2115 else if (!warn_if_not_aligned_p
2116 && TREE_CODE (decl) == FUNCTION_DECL
2117 && DECL_ALIGN (decl) > bitalign)
2119 /* Don't warn for function alignment here if warn_if_not_aligned_p
2120 is true. It will be warned about later. */
2121 if (DECL_USER_ALIGN (decl))
2123 /* Only reject attempts to relax/override an alignment
2124 explicitly specified previously and accept declarations
2125 that appear to relax the implicit function alignment for
2126 the target. Both increasing and increasing the alignment
2127 set by -falign-functions setting is permitted. */
2128 error ("alignment for %q+D was previously specified as %d "
2129 "and may not be decreased", decl,
2130 DECL_ALIGN (decl) / BITS_PER_UNIT);
2131 *no_add_attrs = true;
2134 else if (warn_if_not_aligned_p
2135 && TREE_CODE (decl) == FIELD_DECL
2136 && !DECL_C_BIT_FIELD (decl))
2138 SET_DECL_WARN_IF_NOT_ALIGN (decl, bitalign);
2139 warn_if_not_aligned_p = false;
2140 set_align = false;
2143 if (warn_if_not_aligned_p)
2145 error ("%<warn_if_not_aligned%> may not be specified for %q+D",
2146 decl);
2147 *no_add_attrs = true;
2149 else if (!is_type && !*no_add_attrs && set_align)
2151 SET_DECL_ALIGN (decl, bitalign);
2152 DECL_USER_ALIGN (decl) = 1;
2155 return NULL_TREE;
2158 /* Handle a "aligned" attribute; arguments as in
2159 struct attribute_spec.handler. */
2161 static tree
2162 handle_aligned_attribute (tree *node, tree name, tree args,
2163 int flags, bool *no_add_attrs)
2165 return common_handle_aligned_attribute (node, name, args, flags,
2166 no_add_attrs, false);
2169 /* Handle a "warn_if_not_aligned" attribute; arguments as in
2170 struct attribute_spec.handler. */
2172 static tree
2173 handle_warn_if_not_aligned_attribute (tree *node, tree name,
2174 tree args, int flags,
2175 bool *no_add_attrs)
2177 return common_handle_aligned_attribute (node, name, args, flags,
2178 no_add_attrs, true);
2181 /* Handle a "weak" attribute; arguments as in
2182 struct attribute_spec.handler. */
2184 static tree
2185 handle_weak_attribute (tree *node, tree name,
2186 tree ARG_UNUSED (args),
2187 int ARG_UNUSED (flags),
2188 bool * ARG_UNUSED (no_add_attrs))
2190 if (TREE_CODE (*node) == FUNCTION_DECL
2191 && DECL_DECLARED_INLINE_P (*node))
2193 warning (OPT_Wattributes, "inline function %q+D declared weak", *node);
2194 *no_add_attrs = true;
2196 else if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (*node)))
2198 error ("indirect function %q+D cannot be declared weak", *node);
2199 *no_add_attrs = true;
2200 return NULL_TREE;
2202 else if (VAR_OR_FUNCTION_DECL_P (*node))
2203 declare_weak (*node);
2204 else
2205 warning (OPT_Wattributes, "%qE attribute ignored", name);
2207 return NULL_TREE;
2210 /* Handle a "noplt" attribute; arguments as in
2211 struct attribute_spec.handler. */
2213 static tree
2214 handle_noplt_attribute (tree *node, tree name,
2215 tree ARG_UNUSED (args),
2216 int ARG_UNUSED (flags),
2217 bool * ARG_UNUSED (no_add_attrs))
2219 if (TREE_CODE (*node) != FUNCTION_DECL)
2221 warning (OPT_Wattributes,
2222 "%qE attribute is only applicable on functions", name);
2223 *no_add_attrs = true;
2224 return NULL_TREE;
2226 return NULL_TREE;
2229 /* Handle an "alias" or "ifunc" attribute; arguments as in
2230 struct attribute_spec.handler, except that IS_ALIAS tells us
2231 whether this is an alias as opposed to ifunc attribute. */
2233 static tree
2234 handle_alias_ifunc_attribute (bool is_alias, tree *node, tree name, tree args,
2235 bool *no_add_attrs)
2237 tree decl = *node;
2239 if (TREE_CODE (decl) != FUNCTION_DECL
2240 && (!is_alias || !VAR_P (decl)))
2242 warning (OPT_Wattributes, "%qE attribute ignored", name);
2243 *no_add_attrs = true;
2245 else if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl))
2246 || (TREE_CODE (decl) != FUNCTION_DECL
2247 && TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl))
2248 /* A static variable declaration is always a tentative definition,
2249 but the alias is a non-tentative definition which overrides. */
2250 || (TREE_CODE (decl) != FUNCTION_DECL
2251 && ! TREE_PUBLIC (decl) && DECL_INITIAL (decl)))
2253 error ("%q+D defined both normally and as %qE attribute", decl, name);
2254 *no_add_attrs = true;
2255 return NULL_TREE;
2257 else if (!is_alias
2258 && (lookup_attribute ("weak", DECL_ATTRIBUTES (decl))
2259 || lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))))
2261 error ("weak %q+D cannot be defined %qE", decl, name);
2262 *no_add_attrs = true;
2263 return NULL_TREE;
2266 /* Note that the very first time we process a nested declaration,
2267 decl_function_context will not be set. Indeed, *would* never
2268 be set except for the DECL_INITIAL/DECL_EXTERNAL frobbery that
2269 we do below. After such frobbery, pushdecl would set the context.
2270 In any case, this is never what we want. */
2271 else if (decl_function_context (decl) == 0 && current_function_decl == NULL)
2273 tree id;
2275 id = TREE_VALUE (args);
2276 if (TREE_CODE (id) != STRING_CST)
2278 error ("attribute %qE argument not a string", name);
2279 *no_add_attrs = true;
2280 return NULL_TREE;
2282 id = get_identifier (TREE_STRING_POINTER (id));
2283 /* This counts as a use of the object pointed to. */
2284 TREE_USED (id) = 1;
2286 if (TREE_CODE (decl) == FUNCTION_DECL)
2287 DECL_INITIAL (decl) = error_mark_node;
2288 else
2289 TREE_STATIC (decl) = 1;
2291 if (!is_alias)
2293 /* ifuncs are also aliases, so set that attribute too. */
2294 DECL_ATTRIBUTES (decl)
2295 = tree_cons (get_identifier ("alias"), args,
2296 DECL_ATTRIBUTES (decl));
2297 DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("ifunc"),
2298 NULL, DECL_ATTRIBUTES (decl));
2301 else
2303 warning (OPT_Wattributes, "%qE attribute ignored", name);
2304 *no_add_attrs = true;
2307 if (decl_in_symtab_p (*node))
2309 struct symtab_node *n = symtab_node::get (decl);
2310 if (n && n->refuse_visibility_changes)
2312 if (is_alias)
2313 error ("%+qD declared alias after being used", decl);
2314 else
2315 error ("%+qD declared ifunc after being used", decl);
2320 return NULL_TREE;
2323 /* Handle an "alias" or "ifunc" attribute; arguments as in
2324 struct attribute_spec.handler. */
2326 static tree
2327 handle_ifunc_attribute (tree *node, tree name, tree args,
2328 int ARG_UNUSED (flags), bool *no_add_attrs)
2330 return handle_alias_ifunc_attribute (false, node, name, args, no_add_attrs);
2333 /* Handle an "alias" or "ifunc" attribute; arguments as in
2334 struct attribute_spec.handler. */
2336 static tree
2337 handle_alias_attribute (tree *node, tree name, tree args,
2338 int ARG_UNUSED (flags), bool *no_add_attrs)
2340 return handle_alias_ifunc_attribute (true, node, name, args, no_add_attrs);
2343 /* Handle the "copy" attribute NAME by copying the set of attributes
2344 from the symbol referenced by ARGS to the declaration of *NODE. */
2346 static tree
2347 handle_copy_attribute (tree *node, tree name, tree args,
2348 int flags, bool *no_add_attrs)
2350 /* Do not apply the copy attribute itself. It serves no purpose
2351 other than to copy other attributes. */
2352 *no_add_attrs = true;
2354 tree decl = *node;
2356 tree ref = TREE_VALUE (args);
2357 if (ref == error_mark_node)
2358 return NULL_TREE;
2360 if (TREE_CODE (ref) == STRING_CST)
2362 /* Explicitly handle this case since using a string literal
2363 as an argument is a likely mistake. */
2364 error_at (DECL_SOURCE_LOCATION (decl),
2365 "%qE attribute argument cannot be a string",
2366 name);
2367 return NULL_TREE;
2370 if (CONSTANT_CLASS_P (ref)
2371 && (INTEGRAL_TYPE_P (TREE_TYPE (ref))
2372 || FLOAT_TYPE_P (TREE_TYPE (ref))))
2374 /* Similar to the string case, since some function attributes
2375 accept literal numbers as arguments (e.g., alloc_size or
2376 nonnull) using one here is a likely mistake. */
2377 error_at (DECL_SOURCE_LOCATION (decl),
2378 "%qE attribute argument cannot be a constant arithmetic "
2379 "expression",
2380 name);
2381 return NULL_TREE;
2384 if (ref == node[1])
2386 /* Another possible mistake (but indirect self-references aren't
2387 and diagnosed and shouldn't be). */
2388 if (warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
2389 "%qE attribute ignored on a redeclaration "
2390 "of the referenced symbol",
2391 name))
2392 inform (DECL_SOURCE_LOCATION (node[1]),
2393 "previous declaration here");
2394 return NULL_TREE;
2397 /* Consider address-of expressions in the attribute argument
2398 as requests to copy from the referenced entity. For constant
2399 expressions, consider those to be requests to copy from their
2400 type, such as in:
2401 struct __attribute__ (copy ((struct T *)0)) U { ... };
2402 which copies type attributes from struct T to the declaration
2403 of struct U. */
2404 if (TREE_CODE (ref) == ADDR_EXPR)
2405 ref = TREE_OPERAND (ref, 0);
2406 else if (CONSTANT_CLASS_P (ref))
2407 ref = TREE_TYPE (ref);
2409 if (DECL_P (decl))
2411 if ((VAR_P (decl)
2412 && (TREE_CODE (ref) == FUNCTION_DECL
2413 || (EXPR_P (ref)
2414 && POINTER_TYPE_P (TREE_TYPE (ref))
2415 && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (ref))))))
2416 || (TREE_CODE (decl) == FUNCTION_DECL
2417 && (VAR_P (ref)
2418 || (EXPR_P (ref)
2419 && !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (ref))))))
2421 /* It makes no sense to try to copy function attributes
2422 to a variable, or variable attributes to a function. */
2423 if (warning (OPT_Wattributes,
2424 "%qE attribute ignored on a declaration of "
2425 "a different kind than referenced symbol",
2426 name)
2427 && DECL_P (ref))
2428 inform (DECL_SOURCE_LOCATION (ref),
2429 "symbol %qD referenced by %qD declared here", ref, decl);
2430 return NULL_TREE;
2433 tree attrs = NULL_TREE;
2434 if (DECL_P (ref))
2435 attrs = DECL_ATTRIBUTES (ref);
2436 else if (TYPE_P (ref))
2437 attrs = TYPE_ATTRIBUTES (ref);
2439 /* Copy decl attributes from REF to DECL. */
2440 for (tree at = attrs; at; at = TREE_CHAIN (at))
2442 /* Avoid copying attributes that affect a symbol linkage,
2443 inlining, or visibility since those in all likelihood
2444 only apply to the target.
2445 FIXME: make it possible to specify which attributes to
2446 copy or not to copy in the copy attribute itself. */
2447 tree atname = get_attribute_name (at);
2448 if (is_attribute_p ("alias", atname)
2449 || is_attribute_p ("always_inline", atname)
2450 || is_attribute_p ("gnu_inline", atname)
2451 || is_attribute_p ("ifunc", atname)
2452 || is_attribute_p ("noinline", atname)
2453 || is_attribute_p ("visibility", atname)
2454 || is_attribute_p ("weak", atname)
2455 || is_attribute_p ("weakref", atname))
2456 continue;
2458 tree atargs = TREE_VALUE (at);
2459 /* Create a copy of just the one attribute ar AT, including
2460 its argumentsm and add it to DECL. */
2461 tree attr = tree_cons (atname, copy_list (atargs), NULL_TREE);
2462 decl_attributes (node, attr, flags, ref);
2465 /* Proceed to copy type attributes below. */
2467 else if (!TYPE_P (decl))
2469 error_at (DECL_SOURCE_LOCATION (decl),
2470 "%qE attribute must apply to a declaration",
2471 name);
2472 return NULL_TREE;
2475 tree reftype = ref;
2476 if (DECL_P (ref) || EXPR_P (ref))
2477 reftype = TREE_TYPE (ref);
2479 if (POINTER_TYPE_P (reftype))
2480 reftype = TREE_TYPE (reftype);
2482 tree attrs = TYPE_ATTRIBUTES (reftype);
2484 /* Copy type attributes from REF to DECL. */
2485 for (tree at = attrs; at; at = TREE_CHAIN (at))
2486 decl_attributes (node, at, flags, ref);
2488 return NULL_TREE;
2491 /* Handle a "weakref" attribute; arguments as in struct
2492 attribute_spec.handler. */
2494 static tree
2495 handle_weakref_attribute (tree *node, tree ARG_UNUSED (name), tree args,
2496 int flags, bool *no_add_attrs)
2498 tree attr = NULL_TREE;
2500 /* We must ignore the attribute when it is associated with
2501 local-scoped decls, since attribute alias is ignored and many
2502 such symbols do not even have a DECL_WEAK field. */
2503 if (decl_function_context (*node)
2504 || current_function_decl
2505 || !VAR_OR_FUNCTION_DECL_P (*node))
2507 warning (OPT_Wattributes, "%qE attribute ignored", name);
2508 *no_add_attrs = true;
2509 return NULL_TREE;
2512 if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (*node)))
2514 error ("indirect function %q+D cannot be declared weakref", *node);
2515 *no_add_attrs = true;
2516 return NULL_TREE;
2519 /* The idea here is that `weakref("name")' mutates into `weakref,
2520 alias("name")', and weakref without arguments, in turn,
2521 implicitly adds weak. */
2523 if (args)
2525 attr = tree_cons (get_identifier ("alias"), args, attr);
2526 attr = tree_cons (get_identifier ("weakref"), NULL_TREE, attr);
2528 *no_add_attrs = true;
2530 decl_attributes (node, attr, flags);
2532 else
2534 if (lookup_attribute ("alias", DECL_ATTRIBUTES (*node)))
2535 error_at (DECL_SOURCE_LOCATION (*node),
2536 "weakref attribute must appear before alias attribute");
2538 /* Can't call declare_weak because it wants this to be TREE_PUBLIC,
2539 and that isn't supported; and because it wants to add it to
2540 the list of weak decls, which isn't helpful. */
2541 DECL_WEAK (*node) = 1;
2544 if (decl_in_symtab_p (*node))
2546 struct symtab_node *n = symtab_node::get (*node);
2547 if (n && n->refuse_visibility_changes)
2548 error ("%+qD declared weakref after being used", *node);
2551 return NULL_TREE;
2554 /* Handle an "visibility" attribute; arguments as in
2555 struct attribute_spec.handler. */
2557 static tree
2558 handle_visibility_attribute (tree *node, tree name, tree args,
2559 int ARG_UNUSED (flags),
2560 bool *ARG_UNUSED (no_add_attrs))
2562 tree decl = *node;
2563 tree id = TREE_VALUE (args);
2564 enum symbol_visibility vis;
2566 if (TYPE_P (*node))
2568 if (TREE_CODE (*node) == ENUMERAL_TYPE)
2569 /* OK */;
2570 else if (!RECORD_OR_UNION_TYPE_P (*node))
2572 warning (OPT_Wattributes, "%qE attribute ignored on non-class types",
2573 name);
2574 return NULL_TREE;
2576 else if (TYPE_FIELDS (*node))
2578 error ("%qE attribute ignored because %qT is already defined",
2579 name, *node);
2580 return NULL_TREE;
2583 else if (decl_function_context (decl) != 0 || !TREE_PUBLIC (decl))
2585 warning (OPT_Wattributes, "%qE attribute ignored", name);
2586 return NULL_TREE;
2589 if (TREE_CODE (id) != STRING_CST)
2591 error ("visibility argument not a string");
2592 return NULL_TREE;
2595 /* If this is a type, set the visibility on the type decl. */
2596 if (TYPE_P (decl))
2598 decl = TYPE_NAME (decl);
2599 if (!decl)
2600 return NULL_TREE;
2601 if (TREE_CODE (decl) == IDENTIFIER_NODE)
2603 warning (OPT_Wattributes, "%qE attribute ignored on types",
2604 name);
2605 return NULL_TREE;
2609 if (strcmp (TREE_STRING_POINTER (id), "default") == 0)
2610 vis = VISIBILITY_DEFAULT;
2611 else if (strcmp (TREE_STRING_POINTER (id), "internal") == 0)
2612 vis = VISIBILITY_INTERNAL;
2613 else if (strcmp (TREE_STRING_POINTER (id), "hidden") == 0)
2614 vis = VISIBILITY_HIDDEN;
2615 else if (strcmp (TREE_STRING_POINTER (id), "protected") == 0)
2616 vis = VISIBILITY_PROTECTED;
2617 else
2619 error ("visibility argument must be one of \"default\", \"hidden\", \"protected\" or \"internal\"");
2620 vis = VISIBILITY_DEFAULT;
2623 if (DECL_VISIBILITY_SPECIFIED (decl)
2624 && vis != DECL_VISIBILITY (decl))
2626 tree attributes = (TYPE_P (*node)
2627 ? TYPE_ATTRIBUTES (*node)
2628 : DECL_ATTRIBUTES (decl));
2629 if (lookup_attribute ("visibility", attributes))
2630 error ("%qD redeclared with different visibility", decl);
2631 else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
2632 && lookup_attribute ("dllimport", attributes))
2633 error ("%qD was declared %qs which implies default visibility",
2634 decl, "dllimport");
2635 else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
2636 && lookup_attribute ("dllexport", attributes))
2637 error ("%qD was declared %qs which implies default visibility",
2638 decl, "dllexport");
2641 DECL_VISIBILITY (decl) = vis;
2642 DECL_VISIBILITY_SPECIFIED (decl) = 1;
2644 /* Go ahead and attach the attribute to the node as well. This is needed
2645 so we can determine whether we have VISIBILITY_DEFAULT because the
2646 visibility was not specified, or because it was explicitly overridden
2647 from the containing scope. */
2649 return NULL_TREE;
2652 /* Handle an "tls_model" attribute; arguments as in
2653 struct attribute_spec.handler. */
2655 static tree
2656 handle_tls_model_attribute (tree *node, tree name, tree args,
2657 int ARG_UNUSED (flags),
2658 bool *ARG_UNUSED (no_add_attrs))
2660 tree id;
2661 tree decl = *node;
2662 enum tls_model kind;
2664 if (!VAR_P (decl))
2666 warning (OPT_Wattributes, "%qE attribute ignored because %qD "
2667 "is not a variable",
2668 name, decl);
2669 return NULL_TREE;
2672 if (!DECL_THREAD_LOCAL_P (decl))
2674 warning (OPT_Wattributes, "%qE attribute ignored because %qD does "
2675 "not have thread storage duration", name, decl);
2676 return NULL_TREE;
2679 kind = DECL_TLS_MODEL (decl);
2680 id = TREE_VALUE (args);
2681 if (TREE_CODE (id) != STRING_CST)
2683 error ("%qE argument not a string", name);
2684 return NULL_TREE;
2687 if (!strcmp (TREE_STRING_POINTER (id), "local-exec"))
2688 kind = TLS_MODEL_LOCAL_EXEC;
2689 else if (!strcmp (TREE_STRING_POINTER (id), "initial-exec"))
2690 kind = TLS_MODEL_INITIAL_EXEC;
2691 else if (!strcmp (TREE_STRING_POINTER (id), "local-dynamic"))
2692 kind = optimize ? TLS_MODEL_LOCAL_DYNAMIC : TLS_MODEL_GLOBAL_DYNAMIC;
2693 else if (!strcmp (TREE_STRING_POINTER (id), "global-dynamic"))
2694 kind = TLS_MODEL_GLOBAL_DYNAMIC;
2695 else
2696 error ("%qE argument must be one of %qs, %qs, %qs, or %qs",
2697 name,
2698 "local-exec", "initial-exec", "local-dynamic", "global-dynamic");
2700 set_decl_tls_model (decl, kind);
2701 return NULL_TREE;
2704 /* Handle a "no_instrument_function" attribute; arguments as in
2705 struct attribute_spec.handler. */
2707 static tree
2708 handle_no_instrument_function_attribute (tree *node, tree name,
2709 tree ARG_UNUSED (args),
2710 int ARG_UNUSED (flags),
2711 bool *no_add_attrs)
2713 tree decl = *node;
2715 if (TREE_CODE (decl) != FUNCTION_DECL)
2717 error_at (DECL_SOURCE_LOCATION (decl),
2718 "%qE attribute applies only to functions", name);
2719 *no_add_attrs = true;
2721 else
2722 DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
2724 return NULL_TREE;
2727 /* Handle a "no_profile_instrument_function" attribute; arguments as in
2728 struct attribute_spec.handler. */
2730 static tree
2731 handle_no_profile_instrument_function_attribute (tree *node, tree name, tree,
2732 int, bool *no_add_attrs)
2734 if (TREE_CODE (*node) != FUNCTION_DECL)
2736 warning (OPT_Wattributes, "%qE attribute ignored", name);
2737 *no_add_attrs = true;
2740 return NULL_TREE;
2743 /* Handle a "malloc" attribute; arguments as in
2744 struct attribute_spec.handler. */
2746 static tree
2747 handle_malloc_attribute (tree *node, tree name, tree ARG_UNUSED (args),
2748 int ARG_UNUSED (flags), bool *no_add_attrs)
2750 if (TREE_CODE (*node) == FUNCTION_DECL
2751 && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*node))))
2752 DECL_IS_MALLOC (*node) = 1;
2753 else
2755 warning (OPT_Wattributes, "%qE attribute ignored", name);
2756 *no_add_attrs = true;
2759 return NULL_TREE;
2762 /* Handle a "alloc_size" attribute; arguments as in
2763 struct attribute_spec.handler. */
2765 static tree
2766 handle_alloc_size_attribute (tree *node, tree name, tree args,
2767 int ARG_UNUSED (flags), bool *no_add_attrs)
2769 tree decl = *node;
2770 tree rettype = TREE_TYPE (decl);
2771 if (!POINTER_TYPE_P (rettype))
2773 warning (OPT_Wattributes,
2774 "%qE attribute ignored on a function returning %qT",
2775 name, rettype);
2776 *no_add_attrs = true;
2777 return NULL_TREE;
2780 for (int i = 1; args; ++i)
2782 tree pos = TREE_VALUE (args);
2783 /* NEXT is null when the attribute includes just one argument.
2784 That's used to tell positional_argument to avoid mentioning
2785 the argument number in diagnostics (since there's just one
2786 mentioning it is unnecessary and coule be confusing). */
2787 tree next = TREE_CHAIN (args);
2788 if (tree val = positional_argument (decl, name, pos, INTEGER_TYPE,
2789 next || i > 1 ? i : 0))
2790 TREE_VALUE (args) = val;
2791 else
2793 *no_add_attrs = true;
2794 break;
2797 args = next;
2800 return NULL_TREE;
2803 /* Handle a "alloc_align" attribute; arguments as in
2804 struct attribute_spec.handler. */
2806 static tree
2807 handle_alloc_align_attribute (tree *node, tree name, tree args, int,
2808 bool *no_add_attrs)
2810 tree decl = *node;
2811 tree rettype = TREE_TYPE (decl);
2812 if (!POINTER_TYPE_P (rettype))
2814 warning (OPT_Wattributes,
2815 "%qE attribute ignored on a function returning %qT",
2816 name, rettype);
2817 *no_add_attrs = true;
2818 return NULL_TREE;
2821 if (!positional_argument (*node, name, TREE_VALUE (args), INTEGER_TYPE))
2822 *no_add_attrs = true;
2824 return NULL_TREE;
2827 /* Handle a "assume_aligned" attribute; arguments as in
2828 struct attribute_spec.handler. */
2830 static tree
2831 handle_assume_aligned_attribute (tree *node, tree name, tree args, int,
2832 bool *no_add_attrs)
2834 tree decl = *node;
2835 tree rettype = TREE_TYPE (decl);
2836 if (TREE_CODE (rettype) != POINTER_TYPE)
2838 warning (OPT_Wattributes,
2839 "%qE attribute ignored on a function returning %qT",
2840 name, rettype);
2841 *no_add_attrs = true;
2842 return NULL_TREE;
2845 /* The alignment specified by the first argument. */
2846 tree align = NULL_TREE;
2848 for (; args; args = TREE_CHAIN (args))
2850 tree val = TREE_VALUE (args);
2851 if (val && TREE_CODE (val) != IDENTIFIER_NODE
2852 && TREE_CODE (val) != FUNCTION_DECL)
2853 val = default_conversion (val);
2855 if (!tree_fits_shwi_p (val))
2857 warning (OPT_Wattributes,
2858 "%qE attribute %E is not an integer constant",
2859 name, val);
2860 *no_add_attrs = true;
2861 return NULL_TREE;
2864 if (!align)
2866 /* Validate and save the alignment. */
2867 if (!integer_pow2p (val))
2869 warning (OPT_Wattributes,
2870 "%qE attribute argument %E is not a power of 2",
2871 name, val);
2872 *no_add_attrs = true;
2873 return NULL_TREE;
2876 align = val;
2878 else if (tree_int_cst_sgn (val) < 0 || tree_int_cst_le (align, val))
2880 /* The misalignment specified by the second argument
2881 must be non-negative and less than the alignment. */
2882 warning (OPT_Wattributes,
2883 "%qE attribute argument %E is not in the range [0, %E)",
2884 name, val, align);
2885 *no_add_attrs = true;
2886 return NULL_TREE;
2889 return NULL_TREE;
2892 /* Handle a "fn spec" attribute; arguments as in
2893 struct attribute_spec.handler. */
2895 static tree
2896 handle_fnspec_attribute (tree *node ATTRIBUTE_UNUSED, tree ARG_UNUSED (name),
2897 tree args, int ARG_UNUSED (flags),
2898 bool *no_add_attrs ATTRIBUTE_UNUSED)
2900 gcc_assert (args
2901 && TREE_CODE (TREE_VALUE (args)) == STRING_CST
2902 && !TREE_CHAIN (args));
2903 return NULL_TREE;
2906 /* Handle a "warn_unused" attribute; arguments as in
2907 struct attribute_spec.handler. */
2909 static tree
2910 handle_warn_unused_attribute (tree *node, tree name,
2911 tree args ATTRIBUTE_UNUSED,
2912 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
2914 if (TYPE_P (*node))
2915 /* Do nothing else, just set the attribute. We'll get at
2916 it later with lookup_attribute. */
2918 else
2920 warning (OPT_Wattributes, "%qE attribute ignored", name);
2921 *no_add_attrs = true;
2924 return NULL_TREE;
2927 /* Handle an "omp declare simd" attribute; arguments as in
2928 struct attribute_spec.handler. */
2930 static tree
2931 handle_omp_declare_simd_attribute (tree *, tree, tree, int, bool *)
2933 return NULL_TREE;
2936 /* Handle a "simd" attribute. */
2938 static tree
2939 handle_simd_attribute (tree *node, tree name, tree args, int, bool *no_add_attrs)
2941 if (TREE_CODE (*node) == FUNCTION_DECL)
2943 tree t = get_identifier ("omp declare simd");
2944 tree attr = NULL_TREE;
2945 if (args)
2947 tree id = TREE_VALUE (args);
2949 if (TREE_CODE (id) != STRING_CST)
2951 error ("attribute %qE argument not a string", name);
2952 *no_add_attrs = true;
2953 return NULL_TREE;
2956 if (strcmp (TREE_STRING_POINTER (id), "notinbranch") == 0)
2957 attr = build_omp_clause (DECL_SOURCE_LOCATION (*node),
2958 OMP_CLAUSE_NOTINBRANCH);
2959 else if (strcmp (TREE_STRING_POINTER (id), "inbranch") == 0)
2960 attr = build_omp_clause (DECL_SOURCE_LOCATION (*node),
2961 OMP_CLAUSE_INBRANCH);
2962 else
2964 error ("only %<inbranch%> and %<notinbranch%> flags are "
2965 "allowed for %<__simd__%> attribute");
2966 *no_add_attrs = true;
2967 return NULL_TREE;
2971 DECL_ATTRIBUTES (*node)
2972 = tree_cons (t, build_tree_list (NULL_TREE, attr),
2973 DECL_ATTRIBUTES (*node));
2975 else
2977 warning (OPT_Wattributes, "%qE attribute ignored", name);
2978 *no_add_attrs = true;
2981 return NULL_TREE;
2984 /* Handle an "omp declare target" attribute; arguments as in
2985 struct attribute_spec.handler. */
2987 static tree
2988 handle_omp_declare_target_attribute (tree *, tree, tree, int, bool *)
2990 return NULL_TREE;
2993 /* Handle a "returns_twice" attribute; arguments as in
2994 struct attribute_spec.handler. */
2996 static tree
2997 handle_returns_twice_attribute (tree *node, tree name, tree ARG_UNUSED (args),
2998 int ARG_UNUSED (flags), bool *no_add_attrs)
3000 if (TREE_CODE (*node) == FUNCTION_DECL)
3001 DECL_IS_RETURNS_TWICE (*node) = 1;
3002 else
3004 warning (OPT_Wattributes, "%qE attribute ignored", name);
3005 *no_add_attrs = true;
3008 return NULL_TREE;
3011 /* Handle a "no_limit_stack" attribute; arguments as in
3012 struct attribute_spec.handler. */
3014 static tree
3015 handle_no_limit_stack_attribute (tree *node, tree name,
3016 tree ARG_UNUSED (args),
3017 int ARG_UNUSED (flags),
3018 bool *no_add_attrs)
3020 tree decl = *node;
3022 if (TREE_CODE (decl) != FUNCTION_DECL)
3024 error_at (DECL_SOURCE_LOCATION (decl),
3025 "%qE attribute applies only to functions", name);
3026 *no_add_attrs = true;
3028 else if (DECL_INITIAL (decl))
3030 error_at (DECL_SOURCE_LOCATION (decl),
3031 "can%'t set %qE attribute after definition", name);
3032 *no_add_attrs = true;
3034 else
3035 DECL_NO_LIMIT_STACK (decl) = 1;
3037 return NULL_TREE;
3040 /* Handle a "pure" attribute; arguments as in
3041 struct attribute_spec.handler. */
3043 static tree
3044 handle_pure_attribute (tree *node, tree name, tree ARG_UNUSED (args),
3045 int ARG_UNUSED (flags), bool *no_add_attrs)
3047 if (TREE_CODE (*node) == FUNCTION_DECL)
3049 tree type = TREE_TYPE (*node);
3050 if (VOID_TYPE_P (TREE_TYPE (type)))
3051 warning (OPT_Wattributes, "%qE attribute on function "
3052 "returning %<void%>", name);
3054 DECL_PURE_P (*node) = 1;
3055 /* ??? TODO: Support types. */
3057 else
3059 warning (OPT_Wattributes, "%qE attribute ignored", name);
3060 *no_add_attrs = true;
3063 return NULL_TREE;
3066 /* Digest an attribute list destined for a transactional memory statement.
3067 ALLOWED is the set of attributes that are allowed for this statement;
3068 return the attribute we parsed. Multiple attributes are never allowed. */
3071 parse_tm_stmt_attr (tree attrs, int allowed)
3073 tree a_seen = NULL;
3074 int m_seen = 0;
3076 for ( ; attrs ; attrs = TREE_CHAIN (attrs))
3078 tree a = TREE_PURPOSE (attrs);
3079 int m = 0;
3081 if (is_attribute_p ("outer", a))
3082 m = TM_STMT_ATTR_OUTER;
3084 if ((m & allowed) == 0)
3086 warning (OPT_Wattributes, "%qE attribute directive ignored", a);
3087 continue;
3090 if (m_seen == 0)
3092 a_seen = a;
3093 m_seen = m;
3095 else if (m_seen == m)
3096 warning (OPT_Wattributes, "%qE attribute duplicated", a);
3097 else
3098 warning (OPT_Wattributes, "%qE attribute follows %qE", a, a_seen);
3101 return m_seen;
3104 /* Transform a TM attribute name into a maskable integer and back.
3105 Note that NULL (i.e. no attribute) is mapped to UNKNOWN, corresponding
3106 to how the lack of an attribute is treated. */
3109 tm_attr_to_mask (tree attr)
3111 if (attr == NULL)
3112 return 0;
3113 if (is_attribute_p ("transaction_safe", attr))
3114 return TM_ATTR_SAFE;
3115 if (is_attribute_p ("transaction_callable", attr))
3116 return TM_ATTR_CALLABLE;
3117 if (is_attribute_p ("transaction_pure", attr))
3118 return TM_ATTR_PURE;
3119 if (is_attribute_p ("transaction_unsafe", attr))
3120 return TM_ATTR_IRREVOCABLE;
3121 if (is_attribute_p ("transaction_may_cancel_outer", attr))
3122 return TM_ATTR_MAY_CANCEL_OUTER;
3123 return 0;
3126 tree
3127 tm_mask_to_attr (int mask)
3129 const char *str;
3130 switch (mask)
3132 case TM_ATTR_SAFE:
3133 str = "transaction_safe";
3134 break;
3135 case TM_ATTR_CALLABLE:
3136 str = "transaction_callable";
3137 break;
3138 case TM_ATTR_PURE:
3139 str = "transaction_pure";
3140 break;
3141 case TM_ATTR_IRREVOCABLE:
3142 str = "transaction_unsafe";
3143 break;
3144 case TM_ATTR_MAY_CANCEL_OUTER:
3145 str = "transaction_may_cancel_outer";
3146 break;
3147 default:
3148 gcc_unreachable ();
3150 return get_identifier (str);
3153 /* Return the first TM attribute seen in LIST. */
3155 tree
3156 find_tm_attribute (tree list)
3158 for (; list ; list = TREE_CHAIN (list))
3160 tree name = TREE_PURPOSE (list);
3161 if (tm_attr_to_mask (name) != 0)
3162 return name;
3164 return NULL_TREE;
3167 /* Handle the TM attributes; arguments as in struct attribute_spec.handler.
3168 Here we accept only function types, and verify that none of the other
3169 function TM attributes are also applied. */
3170 /* ??? We need to accept class types for C++, but not C. This greatly
3171 complicates this function, since we can no longer rely on the extra
3172 processing given by function_type_required. */
3174 static tree
3175 handle_tm_attribute (tree *node, tree name, tree args,
3176 int flags, bool *no_add_attrs)
3178 /* Only one path adds the attribute; others don't. */
3179 *no_add_attrs = true;
3181 switch (TREE_CODE (*node))
3183 case RECORD_TYPE:
3184 case UNION_TYPE:
3185 /* Only tm_callable and tm_safe apply to classes. */
3186 if (tm_attr_to_mask (name) & ~(TM_ATTR_SAFE | TM_ATTR_CALLABLE))
3187 goto ignored;
3188 /* FALLTHRU */
3190 case FUNCTION_TYPE:
3191 case METHOD_TYPE:
3193 tree old_name = find_tm_attribute (TYPE_ATTRIBUTES (*node));
3194 if (old_name == name)
3196 else if (old_name != NULL_TREE)
3197 error ("type was previously declared %qE", old_name);
3198 else
3199 *no_add_attrs = false;
3201 break;
3203 case FUNCTION_DECL:
3205 /* transaction_safe_dynamic goes on the FUNCTION_DECL, but we also
3206 want to set transaction_safe on the type. */
3207 gcc_assert (is_attribute_p ("transaction_safe_dynamic", name));
3208 if (!TYPE_P (DECL_CONTEXT (*node)))
3209 error_at (DECL_SOURCE_LOCATION (*node),
3210 "%<transaction_safe_dynamic%> may only be specified for "
3211 "a virtual function");
3212 *no_add_attrs = false;
3213 decl_attributes (&TREE_TYPE (*node),
3214 build_tree_list (get_identifier ("transaction_safe"),
3215 NULL_TREE),
3217 break;
3220 case POINTER_TYPE:
3222 enum tree_code subcode = TREE_CODE (TREE_TYPE (*node));
3223 if (subcode == FUNCTION_TYPE || subcode == METHOD_TYPE)
3225 tree fn_tmp = TREE_TYPE (*node);
3226 decl_attributes (&fn_tmp, tree_cons (name, args, NULL), 0);
3227 *node = build_pointer_type (fn_tmp);
3228 break;
3231 /* FALLTHRU */
3233 default:
3234 /* If a function is next, pass it on to be tried next. */
3235 if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
3236 return tree_cons (name, args, NULL);
3238 ignored:
3239 warning (OPT_Wattributes, "%qE attribute ignored", name);
3240 break;
3243 return NULL_TREE;
3246 /* Handle the TM_WRAP attribute; arguments as in
3247 struct attribute_spec.handler. */
3249 static tree
3250 handle_tm_wrap_attribute (tree *node, tree name, tree args,
3251 int ARG_UNUSED (flags), bool *no_add_attrs)
3253 tree decl = *node;
3255 /* We don't need the attribute even on success, since we
3256 record the entry in an external table. */
3257 *no_add_attrs = true;
3259 if (TREE_CODE (decl) != FUNCTION_DECL)
3260 warning (OPT_Wattributes, "%qE attribute ignored", name);
3261 else
3263 tree wrap_decl = TREE_VALUE (args);
3264 if (error_operand_p (wrap_decl))
3266 else if (TREE_CODE (wrap_decl) != IDENTIFIER_NODE
3267 && !VAR_OR_FUNCTION_DECL_P (wrap_decl))
3268 error ("%qE argument not an identifier", name);
3269 else
3271 if (TREE_CODE (wrap_decl) == IDENTIFIER_NODE)
3272 wrap_decl = lookup_name (wrap_decl);
3273 if (wrap_decl && TREE_CODE (wrap_decl) == FUNCTION_DECL)
3275 if (lang_hooks.types_compatible_p (TREE_TYPE (decl),
3276 TREE_TYPE (wrap_decl)))
3277 record_tm_replacement (wrap_decl, decl);
3278 else
3279 error ("%qD is not compatible with %qD", wrap_decl, decl);
3281 else
3282 error ("%qE argument is not a function", name);
3286 return NULL_TREE;
3289 /* Ignore the given attribute. Used when this attribute may be usefully
3290 overridden by the target, but is not used generically. */
3292 static tree
3293 ignore_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name),
3294 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
3295 bool *no_add_attrs)
3297 *no_add_attrs = true;
3298 return NULL_TREE;
3301 /* Handle a "no vops" attribute; arguments as in
3302 struct attribute_spec.handler. */
3304 static tree
3305 handle_novops_attribute (tree *node, tree ARG_UNUSED (name),
3306 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
3307 bool *ARG_UNUSED (no_add_attrs))
3309 gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
3310 DECL_IS_NOVOPS (*node) = 1;
3311 return NULL_TREE;
3314 /* Handle a "deprecated" attribute; arguments as in
3315 struct attribute_spec.handler. */
3317 static tree
3318 handle_deprecated_attribute (tree *node, tree name,
3319 tree args, int flags,
3320 bool *no_add_attrs)
3322 tree type = NULL_TREE;
3323 int warn = 0;
3324 tree what = NULL_TREE;
3326 if (!args)
3327 *no_add_attrs = true;
3328 else if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
3330 error ("deprecated message is not a string");
3331 *no_add_attrs = true;
3334 if (DECL_P (*node))
3336 tree decl = *node;
3337 type = TREE_TYPE (decl);
3339 if (TREE_CODE (decl) == TYPE_DECL
3340 || TREE_CODE (decl) == PARM_DECL
3341 || VAR_OR_FUNCTION_DECL_P (decl)
3342 || TREE_CODE (decl) == FIELD_DECL
3343 || TREE_CODE (decl) == CONST_DECL
3344 || objc_method_decl (TREE_CODE (decl)))
3345 TREE_DEPRECATED (decl) = 1;
3346 else
3347 warn = 1;
3349 else if (TYPE_P (*node))
3351 if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
3352 *node = build_variant_type_copy (*node);
3353 TREE_DEPRECATED (*node) = 1;
3354 type = *node;
3356 else
3357 warn = 1;
3359 if (warn)
3361 *no_add_attrs = true;
3362 if (type && TYPE_NAME (type))
3364 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
3365 what = TYPE_NAME (*node);
3366 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
3367 && DECL_NAME (TYPE_NAME (type)))
3368 what = DECL_NAME (TYPE_NAME (type));
3370 if (what)
3371 warning (OPT_Wattributes, "%qE attribute ignored for %qE", name, what);
3372 else
3373 warning (OPT_Wattributes, "%qE attribute ignored", name);
3376 return NULL_TREE;
3379 /* Return the "base" type from TYPE that is suitable to apply attribute
3380 vector_size to by stripping arrays, function types, etc. */
3381 static tree
3382 type_for_vector_size (tree type)
3384 /* We need to provide for vector pointers, vector arrays, and
3385 functions returning vectors. For example:
3387 __attribute__((vector_size(16))) short *foo;
3389 In this case, the mode is SI, but the type being modified is
3390 HI, so we need to look further. */
3392 while (POINTER_TYPE_P (type)
3393 || TREE_CODE (type) == FUNCTION_TYPE
3394 || TREE_CODE (type) == METHOD_TYPE
3395 || TREE_CODE (type) == ARRAY_TYPE
3396 || TREE_CODE (type) == OFFSET_TYPE)
3397 type = TREE_TYPE (type);
3399 return type;
3402 /* Given TYPE, return the base type to which the vector_size attribute
3403 ATNAME with ARGS, when non-null, can be applied, if one exists.
3404 On success and when both ARGS and PTRNUNITS are non-null, set
3405 *PTRNUNINTS to the number of vector units. When PTRNUNITS is not
3406 null, issue a warning when the attribute argument is not constant
3407 and an error if there is no such type. Otherwise issue a warning
3408 in the latter case and return null. */
3410 static tree
3411 type_valid_for_vector_size (tree type, tree atname, tree args,
3412 unsigned HOST_WIDE_INT *ptrnunits)
3414 bool error_p = ptrnunits != NULL;
3416 /* Get the mode of the type being modified. */
3417 machine_mode orig_mode = TYPE_MODE (type);
3419 if ((!INTEGRAL_TYPE_P (type)
3420 && !SCALAR_FLOAT_TYPE_P (type)
3421 && !FIXED_POINT_TYPE_P (type))
3422 || (!SCALAR_FLOAT_MODE_P (orig_mode)
3423 && GET_MODE_CLASS (orig_mode) != MODE_INT
3424 && !ALL_SCALAR_FIXED_POINT_MODE_P (orig_mode))
3425 || !tree_fits_uhwi_p (TYPE_SIZE_UNIT (type))
3426 || TREE_CODE (type) == BOOLEAN_TYPE)
3428 if (error_p)
3429 error ("invalid vector type for attribute %qE", atname);
3430 else
3431 warning (OPT_Wattributes, "invalid vector type for attribute %qE",
3432 atname);
3433 return NULL_TREE;
3436 /* When no argument has been provided this is just a request to validate
3437 the type above. Return TYPE to indicate success. */
3438 if (!args)
3439 return type;
3441 tree size = TREE_VALUE (args);
3442 if (size && TREE_CODE (size) != IDENTIFIER_NODE
3443 && TREE_CODE (size) != FUNCTION_DECL)
3444 size = default_conversion (size);
3446 if (!tree_fits_uhwi_p (size))
3448 /* FIXME: make the error message more informative. */
3449 if (error_p)
3450 warning (OPT_Wattributes, "%qE attribute ignored", atname);
3451 return NULL_TREE;
3454 unsigned HOST_WIDE_INT vecsize = tree_to_uhwi (size);
3455 if (vecsize % tree_to_uhwi (TYPE_SIZE_UNIT (type)))
3457 if (error_p)
3458 error ("vector size not an integral multiple of component size");
3459 return NULL_TREE;
3462 if (vecsize == 0)
3464 error ("zero vector size");
3465 return NULL;
3468 /* Calculate how many units fit in the vector. */
3469 unsigned HOST_WIDE_INT nunits = vecsize / tree_to_uhwi (TYPE_SIZE_UNIT (type));
3470 if (nunits & (nunits - 1))
3472 if (error_p)
3473 error ("number of components of the vector not a power of two");
3474 else
3475 warning (OPT_Wattributes,
3476 "number of components of the vector not a power of two");
3477 return NULL_TREE;
3480 if (ptrnunits)
3481 *ptrnunits = nunits;
3483 return type;
3486 /* Handle a "vector_size" attribute; arguments as in
3487 struct attribute_spec.handler. */
3489 static tree
3490 handle_vector_size_attribute (tree *node, tree name, tree args,
3491 int ARG_UNUSED (flags),
3492 bool *no_add_attrs)
3494 *no_add_attrs = true;
3496 /* Determine the "base" type to apply the attribute to. */
3497 tree type = type_for_vector_size (*node);
3499 /* Get the vector size (in bytes) and let the function compute
3500 the number of vector units. */
3501 unsigned HOST_WIDE_INT nunits;
3502 type = type_valid_for_vector_size (type, name, args, &nunits);
3503 if (!type)
3504 return NULL_TREE;
3506 tree new_type = build_vector_type (type, nunits);
3508 /* Build back pointers if needed. */
3509 *node = lang_hooks.types.reconstruct_complex_type (*node, new_type);
3511 return NULL_TREE;
3514 /* Handle the "nonnull" attribute. */
3516 static tree
3517 handle_nonnull_attribute (tree *node, tree name,
3518 tree args, int ARG_UNUSED (flags),
3519 bool *no_add_attrs)
3521 tree type = *node;
3523 /* If no arguments are specified, all pointer arguments should be
3524 non-null. Verify a full prototype is given so that the arguments
3525 will have the correct types when we actually check them later.
3526 Avoid diagnosing type-generic built-ins since those have no
3527 prototype. */
3528 if (!args)
3530 if (!prototype_p (type)
3531 && (!TYPE_ATTRIBUTES (type)
3532 || !lookup_attribute ("type generic", TYPE_ATTRIBUTES (type))))
3534 error ("nonnull attribute without arguments on a non-prototype");
3535 *no_add_attrs = true;
3537 return NULL_TREE;
3540 for (int i = 1; args; ++i)
3542 tree pos = TREE_VALUE (args);
3543 /* NEXT is null when the attribute includes just one argument.
3544 That's used to tell positional_argument to avoid mentioning
3545 the argument number in diagnostics (since there's just one
3546 mentioning it is unnecessary and coule be confusing). */
3547 tree next = TREE_CHAIN (args);
3548 if (tree val = positional_argument (type, name, pos, POINTER_TYPE,
3549 next || i > 1 ? i : 0))
3550 TREE_VALUE (args) = val;
3551 else
3553 *no_add_attrs = true;
3554 break;
3556 args = next;
3559 return NULL_TREE;
3562 /* Handle the "nonstring" variable attribute. */
3564 static tree
3565 handle_nonstring_attribute (tree *node, tree name, tree ARG_UNUSED (args),
3566 int ARG_UNUSED (flags), bool *no_add_attrs)
3568 gcc_assert (!args);
3569 tree_code code = TREE_CODE (*node);
3571 if (VAR_P (*node)
3572 || code == FIELD_DECL
3573 || code == PARM_DECL)
3575 tree type = TREE_TYPE (*node);
3577 if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
3579 /* Accept the attribute on arrays and pointers to all three
3580 narrow character types. */
3581 tree eltype = TREE_TYPE (type);
3582 eltype = TYPE_MAIN_VARIANT (eltype);
3583 if (eltype == char_type_node
3584 || eltype == signed_char_type_node
3585 || eltype == unsigned_char_type_node)
3586 return NULL_TREE;
3589 warning (OPT_Wattributes,
3590 "%qE attribute ignored on objects of type %qT",
3591 name, type);
3592 *no_add_attrs = true;
3593 return NULL_TREE;
3596 if (code == FUNCTION_DECL)
3597 warning (OPT_Wattributes,
3598 "%qE attribute does not apply to functions", name);
3599 else if (code == TYPE_DECL)
3600 warning (OPT_Wattributes,
3601 "%qE attribute does not apply to types", name);
3602 else
3603 warning (OPT_Wattributes, "%qE attribute ignored", name);
3605 *no_add_attrs = true;
3606 return NULL_TREE;
3609 /* Handle a "nothrow" attribute; arguments as in
3610 struct attribute_spec.handler. */
3612 static tree
3613 handle_nothrow_attribute (tree *node, tree name, tree ARG_UNUSED (args),
3614 int ARG_UNUSED (flags), bool *no_add_attrs)
3616 if (TREE_CODE (*node) == FUNCTION_DECL)
3617 TREE_NOTHROW (*node) = 1;
3618 /* ??? TODO: Support types. */
3619 else
3621 warning (OPT_Wattributes, "%qE attribute ignored", name);
3622 *no_add_attrs = true;
3625 return NULL_TREE;
3628 /* Handle a "cleanup" attribute; arguments as in
3629 struct attribute_spec.handler. */
3631 static tree
3632 handle_cleanup_attribute (tree *node, tree name, tree args,
3633 int ARG_UNUSED (flags), bool *no_add_attrs)
3635 tree decl = *node;
3636 tree cleanup_id, cleanup_decl;
3638 /* ??? Could perhaps support cleanups on TREE_STATIC, much like we do
3639 for global destructors in C++. This requires infrastructure that
3640 we don't have generically at the moment. It's also not a feature
3641 we'd be missing too much, since we do have attribute constructor. */
3642 if (!VAR_P (decl) || TREE_STATIC (decl))
3644 warning (OPT_Wattributes, "%qE attribute ignored", name);
3645 *no_add_attrs = true;
3646 return NULL_TREE;
3649 /* Verify that the argument is a function in scope. */
3650 /* ??? We could support pointers to functions here as well, if
3651 that was considered desirable. */
3652 cleanup_id = TREE_VALUE (args);
3653 if (TREE_CODE (cleanup_id) != IDENTIFIER_NODE)
3655 error ("cleanup argument not an identifier");
3656 *no_add_attrs = true;
3657 return NULL_TREE;
3659 cleanup_decl = lookup_name (cleanup_id);
3660 if (!cleanup_decl || TREE_CODE (cleanup_decl) != FUNCTION_DECL)
3662 error ("cleanup argument not a function");
3663 *no_add_attrs = true;
3664 return NULL_TREE;
3667 /* That the function has proper type is checked with the
3668 eventual call to build_function_call. */
3670 return NULL_TREE;
3673 /* Handle a "warn_unused_result" attribute. No special handling. */
3675 static tree
3676 handle_warn_unused_result_attribute (tree *node, tree name,
3677 tree ARG_UNUSED (args),
3678 int ARG_UNUSED (flags), bool *no_add_attrs)
3680 /* Ignore the attribute for functions not returning any value. */
3681 if (VOID_TYPE_P (TREE_TYPE (*node)))
3683 warning (OPT_Wattributes, "%qE attribute ignored", name);
3684 *no_add_attrs = true;
3687 return NULL_TREE;
3690 /* Handle a "sentinel" attribute. */
3692 static tree
3693 handle_sentinel_attribute (tree *node, tree name, tree args,
3694 int ARG_UNUSED (flags), bool *no_add_attrs)
3696 if (!prototype_p (*node))
3698 warning (OPT_Wattributes,
3699 "%qE attribute requires prototypes with named arguments", name);
3700 *no_add_attrs = true;
3702 else
3704 if (!stdarg_p (*node))
3706 warning (OPT_Wattributes,
3707 "%qE attribute only applies to variadic functions", name);
3708 *no_add_attrs = true;
3712 if (args)
3714 tree position = TREE_VALUE (args);
3715 if (position && TREE_CODE (position) != IDENTIFIER_NODE
3716 && TREE_CODE (position) != FUNCTION_DECL)
3717 position = default_conversion (position);
3719 if (TREE_CODE (position) != INTEGER_CST
3720 || !INTEGRAL_TYPE_P (TREE_TYPE (position)))
3722 warning (OPT_Wattributes,
3723 "requested position is not an integer constant");
3724 *no_add_attrs = true;
3726 else
3728 if (tree_int_cst_lt (position, integer_zero_node))
3730 warning (OPT_Wattributes,
3731 "requested position is less than zero");
3732 *no_add_attrs = true;
3737 return NULL_TREE;
3740 /* Handle a "type_generic" attribute. */
3742 static tree
3743 handle_type_generic_attribute (tree *node, tree ARG_UNUSED (name),
3744 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
3745 bool * ARG_UNUSED (no_add_attrs))
3747 /* Ensure we have a function type. */
3748 gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
3750 /* Ensure we have a variadic function. */
3751 gcc_assert (!prototype_p (*node) || stdarg_p (*node));
3753 return NULL_TREE;
3756 /* Handle a "target" attribute. */
3758 static tree
3759 handle_target_attribute (tree *node, tree name, tree args, int flags,
3760 bool *no_add_attrs)
3762 /* Ensure we have a function type. */
3763 if (TREE_CODE (*node) != FUNCTION_DECL)
3765 warning (OPT_Wattributes, "%qE attribute ignored", name);
3766 *no_add_attrs = true;
3768 else if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (*node)))
3770 warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
3771 "with %qs attribute", name, "target_clones");
3772 *no_add_attrs = true;
3774 else if (! targetm.target_option.valid_attribute_p (*node, name, args,
3775 flags))
3776 *no_add_attrs = true;
3778 /* Check that there's no empty string in values of the attribute. */
3779 for (tree t = args; t != NULL_TREE; t = TREE_CHAIN (t))
3781 tree value = TREE_VALUE (t);
3782 if (TREE_CODE (value) == STRING_CST
3783 && TREE_STRING_LENGTH (value) == 1
3784 && TREE_STRING_POINTER (value)[0] == '\0')
3786 warning (OPT_Wattributes, "empty string in attribute %<target%>");
3787 *no_add_attrs = true;
3791 return NULL_TREE;
3794 /* Handle a "target_clones" attribute. */
3796 static tree
3797 handle_target_clones_attribute (tree *node, tree name, tree ARG_UNUSED (args),
3798 int ARG_UNUSED (flags), bool *no_add_attrs)
3800 /* Ensure we have a function type. */
3801 if (TREE_CODE (*node) == FUNCTION_DECL)
3803 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (*node)))
3805 warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
3806 "with %qs attribute", name, "always_inline");
3807 *no_add_attrs = true;
3809 else if (lookup_attribute ("target", DECL_ATTRIBUTES (*node)))
3811 warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
3812 "with %qs attribute", name, "target");
3813 *no_add_attrs = true;
3815 else
3816 /* Do not inline functions with multiple clone targets. */
3817 DECL_UNINLINABLE (*node) = 1;
3819 else
3821 warning (OPT_Wattributes, "%qE attribute ignored", name);
3822 *no_add_attrs = true;
3824 return NULL_TREE;
3827 /* For handling "optimize" attribute. arguments as in
3828 struct attribute_spec.handler. */
3830 static tree
3831 handle_optimize_attribute (tree *node, tree name, tree args,
3832 int ARG_UNUSED (flags), bool *no_add_attrs)
3834 /* Ensure we have a function type. */
3835 if (TREE_CODE (*node) != FUNCTION_DECL)
3837 warning (OPT_Wattributes, "%qE attribute ignored", name);
3838 *no_add_attrs = true;
3840 else
3842 struct cl_optimization cur_opts;
3843 tree old_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node);
3845 /* Save current options. */
3846 cl_optimization_save (&cur_opts, &global_options);
3848 /* If we previously had some optimization options, use them as the
3849 default. */
3850 if (old_opts)
3851 cl_optimization_restore (&global_options,
3852 TREE_OPTIMIZATION (old_opts));
3854 /* Parse options, and update the vector. */
3855 parse_optimize_options (args, true);
3856 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node)
3857 = build_optimization_node (&global_options);
3859 /* Restore current options. */
3860 cl_optimization_restore (&global_options, &cur_opts);
3863 return NULL_TREE;
3866 /* Handle a "no_split_stack" attribute. */
3868 static tree
3869 handle_no_split_stack_attribute (tree *node, tree name,
3870 tree ARG_UNUSED (args),
3871 int ARG_UNUSED (flags),
3872 bool *no_add_attrs)
3874 tree decl = *node;
3876 if (TREE_CODE (decl) != FUNCTION_DECL)
3878 error_at (DECL_SOURCE_LOCATION (decl),
3879 "%qE attribute applies only to functions", name);
3880 *no_add_attrs = true;
3882 else if (DECL_INITIAL (decl))
3884 error_at (DECL_SOURCE_LOCATION (decl),
3885 "can%'t set %qE attribute after definition", name);
3886 *no_add_attrs = true;
3889 return NULL_TREE;
3892 /* Handle a "returns_nonnull" attribute; arguments as in
3893 struct attribute_spec.handler. */
3895 static tree
3896 handle_returns_nonnull_attribute (tree *node, tree, tree, int,
3897 bool *no_add_attrs)
3899 // Even without a prototype we still have a return type we can check.
3900 if (TREE_CODE (TREE_TYPE (*node)) != POINTER_TYPE)
3902 error ("returns_nonnull attribute on a function not returning a pointer");
3903 *no_add_attrs = true;
3905 return NULL_TREE;
3908 /* Handle a "designated_init" attribute; arguments as in
3909 struct attribute_spec.handler. */
3911 static tree
3912 handle_designated_init_attribute (tree *node, tree name, tree, int,
3913 bool *no_add_attrs)
3915 if (TREE_CODE (*node) != RECORD_TYPE)
3917 error ("%qE attribute is only valid on %<struct%> type", name);
3918 *no_add_attrs = true;
3920 return NULL_TREE;
3924 /* Handle a "fallthrough" attribute; arguments as in struct
3925 attribute_spec.handler. */
3927 static tree
3928 handle_fallthrough_attribute (tree *, tree name, tree, int,
3929 bool *no_add_attrs)
3931 warning (OPT_Wattributes, "%qE attribute ignored", name);
3932 *no_add_attrs = true;
3933 return NULL_TREE;
3936 static tree
3937 handle_patchable_function_entry_attribute (tree *, tree, tree, int, bool *)
3939 /* Nothing to be done here. */
3940 return NULL_TREE;
3943 /* Attempt to partially validate a single attribute ATTR as if
3944 it were to be applied to an entity OPER. */
3946 static bool
3947 validate_attribute (location_t atloc, tree oper, tree attr)
3949 /* Determine whether the name of the attribute is valid
3950 and fail with an error if not. */
3951 tree atname = get_attribute_name (attr);
3952 if (!lookup_attribute_spec (atname))
3954 if (atloc != UNKNOWN_LOCATION)
3955 error_at (atloc, "unknown attribute %qE", atname);
3956 return false;
3959 tree args = TREE_VALUE (attr);
3960 if (!args)
3961 return true;
3963 /* FIXME: Do some validation. */
3964 const char *atstr = IDENTIFIER_POINTER (atname);
3965 if (!strcmp (atstr, "format"))
3966 return true;
3968 /* Only when attribute arguments have been provided try to validate
3969 the whole thing. decl_attributes doesn't return an indication of
3970 success or failure so proceed regardless. */
3971 const char tmpname[] = "__builtin_has_attribute_tmp.";
3972 tree tmpid = get_identifier (tmpname);
3973 tree tmpdecl;
3974 if (!strcmp (atstr, "vector_size"))
3976 tree type = TYPE_P (oper) ? oper : TREE_TYPE (oper);
3977 /* Check for function type here since type_for_vector_size
3978 strips it while looking for a function's return type. */
3979 if (FUNC_OR_METHOD_TYPE_P (type))
3981 warning_at (atloc, OPT_Wattributes,
3982 "invalid operand type %qT for %qs", type, atstr);
3983 return false;
3986 type = type_for_vector_size (type);
3987 if (VECTOR_TYPE_P (type))
3988 type = TREE_TYPE (type);
3989 /* Avoid trying to apply attribute vector_size to OPER since
3990 it's overly restrictive. Simply make sure it has the right
3991 type. */
3992 return type_valid_for_vector_size (type, atname, args, NULL);
3995 if (TYPE_P (oper))
3996 tmpdecl = build_decl (atloc, TYPE_DECL, tmpid, oper);
3997 else
3998 tmpdecl = build_decl (atloc, TREE_CODE (oper), tmpid, TREE_TYPE (oper));
4000 /* Temporarily clear CURRENT_FUNCTION_DECL to make decl_attributes
4001 believe the DECL declared above is at file scope. (See bug 87526.) */
4002 tree save_curfunc = current_function_decl;
4003 current_function_decl = NULL_TREE;
4004 if (DECL_P (tmpdecl))
4006 if (DECL_P (oper))
4007 /* An alias cannot be a defintion so declare the symbol extern. */
4008 DECL_EXTERNAL (tmpdecl) = true;
4009 /* Attribute visibility only applies to symbols visible from other
4010 translation units so make it "public." */
4011 TREE_PUBLIC (tmpdecl) = TREE_PUBLIC (oper);
4013 decl_attributes (&tmpdecl, attr, 0);
4014 current_function_decl = save_curfunc;
4016 /* FIXME: Change decl_attributes to indicate success or failure (and
4017 parameterize it to avoid failing with errors). */
4018 return true;
4021 /* Return true if the DECL, EXPR, or TYPE t has been declared with
4022 attribute ATTR. For DECL, consider also its type. For EXPR,
4023 consider just its type. */
4025 bool
4026 has_attribute (location_t atloc, tree t, tree attr, tree (*convert)(tree))
4028 if (!attr || !t || t == error_mark_node)
4029 return false;
4031 if (!validate_attribute (atloc, t, attr))
4032 return false;
4034 tree type = NULL_TREE;
4035 tree expr = NULL_TREE;
4036 if (TYPE_P (t))
4037 type = t;
4038 else
4042 /* Determine the array element/member declaration from
4043 an ARRAY/COMPONENT_REF. */
4044 STRIP_NOPS (t);
4045 tree_code code = TREE_CODE (t);
4046 if (code == ARRAY_REF)
4047 t = TREE_OPERAND (t, 0);
4048 else if (code == COMPONENT_REF)
4049 t = TREE_OPERAND (t, 1);
4050 else
4051 break;
4052 } while (true);
4053 expr = t;
4056 /* Set to true when an attribute is found in the referenced entity
4057 that matches the specified attribute. */
4058 bool found_match = false;
4060 tree atname = get_attribute_name (attr);
4061 const char *namestr = IDENTIFIER_POINTER (atname);
4063 /* Iterate once for a type and twice for a function or variable
4064 declaration: once for the DECL and the second time for its
4065 TYPE. */
4066 for (bool done = false; !found_match && !done; )
4068 tree atlist;
4069 if (type)
4071 if (type == error_mark_node)
4073 /* This could be a label. FIXME: add support for labels. */
4074 warning_at (atloc, OPT_Wattributes,
4075 (TYPE_P (t)
4076 ? G_("%qs attribute not supported for %qT "
4077 "in %<__builtin_has_attribute%>")
4078 : G_("%qs attribute not supported for %qE "
4079 "in %<__builtin_has_attribute%>")),
4080 namestr, t);
4081 return false;
4084 /* Clear EXPR to prevent considering it again below. */
4085 atlist = TYPE_ATTRIBUTES (type);
4086 expr = NULL_TREE;
4087 done = true;
4089 else if (DECL_P (expr))
4091 /* Set TYPE to the DECL's type to process it on the next
4092 iteration. */
4093 atlist = DECL_ATTRIBUTES (expr);
4094 type = TREE_TYPE (expr);
4096 else
4098 atlist = TYPE_ATTRIBUTES (TREE_TYPE (expr));
4099 done = true;
4102 /* True when an attribute with the sought name (though not necessarily
4103 with the sought attributes) has been found on the attribute chain. */
4104 bool found_attr = false;
4106 /* When clear, the first mismatched attribute argument results
4107 in failure. Otherwise, the first matched attribute argument
4108 results in success. */
4109 bool attr_nonnull = !strcmp ("nonnull", namestr);
4110 bool ignore_mismatches = attr_nonnull;
4112 /* Iterate over the instances of the sought attribute on the DECL or
4113 TYPE (there may be multiple instances with different arguments). */
4114 for (; (atlist = lookup_attribute (namestr, atlist));
4115 found_attr = true, atlist = TREE_CHAIN (atlist))
4117 /* If there are no arguments to match the result is true except
4118 for nonnull where the attribute with no arguments must match. */
4119 if (!TREE_VALUE (attr))
4120 return attr_nonnull ? !TREE_VALUE (atlist) : true;
4122 /* Attribute nonnull with no arguments subsumes all values of
4123 the attribute. FIXME: This is overly broad since it only
4124 applies to pointer arguments, but querying non-pointer
4125 arguments is diagnosed. */
4126 if (!TREE_VALUE (atlist) && attr_nonnull)
4127 return true;
4129 /* Iterate over the DECL or TYPE attribute argument's values. */
4130 for (tree val = TREE_VALUE (atlist); val; val = TREE_CHAIN (val))
4132 /* Iterate over the arguments in the sought attribute comparing
4133 their values to those specified for the DECL or TYPE. */
4134 for (tree arg = TREE_VALUE (attr); arg; arg = TREE_CHAIN (arg))
4136 tree v1 = TREE_VALUE (val);
4137 tree v2 = TREE_VALUE (arg);
4138 if (v1 == v2)
4139 return true;
4141 if (!v1 || !v2)
4142 break;
4144 if (TREE_CODE (v1) == IDENTIFIER_NODE
4145 || TREE_CODE (v2) == IDENTIFIER_NODE)
4146 /* Two identifiers are the same if their values are
4147 equal (that's handled above). Otherwise ther are
4148 either not the same or oneis not an identifier. */
4149 return false;
4151 /* Convert to make them equality-comparable. */
4152 v1 = convert (v1);
4153 v2 = convert (v2);
4155 /* A positive value indicates equality, negative means
4156 "don't know." */
4157 if (simple_cst_equal (v1, v2) == 1)
4158 return true;
4160 if (!ignore_mismatches)
4161 break;
4166 if (!found_attr)
4168 /* Some attributes are encoded directly in the tree node. */
4169 if (!strcmp ("aligned", namestr))
4171 if (tree arg = TREE_VALUE (attr))
4173 arg = convert (TREE_VALUE (arg));
4174 if (expr && DECL_P (expr)
4175 && DECL_USER_ALIGN (expr)
4176 && tree_fits_uhwi_p (arg))
4177 found_match = DECL_ALIGN_UNIT (expr) == tree_to_uhwi (arg);
4178 else if (type && TYPE_USER_ALIGN (type))
4179 found_match = TYPE_ALIGN_UNIT (type) == tree_to_uhwi (arg);
4181 else if (expr && DECL_P (expr))
4182 found_match = DECL_USER_ALIGN (expr);
4183 else if (type)
4184 found_match = TYPE_USER_ALIGN (type);
4186 else if (!strcmp ("const", namestr))
4188 if (expr && DECL_P (expr))
4189 found_match = TREE_READONLY (expr);
4191 else if (!strcmp ("pure", namestr))
4193 if (expr && DECL_P (expr))
4194 found_match = DECL_PURE_P (expr);
4196 else if (!strcmp ("deprecated", namestr))
4198 found_match = TREE_DEPRECATED (expr ? expr : type);
4199 if (found_match)
4200 return true;
4202 else if (!strcmp ("vector_size", namestr))
4204 if (!type)
4205 continue;
4207 /* Determine the base type from arrays, pointers, and such.
4208 Fail if the base type is not a vector. */
4209 type = type_for_vector_size (type);
4210 if (!VECTOR_TYPE_P (type))
4211 return false;
4213 if (tree arg = TREE_VALUE (attr))
4215 /* Compare the vector size argument for equality. */
4216 arg = convert (TREE_VALUE (arg));
4217 return tree_int_cst_equal (arg, TYPE_SIZE_UNIT (type)) == 1;
4219 else
4220 return true;
4222 else if (!strcmp ("warn_if_not_aligned", namestr))
4224 if (tree arg = TREE_VALUE (attr))
4226 arg = convert (TREE_VALUE (arg));
4227 if (expr && DECL_P (expr))
4228 found_match = (DECL_WARN_IF_NOT_ALIGN (expr)
4229 == tree_to_uhwi (arg) * BITS_PER_UNIT);
4230 else if (type)
4231 found_match = (TYPE_WARN_IF_NOT_ALIGN (type)
4232 == tree_to_uhwi (arg) * BITS_PER_UNIT);
4234 else if (expr && DECL_P (expr))
4235 found_match = DECL_WARN_IF_NOT_ALIGN (expr);
4236 else if (type)
4237 found_match = TYPE_WARN_IF_NOT_ALIGN (type);
4239 else if (!strcmp ("transparent_union", namestr))
4241 if (type)
4242 found_match = TYPE_TRANSPARENT_AGGR (type) != 0;
4244 else if (!strcmp ("mode", namestr))
4246 /* Finally issue a warning for attributes that cannot
4247 be supported in this context. Attribute mode is not
4248 added to a symbol and cannot be determined from it. */
4249 warning_at (atloc, OPT_Wattributes,
4250 "%qs attribute not supported in "
4251 "%<__builtin_has_attribute%>", namestr);
4252 break;
4256 return found_match;