1 /* Functions dealing with attribute handling, used by most front ends.
2    Copyright (C) 1992-2019 Free Software Foundation, Inc.
3 
4 This file is part of GCC.
5 
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10 
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19 
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "target.h"
24 #include "tree.h"
25 #include "stringpool.h"
26 #include "diagnostic-core.h"
27 #include "attribs.h"
28 #include "stor-layout.h"
29 #include "langhooks.h"
30 #include "plugin.h"
31 #include "selftest.h"
32 #include "hash-set.h"
33 #include "diagnostic.h"
34 #include "pretty-print.h"
35 #include "intl.h"
36 
37 /* Table of the tables of attributes (common, language, format, machine)
38    searched.  */
39 static const struct attribute_spec *attribute_tables[4];
40 
41 /* Substring representation.  */
42 
43 struct substring
44 {
45   const char *str;
46   int length;
47 };
48 
49 /* Simple hash function to avoid need to scan whole string.  */
50 
51 static inline hashval_t
substring_hash(const char * str,int l)52 substring_hash (const char *str, int l)
53 {
54   return str[0] + str[l - 1] * 256 + l * 65536;
55 }
56 
57 /* Used for attribute_hash.  */
58 
59 struct attribute_hasher : nofree_ptr_hash <attribute_spec>
60 {
61   typedef substring *compare_type;
62   static inline hashval_t hash (const attribute_spec *);
63   static inline bool equal (const attribute_spec *, const substring *);
64 };
65 
66 inline hashval_t
hash(const attribute_spec * spec)67 attribute_hasher::hash (const attribute_spec *spec)
68 {
69   const int l = strlen (spec->name);
70   return substring_hash (spec->name, l);
71 }
72 
73 inline bool
equal(const attribute_spec * spec,const substring * str)74 attribute_hasher::equal (const attribute_spec *spec, const substring *str)
75 {
76   return (strncmp (spec->name, str->str, str->length) == 0
77 	  && !spec->name[str->length]);
78 }
79 
80 /* Scoped attribute name representation.  */
81 
82 struct scoped_attributes
83 {
84   const char *ns;
85   vec<attribute_spec> attributes;
86   hash_table<attribute_hasher> *attribute_hash;
87 };
88 
89 /* The table of scope attributes.  */
90 static vec<scoped_attributes> attributes_table;
91 
92 static scoped_attributes* find_attribute_namespace (const char*);
93 static void register_scoped_attribute (const struct attribute_spec *,
94 				       scoped_attributes *);
95 
96 static bool attributes_initialized = false;
97 
98 /* Default empty table of attributes.  */
99 
100 static const struct attribute_spec empty_attribute_table[] =
101 {
102   { NULL, 0, 0, false, false, false, false, NULL, NULL }
103 };
104 
105 /* Return base name of the attribute.  Ie '__attr__' is turned into 'attr'.
106    To avoid need for copying, we simply return length of the string.  */
107 
108 static void
extract_attribute_substring(struct substring * str)109 extract_attribute_substring (struct substring *str)
110 {
111   if (str->length > 4 && str->str[0] == '_' && str->str[1] == '_'
112       && str->str[str->length - 1] == '_' && str->str[str->length - 2] == '_')
113     {
114       str->length -= 4;
115       str->str += 2;
116     }
117 }
118 
119 /* Insert an array of attributes ATTRIBUTES into a namespace.  This
120    array must be NULL terminated.  NS is the name of attribute
121    namespace.  The function returns the namespace into which the
122    attributes have been registered.  */
123 
124 scoped_attributes *
register_scoped_attributes(const struct attribute_spec * attributes,const char * ns)125 register_scoped_attributes (const struct attribute_spec *attributes,
126 			    const char *ns)
127 {
128   scoped_attributes *result = NULL;
129 
130   /* See if we already have attributes in the namespace NS.  */
131   result = find_attribute_namespace (ns);
132 
133   if (result == NULL)
134     {
135       /* We don't have any namespace NS yet.  Create one.  */
136       scoped_attributes sa;
137 
138       if (attributes_table.is_empty ())
139 	attributes_table.create (64);
140 
141       memset (&sa, 0, sizeof (sa));
142       sa.ns = ns;
143       sa.attributes.create (64);
144       result = attributes_table.safe_push (sa);
145       result->attribute_hash = new hash_table<attribute_hasher> (200);
146     }
147 
148   /* Really add the attributes to their namespace now.  */
149   for (unsigned i = 0; attributes[i].name != NULL; ++i)
150     {
151       result->attributes.safe_push (attributes[i]);
152       register_scoped_attribute (&attributes[i], result);
153     }
154 
155   gcc_assert (result != NULL);
156 
157   return result;
158 }
159 
160 /* Return the namespace which name is NS, NULL if none exist.  */
161 
162 static scoped_attributes*
find_attribute_namespace(const char * ns)163 find_attribute_namespace (const char* ns)
164 {
165   unsigned ix;
166   scoped_attributes *iter;
167 
168   FOR_EACH_VEC_ELT (attributes_table, ix, iter)
169     if (ns == iter->ns
170 	|| (iter->ns != NULL
171 	    && ns != NULL
172 	    && !strcmp (iter->ns, ns)))
173       return iter;
174   return NULL;
175 }
176 
177 /* Make some sanity checks on the attribute tables.  */
178 
179 static void
check_attribute_tables(void)180 check_attribute_tables (void)
181 {
182   for (size_t i = 0; i < ARRAY_SIZE (attribute_tables); i++)
183     for (size_t j = 0; attribute_tables[i][j].name != NULL; j++)
184       {
185 	/* The name must not begin and end with __.  */
186 	const char *name = attribute_tables[i][j].name;
187 	int len = strlen (name);
188 
189 	gcc_assert (!(name[0] == '_' && name[1] == '_'
190 		      && name[len - 1] == '_' && name[len - 2] == '_'));
191 
192 	/* The minimum and maximum lengths must be consistent.  */
193 	gcc_assert (attribute_tables[i][j].min_length >= 0);
194 
195 	gcc_assert (attribute_tables[i][j].max_length == -1
196 		    || (attribute_tables[i][j].max_length
197 			>= attribute_tables[i][j].min_length));
198 
199 	/* An attribute cannot require both a DECL and a TYPE.  */
200 	gcc_assert (!attribute_tables[i][j].decl_required
201 		    || !attribute_tables[i][j].type_required);
202 
203 	  /* If an attribute requires a function type, in particular
204 	     it requires a type.  */
205 	gcc_assert (!attribute_tables[i][j].function_type_required
206 		    || attribute_tables[i][j].type_required);
207       }
208 
209   /* Check that each name occurs just once in each table.  */
210   for (size_t i = 0; i < ARRAY_SIZE (attribute_tables); i++)
211     for (size_t j = 0; attribute_tables[i][j].name != NULL; j++)
212       for (size_t k = j + 1; attribute_tables[i][k].name != NULL; k++)
213 	gcc_assert (strcmp (attribute_tables[i][j].name,
214 			    attribute_tables[i][k].name));
215 
216   /* Check that no name occurs in more than one table.  Names that
217      begin with '*' are exempt, and may be overridden.  */
218   for (size_t i = 0; i < ARRAY_SIZE (attribute_tables); i++)
219     for (size_t j = i + 1; j < ARRAY_SIZE (attribute_tables); j++)
220       for (size_t k = 0; attribute_tables[i][k].name != NULL; k++)
221 	for (size_t l = 0; attribute_tables[j][l].name != NULL; l++)
222 	  gcc_assert (attribute_tables[i][k].name[0] == '*'
223 		      || strcmp (attribute_tables[i][k].name,
224 				 attribute_tables[j][l].name));
225 }
226 
227 /* Initialize attribute tables, and make some sanity checks if checking is
228    enabled.  */
229 
230 void
init_attributes(void)231 init_attributes (void)
232 {
233   size_t i;
234 
235   if (attributes_initialized)
236     return;
237 
238   attribute_tables[0] = lang_hooks.common_attribute_table;
239   attribute_tables[1] = lang_hooks.attribute_table;
240   attribute_tables[2] = lang_hooks.format_attribute_table;
241   attribute_tables[3] = targetm.attribute_table;
242 
243   /* Translate NULL pointers to pointers to the empty table.  */
244   for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
245     if (attribute_tables[i] == NULL)
246       attribute_tables[i] = empty_attribute_table;
247 
248   if (flag_checking)
249     check_attribute_tables ();
250 
251   for (i = 0; i < ARRAY_SIZE (attribute_tables); ++i)
252     /* Put all the GNU attributes into the "gnu" namespace.  */
253     register_scoped_attributes (attribute_tables[i], "gnu");
254 
255   invoke_plugin_callbacks (PLUGIN_ATTRIBUTES, NULL);
256   attributes_initialized = true;
257 }
258 
259 /* Insert a single ATTR into the attribute table.  */
260 
261 void
register_attribute(const struct attribute_spec * attr)262 register_attribute (const struct attribute_spec *attr)
263 {
264   register_scoped_attribute (attr, find_attribute_namespace ("gnu"));
265 }
266 
267 /* Insert a single attribute ATTR into a namespace of attributes.  */
268 
269 static void
register_scoped_attribute(const struct attribute_spec * attr,scoped_attributes * name_space)270 register_scoped_attribute (const struct attribute_spec *attr,
271 			   scoped_attributes *name_space)
272 {
273   struct substring str;
274   attribute_spec **slot;
275 
276   gcc_assert (attr != NULL && name_space != NULL);
277 
278   gcc_assert (name_space->attribute_hash);
279 
280   str.str = attr->name;
281   str.length = strlen (str.str);
282 
283   /* Attribute names in the table must be in the form 'text' and not
284      in the form '__text__'.  */
285   gcc_assert (str.length > 0 && str.str[0] != '_');
286 
287   slot = name_space->attribute_hash
288 	 ->find_slot_with_hash (&str, substring_hash (str.str, str.length),
289 				INSERT);
290   gcc_assert (!*slot || attr->name[0] == '*');
291   *slot = CONST_CAST (struct attribute_spec *, attr);
292 }
293 
294 /* Return the spec for the scoped attribute with namespace NS and
295    name NAME.   */
296 
297 static const struct attribute_spec *
lookup_scoped_attribute_spec(const_tree ns,const_tree name)298 lookup_scoped_attribute_spec (const_tree ns, const_tree name)
299 {
300   struct substring attr;
301   scoped_attributes *attrs;
302 
303   const char *ns_str = (ns != NULL_TREE) ? IDENTIFIER_POINTER (ns): NULL;
304 
305   attrs = find_attribute_namespace (ns_str);
306 
307   if (attrs == NULL)
308     return NULL;
309 
310   attr.str = IDENTIFIER_POINTER (name);
311   attr.length = IDENTIFIER_LENGTH (name);
312   extract_attribute_substring (&attr);
313   return attrs->attribute_hash->find_with_hash (&attr,
314 						substring_hash (attr.str,
315 							       	attr.length));
316 }
317 
318 /* Return the spec for the attribute named NAME.  If NAME is a TREE_LIST,
319    it also specifies the attribute namespace.  */
320 
321 const struct attribute_spec *
lookup_attribute_spec(const_tree name)322 lookup_attribute_spec (const_tree name)
323 {
324   tree ns;
325   if (TREE_CODE (name) == TREE_LIST)
326     {
327       ns = TREE_PURPOSE (name);
328       name = TREE_VALUE (name);
329     }
330   else
331     ns = get_identifier ("gnu");
332   return lookup_scoped_attribute_spec (ns, name);
333 }
334 
335 
336 /* Return the namespace of the attribute ATTR.  This accessor works on
337    GNU and C++11 (scoped) attributes.  On GNU attributes,
338    it returns an identifier tree for the string "gnu".
339 
340    Please read the comments of cxx11_attribute_p to understand the
341    format of attributes.  */
342 
343 static tree
get_attribute_namespace(const_tree attr)344 get_attribute_namespace (const_tree attr)
345 {
346   if (cxx11_attribute_p (attr))
347     return TREE_PURPOSE (TREE_PURPOSE (attr));
348   return get_identifier ("gnu");
349 }
350 
351 /* Check LAST_DECL and NODE of the same symbol for attributes that are
352    recorded in SPEC to be mutually exclusive with ATTRNAME, diagnose
353    them, and return true if any have been found.  NODE can be a DECL
354    or a TYPE.  */
355 
356 static bool
diag_attr_exclusions(tree last_decl,tree node,tree attrname,const attribute_spec * spec)357 diag_attr_exclusions (tree last_decl, tree node, tree attrname,
358 		      const attribute_spec *spec)
359 {
360   const attribute_spec::exclusions *excl = spec->exclude;
361 
362   tree_code code = TREE_CODE (node);
363 
364   if ((code == FUNCTION_DECL && !excl->function
365        && (!excl->type || !spec->affects_type_identity))
366       || (code == VAR_DECL && !excl->variable
367 	  && (!excl->type || !spec->affects_type_identity))
368       || (((code == TYPE_DECL || RECORD_OR_UNION_TYPE_P (node)) && !excl->type)))
369     return false;
370 
371   /* True if an attribute that's mutually exclusive with ATTRNAME
372      has been found.  */
373   bool found = false;
374 
375   if (last_decl && last_decl != node && TREE_TYPE (last_decl) != node)
376     {
377       /* Check both the last DECL and its type for conflicts with
378 	 the attribute being added to the current decl or type.  */
379       found |= diag_attr_exclusions (last_decl, last_decl, attrname, spec);
380       tree decl_type = TREE_TYPE (last_decl);
381       found |= diag_attr_exclusions (last_decl, decl_type, attrname, spec);
382     }
383 
384   /* NODE is either the current DECL to which the attribute is being
385      applied or its TYPE.  For the former, consider the attributes on
386      both the DECL and its type.  */
387   tree attrs[2];
388 
389   if (DECL_P (node))
390     {
391       attrs[0] = DECL_ATTRIBUTES (node);
392       attrs[1] = TYPE_ATTRIBUTES (TREE_TYPE (node));
393     }
394   else
395     {
396       attrs[0] = TYPE_ATTRIBUTES (node);
397       attrs[1] = NULL_TREE;
398     }
399 
400   /* Iterate over the mutually exclusive attribute names and verify
401      that the symbol doesn't contain it.  */
402   for (unsigned i = 0; i != sizeof attrs / sizeof *attrs; ++i)
403     {
404       if (!attrs[i])
405 	continue;
406 
407       for ( ; excl->name; ++excl)
408 	{
409 	  /* Avoid checking the attribute against itself.  */
410 	  if (is_attribute_p (excl->name, attrname))
411 	    continue;
412 
413 	  if (!lookup_attribute (excl->name, attrs[i]))
414 	    continue;
415 
416 	  /* An exclusion may apply either to a function declaration,
417 	     type declaration, or a field/variable declaration, or
418 	     any subset of the three.  */
419 	  if (TREE_CODE (node) == FUNCTION_DECL
420 	      && !excl->function)
421 	    continue;
422 
423 	  if (TREE_CODE (node) == TYPE_DECL
424 	      && !excl->type)
425 	    continue;
426 
427 	  if ((TREE_CODE (node) == FIELD_DECL
428 	       || TREE_CODE (node) == VAR_DECL)
429 	      && !excl->variable)
430 	    continue;
431 
432 	  found = true;
433 
434 	  /* Print a note?  */
435 	  bool note = last_decl != NULL_TREE;
436 	  auto_diagnostic_group d;
437 	  if (TREE_CODE (node) == FUNCTION_DECL
438 	      && fndecl_built_in_p (node))
439 	    note &= warning (OPT_Wattributes,
440 			     "ignoring attribute %qE in declaration of "
441 			     "a built-in function %qD because it conflicts "
442 			     "with attribute %qs",
443 			     attrname, node, excl->name);
444 	  else
445 	    note &= warning (OPT_Wattributes,
446 			     "ignoring attribute %qE because "
447 			     "it conflicts with attribute %qs",
448 			     attrname, excl->name);
449 
450 	  if (note)
451 	    inform (DECL_SOURCE_LOCATION (last_decl),
452 		    "previous declaration here");
453 	}
454     }
455 
456   return found;
457 }
458 
459 /* Process the attributes listed in ATTRIBUTES and install them in *NODE,
460    which is either a DECL (including a TYPE_DECL) or a TYPE.  If a DECL,
461    it should be modified in place; if a TYPE, a copy should be created
462    unless ATTR_FLAG_TYPE_IN_PLACE is set in FLAGS.  FLAGS gives further
463    information, in the form of a bitwise OR of flags in enum attribute_flags
464    from tree.h.  Depending on these flags, some attributes may be
465    returned to be applied at a later stage (for example, to apply
466    a decl attribute to the declaration rather than to its type).  */
467 
468 tree
decl_attributes(tree * node,tree attributes,int flags,tree last_decl)469 decl_attributes (tree *node, tree attributes, int flags,
470 		 tree last_decl /* = NULL_TREE */)
471 {
472   tree a;
473   tree returned_attrs = NULL_TREE;
474 
475   if (TREE_TYPE (*node) == error_mark_node || attributes == error_mark_node)
476     return NULL_TREE;
477 
478   if (!attributes_initialized)
479     init_attributes ();
480 
481   /* If this is a function and the user used #pragma GCC optimize, add the
482      options to the attribute((optimize(...))) list.  */
483   if (TREE_CODE (*node) == FUNCTION_DECL && current_optimize_pragma)
484     {
485       tree cur_attr = lookup_attribute ("optimize", attributes);
486       tree opts = copy_list (current_optimize_pragma);
487 
488       if (! cur_attr)
489 	attributes
490 	  = tree_cons (get_identifier ("optimize"), opts, attributes);
491       else
492 	TREE_VALUE (cur_attr) = chainon (opts, TREE_VALUE (cur_attr));
493     }
494 
495   if (TREE_CODE (*node) == FUNCTION_DECL
496       && optimization_current_node != optimization_default_node
497       && !DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node))
498     DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node) = optimization_current_node;
499 
500   /* If this is a function and the user used #pragma GCC target, add the
501      options to the attribute((target(...))) list.  */
502   if (TREE_CODE (*node) == FUNCTION_DECL
503       && current_target_pragma
504       && targetm.target_option.valid_attribute_p (*node, NULL_TREE,
505 						  current_target_pragma, 0))
506     {
507       tree cur_attr = lookup_attribute ("target", attributes);
508       tree opts = copy_list (current_target_pragma);
509 
510       if (! cur_attr)
511 	attributes = tree_cons (get_identifier ("target"), opts, attributes);
512       else
513 	TREE_VALUE (cur_attr) = chainon (opts, TREE_VALUE (cur_attr));
514     }
515 
516   /* A "naked" function attribute implies "noinline" and "noclone" for
517      those targets that support it.  */
518   if (TREE_CODE (*node) == FUNCTION_DECL
519       && attributes
520       && lookup_attribute ("naked", attributes) != NULL
521       && lookup_attribute_spec (get_identifier ("naked")))
522     {
523       if (lookup_attribute ("noinline", attributes) == NULL)
524 	attributes = tree_cons (get_identifier ("noinline"), NULL, attributes);
525 
526       if (lookup_attribute ("noclone", attributes) == NULL)
527 	attributes = tree_cons (get_identifier ("noclone"),  NULL, attributes);
528     }
529 
530   /* A "noipa" function attribute implies "noinline", "noclone" and "no_icf"
531      for those targets that support it.  */
532   if (TREE_CODE (*node) == FUNCTION_DECL
533       && attributes
534       && lookup_attribute ("noipa", attributes) != NULL
535       && lookup_attribute_spec (get_identifier ("noipa")))
536     {
537       if (lookup_attribute ("noinline", attributes) == NULL)
538 	attributes = tree_cons (get_identifier ("noinline"), NULL, attributes);
539 
540       if (lookup_attribute ("noclone", attributes) == NULL)
541 	attributes = tree_cons (get_identifier ("noclone"),  NULL, attributes);
542 
543       if (lookup_attribute ("no_icf", attributes) == NULL)
544 	attributes = tree_cons (get_identifier ("no_icf"),  NULL, attributes);
545     }
546 
547   targetm.insert_attributes (*node, &attributes);
548 
549   /* Note that attributes on the same declaration are not necessarily
550      in the same order as in the source.  */
551   for (a = attributes; a; a = TREE_CHAIN (a))
552     {
553       tree ns = get_attribute_namespace (a);
554       tree name = get_attribute_name (a);
555       tree args = TREE_VALUE (a);
556       tree *anode = node;
557       const struct attribute_spec *spec
558 	= lookup_scoped_attribute_spec (ns, name);
559       int fn_ptr_quals = 0;
560       tree fn_ptr_tmp = NULL_TREE;
561 
562       if (spec == NULL)
563 	{
564 	  if (!(flags & (int) ATTR_FLAG_BUILT_IN))
565 	    {
566 	      if (ns == NULL_TREE || !cxx11_attribute_p (a))
567 		warning (OPT_Wattributes, "%qE attribute directive ignored",
568 			 name);
569 	      else
570 		warning (OPT_Wattributes,
571 			 "%<%E::%E%> scoped attribute directive ignored",
572 			 ns, name);
573 	    }
574 	  continue;
575 	}
576       else if (list_length (args) < spec->min_length
577 	       || (spec->max_length >= 0
578 		   && list_length (args) > spec->max_length))
579 	{
580 	  error ("wrong number of arguments specified for %qE attribute",
581 		 name);
582 	  continue;
583 	}
584       gcc_assert (is_attribute_p (spec->name, name));
585 
586       if (TYPE_P (*node)
587 	  && cxx11_attribute_p (a)
588 	  && !(flags & ATTR_FLAG_TYPE_IN_PLACE))
589 	{
590 	  /* This is a c++11 attribute that appertains to a
591 	     type-specifier, outside of the definition of, a class
592 	     type.  Ignore it.  */
593 	  auto_diagnostic_group d;
594 	  if (warning (OPT_Wattributes, "attribute ignored"))
595 	    inform (input_location,
596 		    "an attribute that appertains to a type-specifier "
597 		    "is ignored");
598 	  continue;
599 	}
600 
601       if (spec->decl_required && !DECL_P (*anode))
602 	{
603 	  if (flags & ((int) ATTR_FLAG_DECL_NEXT
604 		       | (int) ATTR_FLAG_FUNCTION_NEXT
605 		       | (int) ATTR_FLAG_ARRAY_NEXT))
606 	    {
607 	      /* Pass on this attribute to be tried again.  */
608 	      tree attr = tree_cons (name, args, NULL_TREE);
609 	      returned_attrs = chainon (returned_attrs, attr);
610 	      continue;
611 	    }
612 	  else
613 	    {
614 	      warning (OPT_Wattributes, "%qE attribute does not apply to types",
615 		       name);
616 	      continue;
617 	    }
618 	}
619 
620       /* If we require a type, but were passed a decl, set up to make a
621 	 new type and update the one in the decl.  ATTR_FLAG_TYPE_IN_PLACE
622 	 would have applied if we'd been passed a type, but we cannot modify
623 	 the decl's type in place here.  */
624       if (spec->type_required && DECL_P (*anode))
625 	{
626 	  anode = &TREE_TYPE (*anode);
627 	  flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
628 	}
629 
630       if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE
631 	  && TREE_CODE (*anode) != METHOD_TYPE)
632 	{
633 	  if (TREE_CODE (*anode) == POINTER_TYPE
634 	      && (TREE_CODE (TREE_TYPE (*anode)) == FUNCTION_TYPE
635 		  || TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE))
636 	    {
637 	      /* OK, this is a bit convoluted.  We can't just make a copy
638 		 of the pointer type and modify its TREE_TYPE, because if
639 		 we change the attributes of the target type the pointer
640 		 type needs to have a different TYPE_MAIN_VARIANT.  So we
641 		 pull out the target type now, frob it as appropriate, and
642 		 rebuild the pointer type later.
643 
644 		 This would all be simpler if attributes were part of the
645 		 declarator, grumble grumble.  */
646 	      fn_ptr_tmp = TREE_TYPE (*anode);
647 	      fn_ptr_quals = TYPE_QUALS (*anode);
648 	      anode = &fn_ptr_tmp;
649 	      flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
650 	    }
651 	  else if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
652 	    {
653 	      /* Pass on this attribute to be tried again.  */
654 	      tree attr = tree_cons (name, args, NULL_TREE);
655 	      returned_attrs = chainon (returned_attrs, attr);
656 	      continue;
657 	    }
658 
659 	  if (TREE_CODE (*anode) != FUNCTION_TYPE
660 	      && TREE_CODE (*anode) != METHOD_TYPE)
661 	    {
662 	      warning (OPT_Wattributes,
663 		       "%qE attribute only applies to function types",
664 		       name);
665 	      continue;
666 	    }
667 	}
668 
669       if (TYPE_P (*anode)
670 	  && (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
671 	  && TYPE_SIZE (*anode) != NULL_TREE)
672 	{
673 	  warning (OPT_Wattributes, "type attributes ignored after type is already defined");
674 	  continue;
675 	}
676 
677       bool no_add_attrs = false;
678 
679       /* Check for exclusions with other attributes on the current
680 	 declation as well as the last declaration of the same
681 	 symbol already processed (if one exists).  Detect and
682 	 reject incompatible attributes.  */
683       bool built_in = flags & ATTR_FLAG_BUILT_IN;
684       if (spec->exclude
685 	  && (flag_checking || !built_in)
686 	  && !error_operand_p (last_decl))
687 	{
688 	  /* Always check attributes on user-defined functions.
689 	     Check them on built-ins only when -fchecking is set.
690 	     Ignore __builtin_unreachable -- it's both const and
691 	     noreturn.  */
692 
693 	  if (!built_in
694 	      || !DECL_P (*anode)
695 	      || (DECL_FUNCTION_CODE (*anode) != BUILT_IN_UNREACHABLE
696 		  && (DECL_FUNCTION_CODE (*anode)
697 		      != BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE)))
698 	    {
699 	      bool no_add = diag_attr_exclusions (last_decl, *anode, name, spec);
700 	      if (!no_add && anode != node)
701 		no_add = diag_attr_exclusions (last_decl, *node, name, spec);
702 	      no_add_attrs |= no_add;
703 	    }
704 	}
705 
706       if (no_add_attrs)
707 	continue;
708 
709       if (spec->handler != NULL)
710 	{
711 	  int cxx11_flag =
712 	    cxx11_attribute_p (a) ? ATTR_FLAG_CXX11 : 0;
713 
714 	  /* Pass in an array of the current declaration followed
715 	     by the last pushed/merged declaration if  one exists.
716 	     If the handler changes CUR_AND_LAST_DECL[0] replace
717 	     *ANODE with its value.  */
718 	  tree cur_and_last_decl[] = { *anode, last_decl };
719 	  tree ret = (spec->handler) (cur_and_last_decl, name, args,
720 				      flags|cxx11_flag, &no_add_attrs);
721 
722 	  *anode = cur_and_last_decl[0];
723 	  if (ret == error_mark_node)
724 	    {
725 	      warning (OPT_Wattributes, "%qE attribute ignored", name);
726 	      no_add_attrs = true;
727 	    }
728 	  else
729 	    returned_attrs = chainon (ret, returned_attrs);
730 	}
731 
732       /* Layout the decl in case anything changed.  */
733       if (spec->type_required && DECL_P (*node)
734 	  && (VAR_P (*node)
735 	      || TREE_CODE (*node) == PARM_DECL
736 	      || TREE_CODE (*node) == RESULT_DECL))
737 	relayout_decl (*node);
738 
739       if (!no_add_attrs)
740 	{
741 	  tree old_attrs;
742 	  tree a;
743 
744 	  if (DECL_P (*anode))
745 	    old_attrs = DECL_ATTRIBUTES (*anode);
746 	  else
747 	    old_attrs = TYPE_ATTRIBUTES (*anode);
748 
749 	  for (a = lookup_attribute (spec->name, old_attrs);
750 	       a != NULL_TREE;
751 	       a = lookup_attribute (spec->name, TREE_CHAIN (a)))
752 	    {
753 	      if (simple_cst_equal (TREE_VALUE (a), args) == 1)
754 		break;
755 	    }
756 
757 	  if (a == NULL_TREE)
758 	    {
759 	      /* This attribute isn't already in the list.  */
760 	      if (DECL_P (*anode))
761 		DECL_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
762 	      else if (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
763 		{
764 		  TYPE_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
765 		  /* If this is the main variant, also push the attributes
766 		     out to the other variants.  */
767 		  if (*anode == TYPE_MAIN_VARIANT (*anode))
768 		    {
769 		      tree variant;
770 		      for (variant = *anode; variant;
771 			   variant = TYPE_NEXT_VARIANT (variant))
772 			{
773 			  if (TYPE_ATTRIBUTES (variant) == old_attrs)
774 			    TYPE_ATTRIBUTES (variant)
775 			      = TYPE_ATTRIBUTES (*anode);
776 			  else if (!lookup_attribute
777 				   (spec->name, TYPE_ATTRIBUTES (variant)))
778 			    TYPE_ATTRIBUTES (variant) = tree_cons
779 			      (name, args, TYPE_ATTRIBUTES (variant));
780 			}
781 		    }
782 		}
783 	      else
784 		*anode = build_type_attribute_variant (*anode,
785 						       tree_cons (name, args,
786 								  old_attrs));
787 	    }
788 	}
789 
790       if (fn_ptr_tmp)
791 	{
792 	  /* Rebuild the function pointer type and put it in the
793 	     appropriate place.  */
794 	  fn_ptr_tmp = build_pointer_type (fn_ptr_tmp);
795 	  if (fn_ptr_quals)
796 	    fn_ptr_tmp = build_qualified_type (fn_ptr_tmp, fn_ptr_quals);
797 	  if (DECL_P (*node))
798 	    TREE_TYPE (*node) = fn_ptr_tmp;
799 	  else
800 	    {
801 	      gcc_assert (TREE_CODE (*node) == POINTER_TYPE);
802 	      *node = fn_ptr_tmp;
803 	    }
804 	}
805     }
806 
807   return returned_attrs;
808 }
809 
810 /* Return TRUE iff ATTR has been parsed by the front-end as a C++-11
811    attribute.
812 
813    When G++ parses a C++11 attribute, it is represented as
814    a TREE_LIST which TREE_PURPOSE is itself a TREE_LIST.  TREE_PURPOSE
815    (TREE_PURPOSE (ATTR)) is the namespace of the attribute, and the
816    TREE_VALUE (TREE_PURPOSE (ATTR)) is its non-qualified name.  Please
817    use get_attribute_namespace and get_attribute_name to retrieve the
818    namespace and name of the attribute, as these accessors work with
819    GNU attributes as well.  */
820 
821 bool
cxx11_attribute_p(const_tree attr)822 cxx11_attribute_p (const_tree attr)
823 {
824   if (attr == NULL_TREE
825       || TREE_CODE (attr) != TREE_LIST)
826     return false;
827 
828   return (TREE_CODE (TREE_PURPOSE (attr)) == TREE_LIST);
829 }
830 
831 /* Return the name of the attribute ATTR.  This accessor works on GNU
832    and C++11 (scoped) attributes.
833 
834    Please read the comments of cxx11_attribute_p to understand the
835    format of attributes.  */
836 
837 tree
get_attribute_name(const_tree attr)838 get_attribute_name (const_tree attr)
839 {
840   if (cxx11_attribute_p (attr))
841     return TREE_VALUE (TREE_PURPOSE (attr));
842   return TREE_PURPOSE (attr);
843 }
844 
845 /* Subroutine of set_method_tm_attributes.  Apply TM attribute ATTR
846    to the method FNDECL.  */
847 
848 void
apply_tm_attr(tree fndecl,tree attr)849 apply_tm_attr (tree fndecl, tree attr)
850 {
851   decl_attributes (&TREE_TYPE (fndecl), tree_cons (attr, NULL, NULL), 0);
852 }
853 
854 /* Makes a function attribute of the form NAME(ARG_NAME) and chains
855    it to CHAIN.  */
856 
857 tree
make_attribute(const char * name,const char * arg_name,tree chain)858 make_attribute (const char *name, const char *arg_name, tree chain)
859 {
860   tree attr_name;
861   tree attr_arg_name;
862   tree attr_args;
863   tree attr;
864 
865   attr_name = get_identifier (name);
866   attr_arg_name = build_string (strlen (arg_name), arg_name);
867   attr_args = tree_cons (NULL_TREE, attr_arg_name, NULL_TREE);
868   attr = tree_cons (attr_name, attr_args, chain);
869   return attr;
870 }
871 
872 
873 /* Common functions used for target clone support.  */
874 
875 /* Comparator function to be used in qsort routine to sort attribute
876    specification strings to "target".  */
877 
878 static int
attr_strcmp(const void * v1,const void * v2)879 attr_strcmp (const void *v1, const void *v2)
880 {
881   const char *c1 = *(char *const*)v1;
882   const char *c2 = *(char *const*)v2;
883   return strcmp (c1, c2);
884 }
885 
886 /* ARGLIST is the argument to target attribute.  This function tokenizes
887    the comma separated arguments, sorts them and returns a string which
888    is a unique identifier for the comma separated arguments.   It also
889    replaces non-identifier characters "=,-" with "_".  */
890 
891 char *
sorted_attr_string(tree arglist)892 sorted_attr_string (tree arglist)
893 {
894   tree arg;
895   size_t str_len_sum = 0;
896   char **args = NULL;
897   char *attr_str, *ret_str;
898   char *attr = NULL;
899   unsigned int argnum = 1;
900   unsigned int i;
901 
902   for (arg = arglist; arg; arg = TREE_CHAIN (arg))
903     {
904       const char *str = TREE_STRING_POINTER (TREE_VALUE (arg));
905       size_t len = strlen (str);
906       str_len_sum += len + 1;
907       if (arg != arglist)
908 	argnum++;
909       for (i = 0; i < strlen (str); i++)
910 	if (str[i] == ',')
911 	  argnum++;
912     }
913 
914   attr_str = XNEWVEC (char, str_len_sum);
915   str_len_sum = 0;
916   for (arg = arglist; arg; arg = TREE_CHAIN (arg))
917     {
918       const char *str = TREE_STRING_POINTER (TREE_VALUE (arg));
919       size_t len = strlen (str);
920       memcpy (attr_str + str_len_sum, str, len);
921       attr_str[str_len_sum + len] = TREE_CHAIN (arg) ? ',' : '\0';
922       str_len_sum += len + 1;
923     }
924 
925   /* Replace "=,-" with "_".  */
926   for (i = 0; i < strlen (attr_str); i++)
927     if (attr_str[i] == '=' || attr_str[i]== '-')
928       attr_str[i] = '_';
929 
930   if (argnum == 1)
931     return attr_str;
932 
933   args = XNEWVEC (char *, argnum);
934 
935   i = 0;
936   attr = strtok (attr_str, ",");
937   while (attr != NULL)
938     {
939       args[i] = attr;
940       i++;
941       attr = strtok (NULL, ",");
942     }
943 
944   qsort (args, argnum, sizeof (char *), attr_strcmp);
945 
946   ret_str = XNEWVEC (char, str_len_sum);
947   str_len_sum = 0;
948   for (i = 0; i < argnum; i++)
949     {
950       size_t len = strlen (args[i]);
951       memcpy (ret_str + str_len_sum, args[i], len);
952       ret_str[str_len_sum + len] = i < argnum - 1 ? '_' : '\0';
953       str_len_sum += len + 1;
954     }
955 
956   XDELETEVEC (args);
957   XDELETEVEC (attr_str);
958   return ret_str;
959 }
960 
961 
962 /* This function returns true if FN1 and FN2 are versions of the same function,
963    that is, the target strings of the function decls are different.  This assumes
964    that FN1 and FN2 have the same signature.  */
965 
966 bool
common_function_versions(tree fn1,tree fn2)967 common_function_versions (tree fn1, tree fn2)
968 {
969   tree attr1, attr2;
970   char *target1, *target2;
971   bool result;
972 
973   if (TREE_CODE (fn1) != FUNCTION_DECL
974       || TREE_CODE (fn2) != FUNCTION_DECL)
975     return false;
976 
977   attr1 = lookup_attribute ("target", DECL_ATTRIBUTES (fn1));
978   attr2 = lookup_attribute ("target", DECL_ATTRIBUTES (fn2));
979 
980   /* At least one function decl should have the target attribute specified.  */
981   if (attr1 == NULL_TREE && attr2 == NULL_TREE)
982     return false;
983 
984   /* Diagnose missing target attribute if one of the decls is already
985      multi-versioned.  */
986   if (attr1 == NULL_TREE || attr2 == NULL_TREE)
987     {
988       if (DECL_FUNCTION_VERSIONED (fn1) || DECL_FUNCTION_VERSIONED (fn2))
989 	{
990 	  if (attr2 != NULL_TREE)
991 	    {
992 	      std::swap (fn1, fn2);
993 	      attr1 = attr2;
994 	    }
995 	  error_at (DECL_SOURCE_LOCATION (fn2),
996 		    "missing %<target%> attribute for multi-versioned %qD",
997 		    fn2);
998 	  inform (DECL_SOURCE_LOCATION (fn1),
999 		  "previous declaration of %qD", fn1);
1000 	  /* Prevent diagnosing of the same error multiple times.  */
1001 	  DECL_ATTRIBUTES (fn2)
1002 	    = tree_cons (get_identifier ("target"),
1003 			 copy_node (TREE_VALUE (attr1)),
1004 			 DECL_ATTRIBUTES (fn2));
1005 	}
1006       return false;
1007     }
1008 
1009   target1 = sorted_attr_string (TREE_VALUE (attr1));
1010   target2 = sorted_attr_string (TREE_VALUE (attr2));
1011 
1012   /* The sorted target strings must be different for fn1 and fn2
1013      to be versions.  */
1014   if (strcmp (target1, target2) == 0)
1015     result = false;
1016   else
1017     result = true;
1018 
1019   XDELETEVEC (target1);
1020   XDELETEVEC (target2);
1021 
1022   return result;
1023 }
1024 
1025 /* Return a new name by appending SUFFIX to the DECL name.  If make_unique
1026    is true, append the full path name of the source file.  */
1027 
1028 char *
make_unique_name(tree decl,const char * suffix,bool make_unique)1029 make_unique_name (tree decl, const char *suffix, bool make_unique)
1030 {
1031   char *global_var_name;
1032   int name_len;
1033   const char *name;
1034   const char *unique_name = NULL;
1035 
1036   name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
1037 
1038   /* Get a unique name that can be used globally without any chances
1039      of collision at link time.  */
1040   if (make_unique)
1041     unique_name = IDENTIFIER_POINTER (get_file_function_name ("\0"));
1042 
1043   name_len = strlen (name) + strlen (suffix) + 2;
1044 
1045   if (make_unique)
1046     name_len += strlen (unique_name) + 1;
1047   global_var_name = XNEWVEC (char, name_len);
1048 
1049   /* Use '.' to concatenate names as it is demangler friendly.  */
1050   if (make_unique)
1051     snprintf (global_var_name, name_len, "%s.%s.%s", name, unique_name,
1052 	      suffix);
1053   else
1054     snprintf (global_var_name, name_len, "%s.%s", name, suffix);
1055 
1056   return global_var_name;
1057 }
1058 
1059 /* Make a dispatcher declaration for the multi-versioned function DECL.
1060    Calls to DECL function will be replaced with calls to the dispatcher
1061    by the front-end.  Return the decl created.  */
1062 
1063 tree
make_dispatcher_decl(const tree decl)1064 make_dispatcher_decl (const tree decl)
1065 {
1066   tree func_decl;
1067   char *func_name;
1068   tree fn_type, func_type;
1069 
1070   func_name = xstrdup (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
1071 
1072   fn_type = TREE_TYPE (decl);
1073   func_type = build_function_type (TREE_TYPE (fn_type),
1074 				   TYPE_ARG_TYPES (fn_type));
1075 
1076   func_decl = build_fn_decl (func_name, func_type);
1077   XDELETEVEC (func_name);
1078   TREE_USED (func_decl) = 1;
1079   DECL_CONTEXT (func_decl) = NULL_TREE;
1080   DECL_INITIAL (func_decl) = error_mark_node;
1081   DECL_ARTIFICIAL (func_decl) = 1;
1082   /* Mark this func as external, the resolver will flip it again if
1083      it gets generated.  */
1084   DECL_EXTERNAL (func_decl) = 1;
1085   /* This will be of type IFUNCs have to be externally visible.  */
1086   TREE_PUBLIC (func_decl) = 1;
1087 
1088   return func_decl;
1089 }
1090 
1091 /* Returns true if decl is multi-versioned and DECL is the default function,
1092    that is it is not tagged with target specific optimization.  */
1093 
1094 bool
is_function_default_version(const tree decl)1095 is_function_default_version (const tree decl)
1096 {
1097   if (TREE_CODE (decl) != FUNCTION_DECL
1098       || !DECL_FUNCTION_VERSIONED (decl))
1099     return false;
1100   tree attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl));
1101   gcc_assert (attr);
1102   attr = TREE_VALUE (TREE_VALUE (attr));
1103   return (TREE_CODE (attr) == STRING_CST
1104 	  && strcmp (TREE_STRING_POINTER (attr), "default") == 0);
1105 }
1106 
1107 /* Return a declaration like DDECL except that its DECL_ATTRIBUTES
1108    is ATTRIBUTE.  */
1109 
1110 tree
build_decl_attribute_variant(tree ddecl,tree attribute)1111 build_decl_attribute_variant (tree ddecl, tree attribute)
1112 {
1113   DECL_ATTRIBUTES (ddecl) = attribute;
1114   return ddecl;
1115 }
1116 
1117 /* Return a type like TTYPE except that its TYPE_ATTRIBUTE
1118    is ATTRIBUTE and its qualifiers are QUALS.
1119 
1120    Record such modified types already made so we don't make duplicates.  */
1121 
1122 tree
build_type_attribute_qual_variant(tree otype,tree attribute,int quals)1123 build_type_attribute_qual_variant (tree otype, tree attribute, int quals)
1124 {
1125   tree ttype = otype;
1126   if (! attribute_list_equal (TYPE_ATTRIBUTES (ttype), attribute))
1127     {
1128       tree ntype;
1129 
1130       /* Building a distinct copy of a tagged type is inappropriate; it
1131 	 causes breakage in code that expects there to be a one-to-one
1132 	 relationship between a struct and its fields.
1133 	 build_duplicate_type is another solution (as used in
1134 	 handle_transparent_union_attribute), but that doesn't play well
1135 	 with the stronger C++ type identity model.  */
1136       if (TREE_CODE (ttype) == RECORD_TYPE
1137 	  || TREE_CODE (ttype) == UNION_TYPE
1138 	  || TREE_CODE (ttype) == QUAL_UNION_TYPE
1139 	  || TREE_CODE (ttype) == ENUMERAL_TYPE)
1140 	{
1141 	  warning (OPT_Wattributes,
1142 		   "ignoring attributes applied to %qT after definition",
1143 		   TYPE_MAIN_VARIANT (ttype));
1144 	  return build_qualified_type (ttype, quals);
1145 	}
1146 
1147       ttype = build_qualified_type (ttype, TYPE_UNQUALIFIED);
1148       if (lang_hooks.types.copy_lang_qualifiers
1149 	  && otype != TYPE_MAIN_VARIANT (otype))
1150 	ttype = (lang_hooks.types.copy_lang_qualifiers
1151 		 (ttype, TYPE_MAIN_VARIANT (otype)));
1152 
1153       tree dtype = ntype = build_distinct_type_copy (ttype);
1154 
1155       TYPE_ATTRIBUTES (ntype) = attribute;
1156 
1157       hashval_t hash = type_hash_canon_hash (ntype);
1158       ntype = type_hash_canon (hash, ntype);
1159 
1160       if (ntype != dtype)
1161 	/* This variant was already in the hash table, don't mess with
1162 	   TYPE_CANONICAL.  */;
1163       else if (TYPE_STRUCTURAL_EQUALITY_P (ttype)
1164 	       || !comp_type_attributes (ntype, ttype))
1165 	/* If the target-dependent attributes make NTYPE different from
1166 	   its canonical type, we will need to use structural equality
1167 	   checks for this type.
1168 
1169 	   We shouldn't get here for stripping attributes from a type;
1170 	   the no-attribute type might not need structural comparison.  But
1171 	   we can if was discarded from type_hash_table.  */
1172 	SET_TYPE_STRUCTURAL_EQUALITY (ntype);
1173       else if (TYPE_CANONICAL (ntype) == ntype)
1174 	TYPE_CANONICAL (ntype) = TYPE_CANONICAL (ttype);
1175 
1176       ttype = build_qualified_type (ntype, quals);
1177       if (lang_hooks.types.copy_lang_qualifiers
1178 	  && otype != TYPE_MAIN_VARIANT (otype))
1179 	ttype = lang_hooks.types.copy_lang_qualifiers (ttype, otype);
1180     }
1181   else if (TYPE_QUALS (ttype) != quals)
1182     ttype = build_qualified_type (ttype, quals);
1183 
1184   return ttype;
1185 }
1186 
1187 /* Compare two identifier nodes representing attributes.
1188    Return true if they are the same, false otherwise.  */
1189 
1190 static bool
cmp_attrib_identifiers(const_tree attr1,const_tree attr2)1191 cmp_attrib_identifiers (const_tree attr1, const_tree attr2)
1192 {
1193   /* Make sure we're dealing with IDENTIFIER_NODEs.  */
1194   gcc_checking_assert (TREE_CODE (attr1) == IDENTIFIER_NODE
1195 		       && TREE_CODE (attr2) == IDENTIFIER_NODE);
1196 
1197   /* Identifiers can be compared directly for equality.  */
1198   if (attr1 == attr2)
1199     return true;
1200 
1201   return cmp_attribs (IDENTIFIER_POINTER (attr1), IDENTIFIER_LENGTH (attr1),
1202 		      IDENTIFIER_POINTER (attr2), IDENTIFIER_LENGTH (attr2));
1203 }
1204 
1205 /* Compare two constructor-element-type constants.  Return 1 if the lists
1206    are known to be equal; otherwise return 0.  */
1207 
1208 static bool
simple_cst_list_equal(const_tree l1,const_tree l2)1209 simple_cst_list_equal (const_tree l1, const_tree l2)
1210 {
1211   while (l1 != NULL_TREE && l2 != NULL_TREE)
1212     {
1213       if (simple_cst_equal (TREE_VALUE (l1), TREE_VALUE (l2)) != 1)
1214 	return false;
1215 
1216       l1 = TREE_CHAIN (l1);
1217       l2 = TREE_CHAIN (l2);
1218     }
1219 
1220   return l1 == l2;
1221 }
1222 
1223 /* Check if "omp declare simd" attribute arguments, CLAUSES1 and CLAUSES2, are
1224    the same.  */
1225 
1226 static bool
omp_declare_simd_clauses_equal(tree clauses1,tree clauses2)1227 omp_declare_simd_clauses_equal (tree clauses1, tree clauses2)
1228 {
1229   tree cl1, cl2;
1230   for (cl1 = clauses1, cl2 = clauses2;
1231        cl1 && cl2;
1232        cl1 = OMP_CLAUSE_CHAIN (cl1), cl2 = OMP_CLAUSE_CHAIN (cl2))
1233     {
1234       if (OMP_CLAUSE_CODE (cl1) != OMP_CLAUSE_CODE (cl2))
1235 	return false;
1236       if (OMP_CLAUSE_CODE (cl1) != OMP_CLAUSE_SIMDLEN)
1237 	{
1238 	  if (simple_cst_equal (OMP_CLAUSE_DECL (cl1),
1239 				OMP_CLAUSE_DECL (cl2)) != 1)
1240 	    return false;
1241 	}
1242       switch (OMP_CLAUSE_CODE (cl1))
1243 	{
1244 	case OMP_CLAUSE_ALIGNED:
1245 	  if (simple_cst_equal (OMP_CLAUSE_ALIGNED_ALIGNMENT (cl1),
1246 				OMP_CLAUSE_ALIGNED_ALIGNMENT (cl2)) != 1)
1247 	    return false;
1248 	  break;
1249 	case OMP_CLAUSE_LINEAR:
1250 	  if (simple_cst_equal (OMP_CLAUSE_LINEAR_STEP (cl1),
1251 				OMP_CLAUSE_LINEAR_STEP (cl2)) != 1)
1252 	    return false;
1253 	  break;
1254 	case OMP_CLAUSE_SIMDLEN:
1255 	  if (simple_cst_equal (OMP_CLAUSE_SIMDLEN_EXPR (cl1),
1256 				OMP_CLAUSE_SIMDLEN_EXPR (cl2)) != 1)
1257 	    return false;
1258 	default:
1259 	  break;
1260 	}
1261     }
1262   return true;
1263 }
1264 
1265 
1266 /* Compare two attributes for their value identity.  Return true if the
1267    attribute values are known to be equal; otherwise return false.  */
1268 
1269 bool
attribute_value_equal(const_tree attr1,const_tree attr2)1270 attribute_value_equal (const_tree attr1, const_tree attr2)
1271 {
1272   if (TREE_VALUE (attr1) == TREE_VALUE (attr2))
1273     return true;
1274 
1275   if (TREE_VALUE (attr1) != NULL_TREE
1276       && TREE_CODE (TREE_VALUE (attr1)) == TREE_LIST
1277       && TREE_VALUE (attr2) != NULL_TREE
1278       && TREE_CODE (TREE_VALUE (attr2)) == TREE_LIST)
1279     {
1280       /* Handle attribute format.  */
1281       if (is_attribute_p ("format", get_attribute_name (attr1)))
1282 	{
1283 	  attr1 = TREE_VALUE (attr1);
1284 	  attr2 = TREE_VALUE (attr2);
1285 	  /* Compare the archetypes (printf/scanf/strftime/...).  */
1286 	  if (!cmp_attrib_identifiers (TREE_VALUE (attr1), TREE_VALUE (attr2)))
1287 	    return false;
1288 	  /* Archetypes are the same.  Compare the rest.  */
1289 	  return (simple_cst_list_equal (TREE_CHAIN (attr1),
1290 					 TREE_CHAIN (attr2)) == 1);
1291 	}
1292       return (simple_cst_list_equal (TREE_VALUE (attr1),
1293 				     TREE_VALUE (attr2)) == 1);
1294     }
1295 
1296   if (TREE_VALUE (attr1)
1297       && TREE_CODE (TREE_VALUE (attr1)) == OMP_CLAUSE
1298       && TREE_VALUE (attr2)
1299       && TREE_CODE (TREE_VALUE (attr2)) == OMP_CLAUSE)
1300     return omp_declare_simd_clauses_equal (TREE_VALUE (attr1),
1301 					   TREE_VALUE (attr2));
1302 
1303   return (simple_cst_equal (TREE_VALUE (attr1), TREE_VALUE (attr2)) == 1);
1304 }
1305 
1306 /* Return 0 if the attributes for two types are incompatible, 1 if they
1307    are compatible, and 2 if they are nearly compatible (which causes a
1308    warning to be generated).  */
1309 int
comp_type_attributes(const_tree type1,const_tree type2)1310 comp_type_attributes (const_tree type1, const_tree type2)
1311 {
1312   const_tree a1 = TYPE_ATTRIBUTES (type1);
1313   const_tree a2 = TYPE_ATTRIBUTES (type2);
1314   const_tree a;
1315 
1316   if (a1 == a2)
1317     return 1;
1318   for (a = a1; a != NULL_TREE; a = TREE_CHAIN (a))
1319     {
1320       const struct attribute_spec *as;
1321       const_tree attr;
1322 
1323       as = lookup_attribute_spec (get_attribute_name (a));
1324       if (!as || as->affects_type_identity == false)
1325 	continue;
1326 
1327       attr = lookup_attribute (as->name, CONST_CAST_TREE (a2));
1328       if (!attr || !attribute_value_equal (a, attr))
1329 	break;
1330     }
1331   if (!a)
1332     {
1333       for (a = a2; a != NULL_TREE; a = TREE_CHAIN (a))
1334 	{
1335 	  const struct attribute_spec *as;
1336 
1337 	  as = lookup_attribute_spec (get_attribute_name (a));
1338 	  if (!as || as->affects_type_identity == false)
1339 	    continue;
1340 
1341 	  if (!lookup_attribute (as->name, CONST_CAST_TREE (a1)))
1342 	    break;
1343 	  /* We don't need to compare trees again, as we did this
1344 	     already in first loop.  */
1345 	}
1346       /* All types - affecting identity - are equal, so
1347 	 there is no need to call target hook for comparison.  */
1348       if (!a)
1349 	return 1;
1350     }
1351   if (lookup_attribute ("transaction_safe", CONST_CAST_TREE (a)))
1352     return 0;
1353   if ((lookup_attribute ("nocf_check", TYPE_ATTRIBUTES (type1)) != NULL)
1354       ^ (lookup_attribute ("nocf_check", TYPE_ATTRIBUTES (type2)) != NULL))
1355     return 0;
1356   /* As some type combinations - like default calling-convention - might
1357      be compatible, we have to call the target hook to get the final result.  */
1358   return targetm.comp_type_attributes (type1, type2);
1359 }
1360 
1361 /* Return a type like TTYPE except that its TYPE_ATTRIBUTE
1362    is ATTRIBUTE.
1363 
1364    Record such modified types already made so we don't make duplicates.  */
1365 
1366 tree
build_type_attribute_variant(tree ttype,tree attribute)1367 build_type_attribute_variant (tree ttype, tree attribute)
1368 {
1369   return build_type_attribute_qual_variant (ttype, attribute,
1370 					    TYPE_QUALS (ttype));
1371 }
1372 
1373 /* A variant of lookup_attribute() that can be used with an identifier
1374    as the first argument, and where the identifier can be either
1375    'text' or '__text__'.
1376 
1377    Given an attribute ATTR_IDENTIFIER, and a list of attributes LIST,
1378    return a pointer to the attribute's list element if the attribute
1379    is part of the list, or NULL_TREE if not found.  If the attribute
1380    appears more than once, this only returns the first occurrence; the
1381    TREE_CHAIN of the return value should be passed back in if further
1382    occurrences are wanted.  ATTR_IDENTIFIER must be an identifier but
1383    can be in the form 'text' or '__text__'.  */
1384 static tree
lookup_ident_attribute(tree attr_identifier,tree list)1385 lookup_ident_attribute (tree attr_identifier, tree list)
1386 {
1387   gcc_checking_assert (TREE_CODE (attr_identifier) == IDENTIFIER_NODE);
1388 
1389   while (list)
1390     {
1391       gcc_checking_assert (TREE_CODE (get_attribute_name (list))
1392 			   == IDENTIFIER_NODE);
1393 
1394       if (cmp_attrib_identifiers (attr_identifier,
1395 				  get_attribute_name (list)))
1396 	/* Found it.  */
1397 	break;
1398       list = TREE_CHAIN (list);
1399     }
1400 
1401   return list;
1402 }
1403 
1404 /* Remove any instances of attribute ATTR_NAME in LIST and return the
1405    modified list.  */
1406 
1407 tree
remove_attribute(const char * attr_name,tree list)1408 remove_attribute (const char *attr_name, tree list)
1409 {
1410   tree *p;
1411   gcc_checking_assert (attr_name[0] != '_');
1412 
1413   for (p = &list; *p;)
1414     {
1415       tree l = *p;
1416 
1417       tree attr = get_attribute_name (l);
1418       if (is_attribute_p (attr_name, attr))
1419 	*p = TREE_CHAIN (l);
1420       else
1421 	p = &TREE_CHAIN (l);
1422     }
1423 
1424   return list;
1425 }
1426 
1427 /* Return an attribute list that is the union of a1 and a2.  */
1428 
1429 tree
merge_attributes(tree a1,tree a2)1430 merge_attributes (tree a1, tree a2)
1431 {
1432   tree attributes;
1433 
1434   /* Either one unset?  Take the set one.  */
1435 
1436   if ((attributes = a1) == 0)
1437     attributes = a2;
1438 
1439   /* One that completely contains the other?  Take it.  */
1440 
1441   else if (a2 != 0 && ! attribute_list_contained (a1, a2))
1442     {
1443       if (attribute_list_contained (a2, a1))
1444 	attributes = a2;
1445       else
1446 	{
1447 	  /* Pick the longest list, and hang on the other list.  */
1448 
1449 	  if (list_length (a1) < list_length (a2))
1450 	    attributes = a2, a2 = a1;
1451 
1452 	  for (; a2 != 0; a2 = TREE_CHAIN (a2))
1453 	    {
1454 	      tree a;
1455 	      for (a = lookup_ident_attribute (get_attribute_name (a2),
1456 					       attributes);
1457 		   a != NULL_TREE && !attribute_value_equal (a, a2);
1458 		   a = lookup_ident_attribute (get_attribute_name (a2),
1459 					       TREE_CHAIN (a)))
1460 		;
1461 	      if (a == NULL_TREE)
1462 		{
1463 		  a1 = copy_node (a2);
1464 		  TREE_CHAIN (a1) = attributes;
1465 		  attributes = a1;
1466 		}
1467 	    }
1468 	}
1469     }
1470   return attributes;
1471 }
1472 
1473 /* Given types T1 and T2, merge their attributes and return
1474   the result.  */
1475 
1476 tree
merge_type_attributes(tree t1,tree t2)1477 merge_type_attributes (tree t1, tree t2)
1478 {
1479   return merge_attributes (TYPE_ATTRIBUTES (t1),
1480 			   TYPE_ATTRIBUTES (t2));
1481 }
1482 
1483 /* Given decls OLDDECL and NEWDECL, merge their attributes and return
1484    the result.  */
1485 
1486 tree
merge_decl_attributes(tree olddecl,tree newdecl)1487 merge_decl_attributes (tree olddecl, tree newdecl)
1488 {
1489   return merge_attributes (DECL_ATTRIBUTES (olddecl),
1490 			   DECL_ATTRIBUTES (newdecl));
1491 }
1492 
1493 /* Duplicate all attributes with name NAME in ATTR list to *ATTRS if
1494    they are missing there.  */
1495 
1496 void
duplicate_one_attribute(tree * attrs,tree attr,const char * name)1497 duplicate_one_attribute (tree *attrs, tree attr, const char *name)
1498 {
1499   attr = lookup_attribute (name, attr);
1500   if (!attr)
1501     return;
1502   tree a = lookup_attribute (name, *attrs);
1503   while (attr)
1504     {
1505       tree a2;
1506       for (a2 = a; a2; a2 = lookup_attribute (name, TREE_CHAIN (a2)))
1507 	if (attribute_value_equal (attr, a2))
1508 	  break;
1509       if (!a2)
1510 	{
1511 	  a2 = copy_node (attr);
1512 	  TREE_CHAIN (a2) = *attrs;
1513 	  *attrs = a2;
1514 	}
1515       attr = lookup_attribute (name, TREE_CHAIN (attr));
1516     }
1517 }
1518 
1519 /* Duplicate all attributes from user DECL to the corresponding
1520    builtin that should be propagated.  */
1521 
1522 void
copy_attributes_to_builtin(tree decl)1523 copy_attributes_to_builtin (tree decl)
1524 {
1525   tree b = builtin_decl_explicit (DECL_FUNCTION_CODE (decl));
1526   if (b)
1527     duplicate_one_attribute (&DECL_ATTRIBUTES (b),
1528 			     DECL_ATTRIBUTES (decl), "omp declare simd");
1529 }
1530 
1531 #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
1532 
1533 /* Specialization of merge_decl_attributes for various Windows targets.
1534 
1535    This handles the following situation:
1536 
1537      __declspec (dllimport) int foo;
1538      int foo;
1539 
1540    The second instance of `foo' nullifies the dllimport.  */
1541 
1542 tree
merge_dllimport_decl_attributes(tree old,tree new_tree)1543 merge_dllimport_decl_attributes (tree old, tree new_tree)
1544 {
1545   tree a;
1546   int delete_dllimport_p = 1;
1547 
1548   /* What we need to do here is remove from `old' dllimport if it doesn't
1549      appear in `new'.  dllimport behaves like extern: if a declaration is
1550      marked dllimport and a definition appears later, then the object
1551      is not dllimport'd.  We also remove a `new' dllimport if the old list
1552      contains dllexport:  dllexport always overrides dllimport, regardless
1553      of the order of declaration.  */
1554   if (!VAR_OR_FUNCTION_DECL_P (new_tree))
1555     delete_dllimport_p = 0;
1556   else if (DECL_DLLIMPORT_P (new_tree)
1557      	   && lookup_attribute ("dllexport", DECL_ATTRIBUTES (old)))
1558     {
1559       DECL_DLLIMPORT_P (new_tree) = 0;
1560       warning (OPT_Wattributes, "%q+D already declared with dllexport "
1561 	       "attribute: dllimport ignored", new_tree);
1562     }
1563   else if (DECL_DLLIMPORT_P (old) && !DECL_DLLIMPORT_P (new_tree))
1564     {
1565       /* Warn about overriding a symbol that has already been used, e.g.:
1566 	   extern int __attribute__ ((dllimport)) foo;
1567 	   int* bar () {return &foo;}
1568 	   int foo;
1569       */
1570       if (TREE_USED (old))
1571 	{
1572 	  warning (0, "%q+D redeclared without dllimport attribute "
1573 		   "after being referenced with dll linkage", new_tree);
1574 	  /* If we have used a variable's address with dllimport linkage,
1575 	      keep the old DECL_DLLIMPORT_P flag: the ADDR_EXPR using the
1576 	      decl may already have had TREE_CONSTANT computed.
1577 	      We still remove the attribute so that assembler code refers
1578 	      to '&foo rather than '_imp__foo'.  */
1579 	  if (VAR_P (old) && TREE_ADDRESSABLE (old))
1580 	    DECL_DLLIMPORT_P (new_tree) = 1;
1581 	}
1582 
1583       /* Let an inline definition silently override the external reference,
1584 	 but otherwise warn about attribute inconsistency.  */
1585       else if (VAR_P (new_tree) || !DECL_DECLARED_INLINE_P (new_tree))
1586 	warning (OPT_Wattributes, "%q+D redeclared without dllimport "
1587 		 "attribute: previous dllimport ignored", new_tree);
1588     }
1589   else
1590     delete_dllimport_p = 0;
1591 
1592   a = merge_attributes (DECL_ATTRIBUTES (old), DECL_ATTRIBUTES (new_tree));
1593 
1594   if (delete_dllimport_p)
1595     a = remove_attribute ("dllimport", a);
1596 
1597   return a;
1598 }
1599 
1600 /* Handle a "dllimport" or "dllexport" attribute; arguments as in
1601    struct attribute_spec.handler.  */
1602 
1603 tree
handle_dll_attribute(tree * pnode,tree name,tree args,int flags,bool * no_add_attrs)1604 handle_dll_attribute (tree * pnode, tree name, tree args, int flags,
1605 		      bool *no_add_attrs)
1606 {
1607   tree node = *pnode;
1608   bool is_dllimport;
1609 
1610   /* These attributes may apply to structure and union types being created,
1611      but otherwise should pass to the declaration involved.  */
1612   if (!DECL_P (node))
1613     {
1614       if (flags & ((int) ATTR_FLAG_DECL_NEXT | (int) ATTR_FLAG_FUNCTION_NEXT
1615 		   | (int) ATTR_FLAG_ARRAY_NEXT))
1616 	{
1617 	  *no_add_attrs = true;
1618 	  return tree_cons (name, args, NULL_TREE);
1619 	}
1620       if (TREE_CODE (node) == RECORD_TYPE
1621 	  || TREE_CODE (node) == UNION_TYPE)
1622 	{
1623 	  node = TYPE_NAME (node);
1624 	  if (!node)
1625 	    return NULL_TREE;
1626 	}
1627       else
1628 	{
1629 	  warning (OPT_Wattributes, "%qE attribute ignored",
1630 		   name);
1631 	  *no_add_attrs = true;
1632 	  return NULL_TREE;
1633 	}
1634     }
1635 
1636   if (!VAR_OR_FUNCTION_DECL_P (node) && TREE_CODE (node) != TYPE_DECL)
1637     {
1638       *no_add_attrs = true;
1639       warning (OPT_Wattributes, "%qE attribute ignored",
1640 	       name);
1641       return NULL_TREE;
1642     }
1643 
1644   if (TREE_CODE (node) == TYPE_DECL
1645       && TREE_CODE (TREE_TYPE (node)) != RECORD_TYPE
1646       && TREE_CODE (TREE_TYPE (node)) != UNION_TYPE)
1647     {
1648       *no_add_attrs = true;
1649       warning (OPT_Wattributes, "%qE attribute ignored",
1650 	       name);
1651       return NULL_TREE;
1652     }
1653 
1654   is_dllimport = is_attribute_p ("dllimport", name);
1655 
1656   /* Report error on dllimport ambiguities seen now before they cause
1657      any damage.  */
1658   if (is_dllimport)
1659     {
1660       /* Honor any target-specific overrides.  */
1661       if (!targetm.valid_dllimport_attribute_p (node))
1662 	*no_add_attrs = true;
1663 
1664      else if (TREE_CODE (node) == FUNCTION_DECL
1665 	      && DECL_DECLARED_INLINE_P (node))
1666 	{
1667 	  warning (OPT_Wattributes, "inline function %q+D declared as "
1668 		  "dllimport: attribute ignored", node);
1669 	  *no_add_attrs = true;
1670 	}
1671       /* Like MS, treat definition of dllimported variables and
1672 	 non-inlined functions on declaration as syntax errors.  */
1673      else if (TREE_CODE (node) == FUNCTION_DECL && DECL_INITIAL (node))
1674 	{
1675 	  error ("function %q+D definition is marked dllimport", node);
1676 	  *no_add_attrs = true;
1677 	}
1678 
1679      else if (VAR_P (node))
1680 	{
1681 	  if (DECL_INITIAL (node))
1682 	    {
1683 	      error ("variable %q+D definition is marked dllimport",
1684 		     node);
1685 	      *no_add_attrs = true;
1686 	    }
1687 
1688 	  /* `extern' needn't be specified with dllimport.
1689 	     Specify `extern' now and hope for the best.  Sigh.  */
1690 	  DECL_EXTERNAL (node) = 1;
1691 	  /* Also, implicitly give dllimport'd variables declared within
1692 	     a function global scope, unless declared static.  */
1693 	  if (current_function_decl != NULL_TREE && !TREE_STATIC (node))
1694 	    TREE_PUBLIC (node) = 1;
1695 	  /* Clear TREE_STATIC because DECL_EXTERNAL is set, unless
1696 	     it is a C++ static data member.  */
1697 	  if (DECL_CONTEXT (node) == NULL_TREE
1698 	      || !RECORD_OR_UNION_TYPE_P (DECL_CONTEXT (node)))
1699 	    TREE_STATIC (node) = 0;
1700 	}
1701 
1702       if (*no_add_attrs == false)
1703 	DECL_DLLIMPORT_P (node) = 1;
1704     }
1705   else if (TREE_CODE (node) == FUNCTION_DECL
1706 	   && DECL_DECLARED_INLINE_P (node)
1707 	   && flag_keep_inline_dllexport)
1708     /* An exported function, even if inline, must be emitted.  */
1709     DECL_EXTERNAL (node) = 0;
1710 
1711   /*  Report error if symbol is not accessible at global scope.  */
1712   if (!TREE_PUBLIC (node) && VAR_OR_FUNCTION_DECL_P (node))
1713     {
1714       error ("external linkage required for symbol %q+D because of "
1715 	     "%qE attribute", node, name);
1716       *no_add_attrs = true;
1717     }
1718 
1719   /* A dllexport'd entity must have default visibility so that other
1720      program units (shared libraries or the main executable) can see
1721      it.  A dllimport'd entity must have default visibility so that
1722      the linker knows that undefined references within this program
1723      unit can be resolved by the dynamic linker.  */
1724   if (!*no_add_attrs)
1725     {
1726       if (DECL_VISIBILITY_SPECIFIED (node)
1727 	  && DECL_VISIBILITY (node) != VISIBILITY_DEFAULT)
1728 	error ("%qE implies default visibility, but %qD has already "
1729 	       "been declared with a different visibility",
1730 	       name, node);
1731       DECL_VISIBILITY (node) = VISIBILITY_DEFAULT;
1732       DECL_VISIBILITY_SPECIFIED (node) = 1;
1733     }
1734 
1735   return NULL_TREE;
1736 }
1737 
1738 #endif /* TARGET_DLLIMPORT_DECL_ATTRIBUTES  */
1739 
1740 /* Given two lists of attributes, return true if list l2 is
1741    equivalent to l1.  */
1742 
1743 int
attribute_list_equal(const_tree l1,const_tree l2)1744 attribute_list_equal (const_tree l1, const_tree l2)
1745 {
1746   if (l1 == l2)
1747     return 1;
1748 
1749   return attribute_list_contained (l1, l2)
1750 	 && attribute_list_contained (l2, l1);
1751 }
1752 
1753 /* Given two lists of attributes, return true if list L2 is
1754    completely contained within L1.  */
1755 /* ??? This would be faster if attribute names were stored in a canonicalized
1756    form.  Otherwise, if L1 uses `foo' and L2 uses `__foo__', the long method
1757    must be used to show these elements are equivalent (which they are).  */
1758 /* ??? It's not clear that attributes with arguments will always be handled
1759    correctly.  */
1760 
1761 int
attribute_list_contained(const_tree l1,const_tree l2)1762 attribute_list_contained (const_tree l1, const_tree l2)
1763 {
1764   const_tree t1, t2;
1765 
1766   /* First check the obvious, maybe the lists are identical.  */
1767   if (l1 == l2)
1768     return 1;
1769 
1770   /* Maybe the lists are similar.  */
1771   for (t1 = l1, t2 = l2;
1772        t1 != 0 && t2 != 0
1773        && get_attribute_name (t1) == get_attribute_name (t2)
1774        && TREE_VALUE (t1) == TREE_VALUE (t2);
1775        t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
1776     ;
1777 
1778   /* Maybe the lists are equal.  */
1779   if (t1 == 0 && t2 == 0)
1780     return 1;
1781 
1782   for (; t2 != 0; t2 = TREE_CHAIN (t2))
1783     {
1784       const_tree attr;
1785       /* This CONST_CAST is okay because lookup_attribute does not
1786 	 modify its argument and the return value is assigned to a
1787 	 const_tree.  */
1788       for (attr = lookup_ident_attribute (get_attribute_name (t2),
1789 					  CONST_CAST_TREE (l1));
1790 	   attr != NULL_TREE && !attribute_value_equal (t2, attr);
1791 	   attr = lookup_ident_attribute (get_attribute_name (t2),
1792 					  TREE_CHAIN (attr)))
1793 	;
1794 
1795       if (attr == NULL_TREE)
1796 	return 0;
1797     }
1798 
1799   return 1;
1800 }
1801 
1802 /* The backbone of lookup_attribute().  ATTR_LEN is the string length
1803    of ATTR_NAME, and LIST is not NULL_TREE.
1804 
1805    The function is called from lookup_attribute in order to optimize
1806    for size.  */
1807 
1808 tree
private_lookup_attribute(const char * attr_name,size_t attr_len,tree list)1809 private_lookup_attribute (const char *attr_name, size_t attr_len, tree list)
1810 {
1811   while (list)
1812     {
1813       tree attr = get_attribute_name (list);
1814       size_t ident_len = IDENTIFIER_LENGTH (attr);
1815       if (cmp_attribs (attr_name, attr_len, IDENTIFIER_POINTER (attr),
1816 		       ident_len))
1817 	break;
1818       list = TREE_CHAIN (list);
1819     }
1820 
1821   return list;
1822 }
1823 
1824 /* Return true if the function decl or type NODE has been declared
1825    with attribute ANAME among attributes ATTRS.  */
1826 
1827 static bool
has_attribute(tree node,tree attrs,const char * aname)1828 has_attribute (tree node, tree attrs, const char *aname)
1829 {
1830   if (!strcmp (aname, "const"))
1831     {
1832       if (DECL_P (node) && TREE_READONLY (node))
1833 	return true;
1834     }
1835   else if (!strcmp (aname, "malloc"))
1836     {
1837       if (DECL_P (node) && DECL_IS_MALLOC (node))
1838 	return true;
1839     }
1840   else if (!strcmp (aname, "noreturn"))
1841     {
1842       if (DECL_P (node) && TREE_THIS_VOLATILE (node))
1843 	return true;
1844     }
1845   else if (!strcmp (aname, "nothrow"))
1846     {
1847       if (TREE_NOTHROW (node))
1848 	return true;
1849     }
1850   else if (!strcmp (aname, "pure"))
1851     {
1852       if (DECL_P (node) && DECL_PURE_P (node))
1853 	return true;
1854     }
1855 
1856   return lookup_attribute (aname, attrs);
1857 }
1858 
1859 /* Return the number of mismatched function or type attributes between
1860    the "template" function declaration TMPL and DECL.  The word "template"
1861    doesn't necessarily refer to a C++ template but rather a declaration
1862    whose attributes should be matched by those on DECL.  For a non-zero
1863    return value set *ATTRSTR to a string representation of the list of
1864    mismatched attributes with quoted names.
1865    ATTRLIST is a list of additional attributes that SPEC should be
1866    taken to ultimately be declared with.  */
1867 
1868 unsigned
decls_mismatched_attributes(tree tmpl,tree decl,tree attrlist,const char * const blacklist[],pretty_printer * attrstr)1869 decls_mismatched_attributes (tree tmpl, tree decl, tree attrlist,
1870 			     const char* const blacklist[],
1871 			     pretty_printer *attrstr)
1872 {
1873   if (TREE_CODE (tmpl) != FUNCTION_DECL)
1874     return 0;
1875 
1876   /* Avoid warning if either declaration or its type is deprecated.  */
1877   if (TREE_DEPRECATED (tmpl)
1878       || TREE_DEPRECATED (decl))
1879     return 0;
1880 
1881   const tree tmpls[] = { tmpl, TREE_TYPE (tmpl) };
1882   const tree decls[] = { decl, TREE_TYPE (decl) };
1883 
1884   if (TREE_DEPRECATED (tmpls[1])
1885       || TREE_DEPRECATED (decls[1])
1886       || TREE_DEPRECATED (TREE_TYPE (tmpls[1]))
1887       || TREE_DEPRECATED (TREE_TYPE (decls[1])))
1888     return 0;
1889 
1890   tree tmpl_attrs[] = { DECL_ATTRIBUTES (tmpl), TYPE_ATTRIBUTES (tmpls[1]) };
1891   tree decl_attrs[] = { DECL_ATTRIBUTES (decl), TYPE_ATTRIBUTES (decls[1]) };
1892 
1893   if (!decl_attrs[0])
1894     decl_attrs[0] = attrlist;
1895   else if (!decl_attrs[1])
1896     decl_attrs[1] = attrlist;
1897 
1898   /* Avoid warning if the template has no attributes.  */
1899   if (!tmpl_attrs[0] && !tmpl_attrs[1])
1900     return 0;
1901 
1902   /* Avoid warning if either declaration contains an attribute on
1903      the white list below.  */
1904   const char* const whitelist[] = {
1905     "error", "warning"
1906   };
1907 
1908   for (unsigned i = 0; i != 2; ++i)
1909     for (unsigned j = 0; j != sizeof whitelist / sizeof *whitelist; ++j)
1910       if (lookup_attribute (whitelist[j], tmpl_attrs[i])
1911 	  || lookup_attribute (whitelist[j], decl_attrs[i]))
1912 	return 0;
1913 
1914   /* Put together a list of the black-listed attributes that the template
1915      is declared with and the declaration is not, in case it's not apparent
1916      from the most recent declaration of the template.  */
1917   unsigned nattrs = 0;
1918 
1919   for (unsigned i = 0; blacklist[i]; ++i)
1920     {
1921       /* Attribute leaf only applies to extern functions.  Avoid mentioning
1922 	 it when it's missing from a static declaration.  */
1923       if (!TREE_PUBLIC (decl)
1924 	  && !strcmp ("leaf", blacklist[i]))
1925 	continue;
1926 
1927       for (unsigned j = 0; j != 2; ++j)
1928 	{
1929 	  if (!has_attribute (tmpls[j], tmpl_attrs[j], blacklist[i]))
1930 	    continue;
1931 
1932 	  unsigned kmax = 1 + !!decl_attrs[1];
1933 	  for (unsigned k = 0; k != kmax; ++k)
1934 	    {
1935 	      if (has_attribute (decls[k], decl_attrs[k], blacklist[i]))
1936 		break;
1937 
1938 	      if (!k && kmax > 1)
1939 		continue;
1940 
1941 	      if (nattrs)
1942 		pp_string (attrstr, ", ");
1943 	      pp_begin_quote (attrstr, pp_show_color (global_dc->printer));
1944 	      pp_string (attrstr, blacklist[i]);
1945 	      pp_end_quote (attrstr, pp_show_color (global_dc->printer));
1946 	      ++nattrs;
1947 	    }
1948 	}
1949     }
1950 
1951   return nattrs;
1952 }
1953 
1954 /* Issue a warning for the declaration ALIAS for TARGET where ALIAS
1955    specifies either attributes that are incompatible with those of
1956    TARGET, or attributes that are missing and that declaring ALIAS
1957    with would benefit.  */
1958 
1959 void
maybe_diag_alias_attributes(tree alias,tree target)1960 maybe_diag_alias_attributes (tree alias, tree target)
1961 {
1962   /* Do not expect attributes to match between aliases and ifunc
1963      resolvers.  There is no obvious correspondence between them.  */
1964   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)))
1965     return;
1966 
1967   const char* const blacklist[] = {
1968     "alloc_align", "alloc_size", "cold", "const", "hot", "leaf", "malloc",
1969     "nonnull", "noreturn", "nothrow", "pure", "returns_nonnull",
1970     "returns_twice", NULL
1971   };
1972 
1973   pretty_printer attrnames;
1974   if (warn_attribute_alias > 1)
1975     {
1976       /* With -Wattribute-alias=2 detect alias declarations that are more
1977 	 restrictive than their targets first.  Those indicate potential
1978 	 codegen bugs.  */
1979       if (unsigned n = decls_mismatched_attributes (alias, target, NULL_TREE,
1980 						    blacklist, &attrnames))
1981 	{
1982 	  auto_diagnostic_group d;
1983 	  if (warning_n (DECL_SOURCE_LOCATION (alias),
1984 			 OPT_Wattribute_alias_, n,
1985 			 "%qD specifies more restrictive attribute than "
1986 			 "its target %qD: %s",
1987 			 "%qD specifies more restrictive attributes than "
1988 			 "its target %qD: %s",
1989 			 alias, target, pp_formatted_text (&attrnames)))
1990 	    inform (DECL_SOURCE_LOCATION (target),
1991 		    "%qD target declared here", alias);
1992 	  return;
1993 	}
1994     }
1995 
1996   /* Detect alias declarations that are less restrictive than their
1997      targets.  Those suggest potential optimization opportunities
1998      (solved by adding the missing attribute(s) to the alias).  */
1999   if (unsigned n = decls_mismatched_attributes (target, alias, NULL_TREE,
2000 						blacklist, &attrnames))
2001     {
2002       auto_diagnostic_group d;
2003       if (warning_n (DECL_SOURCE_LOCATION (alias),
2004 		     OPT_Wmissing_attributes, n,
2005 		     "%qD specifies less restrictive attribute than "
2006 		     "its target %qD: %s",
2007 		     "%qD specifies less restrictive attributes than "
2008 		     "its target %qD: %s",
2009 		     alias, target, pp_formatted_text (&attrnames)))
2010 	inform (DECL_SOURCE_LOCATION (target),
2011 		"%qD target declared here", alias);
2012     }
2013 }
2014 
2015 
2016 #if CHECKING_P
2017 
2018 namespace selftest
2019 {
2020 
2021 /* Helper types to verify the consistency attribute exclusions.  */
2022 
2023 typedef std::pair<const char *, const char *> excl_pair;
2024 
2025 struct excl_hash_traits: typed_noop_remove<excl_pair>
2026 {
2027   typedef excl_pair  value_type;
2028   typedef value_type compare_type;
2029 
hashexcl_hash_traits2030   static hashval_t hash (const value_type &x)
2031   {
2032     hashval_t h1 = htab_hash_string (x.first);
2033     hashval_t h2 = htab_hash_string (x.second);
2034     return h1 ^ h2;
2035   }
2036 
equalexcl_hash_traits2037   static bool equal (const value_type &x, const value_type &y)
2038   {
2039     return !strcmp (x.first, y.first) && !strcmp (x.second, y.second);
2040   }
2041 
mark_deletedexcl_hash_traits2042   static void mark_deleted (value_type &x)
2043   {
2044     x = value_type (NULL, NULL);
2045   }
2046 
mark_emptyexcl_hash_traits2047   static void mark_empty (value_type &x)
2048   {
2049     x = value_type ("", "");
2050   }
2051 
is_deletedexcl_hash_traits2052   static bool is_deleted (const value_type &x)
2053   {
2054     return !x.first && !x.second;
2055   }
2056 
is_emptyexcl_hash_traits2057   static bool is_empty (const value_type &x)
2058   {
2059     return !*x.first && !*x.second;
2060   }
2061 };
2062 
2063 
2064 /* Self-test to verify that each attribute exclusion is symmetric,
2065    meaning that if attribute A is encoded as incompatible with
2066    attribute B then the opposite relationship is also encoded.
2067    This test also detects most cases of misspelled attribute names
2068    in exclusions.  */
2069 
2070 static void
test_attribute_exclusions()2071 test_attribute_exclusions ()
2072 {
2073   /* Iterate over the array of attribute tables first (with TI0 as
2074      the index) and over the array of attribute_spec in each table
2075      (with SI0 as the index).  */
2076   const size_t ntables = ARRAY_SIZE (attribute_tables);
2077 
2078   /* Set of pairs of mutually exclusive attributes.  */
2079   typedef hash_set<excl_pair, false, excl_hash_traits> exclusion_set;
2080   exclusion_set excl_set;
2081 
2082   for (size_t ti0 = 0; ti0 != ntables; ++ti0)
2083     for (size_t s0 = 0; attribute_tables[ti0][s0].name; ++s0)
2084       {
2085 	const attribute_spec::exclusions *excl
2086 	  = attribute_tables[ti0][s0].exclude;
2087 
2088 	/* Skip each attribute that doesn't define exclusions.  */
2089 	if (!excl)
2090 	  continue;
2091 
2092 	const char *attr_name = attribute_tables[ti0][s0].name;
2093 
2094 	/* Iterate over the set of exclusions for every attribute
2095 	   (with EI0 as the index) adding the exclusions defined
2096 	   for each to the set.  */
2097 	for (size_t ei0 = 0; excl[ei0].name; ++ei0)
2098 	  {
2099 	    const char *excl_name = excl[ei0].name;
2100 
2101 	    if (!strcmp (attr_name, excl_name))
2102 	      continue;
2103 
2104 	    excl_set.add (excl_pair (attr_name, excl_name));
2105 	  }
2106       }
2107 
2108   /* Traverse the set of mutually exclusive pairs of attributes
2109      and verify that they are symmetric.  */
2110   for (exclusion_set::iterator it = excl_set.begin ();
2111        it != excl_set.end ();
2112        ++it)
2113     {
2114       if (!excl_set.contains (excl_pair ((*it).second, (*it).first)))
2115 	{
2116 	  /* An exclusion for an attribute has been found that
2117 	     doesn't have a corresponding exclusion in the opposite
2118 	     direction.  */
2119 	  char desc[120];
2120 	  sprintf (desc, "'%s' attribute exclusion '%s' must be symmetric",
2121 		   (*it).first, (*it).second);
2122 	  fail (SELFTEST_LOCATION, desc);
2123 	}
2124     }
2125 }
2126 
2127 void
attribute_c_tests()2128 attribute_c_tests ()
2129 {
2130   test_attribute_exclusions ();
2131 }
2132 
2133 } /* namespace selftest */
2134 
2135 #endif /* CHECKING_P */
2136