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