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