xref: /netbsd-src/external/gpl3/gcc/dist/gcc/attribs.cc (revision 0a3071956a3a9fdebdbf7f338cf2d439b45fc728)
1 /* Functions dealing with attribute handling, used by most front ends.
2    Copyright (C) 1992-2022 Free Software Foundation, Inc.
3 
4 This file is part of GCC.
5 
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10 
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19 
20 #define INCLUDE_STRING
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "target.h"
25 #include "tree.h"
26 #include "stringpool.h"
27 #include "diagnostic-core.h"
28 #include "attribs.h"
29 #include "fold-const.h"
30 #include "stor-layout.h"
31 #include "langhooks.h"
32 #include "plugin.h"
33 #include "selftest.h"
34 #include "hash-set.h"
35 #include "diagnostic.h"
36 #include "pretty-print.h"
37 #include "tree-pretty-print.h"
38 #include "intl.h"
39 
40 /* Table of the tables of attributes (common, language, format, machine)
41    searched.  */
42 static const struct attribute_spec *attribute_tables[4];
43 
44 /* Substring representation.  */
45 
46 struct substring
47 {
48   const char *str;
49   int length;
50 };
51 
52 /* Simple hash function to avoid need to scan whole string.  */
53 
54 static inline hashval_t
substring_hash(const char * str,int l)55 substring_hash (const char *str, int l)
56 {
57   return str[0] + str[l - 1] * 256 + l * 65536;
58 }
59 
60 /* Used for attribute_hash.  */
61 
62 struct attribute_hasher : nofree_ptr_hash <attribute_spec>
63 {
64   typedef substring *compare_type;
65   static inline hashval_t hash (const attribute_spec *);
66   static inline bool equal (const attribute_spec *, const substring *);
67 };
68 
69 inline hashval_t
hash(const attribute_spec * spec)70 attribute_hasher::hash (const attribute_spec *spec)
71 {
72   const int l = strlen (spec->name);
73   return substring_hash (spec->name, l);
74 }
75 
76 inline bool
equal(const attribute_spec * spec,const substring * str)77 attribute_hasher::equal (const attribute_spec *spec, const substring *str)
78 {
79   return (strncmp (spec->name, str->str, str->length) == 0
80 	  && !spec->name[str->length]);
81 }
82 
83 /* Scoped attribute name representation.  */
84 
85 struct scoped_attributes
86 {
87   const char *ns;
88   vec<attribute_spec> attributes;
89   hash_table<attribute_hasher> *attribute_hash;
90   /* True if we should not warn about unknown attributes in this NS.  */
91   bool ignored_p;
92 };
93 
94 /* The table of scope attributes.  */
95 static vec<scoped_attributes> attributes_table;
96 
97 static scoped_attributes* find_attribute_namespace (const char*);
98 static void register_scoped_attribute (const struct attribute_spec *,
99 				       scoped_attributes *);
100 static const struct attribute_spec *lookup_scoped_attribute_spec (const_tree,
101 								  const_tree);
102 
103 static bool attributes_initialized = false;
104 
105 /* Default empty table of attributes.  */
106 
107 static const struct attribute_spec empty_attribute_table[] =
108 {
109   { NULL, 0, 0, false, false, false, false, NULL, NULL }
110 };
111 
112 /* Insert an array of attributes ATTRIBUTES into a namespace.  This
113    array must be NULL terminated.  NS is the name of attribute
114    namespace.  IGNORED_P is true iff all unknown attributes in this
115    namespace should be ignored for the purposes of -Wattributes.  The
116    function returns the namespace into which the attributes have been
117    registered.  */
118 
119 scoped_attributes *
register_scoped_attributes(const struct attribute_spec * attributes,const char * ns,bool ignored_p)120 register_scoped_attributes (const struct attribute_spec *attributes,
121 			    const char *ns, bool ignored_p /*=false*/)
122 {
123   scoped_attributes *result = NULL;
124 
125   /* See if we already have attributes in the namespace NS.  */
126   result = find_attribute_namespace (ns);
127 
128   if (result == NULL)
129     {
130       /* We don't have any namespace NS yet.  Create one.  */
131       scoped_attributes sa;
132 
133       if (attributes_table.is_empty ())
134 	attributes_table.create (64);
135 
136       memset (&sa, 0, sizeof (sa));
137       sa.ns = ns;
138       sa.attributes.create (64);
139       sa.ignored_p = ignored_p;
140       result = attributes_table.safe_push (sa);
141       result->attribute_hash = new hash_table<attribute_hasher> (200);
142     }
143   else
144     result->ignored_p |= ignored_p;
145 
146   /* Really add the attributes to their namespace now.  */
147   for (unsigned i = 0; attributes[i].name != NULL; ++i)
148     {
149       result->attributes.safe_push (attributes[i]);
150       register_scoped_attribute (&attributes[i], result);
151     }
152 
153   gcc_assert (result != NULL);
154 
155   return result;
156 }
157 
158 /* Return the namespace which name is NS, NULL if none exist.  */
159 
160 static scoped_attributes*
find_attribute_namespace(const char * ns)161 find_attribute_namespace (const char* ns)
162 {
163   for (scoped_attributes &iter : attributes_table)
164     if (ns == iter.ns
165 	|| (iter.ns != NULL
166 	    && ns != NULL
167 	    && !strcmp (iter.ns, ns)))
168       return &iter;
169   return NULL;
170 }
171 
172 /* Make some sanity checks on the attribute tables.  */
173 
174 static void
check_attribute_tables(void)175 check_attribute_tables (void)
176 {
177   for (size_t i = 0; i < ARRAY_SIZE (attribute_tables); i++)
178     for (size_t j = 0; attribute_tables[i][j].name != NULL; j++)
179       {
180 	/* The name must not begin and end with __.  */
181 	const char *name = attribute_tables[i][j].name;
182 	int len = strlen (name);
183 
184 	gcc_assert (!(name[0] == '_' && name[1] == '_'
185 		      && name[len - 1] == '_' && name[len - 2] == '_'));
186 
187 	/* The minimum and maximum lengths must be consistent.  */
188 	gcc_assert (attribute_tables[i][j].min_length >= 0);
189 
190 	gcc_assert (attribute_tables[i][j].max_length == -1
191 		    || (attribute_tables[i][j].max_length
192 			>= attribute_tables[i][j].min_length));
193 
194 	/* An attribute cannot require both a DECL and a TYPE.  */
195 	gcc_assert (!attribute_tables[i][j].decl_required
196 		    || !attribute_tables[i][j].type_required);
197 
198 	  /* If an attribute requires a function type, in particular
199 	     it requires a type.  */
200 	gcc_assert (!attribute_tables[i][j].function_type_required
201 		    || attribute_tables[i][j].type_required);
202       }
203 
204   /* Check that each name occurs just once in each table.  */
205   for (size_t i = 0; i < ARRAY_SIZE (attribute_tables); i++)
206     for (size_t j = 0; attribute_tables[i][j].name != NULL; j++)
207       for (size_t k = j + 1; attribute_tables[i][k].name != NULL; k++)
208 	gcc_assert (strcmp (attribute_tables[i][j].name,
209 			    attribute_tables[i][k].name));
210 
211   /* Check that no name occurs in more than one table.  Names that
212      begin with '*' are exempt, and may be overridden.  */
213   for (size_t i = 0; i < ARRAY_SIZE (attribute_tables); i++)
214     for (size_t j = i + 1; j < ARRAY_SIZE (attribute_tables); j++)
215       for (size_t k = 0; attribute_tables[i][k].name != NULL; k++)
216 	for (size_t l = 0; attribute_tables[j][l].name != NULL; l++)
217 	  gcc_assert (attribute_tables[i][k].name[0] == '*'
218 		      || strcmp (attribute_tables[i][k].name,
219 				 attribute_tables[j][l].name));
220 }
221 
222 /* Used to stash pointers to allocated memory so that we can free them at
223    the end of parsing of all TUs. */
224 static vec<attribute_spec *> ignored_attributes_table;
225 
226 /* Parse arguments V of -Wno-attributes=.
227    Currently we accept:
228      vendor::attr
229      vendor::
230    This functions also registers the parsed attributes so that we don't
231    warn that we don't recognize them.  */
232 
233 void
handle_ignored_attributes_option(vec<char * > * v)234 handle_ignored_attributes_option (vec<char *> *v)
235 {
236   if (v == nullptr)
237     return;
238 
239   for (auto opt : v)
240     {
241       char *cln = strstr (opt, "::");
242       /* We don't accept '::attr'.  */
243       if (cln == nullptr || cln == opt)
244 	{
245 	  error ("wrong argument to ignored attributes");
246 	  inform (input_location, "valid format is %<ns::attr%> or %<ns::%>");
247 	  continue;
248 	}
249       const char *vendor_start = opt;
250       ptrdiff_t vendor_len = cln - opt;
251       const char *attr_start = cln + 2;
252       /* This could really use rawmemchr :(.  */
253       ptrdiff_t attr_len = strchr (attr_start, '\0') - attr_start;
254       /* Verify that they look valid.  */
255       auto valid_p = [](const char *const s, ptrdiff_t len) {
256 	bool ok = false;
257 
258 	for (int i = 0; i < len; ++i)
259 	  if (ISALNUM (s[i]))
260 	    ok = true;
261 	  else if (s[i] != '_')
262 	    return false;
263 
264 	return ok;
265       };
266       if (!valid_p (vendor_start, vendor_len))
267 	{
268 	  error ("wrong argument to ignored attributes");
269 	  continue;
270 	}
271       canonicalize_attr_name (vendor_start, vendor_len);
272       /* We perform all this hijinks so that we don't have to copy OPT.  */
273       tree vendor_id = get_identifier_with_length (vendor_start, vendor_len);
274       const char *attr;
275       /* In the "vendor::" case, we should ignore *any* attribute coming
276 	 from this attribute namespace.  */
277       if (attr_len > 0)
278 	{
279 	  if (!valid_p (attr_start, attr_len))
280 	    {
281 	      error ("wrong argument to ignored attributes");
282 	      continue;
283 	    }
284 	  canonicalize_attr_name (attr_start, attr_len);
285 	  tree attr_id = get_identifier_with_length (attr_start, attr_len);
286 	  attr = IDENTIFIER_POINTER (attr_id);
287 	  /* If we've already seen this vendor::attr, ignore it.  Attempting to
288 	     register it twice would lead to a crash.  */
289 	  if (lookup_scoped_attribute_spec (vendor_id, attr_id))
290 	    continue;
291 	}
292       else
293 	attr = nullptr;
294       /* Create a table with extra attributes which we will register.
295 	 We can't free it here, so squirrel away the pointers.  */
296       attribute_spec *table = new attribute_spec[2];
297       ignored_attributes_table.safe_push (table);
298       table[0] = { attr, 0, -2, false, false, false, false, nullptr, nullptr };
299       table[1] = { nullptr, 0, 0, false, false, false, false, nullptr,
300 		   nullptr };
301       register_scoped_attributes (table, IDENTIFIER_POINTER (vendor_id), !attr);
302     }
303 }
304 
305 /* Free data we might have allocated when adding extra attributes.  */
306 
307 void
free_attr_data()308 free_attr_data ()
309 {
310   for (auto x : ignored_attributes_table)
311     delete[] x;
312   ignored_attributes_table.release ();
313 }
314 
315 /* Initialize attribute tables, and make some sanity checks if checking is
316    enabled.  */
317 
318 void
init_attributes(void)319 init_attributes (void)
320 {
321   size_t i;
322 
323   if (attributes_initialized)
324     return;
325 
326   attribute_tables[0] = lang_hooks.common_attribute_table;
327   attribute_tables[1] = lang_hooks.attribute_table;
328   attribute_tables[2] = lang_hooks.format_attribute_table;
329   attribute_tables[3] = targetm.attribute_table;
330 
331   /* Translate NULL pointers to pointers to the empty table.  */
332   for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
333     if (attribute_tables[i] == NULL)
334       attribute_tables[i] = empty_attribute_table;
335 
336   if (flag_checking)
337     check_attribute_tables ();
338 
339   for (i = 0; i < ARRAY_SIZE (attribute_tables); ++i)
340     /* Put all the GNU attributes into the "gnu" namespace.  */
341     register_scoped_attributes (attribute_tables[i], "gnu");
342 
343   vec<char *> *ignored = (vec<char *> *) flag_ignored_attributes;
344   handle_ignored_attributes_option (ignored);
345 
346   invoke_plugin_callbacks (PLUGIN_ATTRIBUTES, NULL);
347   attributes_initialized = true;
348 }
349 
350 /* Insert a single ATTR into the attribute table.  */
351 
352 void
register_attribute(const struct attribute_spec * attr)353 register_attribute (const struct attribute_spec *attr)
354 {
355   register_scoped_attribute (attr, find_attribute_namespace ("gnu"));
356 }
357 
358 /* Insert a single attribute ATTR into a namespace of attributes.  */
359 
360 static void
register_scoped_attribute(const struct attribute_spec * attr,scoped_attributes * name_space)361 register_scoped_attribute (const struct attribute_spec *attr,
362 			   scoped_attributes *name_space)
363 {
364   struct substring str;
365   attribute_spec **slot;
366 
367   gcc_assert (attr != NULL && name_space != NULL);
368 
369   gcc_assert (name_space->attribute_hash);
370 
371   str.str = attr->name;
372   str.length = strlen (str.str);
373 
374   /* Attribute names in the table must be in the form 'text' and not
375      in the form '__text__'.  */
376   gcc_checking_assert (!canonicalize_attr_name (str.str, str.length));
377 
378   slot = name_space->attribute_hash
379 	 ->find_slot_with_hash (&str, substring_hash (str.str, str.length),
380 				INSERT);
381   gcc_assert (!*slot || attr->name[0] == '*');
382   *slot = CONST_CAST (struct attribute_spec *, attr);
383 }
384 
385 /* Return the spec for the scoped attribute with namespace NS and
386    name NAME.   */
387 
388 static const struct attribute_spec *
lookup_scoped_attribute_spec(const_tree ns,const_tree name)389 lookup_scoped_attribute_spec (const_tree ns, const_tree name)
390 {
391   struct substring attr;
392   scoped_attributes *attrs;
393 
394   const char *ns_str = (ns != NULL_TREE) ? IDENTIFIER_POINTER (ns): NULL;
395 
396   attrs = find_attribute_namespace (ns_str);
397 
398   if (attrs == NULL)
399     return NULL;
400 
401   attr.str = IDENTIFIER_POINTER (name);
402   attr.length = IDENTIFIER_LENGTH (name);
403   return attrs->attribute_hash->find_with_hash (&attr,
404 						substring_hash (attr.str,
405 							       	attr.length));
406 }
407 
408 /* Return the spec for the attribute named NAME.  If NAME is a TREE_LIST,
409    it also specifies the attribute namespace.  */
410 
411 const struct attribute_spec *
lookup_attribute_spec(const_tree name)412 lookup_attribute_spec (const_tree name)
413 {
414   tree ns;
415   if (TREE_CODE (name) == TREE_LIST)
416     {
417       ns = TREE_PURPOSE (name);
418       name = TREE_VALUE (name);
419     }
420   else
421     ns = get_identifier ("gnu");
422   return lookup_scoped_attribute_spec (ns, name);
423 }
424 
425 
426 /* Return the namespace of the attribute ATTR.  This accessor works on
427    GNU and C++11 (scoped) attributes.  On GNU attributes,
428    it returns an identifier tree for the string "gnu".
429 
430    Please read the comments of cxx11_attribute_p to understand the
431    format of attributes.  */
432 
433 tree
get_attribute_namespace(const_tree attr)434 get_attribute_namespace (const_tree attr)
435 {
436   if (cxx11_attribute_p (attr))
437     return TREE_PURPOSE (TREE_PURPOSE (attr));
438   return get_identifier ("gnu");
439 }
440 
441 /* Check LAST_DECL and NODE of the same symbol for attributes that are
442    recorded in SPEC to be mutually exclusive with ATTRNAME, diagnose
443    them, and return true if any have been found.  NODE can be a DECL
444    or a TYPE.  */
445 
446 static bool
diag_attr_exclusions(tree last_decl,tree node,tree attrname,const attribute_spec * spec)447 diag_attr_exclusions (tree last_decl, tree node, tree attrname,
448 		      const attribute_spec *spec)
449 {
450   const attribute_spec::exclusions *excl = spec->exclude;
451 
452   tree_code code = TREE_CODE (node);
453 
454   if ((code == FUNCTION_DECL && !excl->function
455        && (!excl->type || !spec->affects_type_identity))
456       || (code == VAR_DECL && !excl->variable
457 	  && (!excl->type || !spec->affects_type_identity))
458       || (((code == TYPE_DECL || RECORD_OR_UNION_TYPE_P (node)) && !excl->type)))
459     return false;
460 
461   /* True if an attribute that's mutually exclusive with ATTRNAME
462      has been found.  */
463   bool found = false;
464 
465   if (last_decl && last_decl != node && TREE_TYPE (last_decl) != node)
466     {
467       /* Check both the last DECL and its type for conflicts with
468 	 the attribute being added to the current decl or type.  */
469       found |= diag_attr_exclusions (last_decl, last_decl, attrname, spec);
470       tree decl_type = TREE_TYPE (last_decl);
471       found |= diag_attr_exclusions (last_decl, decl_type, attrname, spec);
472     }
473 
474   /* NODE is either the current DECL to which the attribute is being
475      applied or its TYPE.  For the former, consider the attributes on
476      both the DECL and its type.  */
477   tree attrs[2];
478 
479   if (DECL_P (node))
480     {
481       attrs[0] = DECL_ATTRIBUTES (node);
482       if (TREE_TYPE (node))
483 	attrs[1] = TYPE_ATTRIBUTES (TREE_TYPE (node));
484       else
485 	/* TREE_TYPE can be NULL e.g. while processing attributes on
486 	   enumerators.  */
487 	attrs[1] = NULL_TREE;
488     }
489   else
490     {
491       attrs[0] = TYPE_ATTRIBUTES (node);
492       attrs[1] = NULL_TREE;
493     }
494 
495   /* Iterate over the mutually exclusive attribute names and verify
496      that the symbol doesn't contain it.  */
497   for (unsigned i = 0; i != sizeof attrs / sizeof *attrs; ++i)
498     {
499       if (!attrs[i])
500 	continue;
501 
502       for ( ; excl->name; ++excl)
503 	{
504 	  /* Avoid checking the attribute against itself.  */
505 	  if (is_attribute_p (excl->name, attrname))
506 	    continue;
507 
508 	  if (!lookup_attribute (excl->name, attrs[i]))
509 	    continue;
510 
511 	  /* An exclusion may apply either to a function declaration,
512 	     type declaration, or a field/variable declaration, or
513 	     any subset of the three.  */
514 	  if (TREE_CODE (node) == FUNCTION_DECL
515 	      && !excl->function)
516 	    continue;
517 
518 	  if (TREE_CODE (node) == TYPE_DECL
519 	      && !excl->type)
520 	    continue;
521 
522 	  if ((TREE_CODE (node) == FIELD_DECL
523 	       || TREE_CODE (node) == VAR_DECL)
524 	      && !excl->variable)
525 	    continue;
526 
527 	  found = true;
528 
529 	  /* Print a note?  */
530 	  bool note = last_decl != NULL_TREE;
531 	  auto_diagnostic_group d;
532 	  if (TREE_CODE (node) == FUNCTION_DECL
533 	      && fndecl_built_in_p (node))
534 	    note &= warning (OPT_Wattributes,
535 			     "ignoring attribute %qE in declaration of "
536 			     "a built-in function %qD because it conflicts "
537 			     "with attribute %qs",
538 			     attrname, node, excl->name);
539 	  else
540 	    note &= warning (OPT_Wattributes,
541 			     "ignoring attribute %qE because "
542 			     "it conflicts with attribute %qs",
543 			     attrname, excl->name);
544 
545 	  if (note)
546 	    inform (DECL_SOURCE_LOCATION (last_decl),
547 		    "previous declaration here");
548 	}
549     }
550 
551   return found;
552 }
553 
554 /* Return true iff we should not complain about unknown attributes
555    coming from the attribute namespace NS.  This is the case for
556    the -Wno-attributes=ns:: command-line option.  */
557 
558 static bool
attr_namespace_ignored_p(tree ns)559 attr_namespace_ignored_p (tree ns)
560 {
561   if (ns == NULL_TREE)
562     return false;
563   scoped_attributes *r = find_attribute_namespace (IDENTIFIER_POINTER (ns));
564   return r && r->ignored_p;
565 }
566 
567 /* Return true if the attribute ATTR should not be warned about.  */
568 
569 bool
attribute_ignored_p(tree attr)570 attribute_ignored_p (tree attr)
571 {
572   if (!cxx11_attribute_p (attr))
573     return false;
574   if (tree ns = get_attribute_namespace (attr))
575     {
576       const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attr));
577       if (as == NULL && attr_namespace_ignored_p (ns))
578 	return true;
579       if (as && as->max_length == -2)
580 	return true;
581     }
582   return false;
583 }
584 
585 /* Like above, but takes an attribute_spec AS, which must be nonnull.  */
586 
587 bool
attribute_ignored_p(const attribute_spec * const as)588 attribute_ignored_p (const attribute_spec *const as)
589 {
590   return as->max_length == -2;
591 }
592 
593 /* Process the attributes listed in ATTRIBUTES and install them in *NODE,
594    which is either a DECL (including a TYPE_DECL) or a TYPE.  If a DECL,
595    it should be modified in place; if a TYPE, a copy should be created
596    unless ATTR_FLAG_TYPE_IN_PLACE is set in FLAGS.  FLAGS gives further
597    information, in the form of a bitwise OR of flags in enum attribute_flags
598    from tree.h.  Depending on these flags, some attributes may be
599    returned to be applied at a later stage (for example, to apply
600    a decl attribute to the declaration rather than to its type).  */
601 
602 tree
decl_attributes(tree * node,tree attributes,int flags,tree last_decl)603 decl_attributes (tree *node, tree attributes, int flags,
604 		 tree last_decl /* = NULL_TREE */)
605 {
606   tree returned_attrs = NULL_TREE;
607 
608   if (TREE_TYPE (*node) == error_mark_node || attributes == error_mark_node)
609     return NULL_TREE;
610 
611   if (!attributes_initialized)
612     init_attributes ();
613 
614   /* If this is a function and the user used #pragma GCC optimize, add the
615      options to the attribute((optimize(...))) list.  */
616   if (TREE_CODE (*node) == FUNCTION_DECL && current_optimize_pragma)
617     {
618       tree cur_attr = lookup_attribute ("optimize", attributes);
619       tree opts = copy_list (current_optimize_pragma);
620 
621       if (! cur_attr)
622 	attributes
623 	  = tree_cons (get_identifier ("optimize"), opts, attributes);
624       else
625 	TREE_VALUE (cur_attr) = chainon (opts, TREE_VALUE (cur_attr));
626     }
627 
628   if (TREE_CODE (*node) == FUNCTION_DECL
629       && (optimization_current_node != optimization_default_node
630 	  || target_option_current_node != target_option_default_node)
631       && !DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node))
632     {
633       DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node) = optimization_current_node;
634       /* Don't set DECL_FUNCTION_SPECIFIC_TARGET for targets that don't
635 	 support #pragma GCC target or target attribute.  */
636       if (target_option_default_node)
637 	{
638 	  tree cur_tree
639 	    = build_target_option_node (&global_options, &global_options_set);
640 	  tree old_tree = DECL_FUNCTION_SPECIFIC_TARGET (*node);
641 	  if (!old_tree)
642 	    old_tree = target_option_default_node;
643 	  /* The changes on optimization options can cause the changes in
644 	     target options, update it accordingly if it's changed.  */
645 	  if (old_tree != cur_tree)
646 	    DECL_FUNCTION_SPECIFIC_TARGET (*node) = cur_tree;
647 	}
648     }
649 
650   /* If this is a function and the user used #pragma GCC target, add the
651      options to the attribute((target(...))) list.  */
652   if (TREE_CODE (*node) == FUNCTION_DECL
653       && current_target_pragma
654       && targetm.target_option.valid_attribute_p (*node, NULL_TREE,
655 						  current_target_pragma, 0))
656     {
657       tree cur_attr = lookup_attribute ("target", attributes);
658       tree opts = copy_list (current_target_pragma);
659 
660       if (! cur_attr)
661 	attributes = tree_cons (get_identifier ("target"), opts, attributes);
662       else
663 	TREE_VALUE (cur_attr) = chainon (opts, TREE_VALUE (cur_attr));
664     }
665 
666   /* A "naked" function attribute implies "noinline" and "noclone" for
667      those targets that support it.  */
668   if (TREE_CODE (*node) == FUNCTION_DECL
669       && attributes
670       && lookup_attribute ("naked", attributes) != NULL
671       && lookup_attribute_spec (get_identifier ("naked"))
672       && lookup_attribute ("noipa", attributes) == NULL)
673 	attributes = tree_cons (get_identifier ("noipa"), NULL, attributes);
674 
675   /* A "noipa" function attribute implies "noinline", "noclone" and "no_icf"
676      for those targets that support it.  */
677   if (TREE_CODE (*node) == FUNCTION_DECL
678       && attributes
679       && lookup_attribute ("noipa", attributes) != NULL
680       && lookup_attribute_spec (get_identifier ("noipa")))
681     {
682       if (lookup_attribute ("noinline", attributes) == NULL)
683 	attributes = tree_cons (get_identifier ("noinline"), NULL, attributes);
684 
685       if (lookup_attribute ("noclone", attributes) == NULL)
686 	attributes = tree_cons (get_identifier ("noclone"),  NULL, attributes);
687 
688       if (lookup_attribute ("no_icf", attributes) == NULL)
689 	attributes = tree_cons (get_identifier ("no_icf"),  NULL, attributes);
690     }
691 
692   targetm.insert_attributes (*node, &attributes);
693 
694   /* Note that attributes on the same declaration are not necessarily
695      in the same order as in the source.  */
696   for (tree attr = attributes; attr; attr = TREE_CHAIN (attr))
697     {
698       tree ns = get_attribute_namespace (attr);
699       tree name = get_attribute_name (attr);
700       tree args = TREE_VALUE (attr);
701       tree *anode = node;
702       const struct attribute_spec *spec
703 	= lookup_scoped_attribute_spec (ns, name);
704       int fn_ptr_quals = 0;
705       tree fn_ptr_tmp = NULL_TREE;
706       const bool cxx11_attr_p = cxx11_attribute_p (attr);
707 
708       if (spec == NULL)
709 	{
710 	  if (!(flags & (int) ATTR_FLAG_BUILT_IN)
711 	      && !attr_namespace_ignored_p (ns))
712 	    {
713 	      if (ns == NULL_TREE || !cxx11_attr_p)
714 		warning (OPT_Wattributes, "%qE attribute directive ignored",
715 			 name);
716 	      else
717 		warning (OPT_Wattributes,
718 			 "%<%E::%E%> scoped attribute directive ignored",
719 			 ns, name);
720 	    }
721 	  continue;
722 	}
723       else
724 	{
725 	  int nargs = list_length (args);
726 	  if (nargs < spec->min_length
727 	      || (spec->max_length >= 0
728 		  && nargs > spec->max_length))
729 	    {
730 	      error ("wrong number of arguments specified for %qE attribute",
731 		     name);
732 	      if (spec->max_length < 0)
733 		inform (input_location, "expected %i or more, found %i",
734 			spec->min_length, nargs);
735 	      else
736 		inform (input_location, "expected between %i and %i, found %i",
737 			spec->min_length, spec->max_length, nargs);
738 	      continue;
739 	    }
740 	}
741       gcc_assert (is_attribute_p (spec->name, name));
742 
743       if (spec->decl_required && !DECL_P (*anode))
744 	{
745 	  if (flags & ((int) ATTR_FLAG_DECL_NEXT
746 		       | (int) ATTR_FLAG_FUNCTION_NEXT
747 		       | (int) ATTR_FLAG_ARRAY_NEXT))
748 	    {
749 	      /* Pass on this attribute to be tried again.  */
750 	      tree attr = tree_cons (name, args, NULL_TREE);
751 	      returned_attrs = chainon (returned_attrs, attr);
752 	      continue;
753 	    }
754 	  else
755 	    {
756 	      warning (OPT_Wattributes, "%qE attribute does not apply to types",
757 		       name);
758 	      continue;
759 	    }
760 	}
761 
762       /* If we require a type, but were passed a decl, set up to make a
763 	 new type and update the one in the decl.  ATTR_FLAG_TYPE_IN_PLACE
764 	 would have applied if we'd been passed a type, but we cannot modify
765 	 the decl's type in place here.  */
766       if (spec->type_required && DECL_P (*anode))
767 	{
768 	  anode = &TREE_TYPE (*anode);
769 	  flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
770 	}
771 
772       if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE
773 	  && TREE_CODE (*anode) != METHOD_TYPE)
774 	{
775 	  if (TREE_CODE (*anode) == POINTER_TYPE
776 	      && (TREE_CODE (TREE_TYPE (*anode)) == FUNCTION_TYPE
777 		  || TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE))
778 	    {
779 	      /* OK, this is a bit convoluted.  We can't just make a copy
780 		 of the pointer type and modify its TREE_TYPE, because if
781 		 we change the attributes of the target type the pointer
782 		 type needs to have a different TYPE_MAIN_VARIANT.  So we
783 		 pull out the target type now, frob it as appropriate, and
784 		 rebuild the pointer type later.
785 
786 		 This would all be simpler if attributes were part of the
787 		 declarator, grumble grumble.  */
788 	      fn_ptr_tmp = TREE_TYPE (*anode);
789 	      fn_ptr_quals = TYPE_QUALS (*anode);
790 	      anode = &fn_ptr_tmp;
791 	      flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
792 	    }
793 	  else if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
794 	    {
795 	      /* Pass on this attribute to be tried again.  */
796 	      tree attr = tree_cons (name, args, NULL_TREE);
797 	      returned_attrs = chainon (returned_attrs, attr);
798 	      continue;
799 	    }
800 
801 	  if (TREE_CODE (*anode) != FUNCTION_TYPE
802 	      && TREE_CODE (*anode) != METHOD_TYPE)
803 	    {
804 	      warning (OPT_Wattributes,
805 		       "%qE attribute only applies to function types",
806 		       name);
807 	      continue;
808 	    }
809 	}
810 
811       if (TYPE_P (*anode)
812 	  && (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
813 	  && TYPE_SIZE (*anode) != NULL_TREE)
814 	{
815 	  warning (OPT_Wattributes, "type attributes ignored after type is already defined");
816 	  continue;
817 	}
818 
819       bool no_add_attrs = false;
820 
821       /* Check for exclusions with other attributes on the current
822 	 declation as well as the last declaration of the same
823 	 symbol already processed (if one exists).  Detect and
824 	 reject incompatible attributes.  */
825       bool built_in = flags & ATTR_FLAG_BUILT_IN;
826       if (spec->exclude
827 	  && (flag_checking || !built_in)
828 	  && !error_operand_p (last_decl))
829 	{
830 	  /* Always check attributes on user-defined functions.
831 	     Check them on built-ins only when -fchecking is set.
832 	     Ignore __builtin_unreachable -- it's both const and
833 	     noreturn.  */
834 
835 	  if (!built_in
836 	      || !DECL_P (*anode)
837 	      || DECL_BUILT_IN_CLASS (*anode) != BUILT_IN_NORMAL
838 	      || (DECL_FUNCTION_CODE (*anode) != BUILT_IN_UNREACHABLE
839 		  && (DECL_FUNCTION_CODE (*anode)
840 		      != BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE)))
841 	    {
842 	      bool no_add = diag_attr_exclusions (last_decl, *anode, name, spec);
843 	      if (!no_add && anode != node)
844 		no_add = diag_attr_exclusions (last_decl, *node, name, spec);
845 	      no_add_attrs |= no_add;
846 	    }
847 	}
848 
849       if (no_add_attrs
850 	  /* Don't add attributes registered just for -Wno-attributes=foo::bar
851 	     purposes.  */
852 	  || attribute_ignored_p (attr))
853 	continue;
854 
855       if (spec->handler != NULL)
856 	{
857 	  int cxx11_flag = (cxx11_attr_p ? ATTR_FLAG_CXX11 : 0);
858 
859 	  /* Pass in an array of the current declaration followed
860 	     by the last pushed/merged declaration if one exists.
861 	     For calls that modify the type attributes of a DECL
862 	     and for which *ANODE is *NODE's type, also pass in
863 	     the DECL as the third element to use in diagnostics.
864 	     If the handler changes CUR_AND_LAST_DECL[0] replace
865 	     *ANODE with its value.  */
866 	  tree cur_and_last_decl[3] = { *anode, last_decl };
867 	  if (anode != node && DECL_P (*node))
868 	    cur_and_last_decl[2] = *node;
869 
870 	  tree ret = (spec->handler) (cur_and_last_decl, name, args,
871 				      flags|cxx11_flag, &no_add_attrs);
872 
873 	  *anode = cur_and_last_decl[0];
874 	  if (ret == error_mark_node)
875 	    {
876 	      warning (OPT_Wattributes, "%qE attribute ignored", name);
877 	      no_add_attrs = true;
878 	    }
879 	  else
880 	    returned_attrs = chainon (ret, returned_attrs);
881 	}
882 
883       /* Layout the decl in case anything changed.  */
884       if (spec->type_required && DECL_P (*node)
885 	  && (VAR_P (*node)
886 	      || TREE_CODE (*node) == PARM_DECL
887 	      || TREE_CODE (*node) == RESULT_DECL))
888 	relayout_decl (*node);
889 
890       if (!no_add_attrs)
891 	{
892 	  tree old_attrs;
893 	  tree a;
894 
895 	  if (DECL_P (*anode))
896 	    old_attrs = DECL_ATTRIBUTES (*anode);
897 	  else
898 	    old_attrs = TYPE_ATTRIBUTES (*anode);
899 
900 	  for (a = lookup_attribute (spec->name, old_attrs);
901 	       a != NULL_TREE;
902 	       a = lookup_attribute (spec->name, TREE_CHAIN (a)))
903 	    {
904 	      if (simple_cst_equal (TREE_VALUE (a), args) == 1)
905 		break;
906 	    }
907 
908 	  if (a == NULL_TREE)
909 	    {
910 	      /* This attribute isn't already in the list.  */
911 	      tree r;
912 	      /* Preserve the C++11 form.  */
913 	      if (cxx11_attr_p)
914 		r = tree_cons (build_tree_list (ns, name), args, old_attrs);
915 	      else
916 		r = tree_cons (name, args, old_attrs);
917 
918 	      if (DECL_P (*anode))
919 		DECL_ATTRIBUTES (*anode) = r;
920 	      else if (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
921 		{
922 		  TYPE_ATTRIBUTES (*anode) = r;
923 		  /* If this is the main variant, also push the attributes
924 		     out to the other variants.  */
925 		  if (*anode == TYPE_MAIN_VARIANT (*anode))
926 		    {
927 		      for (tree variant = *anode; variant;
928 			   variant = TYPE_NEXT_VARIANT (variant))
929 			{
930 			  if (TYPE_ATTRIBUTES (variant) == old_attrs)
931 			    TYPE_ATTRIBUTES (variant)
932 			      = TYPE_ATTRIBUTES (*anode);
933 			  else if (!lookup_attribute
934 				   (spec->name, TYPE_ATTRIBUTES (variant)))
935 			    TYPE_ATTRIBUTES (variant) = tree_cons
936 			      (name, args, TYPE_ATTRIBUTES (variant));
937 			}
938 		    }
939 		}
940 	      else
941 		*anode = build_type_attribute_variant (*anode, r);
942 	    }
943 	}
944 
945       if (fn_ptr_tmp)
946 	{
947 	  /* Rebuild the function pointer type and put it in the
948 	     appropriate place.  */
949 	  fn_ptr_tmp = build_pointer_type (fn_ptr_tmp);
950 	  if (fn_ptr_quals)
951 	    fn_ptr_tmp = build_qualified_type (fn_ptr_tmp, fn_ptr_quals);
952 	  if (DECL_P (*node))
953 	    TREE_TYPE (*node) = fn_ptr_tmp;
954 	  else
955 	    {
956 	      gcc_assert (TREE_CODE (*node) == POINTER_TYPE);
957 	      *node = fn_ptr_tmp;
958 	    }
959 	}
960     }
961 
962   return returned_attrs;
963 }
964 
965 /* Return TRUE iff ATTR has been parsed by the front-end as a C++-11
966    attribute.
967 
968    When G++ parses a C++11 attribute, it is represented as
969    a TREE_LIST which TREE_PURPOSE is itself a TREE_LIST.  TREE_PURPOSE
970    (TREE_PURPOSE (ATTR)) is the namespace of the attribute, and the
971    TREE_VALUE (TREE_PURPOSE (ATTR)) is its non-qualified name.  Please
972    use get_attribute_namespace and get_attribute_name to retrieve the
973    namespace and name of the attribute, as these accessors work with
974    GNU attributes as well.  */
975 
976 bool
cxx11_attribute_p(const_tree attr)977 cxx11_attribute_p (const_tree attr)
978 {
979   if (attr == NULL_TREE
980       || TREE_CODE (attr) != TREE_LIST)
981     return false;
982 
983   return (TREE_CODE (TREE_PURPOSE (attr)) == TREE_LIST);
984 }
985 
986 /* Return the name of the attribute ATTR.  This accessor works on GNU
987    and C++11 (scoped) attributes.
988 
989    Please read the comments of cxx11_attribute_p to understand the
990    format of attributes.  */
991 
992 tree
get_attribute_name(const_tree attr)993 get_attribute_name (const_tree attr)
994 {
995   if (cxx11_attribute_p (attr))
996     return TREE_VALUE (TREE_PURPOSE (attr));
997   return TREE_PURPOSE (attr);
998 }
999 
1000 /* Subroutine of set_method_tm_attributes.  Apply TM attribute ATTR
1001    to the method FNDECL.  */
1002 
1003 void
apply_tm_attr(tree fndecl,tree attr)1004 apply_tm_attr (tree fndecl, tree attr)
1005 {
1006   decl_attributes (&TREE_TYPE (fndecl), tree_cons (attr, NULL, NULL), 0);
1007 }
1008 
1009 /* Makes a function attribute of the form NAME(ARG_NAME) and chains
1010    it to CHAIN.  */
1011 
1012 tree
make_attribute(const char * name,const char * arg_name,tree chain)1013 make_attribute (const char *name, const char *arg_name, tree chain)
1014 {
1015   tree attr_name;
1016   tree attr_arg_name;
1017   tree attr_args;
1018   tree attr;
1019 
1020   attr_name = get_identifier (name);
1021   attr_arg_name = build_string (strlen (arg_name), arg_name);
1022   attr_args = tree_cons (NULL_TREE, attr_arg_name, NULL_TREE);
1023   attr = tree_cons (attr_name, attr_args, chain);
1024   return attr;
1025 }
1026 
1027 
1028 /* Common functions used for target clone support.  */
1029 
1030 /* Comparator function to be used in qsort routine to sort attribute
1031    specification strings to "target".  */
1032 
1033 static int
attr_strcmp(const void * v1,const void * v2)1034 attr_strcmp (const void *v1, const void *v2)
1035 {
1036   const char *c1 = *(char *const*)v1;
1037   const char *c2 = *(char *const*)v2;
1038   return strcmp (c1, c2);
1039 }
1040 
1041 /* ARGLIST is the argument to target attribute.  This function tokenizes
1042    the comma separated arguments, sorts them and returns a string which
1043    is a unique identifier for the comma separated arguments.   It also
1044    replaces non-identifier characters "=,-" with "_".  */
1045 
1046 char *
sorted_attr_string(tree arglist)1047 sorted_attr_string (tree arglist)
1048 {
1049   tree arg;
1050   size_t str_len_sum = 0;
1051   char **args = NULL;
1052   char *attr_str, *ret_str;
1053   char *attr = NULL;
1054   unsigned int argnum = 1;
1055   unsigned int i;
1056 
1057   for (arg = arglist; arg; arg = TREE_CHAIN (arg))
1058     {
1059       const char *str = TREE_STRING_POINTER (TREE_VALUE (arg));
1060       size_t len = strlen (str);
1061       str_len_sum += len + 1;
1062       if (arg != arglist)
1063 	argnum++;
1064       for (i = 0; i < strlen (str); i++)
1065 	if (str[i] == ',')
1066 	  argnum++;
1067     }
1068 
1069   attr_str = XNEWVEC (char, str_len_sum);
1070   str_len_sum = 0;
1071   for (arg = arglist; arg; arg = TREE_CHAIN (arg))
1072     {
1073       const char *str = TREE_STRING_POINTER (TREE_VALUE (arg));
1074       size_t len = strlen (str);
1075       memcpy (attr_str + str_len_sum, str, len);
1076       attr_str[str_len_sum + len] = TREE_CHAIN (arg) ? ',' : '\0';
1077       str_len_sum += len + 1;
1078     }
1079 
1080   /* Replace "=,-" with "_".  */
1081   for (i = 0; i < strlen (attr_str); i++)
1082     if (attr_str[i] == '=' || attr_str[i]== '-')
1083       attr_str[i] = '_';
1084 
1085   if (argnum == 1)
1086     return attr_str;
1087 
1088   args = XNEWVEC (char *, argnum);
1089 
1090   i = 0;
1091   attr = strtok (attr_str, ",");
1092   while (attr != NULL)
1093     {
1094       args[i] = attr;
1095       i++;
1096       attr = strtok (NULL, ",");
1097     }
1098 
1099   qsort (args, argnum, sizeof (char *), attr_strcmp);
1100 
1101   ret_str = XNEWVEC (char, str_len_sum);
1102   str_len_sum = 0;
1103   for (i = 0; i < argnum; i++)
1104     {
1105       size_t len = strlen (args[i]);
1106       memcpy (ret_str + str_len_sum, args[i], len);
1107       ret_str[str_len_sum + len] = i < argnum - 1 ? '_' : '\0';
1108       str_len_sum += len + 1;
1109     }
1110 
1111   XDELETEVEC (args);
1112   XDELETEVEC (attr_str);
1113   return ret_str;
1114 }
1115 
1116 
1117 /* This function returns true if FN1 and FN2 are versions of the same function,
1118    that is, the target strings of the function decls are different.  This assumes
1119    that FN1 and FN2 have the same signature.  */
1120 
1121 bool
common_function_versions(tree fn1,tree fn2)1122 common_function_versions (tree fn1, tree fn2)
1123 {
1124   tree attr1, attr2;
1125   char *target1, *target2;
1126   bool result;
1127 
1128   if (TREE_CODE (fn1) != FUNCTION_DECL
1129       || TREE_CODE (fn2) != FUNCTION_DECL)
1130     return false;
1131 
1132   attr1 = lookup_attribute ("target", DECL_ATTRIBUTES (fn1));
1133   attr2 = lookup_attribute ("target", DECL_ATTRIBUTES (fn2));
1134 
1135   /* At least one function decl should have the target attribute specified.  */
1136   if (attr1 == NULL_TREE && attr2 == NULL_TREE)
1137     return false;
1138 
1139   /* Diagnose missing target attribute if one of the decls is already
1140      multi-versioned.  */
1141   if (attr1 == NULL_TREE || attr2 == NULL_TREE)
1142     {
1143       if (DECL_FUNCTION_VERSIONED (fn1) || DECL_FUNCTION_VERSIONED (fn2))
1144 	{
1145 	  if (attr2 != NULL_TREE)
1146 	    {
1147 	      std::swap (fn1, fn2);
1148 	      attr1 = attr2;
1149 	    }
1150 	  error_at (DECL_SOURCE_LOCATION (fn2),
1151 		    "missing %<target%> attribute for multi-versioned %qD",
1152 		    fn2);
1153 	  inform (DECL_SOURCE_LOCATION (fn1),
1154 		  "previous declaration of %qD", fn1);
1155 	  /* Prevent diagnosing of the same error multiple times.  */
1156 	  DECL_ATTRIBUTES (fn2)
1157 	    = tree_cons (get_identifier ("target"),
1158 			 copy_node (TREE_VALUE (attr1)),
1159 			 DECL_ATTRIBUTES (fn2));
1160 	}
1161       return false;
1162     }
1163 
1164   target1 = sorted_attr_string (TREE_VALUE (attr1));
1165   target2 = sorted_attr_string (TREE_VALUE (attr2));
1166 
1167   /* The sorted target strings must be different for fn1 and fn2
1168      to be versions.  */
1169   if (strcmp (target1, target2) == 0)
1170     result = false;
1171   else
1172     result = true;
1173 
1174   XDELETEVEC (target1);
1175   XDELETEVEC (target2);
1176 
1177   return result;
1178 }
1179 
1180 /* Make a dispatcher declaration for the multi-versioned function DECL.
1181    Calls to DECL function will be replaced with calls to the dispatcher
1182    by the front-end.  Return the decl created.  */
1183 
1184 tree
make_dispatcher_decl(const tree decl)1185 make_dispatcher_decl (const tree decl)
1186 {
1187   tree func_decl;
1188   char *func_name;
1189   tree fn_type, func_type;
1190 
1191   func_name = xstrdup (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
1192 
1193   fn_type = TREE_TYPE (decl);
1194   func_type = build_function_type (TREE_TYPE (fn_type),
1195 				   TYPE_ARG_TYPES (fn_type));
1196 
1197   func_decl = build_fn_decl (func_name, func_type);
1198   XDELETEVEC (func_name);
1199   TREE_USED (func_decl) = 1;
1200   DECL_CONTEXT (func_decl) = NULL_TREE;
1201   DECL_INITIAL (func_decl) = error_mark_node;
1202   DECL_ARTIFICIAL (func_decl) = 1;
1203   /* Mark this func as external, the resolver will flip it again if
1204      it gets generated.  */
1205   DECL_EXTERNAL (func_decl) = 1;
1206   /* This will be of type IFUNCs have to be externally visible.  */
1207   TREE_PUBLIC (func_decl) = 1;
1208 
1209   return func_decl;
1210 }
1211 
1212 /* Returns true if decl is multi-versioned and DECL is the default function,
1213    that is it is not tagged with target specific optimization.  */
1214 
1215 bool
is_function_default_version(const tree decl)1216 is_function_default_version (const tree decl)
1217 {
1218   if (TREE_CODE (decl) != FUNCTION_DECL
1219       || !DECL_FUNCTION_VERSIONED (decl))
1220     return false;
1221   tree attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl));
1222   gcc_assert (attr);
1223   attr = TREE_VALUE (TREE_VALUE (attr));
1224   return (TREE_CODE (attr) == STRING_CST
1225 	  && strcmp (TREE_STRING_POINTER (attr), "default") == 0);
1226 }
1227 
1228 /* Return a declaration like DDECL except that its DECL_ATTRIBUTES
1229    is ATTRIBUTE.  */
1230 
1231 tree
build_decl_attribute_variant(tree ddecl,tree attribute)1232 build_decl_attribute_variant (tree ddecl, tree attribute)
1233 {
1234   DECL_ATTRIBUTES (ddecl) = attribute;
1235   return ddecl;
1236 }
1237 
1238 /* Return a type like TTYPE except that its TYPE_ATTRIBUTE
1239    is ATTRIBUTE and its qualifiers are QUALS.
1240 
1241    Record such modified types already made so we don't make duplicates.  */
1242 
1243 tree
build_type_attribute_qual_variant(tree otype,tree attribute,int quals)1244 build_type_attribute_qual_variant (tree otype, tree attribute, int quals)
1245 {
1246   tree ttype = otype;
1247   if (! attribute_list_equal (TYPE_ATTRIBUTES (ttype), attribute))
1248     {
1249       tree ntype;
1250 
1251       /* Building a distinct copy of a tagged type is inappropriate; it
1252 	 causes breakage in code that expects there to be a one-to-one
1253 	 relationship between a struct and its fields.
1254 	 build_duplicate_type is another solution (as used in
1255 	 handle_transparent_union_attribute), but that doesn't play well
1256 	 with the stronger C++ type identity model.  */
1257       if (TREE_CODE (ttype) == RECORD_TYPE
1258 	  || TREE_CODE (ttype) == UNION_TYPE
1259 	  || TREE_CODE (ttype) == QUAL_UNION_TYPE
1260 	  || TREE_CODE (ttype) == ENUMERAL_TYPE)
1261 	{
1262 	  warning (OPT_Wattributes,
1263 		   "ignoring attributes applied to %qT after definition",
1264 		   TYPE_MAIN_VARIANT (ttype));
1265 	  return build_qualified_type (ttype, quals);
1266 	}
1267 
1268       ttype = build_qualified_type (ttype, TYPE_UNQUALIFIED);
1269       if (lang_hooks.types.copy_lang_qualifiers
1270 	  && otype != TYPE_MAIN_VARIANT (otype))
1271 	ttype = (lang_hooks.types.copy_lang_qualifiers
1272 		 (ttype, TYPE_MAIN_VARIANT (otype)));
1273 
1274       tree dtype = ntype = build_distinct_type_copy (ttype);
1275 
1276       TYPE_ATTRIBUTES (ntype) = attribute;
1277 
1278       hashval_t hash = type_hash_canon_hash (ntype);
1279       ntype = type_hash_canon (hash, ntype);
1280 
1281       if (ntype != dtype)
1282 	/* This variant was already in the hash table, don't mess with
1283 	   TYPE_CANONICAL.  */;
1284       else if (TYPE_STRUCTURAL_EQUALITY_P (ttype)
1285 	       || !comp_type_attributes (ntype, ttype))
1286 	/* If the target-dependent attributes make NTYPE different from
1287 	   its canonical type, we will need to use structural equality
1288 	   checks for this type.
1289 
1290 	   We shouldn't get here for stripping attributes from a type;
1291 	   the no-attribute type might not need structural comparison.  But
1292 	   we can if was discarded from type_hash_table.  */
1293 	SET_TYPE_STRUCTURAL_EQUALITY (ntype);
1294       else if (TYPE_CANONICAL (ntype) == ntype)
1295 	TYPE_CANONICAL (ntype) = TYPE_CANONICAL (ttype);
1296 
1297       ttype = build_qualified_type (ntype, quals);
1298       if (lang_hooks.types.copy_lang_qualifiers
1299 	  && otype != TYPE_MAIN_VARIANT (otype))
1300 	ttype = lang_hooks.types.copy_lang_qualifiers (ttype, otype);
1301     }
1302   else if (TYPE_QUALS (ttype) != quals)
1303     ttype = build_qualified_type (ttype, quals);
1304 
1305   return ttype;
1306 }
1307 
1308 /* Compare two identifier nodes representing attributes.
1309    Return true if they are the same, false otherwise.  */
1310 
1311 static bool
cmp_attrib_identifiers(const_tree attr1,const_tree attr2)1312 cmp_attrib_identifiers (const_tree attr1, const_tree attr2)
1313 {
1314   /* Make sure we're dealing with IDENTIFIER_NODEs.  */
1315   gcc_checking_assert (TREE_CODE (attr1) == IDENTIFIER_NODE
1316 		       && TREE_CODE (attr2) == IDENTIFIER_NODE);
1317 
1318   /* Identifiers can be compared directly for equality.  */
1319   if (attr1 == attr2)
1320     return true;
1321 
1322   return cmp_attribs (IDENTIFIER_POINTER (attr1), IDENTIFIER_LENGTH (attr1),
1323 		      IDENTIFIER_POINTER (attr2), IDENTIFIER_LENGTH (attr2));
1324 }
1325 
1326 /* Compare two constructor-element-type constants.  Return 1 if the lists
1327    are known to be equal; otherwise return 0.  */
1328 
1329 bool
simple_cst_list_equal(const_tree l1,const_tree l2)1330 simple_cst_list_equal (const_tree l1, const_tree l2)
1331 {
1332   while (l1 != NULL_TREE && l2 != NULL_TREE)
1333     {
1334       if (simple_cst_equal (TREE_VALUE (l1), TREE_VALUE (l2)) != 1)
1335 	return false;
1336 
1337       l1 = TREE_CHAIN (l1);
1338       l2 = TREE_CHAIN (l2);
1339     }
1340 
1341   return l1 == l2;
1342 }
1343 
1344 /* Check if "omp declare simd" attribute arguments, CLAUSES1 and CLAUSES2, are
1345    the same.  */
1346 
1347 static bool
omp_declare_simd_clauses_equal(tree clauses1,tree clauses2)1348 omp_declare_simd_clauses_equal (tree clauses1, tree clauses2)
1349 {
1350   tree cl1, cl2;
1351   for (cl1 = clauses1, cl2 = clauses2;
1352        cl1 && cl2;
1353        cl1 = OMP_CLAUSE_CHAIN (cl1), cl2 = OMP_CLAUSE_CHAIN (cl2))
1354     {
1355       if (OMP_CLAUSE_CODE (cl1) != OMP_CLAUSE_CODE (cl2))
1356 	return false;
1357       if (OMP_CLAUSE_CODE (cl1) != OMP_CLAUSE_SIMDLEN)
1358 	{
1359 	  if (simple_cst_equal (OMP_CLAUSE_DECL (cl1),
1360 				OMP_CLAUSE_DECL (cl2)) != 1)
1361 	    return false;
1362 	}
1363       switch (OMP_CLAUSE_CODE (cl1))
1364 	{
1365 	case OMP_CLAUSE_ALIGNED:
1366 	  if (simple_cst_equal (OMP_CLAUSE_ALIGNED_ALIGNMENT (cl1),
1367 				OMP_CLAUSE_ALIGNED_ALIGNMENT (cl2)) != 1)
1368 	    return false;
1369 	  break;
1370 	case OMP_CLAUSE_LINEAR:
1371 	  if (simple_cst_equal (OMP_CLAUSE_LINEAR_STEP (cl1),
1372 				OMP_CLAUSE_LINEAR_STEP (cl2)) != 1)
1373 	    return false;
1374 	  break;
1375 	case OMP_CLAUSE_SIMDLEN:
1376 	  if (simple_cst_equal (OMP_CLAUSE_SIMDLEN_EXPR (cl1),
1377 				OMP_CLAUSE_SIMDLEN_EXPR (cl2)) != 1)
1378 	    return false;
1379 	default:
1380 	  break;
1381 	}
1382     }
1383   return true;
1384 }
1385 
1386 
1387 /* Compare two attributes for their value identity.  Return true if the
1388    attribute values are known to be equal; otherwise return false.  */
1389 
1390 bool
attribute_value_equal(const_tree attr1,const_tree attr2)1391 attribute_value_equal (const_tree attr1, const_tree attr2)
1392 {
1393   if (TREE_VALUE (attr1) == TREE_VALUE (attr2))
1394     return true;
1395 
1396   if (TREE_VALUE (attr1) != NULL_TREE
1397       && TREE_CODE (TREE_VALUE (attr1)) == TREE_LIST
1398       && TREE_VALUE (attr2) != NULL_TREE
1399       && TREE_CODE (TREE_VALUE (attr2)) == TREE_LIST)
1400     {
1401       /* Handle attribute format.  */
1402       if (is_attribute_p ("format", get_attribute_name (attr1)))
1403 	{
1404 	  attr1 = TREE_VALUE (attr1);
1405 	  attr2 = TREE_VALUE (attr2);
1406 	  /* Compare the archetypes (printf/scanf/strftime/...).  */
1407 	  if (!cmp_attrib_identifiers (TREE_VALUE (attr1), TREE_VALUE (attr2)))
1408 	    return false;
1409 	  /* Archetypes are the same.  Compare the rest.  */
1410 	  return (simple_cst_list_equal (TREE_CHAIN (attr1),
1411 					 TREE_CHAIN (attr2)) == 1);
1412 	}
1413       return (simple_cst_list_equal (TREE_VALUE (attr1),
1414 				     TREE_VALUE (attr2)) == 1);
1415     }
1416 
1417   if (TREE_VALUE (attr1)
1418       && TREE_CODE (TREE_VALUE (attr1)) == OMP_CLAUSE
1419       && TREE_VALUE (attr2)
1420       && TREE_CODE (TREE_VALUE (attr2)) == OMP_CLAUSE)
1421     return omp_declare_simd_clauses_equal (TREE_VALUE (attr1),
1422 					   TREE_VALUE (attr2));
1423 
1424   return (simple_cst_equal (TREE_VALUE (attr1), TREE_VALUE (attr2)) == 1);
1425 }
1426 
1427 /* Return 0 if the attributes for two types are incompatible, 1 if they
1428    are compatible, and 2 if they are nearly compatible (which causes a
1429    warning to be generated).  */
1430 int
comp_type_attributes(const_tree type1,const_tree type2)1431 comp_type_attributes (const_tree type1, const_tree type2)
1432 {
1433   const_tree a1 = TYPE_ATTRIBUTES (type1);
1434   const_tree a2 = TYPE_ATTRIBUTES (type2);
1435   const_tree a;
1436 
1437   if (a1 == a2)
1438     return 1;
1439   for (a = a1; a != NULL_TREE; a = TREE_CHAIN (a))
1440     {
1441       const struct attribute_spec *as;
1442       const_tree attr;
1443 
1444       as = lookup_attribute_spec (get_attribute_name (a));
1445       if (!as || as->affects_type_identity == false)
1446 	continue;
1447 
1448       attr = lookup_attribute (as->name, CONST_CAST_TREE (a2));
1449       if (!attr || !attribute_value_equal (a, attr))
1450 	break;
1451     }
1452   if (!a)
1453     {
1454       for (a = a2; a != NULL_TREE; a = TREE_CHAIN (a))
1455 	{
1456 	  const struct attribute_spec *as;
1457 
1458 	  as = lookup_attribute_spec (get_attribute_name (a));
1459 	  if (!as || as->affects_type_identity == false)
1460 	    continue;
1461 
1462 	  if (!lookup_attribute (as->name, CONST_CAST_TREE (a1)))
1463 	    break;
1464 	  /* We don't need to compare trees again, as we did this
1465 	     already in first loop.  */
1466 	}
1467       /* All types - affecting identity - are equal, so
1468 	 there is no need to call target hook for comparison.  */
1469       if (!a)
1470 	return 1;
1471     }
1472   if (lookup_attribute ("transaction_safe", CONST_CAST_TREE (a)))
1473     return 0;
1474   if ((lookup_attribute ("nocf_check", TYPE_ATTRIBUTES (type1)) != NULL)
1475       ^ (lookup_attribute ("nocf_check", TYPE_ATTRIBUTES (type2)) != NULL))
1476     return 0;
1477   /* As some type combinations - like default calling-convention - might
1478      be compatible, we have to call the target hook to get the final result.  */
1479   return targetm.comp_type_attributes (type1, type2);
1480 }
1481 
1482 /* PREDICATE acts as a function of type:
1483 
1484      (const_tree attr, const attribute_spec *as) -> bool
1485 
1486    where ATTR is an attribute and AS is its possibly-null specification.
1487    Return a list of every attribute in attribute list ATTRS for which
1488    PREDICATE is true.  Return ATTRS itself if PREDICATE returns true
1489    for every attribute.  */
1490 
1491 template<typename Predicate>
1492 tree
remove_attributes_matching(tree attrs,Predicate predicate)1493 remove_attributes_matching (tree attrs, Predicate predicate)
1494 {
1495   tree new_attrs = NULL_TREE;
1496   tree *ptr = &new_attrs;
1497   const_tree start = attrs;
1498   for (const_tree attr = attrs; attr; attr = TREE_CHAIN (attr))
1499     {
1500       tree name = get_attribute_name (attr);
1501       const attribute_spec *as = lookup_attribute_spec (name);
1502       const_tree end;
1503       if (!predicate (attr, as))
1504 	end = attr;
1505       else if (start == attrs)
1506 	continue;
1507       else
1508 	end = TREE_CHAIN (attr);
1509 
1510       for (; start != end; start = TREE_CHAIN (start))
1511 	{
1512 	  *ptr = tree_cons (TREE_PURPOSE (start),
1513 			    TREE_VALUE (start), NULL_TREE);
1514 	  TREE_CHAIN (*ptr) = NULL_TREE;
1515 	  ptr = &TREE_CHAIN (*ptr);
1516 	}
1517       start = TREE_CHAIN (attr);
1518     }
1519   gcc_assert (!start || start == attrs);
1520   return start ? attrs : new_attrs;
1521 }
1522 
1523 /* If VALUE is true, return the subset of ATTRS that affect type identity,
1524    otherwise return the subset of ATTRS that don't affect type identity.  */
1525 
1526 tree
affects_type_identity_attributes(tree attrs,bool value)1527 affects_type_identity_attributes (tree attrs, bool value)
1528 {
1529   auto predicate = [value](const_tree, const attribute_spec *as) -> bool
1530     {
1531       return bool (as && as->affects_type_identity) == value;
1532     };
1533   return remove_attributes_matching (attrs, predicate);
1534 }
1535 
1536 /* Remove attributes that affect type identity from ATTRS unless the
1537    same attributes occur in OK_ATTRS.  */
1538 
1539 tree
restrict_type_identity_attributes_to(tree attrs,tree ok_attrs)1540 restrict_type_identity_attributes_to (tree attrs, tree ok_attrs)
1541 {
1542   auto predicate = [ok_attrs](const_tree attr,
1543 			      const attribute_spec *as) -> bool
1544     {
1545       if (!as || !as->affects_type_identity)
1546 	return true;
1547 
1548       for (tree ok_attr = lookup_attribute (as->name, ok_attrs);
1549 	   ok_attr;
1550 	   ok_attr = lookup_attribute (as->name, TREE_CHAIN (ok_attr)))
1551 	if (simple_cst_equal (TREE_VALUE (ok_attr), TREE_VALUE (attr)) == 1)
1552 	  return true;
1553 
1554       return false;
1555     };
1556   return remove_attributes_matching (attrs, predicate);
1557 }
1558 
1559 /* Return a type like TTYPE except that its TYPE_ATTRIBUTE
1560    is ATTRIBUTE.
1561 
1562    Record such modified types already made so we don't make duplicates.  */
1563 
1564 tree
build_type_attribute_variant(tree ttype,tree attribute)1565 build_type_attribute_variant (tree ttype, tree attribute)
1566 {
1567   return build_type_attribute_qual_variant (ttype, attribute,
1568 					    TYPE_QUALS (ttype));
1569 }
1570 
1571 /* A variant of lookup_attribute() that can be used with an identifier
1572    as the first argument, and where the identifier can be either
1573    'text' or '__text__'.
1574 
1575    Given an attribute ATTR_IDENTIFIER, and a list of attributes LIST,
1576    return a pointer to the attribute's list element if the attribute
1577    is part of the list, or NULL_TREE if not found.  If the attribute
1578    appears more than once, this only returns the first occurrence; the
1579    TREE_CHAIN of the return value should be passed back in if further
1580    occurrences are wanted.  ATTR_IDENTIFIER must be an identifier but
1581    can be in the form 'text' or '__text__'.  */
1582 static tree
lookup_ident_attribute(tree attr_identifier,tree list)1583 lookup_ident_attribute (tree attr_identifier, tree list)
1584 {
1585   gcc_checking_assert (TREE_CODE (attr_identifier) == IDENTIFIER_NODE);
1586 
1587   while (list)
1588     {
1589       gcc_checking_assert (TREE_CODE (get_attribute_name (list))
1590 			   == IDENTIFIER_NODE);
1591 
1592       if (cmp_attrib_identifiers (attr_identifier,
1593 				  get_attribute_name (list)))
1594 	/* Found it.  */
1595 	break;
1596       list = TREE_CHAIN (list);
1597     }
1598 
1599   return list;
1600 }
1601 
1602 /* Remove any instances of attribute ATTR_NAME in LIST and return the
1603    modified list.  */
1604 
1605 tree
remove_attribute(const char * attr_name,tree list)1606 remove_attribute (const char *attr_name, tree list)
1607 {
1608   tree *p;
1609   gcc_checking_assert (attr_name[0] != '_');
1610 
1611   for (p = &list; *p;)
1612     {
1613       tree l = *p;
1614 
1615       tree attr = get_attribute_name (l);
1616       if (is_attribute_p (attr_name, attr))
1617 	*p = TREE_CHAIN (l);
1618       else
1619 	p = &TREE_CHAIN (l);
1620     }
1621 
1622   return list;
1623 }
1624 
1625 /* Return an attribute list that is the union of a1 and a2.  */
1626 
1627 tree
merge_attributes(tree a1,tree a2)1628 merge_attributes (tree a1, tree a2)
1629 {
1630   tree attributes;
1631 
1632   /* Either one unset?  Take the set one.  */
1633 
1634   if ((attributes = a1) == 0)
1635     attributes = a2;
1636 
1637   /* One that completely contains the other?  Take it.  */
1638 
1639   else if (a2 != 0 && ! attribute_list_contained (a1, a2))
1640     {
1641       if (attribute_list_contained (a2, a1))
1642 	attributes = a2;
1643       else
1644 	{
1645 	  /* Pick the longest list, and hang on the other list.  */
1646 
1647 	  if (list_length (a1) < list_length (a2))
1648 	    attributes = a2, a2 = a1;
1649 
1650 	  for (; a2 != 0; a2 = TREE_CHAIN (a2))
1651 	    {
1652 	      tree a;
1653 	      for (a = lookup_ident_attribute (get_attribute_name (a2),
1654 					       attributes);
1655 		   a != NULL_TREE && !attribute_value_equal (a, a2);
1656 		   a = lookup_ident_attribute (get_attribute_name (a2),
1657 					       TREE_CHAIN (a)))
1658 		;
1659 	      if (a == NULL_TREE)
1660 		{
1661 		  a1 = copy_node (a2);
1662 		  TREE_CHAIN (a1) = attributes;
1663 		  attributes = a1;
1664 		}
1665 	    }
1666 	}
1667     }
1668   return attributes;
1669 }
1670 
1671 /* Given types T1 and T2, merge their attributes and return
1672   the result.  */
1673 
1674 tree
merge_type_attributes(tree t1,tree t2)1675 merge_type_attributes (tree t1, tree t2)
1676 {
1677   return merge_attributes (TYPE_ATTRIBUTES (t1),
1678 			   TYPE_ATTRIBUTES (t2));
1679 }
1680 
1681 /* Given decls OLDDECL and NEWDECL, merge their attributes and return
1682    the result.  */
1683 
1684 tree
merge_decl_attributes(tree olddecl,tree newdecl)1685 merge_decl_attributes (tree olddecl, tree newdecl)
1686 {
1687   return merge_attributes (DECL_ATTRIBUTES (olddecl),
1688 			   DECL_ATTRIBUTES (newdecl));
1689 }
1690 
1691 /* Duplicate all attributes with name NAME in ATTR list to *ATTRS if
1692    they are missing there.  */
1693 
1694 void
duplicate_one_attribute(tree * attrs,tree attr,const char * name)1695 duplicate_one_attribute (tree *attrs, tree attr, const char *name)
1696 {
1697   attr = lookup_attribute (name, attr);
1698   if (!attr)
1699     return;
1700   tree a = lookup_attribute (name, *attrs);
1701   while (attr)
1702     {
1703       tree a2;
1704       for (a2 = a; a2; a2 = lookup_attribute (name, TREE_CHAIN (a2)))
1705 	if (attribute_value_equal (attr, a2))
1706 	  break;
1707       if (!a2)
1708 	{
1709 	  a2 = copy_node (attr);
1710 	  TREE_CHAIN (a2) = *attrs;
1711 	  *attrs = a2;
1712 	}
1713       attr = lookup_attribute (name, TREE_CHAIN (attr));
1714     }
1715 }
1716 
1717 /* Duplicate all attributes from user DECL to the corresponding
1718    builtin that should be propagated.  */
1719 
1720 void
copy_attributes_to_builtin(tree decl)1721 copy_attributes_to_builtin (tree decl)
1722 {
1723   tree b = builtin_decl_explicit (DECL_FUNCTION_CODE (decl));
1724   if (b)
1725     duplicate_one_attribute (&DECL_ATTRIBUTES (b),
1726 			     DECL_ATTRIBUTES (decl), "omp declare simd");
1727 }
1728 
1729 #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
1730 
1731 /* Specialization of merge_decl_attributes for various Windows targets.
1732 
1733    This handles the following situation:
1734 
1735      __declspec (dllimport) int foo;
1736      int foo;
1737 
1738    The second instance of `foo' nullifies the dllimport.  */
1739 
1740 tree
merge_dllimport_decl_attributes(tree old,tree new_tree)1741 merge_dllimport_decl_attributes (tree old, tree new_tree)
1742 {
1743   tree a;
1744   int delete_dllimport_p = 1;
1745 
1746   /* What we need to do here is remove from `old' dllimport if it doesn't
1747      appear in `new'.  dllimport behaves like extern: if a declaration is
1748      marked dllimport and a definition appears later, then the object
1749      is not dllimport'd.  We also remove a `new' dllimport if the old list
1750      contains dllexport:  dllexport always overrides dllimport, regardless
1751      of the order of declaration.  */
1752   if (!VAR_OR_FUNCTION_DECL_P (new_tree))
1753     delete_dllimport_p = 0;
1754   else if (DECL_DLLIMPORT_P (new_tree)
1755      	   && lookup_attribute ("dllexport", DECL_ATTRIBUTES (old)))
1756     {
1757       DECL_DLLIMPORT_P (new_tree) = 0;
1758       warning (OPT_Wattributes, "%q+D already declared with dllexport "
1759 	       "attribute: dllimport ignored", new_tree);
1760     }
1761   else if (DECL_DLLIMPORT_P (old) && !DECL_DLLIMPORT_P (new_tree))
1762     {
1763       /* Warn about overriding a symbol that has already been used, e.g.:
1764 	   extern int __attribute__ ((dllimport)) foo;
1765 	   int* bar () {return &foo;}
1766 	   int foo;
1767       */
1768       if (TREE_USED (old))
1769 	{
1770 	  warning (0, "%q+D redeclared without dllimport attribute "
1771 		   "after being referenced with dll linkage", new_tree);
1772 	  /* If we have used a variable's address with dllimport linkage,
1773 	      keep the old DECL_DLLIMPORT_P flag: the ADDR_EXPR using the
1774 	      decl may already have had TREE_CONSTANT computed.
1775 	      We still remove the attribute so that assembler code refers
1776 	      to '&foo rather than '_imp__foo'.  */
1777 	  if (VAR_P (old) && TREE_ADDRESSABLE (old))
1778 	    DECL_DLLIMPORT_P (new_tree) = 1;
1779 	}
1780 
1781       /* Let an inline definition silently override the external reference,
1782 	 but otherwise warn about attribute inconsistency.  */
1783       else if (VAR_P (new_tree) || !DECL_DECLARED_INLINE_P (new_tree))
1784 	warning (OPT_Wattributes, "%q+D redeclared without dllimport "
1785 		 "attribute: previous dllimport ignored", new_tree);
1786     }
1787   else
1788     delete_dllimport_p = 0;
1789 
1790   a = merge_attributes (DECL_ATTRIBUTES (old), DECL_ATTRIBUTES (new_tree));
1791 
1792   if (delete_dllimport_p)
1793     a = remove_attribute ("dllimport", a);
1794 
1795   return a;
1796 }
1797 
1798 /* Handle a "dllimport" or "dllexport" attribute; arguments as in
1799    struct attribute_spec.handler.  */
1800 
1801 tree
handle_dll_attribute(tree * pnode,tree name,tree args,int flags,bool * no_add_attrs)1802 handle_dll_attribute (tree * pnode, tree name, tree args, int flags,
1803 		      bool *no_add_attrs)
1804 {
1805   tree node = *pnode;
1806   bool is_dllimport;
1807 
1808   /* These attributes may apply to structure and union types being created,
1809      but otherwise should pass to the declaration involved.  */
1810   if (!DECL_P (node))
1811     {
1812       if (flags & ((int) ATTR_FLAG_DECL_NEXT | (int) ATTR_FLAG_FUNCTION_NEXT
1813 		   | (int) ATTR_FLAG_ARRAY_NEXT))
1814 	{
1815 	  *no_add_attrs = true;
1816 	  return tree_cons (name, args, NULL_TREE);
1817 	}
1818       if (TREE_CODE (node) == RECORD_TYPE
1819 	  || TREE_CODE (node) == UNION_TYPE)
1820 	{
1821 	  node = TYPE_NAME (node);
1822 	  if (!node)
1823 	    return NULL_TREE;
1824 	}
1825       else
1826 	{
1827 	  warning (OPT_Wattributes, "%qE attribute ignored",
1828 		   name);
1829 	  *no_add_attrs = true;
1830 	  return NULL_TREE;
1831 	}
1832     }
1833 
1834   if (!VAR_OR_FUNCTION_DECL_P (node) && TREE_CODE (node) != TYPE_DECL)
1835     {
1836       *no_add_attrs = true;
1837       warning (OPT_Wattributes, "%qE attribute ignored",
1838 	       name);
1839       return NULL_TREE;
1840     }
1841 
1842   if (TREE_CODE (node) == TYPE_DECL
1843       && TREE_CODE (TREE_TYPE (node)) != RECORD_TYPE
1844       && TREE_CODE (TREE_TYPE (node)) != UNION_TYPE)
1845     {
1846       *no_add_attrs = true;
1847       warning (OPT_Wattributes, "%qE attribute ignored",
1848 	       name);
1849       return NULL_TREE;
1850     }
1851 
1852   is_dllimport = is_attribute_p ("dllimport", name);
1853 
1854   /* Report error on dllimport ambiguities seen now before they cause
1855      any damage.  */
1856   if (is_dllimport)
1857     {
1858       /* Honor any target-specific overrides.  */
1859       if (!targetm.valid_dllimport_attribute_p (node))
1860 	*no_add_attrs = true;
1861 
1862      else if (TREE_CODE (node) == FUNCTION_DECL
1863 	      && DECL_DECLARED_INLINE_P (node))
1864 	{
1865 	  warning (OPT_Wattributes, "inline function %q+D declared as "
1866 		  "dllimport: attribute ignored", node);
1867 	  *no_add_attrs = true;
1868 	}
1869       /* Like MS, treat definition of dllimported variables and
1870 	 non-inlined functions on declaration as syntax errors.  */
1871      else if (TREE_CODE (node) == FUNCTION_DECL && DECL_INITIAL (node))
1872 	{
1873 	  error ("function %q+D definition is marked dllimport", node);
1874 	  *no_add_attrs = true;
1875 	}
1876 
1877      else if (VAR_P (node))
1878 	{
1879 	  if (DECL_INITIAL (node))
1880 	    {
1881 	      error ("variable %q+D definition is marked dllimport",
1882 		     node);
1883 	      *no_add_attrs = true;
1884 	    }
1885 
1886 	  /* `extern' needn't be specified with dllimport.
1887 	     Specify `extern' now and hope for the best.  Sigh.  */
1888 	  DECL_EXTERNAL (node) = 1;
1889 	  /* Also, implicitly give dllimport'd variables declared within
1890 	     a function global scope, unless declared static.  */
1891 	  if (current_function_decl != NULL_TREE && !TREE_STATIC (node))
1892 	    TREE_PUBLIC (node) = 1;
1893 	  /* Clear TREE_STATIC because DECL_EXTERNAL is set, unless
1894 	     it is a C++ static data member.  */
1895 	  if (DECL_CONTEXT (node) == NULL_TREE
1896 	      || !RECORD_OR_UNION_TYPE_P (DECL_CONTEXT (node)))
1897 	    TREE_STATIC (node) = 0;
1898 	}
1899 
1900       if (*no_add_attrs == false)
1901 	DECL_DLLIMPORT_P (node) = 1;
1902     }
1903   else if (TREE_CODE (node) == FUNCTION_DECL
1904 	   && DECL_DECLARED_INLINE_P (node)
1905 	   && flag_keep_inline_dllexport)
1906     /* An exported function, even if inline, must be emitted.  */
1907     DECL_EXTERNAL (node) = 0;
1908 
1909   /*  Report error if symbol is not accessible at global scope.  */
1910   if (!TREE_PUBLIC (node) && VAR_OR_FUNCTION_DECL_P (node))
1911     {
1912       error ("external linkage required for symbol %q+D because of "
1913 	     "%qE attribute", node, name);
1914       *no_add_attrs = true;
1915     }
1916 
1917   /* A dllexport'd entity must have default visibility so that other
1918      program units (shared libraries or the main executable) can see
1919      it.  A dllimport'd entity must have default visibility so that
1920      the linker knows that undefined references within this program
1921      unit can be resolved by the dynamic linker.  */
1922   if (!*no_add_attrs)
1923     {
1924       if (DECL_VISIBILITY_SPECIFIED (node)
1925 	  && DECL_VISIBILITY (node) != VISIBILITY_DEFAULT)
1926 	error ("%qE implies default visibility, but %qD has already "
1927 	       "been declared with a different visibility",
1928 	       name, node);
1929       DECL_VISIBILITY (node) = VISIBILITY_DEFAULT;
1930       DECL_VISIBILITY_SPECIFIED (node) = 1;
1931     }
1932 
1933   return NULL_TREE;
1934 }
1935 
1936 #endif /* TARGET_DLLIMPORT_DECL_ATTRIBUTES  */
1937 
1938 /* Given two lists of attributes, return true if list l2 is
1939    equivalent to l1.  */
1940 
1941 int
attribute_list_equal(const_tree l1,const_tree l2)1942 attribute_list_equal (const_tree l1, const_tree l2)
1943 {
1944   if (l1 == l2)
1945     return 1;
1946 
1947   return attribute_list_contained (l1, l2)
1948 	 && attribute_list_contained (l2, l1);
1949 }
1950 
1951 /* Given two lists of attributes, return true if list L2 is
1952    completely contained within L1.  */
1953 /* ??? This would be faster if attribute names were stored in a canonicalized
1954    form.  Otherwise, if L1 uses `foo' and L2 uses `__foo__', the long method
1955    must be used to show these elements are equivalent (which they are).  */
1956 /* ??? It's not clear that attributes with arguments will always be handled
1957    correctly.  */
1958 
1959 int
attribute_list_contained(const_tree l1,const_tree l2)1960 attribute_list_contained (const_tree l1, const_tree l2)
1961 {
1962   const_tree t1, t2;
1963 
1964   /* First check the obvious, maybe the lists are identical.  */
1965   if (l1 == l2)
1966     return 1;
1967 
1968   /* Maybe the lists are similar.  */
1969   for (t1 = l1, t2 = l2;
1970        t1 != 0 && t2 != 0
1971        && get_attribute_name (t1) == get_attribute_name (t2)
1972        && TREE_VALUE (t1) == TREE_VALUE (t2);
1973        t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
1974     ;
1975 
1976   /* Maybe the lists are equal.  */
1977   if (t1 == 0 && t2 == 0)
1978     return 1;
1979 
1980   for (; t2 != 0; t2 = TREE_CHAIN (t2))
1981     {
1982       const_tree attr;
1983       /* This CONST_CAST is okay because lookup_attribute does not
1984 	 modify its argument and the return value is assigned to a
1985 	 const_tree.  */
1986       for (attr = lookup_ident_attribute (get_attribute_name (t2),
1987 					  CONST_CAST_TREE (l1));
1988 	   attr != NULL_TREE && !attribute_value_equal (t2, attr);
1989 	   attr = lookup_ident_attribute (get_attribute_name (t2),
1990 					  TREE_CHAIN (attr)))
1991 	;
1992 
1993       if (attr == NULL_TREE)
1994 	return 0;
1995     }
1996 
1997   return 1;
1998 }
1999 
2000 /* The backbone of lookup_attribute().  ATTR_LEN is the string length
2001    of ATTR_NAME, and LIST is not NULL_TREE.
2002 
2003    The function is called from lookup_attribute in order to optimize
2004    for size.  */
2005 
2006 tree
private_lookup_attribute(const char * attr_name,size_t attr_len,tree list)2007 private_lookup_attribute (const char *attr_name, size_t attr_len, tree list)
2008 {
2009   while (list)
2010     {
2011       tree attr = get_attribute_name (list);
2012       size_t ident_len = IDENTIFIER_LENGTH (attr);
2013       if (cmp_attribs (attr_name, attr_len, IDENTIFIER_POINTER (attr),
2014 		       ident_len))
2015 	break;
2016       list = TREE_CHAIN (list);
2017     }
2018 
2019   return list;
2020 }
2021 
2022 /* Return true if the function decl or type NODE has been declared
2023    with attribute ANAME among attributes ATTRS.  */
2024 
2025 static bool
has_attribute(tree node,tree attrs,const char * aname)2026 has_attribute (tree node, tree attrs, const char *aname)
2027 {
2028   if (!strcmp (aname, "const"))
2029     {
2030       if (DECL_P (node) && TREE_READONLY (node))
2031 	return true;
2032     }
2033   else if (!strcmp (aname, "malloc"))
2034     {
2035       if (DECL_P (node) && DECL_IS_MALLOC (node))
2036 	return true;
2037     }
2038   else if (!strcmp (aname, "noreturn"))
2039     {
2040       if (DECL_P (node) && TREE_THIS_VOLATILE (node))
2041 	return true;
2042     }
2043   else if (!strcmp (aname, "nothrow"))
2044     {
2045       if (TREE_NOTHROW (node))
2046 	return true;
2047     }
2048   else if (!strcmp (aname, "pure"))
2049     {
2050       if (DECL_P (node) && DECL_PURE_P (node))
2051 	return true;
2052     }
2053 
2054   return lookup_attribute (aname, attrs);
2055 }
2056 
2057 /* Return the number of mismatched function or type attributes between
2058    the "template" function declaration TMPL and DECL.  The word "template"
2059    doesn't necessarily refer to a C++ template but rather a declaration
2060    whose attributes should be matched by those on DECL.  For a non-zero
2061    return value set *ATTRSTR to a string representation of the list of
2062    mismatched attributes with quoted names.
2063    ATTRLIST is a list of additional attributes that SPEC should be
2064    taken to ultimately be declared with.  */
2065 
2066 unsigned
decls_mismatched_attributes(tree tmpl,tree decl,tree attrlist,const char * const blacklist[],pretty_printer * attrstr)2067 decls_mismatched_attributes (tree tmpl, tree decl, tree attrlist,
2068 			     const char* const blacklist[],
2069 			     pretty_printer *attrstr)
2070 {
2071   if (TREE_CODE (tmpl) != FUNCTION_DECL)
2072     return 0;
2073 
2074   /* Avoid warning if either declaration or its type is deprecated.  */
2075   if (TREE_DEPRECATED (tmpl)
2076       || TREE_DEPRECATED (decl))
2077     return 0;
2078 
2079   const tree tmpls[] = { tmpl, TREE_TYPE (tmpl) };
2080   const tree decls[] = { decl, TREE_TYPE (decl) };
2081 
2082   if (TREE_DEPRECATED (tmpls[1])
2083       || TREE_DEPRECATED (decls[1])
2084       || TREE_DEPRECATED (TREE_TYPE (tmpls[1]))
2085       || TREE_DEPRECATED (TREE_TYPE (decls[1])))
2086     return 0;
2087 
2088   tree tmpl_attrs[] = { DECL_ATTRIBUTES (tmpl), TYPE_ATTRIBUTES (tmpls[1]) };
2089   tree decl_attrs[] = { DECL_ATTRIBUTES (decl), TYPE_ATTRIBUTES (decls[1]) };
2090 
2091   if (!decl_attrs[0])
2092     decl_attrs[0] = attrlist;
2093   else if (!decl_attrs[1])
2094     decl_attrs[1] = attrlist;
2095 
2096   /* Avoid warning if the template has no attributes.  */
2097   if (!tmpl_attrs[0] && !tmpl_attrs[1])
2098     return 0;
2099 
2100   /* Avoid warning if either declaration contains an attribute on
2101      the white list below.  */
2102   const char* const whitelist[] = {
2103     "error", "warning"
2104   };
2105 
2106   for (unsigned i = 0; i != 2; ++i)
2107     for (unsigned j = 0; j != sizeof whitelist / sizeof *whitelist; ++j)
2108       if (lookup_attribute (whitelist[j], tmpl_attrs[i])
2109 	  || lookup_attribute (whitelist[j], decl_attrs[i]))
2110 	return 0;
2111 
2112   /* Put together a list of the black-listed attributes that the template
2113      is declared with and the declaration is not, in case it's not apparent
2114      from the most recent declaration of the template.  */
2115   unsigned nattrs = 0;
2116 
2117   for (unsigned i = 0; blacklist[i]; ++i)
2118     {
2119       /* Attribute leaf only applies to extern functions.  Avoid mentioning
2120 	 it when it's missing from a static declaration.  */
2121       if (!TREE_PUBLIC (decl)
2122 	  && !strcmp ("leaf", blacklist[i]))
2123 	continue;
2124 
2125       for (unsigned j = 0; j != 2; ++j)
2126 	{
2127 	  if (!has_attribute (tmpls[j], tmpl_attrs[j], blacklist[i]))
2128 	    continue;
2129 
2130 	  bool found = false;
2131 	  unsigned kmax = 1 + !!decl_attrs[1];
2132 	  for (unsigned k = 0; k != kmax; ++k)
2133 	    {
2134 	      if (has_attribute (decls[k], decl_attrs[k], blacklist[i]))
2135 		{
2136 		  found = true;
2137 		  break;
2138 		}
2139 	    }
2140 
2141 	  if (!found)
2142 	    {
2143 	      if (nattrs)
2144 		pp_string (attrstr, ", ");
2145 	      pp_begin_quote (attrstr, pp_show_color (global_dc->printer));
2146 	      pp_string (attrstr, blacklist[i]);
2147 	      pp_end_quote (attrstr, pp_show_color (global_dc->printer));
2148 	      ++nattrs;
2149 	    }
2150 
2151 	  break;
2152 	}
2153     }
2154 
2155   return nattrs;
2156 }
2157 
2158 /* Issue a warning for the declaration ALIAS for TARGET where ALIAS
2159    specifies either attributes that are incompatible with those of
2160    TARGET, or attributes that are missing and that declaring ALIAS
2161    with would benefit.  */
2162 
2163 void
maybe_diag_alias_attributes(tree alias,tree target)2164 maybe_diag_alias_attributes (tree alias, tree target)
2165 {
2166   /* Do not expect attributes to match between aliases and ifunc
2167      resolvers.  There is no obvious correspondence between them.  */
2168   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)))
2169     return;
2170 
2171   const char* const blacklist[] = {
2172     "alloc_align", "alloc_size", "cold", "const", "hot", "leaf", "malloc",
2173     "nonnull", "noreturn", "nothrow", "pure", "returns_nonnull",
2174     "returns_twice", NULL
2175   };
2176 
2177   pretty_printer attrnames;
2178   if (warn_attribute_alias > 1)
2179     {
2180       /* With -Wattribute-alias=2 detect alias declarations that are more
2181 	 restrictive than their targets first.  Those indicate potential
2182 	 codegen bugs.  */
2183       if (unsigned n = decls_mismatched_attributes (alias, target, NULL_TREE,
2184 						    blacklist, &attrnames))
2185 	{
2186 	  auto_diagnostic_group d;
2187 	  if (warning_n (DECL_SOURCE_LOCATION (alias),
2188 			 OPT_Wattribute_alias_, n,
2189 			 "%qD specifies more restrictive attribute than "
2190 			 "its target %qD: %s",
2191 			 "%qD specifies more restrictive attributes than "
2192 			 "its target %qD: %s",
2193 			 alias, target, pp_formatted_text (&attrnames)))
2194 	    inform (DECL_SOURCE_LOCATION (target),
2195 		    "%qD target declared here", alias);
2196 	  return;
2197 	}
2198     }
2199 
2200   /* Detect alias declarations that are less restrictive than their
2201      targets.  Those suggest potential optimization opportunities
2202      (solved by adding the missing attribute(s) to the alias).  */
2203   if (unsigned n = decls_mismatched_attributes (target, alias, NULL_TREE,
2204 						blacklist, &attrnames))
2205     {
2206       auto_diagnostic_group d;
2207       if (warning_n (DECL_SOURCE_LOCATION (alias),
2208 		     OPT_Wmissing_attributes, n,
2209 		     "%qD specifies less restrictive attribute than "
2210 		     "its target %qD: %s",
2211 		     "%qD specifies less restrictive attributes than "
2212 		     "its target %qD: %s",
2213 		     alias, target, pp_formatted_text (&attrnames)))
2214 	inform (DECL_SOURCE_LOCATION (target),
2215 		"%qD target declared here", alias);
2216     }
2217 }
2218 
2219 /* Initialize a mapping RWM for a call to a function declared with
2220    attribute access in ATTRS.  Each attribute positional operand
2221    inserts one entry into the mapping with the operand number as
2222    the key.  */
2223 
2224 void
init_attr_rdwr_indices(rdwr_map * rwm,tree attrs)2225 init_attr_rdwr_indices (rdwr_map *rwm, tree attrs)
2226 {
2227   if (!attrs)
2228     return;
2229 
2230   for (tree access = attrs;
2231        (access = lookup_attribute ("access", access));
2232        access = TREE_CHAIN (access))
2233     {
2234       /* The TREE_VALUE of an attribute is a TREE_LIST whose TREE_VALUE
2235 	 is the attribute argument's value.  */
2236       tree mode = TREE_VALUE (access);
2237       if (!mode)
2238 	return;
2239 
2240       /* The (optional) list of VLA bounds.  */
2241       tree vblist = TREE_CHAIN (mode);
2242       mode = TREE_VALUE (mode);
2243       if (TREE_CODE (mode) != STRING_CST)
2244 	continue;
2245       gcc_assert (TREE_CODE (mode) == STRING_CST);
2246 
2247       if (vblist)
2248 	vblist = nreverse (copy_list (TREE_VALUE (vblist)));
2249 
2250       for (const char *m = TREE_STRING_POINTER (mode); *m; )
2251 	{
2252 	  attr_access acc = { };
2253 
2254 	  /* Skip the internal-only plus sign.  */
2255 	  if (*m == '+')
2256 	    ++m;
2257 
2258 	  acc.str = m;
2259 	  acc.mode = acc.from_mode_char (*m);
2260 	  acc.sizarg = UINT_MAX;
2261 
2262 	  const char *end;
2263 	  acc.ptrarg = strtoul (++m, const_cast<char**>(&end), 10);
2264 	  m = end;
2265 
2266 	  if (*m == '[')
2267 	    {
2268 	      /* Forms containing the square bracket are internal-only
2269 		 (not specified by an attribute declaration), and used
2270 		 for various forms of array and VLA parameters.  */
2271 	      acc.internal_p = true;
2272 
2273 	      /* Search to the closing bracket and look at the preceding
2274 		 code: it determines the form of the most significant
2275 		 bound of the array.  Others prior to it encode the form
2276 		 of interior VLA bounds.  They're not of interest here.  */
2277 	      end = strchr (m, ']');
2278 	      const char *p = end;
2279 	      gcc_assert (p);
2280 
2281 	      while (ISDIGIT (p[-1]))
2282 		--p;
2283 
2284 	      if (ISDIGIT (*p))
2285 		{
2286 		  /* A digit denotes a constant bound (as in T[3]).  */
2287 		  acc.static_p = p[-1] == 's';
2288 		  acc.minsize = strtoull (p, NULL, 10);
2289 		}
2290 	      else if (' ' == p[-1])
2291 		{
2292 		  /* A space denotes an ordinary array of unspecified bound
2293 		     (as in T[]).  */
2294 		  acc.minsize = 0;
2295 		}
2296 	      else if ('*' == p[-1] || '$' == p[-1])
2297 		{
2298 		  /* An asterisk denotes a VLA.  When the closing bracket
2299 		     is followed by a comma and a dollar sign its bound is
2300 		     on the list.  Otherwise it's a VLA with an unspecified
2301 		     bound.  */
2302 		  acc.static_p = p[-2] == 's';
2303 		  acc.minsize = HOST_WIDE_INT_M1U;
2304 		}
2305 
2306 	      m = end + 1;
2307 	    }
2308 
2309 	  if (*m == ',')
2310 	    {
2311 	      ++m;
2312 	      do
2313 		{
2314 		  if (*m == '$')
2315 		    {
2316 		      ++m;
2317 		      if (!acc.size && vblist)
2318 			{
2319 			  /* Extract the list of VLA bounds for the current
2320 			     parameter, store it in ACC.SIZE, and advance
2321 			     to the list of bounds for the next VLA parameter.
2322 			  */
2323 			  acc.size = TREE_VALUE (vblist);
2324 			  vblist = TREE_CHAIN (vblist);
2325 			}
2326 		    }
2327 
2328 		  if (ISDIGIT (*m))
2329 		    {
2330 		      /* Extract the positional argument.  It's absent
2331 			 for VLAs whose bound doesn't name a function
2332 			 parameter.  */
2333 		      unsigned pos = strtoul (m, const_cast<char**>(&end), 10);
2334 		      if (acc.sizarg == UINT_MAX)
2335 			acc.sizarg = pos;
2336 		      m = end;
2337 		    }
2338 		}
2339 	      while (*m == '$');
2340 	    }
2341 
2342 	  acc.end = m;
2343 
2344 	  bool existing;
2345 	  auto &ref = rwm->get_or_insert (acc.ptrarg, &existing);
2346 	  if (existing)
2347 	    {
2348 	      /* Merge the new spec with the existing.  */
2349 	      if (acc.minsize == HOST_WIDE_INT_M1U)
2350 		ref.minsize = HOST_WIDE_INT_M1U;
2351 
2352 	      if (acc.sizarg != UINT_MAX)
2353 		ref.sizarg = acc.sizarg;
2354 
2355 	      if (acc.mode)
2356 		ref.mode = acc.mode;
2357 	    }
2358 	  else
2359 	    ref = acc;
2360 
2361 	  /* Unconditionally add an entry for the required pointer
2362 	     operand of the attribute, and one for the optional size
2363 	     operand when it's specified.  */
2364 	  if (acc.sizarg != UINT_MAX)
2365 	    rwm->put (acc.sizarg, acc);
2366 	}
2367     }
2368 }
2369 
2370 /* Return the access specification for a function parameter PARM
2371    or null if the current function has no such specification.  */
2372 
2373 attr_access *
get_parm_access(rdwr_map & rdwr_idx,tree parm,tree fndecl)2374 get_parm_access (rdwr_map &rdwr_idx, tree parm,
2375 		 tree fndecl /* = current_function_decl */)
2376 {
2377   tree fntype = TREE_TYPE (fndecl);
2378   init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
2379 
2380   if (rdwr_idx.is_empty ())
2381     return NULL;
2382 
2383   unsigned argpos = 0;
2384   tree fnargs = DECL_ARGUMENTS (fndecl);
2385   for (tree arg = fnargs; arg; arg = TREE_CHAIN (arg), ++argpos)
2386     if (arg == parm)
2387       return rdwr_idx.get (argpos);
2388 
2389   return NULL;
2390 }
2391 
2392 /* Return the internal representation as STRING_CST.  Internal positional
2393    arguments are zero-based.  */
2394 
2395 tree
to_internal_string() const2396 attr_access::to_internal_string () const
2397 {
2398   return build_string (end - str, str);
2399 }
2400 
2401 /* Return the human-readable representation of the external attribute
2402    specification (as it might appear in the source code) as STRING_CST.
2403    External positional arguments are one-based.  */
2404 
2405 tree
to_external_string() const2406 attr_access::to_external_string () const
2407 {
2408   char buf[80];
2409   gcc_assert (mode != access_deferred);
2410   int len = snprintf (buf, sizeof buf, "access (%s, %u",
2411 		      mode_names[mode], ptrarg + 1);
2412   if (sizarg != UINT_MAX)
2413     len += snprintf (buf + len, sizeof buf - len, ", %u", sizarg + 1);
2414   strcpy (buf + len, ")");
2415   return build_string (len + 2, buf);
2416 }
2417 
2418 /* Return the number of specified VLA bounds and set *nunspec to
2419    the number of unspecified ones (those designated by [*]).  */
2420 
2421 unsigned
vla_bounds(unsigned * nunspec) const2422 attr_access::vla_bounds (unsigned *nunspec) const
2423 {
2424   unsigned nbounds = 0;
2425   *nunspec = 0;
2426   /* STR points to the beginning of the specified string for the current
2427      argument that may be followed by the string for the next argument.  */
2428   for (const char* p = strchr (str, ']'); p && *p != '['; --p)
2429     {
2430       if (*p == '*')
2431 	++*nunspec;
2432       else if (*p == '$')
2433 	++nbounds;
2434     }
2435   return nbounds;
2436 }
2437 
2438 /* Reset front end-specific attribute access data from ATTRS.
2439    Called from the free_lang_data pass.  */
2440 
2441 /* static */ void
free_lang_data(tree attrs)2442 attr_access::free_lang_data (tree attrs)
2443 {
2444   for (tree acs = attrs; (acs = lookup_attribute ("access", acs));
2445        acs = TREE_CHAIN (acs))
2446     {
2447       tree vblist = TREE_VALUE (acs);
2448       vblist = TREE_CHAIN (vblist);
2449       if (!vblist)
2450 	continue;
2451 
2452       for (vblist = TREE_VALUE (vblist); vblist; vblist = TREE_CHAIN (vblist))
2453 	{
2454 	  tree *pvbnd = &TREE_VALUE (vblist);
2455 	  if (!*pvbnd || DECL_P (*pvbnd))
2456 	    continue;
2457 
2458 	  /* VLA bounds that are expressions as opposed to DECLs are
2459 	     only used in the front end.  Reset them to keep front end
2460 	     trees leaking into the middle end (see pr97172) and to
2461 	     free up memory.  */
2462 	  *pvbnd = NULL_TREE;
2463 	}
2464     }
2465 
2466   for (tree argspec = attrs; (argspec = lookup_attribute ("arg spec", argspec));
2467        argspec = TREE_CHAIN (argspec))
2468     {
2469       /* Same as above.  */
2470       tree *pvblist = &TREE_VALUE (argspec);
2471       *pvblist = NULL_TREE;
2472     }
2473 }
2474 
2475 /* Defined in attr_access.  */
2476 constexpr char attr_access::mode_chars[];
2477 constexpr char attr_access::mode_names[][11];
2478 
2479 /* Format an array, including a VLA, pointed to by TYPE and used as
2480    a function parameter as a human-readable string.  ACC describes
2481    an access to the parameter and is used to determine the outermost
2482    form of the array including its bound which is otherwise obviated
2483    by its decay to pointer.  Return the formatted string.  */
2484 
2485 std::string
array_as_string(tree type) const2486 attr_access::array_as_string (tree type) const
2487 {
2488   std::string typstr;
2489 
2490   if (type == error_mark_node)
2491     return std::string ();
2492 
2493   if (this->str)
2494     {
2495       /* For array parameters (but not pointers) create a temporary array
2496 	 type that corresponds to the form of the parameter including its
2497 	 qualifiers even though they apply to the pointer, not the array
2498 	 type.  */
2499       const bool vla_p = minsize == HOST_WIDE_INT_M1U;
2500       tree eltype = TREE_TYPE (type);
2501       tree index_type = NULL_TREE;
2502 
2503       if (minsize == HOST_WIDE_INT_M1U)
2504 	{
2505 	  /* Determine if this is a VLA (an array whose most significant
2506 	     bound is nonconstant and whose access string has "$]" in it)
2507 	     extract the bound expression from SIZE.  */
2508 	  const char *p = end;
2509 	  for ( ; p != str && *p-- != ']'; );
2510 	  if (*p == '$')
2511 	    /* SIZE may have been cleared.  Use it with care.  */
2512 	    index_type = build_index_type (size ? TREE_VALUE (size) : size);
2513 	}
2514       else if (minsize)
2515 	index_type = build_index_type (size_int (minsize - 1));
2516 
2517       tree arat = NULL_TREE;
2518       if (static_p || vla_p)
2519 	{
2520 	  tree flag = static_p ? integer_one_node : NULL_TREE;
2521 	  /* Hack: there's no language-independent way to encode
2522 	     the "static" specifier or the "*" notation in an array type.
2523 	     Add a "fake" attribute to have the pretty-printer add "static"
2524 	     or "*".  The "[static N]" notation is only valid in the most
2525 	     significant bound but [*] can be used for any bound.  Because
2526 	     [*] is represented the same as [0] this hack only works for
2527 	     the most significant bound like static and the others are
2528 	     rendered as [0].  */
2529 	  arat = build_tree_list (get_identifier ("array"), flag);
2530 	}
2531 
2532       const int quals = TYPE_QUALS (type);
2533       type = build_array_type (eltype, index_type);
2534       type = build_type_attribute_qual_variant (type, arat, quals);
2535     }
2536 
2537   /* Format the type using the current pretty printer.  The generic tree
2538      printer does a terrible job.  */
2539   pretty_printer *pp = global_dc->printer->clone ();
2540   pp_printf (pp, "%qT", type);
2541   typstr = pp_formatted_text (pp);
2542   delete pp;
2543 
2544   return typstr;
2545 }
2546 
2547 #if CHECKING_P
2548 
2549 namespace selftest
2550 {
2551 
2552 /* Helper types to verify the consistency attribute exclusions.  */
2553 
2554 typedef std::pair<const char *, const char *> excl_pair;
2555 
2556 struct excl_hash_traits: typed_noop_remove<excl_pair>
2557 {
2558   typedef excl_pair  value_type;
2559   typedef value_type compare_type;
2560 
hashselftest::excl_hash_traits2561   static hashval_t hash (const value_type &x)
2562   {
2563     hashval_t h1 = htab_hash_string (x.first);
2564     hashval_t h2 = htab_hash_string (x.second);
2565     return h1 ^ h2;
2566   }
2567 
equalselftest::excl_hash_traits2568   static bool equal (const value_type &x, const value_type &y)
2569   {
2570     return !strcmp (x.first, y.first) && !strcmp (x.second, y.second);
2571   }
2572 
mark_deletedselftest::excl_hash_traits2573   static void mark_deleted (value_type &x)
2574   {
2575     x = value_type (NULL, NULL);
2576   }
2577 
2578   static const bool empty_zero_p = false;
2579 
mark_emptyselftest::excl_hash_traits2580   static void mark_empty (value_type &x)
2581   {
2582     x = value_type ("", "");
2583   }
2584 
is_deletedselftest::excl_hash_traits2585   static bool is_deleted (const value_type &x)
2586   {
2587     return !x.first && !x.second;
2588   }
2589 
is_emptyselftest::excl_hash_traits2590   static bool is_empty (const value_type &x)
2591   {
2592     return !*x.first && !*x.second;
2593   }
2594 };
2595 
2596 
2597 /* Self-test to verify that each attribute exclusion is symmetric,
2598    meaning that if attribute A is encoded as incompatible with
2599    attribute B then the opposite relationship is also encoded.
2600    This test also detects most cases of misspelled attribute names
2601    in exclusions.  */
2602 
2603 static void
test_attribute_exclusions()2604 test_attribute_exclusions ()
2605 {
2606   /* Iterate over the array of attribute tables first (with TI0 as
2607      the index) and over the array of attribute_spec in each table
2608      (with SI0 as the index).  */
2609   const size_t ntables = ARRAY_SIZE (attribute_tables);
2610 
2611   /* Set of pairs of mutually exclusive attributes.  */
2612   typedef hash_set<excl_pair, false, excl_hash_traits> exclusion_set;
2613   exclusion_set excl_set;
2614 
2615   for (size_t ti0 = 0; ti0 != ntables; ++ti0)
2616     for (size_t s0 = 0; attribute_tables[ti0][s0].name; ++s0)
2617       {
2618 	const attribute_spec::exclusions *excl
2619 	  = attribute_tables[ti0][s0].exclude;
2620 
2621 	/* Skip each attribute that doesn't define exclusions.  */
2622 	if (!excl)
2623 	  continue;
2624 
2625 	const char *attr_name = attribute_tables[ti0][s0].name;
2626 
2627 	/* Iterate over the set of exclusions for every attribute
2628 	   (with EI0 as the index) adding the exclusions defined
2629 	   for each to the set.  */
2630 	for (size_t ei0 = 0; excl[ei0].name; ++ei0)
2631 	  {
2632 	    const char *excl_name = excl[ei0].name;
2633 
2634 	    if (!strcmp (attr_name, excl_name))
2635 	      continue;
2636 
2637 	    excl_set.add (excl_pair (attr_name, excl_name));
2638 	  }
2639       }
2640 
2641   /* Traverse the set of mutually exclusive pairs of attributes
2642      and verify that they are symmetric.  */
2643   for (exclusion_set::iterator it = excl_set.begin ();
2644        it != excl_set.end ();
2645        ++it)
2646     {
2647       if (!excl_set.contains (excl_pair ((*it).second, (*it).first)))
2648 	{
2649 	  /* An exclusion for an attribute has been found that
2650 	     doesn't have a corresponding exclusion in the opposite
2651 	     direction.  */
2652 	  char desc[120];
2653 	  sprintf (desc, "'%s' attribute exclusion '%s' must be symmetric",
2654 		   (*it).first, (*it).second);
2655 	  fail (SELFTEST_LOCATION, desc);
2656 	}
2657     }
2658 }
2659 
2660 void
attribs_cc_tests()2661 attribs_cc_tests ()
2662 {
2663   test_attribute_exclusions ();
2664 }
2665 
2666 } /* namespace selftest */
2667 
2668 #endif /* CHECKING_P */
2669