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