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