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