xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/c-family/c-attribs.c (revision 4c3eb207d36f67d31994830c0a694161fc1ca39b)
1 /* C-family attributes handling.
2    Copyright (C) 1992-2020 Free Software Foundation, Inc.
3 
4 This file is part of GCC.
5 
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10 
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19 
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "target.h"
24 #include "function.h"
25 #include "tree.h"
26 #include "memmodel.h"
27 #include "c-common.h"
28 #include "gimple-expr.h"
29 #include "tm_p.h"
30 #include "stringpool.h"
31 #include "cgraph.h"
32 #include "diagnostic.h"
33 #include "intl.h"
34 #include "stor-layout.h"
35 #include "calls.h"
36 #include "attribs.h"
37 #include "varasm.h"
38 #include "trans-mem.h"
39 #include "c-objc.h"
40 #include "common/common-target.h"
41 #include "langhooks.h"
42 #include "tree-inline.h"
43 #include "toplev.h"
44 #include "tree-iterator.h"
45 #include "opts.h"
46 #include "gimplify.h"
47 #include "tree-pretty-print.h"
48 
49 static tree handle_packed_attribute (tree *, tree, tree, int, bool *);
50 static tree handle_nocommon_attribute (tree *, tree, tree, int, bool *);
51 static tree handle_common_attribute (tree *, tree, tree, int, bool *);
52 static tree handle_hot_attribute (tree *, tree, tree, int, bool *);
53 static tree handle_cold_attribute (tree *, tree, tree, int, bool *);
54 static tree handle_no_sanitize_attribute (tree *, tree, tree, int, bool *);
55 static tree handle_no_sanitize_address_attribute (tree *, tree, tree,
56 						  int, bool *);
57 static tree handle_no_sanitize_thread_attribute (tree *, tree, tree,
58 						 int, bool *);
59 static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree,
60 							 int, bool *);
61 static tree handle_no_sanitize_undefined_attribute (tree *, tree, tree, int,
62 						    bool *);
63 static tree handle_asan_odr_indicator_attribute (tree *, tree, tree, int,
64 						 bool *);
65 static tree handle_stack_protect_attribute (tree *, tree, tree, int, bool *);
66 static tree handle_noinline_attribute (tree *, tree, tree, int, bool *);
67 static tree handle_noclone_attribute (tree *, tree, tree, int, bool *);
68 static tree handle_nocf_check_attribute (tree *, tree, tree, int, bool *);
69 static tree handle_symver_attribute (tree *, tree, tree, int, bool *);
70 static tree handle_noicf_attribute (tree *, tree, tree, int, bool *);
71 static tree handle_noipa_attribute (tree *, tree, tree, int, bool *);
72 static tree handle_leaf_attribute (tree *, tree, tree, int, bool *);
73 static tree handle_always_inline_attribute (tree *, tree, tree, int,
74 					    bool *);
75 static tree handle_gnu_inline_attribute (tree *, tree, tree, int, bool *);
76 static tree handle_artificial_attribute (tree *, tree, tree, int, bool *);
77 static tree handle_flatten_attribute (tree *, tree, tree, int, bool *);
78 static tree handle_error_attribute (tree *, tree, tree, int, bool *);
79 static tree handle_used_attribute (tree *, tree, tree, int, bool *);
80 static tree handle_externally_visible_attribute (tree *, tree, tree, int,
81 						 bool *);
82 static tree handle_no_reorder_attribute (tree *, tree, tree, int,
83 						 bool *);
84 static tree handle_const_attribute (tree *, tree, tree, int, bool *);
85 static tree handle_transparent_union_attribute (tree *, tree, tree,
86 						int, bool *);
87 static tree handle_scalar_storage_order_attribute (tree *, tree, tree,
88 						   int, bool *);
89 static tree handle_constructor_attribute (tree *, tree, tree, int, bool *);
90 static tree handle_destructor_attribute (tree *, tree, tree, int, bool *);
91 static tree handle_mode_attribute (tree *, tree, tree, int, bool *);
92 static tree handle_section_attribute (tree *, tree, tree, int, bool *);
93 static tree handle_aligned_attribute (tree *, tree, tree, int, bool *);
94 static tree handle_warn_if_not_aligned_attribute (tree *, tree, tree,
95 						  int, bool *);
96 static tree handle_noinit_attribute (tree *, tree, tree, int, bool *);
97 static tree handle_weak_attribute (tree *, tree, tree, int, bool *) ;
98 static tree handle_noplt_attribute (tree *, tree, tree, int, bool *) ;
99 static tree handle_alias_ifunc_attribute (bool, tree *, tree, tree, bool *);
100 static tree handle_ifunc_attribute (tree *, tree, tree, int, bool *);
101 static tree handle_alias_attribute (tree *, tree, tree, int, bool *);
102 static tree handle_weakref_attribute (tree *, tree, tree, int, bool *) ;
103 static tree handle_visibility_attribute (tree *, tree, tree, int,
104 					 bool *);
105 static tree handle_tls_model_attribute (tree *, tree, tree, int,
106 					bool *);
107 static tree handle_no_instrument_function_attribute (tree *, tree,
108 						     tree, int, bool *);
109 static tree handle_no_profile_instrument_function_attribute (tree *, tree,
110 							     tree, int, bool *);
111 static tree handle_malloc_attribute (tree *, tree, tree, int, bool *);
112 static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *);
113 static tree handle_no_limit_stack_attribute (tree *, tree, tree, int,
114 					     bool *);
115 static tree handle_pure_attribute (tree *, tree, tree, int, bool *);
116 static tree handle_tm_attribute (tree *, tree, tree, int, bool *);
117 static tree handle_tm_wrap_attribute (tree *, tree, tree, int, bool *);
118 static tree handle_novops_attribute (tree *, tree, tree, int, bool *);
119 static tree handle_vector_size_attribute (tree *, tree, tree, int,
120 					  bool *);
121 static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
122 static tree handle_nonstring_attribute (tree *, tree, tree, int, bool *);
123 static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *);
124 static tree handle_cleanup_attribute (tree *, tree, tree, int, bool *);
125 static tree handle_warn_unused_result_attribute (tree *, tree, tree, int,
126 						 bool *);
127 static tree handle_access_attribute (tree *, tree, tree, int, bool *);
128 
129 static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *);
130 static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
131 static tree handle_alloc_size_attribute (tree *, tree, tree, int, bool *);
132 static tree handle_alloc_align_attribute (tree *, tree, tree, int, bool *);
133 static tree handle_assume_aligned_attribute (tree *, tree, tree, int, bool *);
134 static tree handle_target_attribute (tree *, tree, tree, int, bool *);
135 static tree handle_target_clones_attribute (tree *, tree, tree, int, bool *);
136 static tree handle_optimize_attribute (tree *, tree, tree, int, bool *);
137 static tree ignore_attribute (tree *, tree, tree, int, bool *);
138 static tree handle_no_split_stack_attribute (tree *, tree, tree, int, bool *);
139 static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *);
140 static tree handle_warn_unused_attribute (tree *, tree, tree, int, bool *);
141 static tree handle_returns_nonnull_attribute (tree *, tree, tree, int, bool *);
142 static tree handle_omp_declare_simd_attribute (tree *, tree, tree, int,
143 					       bool *);
144 static tree handle_omp_declare_variant_attribute (tree *, tree, tree, int,
145 						  bool *);
146 static tree handle_simd_attribute (tree *, tree, tree, int, bool *);
147 static tree handle_omp_declare_target_attribute (tree *, tree, tree, int,
148 						 bool *);
149 static tree handle_designated_init_attribute (tree *, tree, tree, int, bool *);
150 static tree handle_patchable_function_entry_attribute (tree *, tree, tree,
151 						       int, bool *);
152 static tree handle_copy_attribute (tree *, tree, tree, int, bool *);
153 
154 /* Helper to define attribute exclusions.  */
155 #define ATTR_EXCL(name, function, type, variable)	\
156   { name, function, type, variable }
157 
158 /* Define attributes that are mutually exclusive with one another.  */
159 static const struct attribute_spec::exclusions attr_aligned_exclusions[] =
160 {
161   /* Attribute name     exclusion applies to:
162 	                function, type, variable */
163   ATTR_EXCL ("aligned", true, false, false),
164   ATTR_EXCL ("packed", true, false, false),
165   ATTR_EXCL (NULL, false, false, false)
166 };
167 
168 extern const struct attribute_spec::exclusions attr_cold_hot_exclusions[] =
169 {
170   ATTR_EXCL ("cold", true, true, true),
171   ATTR_EXCL ("hot", true, true, true),
172   ATTR_EXCL (NULL, false, false, false)
173 };
174 
175 static const struct attribute_spec::exclusions attr_common_exclusions[] =
176 {
177   ATTR_EXCL ("common", true, true, true),
178   ATTR_EXCL ("nocommon", true, true, true),
179   ATTR_EXCL (NULL, false, false, false),
180 };
181 
182 static const struct attribute_spec::exclusions attr_inline_exclusions[] =
183 {
184   ATTR_EXCL ("noinline", true, true, true),
185   ATTR_EXCL (NULL, false, false, false),
186 };
187 
188 static const struct attribute_spec::exclusions attr_noinline_exclusions[] =
189 {
190   ATTR_EXCL ("always_inline", true, true, true),
191   ATTR_EXCL ("gnu_inline", true, true, true),
192   ATTR_EXCL (NULL, false, false, false),
193 };
194 
195 extern const struct attribute_spec::exclusions attr_noreturn_exclusions[] =
196 {
197   ATTR_EXCL ("alloc_align", true, true, true),
198   ATTR_EXCL ("alloc_size", true, true, true),
199   ATTR_EXCL ("const", true, true, true),
200   ATTR_EXCL ("malloc", true, true, true),
201   ATTR_EXCL ("pure", true, true, true),
202   ATTR_EXCL ("returns_twice", true, true, true),
203   ATTR_EXCL ("warn_unused_result", true, true, true),
204   ATTR_EXCL (NULL, false, false, false),
205 };
206 
207 static const struct attribute_spec::exclusions
208 attr_warn_unused_result_exclusions[] =
209 {
210   ATTR_EXCL ("noreturn", true, true, true),
211   ATTR_EXCL ("warn_unused_result", true, true, true),
212   ATTR_EXCL (NULL, false, false, false),
213 };
214 
215 static const struct attribute_spec::exclusions attr_returns_twice_exclusions[] =
216 {
217   ATTR_EXCL ("noreturn", true, true, true),
218   ATTR_EXCL (NULL, false, false, false),
219 };
220 
221 /* Exclusions that apply to attribute alloc_align, alloc_size, and malloc.  */
222 static const struct attribute_spec::exclusions attr_alloc_exclusions[] =
223 {
224   ATTR_EXCL ("const", true, true, true),
225   ATTR_EXCL ("noreturn", true, true, true),
226   ATTR_EXCL ("pure", true, true, true),
227   ATTR_EXCL (NULL, false, false, false),
228 };
229 
230 static const struct attribute_spec::exclusions attr_const_pure_exclusions[] =
231 {
232   ATTR_EXCL ("const", true, true, true),
233   ATTR_EXCL ("alloc_align", true, true, true),
234   ATTR_EXCL ("alloc_size", true, true, true),
235   ATTR_EXCL ("malloc", true, true, true),
236   ATTR_EXCL ("noreturn", true, true, true),
237   ATTR_EXCL ("pure", true, true, true),
238   ATTR_EXCL (NULL, false, false, false)
239 };
240 
241 static const struct attribute_spec::exclusions attr_noinit_exclusions[] =
242 {
243   ATTR_EXCL ("noinit", true, true, true),
244   ATTR_EXCL ("section", true, true, true),
245   ATTR_EXCL (NULL, false, false, false),
246 };
247 
248 /* Table of machine-independent attributes common to all C-like languages.
249 
250    Current list of processed common attributes: nonnull.  */
251 const struct attribute_spec c_common_attribute_table[] =
252 {
253   /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
254        affects_type_identity, handler, exclude } */
255   { "packed",                 0, 0, false, false, false, false,
256 			      handle_packed_attribute,
257 	                      attr_aligned_exclusions },
258   { "nocommon",               0, 0, true,  false, false, false,
259 			      handle_nocommon_attribute,
260 	                      attr_common_exclusions },
261   { "common",                 0, 0, true,  false, false, false,
262 			      handle_common_attribute,
263 	                      attr_common_exclusions },
264   /* FIXME: logically, noreturn attributes should be listed as
265      "false, true, true" and apply to function types.  But implementing this
266      would require all the places in the compiler that use TREE_THIS_VOLATILE
267      on a decl to identify non-returning functions to be located and fixed
268      to check the function type instead.  */
269   { "noreturn",               0, 0, true,  false, false, false,
270 			      handle_noreturn_attribute,
271 	                      attr_noreturn_exclusions },
272   { "volatile",               0, 0, true,  false, false, false,
273 			      handle_noreturn_attribute, NULL },
274   { "stack_protect",          0, 0, true,  false, false, false,
275 			      handle_stack_protect_attribute, NULL },
276   { "noinline",               0, 0, true,  false, false, false,
277 			      handle_noinline_attribute,
278 	                      attr_noinline_exclusions },
279   { "noclone",                0, 0, true,  false, false, false,
280 			      handle_noclone_attribute, NULL },
281   { "no_icf",                 0, 0, true,  false, false, false,
282 			      handle_noicf_attribute, NULL },
283   { "noipa",		      0, 0, true,  false, false, false,
284 			      handle_noipa_attribute, NULL },
285   { "leaf",                   0, 0, true,  false, false, false,
286 			      handle_leaf_attribute, NULL },
287   { "always_inline",          0, 0, true,  false, false, false,
288 			      handle_always_inline_attribute,
289 	                      attr_inline_exclusions },
290   { "gnu_inline",             0, 0, true,  false, false, false,
291 			      handle_gnu_inline_attribute,
292 	                      attr_inline_exclusions },
293   { "artificial",             0, 0, true,  false, false, false,
294 			      handle_artificial_attribute, NULL },
295   { "flatten",                0, 0, true,  false, false, false,
296 			      handle_flatten_attribute, NULL },
297   { "used",                   0, 0, true,  false, false, false,
298 			      handle_used_attribute, NULL },
299   { "unused",                 0, 0, false, false, false, false,
300 			      handle_unused_attribute, NULL },
301   { "externally_visible",     0, 0, true,  false, false, false,
302 			      handle_externally_visible_attribute, NULL },
303   { "no_reorder",	      0, 0, true, false, false, false,
304 	                      handle_no_reorder_attribute, NULL },
305   /* The same comments as for noreturn attributes apply to const ones.  */
306   { "const",                  0, 0, true,  false, false, false,
307 			      handle_const_attribute,
308 	                      attr_const_pure_exclusions },
309   { "scalar_storage_order",   1, 1, false, false, false, false,
310 			      handle_scalar_storage_order_attribute, NULL },
311   { "transparent_union",      0, 0, false, false, false, false,
312 			      handle_transparent_union_attribute, NULL },
313   { "constructor",            0, 1, true,  false, false, false,
314 			      handle_constructor_attribute, NULL },
315   { "destructor",             0, 1, true,  false, false, false,
316 			      handle_destructor_attribute, NULL },
317   { "mode",                   1, 1, false,  true, false, false,
318 			      handle_mode_attribute, NULL },
319   { "section",                1, 1, true,  false, false, false,
320 			      handle_section_attribute, attr_noinit_exclusions },
321   { "aligned",                0, 1, false, false, false, false,
322 			      handle_aligned_attribute,
323 	                      attr_aligned_exclusions },
324   { "warn_if_not_aligned",    0, 1, false, false, false, false,
325 			      handle_warn_if_not_aligned_attribute, NULL },
326   { "weak",                   0, 0, true,  false, false, false,
327 			      handle_weak_attribute, NULL },
328   { "noplt",                   0, 0, true,  false, false, false,
329 			      handle_noplt_attribute, NULL },
330   { "ifunc",                  1, 1, true,  false, false, false,
331 			      handle_ifunc_attribute, NULL },
332   { "alias",                  1, 1, true,  false, false, false,
333 			      handle_alias_attribute, NULL },
334   { "weakref",                0, 1, true,  false, false, false,
335 			      handle_weakref_attribute, NULL },
336   { "no_instrument_function", 0, 0, true,  false, false, false,
337 			      handle_no_instrument_function_attribute,
338 			      NULL },
339   { "no_profile_instrument_function",  0, 0, true, false, false, false,
340 			      handle_no_profile_instrument_function_attribute,
341 			      NULL },
342   { "malloc",                 0, 0, true,  false, false, false,
343 			      handle_malloc_attribute, attr_alloc_exclusions },
344   { "returns_twice",          0, 0, true,  false, false, false,
345 			      handle_returns_twice_attribute,
346 	                      attr_returns_twice_exclusions },
347   { "no_stack_limit",         0, 0, true,  false, false, false,
348 			      handle_no_limit_stack_attribute, NULL },
349   { "pure",                   0, 0, true,  false, false, false,
350 			      handle_pure_attribute,
351 	                      attr_const_pure_exclusions },
352   { "transaction_callable",   0, 0, false, true,  false, false,
353 			      handle_tm_attribute, NULL },
354   { "transaction_unsafe",     0, 0, false, true,  false, true,
355 			      handle_tm_attribute, NULL },
356   { "transaction_safe",       0, 0, false, true,  false, true,
357 			      handle_tm_attribute, NULL },
358   { "transaction_safe_dynamic", 0, 0, true, false,  false, false,
359 			      handle_tm_attribute, NULL },
360   { "transaction_may_cancel_outer", 0, 0, false, true, false, false,
361 			      handle_tm_attribute, NULL },
362   /* ??? These two attributes didn't make the transition from the
363      Intel language document to the multi-vendor language document.  */
364   { "transaction_pure",       0, 0, false, true,  false, false,
365 			      handle_tm_attribute, NULL },
366   { "transaction_wrap",       1, 1, true,  false,  false, false,
367 			     handle_tm_wrap_attribute, NULL },
368   /* For internal use (marking of builtins) only.  The name contains space
369      to prevent its usage in source code.  */
370   { "no vops",                0, 0, true,  false, false, false,
371 			      handle_novops_attribute, NULL },
372   { "deprecated",             0, 1, false, false, false, false,
373 			      handle_deprecated_attribute, NULL },
374   { "vector_size",	      1, 1, false, true, false, true,
375 			      handle_vector_size_attribute, NULL },
376   { "visibility",	      1, 1, false, false, false, false,
377 			      handle_visibility_attribute, NULL },
378   { "tls_model",	      1, 1, true,  false, false, false,
379 			      handle_tls_model_attribute, NULL },
380   { "nonnull",                0, -1, false, true, true, false,
381 			      handle_nonnull_attribute, NULL },
382   { "nonstring",              0, 0, true, false, false, false,
383 			      handle_nonstring_attribute, NULL },
384   { "nothrow",                0, 0, true,  false, false, false,
385 			      handle_nothrow_attribute, NULL },
386   { "may_alias",	      0, 0, false, true, false, false, NULL, NULL },
387   { "cleanup",		      1, 1, true, false, false, false,
388 			      handle_cleanup_attribute, NULL },
389   { "warn_unused_result",     0, 0, false, true, true, false,
390 			      handle_warn_unused_result_attribute,
391 	                      attr_warn_unused_result_exclusions },
392   { "sentinel",               0, 1, false, true, true, false,
393 			      handle_sentinel_attribute, NULL },
394   /* For internal use (marking of builtins) only.  The name contains space
395      to prevent its usage in source code.  */
396   { "type generic",           0, 0, false, true, true, false,
397 			      handle_type_generic_attribute, NULL },
398   { "alloc_size",	      1, 2, false, true, true, false,
399 			      handle_alloc_size_attribute,
400 	                      attr_alloc_exclusions },
401   { "cold",                   0, 0, true,  false, false, false,
402 			      handle_cold_attribute,
403 	                      attr_cold_hot_exclusions },
404   { "hot",                    0, 0, true,  false, false, false,
405 			      handle_hot_attribute,
406 	                      attr_cold_hot_exclusions },
407   { "no_address_safety_analysis",
408 			      0, 0, true, false, false, false,
409 			      handle_no_address_safety_analysis_attribute,
410 			      NULL },
411   { "no_sanitize",	      1, -1, true, false, false, false,
412 			      handle_no_sanitize_attribute, NULL },
413   { "no_sanitize_address",    0, 0, true, false, false, false,
414 			      handle_no_sanitize_address_attribute, NULL },
415   { "no_sanitize_thread",     0, 0, true, false, false, false,
416 			      handle_no_sanitize_thread_attribute, NULL },
417   { "no_sanitize_undefined",  0, 0, true, false, false, false,
418 			      handle_no_sanitize_undefined_attribute, NULL },
419   { "asan odr indicator",     0, 0, true, false, false, false,
420 			      handle_asan_odr_indicator_attribute, NULL },
421   { "warning",		      1, 1, true,  false, false, false,
422 			      handle_error_attribute, NULL },
423   { "error",		      1, 1, true,  false, false, false,
424 			      handle_error_attribute, NULL },
425   { "target",                 1, -1, true, false, false, false,
426 			      handle_target_attribute, NULL },
427   { "target_clones",          1, -1, true, false, false, false,
428 			      handle_target_clones_attribute, NULL },
429   { "optimize",               1, -1, true, false, false, false,
430 			      handle_optimize_attribute, NULL },
431   /* For internal use only.  The leading '*' both prevents its usage in
432      source code and signals that it may be overridden by machine tables.  */
433   { "*tm regparm",            0, 0, false, true, true, false,
434 			      ignore_attribute, NULL },
435   { "no_split_stack",	      0, 0, true,  false, false, false,
436 			      handle_no_split_stack_attribute, NULL },
437   /* For internal use (marking of builtins and runtime functions) only.
438      The name contains space to prevent its usage in source code.  */
439   { "fn spec",		      1, 1, false, true, true, false,
440 			      handle_fnspec_attribute, NULL },
441   { "warn_unused",            0, 0, false, false, false, false,
442 			      handle_warn_unused_attribute, NULL },
443   { "returns_nonnull",        0, 0, false, true, true, false,
444 			      handle_returns_nonnull_attribute, NULL },
445   { "omp declare simd",       0, -1, true,  false, false, false,
446 			      handle_omp_declare_simd_attribute, NULL },
447   { "omp declare variant base", 0, -1, true,  false, false, false,
448 			      handle_omp_declare_variant_attribute, NULL },
449   { "omp declare variant variant", 0, -1, true,  false, false, false,
450 			      handle_omp_declare_variant_attribute, NULL },
451   { "simd",		      0, 1, true,  false, false, false,
452 			      handle_simd_attribute, NULL },
453   { "omp declare target",     0, -1, true, false, false, false,
454 			      handle_omp_declare_target_attribute, NULL },
455   { "omp declare target link", 0, 0, true, false, false, false,
456 			      handle_omp_declare_target_attribute, NULL },
457   { "omp declare target implicit", 0, 0, true, false, false, false,
458 			      handle_omp_declare_target_attribute, NULL },
459   { "omp declare target host", 0, 0, true, false, false, false,
460 			      handle_omp_declare_target_attribute, NULL },
461   { "omp declare target nohost", 0, 0, true, false, false, false,
462 			      handle_omp_declare_target_attribute, NULL },
463   { "omp declare target block", 0, 0, true, false, false, false,
464 			      handle_omp_declare_target_attribute, NULL },
465   { "alloc_align",	      1, 1, false, true, true, false,
466 			      handle_alloc_align_attribute,
467 	                      attr_alloc_exclusions },
468   { "assume_aligned",	      1, 2, false, true, true, false,
469 			      handle_assume_aligned_attribute, NULL },
470   { "designated_init",        0, 0, false, true, false, false,
471 			      handle_designated_init_attribute, NULL },
472   { "fallthrough",	      0, 0, false, false, false, false,
473 			      handle_fallthrough_attribute, NULL },
474   { "patchable_function_entry",	1, 2, true, false, false, false,
475 			      handle_patchable_function_entry_attribute,
476 			      NULL },
477   { "nocf_check",	      0, 0, false, true, true, true,
478 			      handle_nocf_check_attribute, NULL },
479   { "symver",		      1, -1, true, false, false, false,
480 			      handle_symver_attribute, NULL},
481   { "copy",                   1, 1, false, false, false, false,
482 			      handle_copy_attribute, NULL },
483   { "noinit",		      0, 0, true,  false, false, false,
484 			      handle_noinit_attribute, attr_noinit_exclusions },
485   { "access",		      1, 3, false, true, true, false,
486 			      handle_access_attribute, NULL },
487   { NULL,                     0, 0, false, false, false, false, NULL, NULL }
488 };
489 
490 /* Give the specifications for the format attributes, used by C and all
491    descendants.
492 
493    Current list of processed format attributes: format, format_arg.  */
494 const struct attribute_spec c_common_format_attribute_table[] =
495 {
496   /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
497        affects_type_identity, handler, exclude } */
498   { "format",                 3, 3, false, true,  true, false,
499 			      handle_format_attribute, NULL },
500   { "format_arg",             1, 1, false, true,  true, false,
501 			      handle_format_arg_attribute, NULL },
502   { NULL,                     0, 0, false, false, false, false, NULL, NULL }
503 };
504 
505 /* Returns TRUE iff the attribute indicated by ATTR_ID takes a plain
506    identifier as an argument, so the front end shouldn't look it up.  */
507 
508 bool
attribute_takes_identifier_p(const_tree attr_id)509 attribute_takes_identifier_p (const_tree attr_id)
510 {
511   const struct attribute_spec *spec = lookup_attribute_spec (attr_id);
512   if (spec == NULL)
513     /* Unknown attribute that we'll end up ignoring, return true so we
514        don't complain about an identifier argument.  */
515     return true;
516   else if (!strcmp ("mode", spec->name)
517 	   || !strcmp ("format", spec->name)
518 	   || !strcmp ("cleanup", spec->name)
519 	   || !strcmp ("access", spec->name))
520     return true;
521   else
522     return targetm.attribute_takes_identifier_p (attr_id);
523 }
524 
525 /* Verify that argument value POS at position ARGNO to attribute NAME
526    applied to function TYPE refers to a function parameter at position
527    POS and the expected type CODE.  Treat CODE == INTEGER_TYPE as
528    matching all C integral types except bool.  If successful, return
529    POS after default conversions, if any.  Otherwise, issue appropriate
530    warnings and return null.  A non-zero 1-based ARGNO should be passed
531    in by callers only for attributes with more than one argument.  */
532 
533 tree
positional_argument(const_tree fntype,const_tree atname,tree pos,tree_code code,int argno,int flags)534 positional_argument (const_tree fntype, const_tree atname, tree pos,
535 		     tree_code code, int argno /* = 0 */,
536 		     int flags /* = posargflags () */)
537 {
538   if (pos && TREE_CODE (pos) != IDENTIFIER_NODE
539       && TREE_CODE (pos) != FUNCTION_DECL)
540     pos = default_conversion (pos);
541 
542   tree postype = TREE_TYPE (pos);
543   if (pos == error_mark_node || !postype)
544     {
545       /* Only mention the positional argument number when it's non-zero.  */
546       if (argno < 1)
547 	warning (OPT_Wattributes,
548 		 "%qE attribute argument is invalid", atname);
549       else
550 	warning (OPT_Wattributes,
551 		 "%qE attribute argument %i is invalid", atname, argno);
552 
553       return NULL_TREE;
554     }
555 
556   if (!INTEGRAL_TYPE_P (postype))
557     {
558       /* Handle this case specially to avoid mentioning the value
559 	 of pointer constants in diagnostics.  Only mention
560 	 the positional argument number when it's non-zero.  */
561       if (argno < 1)
562 	warning (OPT_Wattributes,
563 		 "%qE attribute argument has type %qT",
564 		 atname, postype);
565       else
566 	warning (OPT_Wattributes,
567 		 "%qE attribute argument %i has type %qT",
568 		 atname, argno, postype);
569 
570       return NULL_TREE;
571     }
572 
573   if (TREE_CODE (pos) != INTEGER_CST)
574     {
575       /* Only mention the argument number when it's non-zero.  */
576       if (argno < 1)
577 	warning (OPT_Wattributes,
578 		 "%qE attribute argument value %qE is not an integer "
579 		 "constant",
580 		 atname, pos);
581       else
582 	warning (OPT_Wattributes,
583 		 "%qE attribute argument %i value %qE is not an integer "
584 		 "constant",
585 		 atname, argno, pos);
586 
587       return NULL_TREE;
588     }
589 
590   /* Argument positions are 1-based.  */
591   if (integer_zerop (pos))
592     {
593       if (flags & POSARG_ZERO)
594 	/* Zero is explicitly allowed.  */
595 	return pos;
596 
597       if (argno < 1)
598 	warning (OPT_Wattributes,
599 		 "%qE attribute argument value %qE does not refer to "
600 		 "a function parameter",
601 		 atname, pos);
602       else
603 	warning (OPT_Wattributes,
604 		 "%qE attribute argument %i value %qE does not refer to "
605 		 "a function parameter",
606 		 atname, argno, pos);
607 
608       return NULL_TREE;
609     }
610 
611   if (!prototype_p (fntype))
612     return pos;
613 
614   /* Verify that the argument position does not exceed the number
615      of formal arguments to the function.  When POSARG_ELLIPSIS
616      is set, ARGNO may be beyond the last argument of a vararg
617      function.  */
618   unsigned nargs = type_num_arguments (fntype);
619   if (!nargs
620       || !tree_fits_uhwi_p (pos)
621       || ((flags & POSARG_ELLIPSIS) == 0
622 	  && !IN_RANGE (tree_to_uhwi (pos), 1, nargs)))
623     {
624 
625       if (argno < 1)
626 	warning (OPT_Wattributes,
627 		 "%qE attribute argument value %qE exceeds the number "
628 		 "of function parameters %u",
629 		 atname, pos, nargs);
630       else
631 	warning (OPT_Wattributes,
632 		 "%qE attribute argument %i value %qE exceeds the number "
633 		 "of function parameters %u",
634 		 atname, argno, pos, nargs);
635       return NULL_TREE;
636     }
637 
638   /* Verify that the type of the referenced formal argument matches
639      the expected type.  */
640   unsigned HOST_WIDE_INT ipos = tree_to_uhwi (pos);
641 
642   /* Zero was handled above.  */
643   gcc_assert (ipos != 0);
644 
645   if (tree argtype = type_argument_type (fntype, ipos))
646     {
647       if (flags & POSARG_ELLIPSIS)
648 	{
649 	  if (argno < 1)
650 	    error ("%qE attribute argument value %qE does not refer to "
651 		   "a variable argument list",
652 		   atname, pos);
653 	  else
654 	    error ("%qE attribute argument %i value %qE does not refer to "
655 		   "a variable argument list",
656 		   atname, argno, pos);
657 	  return NULL_TREE;
658 	}
659 
660       /* Where the expected code is STRING_CST accept any pointer
661 	 expected by attribute format (this includes possibly qualified
662 	 char pointers and, for targets like Darwin, also pointers to
663 	 struct CFString).  */
664       bool type_match;
665       if (code == STRING_CST)
666 	type_match = valid_format_string_type_p (argtype);
667       else if (code == INTEGER_TYPE)
668 	/* For integers, accept enums, wide characters and other types
669 	   that match INTEGRAL_TYPE_P except for bool.  */
670 	type_match = (INTEGRAL_TYPE_P (argtype)
671 		      && TREE_CODE (argtype) != BOOLEAN_TYPE);
672       else
673 	type_match = TREE_CODE (argtype) == code;
674 
675       if (!type_match)
676 	{
677 	  if (code == STRING_CST)
678 	    {
679 	      /* Reject invalid format strings with an error.  */
680 	      if (argno < 1)
681 		error ("%qE attribute argument value %qE refers to "
682 		       "parameter type %qT",
683 		       atname, pos, argtype);
684 	      else
685 		error ("%qE attribute argument %i value %qE refers to "
686 		       "parameter type %qT",
687 		       atname, argno, pos, argtype);
688 
689 	      return NULL_TREE;
690 	    }
691 
692 	  if (argno < 1)
693 	    warning (OPT_Wattributes,
694 		     "%qE attribute argument value %qE refers to "
695 		     "parameter type %qT",
696 		     atname, pos, argtype);
697 	  else
698 	    warning (OPT_Wattributes,
699 		   "%qE attribute argument %i value %qE refers to "
700 		     "parameter type %qT",
701 		     atname, argno, pos, argtype);
702 	  return NULL_TREE;
703 	}
704     }
705   else if (!(flags & POSARG_ELLIPSIS))
706     {
707       if (argno < 1)
708 	warning (OPT_Wattributes,
709 		 "%qE attribute argument value %qE refers to "
710 		 "a variadic function parameter of unknown type",
711 		 atname, pos);
712       else
713 	warning (OPT_Wattributes,
714 		 "%qE attribute argument %i value %qE refers to "
715 		 "a variadic function parameter of unknown type",
716 		 atname, argno, pos);
717       return NULL_TREE;
718     }
719 
720   return pos;
721 }
722 
723 
724 /* Attribute handlers common to C front ends.  */
725 
726 /* Handle a "packed" attribute; arguments as in
727    struct attribute_spec.handler.  */
728 
729 static tree
handle_packed_attribute(tree * node,tree name,tree ARG_UNUSED (args),int flags,bool * no_add_attrs)730 handle_packed_attribute (tree *node, tree name, tree ARG_UNUSED (args),
731 			 int flags, bool *no_add_attrs)
732 {
733   if (TYPE_P (*node))
734     {
735       if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
736 	{
737 	  warning (OPT_Wattributes,
738 		   "%qE attribute ignored for type %qT", name, *node);
739 	  *no_add_attrs = true;
740 	}
741       else
742 	TYPE_PACKED (*node) = 1;
743     }
744   else if (TREE_CODE (*node) == FIELD_DECL)
745     {
746       if (TYPE_ALIGN (TREE_TYPE (*node)) <= BITS_PER_UNIT
747 	  /* Still pack bitfields.  */
748 	  && ! DECL_C_BIT_FIELD (*node))
749 	warning (OPT_Wattributes,
750 		 "%qE attribute ignored for field of type %qT",
751 		 name, TREE_TYPE (*node));
752       else
753 	DECL_PACKED (*node) = 1;
754     }
755   /* We can't set DECL_PACKED for a VAR_DECL, because the bit is
756      used for DECL_REGISTER.  It wouldn't mean anything anyway.
757      We can't set DECL_PACKED on the type of a TYPE_DECL, because
758      that changes what the typedef is typing.  */
759   else
760     {
761       warning (OPT_Wattributes, "%qE attribute ignored", name);
762       *no_add_attrs = true;
763     }
764 
765   return NULL_TREE;
766 }
767 
768 /* Handle a "nocommon" attribute; arguments as in
769    struct attribute_spec.handler.  */
770 
771 static tree
handle_nocommon_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)772 handle_nocommon_attribute (tree *node, tree name,
773 			   tree ARG_UNUSED (args),
774 			   int ARG_UNUSED (flags), bool *no_add_attrs)
775 {
776   if (VAR_P (*node))
777     DECL_COMMON (*node) = 0;
778   else
779     {
780       warning (OPT_Wattributes, "%qE attribute ignored", name);
781       *no_add_attrs = true;
782     }
783 
784   return NULL_TREE;
785 }
786 
787 /* Handle a "common" attribute; arguments as in
788    struct attribute_spec.handler.  */
789 
790 static tree
handle_common_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)791 handle_common_attribute (tree *node, tree name, tree ARG_UNUSED (args),
792 			 int ARG_UNUSED (flags), bool *no_add_attrs)
793 {
794   if (VAR_P (*node))
795     DECL_COMMON (*node) = 1;
796   else
797     {
798       warning (OPT_Wattributes, "%qE attribute ignored", name);
799       *no_add_attrs = true;
800     }
801 
802   return NULL_TREE;
803 }
804 
805 /* Handle a "noreturn" attribute; arguments as in
806    struct attribute_spec.handler.  */
807 
808 tree
handle_noreturn_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)809 handle_noreturn_attribute (tree *node, tree name, tree ARG_UNUSED (args),
810 			   int ARG_UNUSED (flags), bool *no_add_attrs)
811 {
812   tree type = TREE_TYPE (*node);
813 
814   /* See FIXME comment in c_common_attribute_table.  */
815   if (TREE_CODE (*node) == FUNCTION_DECL
816       || objc_method_decl (TREE_CODE (*node)))
817     TREE_THIS_VOLATILE (*node) = 1;
818   else if (TREE_CODE (type) == POINTER_TYPE
819 	   && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
820     TREE_TYPE (*node)
821       = (build_qualified_type
822 	 (build_pointer_type
823 	  (build_type_variant (TREE_TYPE (type),
824 			       TYPE_READONLY (TREE_TYPE (type)), 1)),
825 	  TYPE_QUALS (type)));
826   else
827     {
828       warning (OPT_Wattributes, "%qE attribute ignored", name);
829       *no_add_attrs = true;
830     }
831 
832   return NULL_TREE;
833 }
834 
835 /* Handle a "hot" and attribute; arguments as in
836    struct attribute_spec.handler.  */
837 
838 static tree
handle_hot_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)839 handle_hot_attribute (tree *node, tree name, tree ARG_UNUSED (args),
840 		      int ARG_UNUSED (flags), bool *no_add_attrs)
841 {
842   if (TREE_CODE (*node) == FUNCTION_DECL
843       || TREE_CODE (*node) == LABEL_DECL)
844     {
845       /* Attribute hot processing is done later with lookup_attribute.  */
846     }
847   else
848     {
849       warning (OPT_Wattributes, "%qE attribute ignored", name);
850       *no_add_attrs = true;
851     }
852 
853   return NULL_TREE;
854 }
855 
856 /* Handle a "cold" and attribute; arguments as in
857    struct attribute_spec.handler.  */
858 
859 static tree
handle_cold_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)860 handle_cold_attribute (tree *node, tree name, tree ARG_UNUSED (args),
861 		       int ARG_UNUSED (flags), bool *no_add_attrs)
862 {
863   if (TREE_CODE (*node) == FUNCTION_DECL
864       || TREE_CODE (*node) == LABEL_DECL)
865     {
866       /* Attribute cold processing is done later with lookup_attribute.  */
867     }
868   else
869     {
870       warning (OPT_Wattributes, "%qE attribute ignored", name);
871       *no_add_attrs = true;
872     }
873 
874   return NULL_TREE;
875 }
876 
877 /* Add FLAGS for a function NODE to no_sanitize_flags in DECL_ATTRIBUTES.  */
878 
879 void
add_no_sanitize_value(tree node,unsigned int flags)880 add_no_sanitize_value (tree node, unsigned int flags)
881 {
882   tree attr = lookup_attribute ("no_sanitize", DECL_ATTRIBUTES (node));
883   if (attr)
884     {
885       unsigned int old_value = tree_to_uhwi (TREE_VALUE (attr));
886       flags |= old_value;
887 
888       if (flags == old_value)
889 	return;
890 
891       TREE_VALUE (attr) = build_int_cst (unsigned_type_node, flags);
892     }
893   else
894     DECL_ATTRIBUTES (node)
895       = tree_cons (get_identifier ("no_sanitize"),
896 		   build_int_cst (unsigned_type_node, flags),
897 		   DECL_ATTRIBUTES (node));
898 }
899 
900 /* Handle a "no_sanitize" attribute; arguments as in
901    struct attribute_spec.handler.  */
902 
903 static tree
handle_no_sanitize_attribute(tree * node,tree name,tree args,int,bool * no_add_attrs)904 handle_no_sanitize_attribute (tree *node, tree name, tree args, int,
905 			      bool *no_add_attrs)
906 {
907   unsigned int flags = 0;
908   *no_add_attrs = true;
909   if (TREE_CODE (*node) != FUNCTION_DECL)
910     {
911       warning (OPT_Wattributes, "%qE attribute ignored", name);
912       return NULL_TREE;
913     }
914 
915   for (; args; args = TREE_CHAIN (args))
916     {
917       tree id = TREE_VALUE (args);
918       if (TREE_CODE (id) != STRING_CST)
919 	{
920 	  error ("%qE argument not a string", name);
921 	  return NULL_TREE;
922 	}
923 
924       char *string = ASTRDUP (TREE_STRING_POINTER (id));
925       flags |= parse_no_sanitize_attribute (string);
926     }
927 
928   add_no_sanitize_value (*node, flags);
929 
930   return NULL_TREE;
931 }
932 
933 /* Handle a "no_sanitize_address" attribute; arguments as in
934    struct attribute_spec.handler.  */
935 
936 static tree
handle_no_sanitize_address_attribute(tree * node,tree name,tree,int,bool * no_add_attrs)937 handle_no_sanitize_address_attribute (tree *node, tree name, tree, int,
938 				      bool *no_add_attrs)
939 {
940   *no_add_attrs = true;
941   if (TREE_CODE (*node) != FUNCTION_DECL)
942     warning (OPT_Wattributes, "%qE attribute ignored", name);
943   else
944     add_no_sanitize_value (*node, SANITIZE_ADDRESS);
945 
946   return NULL_TREE;
947 }
948 
949 /* Handle a "no_sanitize_thread" attribute; arguments as in
950    struct attribute_spec.handler.  */
951 
952 static tree
handle_no_sanitize_thread_attribute(tree * node,tree name,tree,int,bool * no_add_attrs)953 handle_no_sanitize_thread_attribute (tree *node, tree name, tree, int,
954 				      bool *no_add_attrs)
955 {
956   *no_add_attrs = true;
957   if (TREE_CODE (*node) != FUNCTION_DECL)
958     warning (OPT_Wattributes, "%qE attribute ignored", name);
959   else
960     add_no_sanitize_value (*node, SANITIZE_THREAD);
961 
962   return NULL_TREE;
963 }
964 
965 
966 /* Handle a "no_address_safety_analysis" attribute; arguments as in
967    struct attribute_spec.handler.  */
968 
969 static tree
handle_no_address_safety_analysis_attribute(tree * node,tree name,tree,int,bool * no_add_attrs)970 handle_no_address_safety_analysis_attribute (tree *node, tree name, tree, int,
971 					     bool *no_add_attrs)
972 {
973   *no_add_attrs = true;
974   if (TREE_CODE (*node) != FUNCTION_DECL)
975     warning (OPT_Wattributes, "%qE attribute ignored", name);
976   else
977     add_no_sanitize_value (*node, SANITIZE_ADDRESS);
978 
979   return NULL_TREE;
980 }
981 
982 /* Handle a "no_sanitize_undefined" attribute; arguments as in
983    struct attribute_spec.handler.  */
984 
985 static tree
handle_no_sanitize_undefined_attribute(tree * node,tree name,tree,int,bool * no_add_attrs)986 handle_no_sanitize_undefined_attribute (tree *node, tree name, tree, int,
987 				      bool *no_add_attrs)
988 {
989   *no_add_attrs = true;
990   if (TREE_CODE (*node) != FUNCTION_DECL)
991     warning (OPT_Wattributes, "%qE attribute ignored", name);
992   else
993     add_no_sanitize_value (*node,
994 			   SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT);
995 
996   return NULL_TREE;
997 }
998 
999 /* Handle an "asan odr indicator" attribute; arguments as in
1000    struct attribute_spec.handler.  */
1001 
1002 static tree
handle_asan_odr_indicator_attribute(tree *,tree,tree,int,bool *)1003 handle_asan_odr_indicator_attribute (tree *, tree, tree, int, bool *)
1004 {
1005   return NULL_TREE;
1006 }
1007 
1008 /* Handle a "stack_protect" attribute; arguments as in
1009    struct attribute_spec.handler.  */
1010 
1011 static tree
handle_stack_protect_attribute(tree * node,tree name,tree,int,bool * no_add_attrs)1012 handle_stack_protect_attribute (tree *node, tree name, tree, int,
1013 				bool *no_add_attrs)
1014 {
1015   if (TREE_CODE (*node) != FUNCTION_DECL)
1016     {
1017       warning (OPT_Wattributes, "%qE attribute ignored", name);
1018       *no_add_attrs = true;
1019     }
1020 
1021   return NULL_TREE;
1022 }
1023 
1024 /* Handle a "noipa" attribute; arguments as in
1025    struct attribute_spec.handler.  */
1026 
1027 static tree
handle_noipa_attribute(tree * node,tree name,tree,int,bool * no_add_attrs)1028 handle_noipa_attribute (tree *node, tree name, tree, int, bool *no_add_attrs)
1029 {
1030   if (TREE_CODE (*node) != FUNCTION_DECL)
1031     {
1032       warning (OPT_Wattributes, "%qE attribute ignored", name);
1033       *no_add_attrs = true;
1034     }
1035 
1036   return NULL_TREE;
1037 }
1038 
1039 /* Handle a "noinline" attribute; arguments as in
1040    struct attribute_spec.handler.  */
1041 
1042 static tree
handle_noinline_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)1043 handle_noinline_attribute (tree *node, tree name,
1044 			   tree ARG_UNUSED (args),
1045 			   int ARG_UNUSED (flags), bool *no_add_attrs)
1046 {
1047   if (TREE_CODE (*node) == FUNCTION_DECL)
1048     {
1049       if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (*node)))
1050 	{
1051 	  warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
1052 		   "with attribute %qs", name, "always_inline");
1053 	  *no_add_attrs = true;
1054 	}
1055       else
1056 	DECL_UNINLINABLE (*node) = 1;
1057     }
1058   else
1059     {
1060       warning (OPT_Wattributes, "%qE attribute ignored", name);
1061       *no_add_attrs = true;
1062     }
1063 
1064   return NULL_TREE;
1065 }
1066 
1067 /* Handle a "noclone" attribute; arguments as in
1068    struct attribute_spec.handler.  */
1069 
1070 static tree
handle_noclone_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)1071 handle_noclone_attribute (tree *node, tree name,
1072 			  tree ARG_UNUSED (args),
1073 			  int ARG_UNUSED (flags), bool *no_add_attrs)
1074 {
1075   if (TREE_CODE (*node) != FUNCTION_DECL)
1076     {
1077       warning (OPT_Wattributes, "%qE attribute ignored", name);
1078       *no_add_attrs = true;
1079     }
1080 
1081   return NULL_TREE;
1082 }
1083 
1084 /* Handle a "nocf_check" attribute; arguments as in
1085    struct attribute_spec.handler.  */
1086 
1087 static tree
handle_nocf_check_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)1088 handle_nocf_check_attribute (tree *node, tree name,
1089 			  tree ARG_UNUSED (args),
1090 			  int ARG_UNUSED (flags), bool *no_add_attrs)
1091 {
1092   if (TREE_CODE (*node) != FUNCTION_TYPE
1093       && TREE_CODE (*node) != METHOD_TYPE)
1094     {
1095       warning (OPT_Wattributes, "%qE attribute ignored", name);
1096       *no_add_attrs = true;
1097     }
1098   else if (!(flag_cf_protection & CF_BRANCH))
1099     {
1100       warning (OPT_Wattributes, "%qE attribute ignored. Use "
1101 				"%<-fcf-protection%> option to enable it",
1102 				name);
1103       *no_add_attrs = true;
1104     }
1105 
1106   return NULL_TREE;
1107 }
1108 
1109 /* Handle a "no_icf" attribute; arguments as in
1110    struct attribute_spec.handler.  */
1111 
1112 static tree
handle_noicf_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)1113 handle_noicf_attribute (tree *node, tree name,
1114 			tree ARG_UNUSED (args),
1115 			int ARG_UNUSED (flags), bool *no_add_attrs)
1116 {
1117   if (TREE_CODE (*node) != FUNCTION_DECL)
1118     {
1119       warning (OPT_Wattributes, "%qE attribute ignored", name);
1120       *no_add_attrs = true;
1121     }
1122 
1123   return NULL_TREE;
1124 }
1125 
1126 
1127 /* Handle a "always_inline" attribute; arguments as in
1128    struct attribute_spec.handler.  */
1129 
1130 static tree
handle_always_inline_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)1131 handle_always_inline_attribute (tree *node, tree name,
1132 				tree ARG_UNUSED (args),
1133 				int ARG_UNUSED (flags),
1134 				bool *no_add_attrs)
1135 {
1136   if (TREE_CODE (*node) == FUNCTION_DECL)
1137     {
1138       if (lookup_attribute ("noinline", DECL_ATTRIBUTES (*node)))
1139 	{
1140 	  warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
1141 		   "with %qs attribute", name, "noinline");
1142 	  *no_add_attrs = true;
1143 	}
1144       else if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (*node)))
1145 	{
1146 	  warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
1147 		   "with %qs attribute", name, "target_clones");
1148 	  *no_add_attrs = true;
1149 	}
1150       else
1151 	/* Set the attribute and mark it for disregarding inline
1152 	   limits.  */
1153 	DECL_DISREGARD_INLINE_LIMITS (*node) = 1;
1154     }
1155   else
1156     {
1157       warning (OPT_Wattributes, "%qE attribute ignored", name);
1158       *no_add_attrs = true;
1159     }
1160 
1161   return NULL_TREE;
1162 }
1163 
1164 /* Handle a "gnu_inline" attribute; arguments as in
1165    struct attribute_spec.handler.  */
1166 
1167 static tree
handle_gnu_inline_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)1168 handle_gnu_inline_attribute (tree *node, tree name,
1169 			     tree ARG_UNUSED (args),
1170 			     int ARG_UNUSED (flags),
1171 			     bool *no_add_attrs)
1172 {
1173   if (TREE_CODE (*node) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (*node))
1174     {
1175       /* Do nothing else, just set the attribute.  We'll get at
1176 	 it later with lookup_attribute.  */
1177     }
1178   else
1179     {
1180       warning (OPT_Wattributes, "%qE attribute ignored", name);
1181       *no_add_attrs = true;
1182     }
1183 
1184   return NULL_TREE;
1185 }
1186 
1187 /* Handle a "leaf" attribute; arguments as in
1188    struct attribute_spec.handler.  */
1189 
1190 static tree
handle_leaf_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)1191 handle_leaf_attribute (tree *node, tree name,
1192 		       tree ARG_UNUSED (args),
1193 		       int ARG_UNUSED (flags), bool *no_add_attrs)
1194 {
1195   if (TREE_CODE (*node) != FUNCTION_DECL)
1196     {
1197       warning (OPT_Wattributes, "%qE attribute ignored", name);
1198       *no_add_attrs = true;
1199     }
1200   if (!TREE_PUBLIC (*node))
1201     {
1202       warning (OPT_Wattributes, "%qE attribute has no effect on unit local "
1203 	       "functions", name);
1204       *no_add_attrs = true;
1205     }
1206 
1207   return NULL_TREE;
1208 }
1209 
1210 /* Handle an "artificial" attribute; arguments as in
1211    struct attribute_spec.handler.  */
1212 
1213 static tree
handle_artificial_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)1214 handle_artificial_attribute (tree *node, tree name,
1215 			     tree ARG_UNUSED (args),
1216 			     int ARG_UNUSED (flags),
1217 			     bool *no_add_attrs)
1218 {
1219   if (TREE_CODE (*node) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (*node))
1220     {
1221       /* Do nothing else, just set the attribute.  We'll get at
1222 	 it later with lookup_attribute.  */
1223     }
1224   else
1225     {
1226       warning (OPT_Wattributes, "%qE attribute ignored", name);
1227       *no_add_attrs = true;
1228     }
1229 
1230   return NULL_TREE;
1231 }
1232 
1233 /* Handle a "flatten" attribute; arguments as in
1234    struct attribute_spec.handler.  */
1235 
1236 static tree
handle_flatten_attribute(tree * node,tree name,tree args ATTRIBUTE_UNUSED,int flags ATTRIBUTE_UNUSED,bool * no_add_attrs)1237 handle_flatten_attribute (tree *node, tree name,
1238 			  tree args ATTRIBUTE_UNUSED,
1239 			  int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
1240 {
1241   if (TREE_CODE (*node) == FUNCTION_DECL)
1242     /* Do nothing else, just set the attribute.  We'll get at
1243        it later with lookup_attribute.  */
1244     ;
1245   else
1246     {
1247       warning (OPT_Wattributes, "%qE attribute ignored", name);
1248       *no_add_attrs = true;
1249     }
1250 
1251   return NULL_TREE;
1252 }
1253 
1254 /* Handle a "warning" or "error" attribute; arguments as in
1255    struct attribute_spec.handler.  */
1256 
1257 static tree
handle_error_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)1258 handle_error_attribute (tree *node, tree name, tree args,
1259 			int ARG_UNUSED (flags), bool *no_add_attrs)
1260 {
1261   if (TREE_CODE (*node) == FUNCTION_DECL
1262       && TREE_CODE (TREE_VALUE (args)) == STRING_CST)
1263     /* Do nothing else, just set the attribute.  We'll get at
1264        it later with lookup_attribute.  */
1265     ;
1266   else
1267     {
1268       warning (OPT_Wattributes, "%qE attribute ignored", name);
1269       *no_add_attrs = true;
1270     }
1271 
1272   return NULL_TREE;
1273 }
1274 
1275 /* Handle a "used" attribute; arguments as in
1276    struct attribute_spec.handler.  */
1277 
1278 static tree
handle_used_attribute(tree * pnode,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)1279 handle_used_attribute (tree *pnode, tree name, tree ARG_UNUSED (args),
1280 		       int ARG_UNUSED (flags), bool *no_add_attrs)
1281 {
1282   tree node = *pnode;
1283 
1284   if (TREE_CODE (node) == FUNCTION_DECL
1285       || (VAR_P (node) && TREE_STATIC (node))
1286       || (TREE_CODE (node) == TYPE_DECL))
1287     {
1288       TREE_USED (node) = 1;
1289       DECL_PRESERVE_P (node) = 1;
1290       if (VAR_P (node))
1291 	DECL_READ_P (node) = 1;
1292     }
1293   else
1294     {
1295       warning (OPT_Wattributes, "%qE attribute ignored", name);
1296       *no_add_attrs = true;
1297     }
1298 
1299   return NULL_TREE;
1300 }
1301 
1302 /* Handle a "unused" attribute; arguments as in
1303    struct attribute_spec.handler.  */
1304 
1305 tree
handle_unused_attribute(tree * node,tree name,tree ARG_UNUSED (args),int flags,bool * no_add_attrs)1306 handle_unused_attribute (tree *node, tree name, tree ARG_UNUSED (args),
1307 			 int flags, bool *no_add_attrs)
1308 {
1309   if (DECL_P (*node))
1310     {
1311       tree decl = *node;
1312 
1313       if (TREE_CODE (decl) == PARM_DECL
1314 	  || VAR_OR_FUNCTION_DECL_P (decl)
1315 	  || TREE_CODE (decl) == LABEL_DECL
1316 	  || TREE_CODE (decl) == CONST_DECL
1317 	  || TREE_CODE (decl) == TYPE_DECL)
1318 	{
1319 	  TREE_USED (decl) = 1;
1320 	  if (VAR_P (decl) || TREE_CODE (decl) == PARM_DECL)
1321 	    DECL_READ_P (decl) = 1;
1322 	}
1323       else
1324 	{
1325 	  warning (OPT_Wattributes, "%qE attribute ignored", name);
1326 	  *no_add_attrs = true;
1327 	}
1328     }
1329   else
1330     {
1331       if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
1332 	*node = build_variant_type_copy (*node);
1333       TREE_USED (*node) = 1;
1334     }
1335 
1336   return NULL_TREE;
1337 }
1338 
1339 /* Handle a "externally_visible" attribute; arguments as in
1340    struct attribute_spec.handler.  */
1341 
1342 static tree
handle_externally_visible_attribute(tree * pnode,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)1343 handle_externally_visible_attribute (tree *pnode, tree name,
1344 				     tree ARG_UNUSED (args),
1345 				     int ARG_UNUSED (flags),
1346 				     bool *no_add_attrs)
1347 {
1348   tree node = *pnode;
1349 
1350   if (VAR_OR_FUNCTION_DECL_P (node))
1351     {
1352       if ((!TREE_STATIC (node) && TREE_CODE (node) != FUNCTION_DECL
1353 	   && !DECL_EXTERNAL (node)) || !TREE_PUBLIC (node))
1354 	{
1355 	  warning (OPT_Wattributes,
1356 		   "%qE attribute have effect only on public objects", name);
1357 	  *no_add_attrs = true;
1358 	}
1359     }
1360   else
1361     {
1362       warning (OPT_Wattributes, "%qE attribute ignored", name);
1363       *no_add_attrs = true;
1364     }
1365 
1366   return NULL_TREE;
1367 }
1368 
1369 /* Handle the "no_reorder" attribute.  Arguments as in
1370    struct attribute_spec.handler.  */
1371 
1372 static tree
handle_no_reorder_attribute(tree * pnode,tree name,tree,int,bool * no_add_attrs)1373 handle_no_reorder_attribute (tree *pnode,
1374 			     tree name,
1375 			     tree,
1376 			     int,
1377 			     bool *no_add_attrs)
1378 {
1379   tree node = *pnode;
1380 
1381   if (!VAR_OR_FUNCTION_DECL_P (node)
1382 	&& !(TREE_STATIC (node) || DECL_EXTERNAL (node)))
1383     {
1384       warning (OPT_Wattributes,
1385 		"%qE attribute only affects top level objects",
1386 		name);
1387       *no_add_attrs = true;
1388     }
1389 
1390   return NULL_TREE;
1391 }
1392 
1393 /* Handle a "const" attribute; arguments as in
1394    struct attribute_spec.handler.  */
1395 
1396 static tree
handle_const_attribute(tree * node,tree name,tree ARG_UNUSED (args),int flags,bool * no_add_attrs)1397 handle_const_attribute (tree *node, tree name, tree ARG_UNUSED (args),
1398 			int flags, bool *no_add_attrs)
1399 {
1400   tree type = TREE_TYPE (*node);
1401 
1402   /* See FIXME comment on noreturn in c_common_attribute_table.  */
1403   if (TREE_CODE (*node) == FUNCTION_DECL)
1404     TREE_READONLY (*node) = 1;
1405   else if (TREE_CODE (type) == POINTER_TYPE
1406 	   && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
1407     TREE_TYPE (*node)
1408       = (build_qualified_type
1409 	 (build_pointer_type
1410 	  (build_type_variant (TREE_TYPE (type), 1,
1411 			       TREE_THIS_VOLATILE (TREE_TYPE (type)))),
1412 	  TYPE_QUALS (type)));
1413   else
1414     {
1415       warning (OPT_Wattributes, "%qE attribute ignored", name);
1416       *no_add_attrs = true;
1417     }
1418 
1419   /* void __builtin_unreachable(void) is const.  Accept other such
1420      built-ins but warn on user-defined functions that return void.  */
1421   if (!(flags & ATTR_FLAG_BUILT_IN)
1422       && TREE_CODE (*node) == FUNCTION_DECL
1423       && VOID_TYPE_P (TREE_TYPE (type)))
1424     warning (OPT_Wattributes, "%qE attribute on function "
1425 	     "returning %<void%>", name);
1426 
1427   return NULL_TREE;
1428 }
1429 
1430 /* Handle a "scalar_storage_order" attribute; arguments as in
1431    struct attribute_spec.handler.  */
1432 
1433 static tree
handle_scalar_storage_order_attribute(tree * node,tree name,tree args,int flags,bool * no_add_attrs)1434 handle_scalar_storage_order_attribute (tree *node, tree name, tree args,
1435 				       int flags, bool *no_add_attrs)
1436 {
1437   tree id = TREE_VALUE (args);
1438   tree type;
1439 
1440   if (TREE_CODE (*node) == TYPE_DECL
1441       && ! (flags & ATTR_FLAG_CXX11))
1442     node = &TREE_TYPE (*node);
1443   type = *node;
1444 
1445   if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
1446     {
1447       error ("%qE attribute is not supported because endianness is not uniform",
1448 	     name);
1449       return NULL_TREE;
1450     }
1451 
1452   if (RECORD_OR_UNION_TYPE_P (type) && !c_dialect_cxx ())
1453     {
1454       bool reverse = false;
1455 
1456       if (TREE_CODE (id) == STRING_CST
1457 	  && strcmp (TREE_STRING_POINTER (id), "big-endian") == 0)
1458 	reverse = !BYTES_BIG_ENDIAN;
1459       else if (TREE_CODE (id) == STRING_CST
1460 	       && strcmp (TREE_STRING_POINTER (id), "little-endian") == 0)
1461 	reverse = BYTES_BIG_ENDIAN;
1462       else
1463 	{
1464 	  error ("attribute %qE argument must be one of %qs or %qs",
1465 		 name, "big-endian", "little-endian");
1466 	  return NULL_TREE;
1467 	}
1468 
1469       if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
1470 	{
1471 	  if (reverse)
1472 	    /* A type variant isn't good enough, since we don't want a cast
1473 	       to such a type to be removed as a no-op.  */
1474 	    *node = type = build_duplicate_type (type);
1475 	}
1476 
1477       TYPE_REVERSE_STORAGE_ORDER (type) = reverse;
1478       return NULL_TREE;
1479     }
1480 
1481   warning (OPT_Wattributes, "%qE attribute ignored", name);
1482   *no_add_attrs = true;
1483   return NULL_TREE;
1484 }
1485 
1486 /* Handle a "transparent_union" attribute; arguments as in
1487    struct attribute_spec.handler.  */
1488 
1489 static tree
handle_transparent_union_attribute(tree * node,tree name,tree ARG_UNUSED (args),int flags,bool * no_add_attrs)1490 handle_transparent_union_attribute (tree *node, tree name,
1491 				    tree ARG_UNUSED (args), int flags,
1492 				    bool *no_add_attrs)
1493 {
1494   tree type;
1495 
1496   *no_add_attrs = true;
1497 
1498   if (TREE_CODE (*node) == TYPE_DECL
1499       && ! (flags & ATTR_FLAG_CXX11))
1500     node = &TREE_TYPE (*node);
1501   type = *node;
1502 
1503   if (TREE_CODE (type) == UNION_TYPE)
1504     {
1505       /* Make sure that the first field will work for a transparent union.
1506 	 If the type isn't complete yet, leave the check to the code in
1507 	 finish_struct.  */
1508       if (TYPE_SIZE (type))
1509 	{
1510 	  tree first = first_field (type);
1511 	  if (first == NULL_TREE
1512 	      || DECL_ARTIFICIAL (first)
1513 	      || TYPE_MODE (type) != DECL_MODE (first))
1514 	    goto ignored;
1515 	}
1516 
1517       if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
1518 	{
1519 	  /* If the type isn't complete yet, setting the flag
1520 	     on a variant wouldn't ever be checked.  */
1521 	  if (!TYPE_SIZE (type))
1522 	    goto ignored;
1523 
1524 	  /* build_duplicate_type doesn't work for C++.  */
1525 	  if (c_dialect_cxx ())
1526 	    goto ignored;
1527 
1528 	  /* A type variant isn't good enough, since we don't want a cast
1529 	     to such a type to be removed as a no-op.  */
1530 	  *node = type = build_duplicate_type (type);
1531 	}
1532 
1533       for (tree t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
1534 	TYPE_TRANSPARENT_AGGR (t) = 1;
1535       return NULL_TREE;
1536     }
1537 
1538  ignored:
1539   warning (OPT_Wattributes, "%qE attribute ignored", name);
1540   return NULL_TREE;
1541 }
1542 
1543 /* Subroutine of handle_{con,de}structor_attribute.  Evaluate ARGS to
1544    get the requested priority for a constructor or destructor,
1545    possibly issuing diagnostics for invalid or reserved
1546    priorities.  */
1547 
1548 static priority_type
get_priority(tree args,bool is_destructor)1549 get_priority (tree args, bool is_destructor)
1550 {
1551   HOST_WIDE_INT pri;
1552   tree arg;
1553 
1554   if (!args)
1555     return DEFAULT_INIT_PRIORITY;
1556 
1557   if (!SUPPORTS_INIT_PRIORITY)
1558     {
1559       if (is_destructor)
1560 	error ("destructor priorities are not supported");
1561       else
1562 	error ("constructor priorities are not supported");
1563       return DEFAULT_INIT_PRIORITY;
1564     }
1565 
1566   arg = TREE_VALUE (args);
1567   if (TREE_CODE (arg) == IDENTIFIER_NODE)
1568     goto invalid;
1569   if (arg == error_mark_node)
1570     return DEFAULT_INIT_PRIORITY;
1571   arg = default_conversion (arg);
1572   if (!tree_fits_shwi_p (arg)
1573       || !INTEGRAL_TYPE_P (TREE_TYPE (arg)))
1574     goto invalid;
1575 
1576   pri = tree_to_shwi (arg);
1577   if (pri < 0 || pri > MAX_INIT_PRIORITY)
1578     goto invalid;
1579 
1580   if (pri <= MAX_RESERVED_INIT_PRIORITY)
1581     {
1582       if (is_destructor)
1583 	warning (OPT_Wprio_ctor_dtor,
1584 		 "destructor priorities from 0 to %d are reserved "
1585 		 "for the implementation",
1586 		 MAX_RESERVED_INIT_PRIORITY);
1587       else
1588 	warning (OPT_Wprio_ctor_dtor,
1589 		 "constructor priorities from 0 to %d are reserved "
1590 		 "for the implementation",
1591 		 MAX_RESERVED_INIT_PRIORITY);
1592     }
1593   return pri;
1594 
1595  invalid:
1596   if (is_destructor)
1597     error ("destructor priorities must be integers from 0 to %d inclusive",
1598 	   MAX_INIT_PRIORITY);
1599   else
1600     error ("constructor priorities must be integers from 0 to %d inclusive",
1601 	   MAX_INIT_PRIORITY);
1602   return DEFAULT_INIT_PRIORITY;
1603 }
1604 
1605 /* Handle a "constructor" attribute; arguments as in
1606    struct attribute_spec.handler.  */
1607 
1608 static tree
handle_constructor_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)1609 handle_constructor_attribute (tree *node, tree name, tree args,
1610 			      int ARG_UNUSED (flags),
1611 			      bool *no_add_attrs)
1612 {
1613   tree decl = *node;
1614   tree type = TREE_TYPE (decl);
1615 
1616   if (TREE_CODE (decl) == FUNCTION_DECL
1617       && TREE_CODE (type) == FUNCTION_TYPE
1618       && decl_function_context (decl) == 0)
1619     {
1620       priority_type priority;
1621       DECL_STATIC_CONSTRUCTOR (decl) = 1;
1622       priority = get_priority (args, /*is_destructor=*/false);
1623       SET_DECL_INIT_PRIORITY (decl, priority);
1624       TREE_USED (decl) = 1;
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 a "destructor" attribute; arguments as in
1636    struct attribute_spec.handler.  */
1637 
1638 static tree
handle_destructor_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)1639 handle_destructor_attribute (tree *node, tree name, tree args,
1640 			     int ARG_UNUSED (flags),
1641 			     bool *no_add_attrs)
1642 {
1643   tree decl = *node;
1644   tree type = TREE_TYPE (decl);
1645 
1646   if (TREE_CODE (decl) == FUNCTION_DECL
1647       && TREE_CODE (type) == FUNCTION_TYPE
1648       && decl_function_context (decl) == 0)
1649     {
1650       priority_type priority;
1651       DECL_STATIC_DESTRUCTOR (decl) = 1;
1652       priority = get_priority (args, /*is_destructor=*/true);
1653       SET_DECL_FINI_PRIORITY (decl, priority);
1654       TREE_USED (decl) = 1;
1655     }
1656   else
1657     {
1658       warning (OPT_Wattributes, "%qE attribute ignored", name);
1659       *no_add_attrs = true;
1660     }
1661 
1662   return NULL_TREE;
1663 }
1664 
1665 /* Nonzero if the mode is a valid vector mode for this architecture.
1666    This returns nonzero even if there is no hardware support for the
1667    vector mode, but we can emulate with narrower modes.  */
1668 
1669 static bool
vector_mode_valid_p(machine_mode mode)1670 vector_mode_valid_p (machine_mode mode)
1671 {
1672   enum mode_class mclass = GET_MODE_CLASS (mode);
1673 
1674   /* Doh!  What's going on?  */
1675   if (mclass != MODE_VECTOR_INT
1676       && mclass != MODE_VECTOR_FLOAT
1677       && mclass != MODE_VECTOR_FRACT
1678       && mclass != MODE_VECTOR_UFRACT
1679       && mclass != MODE_VECTOR_ACCUM
1680       && mclass != MODE_VECTOR_UACCUM)
1681     return false;
1682 
1683   /* Hardware support.  Woo hoo!  */
1684   if (targetm.vector_mode_supported_p (mode))
1685     return true;
1686 
1687   /* We should probably return 1 if requesting V4DI and we have no DI,
1688      but we have V2DI, but this is probably very unlikely.  */
1689 
1690   /* If we have support for the inner mode, we can safely emulate it.
1691      We may not have V2DI, but me can emulate with a pair of DIs.  */
1692   return targetm.scalar_mode_supported_p (GET_MODE_INNER (mode));
1693 }
1694 
1695 
1696 /* Handle a "mode" attribute; arguments as in
1697    struct attribute_spec.handler.  */
1698 
1699 static tree
handle_mode_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)1700 handle_mode_attribute (tree *node, tree name, tree args,
1701 		       int ARG_UNUSED (flags), bool *no_add_attrs)
1702 {
1703   tree type = *node;
1704   tree ident = TREE_VALUE (args);
1705 
1706   *no_add_attrs = true;
1707 
1708   if (TREE_CODE (ident) != IDENTIFIER_NODE)
1709     warning (OPT_Wattributes, "%qE attribute ignored", name);
1710   else
1711     {
1712       int j;
1713       const char *p = IDENTIFIER_POINTER (ident);
1714       int len = strlen (p);
1715       machine_mode mode = VOIDmode;
1716       tree typefm;
1717       bool valid_mode;
1718 
1719       if (len > 4 && p[0] == '_' && p[1] == '_'
1720 	  && p[len - 1] == '_' && p[len - 2] == '_')
1721 	{
1722 	  char *newp = (char *) alloca (len - 1);
1723 
1724 	  strcpy (newp, &p[2]);
1725 	  newp[len - 4] = '\0';
1726 	  p = newp;
1727 	}
1728 
1729       /* Change this type to have a type with the specified mode.
1730 	 First check for the special modes.  */
1731       if (!strcmp (p, "byte"))
1732 	mode = byte_mode;
1733       else if (!strcmp (p, "word"))
1734 	mode = word_mode;
1735       else if (!strcmp (p, "pointer"))
1736 	mode = ptr_mode;
1737       else if (!strcmp (p, "libgcc_cmp_return"))
1738 	mode = targetm.libgcc_cmp_return_mode ();
1739       else if (!strcmp (p, "libgcc_shift_count"))
1740 	mode = targetm.libgcc_shift_count_mode ();
1741       else if (!strcmp (p, "unwind_word"))
1742 	mode = targetm.unwind_word_mode ();
1743       else
1744 	for (j = 0; j < NUM_MACHINE_MODES; j++)
1745 	  if (!strcmp (p, GET_MODE_NAME (j)))
1746 	    {
1747 	      mode = (machine_mode) j;
1748 	      break;
1749 	    }
1750 
1751       if (mode == VOIDmode)
1752 	{
1753 	  error ("unknown machine mode %qE", ident);
1754 	  return NULL_TREE;
1755 	}
1756 
1757       /* Allow the target a chance to translate MODE into something supported.
1758 	 See PR86324.  */
1759       mode = targetm.translate_mode_attribute (mode);
1760 
1761       valid_mode = false;
1762       switch (GET_MODE_CLASS (mode))
1763 	{
1764 	case MODE_INT:
1765 	case MODE_PARTIAL_INT:
1766 	case MODE_FLOAT:
1767 	case MODE_DECIMAL_FLOAT:
1768 	case MODE_FRACT:
1769 	case MODE_UFRACT:
1770 	case MODE_ACCUM:
1771 	case MODE_UACCUM:
1772 	  valid_mode
1773 	    = targetm.scalar_mode_supported_p (as_a <scalar_mode> (mode));
1774 	  break;
1775 
1776 	case MODE_COMPLEX_INT:
1777 	case MODE_COMPLEX_FLOAT:
1778 	  valid_mode = targetm.scalar_mode_supported_p (GET_MODE_INNER (mode));
1779 	  break;
1780 
1781 	case MODE_VECTOR_INT:
1782 	case MODE_VECTOR_FLOAT:
1783 	case MODE_VECTOR_FRACT:
1784 	case MODE_VECTOR_UFRACT:
1785 	case MODE_VECTOR_ACCUM:
1786 	case MODE_VECTOR_UACCUM:
1787 	  warning (OPT_Wattributes, "specifying vector types with "
1788 		   "%<__attribute__ ((mode))%> is deprecated");
1789 	  inform (input_location,
1790 		  "use %<__attribute__ ((vector_size))%> instead");
1791 	  valid_mode = vector_mode_valid_p (mode);
1792 	  break;
1793 
1794 	default:
1795 	  break;
1796 	}
1797       if (!valid_mode)
1798 	{
1799 	  error ("unable to emulate %qs", p);
1800 	  return NULL_TREE;
1801 	}
1802 
1803       if (POINTER_TYPE_P (type))
1804 	{
1805 	  scalar_int_mode addr_mode;
1806 	  addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (type));
1807 	  tree (*fn)(tree, machine_mode, bool);
1808 
1809 	  if (!is_a <scalar_int_mode> (mode, &addr_mode)
1810 	      || !targetm.addr_space.valid_pointer_mode (addr_mode, as))
1811 	    {
1812 	      error ("invalid pointer mode %qs", p);
1813 	      return NULL_TREE;
1814 	    }
1815 
1816 	  if (TREE_CODE (type) == POINTER_TYPE)
1817 	    fn = build_pointer_type_for_mode;
1818 	  else
1819 	    fn = build_reference_type_for_mode;
1820 	  typefm = fn (TREE_TYPE (type), addr_mode, false);
1821 	}
1822       else
1823 	{
1824 	  /* For fixed-point modes, we need to test if the signness of type
1825 	     and the machine mode are consistent.  */
1826 	  if (ALL_FIXED_POINT_MODE_P (mode)
1827 	      && TYPE_UNSIGNED (type) != UNSIGNED_FIXED_POINT_MODE_P (mode))
1828 	    {
1829 	      error ("signedness of type and machine mode %qs don%'t match", p);
1830 	      return NULL_TREE;
1831 	    }
1832 	  /* For fixed-point modes, we need to pass saturating info.  */
1833 	  typefm = lang_hooks.types.type_for_mode (mode,
1834 			ALL_FIXED_POINT_MODE_P (mode) ? TYPE_SATURATING (type)
1835 						      : TYPE_UNSIGNED (type));
1836 	}
1837 
1838       if (typefm == NULL_TREE)
1839 	{
1840 	  error ("no data type for mode %qs", p);
1841 	  return NULL_TREE;
1842 	}
1843       else if (TREE_CODE (type) == ENUMERAL_TYPE)
1844 	{
1845 	  /* For enumeral types, copy the precision from the integer
1846 	     type returned above.  If not an INTEGER_TYPE, we can't use
1847 	     this mode for this type.  */
1848 	  if (TREE_CODE (typefm) != INTEGER_TYPE)
1849 	    {
1850 	      error ("cannot use mode %qs for enumerated types", p);
1851 	      return NULL_TREE;
1852 	    }
1853 
1854 	  if (flags & ATTR_FLAG_TYPE_IN_PLACE)
1855 	    {
1856 	      TYPE_PRECISION (type) = TYPE_PRECISION (typefm);
1857 	      typefm = type;
1858 	    }
1859 	  else
1860 	    {
1861 	      /* We cannot build a type variant, as there's code that assumes
1862 		 that TYPE_MAIN_VARIANT has the same mode.  This includes the
1863 		 debug generators.  Instead, create a subrange type.  This
1864 		 results in all of the enumeral values being emitted only once
1865 		 in the original, and the subtype gets them by reference.  */
1866 	      if (TYPE_UNSIGNED (type))
1867 		typefm = make_unsigned_type (TYPE_PRECISION (typefm));
1868 	      else
1869 		typefm = make_signed_type (TYPE_PRECISION (typefm));
1870 	      TREE_TYPE (typefm) = type;
1871 	    }
1872 	  *no_add_attrs = false;
1873 	}
1874       else if (VECTOR_MODE_P (mode)
1875 	       ? TREE_CODE (type) != TREE_CODE (TREE_TYPE (typefm))
1876 	       : TREE_CODE (type) != TREE_CODE (typefm))
1877 	{
1878 	  error ("mode %qs applied to inappropriate type", p);
1879 	  return NULL_TREE;
1880 	}
1881 
1882       *node = build_qualified_type (typefm, TYPE_QUALS (type));
1883     }
1884 
1885   return NULL_TREE;
1886 }
1887 
1888 /* Handle a "section" attribute; arguments as in
1889    struct attribute_spec.handler.  */
1890 
1891 static tree
handle_section_attribute(tree * node,tree ARG_UNUSED (name),tree args,int ARG_UNUSED (flags),bool * no_add_attrs)1892 handle_section_attribute (tree *node, tree ARG_UNUSED (name), tree args,
1893 			  int ARG_UNUSED (flags), bool *no_add_attrs)
1894 {
1895   tree decl = *node;
1896   tree res = NULL_TREE;
1897 
1898   if (!targetm_common.have_named_sections)
1899     {
1900       error_at (DECL_SOURCE_LOCATION (*node),
1901 		"section attributes are not supported for this target");
1902       goto fail;
1903     }
1904 
1905   if (!VAR_OR_FUNCTION_DECL_P (decl))
1906     {
1907       error ("section attribute not allowed for %q+D", *node);
1908       goto fail;
1909     }
1910 
1911   if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
1912     {
1913       error ("section attribute argument not a string constant");
1914       goto fail;
1915     }
1916 
1917   if (VAR_P (decl)
1918       && current_function_decl != NULL_TREE
1919       && !TREE_STATIC (decl))
1920     {
1921       error_at (DECL_SOURCE_LOCATION (decl),
1922 		"section attribute cannot be specified for local variables");
1923       goto fail;
1924     }
1925 
1926   /* The decl may have already been given a section attribute
1927      from a previous declaration.  Ensure they match.  */
1928   if (DECL_SECTION_NAME (decl) != NULL
1929       && strcmp (DECL_SECTION_NAME (decl),
1930 		 TREE_STRING_POINTER (TREE_VALUE (args))) != 0)
1931     {
1932       error ("section of %q+D conflicts with previous declaration", *node);
1933       goto fail;
1934     }
1935 
1936   if (VAR_P (decl)
1937       && !targetm.have_tls && targetm.emutls.tmpl_section
1938       && DECL_THREAD_LOCAL_P (decl))
1939     {
1940       error ("section of %q+D cannot be overridden", *node);
1941       goto fail;
1942     }
1943 
1944   res = targetm.handle_generic_attribute (node, name, args, flags,
1945 					  no_add_attrs);
1946 
1947   /* If the back end confirms the attribute can be added then continue onto
1948      final processing.  */
1949   if (!(*no_add_attrs))
1950     {
1951       set_decl_section_name (decl, TREE_STRING_POINTER (TREE_VALUE (args)));
1952       return res;
1953     }
1954 
1955 fail:
1956   *no_add_attrs = true;
1957   return res;
1958 }
1959 
1960 /* Common codes shared by handle_warn_if_not_aligned_attribute and
1961    handle_aligned_attribute.  */
1962 
1963 static tree
common_handle_aligned_attribute(tree * node,tree name,tree args,int flags,bool * no_add_attrs,bool warn_if_not_aligned_p)1964 common_handle_aligned_attribute (tree *node, tree name, tree args, int flags,
1965 				 bool *no_add_attrs,
1966 				 bool warn_if_not_aligned_p)
1967 {
1968   tree decl = NULL_TREE;
1969   tree *type = NULL;
1970   bool is_type = false;
1971   tree align_expr;
1972 
1973   /* The last (already pushed) declaration with all validated attributes
1974      merged in or the current about-to-be-pushed one if one hasn't been
1975      yet.  */
1976   tree last_decl = node[1] ? node[1] : *node;
1977 
1978   if (args)
1979     {
1980       align_expr = TREE_VALUE (args);
1981       if (align_expr && TREE_CODE (align_expr) != IDENTIFIER_NODE
1982 	  && TREE_CODE (align_expr) != FUNCTION_DECL)
1983 	align_expr = default_conversion (align_expr);
1984     }
1985   else
1986     align_expr = size_int (ATTRIBUTE_ALIGNED_VALUE / BITS_PER_UNIT);
1987 
1988   if (DECL_P (*node))
1989     {
1990       decl = *node;
1991       type = &TREE_TYPE (decl);
1992       is_type = TREE_CODE (*node) == TYPE_DECL;
1993     }
1994   else if (TYPE_P (*node))
1995     type = node, is_type = true;
1996 
1997   /* True to consider invalid alignments greater than MAX_OFILE_ALIGNMENT.  */
1998   bool objfile = (TREE_CODE (*node) == FUNCTION_DECL
1999 		  || (VAR_P (*node) && TREE_STATIC (*node)));
2000   /* Log2 of specified alignment.  */
2001   int pow2align = check_user_alignment (align_expr, objfile,
2002 					/* warn_zero = */ true);
2003   if (pow2align == -1)
2004     {
2005       *no_add_attrs = true;
2006       return NULL_TREE;
2007     }
2008 
2009   /* The alignment in bits corresponding to the specified alignment.  */
2010   unsigned bitalign = (1U << pow2align) * BITS_PER_UNIT;
2011 
2012   /* The alignment of the current declaration and that of the last
2013      pushed declaration, determined on demand below.  */
2014   unsigned curalign = 0;
2015   unsigned lastalign = 0;
2016 
2017   /* True when SET_DECL_ALIGN() should be called for the decl when
2018      *NO_ADD_ATTRS is false.  */
2019   bool set_align = true;
2020   if (is_type)
2021     {
2022       if ((flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
2023 	/* OK, modify the type in place.  */;
2024       /* If we have a TYPE_DECL, then copy the type, so that we
2025 	 don't accidentally modify a builtin type.  See pushdecl.  */
2026       else if (decl && TREE_TYPE (decl) != error_mark_node
2027 	       && DECL_ORIGINAL_TYPE (decl) == NULL_TREE)
2028 	{
2029 	  tree tt = TREE_TYPE (decl);
2030 	  *type = build_variant_type_copy (*type);
2031 	  DECL_ORIGINAL_TYPE (decl) = tt;
2032 	  TYPE_NAME (*type) = decl;
2033 	  TREE_USED (*type) = TREE_USED (decl);
2034 	  TREE_TYPE (decl) = *type;
2035 	}
2036       else
2037 	*type = build_variant_type_copy (*type);
2038 
2039       if (warn_if_not_aligned_p)
2040 	{
2041 	  SET_TYPE_WARN_IF_NOT_ALIGN (*type, bitalign);
2042 	  warn_if_not_aligned_p = false;
2043 	}
2044       else
2045 	{
2046 	  SET_TYPE_ALIGN (*type, bitalign);
2047 	  TYPE_USER_ALIGN (*type) = 1;
2048 	}
2049     }
2050   else if (! VAR_OR_FUNCTION_DECL_P (decl)
2051 	   && TREE_CODE (decl) != FIELD_DECL)
2052     {
2053       error ("alignment may not be specified for %q+D", decl);
2054       *no_add_attrs = true;
2055     }
2056   else if (TREE_CODE (decl) == FUNCTION_DECL
2057 	   && ((curalign = DECL_ALIGN (decl)) > bitalign
2058 	       || ((lastalign = DECL_ALIGN (last_decl)) > bitalign)))
2059     {
2060       /* Either a prior attribute on the same declaration or one
2061 	 on a prior declaration of the same function specifies
2062 	 stricter alignment than this attribute.  */
2063       bool note = lastalign != 0;
2064       if (lastalign)
2065 	curalign = lastalign;
2066 
2067       curalign /= BITS_PER_UNIT;
2068       unsigned newalign = bitalign / BITS_PER_UNIT;
2069 
2070       auto_diagnostic_group d;
2071       if ((DECL_USER_ALIGN (decl)
2072 	   || DECL_USER_ALIGN (last_decl)))
2073 	{
2074 	  if (warning (OPT_Wattributes,
2075 		       "ignoring attribute %<%E (%u)%> because it conflicts "
2076 		       "with attribute %<%E (%u)%>",
2077 		       name, newalign, name, curalign)
2078 	      && note)
2079 	    inform (DECL_SOURCE_LOCATION (last_decl),
2080 		    "previous declaration here");
2081 	  /* Only reject attempts to relax/override an alignment
2082 	     explicitly specified previously and accept declarations
2083 	     that appear to relax the implicit function alignment for
2084 	     the target.  Both increasing and increasing the alignment
2085 	     set by -falign-functions setting is permitted.  */
2086 	  *no_add_attrs = true;
2087 	}
2088       else if (!warn_if_not_aligned_p)
2089 	{
2090 	  /* Do not fail for attribute warn_if_not_aligned.  Otherwise,
2091 	     silently avoid applying the alignment to the declaration
2092 	     because it's implicitly satisfied by the target.  Apply
2093 	     the attribute nevertheless so it can be retrieved by
2094 	     __builtin_has_attribute.  */
2095 	  set_align = false;
2096 	}
2097     }
2098   else if (DECL_USER_ALIGN (decl)
2099 	   && DECL_ALIGN (decl) > bitalign)
2100     /* C++-11 [dcl.align/4]:
2101 
2102 	   When multiple alignment-specifiers are specified for an
2103 	   entity, the alignment requirement shall be set to the
2104 	   strictest specified alignment.
2105 
2106       This formally comes from the c++11 specification but we are
2107       doing it for the GNU attribute syntax as well.  */
2108     *no_add_attrs = true;
2109   else if (!warn_if_not_aligned_p
2110 	   && TREE_CODE (decl) == FUNCTION_DECL
2111 	   && DECL_ALIGN (decl) > bitalign)
2112     {
2113       /* Don't warn for function alignment here if warn_if_not_aligned_p
2114 	 is true.  It will be warned about later.  */
2115       if (DECL_USER_ALIGN (decl))
2116 	{
2117 	  /* Only reject attempts to relax/override an alignment
2118 	     explicitly specified previously and accept declarations
2119 	     that appear to relax the implicit function alignment for
2120 	     the target.  Both increasing and increasing the alignment
2121 	     set by -falign-functions setting is permitted.  */
2122 	  error ("alignment for %q+D was previously specified as %d "
2123 		 "and may not be decreased", decl,
2124 		 DECL_ALIGN (decl) / BITS_PER_UNIT);
2125 	  *no_add_attrs = true;
2126 	}
2127     }
2128   else if (warn_if_not_aligned_p
2129 	   && TREE_CODE (decl) == FIELD_DECL
2130 	   && !DECL_C_BIT_FIELD (decl))
2131     {
2132       SET_DECL_WARN_IF_NOT_ALIGN (decl, bitalign);
2133       warn_if_not_aligned_p = false;
2134       set_align = false;
2135     }
2136 
2137   if (warn_if_not_aligned_p)
2138     {
2139       error ("%<warn_if_not_aligned%> may not be specified for %q+D",
2140 	     decl);
2141       *no_add_attrs = true;
2142     }
2143   else if (!is_type && !*no_add_attrs && set_align)
2144     {
2145       SET_DECL_ALIGN (decl, bitalign);
2146       DECL_USER_ALIGN (decl) = 1;
2147     }
2148 
2149   return NULL_TREE;
2150 }
2151 
2152 /* Handle a "aligned" attribute; arguments as in
2153    struct attribute_spec.handler.  */
2154 
2155 static tree
handle_aligned_attribute(tree * node,tree name,tree args,int flags,bool * no_add_attrs)2156 handle_aligned_attribute (tree *node, tree name, tree args,
2157 			  int flags, bool *no_add_attrs)
2158 {
2159   return common_handle_aligned_attribute (node, name, args, flags,
2160 					 no_add_attrs, false);
2161 }
2162 
2163 /* Handle a "warn_if_not_aligned" attribute; arguments as in
2164    struct attribute_spec.handler.  */
2165 
2166 static tree
handle_warn_if_not_aligned_attribute(tree * node,tree name,tree args,int flags,bool * no_add_attrs)2167 handle_warn_if_not_aligned_attribute (tree *node, tree name,
2168 				      tree args, int flags,
2169 				      bool *no_add_attrs)
2170 {
2171   return common_handle_aligned_attribute (node, name, args, flags,
2172 					  no_add_attrs, true);
2173 }
2174 
2175 /* Handle a "weak" attribute; arguments as in
2176    struct attribute_spec.handler.  */
2177 
2178 static tree
handle_weak_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))2179 handle_weak_attribute (tree *node, tree name,
2180 		       tree ARG_UNUSED (args),
2181 		       int ARG_UNUSED (flags),
2182 		       bool * ARG_UNUSED (no_add_attrs))
2183 {
2184   if (TREE_CODE (*node) == FUNCTION_DECL
2185       && DECL_DECLARED_INLINE_P (*node))
2186     {
2187       warning (OPT_Wattributes, "inline function %q+D declared weak", *node);
2188       *no_add_attrs = true;
2189     }
2190   else if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (*node)))
2191     {
2192       error ("indirect function %q+D cannot be declared weak", *node);
2193       *no_add_attrs = true;
2194       return NULL_TREE;
2195     }
2196   else if (VAR_OR_FUNCTION_DECL_P (*node))
2197     declare_weak (*node);
2198   else
2199     warning (OPT_Wattributes, "%qE attribute ignored", name);
2200 
2201   return NULL_TREE;
2202 }
2203 
2204 /* Handle a "noinit" attribute; arguments as in struct
2205    attribute_spec.handler.  Check whether the attribute is allowed
2206    here and add the attribute to the variable decl tree or otherwise
2207    issue a diagnostic.  This function checks NODE is of the expected
2208    type and issues diagnostics otherwise using NAME.  If it is not of
2209    the expected type *NO_ADD_ATTRS will be set to true.  */
2210 
2211 static tree
handle_noinit_attribute(tree * node,tree name,tree args,int flags ATTRIBUTE_UNUSED,bool * no_add_attrs)2212 handle_noinit_attribute (tree * node,
2213 		  tree   name,
2214 		  tree   args,
2215 		  int    flags ATTRIBUTE_UNUSED,
2216 		  bool *no_add_attrs)
2217 {
2218   const char *message = NULL;
2219   tree res = NULL_TREE;
2220 
2221   gcc_assert (DECL_P (*node));
2222   gcc_assert (args == NULL);
2223 
2224   if (TREE_CODE (*node) != VAR_DECL)
2225     message = G_("%qE attribute only applies to variables");
2226 
2227   /* Check that it's possible for the variable to have a section.  */
2228   else if ((TREE_STATIC (*node) || DECL_EXTERNAL (*node) || in_lto_p)
2229 	   && DECL_SECTION_NAME (*node))
2230     message = G_("%qE attribute cannot be applied to variables "
2231 		 "with specific sections");
2232 
2233   else if (!targetm.have_switchable_bss_sections)
2234     message = G_("%qE attribute is specific to ELF targets");
2235 
2236   if (message)
2237     {
2238       warning (OPT_Wattributes, message, name);
2239       *no_add_attrs = true;
2240     }
2241   else
2242     {
2243       res = targetm.handle_generic_attribute (node, name, args, flags,
2244 					      no_add_attrs);
2245       /* If the back end confirms the attribute can be added then continue onto
2246 	 final processing.  */
2247       if (!(*no_add_attrs))
2248 	{
2249 	  /* If this var is thought to be common, then change this.  Common
2250 	     variables are assigned to sections before the backend has a
2251 	     chance to process them.  Do this only if the attribute is
2252 	     valid.  */
2253 	  if (DECL_COMMON (*node))
2254 	    DECL_COMMON (*node) = 0;
2255 	}
2256     }
2257 
2258   return res;
2259 }
2260 
2261 
2262 /* Handle a "noplt" attribute; arguments as in
2263    struct attribute_spec.handler.  */
2264 
2265 static tree
handle_noplt_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))2266 handle_noplt_attribute (tree *node, tree name,
2267 		       tree ARG_UNUSED (args),
2268 		       int ARG_UNUSED (flags),
2269 		       bool * ARG_UNUSED (no_add_attrs))
2270 {
2271   if (TREE_CODE (*node) != FUNCTION_DECL)
2272     {
2273       warning (OPT_Wattributes,
2274 	       "%qE attribute is only applicable on functions", name);
2275       *no_add_attrs = true;
2276       return NULL_TREE;
2277     }
2278   return NULL_TREE;
2279 }
2280 
2281 /* Handle a "symver" attribute.  */
2282 
2283 static tree
handle_symver_attribute(tree * node,tree ARG_UNUSED (name),tree args,int ARG_UNUSED (flags),bool * no_add_attrs)2284 handle_symver_attribute (tree *node, tree ARG_UNUSED (name), tree args,
2285 			 int ARG_UNUSED (flags), bool *no_add_attrs)
2286 {
2287   tree symver;
2288   const char *symver_str;
2289 
2290   if (TREE_CODE (*node) != FUNCTION_DECL && TREE_CODE (*node) != VAR_DECL)
2291     {
2292       warning (OPT_Wattributes,
2293 	       "%<symver%> attribute only applies to functions and variables");
2294       *no_add_attrs = true;
2295       return NULL_TREE;
2296     }
2297 
2298   if (!decl_in_symtab_p (*node))
2299     {
2300       warning (OPT_Wattributes,
2301 	       "%<symver%> attribute is only applicable to symbols");
2302       *no_add_attrs = true;
2303       return NULL_TREE;
2304     }
2305 
2306   for (; args; args = TREE_CHAIN (args))
2307     {
2308       symver = TREE_VALUE (args);
2309       if (TREE_CODE (symver) != STRING_CST)
2310 	{
2311 	  error ("%<symver%> attribute argument not a string constant");
2312 	  *no_add_attrs = true;
2313 	  return NULL_TREE;
2314 	}
2315 
2316       symver_str = TREE_STRING_POINTER (symver);
2317 
2318       int ats = 0;
2319       for (int n = 0; (int)n < TREE_STRING_LENGTH (symver); n++)
2320 	if (symver_str[n] == '@')
2321 	  ats++;
2322 
2323       if (ats != 1 && ats != 2)
2324 	{
2325 	  error ("symver attribute argument must have format %<name@nodename%>");
2326 	  error ("%<symver%> attribute argument %qs must contain one or two "
2327 		 "%<@%>", symver_str);
2328 	  *no_add_attrs = true;
2329 	  return NULL_TREE;
2330 	}
2331     }
2332 
2333   return NULL_TREE;
2334 }
2335 
2336 
2337 /* Handle an "alias" or "ifunc" attribute; arguments as in
2338    struct attribute_spec.handler, except that IS_ALIAS tells us
2339    whether this is an alias as opposed to ifunc attribute.  */
2340 
2341 static tree
handle_alias_ifunc_attribute(bool is_alias,tree * node,tree name,tree args,bool * no_add_attrs)2342 handle_alias_ifunc_attribute (bool is_alias, tree *node, tree name, tree args,
2343 			      bool *no_add_attrs)
2344 {
2345   tree decl = *node;
2346 
2347   if (TREE_CODE (decl) != FUNCTION_DECL
2348       && (!is_alias || !VAR_P (decl)))
2349     {
2350       warning (OPT_Wattributes, "%qE attribute ignored", name);
2351       *no_add_attrs = true;
2352     }
2353   else if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl))
2354       || (TREE_CODE (decl) != FUNCTION_DECL
2355 	  && TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl))
2356       /* A static variable declaration is always a tentative definition,
2357 	 but the alias is a non-tentative definition which overrides.  */
2358       || (TREE_CODE (decl) != FUNCTION_DECL
2359 	  && ! TREE_PUBLIC (decl) && DECL_INITIAL (decl)))
2360     {
2361       error ("%q+D defined both normally and as %qE attribute", decl, name);
2362       *no_add_attrs = true;
2363       return NULL_TREE;
2364     }
2365   else if (!is_alias
2366 	   && (lookup_attribute ("weak", DECL_ATTRIBUTES (decl))
2367 	       || lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))))
2368     {
2369       error ("weak %q+D cannot be defined %qE", decl, name);
2370       *no_add_attrs = true;
2371       return NULL_TREE;
2372     }
2373 
2374   /* Note that the very first time we process a nested declaration,
2375      decl_function_context will not be set.  Indeed, *would* never
2376      be set except for the DECL_INITIAL/DECL_EXTERNAL frobbery that
2377      we do below.  After such frobbery, pushdecl would set the context.
2378      In any case, this is never what we want.  */
2379   else if (decl_function_context (decl) == 0 && current_function_decl == NULL)
2380     {
2381       tree id;
2382 
2383       id = TREE_VALUE (args);
2384       if (TREE_CODE (id) != STRING_CST)
2385 	{
2386 	  error ("attribute %qE argument not a string", name);
2387 	  *no_add_attrs = true;
2388 	  return NULL_TREE;
2389 	}
2390       id = get_identifier (TREE_STRING_POINTER (id));
2391       /* This counts as a use of the object pointed to.  */
2392       TREE_USED (id) = 1;
2393 
2394       if (TREE_CODE (decl) == FUNCTION_DECL)
2395 	DECL_INITIAL (decl) = error_mark_node;
2396       else
2397 	TREE_STATIC (decl) = 1;
2398 
2399       if (!is_alias)
2400 	{
2401 	  /* ifuncs are also aliases, so set that attribute too.  */
2402 	  DECL_ATTRIBUTES (decl)
2403 	    = tree_cons (get_identifier ("alias"), args,
2404 			 DECL_ATTRIBUTES (decl));
2405 	  DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("ifunc"),
2406 					      NULL, DECL_ATTRIBUTES (decl));
2407 	}
2408     }
2409   else
2410     {
2411       warning (OPT_Wattributes, "%qE attribute ignored", name);
2412       *no_add_attrs = true;
2413     }
2414 
2415   if (decl_in_symtab_p (*node))
2416     {
2417       struct symtab_node *n = symtab_node::get (decl);
2418       if (n && n->refuse_visibility_changes)
2419 	error ("%+qD declared %qs after being used",
2420 	       decl, is_alias ? "alias" : "ifunc");
2421     }
2422 
2423 
2424   return NULL_TREE;
2425 }
2426 
2427 /* Handle an "alias" or "ifunc" attribute; arguments as in
2428    struct attribute_spec.handler.  */
2429 
2430 static tree
handle_ifunc_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)2431 handle_ifunc_attribute (tree *node, tree name, tree args,
2432 			int ARG_UNUSED (flags), bool *no_add_attrs)
2433 {
2434   return handle_alias_ifunc_attribute (false, node, name, args, no_add_attrs);
2435 }
2436 
2437 /* Handle an "alias" or "ifunc" attribute; arguments as in
2438    struct attribute_spec.handler.  */
2439 
2440 static tree
handle_alias_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)2441 handle_alias_attribute (tree *node, tree name, tree args,
2442 			int ARG_UNUSED (flags), bool *no_add_attrs)
2443 {
2444   return handle_alias_ifunc_attribute (true, node, name, args, no_add_attrs);
2445 }
2446 
2447 /* Handle the "copy" attribute NAME by copying the set of attributes
2448    from the symbol referenced by ARGS to the declaration of *NODE.  */
2449 
2450 static tree
handle_copy_attribute(tree * node,tree name,tree args,int flags,bool * no_add_attrs)2451 handle_copy_attribute (tree *node, tree name, tree args,
2452 		       int flags, bool *no_add_attrs)
2453 {
2454   /* Do not apply the copy attribute itself.  It serves no purpose
2455      other than to copy other attributes.  */
2456   *no_add_attrs = true;
2457 
2458   tree decl = *node;
2459 
2460   tree ref = TREE_VALUE (args);
2461   if (ref == error_mark_node)
2462     return NULL_TREE;
2463 
2464   if (TREE_CODE (ref) == STRING_CST)
2465     {
2466       /* Explicitly handle this case since using a string literal
2467 	 as an argument is a likely mistake.  */
2468       error_at (DECL_SOURCE_LOCATION (decl),
2469 		"%qE attribute argument cannot be a string",
2470 		name);
2471       return NULL_TREE;
2472     }
2473 
2474   if (CONSTANT_CLASS_P (ref)
2475       && (INTEGRAL_TYPE_P (TREE_TYPE (ref))
2476 	  || FLOAT_TYPE_P (TREE_TYPE (ref))))
2477     {
2478       /* Similar to the string case, since some function attributes
2479 	 accept literal numbers as arguments (e.g., alloc_size or
2480 	 nonnull) using one here is a likely mistake.  */
2481       error_at (DECL_SOURCE_LOCATION (decl),
2482 		"%qE attribute argument cannot be a constant arithmetic "
2483 		"expression",
2484 		name);
2485       return NULL_TREE;
2486     }
2487 
2488   if (ref == node[1])
2489     {
2490       /* Another possible mistake (but indirect self-references aren't
2491 	 and diagnosed and shouldn't be).  */
2492       if (warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes,
2493 		      "%qE attribute ignored on a redeclaration "
2494 		      "of the referenced symbol",
2495 		      name))
2496 	inform (DECL_SOURCE_LOCATION (node[1]),
2497 		"previous declaration here");
2498       return NULL_TREE;
2499     }
2500 
2501   /* Consider address-of expressions in the attribute argument
2502      as requests to copy from the referenced entity.  */
2503   if (TREE_CODE (ref) == ADDR_EXPR)
2504     ref = TREE_OPERAND (ref, 0);
2505 
2506   do
2507     {
2508       /* Drill down into references to find the referenced decl.  */
2509       tree_code refcode = TREE_CODE (ref);
2510       if (refcode == ARRAY_REF
2511 	  || refcode == INDIRECT_REF)
2512 	ref = TREE_OPERAND (ref, 0);
2513       else if (refcode == COMPONENT_REF)
2514 	ref = TREE_OPERAND (ref, 1);
2515       else
2516 	break;
2517     } while (!DECL_P (ref));
2518 
2519   /* For object pointer expressions, consider those to be requests
2520      to copy from their type, such as in:
2521        struct __attribute__ (copy ((struct T *)0)) U { ... };
2522      which copies type attributes from struct T to the declaration
2523      of struct U.  */
2524   if ((CONSTANT_CLASS_P (ref) || EXPR_P (ref))
2525       && POINTER_TYPE_P (TREE_TYPE (ref))
2526       && !FUNCTION_POINTER_TYPE_P (TREE_TYPE (ref)))
2527     ref = TREE_TYPE (ref);
2528 
2529   tree reftype = TYPE_P (ref) ? ref : TREE_TYPE (ref);
2530 
2531   if (DECL_P (decl))
2532     {
2533       if ((VAR_P (decl)
2534 	   && (TREE_CODE (ref) == FUNCTION_DECL
2535 	       || (EXPR_P (ref)
2536 		   && POINTER_TYPE_P (reftype)
2537 		   && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (reftype)))))
2538 	  || (TREE_CODE (decl) == FUNCTION_DECL
2539 	      && (VAR_P (ref)
2540 		  || (EXPR_P (ref)
2541 		      && !FUNC_OR_METHOD_TYPE_P (reftype)
2542 		      && (!POINTER_TYPE_P (reftype)
2543 			  || !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (reftype)))))))
2544 	{
2545 	  /* It makes no sense to try to copy function attributes
2546 	     to a variable, or variable attributes to a function.  */
2547 	  if (warning (OPT_Wattributes,
2548 		       "%qE attribute ignored on a declaration of "
2549 		       "a different kind than referenced symbol",
2550 		       name)
2551 	      && DECL_P (ref))
2552 	    inform (DECL_SOURCE_LOCATION (ref),
2553 		    "symbol %qD referenced by %qD declared here", ref, decl);
2554 	  return NULL_TREE;
2555 	}
2556 
2557       tree attrs = NULL_TREE;
2558       if (DECL_P (ref))
2559 	attrs = DECL_ATTRIBUTES (ref);
2560       else if (TYPE_P (ref))
2561 	attrs = TYPE_ATTRIBUTES (ref);
2562 
2563       /* Copy decl attributes from REF to DECL.  */
2564       for (tree at = attrs; at; at = TREE_CHAIN (at))
2565 	{
2566 	  /* Avoid copying attributes that affect a symbol linkage,
2567 	     inlining, or visibility since those in all likelihood
2568 	     only apply to the target.
2569 	     FIXME: make it possible to specify which attributes to
2570 	     copy or not to copy in the copy attribute itself.  */
2571 	  tree atname = get_attribute_name (at);
2572 	  if (is_attribute_p ("alias", atname)
2573 	      || is_attribute_p ("always_inline", atname)
2574 	      || is_attribute_p ("gnu_inline", atname)
2575 	      || is_attribute_p ("ifunc", atname)
2576 	      || is_attribute_p ("noinline", atname)
2577 	      || is_attribute_p ("visibility", atname)
2578 	      || is_attribute_p ("weak", atname)
2579 	      || is_attribute_p ("weakref", atname)
2580 	      || is_attribute_p ("target_clones", atname))
2581 	    continue;
2582 
2583 	  /* Attribute leaf only applies to extern functions.
2584 	     Avoid copying it to static ones.  */
2585 	  if (!TREE_PUBLIC (decl)
2586 	      && is_attribute_p ("leaf", atname))
2587 	    continue;
2588 
2589 	  tree atargs = TREE_VALUE (at);
2590 	  /* Create a copy of just the one attribute ar AT, including
2591 	     its argumentsm and add it to DECL.  */
2592 	  tree attr = tree_cons (atname, copy_list (atargs), NULL_TREE);
2593 	  decl_attributes (node, attr, flags,  EXPR_P (ref) ? NULL_TREE : ref);
2594 	}
2595 
2596       /* Proceed to copy type attributes below.  */
2597     }
2598   else if (!TYPE_P (decl))
2599     {
2600       error_at (DECL_SOURCE_LOCATION (decl),
2601 		"%qE attribute must apply to a declaration",
2602 		name);
2603       return NULL_TREE;
2604     }
2605 
2606   /* A function declared with attribute nothrow has the attribute
2607      attached to it, but a C++ throw() function does not.  */
2608   if (TREE_NOTHROW (ref))
2609     TREE_NOTHROW (decl) = true;
2610 
2611   /* Similarly, a function declared with attribute noreturn has it
2612      attached on to it, but a C11 _Noreturn function does not.  */
2613   if (DECL_P (ref)
2614       && TREE_THIS_VOLATILE (ref)
2615       && FUNC_OR_METHOD_TYPE_P (reftype))
2616     TREE_THIS_VOLATILE (decl) = true;
2617 
2618   if (POINTER_TYPE_P (reftype))
2619     reftype = TREE_TYPE (reftype);
2620 
2621   if (!TYPE_P (reftype))
2622     return NULL_TREE;
2623 
2624   tree attrs = TYPE_ATTRIBUTES (reftype);
2625 
2626   /* Copy type attributes from REF to DECL.  Pass in REF if it's a DECL
2627      or a type but not if it's an expression.  */
2628   for (tree at = attrs; at; at = TREE_CHAIN (at))
2629     decl_attributes (node, at, flags, EXPR_P (ref) ? NULL_TREE : ref);
2630 
2631   return NULL_TREE;
2632 }
2633 
2634 /* Handle a "weakref" attribute; arguments as in struct
2635    attribute_spec.handler.  */
2636 
2637 static tree
handle_weakref_attribute(tree * node,tree name,tree args,int flags,bool * no_add_attrs)2638 handle_weakref_attribute (tree *node, tree name, tree args,
2639 			  int flags, bool *no_add_attrs)
2640 {
2641   tree attr = NULL_TREE;
2642 
2643   /* We must ignore the attribute when it is associated with
2644      local-scoped decls, since attribute alias is ignored and many
2645      such symbols do not even have a DECL_WEAK field.  */
2646   if (decl_function_context (*node)
2647       || current_function_decl
2648       || !VAR_OR_FUNCTION_DECL_P (*node))
2649     {
2650       warning (OPT_Wattributes, "%qE attribute ignored", name);
2651       *no_add_attrs = true;
2652       return NULL_TREE;
2653     }
2654 
2655   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (*node)))
2656     {
2657       error ("indirect function %q+D cannot be declared %qE",
2658 	     *node, name);
2659       *no_add_attrs = true;
2660       return NULL_TREE;
2661     }
2662 
2663   /* The idea here is that `weakref("name")' mutates into `weakref,
2664      alias("name")', and weakref without arguments, in turn,
2665      implicitly adds weak.  */
2666 
2667   if (args)
2668     {
2669       attr = tree_cons (get_identifier ("alias"), args, attr);
2670       attr = tree_cons (get_identifier ("weakref"), NULL_TREE, attr);
2671 
2672       *no_add_attrs = true;
2673 
2674       decl_attributes (node, attr, flags);
2675     }
2676   else
2677     {
2678       if (lookup_attribute ("alias", DECL_ATTRIBUTES (*node)))
2679 	error_at (DECL_SOURCE_LOCATION (*node),
2680 		  "%qE attribute must appear before %qs attribute",
2681 		  name, "alias");
2682 
2683       /* Can't call declare_weak because it wants this to be TREE_PUBLIC,
2684 	 and that isn't supported; and because it wants to add it to
2685 	 the list of weak decls, which isn't helpful.  */
2686       DECL_WEAK (*node) = 1;
2687     }
2688 
2689   if (decl_in_symtab_p (*node))
2690     {
2691       struct symtab_node *n = symtab_node::get (*node);
2692       if (n && n->refuse_visibility_changes)
2693 	error ("%+qD declared %qE after being used", *node, name);
2694     }
2695 
2696   return NULL_TREE;
2697 }
2698 
2699 /* Handle an "visibility" attribute; arguments as in
2700    struct attribute_spec.handler.  */
2701 
2702 static tree
handle_visibility_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))2703 handle_visibility_attribute (tree *node, tree name, tree args,
2704 			     int ARG_UNUSED (flags),
2705 			     bool *ARG_UNUSED (no_add_attrs))
2706 {
2707   tree decl = *node;
2708   tree id = TREE_VALUE (args);
2709   enum symbol_visibility vis;
2710 
2711   if (TYPE_P (*node))
2712     {
2713       if (TREE_CODE (*node) == ENUMERAL_TYPE)
2714 	/* OK */;
2715       else if (!RECORD_OR_UNION_TYPE_P (*node))
2716 	{
2717 	  warning (OPT_Wattributes, "%qE attribute ignored on non-class types",
2718 		   name);
2719 	  return NULL_TREE;
2720 	}
2721       else if (TYPE_FIELDS (*node))
2722 	{
2723 	  error ("%qE attribute ignored because %qT is already defined",
2724 		 name, *node);
2725 	  return NULL_TREE;
2726 	}
2727     }
2728   else if (decl_function_context (decl) != 0 || !TREE_PUBLIC (decl))
2729     {
2730       warning (OPT_Wattributes, "%qE attribute ignored", name);
2731       return NULL_TREE;
2732     }
2733 
2734   if (TREE_CODE (id) != STRING_CST)
2735     {
2736       error ("visibility argument not a string");
2737       return NULL_TREE;
2738     }
2739 
2740   /*  If this is a type, set the visibility on the type decl.  */
2741   if (TYPE_P (decl))
2742     {
2743       decl = TYPE_NAME (decl);
2744       if (!decl)
2745 	return NULL_TREE;
2746       if (TREE_CODE (decl) == IDENTIFIER_NODE)
2747 	{
2748 	   warning (OPT_Wattributes, "%qE attribute ignored on types",
2749 		    name);
2750 	   return NULL_TREE;
2751 	}
2752     }
2753 
2754   if (strcmp (TREE_STRING_POINTER (id), "default") == 0)
2755     vis = VISIBILITY_DEFAULT;
2756   else if (strcmp (TREE_STRING_POINTER (id), "internal") == 0)
2757     vis = VISIBILITY_INTERNAL;
2758   else if (strcmp (TREE_STRING_POINTER (id), "hidden") == 0)
2759     vis = VISIBILITY_HIDDEN;
2760   else if (strcmp (TREE_STRING_POINTER (id), "protected") == 0)
2761     vis = VISIBILITY_PROTECTED;
2762   else
2763     {
2764       error ("attribute %qE argument must be one of %qs, %qs, %qs, or %qs",
2765 	     name, "default", "hidden", "protected", "internal");
2766       vis = VISIBILITY_DEFAULT;
2767     }
2768 
2769   if (DECL_VISIBILITY_SPECIFIED (decl)
2770       && vis != DECL_VISIBILITY (decl))
2771     {
2772       tree attributes = (TYPE_P (*node)
2773 			 ? TYPE_ATTRIBUTES (*node)
2774 			 : DECL_ATTRIBUTES (decl));
2775       if (lookup_attribute ("visibility", attributes))
2776 	error ("%qD redeclared with different visibility", decl);
2777       else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
2778 	       && lookup_attribute ("dllimport", attributes))
2779 	error ("%qD was declared %qs which implies default visibility",
2780 	       decl, "dllimport");
2781       else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
2782 	       && lookup_attribute ("dllexport", attributes))
2783 	error ("%qD was declared %qs which implies default visibility",
2784 	       decl, "dllexport");
2785     }
2786 
2787   DECL_VISIBILITY (decl) = vis;
2788   DECL_VISIBILITY_SPECIFIED (decl) = 1;
2789 
2790   /* Go ahead and attach the attribute to the node as well.  This is needed
2791      so we can determine whether we have VISIBILITY_DEFAULT because the
2792      visibility was not specified, or because it was explicitly overridden
2793      from the containing scope.  */
2794 
2795   return NULL_TREE;
2796 }
2797 
2798 /* Handle an "tls_model" attribute; arguments as in
2799    struct attribute_spec.handler.  */
2800 
2801 static tree
handle_tls_model_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * ARG_UNUSED (no_add_attrs))2802 handle_tls_model_attribute (tree *node, tree name, tree args,
2803 			    int ARG_UNUSED (flags),
2804 			    bool *ARG_UNUSED (no_add_attrs))
2805 {
2806   tree id;
2807   tree decl = *node;
2808   enum tls_model kind;
2809 
2810   if (!VAR_P (decl))
2811     {
2812       warning (OPT_Wattributes, "%qE attribute ignored because %qD "
2813 	       "is not a variable",
2814 	       name, decl);
2815       return NULL_TREE;
2816     }
2817 
2818   if (!DECL_THREAD_LOCAL_P (decl))
2819     {
2820       warning (OPT_Wattributes, "%qE attribute ignored because %qD does "
2821 	       "not have thread storage duration", name, decl);
2822       return NULL_TREE;
2823     }
2824 
2825   kind = DECL_TLS_MODEL (decl);
2826   id = TREE_VALUE (args);
2827   if (TREE_CODE (id) != STRING_CST)
2828     {
2829       error ("%qE argument not a string", name);
2830       return NULL_TREE;
2831     }
2832 
2833   if (!strcmp (TREE_STRING_POINTER (id), "local-exec"))
2834     kind = TLS_MODEL_LOCAL_EXEC;
2835   else if (!strcmp (TREE_STRING_POINTER (id), "initial-exec"))
2836     kind = TLS_MODEL_INITIAL_EXEC;
2837   else if (!strcmp (TREE_STRING_POINTER (id), "local-dynamic"))
2838     kind = optimize ? TLS_MODEL_LOCAL_DYNAMIC : TLS_MODEL_GLOBAL_DYNAMIC;
2839   else if (!strcmp (TREE_STRING_POINTER (id), "global-dynamic"))
2840     kind = TLS_MODEL_GLOBAL_DYNAMIC;
2841   else
2842     error ("%qE argument must be one of %qs, %qs, %qs, or %qs",
2843 	   name,
2844 	   "local-exec", "initial-exec", "local-dynamic", "global-dynamic");
2845 
2846   set_decl_tls_model (decl, kind);
2847   return NULL_TREE;
2848 }
2849 
2850 /* Handle a "no_instrument_function" attribute; arguments as in
2851    struct attribute_spec.handler.  */
2852 
2853 static tree
handle_no_instrument_function_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)2854 handle_no_instrument_function_attribute (tree *node, tree name,
2855 					 tree ARG_UNUSED (args),
2856 					 int ARG_UNUSED (flags),
2857 					 bool *no_add_attrs)
2858 {
2859   tree decl = *node;
2860 
2861   if (TREE_CODE (decl) != FUNCTION_DECL)
2862     {
2863       error_at (DECL_SOURCE_LOCATION (decl),
2864 		"%qE attribute applies only to functions", name);
2865       *no_add_attrs = true;
2866     }
2867   else
2868     DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
2869 
2870   return NULL_TREE;
2871 }
2872 
2873 /* Handle a "no_profile_instrument_function" attribute; arguments as in
2874    struct attribute_spec.handler.  */
2875 
2876 static tree
handle_no_profile_instrument_function_attribute(tree * node,tree name,tree,int,bool * no_add_attrs)2877 handle_no_profile_instrument_function_attribute (tree *node, tree name, tree,
2878 						 int, bool *no_add_attrs)
2879 {
2880   if (TREE_CODE (*node) != FUNCTION_DECL)
2881     {
2882       warning (OPT_Wattributes, "%qE attribute ignored", name);
2883       *no_add_attrs = true;
2884     }
2885 
2886   return NULL_TREE;
2887 }
2888 
2889 /* Handle a "malloc" attribute; arguments as in
2890    struct attribute_spec.handler.  */
2891 
2892 static tree
handle_malloc_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)2893 handle_malloc_attribute (tree *node, tree name, tree ARG_UNUSED (args),
2894 			 int ARG_UNUSED (flags), bool *no_add_attrs)
2895 {
2896   if (TREE_CODE (*node) == FUNCTION_DECL
2897       && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*node))))
2898     DECL_IS_MALLOC (*node) = 1;
2899   else
2900     {
2901       warning (OPT_Wattributes, "%qE attribute ignored", name);
2902       *no_add_attrs = true;
2903     }
2904 
2905   return NULL_TREE;
2906 }
2907 
2908 /* Handle a "alloc_size" attribute; arguments as in
2909    struct attribute_spec.handler.  */
2910 
2911 static tree
handle_alloc_size_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)2912 handle_alloc_size_attribute (tree *node, tree name, tree args,
2913 			     int ARG_UNUSED (flags), bool *no_add_attrs)
2914 {
2915   tree decl = *node;
2916   tree rettype = TREE_TYPE (decl);
2917   if (!POINTER_TYPE_P (rettype))
2918     {
2919       warning (OPT_Wattributes,
2920 	       "%qE attribute ignored on a function returning %qT",
2921 	       name, rettype);
2922       *no_add_attrs = true;
2923       return NULL_TREE;
2924     }
2925 
2926   for (int i = 1; args; ++i)
2927     {
2928       tree pos = TREE_VALUE (args);
2929       /* NEXT is null when the attribute includes just one argument.
2930 	 That's used to tell positional_argument to avoid mentioning
2931 	 the argument number in diagnostics (since there's just one
2932 	 mentioning it is unnecessary and coule be confusing).  */
2933       tree next = TREE_CHAIN (args);
2934       if (tree val = positional_argument (decl, name, pos, INTEGER_TYPE,
2935 					  next || i > 1 ? i : 0))
2936 	TREE_VALUE (args) = val;
2937       else
2938 	{
2939 	  *no_add_attrs = true;
2940 	  break;
2941 	}
2942 
2943       args = next;
2944     }
2945 
2946   return NULL_TREE;
2947 }
2948 
2949 /* Handle a "alloc_align" attribute; arguments as in
2950    struct attribute_spec.handler.  */
2951 
2952 static tree
handle_alloc_align_attribute(tree * node,tree name,tree args,int,bool * no_add_attrs)2953 handle_alloc_align_attribute (tree *node, tree name, tree args, int,
2954 			      bool *no_add_attrs)
2955 {
2956   tree decl = *node;
2957   tree rettype = TREE_TYPE (decl);
2958   if (!POINTER_TYPE_P (rettype))
2959     {
2960       warning (OPT_Wattributes,
2961 	       "%qE attribute ignored on a function returning %qT",
2962 	       name, rettype);
2963       *no_add_attrs = true;
2964       return NULL_TREE;
2965     }
2966 
2967   if (!positional_argument (*node, name, TREE_VALUE (args), INTEGER_TYPE))
2968     *no_add_attrs = true;
2969 
2970   return NULL_TREE;
2971 }
2972 
2973 /* Handle a "assume_aligned" attribute; arguments as in
2974    struct attribute_spec.handler.  */
2975 
2976 static tree
handle_assume_aligned_attribute(tree * node,tree name,tree args,int,bool * no_add_attrs)2977 handle_assume_aligned_attribute (tree *node, tree name, tree args, int,
2978 				 bool *no_add_attrs)
2979 {
2980   tree decl = *node;
2981   tree rettype = TREE_TYPE (decl);
2982   if (TREE_CODE (rettype) != POINTER_TYPE)
2983     {
2984       warning (OPT_Wattributes,
2985 	       "%qE attribute ignored on a function returning %qT",
2986 	       name, rettype);
2987       *no_add_attrs = true;
2988       return NULL_TREE;
2989     }
2990 
2991   /* The alignment specified by the first argument.  */
2992   tree align = NULL_TREE;
2993 
2994   for (; args; args = TREE_CHAIN (args))
2995     {
2996       tree val = TREE_VALUE (args);
2997       if (val && TREE_CODE (val) != IDENTIFIER_NODE
2998 	  && TREE_CODE (val) != FUNCTION_DECL)
2999 	val = default_conversion (val);
3000 
3001       if (!tree_fits_shwi_p (val))
3002 	{
3003 	  warning (OPT_Wattributes,
3004 		   "%qE attribute argument %E is not an integer constant",
3005 		   name, val);
3006 	  *no_add_attrs = true;
3007 	  return NULL_TREE;
3008 	}
3009       else if (tree_int_cst_sgn (val) < 0)
3010 	{
3011 	  warning (OPT_Wattributes,
3012 		   "%qE attribute argument %E is not positive", name, val);
3013 	  *no_add_attrs = true;
3014 	  return NULL_TREE;
3015 	}
3016 
3017       if (!align)
3018 	{
3019 	  /* Validate and save the alignment.  */
3020 	  if (!integer_pow2p (val))
3021 	    {
3022 	      warning (OPT_Wattributes,
3023 		       "%qE attribute argument %E is not a power of 2",
3024 		       name, val);
3025 	      *no_add_attrs = true;
3026 	      return NULL_TREE;
3027 	    }
3028 
3029 	  align = val;
3030 	}
3031       else if (tree_int_cst_le (align, val))
3032 	{
3033 	  /* The misalignment specified by the second argument
3034 	     must be non-negative and less than the alignment.  */
3035 	  warning (OPT_Wattributes,
3036 		   "%qE attribute argument %E is not in the range [0, %wu]",
3037 		   name, val, tree_to_uhwi (align) - 1);
3038 	  *no_add_attrs = true;
3039 	  return NULL_TREE;
3040 	}
3041     }
3042   return NULL_TREE;
3043 }
3044 
3045 /* Handle a "fn spec" attribute; arguments as in
3046    struct attribute_spec.handler.  */
3047 
3048 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)3049 handle_fnspec_attribute (tree *node ATTRIBUTE_UNUSED, tree ARG_UNUSED (name),
3050 			 tree args, int ARG_UNUSED (flags),
3051 			 bool *no_add_attrs ATTRIBUTE_UNUSED)
3052 {
3053   gcc_assert (args
3054 	      && TREE_CODE (TREE_VALUE (args)) == STRING_CST
3055 	      && !TREE_CHAIN (args));
3056   return NULL_TREE;
3057 }
3058 
3059 /* Handle a "warn_unused" attribute; arguments as in
3060    struct attribute_spec.handler.  */
3061 
3062 static tree
handle_warn_unused_attribute(tree * node,tree name,tree args ATTRIBUTE_UNUSED,int flags ATTRIBUTE_UNUSED,bool * no_add_attrs)3063 handle_warn_unused_attribute (tree *node, tree name,
3064 			      tree args ATTRIBUTE_UNUSED,
3065 			      int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
3066 {
3067   if (TYPE_P (*node))
3068     /* Do nothing else, just set the attribute.  We'll get at
3069        it later with lookup_attribute.  */
3070     ;
3071   else
3072     {
3073       warning (OPT_Wattributes, "%qE attribute ignored", name);
3074       *no_add_attrs = true;
3075     }
3076 
3077   return NULL_TREE;
3078 }
3079 
3080 /* Handle an "omp declare simd" attribute; arguments as in
3081    struct attribute_spec.handler.  */
3082 
3083 static tree
handle_omp_declare_simd_attribute(tree *,tree,tree,int,bool *)3084 handle_omp_declare_simd_attribute (tree *, tree, tree, int, bool *)
3085 {
3086   return NULL_TREE;
3087 }
3088 
3089 /* Handle an "omp declare variant {base,variant}" attribute; arguments as in
3090    struct attribute_spec.handler.  */
3091 
3092 static tree
handle_omp_declare_variant_attribute(tree *,tree,tree,int,bool *)3093 handle_omp_declare_variant_attribute (tree *, tree, tree, int, bool *)
3094 {
3095   return NULL_TREE;
3096 }
3097 
3098 /* Handle a "simd" attribute.  */
3099 
3100 static tree
handle_simd_attribute(tree * node,tree name,tree args,int,bool * no_add_attrs)3101 handle_simd_attribute (tree *node, tree name, tree args, int, bool *no_add_attrs)
3102 {
3103   if (TREE_CODE (*node) == FUNCTION_DECL)
3104     {
3105       tree t = get_identifier ("omp declare simd");
3106       tree attr = NULL_TREE;
3107       if (args)
3108 	{
3109 	  tree id = TREE_VALUE (args);
3110 
3111 	  if (TREE_CODE (id) != STRING_CST)
3112 	    {
3113 	      error ("attribute %qE argument not a string", name);
3114 	      *no_add_attrs = true;
3115 	      return NULL_TREE;
3116 	    }
3117 
3118 	  if (strcmp (TREE_STRING_POINTER (id), "notinbranch") == 0)
3119 	    attr = build_omp_clause (DECL_SOURCE_LOCATION (*node),
3120 				     OMP_CLAUSE_NOTINBRANCH);
3121 	  else if (strcmp (TREE_STRING_POINTER (id), "inbranch") == 0)
3122 	    attr = build_omp_clause (DECL_SOURCE_LOCATION (*node),
3123 				     OMP_CLAUSE_INBRANCH);
3124 	  else
3125 	    {
3126 	      error ("only %<inbranch%> and %<notinbranch%> flags are "
3127 		     "allowed for %<__simd__%> attribute");
3128 	      *no_add_attrs = true;
3129 	      return NULL_TREE;
3130 	    }
3131 	}
3132 
3133       DECL_ATTRIBUTES (*node)
3134 	= tree_cons (t, build_tree_list (NULL_TREE, attr),
3135 		     DECL_ATTRIBUTES (*node));
3136     }
3137   else
3138     {
3139       warning (OPT_Wattributes, "%qE attribute ignored", name);
3140       *no_add_attrs = true;
3141     }
3142 
3143   return NULL_TREE;
3144 }
3145 
3146 /* Handle an "omp declare target" attribute; arguments as in
3147    struct attribute_spec.handler.  */
3148 
3149 static tree
handle_omp_declare_target_attribute(tree *,tree,tree,int,bool *)3150 handle_omp_declare_target_attribute (tree *, tree, tree, int, bool *)
3151 {
3152   return NULL_TREE;
3153 }
3154 
3155 /* Handle a "returns_twice" attribute; arguments as in
3156    struct attribute_spec.handler.  */
3157 
3158 static tree
handle_returns_twice_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)3159 handle_returns_twice_attribute (tree *node, tree name, tree ARG_UNUSED (args),
3160 			 int ARG_UNUSED (flags), bool *no_add_attrs)
3161 {
3162   if (TREE_CODE (*node) == FUNCTION_DECL)
3163     DECL_IS_RETURNS_TWICE (*node) = 1;
3164   else
3165     {
3166       warning (OPT_Wattributes, "%qE attribute ignored", name);
3167       *no_add_attrs = true;
3168     }
3169 
3170   return NULL_TREE;
3171 }
3172 
3173 /* Handle a "no_limit_stack" attribute; arguments as in
3174    struct attribute_spec.handler.  */
3175 
3176 static tree
handle_no_limit_stack_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)3177 handle_no_limit_stack_attribute (tree *node, tree name,
3178 				 tree ARG_UNUSED (args),
3179 				 int ARG_UNUSED (flags),
3180 				 bool *no_add_attrs)
3181 {
3182   tree decl = *node;
3183 
3184   if (TREE_CODE (decl) != FUNCTION_DECL)
3185     {
3186       error_at (DECL_SOURCE_LOCATION (decl),
3187 	     "%qE attribute applies only to functions", name);
3188       *no_add_attrs = true;
3189     }
3190   else if (DECL_INITIAL (decl))
3191     {
3192       error_at (DECL_SOURCE_LOCATION (decl),
3193 		"cannot set %qE attribute after definition", name);
3194       *no_add_attrs = true;
3195     }
3196   else
3197     DECL_NO_LIMIT_STACK (decl) = 1;
3198 
3199   return NULL_TREE;
3200 }
3201 
3202 /* Handle a "pure" attribute; arguments as in
3203    struct attribute_spec.handler.  */
3204 
3205 static tree
handle_pure_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)3206 handle_pure_attribute (tree *node, tree name, tree ARG_UNUSED (args),
3207 		       int ARG_UNUSED (flags), bool *no_add_attrs)
3208 {
3209   if (TREE_CODE (*node) == FUNCTION_DECL)
3210     {
3211       tree type = TREE_TYPE (*node);
3212       if (VOID_TYPE_P (TREE_TYPE (type)))
3213 	warning (OPT_Wattributes, "%qE attribute on function "
3214 		 "returning %<void%>", name);
3215 
3216       DECL_PURE_P (*node) = 1;
3217       /* ??? TODO: Support types.  */
3218     }
3219   else
3220     {
3221       warning (OPT_Wattributes, "%qE attribute ignored", name);
3222       *no_add_attrs = true;
3223     }
3224 
3225   return NULL_TREE;
3226 }
3227 
3228 /* Digest an attribute list destined for a transactional memory statement.
3229    ALLOWED is the set of attributes that are allowed for this statement;
3230    return the attribute we parsed.  Multiple attributes are never allowed.  */
3231 
3232 int
parse_tm_stmt_attr(tree attrs,int allowed)3233 parse_tm_stmt_attr (tree attrs, int allowed)
3234 {
3235   tree a_seen = NULL;
3236   int m_seen = 0;
3237 
3238   for ( ; attrs ; attrs = TREE_CHAIN (attrs))
3239     {
3240       tree a = get_attribute_name (attrs);
3241       tree ns = get_attribute_namespace (attrs);
3242       int m = 0;
3243 
3244       if (is_attribute_p ("outer", a)
3245 	  && (ns == NULL_TREE || strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0))
3246 	m = TM_STMT_ATTR_OUTER;
3247 
3248       if ((m & allowed) == 0)
3249 	{
3250 	  warning (OPT_Wattributes, "%qE attribute directive ignored", a);
3251 	  continue;
3252 	}
3253 
3254       if (m_seen == 0)
3255 	{
3256 	  a_seen = a;
3257 	  m_seen = m;
3258 	}
3259       else if (m_seen == m)
3260 	warning (OPT_Wattributes, "%qE attribute duplicated", a);
3261       else
3262 	warning (OPT_Wattributes, "%qE attribute follows %qE", a, a_seen);
3263     }
3264 
3265   return m_seen;
3266 }
3267 
3268 /* Transform a TM attribute name into a maskable integer and back.
3269    Note that NULL (i.e. no attribute) is mapped to UNKNOWN, corresponding
3270    to how the lack of an attribute is treated.  */
3271 
3272 int
tm_attr_to_mask(tree attr)3273 tm_attr_to_mask (tree attr)
3274 {
3275   if (attr == NULL)
3276     return 0;
3277   if (is_attribute_p ("transaction_safe", attr))
3278     return TM_ATTR_SAFE;
3279   if (is_attribute_p ("transaction_callable", attr))
3280     return TM_ATTR_CALLABLE;
3281   if (is_attribute_p ("transaction_pure", attr))
3282     return TM_ATTR_PURE;
3283   if (is_attribute_p ("transaction_unsafe", attr))
3284     return TM_ATTR_IRREVOCABLE;
3285   if (is_attribute_p ("transaction_may_cancel_outer", attr))
3286     return TM_ATTR_MAY_CANCEL_OUTER;
3287   return 0;
3288 }
3289 
3290 tree
tm_mask_to_attr(int mask)3291 tm_mask_to_attr (int mask)
3292 {
3293   const char *str;
3294   switch (mask)
3295     {
3296     case TM_ATTR_SAFE:
3297       str = "transaction_safe";
3298       break;
3299     case TM_ATTR_CALLABLE:
3300       str = "transaction_callable";
3301       break;
3302     case TM_ATTR_PURE:
3303       str = "transaction_pure";
3304       break;
3305     case TM_ATTR_IRREVOCABLE:
3306       str = "transaction_unsafe";
3307       break;
3308     case TM_ATTR_MAY_CANCEL_OUTER:
3309       str = "transaction_may_cancel_outer";
3310       break;
3311     default:
3312       gcc_unreachable ();
3313     }
3314   return get_identifier (str);
3315 }
3316 
3317 /* Return the first TM attribute seen in LIST.  */
3318 
3319 tree
find_tm_attribute(tree list)3320 find_tm_attribute (tree list)
3321 {
3322   for (; list ; list = TREE_CHAIN (list))
3323     {
3324       tree name = get_attribute_name (list);
3325       if (tm_attr_to_mask (name) != 0)
3326 	return name;
3327     }
3328   return NULL_TREE;
3329 }
3330 
3331 /* Handle the TM attributes; arguments as in struct attribute_spec.handler.
3332    Here we accept only function types, and verify that none of the other
3333    function TM attributes are also applied.  */
3334 /* ??? We need to accept class types for C++, but not C.  This greatly
3335    complicates this function, since we can no longer rely on the extra
3336    processing given by function_type_required.  */
3337 
3338 static tree
handle_tm_attribute(tree * node,tree name,tree args,int flags,bool * no_add_attrs)3339 handle_tm_attribute (tree *node, tree name, tree args,
3340 		     int flags, bool *no_add_attrs)
3341 {
3342   /* Only one path adds the attribute; others don't.  */
3343   *no_add_attrs = true;
3344 
3345   switch (TREE_CODE (*node))
3346     {
3347     case RECORD_TYPE:
3348     case UNION_TYPE:
3349       /* Only tm_callable and tm_safe apply to classes.  */
3350       if (tm_attr_to_mask (name) & ~(TM_ATTR_SAFE | TM_ATTR_CALLABLE))
3351 	goto ignored;
3352       /* FALLTHRU */
3353 
3354     case FUNCTION_TYPE:
3355     case METHOD_TYPE:
3356       {
3357 	tree old_name = find_tm_attribute (TYPE_ATTRIBUTES (*node));
3358 	if (old_name == name)
3359 	  ;
3360 	else if (old_name != NULL_TREE)
3361 	  error ("type was previously declared %qE", old_name);
3362 	else
3363 	  *no_add_attrs = false;
3364       }
3365       break;
3366 
3367     case FUNCTION_DECL:
3368       {
3369 	/* transaction_safe_dynamic goes on the FUNCTION_DECL, but we also
3370 	   want to set transaction_safe on the type.  */
3371 	gcc_assert (is_attribute_p ("transaction_safe_dynamic", name));
3372 	if (!TYPE_P (DECL_CONTEXT (*node)))
3373 	  error_at (DECL_SOURCE_LOCATION (*node),
3374 		    "%<transaction_safe_dynamic%> may only be specified for "
3375 		    "a virtual function");
3376 	*no_add_attrs = false;
3377 	decl_attributes (&TREE_TYPE (*node),
3378 			 build_tree_list (get_identifier ("transaction_safe"),
3379 					  NULL_TREE),
3380 			 0);
3381 	break;
3382       }
3383 
3384     case POINTER_TYPE:
3385       {
3386 	enum tree_code subcode = TREE_CODE (TREE_TYPE (*node));
3387 	if (subcode == FUNCTION_TYPE || subcode == METHOD_TYPE)
3388 	  {
3389 	    tree fn_tmp = TREE_TYPE (*node);
3390 	    decl_attributes (&fn_tmp, tree_cons (name, args, NULL), 0);
3391 	    *node = build_pointer_type (fn_tmp);
3392 	    break;
3393 	  }
3394       }
3395       /* FALLTHRU */
3396 
3397     default:
3398       /* If a function is next, pass it on to be tried next.  */
3399       if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
3400 	return tree_cons (name, args, NULL);
3401 
3402     ignored:
3403       warning (OPT_Wattributes, "%qE attribute ignored", name);
3404       break;
3405     }
3406 
3407   return NULL_TREE;
3408 }
3409 
3410 /* Handle the TM_WRAP attribute; arguments as in
3411    struct attribute_spec.handler.  */
3412 
3413 static tree
handle_tm_wrap_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)3414 handle_tm_wrap_attribute (tree *node, tree name, tree args,
3415 			  int ARG_UNUSED (flags), bool *no_add_attrs)
3416 {
3417   tree decl = *node;
3418 
3419   /* We don't need the attribute even on success, since we
3420      record the entry in an external table.  */
3421   *no_add_attrs = true;
3422 
3423   if (TREE_CODE (decl) != FUNCTION_DECL)
3424     warning (OPT_Wattributes, "%qE attribute ignored", name);
3425   else
3426     {
3427       tree wrap_decl = TREE_VALUE (args);
3428       if (error_operand_p (wrap_decl))
3429 	;
3430       else if (TREE_CODE (wrap_decl) != IDENTIFIER_NODE
3431 	       && !VAR_OR_FUNCTION_DECL_P (wrap_decl))
3432 	error ("%qE argument not an identifier", name);
3433       else
3434 	{
3435 	  if (TREE_CODE (wrap_decl) == IDENTIFIER_NODE)
3436 	    wrap_decl = lookup_name (wrap_decl);
3437 	  if (wrap_decl && TREE_CODE (wrap_decl) == FUNCTION_DECL)
3438 	    {
3439 	      if (lang_hooks.types_compatible_p (TREE_TYPE (decl),
3440 						 TREE_TYPE (wrap_decl)))
3441 		record_tm_replacement (wrap_decl, decl);
3442 	      else
3443 		error ("%qD is not compatible with %qD", wrap_decl, decl);
3444 	    }
3445 	  else
3446 	    error ("%qE argument is not a function", name);
3447 	}
3448     }
3449 
3450   return NULL_TREE;
3451 }
3452 
3453 /* Ignore the given attribute.  Used when this attribute may be usefully
3454    overridden by the target, but is not used generically.  */
3455 
3456 static tree
ignore_attribute(tree * ARG_UNUSED (node),tree ARG_UNUSED (name),tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)3457 ignore_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name),
3458 		  tree ARG_UNUSED (args), int ARG_UNUSED (flags),
3459 		  bool *no_add_attrs)
3460 {
3461   *no_add_attrs = true;
3462   return NULL_TREE;
3463 }
3464 
3465 /* Handle a "no vops" attribute; arguments as in
3466    struct attribute_spec.handler.  */
3467 
3468 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))3469 handle_novops_attribute (tree *node, tree ARG_UNUSED (name),
3470 			 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
3471 			 bool *ARG_UNUSED (no_add_attrs))
3472 {
3473   gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
3474   DECL_IS_NOVOPS (*node) = 1;
3475   return NULL_TREE;
3476 }
3477 
3478 /* Handle a "deprecated" attribute; arguments as in
3479    struct attribute_spec.handler.  */
3480 
3481 tree
handle_deprecated_attribute(tree * node,tree name,tree args,int flags,bool * no_add_attrs)3482 handle_deprecated_attribute (tree *node, tree name,
3483 			     tree args, int flags,
3484 			     bool *no_add_attrs)
3485 {
3486   tree type = NULL_TREE;
3487   int warn = 0;
3488   tree what = NULL_TREE;
3489 
3490   if (!args)
3491     *no_add_attrs = true;
3492   else if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
3493     {
3494       error ("deprecated message is not a string");
3495       *no_add_attrs = true;
3496     }
3497 
3498   if (DECL_P (*node))
3499     {
3500       tree decl = *node;
3501       type = TREE_TYPE (decl);
3502 
3503       if (TREE_CODE (decl) == TYPE_DECL
3504 	  || TREE_CODE (decl) == PARM_DECL
3505 	  || VAR_OR_FUNCTION_DECL_P (decl)
3506 	  || TREE_CODE (decl) == FIELD_DECL
3507 	  || TREE_CODE (decl) == CONST_DECL
3508 	  || objc_method_decl (TREE_CODE (decl)))
3509 	TREE_DEPRECATED (decl) = 1;
3510       else
3511 	warn = 1;
3512     }
3513   else if (TYPE_P (*node))
3514     {
3515       if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
3516 	*node = build_variant_type_copy (*node);
3517       TREE_DEPRECATED (*node) = 1;
3518       type = *node;
3519     }
3520   else
3521     warn = 1;
3522 
3523   if (warn)
3524     {
3525       *no_add_attrs = true;
3526       if (type && TYPE_NAME (type))
3527 	{
3528 	  if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
3529 	    what = TYPE_NAME (*node);
3530 	  else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
3531 		   && DECL_NAME (TYPE_NAME (type)))
3532 	    what = DECL_NAME (TYPE_NAME (type));
3533 	}
3534       if (what)
3535 	warning (OPT_Wattributes, "%qE attribute ignored for %qE", name, what);
3536       else
3537 	warning (OPT_Wattributes, "%qE attribute ignored", name);
3538     }
3539 
3540   return NULL_TREE;
3541 }
3542 
3543 /* Return the "base" type from TYPE that is suitable to apply attribute
3544    vector_size to by stripping arrays, function types, etc.  */
3545 static tree
type_for_vector_size(tree type)3546 type_for_vector_size (tree type)
3547 {
3548   /* We need to provide for vector pointers, vector arrays, and
3549      functions returning vectors.  For example:
3550 
3551        __attribute__((vector_size(16))) short *foo;
3552 
3553      In this case, the mode is SI, but the type being modified is
3554      HI, so we need to look further.  */
3555 
3556   while (POINTER_TYPE_P (type)
3557 	 || TREE_CODE (type) == FUNCTION_TYPE
3558 	 || TREE_CODE (type) == METHOD_TYPE
3559 	 || TREE_CODE (type) == ARRAY_TYPE
3560 	 || TREE_CODE (type) == OFFSET_TYPE)
3561     type = TREE_TYPE (type);
3562 
3563   return type;
3564 }
3565 
3566 /* Given TYPE, return the base type to which the vector_size attribute
3567    ATNAME with ARGS, when non-null, can be applied, if one exists.
3568    On success and when both ARGS and PTRNUNITS are non-null, set
3569    *PTRNUNINTS to the number of vector units.  When PTRNUNITS is not
3570    null, issue a warning when the attribute argument is not constant
3571    and an error if there is no such type.  Otherwise issue a warning
3572    in the latter case and return null.  */
3573 
3574 static tree
type_valid_for_vector_size(tree type,tree atname,tree args,unsigned HOST_WIDE_INT * ptrnunits)3575 type_valid_for_vector_size (tree type, tree atname, tree args,
3576 			    unsigned HOST_WIDE_INT *ptrnunits)
3577 {
3578   bool error_p = ptrnunits != NULL;
3579 
3580   /* Get the mode of the type being modified.  */
3581   machine_mode orig_mode = TYPE_MODE (type);
3582 
3583   if ((!INTEGRAL_TYPE_P (type)
3584        && !SCALAR_FLOAT_TYPE_P (type)
3585        && !FIXED_POINT_TYPE_P (type))
3586       || (!SCALAR_FLOAT_MODE_P (orig_mode)
3587 	  && GET_MODE_CLASS (orig_mode) != MODE_INT
3588 	  && !ALL_SCALAR_FIXED_POINT_MODE_P (orig_mode))
3589       || !tree_fits_uhwi_p (TYPE_SIZE_UNIT (type))
3590       || TREE_CODE (type) == BOOLEAN_TYPE)
3591     {
3592       if (error_p)
3593 	error ("invalid vector type for attribute %qE", atname);
3594       else
3595 	warning (OPT_Wattributes, "invalid vector type for attribute %qE",
3596 		 atname);
3597       return NULL_TREE;
3598     }
3599 
3600   /* When no argument has been provided this is just a request to validate
3601      the type above.  Return TYPE to indicate success.  */
3602   if (!args)
3603     return type;
3604 
3605   tree size = TREE_VALUE (args);
3606   /* Erroneous arguments have already been diagnosed.  */
3607   if (size == error_mark_node)
3608     return NULL_TREE;
3609 
3610   if (size && TREE_CODE (size) != IDENTIFIER_NODE
3611       && TREE_CODE (size) != FUNCTION_DECL)
3612     size = default_conversion (size);
3613 
3614   if (TREE_CODE (size) != INTEGER_CST)
3615     {
3616       if (error_p)
3617 	error ("%qE attribute argument value %qE is not an integer constant",
3618 	       atname, size);
3619       else
3620 	warning (OPT_Wattributes,
3621 		 "%qE attribute argument value %qE is not an integer constant",
3622 		 atname, size);
3623       return NULL_TREE;
3624     }
3625 
3626   if (!TYPE_UNSIGNED (TREE_TYPE (size))
3627       && tree_int_cst_sgn (size) < 0)
3628     {
3629       if (error_p)
3630 	error ("%qE attribute argument value %qE is negative",
3631 	       atname, size);
3632       else
3633 	warning (OPT_Wattributes,
3634 		 "%qE attribute argument value %qE is negative",
3635 		 atname, size);
3636       return NULL_TREE;
3637     }
3638 
3639   /* The attribute argument value is constrained by the maximum bit
3640      alignment representable in unsigned int on the host.  */
3641   unsigned HOST_WIDE_INT vecsize;
3642   unsigned HOST_WIDE_INT maxsize = tree_to_uhwi (max_object_size ());
3643   if (!tree_fits_uhwi_p (size)
3644       || (vecsize = tree_to_uhwi (size)) > maxsize)
3645     {
3646       if (error_p)
3647 	error ("%qE attribute argument value %qE exceeds %wu",
3648 	       atname, size, maxsize);
3649       else
3650 	warning (OPT_Wattributes,
3651 		 "%qE attribute argument value %qE exceeds %wu",
3652 		 atname, size, maxsize);
3653       return NULL_TREE;
3654     }
3655 
3656   if (vecsize % tree_to_uhwi (TYPE_SIZE_UNIT (type)))
3657     {
3658       if (error_p)
3659 	error ("vector size not an integral multiple of component size");
3660       return NULL_TREE;
3661     }
3662 
3663   if (vecsize == 0)
3664     {
3665       error ("zero vector size");
3666       return NULL;
3667     }
3668 
3669   /* Calculate how many units fit in the vector.  */
3670   unsigned HOST_WIDE_INT nunits = vecsize / tree_to_uhwi (TYPE_SIZE_UNIT (type));
3671   if (nunits & (nunits - 1))
3672     {
3673       if (error_p)
3674 	error ("number of components of the vector not a power of two");
3675       else
3676 	warning (OPT_Wattributes,
3677 		 "number of components of the vector not a power of two");
3678       return NULL_TREE;
3679     }
3680 
3681   if (ptrnunits)
3682     *ptrnunits = nunits;
3683 
3684   return type;
3685 }
3686 
3687 /* Handle a "vector_size" attribute; arguments as in
3688    struct attribute_spec.handler.  */
3689 
3690 static tree
handle_vector_size_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)3691 handle_vector_size_attribute (tree *node, tree name, tree args,
3692 			      int ARG_UNUSED (flags),
3693 			      bool *no_add_attrs)
3694 {
3695   *no_add_attrs = true;
3696 
3697   /* Determine the "base" type to apply the attribute to.  */
3698   tree type = type_for_vector_size (*node);
3699 
3700   /* Get the vector size (in bytes) and let the function compute
3701      the number of vector units.  */
3702   unsigned HOST_WIDE_INT nunits;
3703   type = type_valid_for_vector_size (type, name, args, &nunits);
3704   if (!type)
3705     return NULL_TREE;
3706 
3707   tree new_type = build_vector_type (type, nunits);
3708 
3709   /* Build back pointers if needed.  */
3710   *node = lang_hooks.types.reconstruct_complex_type (*node, new_type);
3711 
3712   return NULL_TREE;
3713 }
3714 
3715 /* Handle the "nonnull" attribute.  */
3716 
3717 static tree
handle_nonnull_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)3718 handle_nonnull_attribute (tree *node, tree name,
3719 			  tree args, int ARG_UNUSED (flags),
3720 			  bool *no_add_attrs)
3721 {
3722   tree type = *node;
3723 
3724   /* If no arguments are specified, all pointer arguments should be
3725      non-null.  Verify a full prototype is given so that the arguments
3726      will have the correct types when we actually check them later.
3727      Avoid diagnosing type-generic built-ins since those have no
3728      prototype.  */
3729   if (!args)
3730     {
3731       if (!prototype_p (type)
3732 	  && (!TYPE_ATTRIBUTES (type)
3733 	      || !lookup_attribute ("type generic", TYPE_ATTRIBUTES (type))))
3734 	{
3735 	  error ("%qE attribute without arguments on a non-prototype",
3736 		 name);
3737 	  *no_add_attrs = true;
3738 	}
3739       return NULL_TREE;
3740     }
3741 
3742   for (int i = 1; args; ++i)
3743     {
3744       tree pos = TREE_VALUE (args);
3745       /* NEXT is null when the attribute includes just one argument.
3746 	 That's used to tell positional_argument to avoid mentioning
3747 	 the argument number in diagnostics (since there's just one
3748 	 mentioning it is unnecessary and coule be confusing).  */
3749       tree next = TREE_CHAIN (args);
3750       if (tree val = positional_argument (type, name, pos, POINTER_TYPE,
3751 					  next || i > 1 ? i : 0))
3752 	TREE_VALUE (args) = val;
3753       else
3754 	{
3755 	  *no_add_attrs = true;
3756 	  break;
3757 	}
3758       args = next;
3759     }
3760 
3761   return NULL_TREE;
3762 }
3763 
3764 /* Handle the "nonstring" variable attribute.  */
3765 
3766 static tree
handle_nonstring_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)3767 handle_nonstring_attribute (tree *node, tree name, tree ARG_UNUSED (args),
3768 			    int ARG_UNUSED (flags), bool *no_add_attrs)
3769 {
3770   gcc_assert (!args);
3771   tree_code code = TREE_CODE (*node);
3772 
3773   if (VAR_P (*node)
3774       || code == FIELD_DECL
3775       || code == PARM_DECL)
3776     {
3777       tree type = TREE_TYPE (*node);
3778 
3779       if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
3780 	{
3781 	  /* Accept the attribute on arrays and pointers to all three
3782 	     narrow character types.  */
3783 	  tree eltype = TREE_TYPE (type);
3784 	  eltype = TYPE_MAIN_VARIANT (eltype);
3785 	  if (eltype == char_type_node
3786 	      || eltype == signed_char_type_node
3787 	      || eltype == unsigned_char_type_node)
3788 	    return NULL_TREE;
3789 	}
3790 
3791       warning (OPT_Wattributes,
3792 	       "%qE attribute ignored on objects of type %qT",
3793 	       name, type);
3794       *no_add_attrs = true;
3795       return NULL_TREE;
3796     }
3797 
3798   if (code == FUNCTION_DECL)
3799     warning (OPT_Wattributes,
3800 	     "%qE attribute does not apply to functions", name);
3801   else if (code == TYPE_DECL)
3802     warning (OPT_Wattributes,
3803 	     "%qE attribute does not apply to types", name);
3804   else
3805     warning (OPT_Wattributes, "%qE attribute ignored", name);
3806 
3807   *no_add_attrs = true;
3808   return NULL_TREE;
3809 }
3810 
3811 /* Given a function type FUNCTYPE, returns the type of the parameter
3812    ARGNO or null if ARGNO exceeds the number of parameters.  On failure
3813    set *NARGS to the number of function parameters.  */
3814 
3815 static tree
get_argument_type(tree functype,unsigned argno,unsigned * nargs)3816 get_argument_type (tree functype, unsigned argno, unsigned *nargs)
3817 {
3818   function_args_iterator iter;
3819   function_args_iter_init (&iter, functype);
3820 
3821   unsigned count = 0;
3822 
3823   for ( ; iter.next; ++count, function_args_iter_next (&iter))
3824     {
3825       if (count + 1 == argno)
3826 	{
3827 	  tree argtype = function_args_iter_cond (&iter);
3828 	  if (VOID_TYPE_P (argtype))
3829 	    break;
3830 	  return argtype;
3831 	}
3832     }
3833 
3834   *nargs = count;
3835   return NULL_TREE;
3836 }
3837 
3838 /* Appends ATTRSTR to the access string in ATTRS if one is there
3839    or creates a new one and returns the concatenated access string.  */
3840 
3841 static tree
append_access_attrs(tree t,tree attrs,const char * attrstr,char code,HOST_WIDE_INT idxs[2])3842 append_access_attrs (tree t, tree attrs, const char *attrstr,
3843 		     char code, HOST_WIDE_INT idxs[2])
3844 {
3845   char attrspec[80];
3846   int n1 = sprintf (attrspec, "%c%u", code, (unsigned) idxs[0] - 1);
3847   int n2 = 0;
3848   if (idxs[1])
3849     n2 = sprintf (attrspec + n1 + 1, "%u", (unsigned) idxs[1] - 1);
3850 
3851   size_t newlen = n1 + n2 + !!n2;
3852   char *newspec = attrspec;
3853 
3854   if (tree acs = lookup_attribute ("access", attrs))
3855     {
3856       /* The TREE_VALUE of an attribute is a TREE_LIST whose TREE_VALUE
3857 	 is the attribute argument's value.  */
3858       acs = TREE_VALUE (acs);
3859       gcc_assert (TREE_CODE (acs) == TREE_LIST);
3860       acs = TREE_VALUE (acs);
3861       gcc_assert (TREE_CODE (acs) == STRING_CST);
3862 
3863       /* Check to make sure ATTRSPEC doesn't conflict with another
3864 	 access attribute specified in ATTRS by searching the access
3865 	 string in ATTRS for the position string formatted above into
3866 	 ATTRSPEC, and if it's found, that the two match.  */
3867 
3868       const char *posstr = attrspec + 1;
3869       const char *str = TREE_STRING_POINTER (acs);
3870       const char *pos = str;
3871       for ( ; ; pos += n1)
3872 	{
3873 	  pos = strstr (pos, posstr);
3874 	  if (!pos)
3875 	    break;
3876 
3877 	  if (ISDIGIT (pos[-1]) || ISDIGIT (pos[n1 -1]))
3878 	    continue;
3879 
3880 	  /* Found a matching positional argument.  */
3881 	  if (*attrspec != pos[-1])
3882 	    {
3883 	      /* Mismatch in access mode.  */
3884 	      auto_diagnostic_group d;
3885 	      if (warning (OPT_Wattributes,
3886 			   "attribute %qs mismatch with mode %qs",
3887 			   attrstr,
3888 			   (pos[-1] == 'r'
3889 			    ? "read_only"
3890 			    : (pos[-1] == 'w' ? "write_only" : "read_write")))
3891 		  && DECL_P (t))
3892 		inform (DECL_SOURCE_LOCATION (t),
3893 			"previous declaration here");
3894 	      return NULL_TREE;
3895 	    }
3896 
3897 	  if ((n2 && pos[n1 - 1] != ','))
3898 	    {
3899 	      /* Mismatch in the presence of the size argument.  */
3900 	      auto_diagnostic_group d;
3901 	      if (warning (OPT_Wattributes,
3902 			   "attribute %qs positional argument 2 conflicts "
3903 			   "with previous designation",
3904 			   attrstr)
3905 		  && DECL_P (t))
3906 		inform (DECL_SOURCE_LOCATION (t),
3907 			"previous declaration here");
3908 	      return NULL_TREE;
3909 	    }
3910 
3911 	  if (!n2 && pos[n1 - 1] == ',')
3912 	    {
3913 	      /* Mismatch in the presence of the size argument.  */
3914 	      auto_diagnostic_group d;
3915 	      if (warning (OPT_Wattributes,
3916 			   "attribute %qs missing positional argument 2 "
3917 			   "provided in previous designation",
3918 			   attrstr)
3919 		  && DECL_P (t))
3920 		inform (DECL_SOURCE_LOCATION (t),
3921 			"previous declaration here");
3922 	      return NULL_TREE;
3923 	    }
3924 
3925 	  if (n2 && strncmp (attrspec + n1 + 1, pos + n1, n2))
3926 	    {
3927 	      /* Mismatch in the value of the size argument.  */
3928 	      auto_diagnostic_group d;
3929 	      if (warning (OPT_Wattributes,
3930 			   "attribute %qs mismatched positional argument "
3931 			   "values %i and %i",
3932 			   attrstr, atoi (attrspec + n1 + 1) + 1,
3933 			   atoi (pos + n1) + 1)
3934 		  && DECL_P (t))
3935 		inform (DECL_SOURCE_LOCATION (t),
3936 			"previous declaration here");
3937 	      return NULL_TREE;
3938 	    }
3939 
3940 	  /* Avoid adding the same attribute specification.  */
3941 	  return NULL_TREE;
3942 	}
3943 
3944       /* Connect the two substrings formatted above into a single one.  */
3945       if (idxs[1])
3946 	attrspec[n1] = ',';
3947 
3948       size_t len = strlen (str);
3949       newspec = XNEWVEC (char, newlen + len + 1);
3950       strcpy (newspec, str);
3951       strcpy (newspec + len, attrspec);
3952       newlen += len;
3953     }
3954   else if (idxs[1])
3955     /* Connect the two substrings formatted above into a single one.  */
3956     attrspec[n1] = ',';
3957 
3958   tree ret = build_string (newlen + 1, newspec);
3959   if (newspec != attrspec)
3960     XDELETEVEC (newspec);
3961   return ret;
3962 }
3963 
3964 /* Handle the access attribute (read_only, write_only, and read_write).  */
3965 
3966 static tree
handle_access_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)3967 handle_access_attribute (tree *node, tree name, tree args,
3968 			 int ARG_UNUSED (flags), bool *no_add_attrs)
3969 {
3970   tree type = *node;
3971   tree attrs = TYPE_ATTRIBUTES (type);
3972 
3973   *no_add_attrs = true;
3974 
3975   /* Verify a full prototype is provided so that the argument types
3976      can be validated.  Avoid diagnosing type-generic built-ins since
3977      those have no prototype.  */
3978   if (!args
3979       && !prototype_p (type)
3980       && (!attrs || !lookup_attribute ("type generic", attrs)))
3981     {
3982       error ("attribute %qE without arguments on a non-prototype", name);
3983       return NULL_TREE;
3984     }
3985 
3986   tree access_mode = TREE_VALUE (args);
3987   if (TREE_CODE (access_mode) == STRING_CST)
3988     {
3989       /* This must be a recursive call to handle the condensed internal
3990 	 form of the attribute (see below).  Since all validation has
3991 	 been done simply return here, accepting the attribute as is.  */
3992       *no_add_attrs = false;
3993       return NULL_TREE;
3994     }
3995 
3996   /* Set to true when the access mode has the form of a function call
3997      as in 'attribute (read_only (1, 2))'.  That's an easy mistake to
3998      make and so worth a special diagnostic.  */
3999   bool funcall = false;
4000   if (TREE_CODE (access_mode) == CALL_EXPR)
4001     {
4002       access_mode = CALL_EXPR_FN (access_mode);
4003       if (TREE_CODE (access_mode) != ADDR_EXPR)
4004 	{
4005 	  error ("attribute %qE invalid mode", name);
4006 	  return NULL_TREE;
4007 	}
4008       access_mode = TREE_OPERAND (access_mode, 0);
4009       access_mode = DECL_NAME (access_mode);
4010       funcall = true;
4011     }
4012 
4013   const char* const access_str = IDENTIFIER_POINTER (access_mode);
4014   const char *ps = access_str;
4015   if (ps[0] == '_' && ps[1] == '_')
4016     {
4017       size_t len = strlen (ps);
4018       if (ps[len - 1] == '_' && ps[len - 2] == '_')
4019 	ps += 2;
4020     }
4021 
4022   const bool read_only = strncmp (ps, "read_only", 9) == 0;
4023   const bool write_only = strncmp (ps, "write_only", 10) == 0;
4024   if (!read_only && !write_only && strncmp (ps, "read_write", 10))
4025     {
4026       error ("attribute %qE invalid mode %qs; expected one of "
4027 	     "%qs, %qs, or %qs", name, access_str,
4028 	     "read_only", "read_write", "write_only");
4029       return NULL_TREE;
4030     }
4031 
4032   if (funcall)
4033     {
4034       error ("attribute %qE unexpected %<(%> after mode %qs; expected "
4035 	     "a positional argument or %<)%>",
4036 	     name, access_str);
4037       return NULL_TREE;
4038     }
4039 
4040   args = TREE_CHAIN (args);
4041   if (!args)
4042     {
4043       /* The first positional argument is required.  It may be worth
4044 	 dropping the requirement at some point and having read_only
4045 	 apply to all const-qualified pointers and read_write or
4046 	 write_only to the rest.  */
4047       error ("attribute %<%E(%s)%> missing an argument",
4048 	     name, access_str);
4049       return NULL_TREE;
4050     }
4051 
4052   /* One or more positional arguments have been specified.  Validate
4053      them.  */
4054   tree idxnodes[2] = { NULL_TREE, NULL_TREE };
4055   tree argtypes[2] = { NULL_TREE, NULL_TREE };
4056   /* 1-based attribute positional arguments or zero if not specified.
4057      Invalid negative or excessive values are also stored but used
4058      only in diagnostics.  */
4059   HOST_WIDE_INT idxs[2] = { 0, 0 };
4060 
4061   /* Number of function formal arguments (used in diagnostics).  */
4062   unsigned nfuncargs = 0;
4063   /* Number of (optional) attribute positional arguments.  */
4064   unsigned nattrargs = 0;
4065 
4066   for (unsigned i = 0; i != 2; ++i, args = TREE_CHAIN (args), ++nattrargs)
4067     {
4068       if (!args)
4069 	break;
4070 
4071       idxnodes[i] = TREE_VALUE (args);
4072 
4073       if (TREE_CODE (idxnodes[i]) != IDENTIFIER_NODE
4074 	  && TREE_CODE (idxnodes[i]) != FUNCTION_DECL)
4075 	idxnodes[i] = default_conversion (idxnodes[i]);
4076 
4077       if (tree_fits_shwi_p (idxnodes[i]))
4078 	{
4079 	  idxs[i] = tree_to_shwi (idxnodes[i]);
4080 	  argtypes[i] = get_argument_type (type, idxs[i], &nfuncargs);
4081 	}
4082     }
4083 
4084   if ((nattrargs == 1 && !idxs[0])
4085       || (nattrargs == 2 && (!idxs[0] || !idxs[1])))
4086     {
4087       if (idxnodes[1])
4088 	error ("attribute %<%E(%s, %E, %E)%> invalid positional argument %i",
4089 	       name, access_str, idxnodes[0], idxnodes[1], idxs[0] ? 2 : 1);
4090       else
4091 	error ("attribute %<%E(%s, %E)%> invalid positional argument %i",
4092 	       name, access_str, idxnodes[0], idxs[0] ? 2 : 1);
4093       return NULL_TREE;
4094     }
4095 
4096   /* Format the attribute specification to include in diagnostics.  */
4097   char attrstr[80];
4098   if (idxnodes[1])
4099     snprintf (attrstr, sizeof attrstr, "%s(%s, %lli, %lli)",
4100 	      IDENTIFIER_POINTER (name), access_str,
4101 	      (long long) idxs[0], (long long) idxs[1]);
4102   else if (idxnodes[0])
4103     snprintf (attrstr, sizeof attrstr, "%s(%s, %lli)",
4104 	      IDENTIFIER_POINTER (name), access_str,
4105 	      (long long) idxs[0]);
4106   else
4107     snprintf (attrstr, sizeof attrstr, "%s(%s)",
4108 	      IDENTIFIER_POINTER (name), access_str);
4109 
4110   /* Verify the positional argument values are in range.  */
4111   if (!argtypes[0] || (idxnodes[1] && !argtypes[1]))
4112     {
4113       if (idxnodes[0])
4114 	{
4115 	  if (idxs[0] < 0 || idxs[1] < 0)
4116 	    error ("attribute %qs positional argument %i invalid value %wi",
4117 		   attrstr, idxs[0] < 0 ? 1 : 2,
4118 		   idxs[0] < 0 ? idxs[0] : idxs[1]);
4119 	  else
4120 	    error ("attribute %qs positional argument %i value %wi exceeds "
4121 		   "number of function arguments %u",
4122 		   attrstr, idxs[0] ? 1 : 2,
4123 		   idxs[0] ? idxs[0] : idxs[1],
4124 		   nfuncargs);
4125 	}
4126       else
4127 	error ("attribute %qs invalid positional argument", attrstr);
4128 
4129       return NULL_TREE;
4130     }
4131 
4132   if (!POINTER_TYPE_P (argtypes[0]))
4133     {
4134       /* The first argument must have a pointer or reference type.  */
4135       error ("attribute %qs positional argument 1 references "
4136 	     "non-pointer argument type %qT",
4137 	     attrstr, argtypes[0]);
4138       return NULL_TREE;
4139     }
4140 
4141   {
4142     /* Pointers to functions are not allowed.  */
4143     tree ptrtype = TREE_TYPE (argtypes[0]);
4144     if (FUNC_OR_METHOD_TYPE_P (ptrtype))
4145       {
4146 	error ("attribute %qs positional argument 1 references "
4147 	       "argument of function type %qT",
4148 	       attrstr, ptrtype);
4149 	return NULL_TREE;
4150       }
4151   }
4152 
4153   if (!read_only)
4154     {
4155       /* A read_write and write_only modes must reference non-const
4156 	 arguments.  */
4157       if (TYPE_READONLY (TREE_TYPE (argtypes[0])))
4158 	{
4159 	  error ("attribute %qs positional argument 1 references "
4160 		 "%qs-qualified argument type %qT",
4161 		 attrstr, "const", argtypes[0]);
4162 	  return NULL_TREE;
4163 	}
4164     }
4165   else if (!TYPE_READONLY (TREE_TYPE (argtypes[0])))
4166     {
4167       /* A read_only mode should ideally reference const-qualified
4168 	 arguments but it's not diagnosed error if one doesn't.
4169 	 This makes it possible to annotate legacy, const-incorrect
4170 	 APIs.  It might be worth a diagnostic along the lines of
4171 	 -Wsuggest-const.  */
4172       ;
4173     }
4174 
4175   if (argtypes[1] && !INTEGRAL_TYPE_P (argtypes[1]))
4176     {
4177       error ("attribute %qs positional argument 2 references "
4178 	     "non-integer argument type %qT",
4179 	     attrstr, argtypes[1]);
4180       return NULL_TREE;
4181     }
4182 
4183   /* Verify that the new attribute doesn't conflict with any existing
4184      attributes specified on previous declarations of the same type
4185      and if not, concatenate the two.  */
4186   const char code = read_only ? 'r' : write_only ? 'w' : 'x';
4187   tree new_attrs = append_access_attrs (node[0], attrs, attrstr, code, idxs);
4188   if (!new_attrs)
4189     return NULL_TREE;
4190 
4191   /* Replace any existing access attribute specification with
4192      the concatenation above.  */
4193   new_attrs = tree_cons (NULL_TREE, new_attrs, NULL_TREE);
4194   new_attrs = tree_cons (name, new_attrs, attrs);
4195 
4196   if (node[1])
4197     {
4198       /* Repeat for the previously declared type.  */
4199       attrs = TYPE_ATTRIBUTES (TREE_TYPE (node[1]));
4200       tree attrs1 = append_access_attrs (node[1], attrs, attrstr, code, idxs);
4201       if (!attrs1)
4202 	return NULL_TREE;
4203 
4204       attrs1 = tree_cons (NULL_TREE, attrs1, NULL_TREE);
4205       new_attrs = tree_cons (name, attrs1, attrs);
4206     }
4207 
4208   /* Recursively call self to "replace" the documented/external form
4209      of the attribute with the condensend internal form.  */
4210   decl_attributes (node, new_attrs, flags);
4211   return NULL_TREE;
4212 }
4213 
4214 /* Handle a "nothrow" attribute; arguments as in
4215    struct attribute_spec.handler.  */
4216 
4217 static tree
handle_nothrow_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)4218 handle_nothrow_attribute (tree *node, tree name, tree ARG_UNUSED (args),
4219 			  int ARG_UNUSED (flags), bool *no_add_attrs)
4220 {
4221   if (TREE_CODE (*node) == FUNCTION_DECL)
4222     TREE_NOTHROW (*node) = 1;
4223   /* ??? TODO: Support types.  */
4224   else
4225     {
4226       warning (OPT_Wattributes, "%qE attribute ignored", name);
4227       *no_add_attrs = true;
4228     }
4229 
4230   return NULL_TREE;
4231 }
4232 
4233 /* Handle a "cleanup" attribute; arguments as in
4234    struct attribute_spec.handler.  */
4235 
4236 static tree
handle_cleanup_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)4237 handle_cleanup_attribute (tree *node, tree name, tree args,
4238 			  int ARG_UNUSED (flags), bool *no_add_attrs)
4239 {
4240   tree decl = *node;
4241   tree cleanup_id, cleanup_decl;
4242 
4243   /* ??? Could perhaps support cleanups on TREE_STATIC, much like we do
4244      for global destructors in C++.  This requires infrastructure that
4245      we don't have generically at the moment.  It's also not a feature
4246      we'd be missing too much, since we do have attribute constructor.  */
4247   if (!VAR_P (decl) || TREE_STATIC (decl))
4248     {
4249       warning (OPT_Wattributes, "%qE attribute ignored", name);
4250       *no_add_attrs = true;
4251       return NULL_TREE;
4252     }
4253 
4254   /* Verify that the argument is a function in scope.  */
4255   /* ??? We could support pointers to functions here as well, if
4256      that was considered desirable.  */
4257   cleanup_id = TREE_VALUE (args);
4258   if (TREE_CODE (cleanup_id) != IDENTIFIER_NODE)
4259     {
4260       error ("cleanup argument not an identifier");
4261       *no_add_attrs = true;
4262       return NULL_TREE;
4263     }
4264   cleanup_decl = lookup_name (cleanup_id);
4265   if (!cleanup_decl || TREE_CODE (cleanup_decl) != FUNCTION_DECL)
4266     {
4267       error ("cleanup argument not a function");
4268       *no_add_attrs = true;
4269       return NULL_TREE;
4270     }
4271 
4272   /* That the function has proper type is checked with the
4273      eventual call to build_function_call.  */
4274 
4275   return NULL_TREE;
4276 }
4277 
4278 /* Handle a "warn_unused_result" attribute.  No special handling.  */
4279 
4280 static tree
handle_warn_unused_result_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)4281 handle_warn_unused_result_attribute (tree *node, tree name,
4282 			       tree ARG_UNUSED (args),
4283 			       int ARG_UNUSED (flags), bool *no_add_attrs)
4284 {
4285   /* Ignore the attribute for functions not returning any value.  */
4286   if (VOID_TYPE_P (TREE_TYPE (*node)))
4287     {
4288       warning (OPT_Wattributes, "%qE attribute ignored", name);
4289       *no_add_attrs = true;
4290     }
4291 
4292   return NULL_TREE;
4293 }
4294 
4295 /* Handle a "sentinel" attribute.  */
4296 
4297 static tree
handle_sentinel_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)4298 handle_sentinel_attribute (tree *node, tree name, tree args,
4299 			   int ARG_UNUSED (flags), bool *no_add_attrs)
4300 {
4301   if (!prototype_p (*node))
4302     {
4303       warning (OPT_Wattributes,
4304 	       "%qE attribute requires prototypes with named arguments", name);
4305       *no_add_attrs = true;
4306     }
4307   else
4308     {
4309       if (!stdarg_p (*node))
4310 	{
4311 	  warning (OPT_Wattributes,
4312 		   "%qE attribute only applies to variadic functions", name);
4313 	  *no_add_attrs = true;
4314 	}
4315     }
4316 
4317   if (args)
4318     {
4319       tree position = TREE_VALUE (args);
4320       if (position && TREE_CODE (position) != IDENTIFIER_NODE
4321 	  && TREE_CODE (position) != FUNCTION_DECL)
4322 	position = default_conversion (position);
4323 
4324       if (TREE_CODE (position) != INTEGER_CST
4325 	  || !INTEGRAL_TYPE_P (TREE_TYPE (position)))
4326 	{
4327 	  warning (OPT_Wattributes,
4328 		   "requested position is not an integer constant");
4329 	  *no_add_attrs = true;
4330 	}
4331       else
4332 	{
4333 	  if (tree_int_cst_lt (position, integer_zero_node))
4334 	    {
4335 	      warning (OPT_Wattributes,
4336 		       "requested position is less than zero");
4337 	      *no_add_attrs = true;
4338 	    }
4339 	}
4340     }
4341 
4342   return NULL_TREE;
4343 }
4344 
4345 /* Handle a "type_generic" attribute.  */
4346 
4347 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))4348 handle_type_generic_attribute (tree *node, tree ARG_UNUSED (name),
4349 			       tree ARG_UNUSED (args), int ARG_UNUSED (flags),
4350 			       bool * ARG_UNUSED (no_add_attrs))
4351 {
4352   /* Ensure we have a function type.  */
4353   gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
4354 
4355   /* Ensure we have a variadic function.  */
4356   gcc_assert (!prototype_p (*node) || stdarg_p (*node));
4357 
4358   return NULL_TREE;
4359 }
4360 
4361 /* Handle a "target" attribute.  */
4362 
4363 static tree
handle_target_attribute(tree * node,tree name,tree args,int flags,bool * no_add_attrs)4364 handle_target_attribute (tree *node, tree name, tree args, int flags,
4365 			 bool *no_add_attrs)
4366 {
4367   /* Ensure we have a function type.  */
4368   if (TREE_CODE (*node) != FUNCTION_DECL)
4369     {
4370       warning (OPT_Wattributes, "%qE attribute ignored", name);
4371       *no_add_attrs = true;
4372     }
4373   else if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (*node)))
4374     {
4375       warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
4376 		   "with %qs attribute", name, "target_clones");
4377       *no_add_attrs = true;
4378     }
4379   else if (! targetm.target_option.valid_attribute_p (*node, name, args,
4380 						      flags))
4381     *no_add_attrs = true;
4382 
4383   /* Check that there's no empty string in values of the attribute.  */
4384   for (tree t = args; t != NULL_TREE; t = TREE_CHAIN (t))
4385     {
4386       tree value = TREE_VALUE (t);
4387       if (TREE_CODE (value) == STRING_CST
4388 	  && TREE_STRING_LENGTH (value) == 1
4389 	  && TREE_STRING_POINTER (value)[0] == '\0')
4390 	{
4391 	  warning (OPT_Wattributes, "empty string in attribute %<target%>");
4392 	  *no_add_attrs = true;
4393 	}
4394     }
4395 
4396   return NULL_TREE;
4397 }
4398 
4399 /* Handle a "target_clones" attribute.  */
4400 
4401 static tree
handle_target_clones_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)4402 handle_target_clones_attribute (tree *node, tree name, tree ARG_UNUSED (args),
4403 			  int ARG_UNUSED (flags), bool *no_add_attrs)
4404 {
4405   /* Ensure we have a function type.  */
4406   if (TREE_CODE (*node) == FUNCTION_DECL)
4407     {
4408       if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (*node)))
4409 	{
4410 	  warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
4411 		   "with %qs attribute", name, "always_inline");
4412 	  *no_add_attrs = true;
4413 	}
4414       else if (lookup_attribute ("target", DECL_ATTRIBUTES (*node)))
4415 	{
4416 	  warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
4417 		   "with %qs attribute", name, "target");
4418 	  *no_add_attrs = true;
4419 	}
4420       else
4421       /* Do not inline functions with multiple clone targets.  */
4422 	DECL_UNINLINABLE (*node) = 1;
4423     }
4424   else
4425     {
4426       warning (OPT_Wattributes, "%qE attribute ignored", name);
4427       *no_add_attrs = true;
4428     }
4429   return NULL_TREE;
4430 }
4431 
4432 /* For handling "optimize" attribute. arguments as in
4433    struct attribute_spec.handler.  */
4434 
4435 static tree
handle_optimize_attribute(tree * node,tree name,tree args,int ARG_UNUSED (flags),bool * no_add_attrs)4436 handle_optimize_attribute (tree *node, tree name, tree args,
4437 			   int ARG_UNUSED (flags), bool *no_add_attrs)
4438 {
4439   /* Ensure we have a function type.  */
4440   if (TREE_CODE (*node) != FUNCTION_DECL)
4441     {
4442       warning (OPT_Wattributes, "%qE attribute ignored", name);
4443       *no_add_attrs = true;
4444     }
4445   else
4446     {
4447       struct cl_optimization cur_opts;
4448       tree old_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node);
4449 
4450       /* Save current options.  */
4451       cl_optimization_save (&cur_opts, &global_options);
4452 
4453       /* If we previously had some optimization options, use them as the
4454 	 default.  */
4455       if (old_opts)
4456 	cl_optimization_restore (&global_options,
4457 				 TREE_OPTIMIZATION (old_opts));
4458 
4459       /* Parse options, and update the vector.  */
4460       parse_optimize_options (args, true);
4461       DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node)
4462 	= build_optimization_node (&global_options);
4463 
4464       /* Restore current options.  */
4465       cl_optimization_restore (&global_options, &cur_opts);
4466     }
4467 
4468   return NULL_TREE;
4469 }
4470 
4471 /* Handle a "no_split_stack" attribute.  */
4472 
4473 static tree
handle_no_split_stack_attribute(tree * node,tree name,tree ARG_UNUSED (args),int ARG_UNUSED (flags),bool * no_add_attrs)4474 handle_no_split_stack_attribute (tree *node, tree name,
4475 				 tree ARG_UNUSED (args),
4476 				 int ARG_UNUSED (flags),
4477 				 bool *no_add_attrs)
4478 {
4479   tree decl = *node;
4480 
4481   if (TREE_CODE (decl) != FUNCTION_DECL)
4482     {
4483       error_at (DECL_SOURCE_LOCATION (decl),
4484 		"%qE attribute applies only to functions", name);
4485       *no_add_attrs = true;
4486     }
4487   else if (DECL_INITIAL (decl))
4488     {
4489       error_at (DECL_SOURCE_LOCATION (decl),
4490 		"cannot set %qE attribute after definition", name);
4491       *no_add_attrs = true;
4492     }
4493 
4494   return NULL_TREE;
4495 }
4496 
4497 /* Handle a "returns_nonnull" attribute; arguments as in
4498    struct attribute_spec.handler.  */
4499 
4500 static tree
handle_returns_nonnull_attribute(tree * node,tree name,tree,int,bool * no_add_attrs)4501 handle_returns_nonnull_attribute (tree *node, tree name, tree, int,
4502 				  bool *no_add_attrs)
4503 {
4504   // Even without a prototype we still have a return type we can check.
4505   if (TREE_CODE (TREE_TYPE (*node)) != POINTER_TYPE)
4506     {
4507       error ("%qE attribute on a function not returning a pointer", name);
4508       *no_add_attrs = true;
4509     }
4510   return NULL_TREE;
4511 }
4512 
4513 /* Handle a "designated_init" attribute; arguments as in
4514    struct attribute_spec.handler.  */
4515 
4516 static tree
handle_designated_init_attribute(tree * node,tree name,tree,int,bool * no_add_attrs)4517 handle_designated_init_attribute (tree *node, tree name, tree, int,
4518 				  bool *no_add_attrs)
4519 {
4520   if (TREE_CODE (*node) != RECORD_TYPE)
4521     {
4522       error ("%qE attribute is only valid on %<struct%> type", name);
4523       *no_add_attrs = true;
4524     }
4525   return NULL_TREE;
4526 }
4527 
4528 
4529 /* Handle a "fallthrough" attribute; arguments as in struct
4530    attribute_spec.handler.  */
4531 
4532 tree
handle_fallthrough_attribute(tree *,tree name,tree,int,bool * no_add_attrs)4533 handle_fallthrough_attribute (tree *, tree name, tree, int,
4534 			      bool *no_add_attrs)
4535 {
4536   pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored", name);
4537   *no_add_attrs = true;
4538   return NULL_TREE;
4539 }
4540 
4541 /* Handle a "patchable_function_entry" attributes; arguments as in
4542    struct attribute_spec.handler.  */
4543 
4544 static tree
handle_patchable_function_entry_attribute(tree *,tree name,tree args,int,bool * no_add_attrs)4545 handle_patchable_function_entry_attribute (tree *, tree name, tree args,
4546 					   int, bool *no_add_attrs)
4547 {
4548   for (; args; args = TREE_CHAIN (args))
4549     {
4550       tree val = TREE_VALUE (args);
4551       if (val && TREE_CODE (val) != IDENTIFIER_NODE
4552 	  && TREE_CODE (val) != FUNCTION_DECL)
4553 	val = default_conversion (val);
4554 
4555       if (!tree_fits_uhwi_p (val))
4556 	{
4557 	  warning (OPT_Wattributes,
4558 		   "%qE attribute argument %qE is not an integer constant",
4559 		   name, val);
4560 	  *no_add_attrs = true;
4561 	  return NULL_TREE;
4562 	}
4563     }
4564   return NULL_TREE;
4565 }
4566 
4567 /* Attempt to partially validate a single attribute ATTR as if
4568    it were to be applied to an entity OPER.  */
4569 
4570 static bool
validate_attribute(location_t atloc,tree oper,tree attr)4571 validate_attribute (location_t atloc, tree oper, tree attr)
4572 {
4573   /* Determine whether the name of the attribute is valid
4574      and fail with an error if not.  */
4575   tree atname = get_attribute_name (attr);
4576   if (!lookup_attribute_spec (atname))
4577     {
4578       if (atloc != UNKNOWN_LOCATION)
4579 	error_at (atloc, "unknown attribute %qE", atname);
4580       return false;
4581     }
4582 
4583   tree args = TREE_VALUE (attr);
4584   if (!args)
4585     return true;
4586 
4587   /* FIXME: Do some validation.  */
4588   const char *atstr = IDENTIFIER_POINTER (atname);
4589   if (!strcmp (atstr, "format"))
4590     return true;
4591 
4592   /* Only when attribute arguments have been provided try to validate
4593      the whole thing.  decl_attributes doesn't return an indication of
4594      success or failure so proceed regardless.  */
4595   const char tmpname[] = "__builtin_has_attribute_tmp.";
4596   tree tmpid = get_identifier (tmpname);
4597   tree tmpdecl;
4598   if (!strcmp (atstr, "vector_size"))
4599     {
4600       tree type = TYPE_P (oper) ? oper : TREE_TYPE (oper);
4601       /* Check for function type here since type_for_vector_size
4602 	 strips it while looking for a function's return type.  */
4603       if (FUNC_OR_METHOD_TYPE_P (type))
4604 	{
4605 	  warning_at (atloc, OPT_Wattributes,
4606 		      "invalid operand type %qT for %qs", type, atstr);
4607 	  return false;
4608 	}
4609 
4610       type = type_for_vector_size (type);
4611       if (VECTOR_TYPE_P (type))
4612 	type = TREE_TYPE (type);
4613       /* Avoid trying to apply attribute vector_size to OPER since
4614 	 it's overly restrictive.  Simply make sure it has the right
4615 	 type.  */
4616       return type_valid_for_vector_size (type, atname, args, NULL);
4617     }
4618 
4619   if (TYPE_P (oper))
4620     tmpdecl = build_decl (atloc, TYPE_DECL, tmpid, oper);
4621   else if (DECL_P (oper))
4622     tmpdecl = build_decl (atloc, TREE_CODE (oper), tmpid, TREE_TYPE (oper));
4623   else if (EXPR_P (oper))
4624     tmpdecl = build_decl (atloc, TYPE_DECL, tmpid, TREE_TYPE (oper));
4625   else
4626     return false;
4627 
4628   /* Temporarily clear CURRENT_FUNCTION_DECL to make decl_attributes
4629      believe the DECL declared above is at file scope.  (See bug 87526.)  */
4630   tree save_curfunc = current_function_decl;
4631   current_function_decl = NULL_TREE;
4632   if (DECL_P (tmpdecl))
4633     {
4634       if (DECL_P (oper))
4635 	/* An alias cannot be a definition so declare the symbol extern.  */
4636 	DECL_EXTERNAL (tmpdecl) = true;
4637       /* Attribute visibility only applies to symbols visible from other
4638 	 translation units so make it "public."   */
4639       TREE_PUBLIC (tmpdecl) = TREE_PUBLIC (oper);
4640     }
4641   decl_attributes (&tmpdecl, attr, 0);
4642   current_function_decl = save_curfunc;
4643 
4644   /* FIXME: Change decl_attributes to indicate success or failure (and
4645      parameterize it to avoid failing with errors).  */
4646   return true;
4647 }
4648 
4649 /* Return true if the DECL, EXPR, or TYPE t has been declared with
4650    attribute ATTR.  For DECL, consider also its type.  For EXPR,
4651    consider just its type.  */
4652 
4653 bool
has_attribute(location_t atloc,tree t,tree attr,tree (* convert)(tree))4654 has_attribute (location_t atloc, tree t, tree attr, tree (*convert)(tree))
4655 {
4656   if (!attr || !t || t == error_mark_node)
4657     return false;
4658 
4659   if (!validate_attribute (atloc, t, attr))
4660     return false;
4661 
4662   tree type = NULL_TREE;
4663   tree expr = NULL_TREE;
4664   if (TYPE_P (t))
4665     type = t;
4666   else
4667     {
4668       do
4669 	{
4670 	  /* Determine the array element/member declaration from
4671 	     a COMPONENT_REF and an INDIRECT_REF involving a refeence.  */
4672 	  STRIP_NOPS (t);
4673 	  tree_code code = TREE_CODE (t);
4674 	  if (code == INDIRECT_REF)
4675 	    {
4676 	      tree op0 = TREE_OPERAND (t, 0);
4677 	      if (TREE_CODE (TREE_TYPE (op0)) == REFERENCE_TYPE)
4678 		t = op0;
4679 	      else
4680 		break;
4681 	    }
4682 	  else if (code == COMPONENT_REF)
4683 	    t = TREE_OPERAND (t, 1);
4684 	  else
4685 	    break;
4686 	} while (true);
4687       expr = t;
4688     }
4689 
4690   /* Set to true when an attribute is found in the referenced entity
4691      that matches the specified attribute.  */
4692   bool found_match = false;
4693 
4694   tree atname = get_attribute_name (attr);
4695   const char *namestr = IDENTIFIER_POINTER (atname);
4696 
4697    /* Iterate once for a type and twice for a function or variable
4698      declaration: once for the DECL and the second time for its
4699      TYPE.  */
4700   for (bool done = false; !found_match && !done; )
4701     {
4702       tree atlist;
4703       if (type)
4704 	{
4705 	  if (type == error_mark_node)
4706 	    {
4707 	      /* This could be a label.  FIXME: add support for labels.  */
4708 	      warning_at (atloc, OPT_Wattributes,
4709 			  (TYPE_P (t)
4710 			   ? G_("%qs attribute not supported for %qT "
4711 				"in %<__builtin_has_attribute%>")
4712 			   : G_("%qs attribute not supported for %qE "
4713 				"in %<__builtin_has_attribute%>")),
4714 			  namestr, t);
4715 	      return false;
4716 	    }
4717 
4718 	  /* Clear EXPR to prevent considering it again below.  */
4719 	  atlist = TYPE_ATTRIBUTES (type);
4720 	  expr = NULL_TREE;
4721 	  done = true;
4722 	}
4723       else if (DECL_P (expr))
4724 	{
4725 	  /* Set TYPE to the DECL's type to process it on the next
4726 	     iteration.  */
4727 	  atlist = DECL_ATTRIBUTES (expr);
4728 	  type = TREE_TYPE (expr);
4729 	}
4730       else
4731 	{
4732 	  type = TREE_TYPE (expr);
4733 	  atlist = TYPE_ATTRIBUTES (type);
4734 	  done = true;
4735 	}
4736 
4737      /* True when an attribute with the sought name (though not necessarily
4738 	 with the sought attributes) has been found on the attribute chain.  */
4739       bool found_attr = false;
4740 
4741       /* When clear, the first mismatched attribute argument results
4742 	 in failure.  Otherwise, the first matched attribute argument
4743 	 results in success.  */
4744       bool attr_nonnull = !strcmp ("nonnull", namestr);
4745       bool ignore_mismatches = attr_nonnull;
4746 
4747       /* Iterate over the instances of the sought attribute on the DECL or
4748 	 TYPE (there may be multiple instances with different arguments).  */
4749       for (; (atlist = lookup_attribute (namestr, atlist));
4750 	   found_attr = true, atlist = TREE_CHAIN (atlist))
4751 	{
4752 	  /* If there are no arguments to match the result is true except
4753 	     for nonnull where the attribute with no arguments must match.  */
4754 	  if (!TREE_VALUE (attr))
4755 	    return attr_nonnull ? !TREE_VALUE (atlist) : true;
4756 
4757 	  /* Attribute nonnull with no arguments subsumes all values of
4758 	     the attribute.  FIXME: This is overly broad since it only
4759 	     applies to pointer arguments, but querying non-pointer
4760 	     arguments is diagnosed.  */
4761 	  if (!TREE_VALUE (atlist) && attr_nonnull)
4762 	    return true;
4763 
4764 	  /* Iterate over the DECL or TYPE attribute argument's values.  */
4765 	  for (tree val = TREE_VALUE (atlist); val; val = TREE_CHAIN (val))
4766 	    {
4767 	      /* Iterate over the arguments in the sought attribute comparing
4768 		 their values to those specified for the DECL or TYPE.  */
4769 	      for (tree arg = TREE_VALUE (attr); arg; arg = TREE_CHAIN (arg))
4770 		{
4771 		  tree v1 = TREE_VALUE (val);
4772 		  tree v2 = TREE_VALUE (arg);
4773 		  if (v1 == v2)
4774 		    return true;
4775 
4776 		  if (!v1 || !v2)
4777 		    break;
4778 
4779 		  if (TREE_CODE (v1) == IDENTIFIER_NODE
4780 		      || TREE_CODE (v2) == IDENTIFIER_NODE)
4781 		    /* Two identifiers are the same if their values are
4782 		       equal (that's handled above).  Otherwise ther are
4783 		       either not the same or oneis not an identifier.  */
4784 		    return false;
4785 
4786 		  /* Convert to make them equality-comparable.  */
4787 		  v1 = convert (v1);
4788 		  v2 = convert (v2);
4789 
4790 		  /* A positive value indicates equality, negative means
4791 		     "don't know."  */
4792 		  if (simple_cst_equal (v1, v2) == 1)
4793 		    return true;
4794 
4795 		  if (!ignore_mismatches)
4796 		    break;
4797 		}
4798 	    }
4799 	}
4800 
4801       if (!found_attr)
4802 	{
4803 	  /* Some attributes are encoded directly in the tree node.  */
4804 	  if (!strcmp ("aligned", namestr))
4805 	    {
4806 	      if (tree arg = TREE_VALUE (attr))
4807 		{
4808 		  arg = convert (TREE_VALUE (arg));
4809 		  if (!tree_fits_uhwi_p (arg))
4810 		    /* Invalid argument.  */;
4811 		  else if (expr && DECL_P (expr)
4812 			   && DECL_USER_ALIGN (expr))
4813 		    found_match = DECL_ALIGN_UNIT (expr) == tree_to_uhwi (arg);
4814 		  else if (type && TYPE_USER_ALIGN (type))
4815 		    found_match = TYPE_ALIGN_UNIT (type) == tree_to_uhwi (arg);
4816 		}
4817 	      else if (expr && DECL_P (expr))
4818 		found_match = DECL_USER_ALIGN (expr);
4819 	      else if (type)
4820 		found_match = TYPE_USER_ALIGN (type);
4821 	    }
4822 	  else if (!strcmp ("const", namestr))
4823 	    {
4824 	      if (expr && DECL_P (expr))
4825 		found_match = TREE_READONLY (expr);
4826 	    }
4827 	  else if (!strcmp ("noreturn", namestr))
4828 	    {
4829 	      /* C11 _Noreturn sets the volatile bit without attaching
4830 		 an attribute to the decl.  */
4831 	      if (expr
4832 		  && DECL_P (expr)
4833 		  && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (expr)))
4834 		found_match = TREE_THIS_VOLATILE (expr);
4835 	    }
4836 	  else if (!strcmp ("pure", namestr))
4837 	    {
4838 	      if (expr && DECL_P (expr))
4839 		found_match = DECL_PURE_P (expr);
4840 	    }
4841 	  else if (!strcmp ("deprecated", namestr))
4842 	    {
4843 	      found_match = TREE_DEPRECATED (expr ? expr : type);
4844 	      if (found_match)
4845 		return true;
4846 	    }
4847 	  else if (!strcmp ("vector_size", namestr))
4848 	    {
4849 	      if (!type || !VECTOR_TYPE_P (type))
4850 		return false;
4851 
4852 	      if (tree arg = TREE_VALUE (attr))
4853 		{
4854 		  /* Compare the vector size argument for equality.  */
4855 		  arg = convert (TREE_VALUE (arg));
4856 		  return tree_int_cst_equal (arg, TYPE_SIZE_UNIT (type)) == 1;
4857 		}
4858 	      else
4859 		return true;
4860 	    }
4861 	  else if (!strcmp ("warn_if_not_aligned", namestr))
4862 	    {
4863 	      if (tree arg = TREE_VALUE (attr))
4864 		{
4865 		  arg = convert (TREE_VALUE (arg));
4866 		  if (expr && DECL_P (expr))
4867 		    found_match = (DECL_WARN_IF_NOT_ALIGN (expr)
4868 				   == tree_to_uhwi (arg) * BITS_PER_UNIT);
4869 		  else if (type)
4870 		    found_match = (TYPE_WARN_IF_NOT_ALIGN (type)
4871 				   == tree_to_uhwi (arg) * BITS_PER_UNIT);
4872 		}
4873 	      else if (expr && DECL_P (expr))
4874 		found_match = DECL_WARN_IF_NOT_ALIGN (expr);
4875 	      else if (type)
4876 		found_match = TYPE_WARN_IF_NOT_ALIGN (type);
4877 	    }
4878 	  else if (!strcmp ("transparent_union", namestr))
4879 	    {
4880 	      if (type)
4881 		found_match = TYPE_TRANSPARENT_AGGR (type) != 0;
4882 	    }
4883 	  else if (!strcmp ("mode", namestr))
4884 	    {
4885 	      /* Finally issue a warning for attributes that cannot
4886 		 be supported in this context.  Attribute mode is not
4887 		 added to a symbol and cannot be determined from it.  */
4888 	      warning_at (atloc, OPT_Wattributes,
4889 			  "%qs attribute not supported in "
4890 			  "%<__builtin_has_attribute%>", namestr);
4891 	      break;
4892 	    }
4893 	}
4894     }
4895   return found_match;
4896 }
4897