1 /* C-family attributes handling.
2 Copyright (C) 1992-2018 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 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "target.h"
24 #include "function.h"
25 #include "tree.h"
26 #include "memmodel.h"
27 #include "c-common.h"
28 #include "gimple-expr.h"
29 #include "tm_p.h"
30 #include "stringpool.h"
31 #include "cgraph.h"
32 #include "diagnostic.h"
33 #include "intl.h"
34 #include "stor-layout.h"
35 #include "calls.h"
36 #include "attribs.h"
37 #include "varasm.h"
38 #include "trans-mem.h"
39 #include "c-objc.h"
40 #include "common/common-target.h"
41 #include "langhooks.h"
42 #include "tree-inline.h"
43 #include "toplev.h"
44 #include "tree-iterator.h"
45 #include "opts.h"
46 #include "gimplify.h"
47
48 static tree handle_packed_attribute (tree *, tree, tree, int, bool *);
49 static tree handle_nocommon_attribute (tree *, tree, tree, int, bool *);
50 static tree handle_common_attribute (tree *, tree, tree, int, bool *);
51 static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
52 static tree handle_hot_attribute (tree *, tree, tree, int, bool *);
53 static tree handle_cold_attribute (tree *, tree, tree, int, bool *);
54 static tree handle_no_sanitize_attribute (tree *, tree, tree, int, bool *);
55 static tree handle_no_sanitize_address_attribute (tree *, tree, tree,
56 int, bool *);
57 static tree handle_no_sanitize_thread_attribute (tree *, tree, tree,
58 int, bool *);
59 static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree,
60 int, bool *);
61 static tree handle_no_sanitize_undefined_attribute (tree *, tree, tree, int,
62 bool *);
63 static tree handle_asan_odr_indicator_attribute (tree *, tree, tree, int,
64 bool *);
65 static tree handle_stack_protect_attribute (tree *, tree, tree, int, bool *);
66 static tree handle_noinline_attribute (tree *, tree, tree, int, bool *);
67 static tree handle_noclone_attribute (tree *, tree, tree, int, bool *);
68 static tree handle_nocf_check_attribute (tree *, tree, tree, int, bool *);
69 static tree handle_noicf_attribute (tree *, tree, tree, int, bool *);
70 static tree handle_noipa_attribute (tree *, tree, tree, int, bool *);
71 static tree handle_leaf_attribute (tree *, tree, tree, int, bool *);
72 static tree handle_always_inline_attribute (tree *, tree, tree, int,
73 bool *);
74 static tree handle_gnu_inline_attribute (tree *, tree, tree, int, bool *);
75 static tree handle_artificial_attribute (tree *, tree, tree, int, bool *);
76 static tree handle_flatten_attribute (tree *, tree, tree, int, bool *);
77 static tree handle_error_attribute (tree *, tree, tree, int, bool *);
78 static tree handle_used_attribute (tree *, tree, tree, int, bool *);
79 static tree handle_externally_visible_attribute (tree *, tree, tree, int,
80 bool *);
81 static tree handle_no_reorder_attribute (tree *, tree, tree, int,
82 bool *);
83 static tree handle_const_attribute (tree *, tree, tree, int, bool *);
84 static tree handle_transparent_union_attribute (tree *, tree, tree,
85 int, bool *);
86 static tree handle_scalar_storage_order_attribute (tree *, tree, tree,
87 int, bool *);
88 static tree handle_constructor_attribute (tree *, tree, tree, int, bool *);
89 static tree handle_destructor_attribute (tree *, tree, tree, int, bool *);
90 static tree handle_mode_attribute (tree *, tree, tree, int, bool *);
91 static tree handle_section_attribute (tree *, tree, tree, int, bool *);
92 static tree handle_aligned_attribute (tree *, tree, tree, int, bool *);
93 static tree handle_warn_if_not_aligned_attribute (tree *, tree, tree,
94 int, bool *);
95 static tree handle_weak_attribute (tree *, tree, tree, int, bool *) ;
96 static tree handle_noplt_attribute (tree *, tree, tree, int, bool *) ;
97 static tree handle_alias_ifunc_attribute (bool, tree *, tree, tree, bool *);
98 static tree handle_ifunc_attribute (tree *, tree, tree, int, bool *);
99 static tree handle_alias_attribute (tree *, tree, tree, int, bool *);
100 static tree handle_weakref_attribute (tree *, tree, tree, int, bool *) ;
101 static tree handle_visibility_attribute (tree *, tree, tree, int,
102 bool *);
103 static tree handle_tls_model_attribute (tree *, tree, tree, int,
104 bool *);
105 static tree handle_no_instrument_function_attribute (tree *, tree,
106 tree, int, bool *);
107 static tree handle_no_profile_instrument_function_attribute (tree *, tree,
108 tree, int, bool *);
109 static tree handle_malloc_attribute (tree *, tree, tree, int, bool *);
110 static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *);
111 static tree handle_no_limit_stack_attribute (tree *, tree, tree, int,
112 bool *);
113 static tree handle_pure_attribute (tree *, tree, tree, int, bool *);
114 static tree handle_tm_attribute (tree *, tree, tree, int, bool *);
115 static tree handle_tm_wrap_attribute (tree *, tree, tree, int, bool *);
116 static tree handle_novops_attribute (tree *, tree, tree, int, bool *);
117 static tree handle_deprecated_attribute (tree *, tree, tree, int,
118 bool *);
119 static tree handle_vector_size_attribute (tree *, tree, tree, int,
120 bool *);
121 static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
122 static tree handle_nonstring_attribute (tree *, tree, tree, int, bool *);
123 static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *);
124 static tree handle_cleanup_attribute (tree *, tree, tree, int, bool *);
125 static tree handle_warn_unused_result_attribute (tree *, tree, tree, int,
126 bool *);
127 static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *);
128 static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
129 static tree handle_alloc_size_attribute (tree *, tree, tree, int, bool *);
130 static tree handle_alloc_align_attribute (tree *, tree, tree, int, bool *);
131 static tree handle_assume_aligned_attribute (tree *, tree, tree, int, bool *);
132 static tree handle_target_attribute (tree *, tree, tree, int, bool *);
133 static tree handle_target_clones_attribute (tree *, tree, tree, int, bool *);
134 static tree handle_optimize_attribute (tree *, tree, tree, int, bool *);
135 static tree ignore_attribute (tree *, tree, tree, int, bool *);
136 static tree handle_no_split_stack_attribute (tree *, tree, tree, int, bool *);
137 static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *);
138 static tree handle_warn_unused_attribute (tree *, tree, tree, int, bool *);
139 static tree handle_returns_nonnull_attribute (tree *, tree, tree, int, bool *);
140 static tree handle_omp_declare_simd_attribute (tree *, tree, tree, int,
141 bool *);
142 static tree handle_simd_attribute (tree *, tree, tree, int, bool *);
143 static tree handle_omp_declare_target_attribute (tree *, tree, tree, int,
144 bool *);
145 static tree handle_designated_init_attribute (tree *, tree, tree, int, bool *);
146 static tree handle_bnd_variable_size_attribute (tree *, tree, tree, int, bool *);
147 static tree handle_bnd_legacy (tree *, tree, tree, int, bool *);
148 static tree handle_bnd_instrument (tree *, tree, tree, int, bool *);
149 static tree handle_fallthrough_attribute (tree *, tree, tree, int, bool *);
150 static tree handle_patchable_function_entry_attribute (tree *, tree, tree,
151 int, bool *);
152
153 /* Helper to define attribute exclusions. */
154 #define ATTR_EXCL(name, function, type, variable) \
155 { name, function, type, variable }
156
157 /* Define attributes that are mutually exclusive with one another. */
158 static const struct attribute_spec::exclusions attr_aligned_exclusions[] =
159 {
160 /* Attribute name exclusion applies to:
161 function, type, variable */
162 ATTR_EXCL ("aligned", true, false, false),
163 ATTR_EXCL ("packed", true, false, false),
164 ATTR_EXCL (NULL, false, false, false)
165 };
166
167 static const struct attribute_spec::exclusions attr_cold_hot_exclusions[] =
168 {
169 ATTR_EXCL ("cold", true, true, true),
170 ATTR_EXCL ("hot", true, true, true),
171 ATTR_EXCL (NULL, false, false, false)
172 };
173
174 static const struct attribute_spec::exclusions attr_common_exclusions[] =
175 {
176 ATTR_EXCL ("common", true, true, true),
177 ATTR_EXCL ("nocommon", true, true, true),
178 ATTR_EXCL (NULL, false, false, false),
179 };
180
181 static const struct attribute_spec::exclusions attr_inline_exclusions[] =
182 {
183 ATTR_EXCL ("noinline", true, true, true),
184 ATTR_EXCL (NULL, false, false, false),
185 };
186
187 static const struct attribute_spec::exclusions attr_noinline_exclusions[] =
188 {
189 ATTR_EXCL ("always_inline", true, true, true),
190 ATTR_EXCL ("gnu_inline", true, true, true),
191 ATTR_EXCL (NULL, false, false, false),
192 };
193
194 static const struct attribute_spec::exclusions attr_noreturn_exclusions[] =
195 {
196 ATTR_EXCL ("alloc_align", true, true, true),
197 ATTR_EXCL ("alloc_size", true, true, true),
198 ATTR_EXCL ("const", true, true, true),
199 ATTR_EXCL ("malloc", true, true, true),
200 ATTR_EXCL ("pure", true, true, true),
201 ATTR_EXCL ("returns_twice", true, true, true),
202 ATTR_EXCL ("warn_unused_result", true, true, true),
203 ATTR_EXCL (NULL, false, false, false),
204 };
205
206 static const struct attribute_spec::exclusions
207 attr_warn_unused_result_exclusions[] =
208 {
209 ATTR_EXCL ("noreturn", true, true, true),
210 ATTR_EXCL ("warn_unused_result", true, true, true),
211 ATTR_EXCL (NULL, false, false, false),
212 };
213
214 static const struct attribute_spec::exclusions attr_returns_twice_exclusions[] =
215 {
216 ATTR_EXCL ("noreturn", true, true, true),
217 ATTR_EXCL (NULL, false, false, false),
218 };
219
220 /* Exclusions that apply to attribute alloc_align, alloc_size, and malloc. */
221 static const struct attribute_spec::exclusions attr_alloc_exclusions[] =
222 {
223 ATTR_EXCL ("const", true, true, true),
224 ATTR_EXCL ("noreturn", true, true, true),
225 ATTR_EXCL ("pure", true, true, true),
226 ATTR_EXCL (NULL, false, false, false),
227 };
228
229 static const struct attribute_spec::exclusions attr_const_pure_exclusions[] =
230 {
231 ATTR_EXCL ("const", true, true, true),
232 ATTR_EXCL ("alloc_align", true, true, true),
233 ATTR_EXCL ("alloc_size", true, true, true),
234 ATTR_EXCL ("malloc", true, true, true),
235 ATTR_EXCL ("noreturn", true, true, true),
236 ATTR_EXCL ("pure", true, true, true),
237 ATTR_EXCL (NULL, false, false, false)
238 };
239
240 /* Table of machine-independent attributes common to all C-like languages.
241
242 All attributes referencing arguments should be additionally processed
243 in chkp_copy_function_type_adding_bounds for correct instrumentation
244 by Pointer Bounds Checker.
245 Current list of processed common attributes: nonnull. */
246 const struct attribute_spec c_common_attribute_table[] =
247 {
248 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
249 affects_type_identity, handler, exclude } */
250 { "packed", 0, 0, false, false, false, false,
251 handle_packed_attribute,
252 attr_aligned_exclusions },
253 { "nocommon", 0, 0, true, false, false, false,
254 handle_nocommon_attribute,
255 attr_common_exclusions },
256 { "common", 0, 0, true, false, false, false,
257 handle_common_attribute,
258 attr_common_exclusions },
259 /* FIXME: logically, noreturn attributes should be listed as
260 "false, true, true" and apply to function types. But implementing this
261 would require all the places in the compiler that use TREE_THIS_VOLATILE
262 on a decl to identify non-returning functions to be located and fixed
263 to check the function type instead. */
264 { "noreturn", 0, 0, true, false, false, false,
265 handle_noreturn_attribute,
266 attr_noreturn_exclusions },
267 { "volatile", 0, 0, true, false, false, false,
268 handle_noreturn_attribute, NULL },
269 { "stack_protect", 0, 0, true, false, false, false,
270 handle_stack_protect_attribute, NULL },
271 { "noinline", 0, 0, true, false, false, false,
272 handle_noinline_attribute,
273 attr_noinline_exclusions },
274 { "noclone", 0, 0, true, false, false, false,
275 handle_noclone_attribute, NULL },
276 { "no_icf", 0, 0, true, false, false, false,
277 handle_noicf_attribute, NULL },
278 { "noipa", 0, 0, true, false, false, false,
279 handle_noipa_attribute, NULL },
280 { "leaf", 0, 0, true, false, false, false,
281 handle_leaf_attribute, NULL },
282 { "always_inline", 0, 0, true, false, false, false,
283 handle_always_inline_attribute,
284 attr_inline_exclusions },
285 { "gnu_inline", 0, 0, true, false, false, false,
286 handle_gnu_inline_attribute,
287 attr_inline_exclusions },
288 { "artificial", 0, 0, true, false, false, false,
289 handle_artificial_attribute, NULL },
290 { "flatten", 0, 0, true, false, false, false,
291 handle_flatten_attribute, NULL },
292 { "used", 0, 0, true, false, false, false,
293 handle_used_attribute, NULL },
294 { "unused", 0, 0, false, false, false, false,
295 handle_unused_attribute, NULL },
296 { "externally_visible", 0, 0, true, false, false, false,
297 handle_externally_visible_attribute, NULL },
298 { "no_reorder", 0, 0, true, false, false, false,
299 handle_no_reorder_attribute, NULL },
300 /* The same comments as for noreturn attributes apply to const ones. */
301 { "const", 0, 0, true, false, false, false,
302 handle_const_attribute,
303 attr_const_pure_exclusions },
304 { "scalar_storage_order", 1, 1, false, false, false, false,
305 handle_scalar_storage_order_attribute, NULL },
306 { "transparent_union", 0, 0, false, false, false, false,
307 handle_transparent_union_attribute, NULL },
308 { "constructor", 0, 1, true, false, false, false,
309 handle_constructor_attribute, NULL },
310 { "destructor", 0, 1, true, false, false, false,
311 handle_destructor_attribute, NULL },
312 { "mode", 1, 1, false, true, false, false,
313 handle_mode_attribute, NULL },
314 { "section", 1, 1, true, false, false, false,
315 handle_section_attribute, NULL },
316 { "aligned", 0, 1, false, false, false, false,
317 handle_aligned_attribute,
318 attr_aligned_exclusions },
319 { "warn_if_not_aligned", 0, 1, false, false, false, false,
320 handle_warn_if_not_aligned_attribute, NULL },
321 { "weak", 0, 0, true, false, false, false,
322 handle_weak_attribute, NULL },
323 { "noplt", 0, 0, true, false, false, false,
324 handle_noplt_attribute, NULL },
325 { "ifunc", 1, 1, true, false, false, false,
326 handle_ifunc_attribute, NULL },
327 { "alias", 1, 1, true, false, false, false,
328 handle_alias_attribute, NULL },
329 { "weakref", 0, 1, true, false, false, false,
330 handle_weakref_attribute, NULL },
331 { "no_instrument_function", 0, 0, true, false, false, false,
332 handle_no_instrument_function_attribute,
333 NULL },
334 { "no_profile_instrument_function", 0, 0, true, false, false, false,
335 handle_no_profile_instrument_function_attribute,
336 NULL },
337 { "malloc", 0, 0, true, false, false, false,
338 handle_malloc_attribute, attr_alloc_exclusions },
339 { "returns_twice", 0, 0, true, false, false, false,
340 handle_returns_twice_attribute,
341 attr_returns_twice_exclusions },
342 { "no_stack_limit", 0, 0, true, false, false, false,
343 handle_no_limit_stack_attribute, NULL },
344 { "pure", 0, 0, true, false, false, false,
345 handle_pure_attribute,
346 attr_const_pure_exclusions },
347 { "transaction_callable", 0, 0, false, true, false, false,
348 handle_tm_attribute, NULL },
349 { "transaction_unsafe", 0, 0, false, true, false, true,
350 handle_tm_attribute, NULL },
351 { "transaction_safe", 0, 0, false, true, false, true,
352 handle_tm_attribute, NULL },
353 { "transaction_safe_dynamic", 0, 0, true, false, false, false,
354 handle_tm_attribute, NULL },
355 { "transaction_may_cancel_outer", 0, 0, false, true, false, false,
356 handle_tm_attribute, NULL },
357 /* ??? These two attributes didn't make the transition from the
358 Intel language document to the multi-vendor language document. */
359 { "transaction_pure", 0, 0, false, true, false, false,
360 handle_tm_attribute, NULL },
361 { "transaction_wrap", 1, 1, true, false, false, false,
362 handle_tm_wrap_attribute, NULL },
363 /* For internal use (marking of builtins) only. The name contains space
364 to prevent its usage in source code. */
365 { "no vops", 0, 0, true, false, false, false,
366 handle_novops_attribute, NULL },
367 { "deprecated", 0, 1, false, false, false, false,
368 handle_deprecated_attribute, NULL },
369 { "vector_size", 1, 1, false, true, false, true,
370 handle_vector_size_attribute, NULL },
371 { "visibility", 1, 1, false, false, false, false,
372 handle_visibility_attribute, NULL },
373 { "tls_model", 1, 1, true, false, false, false,
374 handle_tls_model_attribute, NULL },
375 { "nonnull", 0, -1, false, true, true, false,
376 handle_nonnull_attribute, NULL },
377 { "nonstring", 0, 0, true, false, false, false,
378 handle_nonstring_attribute, NULL },
379 { "nothrow", 0, 0, true, false, false, false,
380 handle_nothrow_attribute, NULL },
381 { "may_alias", 0, 0, false, true, false, false, NULL, NULL },
382 { "cleanup", 1, 1, true, false, false, false,
383 handle_cleanup_attribute, NULL },
384 { "warn_unused_result", 0, 0, false, true, true, false,
385 handle_warn_unused_result_attribute,
386 attr_warn_unused_result_exclusions },
387 { "sentinel", 0, 1, false, true, true, false,
388 handle_sentinel_attribute, NULL },
389 /* For internal use (marking of builtins) only. The name contains space
390 to prevent its usage in source code. */
391 { "type generic", 0, 0, false, true, true, false,
392 handle_type_generic_attribute, NULL },
393 { "alloc_size", 1, 2, false, true, true, false,
394 handle_alloc_size_attribute,
395 attr_alloc_exclusions },
396 { "cold", 0, 0, true, false, false, false,
397 handle_cold_attribute,
398 attr_cold_hot_exclusions },
399 { "hot", 0, 0, true, false, false, false,
400 handle_hot_attribute,
401 attr_cold_hot_exclusions },
402 { "no_address_safety_analysis",
403 0, 0, true, false, false, false,
404 handle_no_address_safety_analysis_attribute,
405 NULL },
406 { "no_sanitize", 1, -1, true, false, false, false,
407 handle_no_sanitize_attribute, NULL },
408 { "no_sanitize_address", 0, 0, true, false, false, false,
409 handle_no_sanitize_address_attribute, NULL },
410 { "no_sanitize_thread", 0, 0, true, false, false, false,
411 handle_no_sanitize_thread_attribute, NULL },
412 { "no_sanitize_undefined", 0, 0, true, false, false, false,
413 handle_no_sanitize_undefined_attribute, NULL },
414 { "asan odr indicator", 0, 0, true, false, false, false,
415 handle_asan_odr_indicator_attribute, NULL },
416 { "warning", 1, 1, true, false, false, false,
417 handle_error_attribute, NULL },
418 { "error", 1, 1, true, false, false, false,
419 handle_error_attribute, NULL },
420 { "target", 1, -1, true, false, false, false,
421 handle_target_attribute, NULL },
422 { "target_clones", 1, -1, true, false, false, false,
423 handle_target_clones_attribute, NULL },
424 { "optimize", 1, -1, true, false, false, false,
425 handle_optimize_attribute, NULL },
426 /* For internal use only. The leading '*' both prevents its usage in
427 source code and signals that it may be overridden by machine tables. */
428 { "*tm regparm", 0, 0, false, true, true, false,
429 ignore_attribute, NULL },
430 { "no_split_stack", 0, 0, true, false, false, false,
431 handle_no_split_stack_attribute, NULL },
432 /* For internal use (marking of builtins and runtime functions) only.
433 The name contains space to prevent its usage in source code. */
434 { "fn spec", 1, 1, false, true, true, false,
435 handle_fnspec_attribute, NULL },
436 { "warn_unused", 0, 0, false, false, false, false,
437 handle_warn_unused_attribute, NULL },
438 { "returns_nonnull", 0, 0, false, true, true, false,
439 handle_returns_nonnull_attribute, NULL },
440 { "omp declare simd", 0, -1, true, false, false, false,
441 handle_omp_declare_simd_attribute, NULL },
442 { "simd", 0, 1, true, false, false, false,
443 handle_simd_attribute, NULL },
444 { "omp declare target", 0, 0, true, false, false, false,
445 handle_omp_declare_target_attribute, NULL },
446 { "omp declare target link", 0, 0, true, false, false, false,
447 handle_omp_declare_target_attribute, NULL },
448 { "omp declare target implicit", 0, 0, true, false, false, false,
449 handle_omp_declare_target_attribute, NULL },
450 { "alloc_align", 1, 1, false, true, true, false,
451 handle_alloc_align_attribute,
452 attr_alloc_exclusions },
453 { "assume_aligned", 1, 2, false, true, true, false,
454 handle_assume_aligned_attribute, NULL },
455 { "designated_init", 0, 0, false, true, false, false,
456 handle_designated_init_attribute, NULL },
457 { "bnd_variable_size", 0, 0, true, false, false, false,
458 handle_bnd_variable_size_attribute, NULL },
459 { "bnd_legacy", 0, 0, true, false, false, false,
460 handle_bnd_legacy, NULL },
461 { "bnd_instrument", 0, 0, true, false, false, false,
462 handle_bnd_instrument, NULL },
463 { "fallthrough", 0, 0, false, false, false, false,
464 handle_fallthrough_attribute, NULL },
465 { "patchable_function_entry", 1, 2, true, false, false, false,
466 handle_patchable_function_entry_attribute,
467 NULL },
468 { "nocf_check", 0, 0, false, true, true, true,
469 handle_nocf_check_attribute, NULL },
470 { NULL, 0, 0, false, false, false, false, NULL, NULL }
471 };
472
473 /* Give the specifications for the format attributes, used by C and all
474 descendants.
475
476 All attributes referencing arguments should be additionally processed
477 in chkp_copy_function_type_adding_bounds for correct instrumentation
478 by Pointer Bounds Checker.
479 Current list of processed format attributes: format, format_arg. */
480 const struct attribute_spec c_common_format_attribute_table[] =
481 {
482 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
483 affects_type_identity, handler, exclude } */
484 { "format", 3, 3, false, true, true, false,
485 handle_format_attribute, NULL },
486 { "format_arg", 1, 1, false, true, true, false,
487 handle_format_arg_attribute, NULL },
488 { NULL, 0, 0, false, false, false, false, NULL, NULL }
489 };
490
491 /* Returns TRUE iff the attribute indicated by ATTR_ID takes a plain
492 identifier as an argument, so the front end shouldn't look it up. */
493
494 bool
attribute_takes_identifier_p(const_tree attr_id)495 attribute_takes_identifier_p (const_tree attr_id)
496 {
497 const struct attribute_spec *spec = lookup_attribute_spec (attr_id);
498 if (spec == NULL)
499 /* Unknown attribute that we'll end up ignoring, return true so we
500 don't complain about an identifier argument. */
501 return true;
502 else if (!strcmp ("mode", spec->name)
503 || !strcmp ("format", spec->name)
504 || !strcmp ("cleanup", spec->name))
505 return true;
506 else
507 return targetm.attribute_takes_identifier_p (attr_id);
508 }
509
510 /* Attribute handlers common to C front ends. */
511
512 /* Handle a "packed" attribute; arguments as in
513 struct attribute_spec.handler. */
514
515 static tree
handle_packed_attribute(tree * node,tree name,tree ARG_UNUSED (args),int flags,bool * no_add_attrs)516 handle_packed_attribute (tree *node, tree name, tree ARG_UNUSED (args),
517 int flags, bool *no_add_attrs)
518 {
519 if (TYPE_P (*node))
520 {
521 if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
522 {
523 warning (OPT_Wattributes,
524 "%qE attribute ignored for type %qT", name, *node);
525 *no_add_attrs = true;
526 }
527 else
528 TYPE_PACKED (*node) = 1;
529 }
530 else if (TREE_CODE (*node) == FIELD_DECL)
531 {
532 if (TYPE_ALIGN (TREE_TYPE (*node)) <= BITS_PER_UNIT
533 /* Still pack bitfields. */
534 && ! DECL_C_BIT_FIELD (*node))
535 warning (OPT_Wattributes,
536 "%qE attribute ignored for field of type %qT",
537 name, TREE_TYPE (*node));
538 else
539 DECL_PACKED (*node) = 1;
540 }
541 /* We can't set DECL_PACKED for a VAR_DECL, because the bit is
542 used for DECL_REGISTER. It wouldn't mean anything anyway.
543 We can't set DECL_PACKED on the type of a TYPE_DECL, because
544 that changes what the typedef is typing. */
545 else
546 {
547 warning (OPT_Wattributes, "%qE attribute ignored", name);
548 *no_add_attrs = true;
549 }
550
551 return NULL_TREE;
552 }
553
554 /* Handle a "nocommon" attribute; arguments as in
555 struct attribute_spec.handler. */
556
557 static tree
handle_nocommon_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)558 handle_nocommon_attribute (tree *node, tree name,
559 tree ARG_UNUSED (args),
560 int ARG_UNUSED (flags), bool *no_add_attrs)
561 {
562 if (VAR_P (*node))
563 DECL_COMMON (*node) = 0;
564 else
565 {
566 warning (OPT_Wattributes, "%qE attribute ignored", name);
567 *no_add_attrs = true;
568 }
569
570 return NULL_TREE;
571 }
572
573 /* Handle a "common" attribute; arguments as in
574 struct attribute_spec.handler. */
575
576 static tree
handle_common_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)577 handle_common_attribute (tree *node, tree name, tree ARG_UNUSED (args),
578 int ARG_UNUSED (flags), bool *no_add_attrs)
579 {
580 if (VAR_P (*node))
581 DECL_COMMON (*node) = 1;
582 else
583 {
584 warning (OPT_Wattributes, "%qE attribute ignored", name);
585 *no_add_attrs = true;
586 }
587
588 return NULL_TREE;
589 }
590
591 /* Handle a "noreturn" attribute; arguments as in
592 struct attribute_spec.handler. */
593
594 static tree
handle_noreturn_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)595 handle_noreturn_attribute (tree *node, tree name, tree ARG_UNUSED (args),
596 int ARG_UNUSED (flags), bool *no_add_attrs)
597 {
598 tree type = TREE_TYPE (*node);
599
600 /* See FIXME comment in c_common_attribute_table. */
601 if (TREE_CODE (*node) == FUNCTION_DECL
602 || objc_method_decl (TREE_CODE (*node)))
603 TREE_THIS_VOLATILE (*node) = 1;
604 else if (TREE_CODE (type) == POINTER_TYPE
605 && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
606 TREE_TYPE (*node)
607 = (build_qualified_type
608 (build_pointer_type
609 (build_type_variant (TREE_TYPE (type),
610 TYPE_READONLY (TREE_TYPE (type)), 1)),
611 TYPE_QUALS (type)));
612 else
613 {
614 warning (OPT_Wattributes, "%qE attribute ignored", name);
615 *no_add_attrs = true;
616 }
617
618 return NULL_TREE;
619 }
620
621 /* Handle a "hot" and attribute; arguments as in
622 struct attribute_spec.handler. */
623
624 static tree
handle_hot_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)625 handle_hot_attribute (tree *node, tree name, tree ARG_UNUSED (args),
626 int ARG_UNUSED (flags), bool *no_add_attrs)
627 {
628 if (TREE_CODE (*node) == FUNCTION_DECL
629 || TREE_CODE (*node) == LABEL_DECL)
630 {
631 /* Attribute hot processing is done later with lookup_attribute. */
632 }
633 else
634 {
635 warning (OPT_Wattributes, "%qE attribute ignored", name);
636 *no_add_attrs = true;
637 }
638
639 return NULL_TREE;
640 }
641
642 /* Handle a "cold" and attribute; arguments as in
643 struct attribute_spec.handler. */
644
645 static tree
handle_cold_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)646 handle_cold_attribute (tree *node, tree name, tree ARG_UNUSED (args),
647 int ARG_UNUSED (flags), bool *no_add_attrs)
648 {
649 if (TREE_CODE (*node) == FUNCTION_DECL
650 || TREE_CODE (*node) == LABEL_DECL)
651 {
652 /* Attribute cold processing is done later with lookup_attribute. */
653 }
654 else
655 {
656 warning (OPT_Wattributes, "%qE attribute ignored", name);
657 *no_add_attrs = true;
658 }
659
660 return NULL_TREE;
661 }
662
663 /* Add FLAGS for a function NODE to no_sanitize_flags in DECL_ATTRIBUTES. */
664
665 void
add_no_sanitize_value(tree node,unsigned int flags)666 add_no_sanitize_value (tree node, unsigned int flags)
667 {
668 tree attr = lookup_attribute ("no_sanitize", DECL_ATTRIBUTES (node));
669 if (attr)
670 {
671 unsigned int old_value = tree_to_uhwi (TREE_VALUE (attr));
672 flags |= old_value;
673
674 if (flags == old_value)
675 return;
676
677 TREE_VALUE (attr) = build_int_cst (unsigned_type_node, flags);
678 }
679 else
680 DECL_ATTRIBUTES (node)
681 = tree_cons (get_identifier ("no_sanitize"),
682 build_int_cst (unsigned_type_node, flags),
683 DECL_ATTRIBUTES (node));
684 }
685
686 /* Handle a "no_sanitize" attribute; arguments as in
687 struct attribute_spec.handler. */
688
689 static tree
handle_no_sanitize_attribute(tree * node,tree name,tree args,int,bool * no_add_attrs)690 handle_no_sanitize_attribute (tree *node, tree name, tree args, int,
691 bool *no_add_attrs)
692 {
693 unsigned int flags = 0;
694 *no_add_attrs = true;
695 if (TREE_CODE (*node) != FUNCTION_DECL)
696 {
697 warning (OPT_Wattributes, "%qE attribute ignored", name);
698 return NULL_TREE;
699 }
700
701 for (; args; args = TREE_CHAIN (args))
702 {
703 tree id = TREE_VALUE (args);
704 if (TREE_CODE (id) != STRING_CST)
705 {
706 error ("no_sanitize argument not a string");
707 return NULL_TREE;
708 }
709
710 char *string = ASTRDUP (TREE_STRING_POINTER (id));
711 flags |= parse_no_sanitize_attribute (string);
712 }
713
714 add_no_sanitize_value (*node, flags);
715
716 return NULL_TREE;
717 }
718
719 /* Handle a "no_sanitize_address" attribute; arguments as in
720 struct attribute_spec.handler. */
721
722 static tree
handle_no_sanitize_address_attribute(tree * node,tree name,tree,int,bool * no_add_attrs)723 handle_no_sanitize_address_attribute (tree *node, tree name, tree, int,
724 bool *no_add_attrs)
725 {
726 *no_add_attrs = true;
727 if (TREE_CODE (*node) != FUNCTION_DECL)
728 warning (OPT_Wattributes, "%qE attribute ignored", name);
729 else
730 add_no_sanitize_value (*node, SANITIZE_ADDRESS);
731
732 return NULL_TREE;
733 }
734
735 /* Handle a "no_sanitize_thread" attribute; arguments as in
736 struct attribute_spec.handler. */
737
738 static tree
handle_no_sanitize_thread_attribute(tree * node,tree name,tree,int,bool * no_add_attrs)739 handle_no_sanitize_thread_attribute (tree *node, tree name, tree, int,
740 bool *no_add_attrs)
741 {
742 *no_add_attrs = true;
743 if (TREE_CODE (*node) != FUNCTION_DECL)
744 warning (OPT_Wattributes, "%qE attribute ignored", name);
745 else
746 add_no_sanitize_value (*node, SANITIZE_THREAD);
747
748 return NULL_TREE;
749 }
750
751
752 /* Handle a "no_address_safety_analysis" attribute; arguments as in
753 struct attribute_spec.handler. */
754
755 static tree
handle_no_address_safety_analysis_attribute(tree * node,tree name,tree,int,bool * no_add_attrs)756 handle_no_address_safety_analysis_attribute (tree *node, tree name, tree, int,
757 bool *no_add_attrs)
758 {
759 *no_add_attrs = true;
760 if (TREE_CODE (*node) != FUNCTION_DECL)
761 warning (OPT_Wattributes, "%qE attribute ignored", name);
762 else
763 add_no_sanitize_value (*node, SANITIZE_ADDRESS);
764
765 return NULL_TREE;
766 }
767
768 /* Handle a "no_sanitize_undefined" attribute; arguments as in
769 struct attribute_spec.handler. */
770
771 static tree
handle_no_sanitize_undefined_attribute(tree * node,tree name,tree,int,bool * no_add_attrs)772 handle_no_sanitize_undefined_attribute (tree *node, tree name, tree, int,
773 bool *no_add_attrs)
774 {
775 *no_add_attrs = true;
776 if (TREE_CODE (*node) != FUNCTION_DECL)
777 warning (OPT_Wattributes, "%qE attribute ignored", name);
778 else
779 add_no_sanitize_value (*node,
780 SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT);
781
782 return NULL_TREE;
783 }
784
785 /* Handle an "asan odr indicator" attribute; arguments as in
786 struct attribute_spec.handler. */
787
788 static tree
handle_asan_odr_indicator_attribute(tree *,tree,tree,int,bool *)789 handle_asan_odr_indicator_attribute (tree *, tree, tree, int, bool *)
790 {
791 return NULL_TREE;
792 }
793
794 /* Handle a "stack_protect" attribute; arguments as in
795 struct attribute_spec.handler. */
796
797 static tree
handle_stack_protect_attribute(tree * node,tree name,tree,int,bool * no_add_attrs)798 handle_stack_protect_attribute (tree *node, tree name, tree, int,
799 bool *no_add_attrs)
800 {
801 if (TREE_CODE (*node) != FUNCTION_DECL)
802 {
803 warning (OPT_Wattributes, "%qE attribute ignored", name);
804 *no_add_attrs = true;
805 }
806
807 return NULL_TREE;
808 }
809
810 /* Handle a "noipa" attribute; arguments as in
811 struct attribute_spec.handler. */
812
813 static tree
handle_noipa_attribute(tree * node,tree name,tree,int,bool * no_add_attrs)814 handle_noipa_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
815 {
816 if (TREE_CODE (*node) != FUNCTION_DECL)
817 {
818 warning (OPT_Wattributes, "%qE attribute ignored", name);
819 *no_add_attrs = true;
820 }
821
822 return NULL_TREE;
823 }
824
825 /* Handle a "noinline" attribute; arguments as in
826 struct attribute_spec.handler. */
827
828 static tree
handle_noinline_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)829 handle_noinline_attribute (tree *node, tree name,
830 tree ARG_UNUSED (args),
831 int ARG_UNUSED (flags), bool *no_add_attrs)
832 {
833 if (TREE_CODE (*node) == FUNCTION_DECL)
834 {
835 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (*node)))
836 {
837 warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
838 "with attribute %qs", name, "always_inline");
839 *no_add_attrs = true;
840 }
841 else
842 DECL_UNINLINABLE (*node) = 1;
843 }
844 else
845 {
846 warning (OPT_Wattributes, "%qE attribute ignored", name);
847 *no_add_attrs = true;
848 }
849
850 return NULL_TREE;
851 }
852
853 /* Handle a "noclone" attribute; arguments as in
854 struct attribute_spec.handler. */
855
856 static tree
handle_noclone_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)857 handle_noclone_attribute (tree *node, tree name,
858 tree ARG_UNUSED (args),
859 int ARG_UNUSED (flags), bool *no_add_attrs)
860 {
861 if (TREE_CODE (*node) != FUNCTION_DECL)
862 {
863 warning (OPT_Wattributes, "%qE attribute ignored", name);
864 *no_add_attrs = true;
865 }
866
867 return NULL_TREE;
868 }
869
870 /* Handle a "nocf_check" attribute; arguments as in
871 struct attribute_spec.handler. */
872
873 static tree
handle_nocf_check_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)874 handle_nocf_check_attribute (tree *node, tree name,
875 tree ARG_UNUSED (args),
876 int ARG_UNUSED (flags), bool *no_add_attrs)
877 {
878 if (TREE_CODE (*node) != FUNCTION_TYPE
879 && TREE_CODE (*node) != METHOD_TYPE)
880 {
881 warning (OPT_Wattributes, "%qE attribute ignored", name);
882 *no_add_attrs = true;
883 }
884 else if (!(flag_cf_protection & CF_BRANCH))
885 {
886 warning (OPT_Wattributes, "%qE attribute ignored. Use "
887 "-fcf-protection option to enable it", name);
888 *no_add_attrs = true;
889 }
890
891 return NULL_TREE;
892 }
893
894 /* Handle a "no_icf" attribute; arguments as in
895 struct attribute_spec.handler. */
896
897 static tree
handle_noicf_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)898 handle_noicf_attribute (tree *node, tree name,
899 tree ARG_UNUSED (args),
900 int ARG_UNUSED (flags), bool *no_add_attrs)
901 {
902 if (TREE_CODE (*node) != FUNCTION_DECL)
903 {
904 warning (OPT_Wattributes, "%qE attribute ignored", name);
905 *no_add_attrs = true;
906 }
907
908 return NULL_TREE;
909 }
910
911
912 /* Handle a "always_inline" attribute; arguments as in
913 struct attribute_spec.handler. */
914
915 static tree
handle_always_inline_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)916 handle_always_inline_attribute (tree *node, tree name,
917 tree ARG_UNUSED (args),
918 int ARG_UNUSED (flags),
919 bool *no_add_attrs)
920 {
921 if (TREE_CODE (*node) == FUNCTION_DECL)
922 {
923 if (lookup_attribute ("noinline", DECL_ATTRIBUTES (*node)))
924 {
925 warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
926 "with %qs attribute", name, "noinline");
927 *no_add_attrs = true;
928 }
929 else if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (*node)))
930 {
931 warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
932 "with %qs attribute", name, "target_clones");
933 *no_add_attrs = true;
934 }
935 else
936 /* Set the attribute and mark it for disregarding inline
937 limits. */
938 DECL_DISREGARD_INLINE_LIMITS (*node) = 1;
939 }
940 else
941 {
942 warning (OPT_Wattributes, "%qE attribute ignored", name);
943 *no_add_attrs = true;
944 }
945
946 return NULL_TREE;
947 }
948
949 /* Handle a "gnu_inline" attribute; arguments as in
950 struct attribute_spec.handler. */
951
952 static tree
handle_gnu_inline_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)953 handle_gnu_inline_attribute (tree *node, tree name,
954 tree ARG_UNUSED (args),
955 int ARG_UNUSED (flags),
956 bool *no_add_attrs)
957 {
958 if (TREE_CODE (*node) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (*node))
959 {
960 /* Do nothing else, just set the attribute. We'll get at
961 it later with lookup_attribute. */
962 }
963 else
964 {
965 warning (OPT_Wattributes, "%qE attribute ignored", name);
966 *no_add_attrs = true;
967 }
968
969 return NULL_TREE;
970 }
971
972 /* Handle a "leaf" attribute; arguments as in
973 struct attribute_spec.handler. */
974
975 static tree
handle_leaf_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)976 handle_leaf_attribute (tree *node, tree name,
977 tree ARG_UNUSED (args),
978 int ARG_UNUSED (flags), bool *no_add_attrs)
979 {
980 if (TREE_CODE (*node) != FUNCTION_DECL)
981 {
982 warning (OPT_Wattributes, "%qE attribute ignored", name);
983 *no_add_attrs = true;
984 }
985 if (!TREE_PUBLIC (*node))
986 {
987 warning (OPT_Wattributes, "%qE attribute has no effect on unit local "
988 "functions", name);
989 *no_add_attrs = true;
990 }
991
992 return NULL_TREE;
993 }
994
995 /* Handle an "artificial" attribute; arguments as in
996 struct attribute_spec.handler. */
997
998 static tree
handle_artificial_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)999 handle_artificial_attribute (tree *node, tree name,
1000 tree ARG_UNUSED (args),
1001 int ARG_UNUSED (flags),
1002 bool *no_add_attrs)
1003 {
1004 if (TREE_CODE (*node) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (*node))
1005 {
1006 /* Do nothing else, just set the attribute. We'll get at
1007 it later with lookup_attribute. */
1008 }
1009 else
1010 {
1011 warning (OPT_Wattributes, "%qE attribute ignored", name);
1012 *no_add_attrs = true;
1013 }
1014
1015 return NULL_TREE;
1016 }
1017
1018 /* Handle a "flatten" attribute; arguments as in
1019 struct attribute_spec.handler. */
1020
1021 static tree
handle_flatten_attribute(tree * node,tree name,tree args ATTRIBUTE_UNUSED,int flags ATTRIBUTE_UNUSED,bool * no_add_attrs)1022 handle_flatten_attribute (tree *node, tree name,
1023 tree args ATTRIBUTE_UNUSED,
1024 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
1025 {
1026 if (TREE_CODE (*node) == FUNCTION_DECL)
1027 /* Do nothing else, just set the attribute. We'll get at
1028 it later with lookup_attribute. */
1029 ;
1030 else
1031 {
1032 warning (OPT_Wattributes, "%qE attribute ignored", name);
1033 *no_add_attrs = true;
1034 }
1035
1036 return NULL_TREE;
1037 }
1038
1039 /* Handle a "warning" or "error" attribute; arguments as in
1040 struct attribute_spec.handler. */
1041
1042 static tree
handle_error_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)1043 handle_error_attribute (tree *node, tree name, tree args,
1044 int ARG_UNUSED (flags), bool *no_add_attrs)
1045 {
1046 if (TREE_CODE (*node) == FUNCTION_DECL
1047 && TREE_CODE (TREE_VALUE (args)) == STRING_CST)
1048 /* Do nothing else, just set the attribute. We'll get at
1049 it later with lookup_attribute. */
1050 ;
1051 else
1052 {
1053 warning (OPT_Wattributes, "%qE attribute ignored", name);
1054 *no_add_attrs = true;
1055 }
1056
1057 return NULL_TREE;
1058 }
1059
1060 /* Handle a "used" attribute; arguments as in
1061 struct attribute_spec.handler. */
1062
1063 static tree
handle_used_attribute(tree * pnode,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)1064 handle_used_attribute (tree *pnode, tree name, tree ARG_UNUSED (args),
1065 int ARG_UNUSED (flags), bool *no_add_attrs)
1066 {
1067 tree node = *pnode;
1068
1069 if (TREE_CODE (node) == FUNCTION_DECL
1070 || (VAR_P (node) && TREE_STATIC (node))
1071 || (TREE_CODE (node) == TYPE_DECL))
1072 {
1073 TREE_USED (node) = 1;
1074 DECL_PRESERVE_P (node) = 1;
1075 if (VAR_P (node))
1076 DECL_READ_P (node) = 1;
1077 }
1078 else
1079 {
1080 warning (OPT_Wattributes, "%qE attribute ignored", name);
1081 *no_add_attrs = true;
1082 }
1083
1084 return NULL_TREE;
1085 }
1086
1087 /* Handle a "unused" attribute; arguments as in
1088 struct attribute_spec.handler. */
1089
1090 tree
handle_unused_attribute(tree * node,tree name,tree ARG_UNUSED (args),int flags,bool * no_add_attrs)1091 handle_unused_attribute (tree *node, tree name, tree ARG_UNUSED (args),
1092 int flags, bool *no_add_attrs)
1093 {
1094 if (DECL_P (*node))
1095 {
1096 tree decl = *node;
1097
1098 if (TREE_CODE (decl) == PARM_DECL
1099 || VAR_OR_FUNCTION_DECL_P (decl)
1100 || TREE_CODE (decl) == LABEL_DECL
1101 || TREE_CODE (decl) == CONST_DECL
1102 || TREE_CODE (decl) == TYPE_DECL)
1103 {
1104 TREE_USED (decl) = 1;
1105 if (VAR_P (decl) || TREE_CODE (decl) == PARM_DECL)
1106 DECL_READ_P (decl) = 1;
1107 }
1108 else
1109 {
1110 warning (OPT_Wattributes, "%qE attribute ignored", name);
1111 *no_add_attrs = true;
1112 }
1113 }
1114 else
1115 {
1116 if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
1117 *node = build_variant_type_copy (*node);
1118 TREE_USED (*node) = 1;
1119 }
1120
1121 return NULL_TREE;
1122 }
1123
1124 /* Handle a "externally_visible" attribute; arguments as in
1125 struct attribute_spec.handler. */
1126
1127 static tree
handle_externally_visible_attribute(tree * pnode,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)1128 handle_externally_visible_attribute (tree *pnode, tree name,
1129 tree ARG_UNUSED (args),
1130 int ARG_UNUSED (flags),
1131 bool *no_add_attrs)
1132 {
1133 tree node = *pnode;
1134
1135 if (VAR_OR_FUNCTION_DECL_P (node))
1136 {
1137 if ((!TREE_STATIC (node) && TREE_CODE (node) != FUNCTION_DECL
1138 && !DECL_EXTERNAL (node)) || !TREE_PUBLIC (node))
1139 {
1140 warning (OPT_Wattributes,
1141 "%qE attribute have effect only on public objects", name);
1142 *no_add_attrs = true;
1143 }
1144 }
1145 else
1146 {
1147 warning (OPT_Wattributes, "%qE attribute ignored", name);
1148 *no_add_attrs = true;
1149 }
1150
1151 return NULL_TREE;
1152 }
1153
1154 /* Handle the "no_reorder" attribute. Arguments as in
1155 struct attribute_spec.handler. */
1156
1157 static tree
handle_no_reorder_attribute(tree * pnode,tree name,tree,int,bool * no_add_attrs)1158 handle_no_reorder_attribute (tree *pnode,
1159 tree name,
1160 tree,
1161 int,
1162 bool *no_add_attrs)
1163 {
1164 tree node = *pnode;
1165
1166 if (!VAR_OR_FUNCTION_DECL_P (node)
1167 && !(TREE_STATIC (node) || DECL_EXTERNAL (node)))
1168 {
1169 warning (OPT_Wattributes,
1170 "%qE attribute only affects top level objects",
1171 name);
1172 *no_add_attrs = true;
1173 }
1174
1175 return NULL_TREE;
1176 }
1177
1178 /* Handle a "const" attribute; arguments as in
1179 struct attribute_spec.handler. */
1180
1181 static tree
handle_const_attribute(tree * node,tree name,tree ARG_UNUSED (args),int flags,bool * no_add_attrs)1182 handle_const_attribute (tree *node, tree name, tree ARG_UNUSED (args),
1183 int flags, bool *no_add_attrs)
1184 {
1185 tree type = TREE_TYPE (*node);
1186
1187 /* See FIXME comment on noreturn in c_common_attribute_table. */
1188 if (TREE_CODE (*node) == FUNCTION_DECL)
1189 TREE_READONLY (*node) = 1;
1190 else if (TREE_CODE (type) == POINTER_TYPE
1191 && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
1192 TREE_TYPE (*node)
1193 = (build_qualified_type
1194 (build_pointer_type
1195 (build_type_variant (TREE_TYPE (type), 1,
1196 TREE_THIS_VOLATILE (TREE_TYPE (type)))),
1197 TYPE_QUALS (type)));
1198 else
1199 {
1200 warning (OPT_Wattributes, "%qE attribute ignored", name);
1201 *no_add_attrs = true;
1202 }
1203
1204 /* void __builtin_unreachable(void) is const. Accept other such
1205 built-ins but warn on user-defined functions that return void. */
1206 if (!(flags & ATTR_FLAG_BUILT_IN)
1207 && TREE_CODE (*node) == FUNCTION_DECL
1208 && VOID_TYPE_P (TREE_TYPE (type)))
1209 warning (OPT_Wattributes, "%qE attribute on function "
1210 "returning %<void%>", name);
1211
1212 return NULL_TREE;
1213 }
1214
1215 /* Handle a "scalar_storage_order" attribute; arguments as in
1216 struct attribute_spec.handler. */
1217
1218 static tree
handle_scalar_storage_order_attribute(tree * node,tree name,tree args,int flags,bool * no_add_attrs)1219 handle_scalar_storage_order_attribute (tree *node, tree name, tree args,
1220 int flags, bool *no_add_attrs)
1221 {
1222 tree id = TREE_VALUE (args);
1223 tree type;
1224
1225 if (TREE_CODE (*node) == TYPE_DECL
1226 && ! (flags & ATTR_FLAG_CXX11))
1227 node = &TREE_TYPE (*node);
1228 type = *node;
1229
1230 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
1231 {
1232 error ("scalar_storage_order is not supported because endianness "
1233 "is not uniform");
1234 return NULL_TREE;
1235 }
1236
1237 if (RECORD_OR_UNION_TYPE_P (type) && !c_dialect_cxx ())
1238 {
1239 bool reverse = false;
1240
1241 if (TREE_CODE (id) == STRING_CST
1242 && strcmp (TREE_STRING_POINTER (id), "big-endian") == 0)
1243 reverse = !BYTES_BIG_ENDIAN;
1244 else if (TREE_CODE (id) == STRING_CST
1245 && strcmp (TREE_STRING_POINTER (id), "little-endian") == 0)
1246 reverse = BYTES_BIG_ENDIAN;
1247 else
1248 {
1249 error ("scalar_storage_order argument must be one of \"big-endian\""
1250 " or \"little-endian\"");
1251 return NULL_TREE;
1252 }
1253
1254 if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
1255 {
1256 if (reverse)
1257 /* A type variant isn't good enough, since we don't want a cast
1258 to such a type to be removed as a no-op. */
1259 *node = type = build_duplicate_type (type);
1260 }
1261
1262 TYPE_REVERSE_STORAGE_ORDER (type) = reverse;
1263 return NULL_TREE;
1264 }
1265
1266 warning (OPT_Wattributes, "%qE attribute ignored", name);
1267 *no_add_attrs = true;
1268 return NULL_TREE;
1269 }
1270
1271 /* Handle a "transparent_union" attribute; arguments as in
1272 struct attribute_spec.handler. */
1273
1274 static tree
handle_transparent_union_attribute(tree * node,tree name,tree ARG_UNUSED (args),int flags,bool * no_add_attrs)1275 handle_transparent_union_attribute (tree *node, tree name,
1276 tree ARG_UNUSED (args), int flags,
1277 bool *no_add_attrs)
1278 {
1279 tree type;
1280
1281 *no_add_attrs = true;
1282
1283 if (TREE_CODE (*node) == TYPE_DECL
1284 && ! (flags & ATTR_FLAG_CXX11))
1285 node = &TREE_TYPE (*node);
1286 type = *node;
1287
1288 if (TREE_CODE (type) == UNION_TYPE)
1289 {
1290 /* Make sure that the first field will work for a transparent union.
1291 If the type isn't complete yet, leave the check to the code in
1292 finish_struct. */
1293 if (TYPE_SIZE (type))
1294 {
1295 tree first = first_field (type);
1296 if (first == NULL_TREE
1297 || DECL_ARTIFICIAL (first)
1298 || TYPE_MODE (type) != DECL_MODE (first))
1299 goto ignored;
1300 }
1301
1302 if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
1303 {
1304 /* If the type isn't complete yet, setting the flag
1305 on a variant wouldn't ever be checked. */
1306 if (!TYPE_SIZE (type))
1307 goto ignored;
1308
1309 /* build_duplicate_type doesn't work for C++. */
1310 if (c_dialect_cxx ())
1311 goto ignored;
1312
1313 /* A type variant isn't good enough, since we don't want a cast
1314 to such a type to be removed as a no-op. */
1315 *node = type = build_duplicate_type (type);
1316 }
1317
1318 for (tree t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
1319 TYPE_TRANSPARENT_AGGR (t) = 1;
1320 return NULL_TREE;
1321 }
1322
1323 ignored:
1324 warning (OPT_Wattributes, "%qE attribute ignored", name);
1325 return NULL_TREE;
1326 }
1327
1328 /* Subroutine of handle_{con,de}structor_attribute. Evaluate ARGS to
1329 get the requested priority for a constructor or destructor,
1330 possibly issuing diagnostics for invalid or reserved
1331 priorities. */
1332
1333 static priority_type
get_priority(tree args,bool is_destructor)1334 get_priority (tree args, bool is_destructor)
1335 {
1336 HOST_WIDE_INT pri;
1337 tree arg;
1338
1339 if (!args)
1340 return DEFAULT_INIT_PRIORITY;
1341
1342 if (!SUPPORTS_INIT_PRIORITY)
1343 {
1344 if (is_destructor)
1345 error ("destructor priorities are not supported");
1346 else
1347 error ("constructor priorities are not supported");
1348 return DEFAULT_INIT_PRIORITY;
1349 }
1350
1351 arg = TREE_VALUE (args);
1352 if (TREE_CODE (arg) == IDENTIFIER_NODE)
1353 goto invalid;
1354 if (arg == error_mark_node)
1355 return DEFAULT_INIT_PRIORITY;
1356 arg = default_conversion (arg);
1357 if (!tree_fits_shwi_p (arg)
1358 || !INTEGRAL_TYPE_P (TREE_TYPE (arg)))
1359 goto invalid;
1360
1361 pri = tree_to_shwi (arg);
1362 if (pri < 0 || pri > MAX_INIT_PRIORITY)
1363 goto invalid;
1364
1365 if (pri <= MAX_RESERVED_INIT_PRIORITY)
1366 {
1367 if (is_destructor)
1368 warning (0,
1369 "destructor priorities from 0 to %d are reserved "
1370 "for the implementation",
1371 MAX_RESERVED_INIT_PRIORITY);
1372 else
1373 warning (0,
1374 "constructor priorities from 0 to %d are reserved "
1375 "for the implementation",
1376 MAX_RESERVED_INIT_PRIORITY);
1377 }
1378 return pri;
1379
1380 invalid:
1381 if (is_destructor)
1382 error ("destructor priorities must be integers from 0 to %d inclusive",
1383 MAX_INIT_PRIORITY);
1384 else
1385 error ("constructor priorities must be integers from 0 to %d inclusive",
1386 MAX_INIT_PRIORITY);
1387 return DEFAULT_INIT_PRIORITY;
1388 }
1389
1390 /* Handle a "constructor" attribute; arguments as in
1391 struct attribute_spec.handler. */
1392
1393 static tree
handle_constructor_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)1394 handle_constructor_attribute (tree *node, tree name, tree args,
1395 int ARG_UNUSED (flags),
1396 bool *no_add_attrs)
1397 {
1398 tree decl = *node;
1399 tree type = TREE_TYPE (decl);
1400
1401 if (TREE_CODE (decl) == FUNCTION_DECL
1402 && TREE_CODE (type) == FUNCTION_TYPE
1403 && decl_function_context (decl) == 0)
1404 {
1405 priority_type priority;
1406 DECL_STATIC_CONSTRUCTOR (decl) = 1;
1407 priority = get_priority (args, /*is_destructor=*/false);
1408 SET_DECL_INIT_PRIORITY (decl, priority);
1409 TREE_USED (decl) = 1;
1410 }
1411 else
1412 {
1413 warning (OPT_Wattributes, "%qE attribute ignored", name);
1414 *no_add_attrs = true;
1415 }
1416
1417 return NULL_TREE;
1418 }
1419
1420 /* Handle a "destructor" attribute; arguments as in
1421 struct attribute_spec.handler. */
1422
1423 static tree
handle_destructor_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)1424 handle_destructor_attribute (tree *node, tree name, tree args,
1425 int ARG_UNUSED (flags),
1426 bool *no_add_attrs)
1427 {
1428 tree decl = *node;
1429 tree type = TREE_TYPE (decl);
1430
1431 if (TREE_CODE (decl) == FUNCTION_DECL
1432 && TREE_CODE (type) == FUNCTION_TYPE
1433 && decl_function_context (decl) == 0)
1434 {
1435 priority_type priority;
1436 DECL_STATIC_DESTRUCTOR (decl) = 1;
1437 priority = get_priority (args, /*is_destructor=*/true);
1438 SET_DECL_FINI_PRIORITY (decl, priority);
1439 TREE_USED (decl) = 1;
1440 }
1441 else
1442 {
1443 warning (OPT_Wattributes, "%qE attribute ignored", name);
1444 *no_add_attrs = true;
1445 }
1446
1447 return NULL_TREE;
1448 }
1449
1450 /* Nonzero if the mode is a valid vector mode for this architecture.
1451 This returns nonzero even if there is no hardware support for the
1452 vector mode, but we can emulate with narrower modes. */
1453
1454 static bool
vector_mode_valid_p(machine_mode mode)1455 vector_mode_valid_p (machine_mode mode)
1456 {
1457 enum mode_class mclass = GET_MODE_CLASS (mode);
1458
1459 /* Doh! What's going on? */
1460 if (mclass != MODE_VECTOR_INT
1461 && mclass != MODE_VECTOR_FLOAT
1462 && mclass != MODE_VECTOR_FRACT
1463 && mclass != MODE_VECTOR_UFRACT
1464 && mclass != MODE_VECTOR_ACCUM
1465 && mclass != MODE_VECTOR_UACCUM)
1466 return false;
1467
1468 /* Hardware support. Woo hoo! */
1469 if (targetm.vector_mode_supported_p (mode))
1470 return true;
1471
1472 /* We should probably return 1 if requesting V4DI and we have no DI,
1473 but we have V2DI, but this is probably very unlikely. */
1474
1475 /* If we have support for the inner mode, we can safely emulate it.
1476 We may not have V2DI, but me can emulate with a pair of DIs. */
1477 return targetm.scalar_mode_supported_p (GET_MODE_INNER (mode));
1478 }
1479
1480
1481 /* Handle a "mode" attribute; arguments as in
1482 struct attribute_spec.handler. */
1483
1484 static tree
handle_mode_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)1485 handle_mode_attribute (tree *node, tree name, tree args,
1486 int ARG_UNUSED (flags), bool *no_add_attrs)
1487 {
1488 tree type = *node;
1489 tree ident = TREE_VALUE (args);
1490
1491 *no_add_attrs = true;
1492
1493 if (TREE_CODE (ident) != IDENTIFIER_NODE)
1494 warning (OPT_Wattributes, "%qE attribute ignored", name);
1495 else
1496 {
1497 int j;
1498 const char *p = IDENTIFIER_POINTER (ident);
1499 int len = strlen (p);
1500 machine_mode mode = VOIDmode;
1501 tree typefm;
1502 bool valid_mode;
1503
1504 if (len > 4 && p[0] == '_' && p[1] == '_'
1505 && p[len - 1] == '_' && p[len - 2] == '_')
1506 {
1507 char *newp = (char *) alloca (len - 1);
1508
1509 strcpy (newp, &p[2]);
1510 newp[len - 4] = '\0';
1511 p = newp;
1512 }
1513
1514 /* Change this type to have a type with the specified mode.
1515 First check for the special modes. */
1516 if (!strcmp (p, "byte"))
1517 mode = byte_mode;
1518 else if (!strcmp (p, "word"))
1519 mode = word_mode;
1520 else if (!strcmp (p, "pointer"))
1521 mode = ptr_mode;
1522 else if (!strcmp (p, "libgcc_cmp_return"))
1523 mode = targetm.libgcc_cmp_return_mode ();
1524 else if (!strcmp (p, "libgcc_shift_count"))
1525 mode = targetm.libgcc_shift_count_mode ();
1526 else if (!strcmp (p, "unwind_word"))
1527 mode = targetm.unwind_word_mode ();
1528 else
1529 for (j = 0; j < NUM_MACHINE_MODES; j++)
1530 if (!strcmp (p, GET_MODE_NAME (j)))
1531 {
1532 mode = (machine_mode) j;
1533 break;
1534 }
1535
1536 if (mode == VOIDmode)
1537 {
1538 error ("unknown machine mode %qE", ident);
1539 return NULL_TREE;
1540 }
1541
1542 valid_mode = false;
1543 switch (GET_MODE_CLASS (mode))
1544 {
1545 case MODE_INT:
1546 case MODE_PARTIAL_INT:
1547 case MODE_FLOAT:
1548 case MODE_DECIMAL_FLOAT:
1549 case MODE_FRACT:
1550 case MODE_UFRACT:
1551 case MODE_ACCUM:
1552 case MODE_UACCUM:
1553 valid_mode
1554 = targetm.scalar_mode_supported_p (as_a <scalar_mode> (mode));
1555 break;
1556
1557 case MODE_COMPLEX_INT:
1558 case MODE_COMPLEX_FLOAT:
1559 valid_mode = targetm.scalar_mode_supported_p (GET_MODE_INNER (mode));
1560 break;
1561
1562 case MODE_VECTOR_INT:
1563 case MODE_VECTOR_FLOAT:
1564 case MODE_VECTOR_FRACT:
1565 case MODE_VECTOR_UFRACT:
1566 case MODE_VECTOR_ACCUM:
1567 case MODE_VECTOR_UACCUM:
1568 warning (OPT_Wattributes, "specifying vector types with "
1569 "__attribute__ ((mode)) is deprecated");
1570 warning (OPT_Wattributes,
1571 "use __attribute__ ((vector_size)) instead");
1572 valid_mode = vector_mode_valid_p (mode);
1573 break;
1574
1575 default:
1576 break;
1577 }
1578 if (!valid_mode)
1579 {
1580 error ("unable to emulate %qs", p);
1581 return NULL_TREE;
1582 }
1583
1584 if (POINTER_TYPE_P (type))
1585 {
1586 scalar_int_mode addr_mode;
1587 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (type));
1588 tree (*fn)(tree, machine_mode, bool);
1589
1590 if (!is_a <scalar_int_mode> (mode, &addr_mode)
1591 || !targetm.addr_space.valid_pointer_mode (addr_mode, as))
1592 {
1593 error ("invalid pointer mode %qs", p);
1594 return NULL_TREE;
1595 }
1596
1597 if (TREE_CODE (type) == POINTER_TYPE)
1598 fn = build_pointer_type_for_mode;
1599 else
1600 fn = build_reference_type_for_mode;
1601 typefm = fn (TREE_TYPE (type), addr_mode, false);
1602 }
1603 else
1604 {
1605 /* For fixed-point modes, we need to test if the signness of type
1606 and the machine mode are consistent. */
1607 if (ALL_FIXED_POINT_MODE_P (mode)
1608 && TYPE_UNSIGNED (type) != UNSIGNED_FIXED_POINT_MODE_P (mode))
1609 {
1610 error ("signedness of type and machine mode %qs don%'t match", p);
1611 return NULL_TREE;
1612 }
1613 /* For fixed-point modes, we need to pass saturating info. */
1614 typefm = lang_hooks.types.type_for_mode (mode,
1615 ALL_FIXED_POINT_MODE_P (mode) ? TYPE_SATURATING (type)
1616 : TYPE_UNSIGNED (type));
1617 }
1618
1619 if (typefm == NULL_TREE)
1620 {
1621 error ("no data type for mode %qs", p);
1622 return NULL_TREE;
1623 }
1624 else if (TREE_CODE (type) == ENUMERAL_TYPE)
1625 {
1626 /* For enumeral types, copy the precision from the integer
1627 type returned above. If not an INTEGER_TYPE, we can't use
1628 this mode for this type. */
1629 if (TREE_CODE (typefm) != INTEGER_TYPE)
1630 {
1631 error ("cannot use mode %qs for enumeral types", p);
1632 return NULL_TREE;
1633 }
1634
1635 if (flags & ATTR_FLAG_TYPE_IN_PLACE)
1636 {
1637 TYPE_PRECISION (type) = TYPE_PRECISION (typefm);
1638 typefm = type;
1639 }
1640 else
1641 {
1642 /* We cannot build a type variant, as there's code that assumes
1643 that TYPE_MAIN_VARIANT has the same mode. This includes the
1644 debug generators. Instead, create a subrange type. This
1645 results in all of the enumeral values being emitted only once
1646 in the original, and the subtype gets them by reference. */
1647 if (TYPE_UNSIGNED (type))
1648 typefm = make_unsigned_type (TYPE_PRECISION (typefm));
1649 else
1650 typefm = make_signed_type (TYPE_PRECISION (typefm));
1651 TREE_TYPE (typefm) = type;
1652 }
1653 }
1654 else if (VECTOR_MODE_P (mode)
1655 ? TREE_CODE (type) != TREE_CODE (TREE_TYPE (typefm))
1656 : TREE_CODE (type) != TREE_CODE (typefm))
1657 {
1658 error ("mode %qs applied to inappropriate type", p);
1659 return NULL_TREE;
1660 }
1661
1662 *node = build_qualified_type (typefm, TYPE_QUALS (type));
1663 }
1664
1665 return NULL_TREE;
1666 }
1667
1668 /* Handle a "section" attribute; arguments as in
1669 struct attribute_spec.handler. */
1670
1671 static tree
handle_section_attribute(tree * node,tree ARG_UNUSED (name),tree args,int ARG_UNUSED (flags),bool * no_add_attrs)1672 handle_section_attribute (tree *node, tree ARG_UNUSED (name), tree args,
1673 int ARG_UNUSED (flags), bool *no_add_attrs)
1674 {
1675 tree decl = *node;
1676
1677 if (!targetm_common.have_named_sections)
1678 {
1679 error_at (DECL_SOURCE_LOCATION (*node),
1680 "section attributes are not supported for this target");
1681 goto fail;
1682 }
1683
1684 if (!VAR_OR_FUNCTION_DECL_P (decl))
1685 {
1686 error ("section attribute not allowed for %q+D", *node);
1687 goto fail;
1688 }
1689
1690 if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
1691 {
1692 error ("section attribute argument not a string constant");
1693 goto fail;
1694 }
1695
1696 if (VAR_P (decl)
1697 && current_function_decl != NULL_TREE
1698 && !TREE_STATIC (decl))
1699 {
1700 error_at (DECL_SOURCE_LOCATION (decl),
1701 "section attribute cannot be specified for local variables");
1702 goto fail;
1703 }
1704
1705 /* The decl may have already been given a section attribute
1706 from a previous declaration. Ensure they match. */
1707 if (DECL_SECTION_NAME (decl) != NULL
1708 && strcmp (DECL_SECTION_NAME (decl),
1709 TREE_STRING_POINTER (TREE_VALUE (args))) != 0)
1710 {
1711 error ("section of %q+D conflicts with previous declaration", *node);
1712 goto fail;
1713 }
1714
1715 if (VAR_P (decl)
1716 && !targetm.have_tls && targetm.emutls.tmpl_section
1717 && DECL_THREAD_LOCAL_P (decl))
1718 {
1719 error ("section of %q+D cannot be overridden", *node);
1720 goto fail;
1721 }
1722
1723 set_decl_section_name (decl, TREE_STRING_POINTER (TREE_VALUE (args)));
1724 return NULL_TREE;
1725
1726 fail:
1727 *no_add_attrs = true;
1728 return NULL_TREE;
1729 }
1730
1731 /* If in c++-11, check if the c++-11 alignment constraint with respect
1732 to fundamental alignment (in [dcl.align]) are satisfied. If not in
1733 c++-11 mode, does nothing.
1734
1735 [dcl.align]2/ says:
1736
1737 [* if the constant expression evaluates to a fundamental alignment,
1738 the alignment requirement of the declared entity shall be the
1739 specified fundamental alignment.
1740
1741 * if the constant expression evaluates to an extended alignment
1742 and the implementation supports that alignment in the context
1743 of the declaration, the alignment of the declared entity shall
1744 be that alignment
1745
1746 * if the constant expression evaluates to an extended alignment
1747 and the implementation does not support that alignment in the
1748 context of the declaration, the program is ill-formed]. */
1749
1750 static bool
check_cxx_fundamental_alignment_constraints(tree node,unsigned align_log,int flags)1751 check_cxx_fundamental_alignment_constraints (tree node,
1752 unsigned align_log,
1753 int flags)
1754 {
1755 bool alignment_too_large_p = false;
1756 unsigned requested_alignment = (1U << align_log) * BITS_PER_UNIT;
1757 unsigned max_align = 0;
1758
1759 if ((!(flags & ATTR_FLAG_CXX11) && !warn_cxx_compat)
1760 || (node == NULL_TREE || node == error_mark_node))
1761 return true;
1762
1763 if (cxx_fundamental_alignment_p (requested_alignment))
1764 return true;
1765
1766 if (VAR_P (node))
1767 {
1768 if (TREE_STATIC (node) || DECL_EXTERNAL (node))
1769 /* For file scope variables and static members, the target supports
1770 alignments that are at most MAX_OFILE_ALIGNMENT. */
1771 max_align = MAX_OFILE_ALIGNMENT;
1772 else
1773 /* For stack variables, the target supports at most
1774 MAX_STACK_ALIGNMENT. */
1775 max_align = MAX_STACK_ALIGNMENT;
1776 if (requested_alignment > max_align)
1777 alignment_too_large_p = true;
1778 }
1779 /* Let's be liberal for types and fields; don't limit their alignment any
1780 more than check_user_alignment already did. */
1781
1782 if (alignment_too_large_p)
1783 pedwarn (input_location, OPT_Wattributes,
1784 "requested alignment %d is larger than %d",
1785 requested_alignment / BITS_PER_UNIT, max_align / BITS_PER_UNIT);
1786
1787 return !alignment_too_large_p;
1788 }
1789
1790 /* Common codes shared by handle_warn_if_not_aligned_attribute and
1791 handle_aligned_attribute. */
1792
1793 static tree
common_handle_aligned_attribute(tree * node,tree name,tree args,int flags,bool * no_add_attrs,bool warn_if_not_aligned_p)1794 common_handle_aligned_attribute (tree *node, tree name, tree args, int flags,
1795 bool *no_add_attrs,
1796 bool warn_if_not_aligned_p)
1797 {
1798 tree decl = NULL_TREE;
1799 tree *type = NULL;
1800 bool is_type = false;
1801 tree align_expr;
1802
1803 /* The last (already pushed) declaration with all validated attributes
1804 merged in or the current about-to-be-pushed one if one hasn't been
1805 yet. */
1806 tree last_decl = node[1] ? node[1] : *node;
1807
1808 if (args)
1809 {
1810 align_expr = TREE_VALUE (args);
1811 if (align_expr && TREE_CODE (align_expr) != IDENTIFIER_NODE
1812 && TREE_CODE (align_expr) != FUNCTION_DECL)
1813 align_expr = default_conversion (align_expr);
1814 }
1815 else
1816 align_expr = size_int (ATTRIBUTE_ALIGNED_VALUE / BITS_PER_UNIT);
1817
1818 if (DECL_P (*node))
1819 {
1820 decl = *node;
1821 type = &TREE_TYPE (decl);
1822 is_type = TREE_CODE (*node) == TYPE_DECL;
1823 }
1824 else if (TYPE_P (*node))
1825 type = node, is_type = true;
1826
1827 /* Log2 of specified alignment. */
1828 int pow2align = check_user_alignment (align_expr, true);
1829 if (pow2align == -1
1830 || !check_cxx_fundamental_alignment_constraints (*node, pow2align, flags))
1831 {
1832 *no_add_attrs = true;
1833 return NULL_TREE;
1834 }
1835
1836 /* The alignment in bits corresponding to the specified alignment. */
1837 unsigned bitalign = (1U << pow2align) * BITS_PER_UNIT;
1838
1839 /* The alignment of the current declaration and that of the last
1840 pushed declaration, determined on demand below. */
1841 unsigned curalign = 0;
1842 unsigned lastalign = 0;
1843
1844 if (is_type)
1845 {
1846 if ((flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
1847 /* OK, modify the type in place. */;
1848 /* If we have a TYPE_DECL, then copy the type, so that we
1849 don't accidentally modify a builtin type. See pushdecl. */
1850 else if (decl && TREE_TYPE (decl) != error_mark_node
1851 && DECL_ORIGINAL_TYPE (decl) == NULL_TREE)
1852 {
1853 tree tt = TREE_TYPE (decl);
1854 *type = build_variant_type_copy (*type);
1855 DECL_ORIGINAL_TYPE (decl) = tt;
1856 TYPE_NAME (*type) = decl;
1857 TREE_USED (*type) = TREE_USED (decl);
1858 TREE_TYPE (decl) = *type;
1859 }
1860 else
1861 *type = build_variant_type_copy (*type);
1862
1863 if (warn_if_not_aligned_p)
1864 {
1865 SET_TYPE_WARN_IF_NOT_ALIGN (*type, bitalign);
1866 warn_if_not_aligned_p = false;
1867 }
1868 else
1869 {
1870 SET_TYPE_ALIGN (*type, bitalign);
1871 TYPE_USER_ALIGN (*type) = 1;
1872 }
1873 }
1874 else if (! VAR_OR_FUNCTION_DECL_P (decl)
1875 && TREE_CODE (decl) != FIELD_DECL)
1876 {
1877 error ("alignment may not be specified for %q+D", decl);
1878 *no_add_attrs = true;
1879 }
1880 else if (TREE_CODE (decl) == FUNCTION_DECL
1881 && ((curalign = DECL_ALIGN (decl)) > bitalign
1882 || ((lastalign = DECL_ALIGN (last_decl)) > bitalign)))
1883 {
1884 /* Either a prior attribute on the same declaration or one
1885 on a prior declaration of the same function specifies
1886 stricter alignment than this attribute. */
1887 bool note = lastalign != 0;
1888 if (lastalign)
1889 curalign = lastalign;
1890
1891 curalign /= BITS_PER_UNIT;
1892 bitalign /= BITS_PER_UNIT;
1893
1894 bool diagd = true;
1895 if (DECL_USER_ALIGN (decl) || DECL_USER_ALIGN (last_decl))
1896 diagd = warning (OPT_Wattributes,
1897 "ignoring attribute %<%E (%u)%> because it conflicts "
1898 "with attribute %<%E (%u)%>",
1899 name, bitalign, name, curalign);
1900 else if (!warn_if_not_aligned_p)
1901 /* Do not error out for attribute warn_if_not_aligned. */
1902 error ("alignment for %q+D must be at least %d", decl, curalign);
1903
1904 if (diagd && note)
1905 inform (DECL_SOURCE_LOCATION (last_decl), "previous declaration here");
1906
1907 *no_add_attrs = true;
1908 }
1909 else if (DECL_USER_ALIGN (decl)
1910 && DECL_ALIGN (decl) > bitalign)
1911 /* C++-11 [dcl.align/4]:
1912
1913 When multiple alignment-specifiers are specified for an
1914 entity, the alignment requirement shall be set to the
1915 strictest specified alignment.
1916
1917 This formally comes from the c++11 specification but we are
1918 doing it for the GNU attribute syntax as well. */
1919 *no_add_attrs = true;
1920 else if (!warn_if_not_aligned_p
1921 && TREE_CODE (decl) == FUNCTION_DECL
1922 && DECL_ALIGN (decl) > bitalign)
1923 {
1924 /* Don't warn function alignment here if warn_if_not_aligned_p is
1925 true. It will be warned later. */
1926 if (DECL_USER_ALIGN (decl))
1927 error ("alignment for %q+D was previously specified as %d "
1928 "and may not be decreased", decl,
1929 DECL_ALIGN (decl) / BITS_PER_UNIT);
1930 else
1931 error ("alignment for %q+D must be at least %d", decl,
1932 DECL_ALIGN (decl) / BITS_PER_UNIT);
1933 *no_add_attrs = true;
1934 }
1935 else
1936 {
1937 if (warn_if_not_aligned_p)
1938 {
1939 if (TREE_CODE (decl) == FIELD_DECL && !DECL_C_BIT_FIELD (decl))
1940 {
1941 SET_DECL_WARN_IF_NOT_ALIGN (decl, bitalign);
1942 warn_if_not_aligned_p = false;
1943 }
1944 }
1945 else
1946 {
1947 SET_DECL_ALIGN (decl, bitalign);
1948 DECL_USER_ALIGN (decl) = 1;
1949 }
1950 }
1951
1952 if (warn_if_not_aligned_p)
1953 {
1954 error ("%<warn_if_not_aligned%> may not be specified for %q+D",
1955 decl);
1956 *no_add_attrs = true;
1957 }
1958
1959 return NULL_TREE;
1960 }
1961
1962 /* Handle a "aligned" attribute; arguments as in
1963 struct attribute_spec.handler. */
1964
1965 static tree
handle_aligned_attribute(tree * node,tree name,tree args,int flags,bool * no_add_attrs)1966 handle_aligned_attribute (tree *node, tree name, tree args,
1967 int flags, bool *no_add_attrs)
1968 {
1969 return common_handle_aligned_attribute (node, name, args, flags,
1970 no_add_attrs, false);
1971 }
1972
1973 /* Handle a "warn_if_not_aligned" attribute; arguments as in
1974 struct attribute_spec.handler. */
1975
1976 static tree
handle_warn_if_not_aligned_attribute(tree * node,tree name,tree args,int flags,bool * no_add_attrs)1977 handle_warn_if_not_aligned_attribute (tree *node, tree name,
1978 tree args, int flags,
1979 bool *no_add_attrs)
1980 {
1981 return common_handle_aligned_attribute (node, name, args, flags,
1982 no_add_attrs, true);
1983 }
1984
1985 /* Handle a "weak" attribute; arguments as in
1986 struct attribute_spec.handler. */
1987
1988 static tree
handle_weak_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))1989 handle_weak_attribute (tree *node, tree name,
1990 tree ARG_UNUSED (args),
1991 int ARG_UNUSED (flags),
1992 bool * ARG_UNUSED (no_add_attrs))
1993 {
1994 if (TREE_CODE (*node) == FUNCTION_DECL
1995 && DECL_DECLARED_INLINE_P (*node))
1996 {
1997 warning (OPT_Wattributes, "inline function %q+D declared weak", *node);
1998 *no_add_attrs = true;
1999 }
2000 else if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (*node)))
2001 {
2002 error ("indirect function %q+D cannot be declared weak", *node);
2003 *no_add_attrs = true;
2004 return NULL_TREE;
2005 }
2006 else if (VAR_OR_FUNCTION_DECL_P (*node))
2007 declare_weak (*node);
2008 else
2009 warning (OPT_Wattributes, "%qE attribute ignored", name);
2010
2011 return NULL_TREE;
2012 }
2013
2014 /* Handle a "noplt" attribute; arguments as in
2015 struct attribute_spec.handler. */
2016
2017 static tree
handle_noplt_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))2018 handle_noplt_attribute (tree *node, tree name,
2019 tree ARG_UNUSED (args),
2020 int ARG_UNUSED (flags),
2021 bool * ARG_UNUSED (no_add_attrs))
2022 {
2023 if (TREE_CODE (*node) != FUNCTION_DECL)
2024 {
2025 warning (OPT_Wattributes,
2026 "%qE attribute is only applicable on functions", name);
2027 *no_add_attrs = true;
2028 return NULL_TREE;
2029 }
2030 return NULL_TREE;
2031 }
2032
2033 /* Handle an "alias" or "ifunc" attribute; arguments as in
2034 struct attribute_spec.handler, except that IS_ALIAS tells us
2035 whether this is an alias as opposed to ifunc attribute. */
2036
2037 static tree
handle_alias_ifunc_attribute(bool is_alias,tree * node,tree name,tree args,bool * no_add_attrs)2038 handle_alias_ifunc_attribute (bool is_alias, tree *node, tree name, tree args,
2039 bool *no_add_attrs)
2040 {
2041 tree decl = *node;
2042
2043 if (TREE_CODE (decl) != FUNCTION_DECL
2044 && (!is_alias || !VAR_P (decl)))
2045 {
2046 warning (OPT_Wattributes, "%qE attribute ignored", name);
2047 *no_add_attrs = true;
2048 }
2049 else if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl))
2050 || (TREE_CODE (decl) != FUNCTION_DECL
2051 && TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl))
2052 /* A static variable declaration is always a tentative definition,
2053 but the alias is a non-tentative definition which overrides. */
2054 || (TREE_CODE (decl) != FUNCTION_DECL
2055 && ! TREE_PUBLIC (decl) && DECL_INITIAL (decl)))
2056 {
2057 error ("%q+D defined both normally and as %qE attribute", decl, name);
2058 *no_add_attrs = true;
2059 return NULL_TREE;
2060 }
2061 else if (!is_alias
2062 && (lookup_attribute ("weak", DECL_ATTRIBUTES (decl))
2063 || lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))))
2064 {
2065 error ("weak %q+D cannot be defined %qE", decl, name);
2066 *no_add_attrs = true;
2067 return NULL_TREE;
2068 }
2069
2070 /* Note that the very first time we process a nested declaration,
2071 decl_function_context will not be set. Indeed, *would* never
2072 be set except for the DECL_INITIAL/DECL_EXTERNAL frobbery that
2073 we do below. After such frobbery, pushdecl would set the context.
2074 In any case, this is never what we want. */
2075 else if (decl_function_context (decl) == 0 && current_function_decl == NULL)
2076 {
2077 tree id;
2078
2079 id = TREE_VALUE (args);
2080 if (TREE_CODE (id) != STRING_CST)
2081 {
2082 error ("attribute %qE argument not a string", name);
2083 *no_add_attrs = true;
2084 return NULL_TREE;
2085 }
2086 id = get_identifier (TREE_STRING_POINTER (id));
2087 /* This counts as a use of the object pointed to. */
2088 TREE_USED (id) = 1;
2089
2090 if (TREE_CODE (decl) == FUNCTION_DECL)
2091 DECL_INITIAL (decl) = error_mark_node;
2092 else
2093 TREE_STATIC (decl) = 1;
2094
2095 if (!is_alias)
2096 {
2097 /* ifuncs are also aliases, so set that attribute too. */
2098 DECL_ATTRIBUTES (decl)
2099 = tree_cons (get_identifier ("alias"), args,
2100 DECL_ATTRIBUTES (decl));
2101 DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("ifunc"),
2102 NULL, DECL_ATTRIBUTES (decl));
2103 }
2104 }
2105 else
2106 {
2107 warning (OPT_Wattributes, "%qE attribute ignored", name);
2108 *no_add_attrs = true;
2109 }
2110
2111 if (decl_in_symtab_p (*node))
2112 {
2113 struct symtab_node *n = symtab_node::get (decl);
2114 if (n && n->refuse_visibility_changes)
2115 {
2116 if (is_alias)
2117 error ("%+qD declared alias after being used", decl);
2118 else
2119 error ("%+qD declared ifunc after being used", decl);
2120 }
2121 }
2122
2123
2124 return NULL_TREE;
2125 }
2126
2127 /* Handle an "alias" or "ifunc" attribute; arguments as in
2128 struct attribute_spec.handler. */
2129
2130 static tree
handle_ifunc_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)2131 handle_ifunc_attribute (tree *node, tree name, tree args,
2132 int ARG_UNUSED (flags), bool *no_add_attrs)
2133 {
2134 return handle_alias_ifunc_attribute (false, node, name, args, no_add_attrs);
2135 }
2136
2137 /* Handle an "alias" or "ifunc" attribute; arguments as in
2138 struct attribute_spec.handler. */
2139
2140 static tree
handle_alias_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)2141 handle_alias_attribute (tree *node, tree name, tree args,
2142 int ARG_UNUSED (flags), bool *no_add_attrs)
2143 {
2144 return handle_alias_ifunc_attribute (true, node, name, args, no_add_attrs);
2145 }
2146
2147 /* Handle a "weakref" attribute; arguments as in struct
2148 attribute_spec.handler. */
2149
2150 static tree
handle_weakref_attribute(tree * node,tree ARG_UNUSED (name),tree args,int flags,bool * no_add_attrs)2151 handle_weakref_attribute (tree *node, tree ARG_UNUSED (name), tree args,
2152 int flags, bool *no_add_attrs)
2153 {
2154 tree attr = NULL_TREE;
2155
2156 /* We must ignore the attribute when it is associated with
2157 local-scoped decls, since attribute alias is ignored and many
2158 such symbols do not even have a DECL_WEAK field. */
2159 if (decl_function_context (*node)
2160 || current_function_decl
2161 || !VAR_OR_FUNCTION_DECL_P (*node))
2162 {
2163 warning (OPT_Wattributes, "%qE attribute ignored", name);
2164 *no_add_attrs = true;
2165 return NULL_TREE;
2166 }
2167
2168 if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (*node)))
2169 {
2170 error ("indirect function %q+D cannot be declared weakref", *node);
2171 *no_add_attrs = true;
2172 return NULL_TREE;
2173 }
2174
2175 /* The idea here is that `weakref("name")' mutates into `weakref,
2176 alias("name")', and weakref without arguments, in turn,
2177 implicitly adds weak. */
2178
2179 if (args)
2180 {
2181 attr = tree_cons (get_identifier ("alias"), args, attr);
2182 attr = tree_cons (get_identifier ("weakref"), NULL_TREE, attr);
2183
2184 *no_add_attrs = true;
2185
2186 decl_attributes (node, attr, flags);
2187 }
2188 else
2189 {
2190 if (lookup_attribute ("alias", DECL_ATTRIBUTES (*node)))
2191 error_at (DECL_SOURCE_LOCATION (*node),
2192 "weakref attribute must appear before alias attribute");
2193
2194 /* Can't call declare_weak because it wants this to be TREE_PUBLIC,
2195 and that isn't supported; and because it wants to add it to
2196 the list of weak decls, which isn't helpful. */
2197 DECL_WEAK (*node) = 1;
2198 }
2199
2200 if (decl_in_symtab_p (*node))
2201 {
2202 struct symtab_node *n = symtab_node::get (*node);
2203 if (n && n->refuse_visibility_changes)
2204 error ("%+qD declared weakref after being used", *node);
2205 }
2206
2207 return NULL_TREE;
2208 }
2209
2210 /* Handle an "visibility" attribute; arguments as in
2211 struct attribute_spec.handler. */
2212
2213 static tree
handle_visibility_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))2214 handle_visibility_attribute (tree *node, tree name, tree args,
2215 int ARG_UNUSED (flags),
2216 bool *ARG_UNUSED (no_add_attrs))
2217 {
2218 tree decl = *node;
2219 tree id = TREE_VALUE (args);
2220 enum symbol_visibility vis;
2221
2222 if (TYPE_P (*node))
2223 {
2224 if (TREE_CODE (*node) == ENUMERAL_TYPE)
2225 /* OK */;
2226 else if (!RECORD_OR_UNION_TYPE_P (*node))
2227 {
2228 warning (OPT_Wattributes, "%qE attribute ignored on non-class types",
2229 name);
2230 return NULL_TREE;
2231 }
2232 else if (TYPE_FIELDS (*node))
2233 {
2234 error ("%qE attribute ignored because %qT is already defined",
2235 name, *node);
2236 return NULL_TREE;
2237 }
2238 }
2239 else if (decl_function_context (decl) != 0 || !TREE_PUBLIC (decl))
2240 {
2241 warning (OPT_Wattributes, "%qE attribute ignored", name);
2242 return NULL_TREE;
2243 }
2244
2245 if (TREE_CODE (id) != STRING_CST)
2246 {
2247 error ("visibility argument not a string");
2248 return NULL_TREE;
2249 }
2250
2251 /* If this is a type, set the visibility on the type decl. */
2252 if (TYPE_P (decl))
2253 {
2254 decl = TYPE_NAME (decl);
2255 if (!decl)
2256 return NULL_TREE;
2257 if (TREE_CODE (decl) == IDENTIFIER_NODE)
2258 {
2259 warning (OPT_Wattributes, "%qE attribute ignored on types",
2260 name);
2261 return NULL_TREE;
2262 }
2263 }
2264
2265 if (strcmp (TREE_STRING_POINTER (id), "default") == 0)
2266 vis = VISIBILITY_DEFAULT;
2267 else if (strcmp (TREE_STRING_POINTER (id), "internal") == 0)
2268 vis = VISIBILITY_INTERNAL;
2269 else if (strcmp (TREE_STRING_POINTER (id), "hidden") == 0)
2270 vis = VISIBILITY_HIDDEN;
2271 else if (strcmp (TREE_STRING_POINTER (id), "protected") == 0)
2272 vis = VISIBILITY_PROTECTED;
2273 else
2274 {
2275 error ("visibility argument must be one of \"default\", \"hidden\", \"protected\" or \"internal\"");
2276 vis = VISIBILITY_DEFAULT;
2277 }
2278
2279 if (DECL_VISIBILITY_SPECIFIED (decl)
2280 && vis != DECL_VISIBILITY (decl))
2281 {
2282 tree attributes = (TYPE_P (*node)
2283 ? TYPE_ATTRIBUTES (*node)
2284 : DECL_ATTRIBUTES (decl));
2285 if (lookup_attribute ("visibility", attributes))
2286 error ("%qD redeclared with different visibility", decl);
2287 else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
2288 && lookup_attribute ("dllimport", attributes))
2289 error ("%qD was declared %qs which implies default visibility",
2290 decl, "dllimport");
2291 else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
2292 && lookup_attribute ("dllexport", attributes))
2293 error ("%qD was declared %qs which implies default visibility",
2294 decl, "dllexport");
2295 }
2296
2297 DECL_VISIBILITY (decl) = vis;
2298 DECL_VISIBILITY_SPECIFIED (decl) = 1;
2299
2300 /* Go ahead and attach the attribute to the node as well. This is needed
2301 so we can determine whether we have VISIBILITY_DEFAULT because the
2302 visibility was not specified, or because it was explicitly overridden
2303 from the containing scope. */
2304
2305 return NULL_TREE;
2306 }
2307
2308 /* Handle an "tls_model" attribute; arguments as in
2309 struct attribute_spec.handler. */
2310
2311 static tree
handle_tls_model_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)2312 handle_tls_model_attribute (tree *node, tree name, tree args,
2313 int ARG_UNUSED (flags), bool *no_add_attrs)
2314 {
2315 tree id;
2316 tree decl = *node;
2317 enum tls_model kind;
2318
2319 *no_add_attrs = true;
2320
2321 if (!VAR_P (decl) || !DECL_THREAD_LOCAL_P (decl))
2322 {
2323 warning (OPT_Wattributes, "%qE attribute ignored", name);
2324 return NULL_TREE;
2325 }
2326
2327 kind = DECL_TLS_MODEL (decl);
2328 id = TREE_VALUE (args);
2329 if (TREE_CODE (id) != STRING_CST)
2330 {
2331 error ("tls_model argument not a string");
2332 return NULL_TREE;
2333 }
2334
2335 if (!strcmp (TREE_STRING_POINTER (id), "local-exec"))
2336 kind = TLS_MODEL_LOCAL_EXEC;
2337 else if (!strcmp (TREE_STRING_POINTER (id), "initial-exec"))
2338 kind = TLS_MODEL_INITIAL_EXEC;
2339 else if (!strcmp (TREE_STRING_POINTER (id), "local-dynamic"))
2340 kind = optimize ? TLS_MODEL_LOCAL_DYNAMIC : TLS_MODEL_GLOBAL_DYNAMIC;
2341 else if (!strcmp (TREE_STRING_POINTER (id), "global-dynamic"))
2342 kind = TLS_MODEL_GLOBAL_DYNAMIC;
2343 else
2344 error ("tls_model argument must be one of \"local-exec\", \"initial-exec\", \"local-dynamic\" or \"global-dynamic\"");
2345
2346 set_decl_tls_model (decl, kind);
2347 return NULL_TREE;
2348 }
2349
2350 /* Handle a "no_instrument_function" attribute; arguments as in
2351 struct attribute_spec.handler. */
2352
2353 static tree
handle_no_instrument_function_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)2354 handle_no_instrument_function_attribute (tree *node, tree name,
2355 tree ARG_UNUSED (args),
2356 int ARG_UNUSED (flags),
2357 bool *no_add_attrs)
2358 {
2359 tree decl = *node;
2360
2361 if (TREE_CODE (decl) != FUNCTION_DECL)
2362 {
2363 error_at (DECL_SOURCE_LOCATION (decl),
2364 "%qE attribute applies only to functions", name);
2365 *no_add_attrs = true;
2366 }
2367 else
2368 DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
2369
2370 return NULL_TREE;
2371 }
2372
2373 /* Handle a "no_profile_instrument_function" attribute; arguments as in
2374 struct attribute_spec.handler. */
2375
2376 static tree
handle_no_profile_instrument_function_attribute(tree * node,tree name,tree,int,bool * no_add_attrs)2377 handle_no_profile_instrument_function_attribute (tree *node, tree name, tree,
2378 int, bool *no_add_attrs)
2379 {
2380 if (TREE_CODE (*node) != FUNCTION_DECL)
2381 {
2382 warning (OPT_Wattributes, "%qE attribute ignored", name);
2383 *no_add_attrs = true;
2384 }
2385
2386 return NULL_TREE;
2387 }
2388
2389 /* Handle a "malloc" attribute; arguments as in
2390 struct attribute_spec.handler. */
2391
2392 static tree
handle_malloc_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)2393 handle_malloc_attribute (tree *node, tree name, tree ARG_UNUSED (args),
2394 int ARG_UNUSED (flags), bool *no_add_attrs)
2395 {
2396 if (TREE_CODE (*node) == FUNCTION_DECL
2397 && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*node))))
2398 DECL_IS_MALLOC (*node) = 1;
2399 else
2400 {
2401 warning (OPT_Wattributes, "%qE attribute ignored", name);
2402 *no_add_attrs = true;
2403 }
2404
2405 return NULL_TREE;
2406 }
2407
2408 /* Handle a "alloc_size" attribute; arguments as in
2409 struct attribute_spec.handler. */
2410
2411 static tree
handle_alloc_size_attribute(tree * node,tree ARG_UNUSED (name),tree args,int ARG_UNUSED (flags),bool * no_add_attrs)2412 handle_alloc_size_attribute (tree *node, tree ARG_UNUSED (name), tree args,
2413 int ARG_UNUSED (flags), bool *no_add_attrs)
2414 {
2415 unsigned arg_count = type_num_arguments (*node);
2416 for (; args; args = TREE_CHAIN (args))
2417 {
2418 tree position = TREE_VALUE (args);
2419 if (position && TREE_CODE (position) != IDENTIFIER_NODE
2420 && TREE_CODE (position) != FUNCTION_DECL)
2421 position = default_conversion (position);
2422
2423 if (!tree_fits_uhwi_p (position)
2424 || !arg_count
2425 || !IN_RANGE (tree_to_uhwi (position), 1, arg_count))
2426 {
2427 warning (OPT_Wattributes,
2428 "alloc_size parameter outside range");
2429 *no_add_attrs = true;
2430 return NULL_TREE;
2431 }
2432 }
2433 return NULL_TREE;
2434 }
2435
2436 /* Handle a "alloc_align" attribute; arguments as in
2437 struct attribute_spec.handler. */
2438
2439 static tree
handle_alloc_align_attribute(tree * node,tree,tree args,int,bool * no_add_attrs)2440 handle_alloc_align_attribute (tree *node, tree, tree args, int,
2441 bool *no_add_attrs)
2442 {
2443 unsigned arg_count = type_num_arguments (*node);
2444 tree position = TREE_VALUE (args);
2445 if (position && TREE_CODE (position) != IDENTIFIER_NODE
2446 && TREE_CODE (position) != FUNCTION_DECL)
2447 position = default_conversion (position);
2448
2449 if (!tree_fits_uhwi_p (position)
2450 || !arg_count
2451 || !IN_RANGE (tree_to_uhwi (position), 1, arg_count))
2452 {
2453 warning (OPT_Wattributes,
2454 "alloc_align parameter outside range");
2455 *no_add_attrs = true;
2456 return NULL_TREE;
2457 }
2458 return NULL_TREE;
2459 }
2460
2461 /* Handle a "assume_aligned" attribute; arguments as in
2462 struct attribute_spec.handler. */
2463
2464 static tree
handle_assume_aligned_attribute(tree *,tree,tree args,int,bool * no_add_attrs)2465 handle_assume_aligned_attribute (tree *, tree, tree args, int,
2466 bool *no_add_attrs)
2467 {
2468 for (; args; args = TREE_CHAIN (args))
2469 {
2470 tree position = TREE_VALUE (args);
2471 if (position && TREE_CODE (position) != IDENTIFIER_NODE
2472 && TREE_CODE (position) != FUNCTION_DECL)
2473 position = default_conversion (position);
2474
2475 if (TREE_CODE (position) != INTEGER_CST)
2476 {
2477 warning (OPT_Wattributes,
2478 "assume_aligned parameter not integer constant");
2479 *no_add_attrs = true;
2480 return NULL_TREE;
2481 }
2482 }
2483 return NULL_TREE;
2484 }
2485
2486 /* Handle a "fn spec" attribute; arguments as in
2487 struct attribute_spec.handler. */
2488
2489 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)2490 handle_fnspec_attribute (tree *node ATTRIBUTE_UNUSED, tree ARG_UNUSED (name),
2491 tree args, int ARG_UNUSED (flags),
2492 bool *no_add_attrs ATTRIBUTE_UNUSED)
2493 {
2494 gcc_assert (args
2495 && TREE_CODE (TREE_VALUE (args)) == STRING_CST
2496 && !TREE_CHAIN (args));
2497 return NULL_TREE;
2498 }
2499
2500 /* Handle a "bnd_variable_size" attribute; arguments as in
2501 struct attribute_spec.handler. */
2502
2503 static tree
handle_bnd_variable_size_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)2504 handle_bnd_variable_size_attribute (tree *node, tree name, tree ARG_UNUSED (args),
2505 int ARG_UNUSED (flags), bool *no_add_attrs)
2506 {
2507 if (TREE_CODE (*node) != FIELD_DECL)
2508 {
2509 warning (OPT_Wattributes, "%qE attribute ignored", name);
2510 *no_add_attrs = true;
2511 }
2512
2513 return NULL_TREE;
2514 }
2515
2516 /* Handle a "bnd_legacy" attribute; arguments as in
2517 struct attribute_spec.handler. */
2518
2519 static tree
handle_bnd_legacy(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)2520 handle_bnd_legacy (tree *node, tree name, tree ARG_UNUSED (args),
2521 int ARG_UNUSED (flags), bool *no_add_attrs)
2522 {
2523 if (TREE_CODE (*node) != FUNCTION_DECL)
2524 {
2525 warning (OPT_Wattributes, "%qE attribute ignored", name);
2526 *no_add_attrs = true;
2527 }
2528
2529 return NULL_TREE;
2530 }
2531
2532 /* Handle a "bnd_instrument" attribute; arguments as in
2533 struct attribute_spec.handler. */
2534
2535 static tree
handle_bnd_instrument(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)2536 handle_bnd_instrument (tree *node, tree name, tree ARG_UNUSED (args),
2537 int ARG_UNUSED (flags), bool *no_add_attrs)
2538 {
2539 if (TREE_CODE (*node) != FUNCTION_DECL)
2540 {
2541 warning (OPT_Wattributes, "%qE attribute ignored", name);
2542 *no_add_attrs = true;
2543 }
2544
2545 return NULL_TREE;
2546 }
2547
2548 /* Handle a "warn_unused" attribute; arguments as in
2549 struct attribute_spec.handler. */
2550
2551 static tree
handle_warn_unused_attribute(tree * node,tree name,tree args ATTRIBUTE_UNUSED,int flags ATTRIBUTE_UNUSED,bool * no_add_attrs)2552 handle_warn_unused_attribute (tree *node, tree name,
2553 tree args ATTRIBUTE_UNUSED,
2554 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
2555 {
2556 if (TYPE_P (*node))
2557 /* Do nothing else, just set the attribute. We'll get at
2558 it later with lookup_attribute. */
2559 ;
2560 else
2561 {
2562 warning (OPT_Wattributes, "%qE attribute ignored", name);
2563 *no_add_attrs = true;
2564 }
2565
2566 return NULL_TREE;
2567 }
2568
2569 /* Handle an "omp declare simd" attribute; arguments as in
2570 struct attribute_spec.handler. */
2571
2572 static tree
handle_omp_declare_simd_attribute(tree *,tree,tree,int,bool *)2573 handle_omp_declare_simd_attribute (tree *, tree, tree, int, bool *)
2574 {
2575 return NULL_TREE;
2576 }
2577
2578 /* Handle a "simd" attribute. */
2579
2580 static tree
handle_simd_attribute(tree * node,tree name,tree args,int,bool * no_add_attrs)2581 handle_simd_attribute (tree *node, tree name, tree args, int, bool *no_add_attrs)
2582 {
2583 if (TREE_CODE (*node) == FUNCTION_DECL)
2584 {
2585 tree t = get_identifier ("omp declare simd");
2586 tree attr = NULL_TREE;
2587 if (args)
2588 {
2589 tree id = TREE_VALUE (args);
2590
2591 if (TREE_CODE (id) != STRING_CST)
2592 {
2593 error ("attribute %qE argument not a string", name);
2594 *no_add_attrs = true;
2595 return NULL_TREE;
2596 }
2597
2598 if (strcmp (TREE_STRING_POINTER (id), "notinbranch") == 0)
2599 attr = build_omp_clause (DECL_SOURCE_LOCATION (*node),
2600 OMP_CLAUSE_NOTINBRANCH);
2601 else if (strcmp (TREE_STRING_POINTER (id), "inbranch") == 0)
2602 attr = build_omp_clause (DECL_SOURCE_LOCATION (*node),
2603 OMP_CLAUSE_INBRANCH);
2604 else
2605 {
2606 error ("only %<inbranch%> and %<notinbranch%> flags are "
2607 "allowed for %<__simd__%> attribute");
2608 *no_add_attrs = true;
2609 return NULL_TREE;
2610 }
2611 }
2612
2613 DECL_ATTRIBUTES (*node)
2614 = tree_cons (t, build_tree_list (NULL_TREE, attr),
2615 DECL_ATTRIBUTES (*node));
2616 }
2617 else
2618 {
2619 warning (OPT_Wattributes, "%qE attribute ignored", name);
2620 *no_add_attrs = true;
2621 }
2622
2623 return NULL_TREE;
2624 }
2625
2626 /* Handle an "omp declare target" attribute; arguments as in
2627 struct attribute_spec.handler. */
2628
2629 static tree
handle_omp_declare_target_attribute(tree *,tree,tree,int,bool *)2630 handle_omp_declare_target_attribute (tree *, tree, tree, int, bool *)
2631 {
2632 return NULL_TREE;
2633 }
2634
2635 /* Handle a "returns_twice" attribute; arguments as in
2636 struct attribute_spec.handler. */
2637
2638 static tree
handle_returns_twice_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)2639 handle_returns_twice_attribute (tree *node, tree name, tree ARG_UNUSED (args),
2640 int ARG_UNUSED (flags), bool *no_add_attrs)
2641 {
2642 if (TREE_CODE (*node) == FUNCTION_DECL)
2643 DECL_IS_RETURNS_TWICE (*node) = 1;
2644 else
2645 {
2646 warning (OPT_Wattributes, "%qE attribute ignored", name);
2647 *no_add_attrs = true;
2648 }
2649
2650 return NULL_TREE;
2651 }
2652
2653 /* Handle a "no_limit_stack" attribute; arguments as in
2654 struct attribute_spec.handler. */
2655
2656 static tree
handle_no_limit_stack_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)2657 handle_no_limit_stack_attribute (tree *node, tree name,
2658 tree ARG_UNUSED (args),
2659 int ARG_UNUSED (flags),
2660 bool *no_add_attrs)
2661 {
2662 tree decl = *node;
2663
2664 if (TREE_CODE (decl) != FUNCTION_DECL)
2665 {
2666 error_at (DECL_SOURCE_LOCATION (decl),
2667 "%qE attribute applies only to functions", name);
2668 *no_add_attrs = true;
2669 }
2670 else if (DECL_INITIAL (decl))
2671 {
2672 error_at (DECL_SOURCE_LOCATION (decl),
2673 "can%'t set %qE attribute after definition", name);
2674 *no_add_attrs = true;
2675 }
2676 else
2677 DECL_NO_LIMIT_STACK (decl) = 1;
2678
2679 return NULL_TREE;
2680 }
2681
2682 /* Handle a "pure" attribute; arguments as in
2683 struct attribute_spec.handler. */
2684
2685 static tree
handle_pure_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)2686 handle_pure_attribute (tree *node, tree name, tree ARG_UNUSED (args),
2687 int ARG_UNUSED (flags), bool *no_add_attrs)
2688 {
2689 if (TREE_CODE (*node) == FUNCTION_DECL)
2690 {
2691 tree type = TREE_TYPE (*node);
2692 if (VOID_TYPE_P (TREE_TYPE (type)))
2693 warning (OPT_Wattributes, "%qE attribute on function "
2694 "returning %<void%>", name);
2695
2696 DECL_PURE_P (*node) = 1;
2697 /* ??? TODO: Support types. */
2698 }
2699 else
2700 {
2701 warning (OPT_Wattributes, "%qE attribute ignored", name);
2702 *no_add_attrs = true;
2703 }
2704
2705 return NULL_TREE;
2706 }
2707
2708 /* Digest an attribute list destined for a transactional memory statement.
2709 ALLOWED is the set of attributes that are allowed for this statement;
2710 return the attribute we parsed. Multiple attributes are never allowed. */
2711
2712 int
parse_tm_stmt_attr(tree attrs,int allowed)2713 parse_tm_stmt_attr (tree attrs, int allowed)
2714 {
2715 tree a_seen = NULL;
2716 int m_seen = 0;
2717
2718 for ( ; attrs ; attrs = TREE_CHAIN (attrs))
2719 {
2720 tree a = TREE_PURPOSE (attrs);
2721 int m = 0;
2722
2723 if (is_attribute_p ("outer", a))
2724 m = TM_STMT_ATTR_OUTER;
2725
2726 if ((m & allowed) == 0)
2727 {
2728 warning (OPT_Wattributes, "%qE attribute directive ignored", a);
2729 continue;
2730 }
2731
2732 if (m_seen == 0)
2733 {
2734 a_seen = a;
2735 m_seen = m;
2736 }
2737 else if (m_seen == m)
2738 warning (OPT_Wattributes, "%qE attribute duplicated", a);
2739 else
2740 warning (OPT_Wattributes, "%qE attribute follows %qE", a, a_seen);
2741 }
2742
2743 return m_seen;
2744 }
2745
2746 /* Transform a TM attribute name into a maskable integer and back.
2747 Note that NULL (i.e. no attribute) is mapped to UNKNOWN, corresponding
2748 to how the lack of an attribute is treated. */
2749
2750 int
tm_attr_to_mask(tree attr)2751 tm_attr_to_mask (tree attr)
2752 {
2753 if (attr == NULL)
2754 return 0;
2755 if (is_attribute_p ("transaction_safe", attr))
2756 return TM_ATTR_SAFE;
2757 if (is_attribute_p ("transaction_callable", attr))
2758 return TM_ATTR_CALLABLE;
2759 if (is_attribute_p ("transaction_pure", attr))
2760 return TM_ATTR_PURE;
2761 if (is_attribute_p ("transaction_unsafe", attr))
2762 return TM_ATTR_IRREVOCABLE;
2763 if (is_attribute_p ("transaction_may_cancel_outer", attr))
2764 return TM_ATTR_MAY_CANCEL_OUTER;
2765 return 0;
2766 }
2767
2768 tree
tm_mask_to_attr(int mask)2769 tm_mask_to_attr (int mask)
2770 {
2771 const char *str;
2772 switch (mask)
2773 {
2774 case TM_ATTR_SAFE:
2775 str = "transaction_safe";
2776 break;
2777 case TM_ATTR_CALLABLE:
2778 str = "transaction_callable";
2779 break;
2780 case TM_ATTR_PURE:
2781 str = "transaction_pure";
2782 break;
2783 case TM_ATTR_IRREVOCABLE:
2784 str = "transaction_unsafe";
2785 break;
2786 case TM_ATTR_MAY_CANCEL_OUTER:
2787 str = "transaction_may_cancel_outer";
2788 break;
2789 default:
2790 gcc_unreachable ();
2791 }
2792 return get_identifier (str);
2793 }
2794
2795 /* Return the first TM attribute seen in LIST. */
2796
2797 tree
find_tm_attribute(tree list)2798 find_tm_attribute (tree list)
2799 {
2800 for (; list ; list = TREE_CHAIN (list))
2801 {
2802 tree name = TREE_PURPOSE (list);
2803 if (tm_attr_to_mask (name) != 0)
2804 return name;
2805 }
2806 return NULL_TREE;
2807 }
2808
2809 /* Handle the TM attributes; arguments as in struct attribute_spec.handler.
2810 Here we accept only function types, and verify that none of the other
2811 function TM attributes are also applied. */
2812 /* ??? We need to accept class types for C++, but not C. This greatly
2813 complicates this function, since we can no longer rely on the extra
2814 processing given by function_type_required. */
2815
2816 static tree
handle_tm_attribute(tree * node,tree name,tree args,int flags,bool * no_add_attrs)2817 handle_tm_attribute (tree *node, tree name, tree args,
2818 int flags, bool *no_add_attrs)
2819 {
2820 /* Only one path adds the attribute; others don't. */
2821 *no_add_attrs = true;
2822
2823 switch (TREE_CODE (*node))
2824 {
2825 case RECORD_TYPE:
2826 case UNION_TYPE:
2827 /* Only tm_callable and tm_safe apply to classes. */
2828 if (tm_attr_to_mask (name) & ~(TM_ATTR_SAFE | TM_ATTR_CALLABLE))
2829 goto ignored;
2830 /* FALLTHRU */
2831
2832 case FUNCTION_TYPE:
2833 case METHOD_TYPE:
2834 {
2835 tree old_name = find_tm_attribute (TYPE_ATTRIBUTES (*node));
2836 if (old_name == name)
2837 ;
2838 else if (old_name != NULL_TREE)
2839 error ("type was previously declared %qE", old_name);
2840 else
2841 *no_add_attrs = false;
2842 }
2843 break;
2844
2845 case FUNCTION_DECL:
2846 {
2847 /* transaction_safe_dynamic goes on the FUNCTION_DECL, but we also
2848 want to set transaction_safe on the type. */
2849 gcc_assert (is_attribute_p ("transaction_safe_dynamic", name));
2850 if (!TYPE_P (DECL_CONTEXT (*node)))
2851 error_at (DECL_SOURCE_LOCATION (*node),
2852 "%<transaction_safe_dynamic%> may only be specified for "
2853 "a virtual function");
2854 *no_add_attrs = false;
2855 decl_attributes (&TREE_TYPE (*node),
2856 build_tree_list (get_identifier ("transaction_safe"),
2857 NULL_TREE),
2858 0);
2859 break;
2860 }
2861
2862 case POINTER_TYPE:
2863 {
2864 enum tree_code subcode = TREE_CODE (TREE_TYPE (*node));
2865 if (subcode == FUNCTION_TYPE || subcode == METHOD_TYPE)
2866 {
2867 tree fn_tmp = TREE_TYPE (*node);
2868 decl_attributes (&fn_tmp, tree_cons (name, args, NULL), 0);
2869 *node = build_pointer_type (fn_tmp);
2870 break;
2871 }
2872 }
2873 /* FALLTHRU */
2874
2875 default:
2876 /* If a function is next, pass it on to be tried next. */
2877 if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
2878 return tree_cons (name, args, NULL);
2879
2880 ignored:
2881 warning (OPT_Wattributes, "%qE attribute ignored", name);
2882 break;
2883 }
2884
2885 return NULL_TREE;
2886 }
2887
2888 /* Handle the TM_WRAP attribute; arguments as in
2889 struct attribute_spec.handler. */
2890
2891 static tree
handle_tm_wrap_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)2892 handle_tm_wrap_attribute (tree *node, tree name, tree args,
2893 int ARG_UNUSED (flags), bool *no_add_attrs)
2894 {
2895 tree decl = *node;
2896
2897 /* We don't need the attribute even on success, since we
2898 record the entry in an external table. */
2899 *no_add_attrs = true;
2900
2901 if (TREE_CODE (decl) != FUNCTION_DECL)
2902 warning (OPT_Wattributes, "%qE attribute ignored", name);
2903 else
2904 {
2905 tree wrap_decl = TREE_VALUE (args);
2906 if (error_operand_p (wrap_decl))
2907 ;
2908 else if (TREE_CODE (wrap_decl) != IDENTIFIER_NODE
2909 && !VAR_OR_FUNCTION_DECL_P (wrap_decl))
2910 error ("%qE argument not an identifier", name);
2911 else
2912 {
2913 if (TREE_CODE (wrap_decl) == IDENTIFIER_NODE)
2914 wrap_decl = lookup_name (wrap_decl);
2915 if (wrap_decl && TREE_CODE (wrap_decl) == FUNCTION_DECL)
2916 {
2917 if (lang_hooks.types_compatible_p (TREE_TYPE (decl),
2918 TREE_TYPE (wrap_decl)))
2919 record_tm_replacement (wrap_decl, decl);
2920 else
2921 error ("%qD is not compatible with %qD", wrap_decl, decl);
2922 }
2923 else
2924 error ("%qE argument is not a function", name);
2925 }
2926 }
2927
2928 return NULL_TREE;
2929 }
2930
2931 /* Ignore the given attribute. Used when this attribute may be usefully
2932 overridden by the target, but is not used generically. */
2933
2934 static tree
ignore_attribute(tree * ARG_UNUSED (node),tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)2935 ignore_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name),
2936 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
2937 bool *no_add_attrs)
2938 {
2939 *no_add_attrs = true;
2940 return NULL_TREE;
2941 }
2942
2943 /* Handle a "no vops" attribute; arguments as in
2944 struct attribute_spec.handler. */
2945
2946 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))2947 handle_novops_attribute (tree *node, tree ARG_UNUSED (name),
2948 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
2949 bool *ARG_UNUSED (no_add_attrs))
2950 {
2951 gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
2952 DECL_IS_NOVOPS (*node) = 1;
2953 return NULL_TREE;
2954 }
2955
2956 /* Handle a "deprecated" attribute; arguments as in
2957 struct attribute_spec.handler. */
2958
2959 static tree
handle_deprecated_attribute(tree * node,tree name,tree args,int flags,bool * no_add_attrs)2960 handle_deprecated_attribute (tree *node, tree name,
2961 tree args, int flags,
2962 bool *no_add_attrs)
2963 {
2964 tree type = NULL_TREE;
2965 int warn = 0;
2966 tree what = NULL_TREE;
2967
2968 if (!args)
2969 *no_add_attrs = true;
2970 else if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
2971 {
2972 error ("deprecated message is not a string");
2973 *no_add_attrs = true;
2974 }
2975
2976 if (DECL_P (*node))
2977 {
2978 tree decl = *node;
2979 type = TREE_TYPE (decl);
2980
2981 if (TREE_CODE (decl) == TYPE_DECL
2982 || TREE_CODE (decl) == PARM_DECL
2983 || VAR_OR_FUNCTION_DECL_P (decl)
2984 || TREE_CODE (decl) == FIELD_DECL
2985 || TREE_CODE (decl) == CONST_DECL
2986 || objc_method_decl (TREE_CODE (decl)))
2987 TREE_DEPRECATED (decl) = 1;
2988 else
2989 warn = 1;
2990 }
2991 else if (TYPE_P (*node))
2992 {
2993 if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
2994 *node = build_variant_type_copy (*node);
2995 TREE_DEPRECATED (*node) = 1;
2996 type = *node;
2997 }
2998 else
2999 warn = 1;
3000
3001 if (warn)
3002 {
3003 *no_add_attrs = true;
3004 if (type && TYPE_NAME (type))
3005 {
3006 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
3007 what = TYPE_NAME (*node);
3008 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
3009 && DECL_NAME (TYPE_NAME (type)))
3010 what = DECL_NAME (TYPE_NAME (type));
3011 }
3012 if (what)
3013 warning (OPT_Wattributes, "%qE attribute ignored for %qE", name, what);
3014 else
3015 warning (OPT_Wattributes, "%qE attribute ignored", name);
3016 }
3017
3018 return NULL_TREE;
3019 }
3020
3021 /* Handle a "vector_size" attribute; arguments as in
3022 struct attribute_spec.handler. */
3023
3024 static tree
handle_vector_size_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)3025 handle_vector_size_attribute (tree *node, tree name, tree args,
3026 int ARG_UNUSED (flags),
3027 bool *no_add_attrs)
3028 {
3029 unsigned HOST_WIDE_INT vecsize, nunits;
3030 machine_mode orig_mode;
3031 tree type = *node, new_type, size;
3032
3033 *no_add_attrs = true;
3034
3035 size = TREE_VALUE (args);
3036 if (size && TREE_CODE (size) != IDENTIFIER_NODE
3037 && TREE_CODE (size) != FUNCTION_DECL)
3038 size = default_conversion (size);
3039
3040 if (!tree_fits_uhwi_p (size))
3041 {
3042 warning (OPT_Wattributes, "%qE attribute ignored", name);
3043 return NULL_TREE;
3044 }
3045
3046 /* Get the vector size (in bytes). */
3047 vecsize = tree_to_uhwi (size);
3048
3049 /* We need to provide for vector pointers, vector arrays, and
3050 functions returning vectors. For example:
3051
3052 __attribute__((vector_size(16))) short *foo;
3053
3054 In this case, the mode is SI, but the type being modified is
3055 HI, so we need to look further. */
3056
3057 while (POINTER_TYPE_P (type)
3058 || TREE_CODE (type) == FUNCTION_TYPE
3059 || TREE_CODE (type) == METHOD_TYPE
3060 || TREE_CODE (type) == ARRAY_TYPE
3061 || TREE_CODE (type) == OFFSET_TYPE)
3062 type = TREE_TYPE (type);
3063
3064 /* Get the mode of the type being modified. */
3065 orig_mode = TYPE_MODE (type);
3066
3067 if ((!INTEGRAL_TYPE_P (type)
3068 && !SCALAR_FLOAT_TYPE_P (type)
3069 && !FIXED_POINT_TYPE_P (type))
3070 || (!SCALAR_FLOAT_MODE_P (orig_mode)
3071 && GET_MODE_CLASS (orig_mode) != MODE_INT
3072 && !ALL_SCALAR_FIXED_POINT_MODE_P (orig_mode))
3073 || !tree_fits_uhwi_p (TYPE_SIZE_UNIT (type))
3074 || TREE_CODE (type) == BOOLEAN_TYPE)
3075 {
3076 error ("invalid vector type for attribute %qE", name);
3077 return NULL_TREE;
3078 }
3079
3080 if (vecsize % tree_to_uhwi (TYPE_SIZE_UNIT (type)))
3081 {
3082 error ("vector size not an integral multiple of component size");
3083 return NULL;
3084 }
3085
3086 if (vecsize == 0)
3087 {
3088 error ("zero vector size");
3089 return NULL;
3090 }
3091
3092 /* Calculate how many units fit in the vector. */
3093 nunits = vecsize / tree_to_uhwi (TYPE_SIZE_UNIT (type));
3094 if (nunits & (nunits - 1))
3095 {
3096 error ("number of components of the vector not a power of two");
3097 return NULL_TREE;
3098 }
3099
3100 new_type = build_vector_type (type, nunits);
3101
3102 /* Build back pointers if needed. */
3103 *node = lang_hooks.types.reconstruct_complex_type (*node, new_type);
3104
3105 return NULL_TREE;
3106 }
3107
3108 /* Handle the "nonnull" attribute. */
3109
3110 static tree
handle_nonnull_attribute(tree * node,tree ARG_UNUSED (name),tree args,int ARG_UNUSED (flags),bool * no_add_attrs)3111 handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name),
3112 tree args, int ARG_UNUSED (flags),
3113 bool *no_add_attrs)
3114 {
3115 tree type = *node;
3116 unsigned HOST_WIDE_INT attr_arg_num;
3117
3118 /* If no arguments are specified, all pointer arguments should be
3119 non-null. Verify a full prototype is given so that the arguments
3120 will have the correct types when we actually check them later.
3121 Avoid diagnosing type-generic built-ins since those have no
3122 prototype. */
3123 if (!args)
3124 {
3125 if (!prototype_p (type)
3126 && (!TYPE_ATTRIBUTES (type)
3127 || !lookup_attribute ("type generic", TYPE_ATTRIBUTES (type))))
3128 {
3129 error ("nonnull attribute without arguments on a non-prototype");
3130 *no_add_attrs = true;
3131 }
3132 return NULL_TREE;
3133 }
3134
3135 /* Argument list specified. Verify that each argument number references
3136 a pointer argument. */
3137 for (attr_arg_num = 1; args; attr_arg_num++, args = TREE_CHAIN (args))
3138 {
3139 unsigned HOST_WIDE_INT arg_num = 0, ck_num;
3140
3141 tree arg = TREE_VALUE (args);
3142 if (arg && TREE_CODE (arg) != IDENTIFIER_NODE
3143 && TREE_CODE (arg) != FUNCTION_DECL)
3144 TREE_VALUE (args) = arg = default_conversion (arg);
3145
3146 if (!get_nonnull_operand (arg, &arg_num))
3147 {
3148 error ("nonnull argument has invalid operand number (argument %lu)",
3149 (unsigned long) attr_arg_num);
3150 *no_add_attrs = true;
3151 return NULL_TREE;
3152 }
3153
3154 if (prototype_p (type))
3155 {
3156 function_args_iterator iter;
3157 tree argument;
3158
3159 function_args_iter_init (&iter, type);
3160 for (ck_num = 1; ; ck_num++, function_args_iter_next (&iter))
3161 {
3162 argument = function_args_iter_cond (&iter);
3163 if (argument == NULL_TREE || ck_num == arg_num)
3164 break;
3165 }
3166
3167 if (!argument
3168 || TREE_CODE (argument) == VOID_TYPE)
3169 {
3170 error ("nonnull argument with out-of-range operand number "
3171 "(argument %lu, operand %lu)",
3172 (unsigned long) attr_arg_num, (unsigned long) arg_num);
3173 *no_add_attrs = true;
3174 return NULL_TREE;
3175 }
3176
3177 if (TREE_CODE (argument) != POINTER_TYPE)
3178 {
3179 error ("nonnull argument references non-pointer operand "
3180 "(argument %lu, operand %lu)",
3181 (unsigned long) attr_arg_num, (unsigned long) arg_num);
3182 *no_add_attrs = true;
3183 return NULL_TREE;
3184 }
3185 }
3186 }
3187
3188 return NULL_TREE;
3189 }
3190
3191 /* Handle the "nonstring" variable attribute. */
3192
3193 static tree
handle_nonstring_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)3194 handle_nonstring_attribute (tree *node, tree name, tree ARG_UNUSED (args),
3195 int ARG_UNUSED (flags), bool *no_add_attrs)
3196 {
3197 gcc_assert (!args);
3198 tree_code code = TREE_CODE (*node);
3199
3200 if (VAR_P (*node)
3201 || code == FIELD_DECL
3202 || code == PARM_DECL)
3203 {
3204 tree type = TREE_TYPE (*node);
3205
3206 if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
3207 {
3208 /* Accept the attribute on arrays and pointers to all three
3209 narrow character types. */
3210 tree eltype = TREE_TYPE (type);
3211 eltype = TYPE_MAIN_VARIANT (eltype);
3212 if (eltype == char_type_node
3213 || eltype == signed_char_type_node
3214 || eltype == unsigned_char_type_node)
3215 return NULL_TREE;
3216 }
3217
3218 warning (OPT_Wattributes,
3219 "%qE attribute ignored on objects of type %qT",
3220 name, type);
3221 *no_add_attrs = true;
3222 return NULL_TREE;
3223 }
3224
3225 if (code == FUNCTION_DECL)
3226 warning (OPT_Wattributes,
3227 "%qE attribute does not apply to functions", name);
3228 else if (code == TYPE_DECL)
3229 warning (OPT_Wattributes,
3230 "%qE attribute does not apply to types", name);
3231 else
3232 warning (OPT_Wattributes, "%qE attribute ignored", name);
3233
3234 *no_add_attrs = true;
3235 return NULL_TREE;
3236 }
3237
3238 /* Handle a "nothrow" attribute; arguments as in
3239 struct attribute_spec.handler. */
3240
3241 static tree
handle_nothrow_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)3242 handle_nothrow_attribute (tree *node, tree name, tree ARG_UNUSED (args),
3243 int ARG_UNUSED (flags), bool *no_add_attrs)
3244 {
3245 if (TREE_CODE (*node) == FUNCTION_DECL)
3246 TREE_NOTHROW (*node) = 1;
3247 /* ??? TODO: Support types. */
3248 else
3249 {
3250 warning (OPT_Wattributes, "%qE attribute ignored", name);
3251 *no_add_attrs = true;
3252 }
3253
3254 return NULL_TREE;
3255 }
3256
3257 /* Handle a "cleanup" attribute; arguments as in
3258 struct attribute_spec.handler. */
3259
3260 static tree
handle_cleanup_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)3261 handle_cleanup_attribute (tree *node, tree name, tree args,
3262 int ARG_UNUSED (flags), bool *no_add_attrs)
3263 {
3264 tree decl = *node;
3265 tree cleanup_id, cleanup_decl;
3266
3267 /* ??? Could perhaps support cleanups on TREE_STATIC, much like we do
3268 for global destructors in C++. This requires infrastructure that
3269 we don't have generically at the moment. It's also not a feature
3270 we'd be missing too much, since we do have attribute constructor. */
3271 if (!VAR_P (decl) || TREE_STATIC (decl))
3272 {
3273 warning (OPT_Wattributes, "%qE attribute ignored", name);
3274 *no_add_attrs = true;
3275 return NULL_TREE;
3276 }
3277
3278 /* Verify that the argument is a function in scope. */
3279 /* ??? We could support pointers to functions here as well, if
3280 that was considered desirable. */
3281 cleanup_id = TREE_VALUE (args);
3282 if (TREE_CODE (cleanup_id) != IDENTIFIER_NODE)
3283 {
3284 error ("cleanup argument not an identifier");
3285 *no_add_attrs = true;
3286 return NULL_TREE;
3287 }
3288 cleanup_decl = lookup_name (cleanup_id);
3289 if (!cleanup_decl || TREE_CODE (cleanup_decl) != FUNCTION_DECL)
3290 {
3291 error ("cleanup argument not a function");
3292 *no_add_attrs = true;
3293 return NULL_TREE;
3294 }
3295
3296 /* That the function has proper type is checked with the
3297 eventual call to build_function_call. */
3298
3299 return NULL_TREE;
3300 }
3301
3302 /* Handle a "warn_unused_result" attribute. No special handling. */
3303
3304 static tree
handle_warn_unused_result_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)3305 handle_warn_unused_result_attribute (tree *node, tree name,
3306 tree ARG_UNUSED (args),
3307 int ARG_UNUSED (flags), bool *no_add_attrs)
3308 {
3309 /* Ignore the attribute for functions not returning any value. */
3310 if (VOID_TYPE_P (TREE_TYPE (*node)))
3311 {
3312 warning (OPT_Wattributes, "%qE attribute ignored", name);
3313 *no_add_attrs = true;
3314 }
3315
3316 return NULL_TREE;
3317 }
3318
3319 /* Handle a "sentinel" attribute. */
3320
3321 static tree
handle_sentinel_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)3322 handle_sentinel_attribute (tree *node, tree name, tree args,
3323 int ARG_UNUSED (flags), bool *no_add_attrs)
3324 {
3325 if (!prototype_p (*node))
3326 {
3327 warning (OPT_Wattributes,
3328 "%qE attribute requires prototypes with named arguments", name);
3329 *no_add_attrs = true;
3330 }
3331 else
3332 {
3333 if (!stdarg_p (*node))
3334 {
3335 warning (OPT_Wattributes,
3336 "%qE attribute only applies to variadic functions", name);
3337 *no_add_attrs = true;
3338 }
3339 }
3340
3341 if (args)
3342 {
3343 tree position = TREE_VALUE (args);
3344 if (position && TREE_CODE (position) != IDENTIFIER_NODE
3345 && TREE_CODE (position) != FUNCTION_DECL)
3346 position = default_conversion (position);
3347
3348 if (TREE_CODE (position) != INTEGER_CST
3349 || !INTEGRAL_TYPE_P (TREE_TYPE (position)))
3350 {
3351 warning (OPT_Wattributes,
3352 "requested position is not an integer constant");
3353 *no_add_attrs = true;
3354 }
3355 else
3356 {
3357 if (tree_int_cst_lt (position, integer_zero_node))
3358 {
3359 warning (OPT_Wattributes,
3360 "requested position is less than zero");
3361 *no_add_attrs = true;
3362 }
3363 }
3364 }
3365
3366 return NULL_TREE;
3367 }
3368
3369 /* Handle a "type_generic" attribute. */
3370
3371 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))3372 handle_type_generic_attribute (tree *node, tree ARG_UNUSED (name),
3373 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
3374 bool * ARG_UNUSED (no_add_attrs))
3375 {
3376 /* Ensure we have a function type. */
3377 gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
3378
3379 /* Ensure we have a variadic function. */
3380 gcc_assert (!prototype_p (*node) || stdarg_p (*node));
3381
3382 return NULL_TREE;
3383 }
3384
3385 /* Handle a "target" attribute. */
3386
3387 static tree
handle_target_attribute(tree * node,tree name,tree args,int flags,bool * no_add_attrs)3388 handle_target_attribute (tree *node, tree name, tree args, int flags,
3389 bool *no_add_attrs)
3390 {
3391 /* Ensure we have a function type. */
3392 if (TREE_CODE (*node) != FUNCTION_DECL)
3393 {
3394 warning (OPT_Wattributes, "%qE attribute ignored", name);
3395 *no_add_attrs = true;
3396 }
3397 else if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (*node)))
3398 {
3399 warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
3400 "with %qs attribute", name, "target_clones");
3401 *no_add_attrs = true;
3402 }
3403 else if (! targetm.target_option.valid_attribute_p (*node, name, args,
3404 flags))
3405 *no_add_attrs = true;
3406
3407 /* Check that there's no empty string in values of the attribute. */
3408 for (tree t = args; t != NULL_TREE; t = TREE_CHAIN (t))
3409 {
3410 tree value = TREE_VALUE (t);
3411 if (TREE_CODE (value) == STRING_CST
3412 && TREE_STRING_LENGTH (value) == 1
3413 && TREE_STRING_POINTER (value)[0] == '\0')
3414 {
3415 warning (OPT_Wattributes, "empty string in attribute %<target%>");
3416 *no_add_attrs = true;
3417 }
3418 }
3419
3420 return NULL_TREE;
3421 }
3422
3423 /* Handle a "target_clones" attribute. */
3424
3425 static tree
handle_target_clones_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)3426 handle_target_clones_attribute (tree *node, tree name, tree ARG_UNUSED (args),
3427 int ARG_UNUSED (flags), bool *no_add_attrs)
3428 {
3429 /* Ensure we have a function type. */
3430 if (TREE_CODE (*node) == FUNCTION_DECL)
3431 {
3432 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (*node)))
3433 {
3434 warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
3435 "with %qs attribute", name, "always_inline");
3436 *no_add_attrs = true;
3437 }
3438 else if (lookup_attribute ("target", DECL_ATTRIBUTES (*node)))
3439 {
3440 warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
3441 "with %qs attribute", name, "target");
3442 *no_add_attrs = true;
3443 }
3444 else
3445 /* Do not inline functions with multiple clone targets. */
3446 DECL_UNINLINABLE (*node) = 1;
3447 }
3448 else
3449 {
3450 warning (OPT_Wattributes, "%qE attribute ignored", name);
3451 *no_add_attrs = true;
3452 }
3453 return NULL_TREE;
3454 }
3455
3456 /* For handling "optimize" attribute. arguments as in
3457 struct attribute_spec.handler. */
3458
3459 static tree
handle_optimize_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)3460 handle_optimize_attribute (tree *node, tree name, tree args,
3461 int ARG_UNUSED (flags), bool *no_add_attrs)
3462 {
3463 /* Ensure we have a function type. */
3464 if (TREE_CODE (*node) != FUNCTION_DECL)
3465 {
3466 warning (OPT_Wattributes, "%qE attribute ignored", name);
3467 *no_add_attrs = true;
3468 }
3469 else
3470 {
3471 struct cl_optimization cur_opts;
3472 tree old_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node);
3473
3474 /* Save current options. */
3475 cl_optimization_save (&cur_opts, &global_options);
3476
3477 /* If we previously had some optimization options, use them as the
3478 default. */
3479 if (old_opts)
3480 cl_optimization_restore (&global_options,
3481 TREE_OPTIMIZATION (old_opts));
3482
3483 /* Parse options, and update the vector. */
3484 parse_optimize_options (args, true);
3485 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node)
3486 = build_optimization_node (&global_options);
3487
3488 /* Restore current options. */
3489 cl_optimization_restore (&global_options, &cur_opts);
3490 }
3491
3492 return NULL_TREE;
3493 }
3494
3495 /* Handle a "no_split_stack" attribute. */
3496
3497 static tree
handle_no_split_stack_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)3498 handle_no_split_stack_attribute (tree *node, tree name,
3499 tree ARG_UNUSED (args),
3500 int ARG_UNUSED (flags),
3501 bool *no_add_attrs)
3502 {
3503 tree decl = *node;
3504
3505 if (TREE_CODE (decl) != FUNCTION_DECL)
3506 {
3507 error_at (DECL_SOURCE_LOCATION (decl),
3508 "%qE attribute applies only to functions", name);
3509 *no_add_attrs = true;
3510 }
3511 else if (DECL_INITIAL (decl))
3512 {
3513 error_at (DECL_SOURCE_LOCATION (decl),
3514 "can%'t set %qE attribute after definition", name);
3515 *no_add_attrs = true;
3516 }
3517
3518 return NULL_TREE;
3519 }
3520
3521 /* Handle a "returns_nonnull" attribute; arguments as in
3522 struct attribute_spec.handler. */
3523
3524 static tree
handle_returns_nonnull_attribute(tree * node,tree,tree,int,bool * no_add_attrs)3525 handle_returns_nonnull_attribute (tree *node, tree, tree, int,
3526 bool *no_add_attrs)
3527 {
3528 // Even without a prototype we still have a return type we can check.
3529 if (TREE_CODE (TREE_TYPE (*node)) != POINTER_TYPE)
3530 {
3531 error ("returns_nonnull attribute on a function not returning a pointer");
3532 *no_add_attrs = true;
3533 }
3534 return NULL_TREE;
3535 }
3536
3537 /* Handle a "designated_init" attribute; arguments as in
3538 struct attribute_spec.handler. */
3539
3540 static tree
handle_designated_init_attribute(tree * node,tree name,tree,int,bool * no_add_attrs)3541 handle_designated_init_attribute (tree *node, tree name, tree, int,
3542 bool *no_add_attrs)
3543 {
3544 if (TREE_CODE (*node) != RECORD_TYPE)
3545 {
3546 error ("%qE attribute is only valid on %<struct%> type", name);
3547 *no_add_attrs = true;
3548 }
3549 return NULL_TREE;
3550 }
3551
3552
3553 /* Handle a "fallthrough" attribute; arguments as in struct
3554 attribute_spec.handler. */
3555
3556 static tree
handle_fallthrough_attribute(tree *,tree name,tree,int,bool * no_add_attrs)3557 handle_fallthrough_attribute (tree *, tree name, tree, int,
3558 bool *no_add_attrs)
3559 {
3560 warning (OPT_Wattributes, "%qE attribute ignored", name);
3561 *no_add_attrs = true;
3562 return NULL_TREE;
3563 }
3564
3565 static tree
handle_patchable_function_entry_attribute(tree *,tree,tree,int,bool *)3566 handle_patchable_function_entry_attribute (tree *, tree, tree, int, bool *)
3567 {
3568 /* Nothing to be done here. */
3569 return NULL_TREE;
3570 }
3571