]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/attribs.cc
libstdc++: Add workaround to std::ranges::subrange [PR111948]
[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 304 const scoped_attribute_specs scoped_specs = {
1dad3df1 305 IDENTIFIER_POINTER (vendor_id), { attrs }
7fa24687
RS
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
df4643f9 1478 as = lookup_attribute_spec (TREE_PURPOSE (a));
314e6352
ML
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
df4643f9 1492 as = lookup_attribute_spec (TREE_PURPOSE (a));
314e6352
ML
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 {
df4643f9 1534 const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attr));
a3317f7b
RS
1535 const_tree end;
1536 if (!predicate (attr, as))
1537 end = attr;
1538 else if (start == attrs)
1539 continue;
1540 else
1541 end = TREE_CHAIN (attr);
1542
1543 for (; start != end; start = TREE_CHAIN (start))
1544 {
1545 *ptr = tree_cons (TREE_PURPOSE (start),
1546 TREE_VALUE (start), NULL_TREE);
1547 TREE_CHAIN (*ptr) = NULL_TREE;
1548 ptr = &TREE_CHAIN (*ptr);
1549 }
1550 start = TREE_CHAIN (attr);
1551 }
1552 gcc_assert (!start || start == attrs);
1553 return start ? attrs : new_attrs;
1554}
1555
1556/* If VALUE is true, return the subset of ATTRS that affect type identity,
1557 otherwise return the subset of ATTRS that don't affect type identity. */
1558
1559tree
1560affects_type_identity_attributes (tree attrs, bool value)
1561{
1562 auto predicate = [value](const_tree, const attribute_spec *as) -> bool
1563 {
1564 return bool (as && as->affects_type_identity) == value;
1565 };
1566 return remove_attributes_matching (attrs, predicate);
1567}
1568
1696fc1e
RS
1569/* Remove attributes that affect type identity from ATTRS unless the
1570 same attributes occur in OK_ATTRS. */
1571
1572tree
1573restrict_type_identity_attributes_to (tree attrs, tree ok_attrs)
1574{
1575 auto predicate = [ok_attrs](const_tree attr,
1576 const attribute_spec *as) -> bool
1577 {
1578 if (!as || !as->affects_type_identity)
1579 return true;
1580
1581 for (tree ok_attr = lookup_attribute (as->name, ok_attrs);
1582 ok_attr;
1583 ok_attr = lookup_attribute (as->name, TREE_CHAIN (ok_attr)))
1584 if (simple_cst_equal (TREE_VALUE (ok_attr), TREE_VALUE (attr)) == 1)
1585 return true;
1586
1587 return false;
1588 };
1589 return remove_attributes_matching (attrs, predicate);
1590}
1591
314e6352
ML
1592/* Return a type like TTYPE except that its TYPE_ATTRIBUTE
1593 is ATTRIBUTE.
1594
1595 Record such modified types already made so we don't make duplicates. */
1596
1597tree
1598build_type_attribute_variant (tree ttype, tree attribute)
1599{
1600 return build_type_attribute_qual_variant (ttype, attribute,
1601 TYPE_QUALS (ttype));
1602}
1603\f
1604/* A variant of lookup_attribute() that can be used with an identifier
1605 as the first argument, and where the identifier can be either
1606 'text' or '__text__'.
1607
1608 Given an attribute ATTR_IDENTIFIER, and a list of attributes LIST,
1609 return a pointer to the attribute's list element if the attribute
1610 is part of the list, or NULL_TREE if not found. If the attribute
1611 appears more than once, this only returns the first occurrence; the
1612 TREE_CHAIN of the return value should be passed back in if further
1613 occurrences are wanted. ATTR_IDENTIFIER must be an identifier but
1614 can be in the form 'text' or '__text__'. */
1615static tree
1616lookup_ident_attribute (tree attr_identifier, tree list)
1617{
1618 gcc_checking_assert (TREE_CODE (attr_identifier) == IDENTIFIER_NODE);
1619
1620 while (list)
1621 {
1622 gcc_checking_assert (TREE_CODE (get_attribute_name (list))
1623 == IDENTIFIER_NODE);
1624
1625 if (cmp_attrib_identifiers (attr_identifier,
1626 get_attribute_name (list)))
1627 /* Found it. */
1628 break;
1629 list = TREE_CHAIN (list);
1630 }
1631
1632 return list;
1633}
1634
1635/* Remove any instances of attribute ATTR_NAME in LIST and return the
1636 modified list. */
1637
1638tree
1639remove_attribute (const char *attr_name, tree list)
1640{
1641 tree *p;
1642 gcc_checking_assert (attr_name[0] != '_');
1643
1644 for (p = &list; *p;)
1645 {
1646 tree l = *p;
1647
1648 tree attr = get_attribute_name (l);
1649 if (is_attribute_p (attr_name, attr))
1650 *p = TREE_CHAIN (l);
1651 else
1652 p = &TREE_CHAIN (l);
1653 }
1654
1655 return list;
1656}
1657
88f04e90
JJ
1658/* Similarly but also match namespace on the removed attributes.
1659 ATTR_NS "" stands for NULL or "gnu" namespace. */
0764dc85
JJ
1660
1661tree
1662remove_attribute (const char *attr_ns, const char *attr_name, tree list)
1663{
1664 tree *p;
1665 gcc_checking_assert (attr_name[0] != '_');
1666 gcc_checking_assert (attr_ns == NULL || attr_ns[0] != '_');
1667
1668 for (p = &list; *p;)
1669 {
1670 tree l = *p;
1671
1672 tree attr = get_attribute_name (l);
88f04e90
JJ
1673 if (is_attribute_p (attr_name, attr)
1674 && is_attribute_namespace_p (attr_ns, l))
0764dc85 1675 {
88f04e90
JJ
1676 *p = TREE_CHAIN (l);
1677 continue;
0764dc85
JJ
1678 }
1679 p = &TREE_CHAIN (l);
1680 }
1681
1682 return list;
1683}
1684
314e6352
ML
1685/* Return an attribute list that is the union of a1 and a2. */
1686
1687tree
1688merge_attributes (tree a1, tree a2)
1689{
1690 tree attributes;
1691
1692 /* Either one unset? Take the set one. */
1693
1694 if ((attributes = a1) == 0)
1695 attributes = a2;
1696
1697 /* One that completely contains the other? Take it. */
1698
1699 else if (a2 != 0 && ! attribute_list_contained (a1, a2))
1700 {
1701 if (attribute_list_contained (a2, a1))
1702 attributes = a2;
1703 else
1704 {
1705 /* Pick the longest list, and hang on the other list. */
1706
1707 if (list_length (a1) < list_length (a2))
1708 attributes = a2, a2 = a1;
1709
1710 for (; a2 != 0; a2 = TREE_CHAIN (a2))
1711 {
1712 tree a;
1713 for (a = lookup_ident_attribute (get_attribute_name (a2),
1714 attributes);
1715 a != NULL_TREE && !attribute_value_equal (a, a2);
1716 a = lookup_ident_attribute (get_attribute_name (a2),
1717 TREE_CHAIN (a)))
1718 ;
1719 if (a == NULL_TREE)
1720 {
1721 a1 = copy_node (a2);
1722 TREE_CHAIN (a1) = attributes;
1723 attributes = a1;
1724 }
1725 }
1726 }
1727 }
1728 return attributes;
1729}
1730
1731/* Given types T1 and T2, merge their attributes and return
1732 the result. */
1733
1734tree
1735merge_type_attributes (tree t1, tree t2)
1736{
1737 return merge_attributes (TYPE_ATTRIBUTES (t1),
1738 TYPE_ATTRIBUTES (t2));
1739}
1740
1741/* Given decls OLDDECL and NEWDECL, merge their attributes and return
1742 the result. */
1743
1744tree
1745merge_decl_attributes (tree olddecl, tree newdecl)
1746{
1747 return merge_attributes (DECL_ATTRIBUTES (olddecl),
1748 DECL_ATTRIBUTES (newdecl));
1749}
1750
bc1a75dd
JJ
1751/* Duplicate all attributes with name NAME in ATTR list to *ATTRS if
1752 they are missing there. */
1753
1754void
1755duplicate_one_attribute (tree *attrs, tree attr, const char *name)
1756{
1757 attr = lookup_attribute (name, attr);
1758 if (!attr)
1759 return;
1760 tree a = lookup_attribute (name, *attrs);
1761 while (attr)
1762 {
1763 tree a2;
1764 for (a2 = a; a2; a2 = lookup_attribute (name, TREE_CHAIN (a2)))
1765 if (attribute_value_equal (attr, a2))
1766 break;
1767 if (!a2)
1768 {
1769 a2 = copy_node (attr);
1770 TREE_CHAIN (a2) = *attrs;
1771 *attrs = a2;
1772 }
1773 attr = lookup_attribute (name, TREE_CHAIN (attr));
1774 }
1775}
1776
1777/* Duplicate all attributes from user DECL to the corresponding
1778 builtin that should be propagated. */
1779
1780void
1781copy_attributes_to_builtin (tree decl)
1782{
1783 tree b = builtin_decl_explicit (DECL_FUNCTION_CODE (decl));
1784 if (b)
1785 duplicate_one_attribute (&DECL_ATTRIBUTES (b),
1786 DECL_ATTRIBUTES (decl), "omp declare simd");
1787}
1788
314e6352
ML
1789#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
1790
1791/* Specialization of merge_decl_attributes for various Windows targets.
1792
1793 This handles the following situation:
1794
1795 __declspec (dllimport) int foo;
1796 int foo;
1797
1798 The second instance of `foo' nullifies the dllimport. */
1799
1800tree
1801merge_dllimport_decl_attributes (tree old, tree new_tree)
1802{
1803 tree a;
1804 int delete_dllimport_p = 1;
1805
1806 /* What we need to do here is remove from `old' dllimport if it doesn't
1807 appear in `new'. dllimport behaves like extern: if a declaration is
1808 marked dllimport and a definition appears later, then the object
1809 is not dllimport'd. We also remove a `new' dllimport if the old list
1810 contains dllexport: dllexport always overrides dllimport, regardless
1811 of the order of declaration. */
1812 if (!VAR_OR_FUNCTION_DECL_P (new_tree))
1813 delete_dllimport_p = 0;
1814 else if (DECL_DLLIMPORT_P (new_tree)
1815 && lookup_attribute ("dllexport", DECL_ATTRIBUTES (old)))
1816 {
1817 DECL_DLLIMPORT_P (new_tree) = 0;
1818 warning (OPT_Wattributes, "%q+D already declared with dllexport "
1819 "attribute: dllimport ignored", new_tree);
1820 }
1821 else if (DECL_DLLIMPORT_P (old) && !DECL_DLLIMPORT_P (new_tree))
1822 {
1823 /* Warn about overriding a symbol that has already been used, e.g.:
1824 extern int __attribute__ ((dllimport)) foo;
1825 int* bar () {return &foo;}
1826 int foo;
1827 */
1828 if (TREE_USED (old))
1829 {
1830 warning (0, "%q+D redeclared without dllimport attribute "
1831 "after being referenced with dll linkage", new_tree);
1832 /* If we have used a variable's address with dllimport linkage,
1833 keep the old DECL_DLLIMPORT_P flag: the ADDR_EXPR using the
1834 decl may already have had TREE_CONSTANT computed.
1835 We still remove the attribute so that assembler code refers
1836 to '&foo rather than '_imp__foo'. */
1837 if (VAR_P (old) && TREE_ADDRESSABLE (old))
1838 DECL_DLLIMPORT_P (new_tree) = 1;
1839 }
1840
1841 /* Let an inline definition silently override the external reference,
1842 but otherwise warn about attribute inconsistency. */
1843 else if (VAR_P (new_tree) || !DECL_DECLARED_INLINE_P (new_tree))
1844 warning (OPT_Wattributes, "%q+D redeclared without dllimport "
1845 "attribute: previous dllimport ignored", new_tree);
1846 }
1847 else
1848 delete_dllimport_p = 0;
1849
1850 a = merge_attributes (DECL_ATTRIBUTES (old), DECL_ATTRIBUTES (new_tree));
1851
1852 if (delete_dllimport_p)
1853 a = remove_attribute ("dllimport", a);
1854
1855 return a;
1856}
1857
1858/* Handle a "dllimport" or "dllexport" attribute; arguments as in
1859 struct attribute_spec.handler. */
1860
1861tree
1862handle_dll_attribute (tree * pnode, tree name, tree args, int flags,
1863 bool *no_add_attrs)
1864{
1865 tree node = *pnode;
1866 bool is_dllimport;
1867
1868 /* These attributes may apply to structure and union types being created,
1869 but otherwise should pass to the declaration involved. */
1870 if (!DECL_P (node))
1871 {
1872 if (flags & ((int) ATTR_FLAG_DECL_NEXT | (int) ATTR_FLAG_FUNCTION_NEXT
1873 | (int) ATTR_FLAG_ARRAY_NEXT))
1874 {
1875 *no_add_attrs = true;
1876 return tree_cons (name, args, NULL_TREE);
1877 }
1878 if (TREE_CODE (node) == RECORD_TYPE
1879 || TREE_CODE (node) == UNION_TYPE)
1880 {
1881 node = TYPE_NAME (node);
1882 if (!node)
1883 return NULL_TREE;
1884 }
1885 else
1886 {
1887 warning (OPT_Wattributes, "%qE attribute ignored",
1888 name);
1889 *no_add_attrs = true;
1890 return NULL_TREE;
1891 }
1892 }
1893
1894 if (!VAR_OR_FUNCTION_DECL_P (node) && TREE_CODE (node) != TYPE_DECL)
1895 {
1896 *no_add_attrs = true;
1897 warning (OPT_Wattributes, "%qE attribute ignored",
1898 name);
1899 return NULL_TREE;
1900 }
1901
1902 if (TREE_CODE (node) == TYPE_DECL
1903 && TREE_CODE (TREE_TYPE (node)) != RECORD_TYPE
1904 && TREE_CODE (TREE_TYPE (node)) != UNION_TYPE)
1905 {
1906 *no_add_attrs = true;
1907 warning (OPT_Wattributes, "%qE attribute ignored",
1908 name);
1909 return NULL_TREE;
1910 }
1911
1912 is_dllimport = is_attribute_p ("dllimport", name);
1913
1914 /* Report error on dllimport ambiguities seen now before they cause
1915 any damage. */
1916 if (is_dllimport)
1917 {
1918 /* Honor any target-specific overrides. */
1919 if (!targetm.valid_dllimport_attribute_p (node))
1920 *no_add_attrs = true;
1921
1922 else if (TREE_CODE (node) == FUNCTION_DECL
1923 && DECL_DECLARED_INLINE_P (node))
1924 {
1925 warning (OPT_Wattributes, "inline function %q+D declared as "
0d7bac69 1926 "dllimport: attribute ignored", node);
314e6352
ML
1927 *no_add_attrs = true;
1928 }
1929 /* Like MS, treat definition of dllimported variables and
1930 non-inlined functions on declaration as syntax errors. */
1931 else if (TREE_CODE (node) == FUNCTION_DECL && DECL_INITIAL (node))
1932 {
1933 error ("function %q+D definition is marked dllimport", node);
1934 *no_add_attrs = true;
1935 }
1936
1937 else if (VAR_P (node))
1938 {
1939 if (DECL_INITIAL (node))
1940 {
1941 error ("variable %q+D definition is marked dllimport",
1942 node);
1943 *no_add_attrs = true;
1944 }
1945
1946 /* `extern' needn't be specified with dllimport.
1947 Specify `extern' now and hope for the best. Sigh. */
1948 DECL_EXTERNAL (node) = 1;
1949 /* Also, implicitly give dllimport'd variables declared within
1950 a function global scope, unless declared static. */
1951 if (current_function_decl != NULL_TREE && !TREE_STATIC (node))
1952 TREE_PUBLIC (node) = 1;
3568d2d5
JJ
1953 /* Clear TREE_STATIC because DECL_EXTERNAL is set, unless
1954 it is a C++ static data member. */
1955 if (DECL_CONTEXT (node) == NULL_TREE
1956 || !RECORD_OR_UNION_TYPE_P (DECL_CONTEXT (node)))
1957 TREE_STATIC (node) = 0;
314e6352
ML
1958 }
1959
1960 if (*no_add_attrs == false)
1961 DECL_DLLIMPORT_P (node) = 1;
1962 }
1963 else if (TREE_CODE (node) == FUNCTION_DECL
1964 && DECL_DECLARED_INLINE_P (node)
1965 && flag_keep_inline_dllexport)
1966 /* An exported function, even if inline, must be emitted. */
1967 DECL_EXTERNAL (node) = 0;
1968
1969 /* Report error if symbol is not accessible at global scope. */
1970 if (!TREE_PUBLIC (node) && VAR_OR_FUNCTION_DECL_P (node))
1971 {
1972 error ("external linkage required for symbol %q+D because of "
1973 "%qE attribute", node, name);
1974 *no_add_attrs = true;
1975 }
1976
1977 /* A dllexport'd entity must have default visibility so that other
1978 program units (shared libraries or the main executable) can see
1979 it. A dllimport'd entity must have default visibility so that
1980 the linker knows that undefined references within this program
1981 unit can be resolved by the dynamic linker. */
1982 if (!*no_add_attrs)
1983 {
1984 if (DECL_VISIBILITY_SPECIFIED (node)
1985 && DECL_VISIBILITY (node) != VISIBILITY_DEFAULT)
1986 error ("%qE implies default visibility, but %qD has already "
1987 "been declared with a different visibility",
1988 name, node);
1989 DECL_VISIBILITY (node) = VISIBILITY_DEFAULT;
1990 DECL_VISIBILITY_SPECIFIED (node) = 1;
1991 }
1992
1993 return NULL_TREE;
1994}
1995
1996#endif /* TARGET_DLLIMPORT_DECL_ATTRIBUTES */
1997
1998/* Given two lists of attributes, return true if list l2 is
1999 equivalent to l1. */
2000
2001int
2002attribute_list_equal (const_tree l1, const_tree l2)
2003{
2004 if (l1 == l2)
2005 return 1;
2006
2007 return attribute_list_contained (l1, l2)
2008 && attribute_list_contained (l2, l1);
2009}
2010
2011/* Given two lists of attributes, return true if list L2 is
2012 completely contained within L1. */
2013/* ??? This would be faster if attribute names were stored in a canonicalized
2014 form. Otherwise, if L1 uses `foo' and L2 uses `__foo__', the long method
2015 must be used to show these elements are equivalent (which they are). */
2016/* ??? It's not clear that attributes with arguments will always be handled
2017 correctly. */
2018
2019int
2020attribute_list_contained (const_tree l1, const_tree l2)
2021{
2022 const_tree t1, t2;
2023
2024 /* First check the obvious, maybe the lists are identical. */
2025 if (l1 == l2)
2026 return 1;
2027
2028 /* Maybe the lists are similar. */
2029 for (t1 = l1, t2 = l2;
2030 t1 != 0 && t2 != 0
2031 && get_attribute_name (t1) == get_attribute_name (t2)
2032 && TREE_VALUE (t1) == TREE_VALUE (t2);
2033 t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
2034 ;
2035
2036 /* Maybe the lists are equal. */
2037 if (t1 == 0 && t2 == 0)
2038 return 1;
2039
2040 for (; t2 != 0; t2 = TREE_CHAIN (t2))
2041 {
2042 const_tree attr;
2043 /* This CONST_CAST is okay because lookup_attribute does not
2044 modify its argument and the return value is assigned to a
2045 const_tree. */
2046 for (attr = lookup_ident_attribute (get_attribute_name (t2),
2047 CONST_CAST_TREE (l1));
2048 attr != NULL_TREE && !attribute_value_equal (t2, attr);
2049 attr = lookup_ident_attribute (get_attribute_name (t2),
2050 TREE_CHAIN (attr)))
2051 ;
2052
2053 if (attr == NULL_TREE)
2054 return 0;
2055 }
2056
2057 return 1;
2058}
13bdca74
ML
2059
2060/* The backbone of lookup_attribute(). ATTR_LEN is the string length
2061 of ATTR_NAME, and LIST is not NULL_TREE.
2062
2063 The function is called from lookup_attribute in order to optimize
2064 for size. */
2065
2066tree
2067private_lookup_attribute (const char *attr_name, size_t attr_len, tree list)
2068{
2069 while (list)
2070 {
2071 tree attr = get_attribute_name (list);
2072 size_t ident_len = IDENTIFIER_LENGTH (attr);
2073 if (cmp_attribs (attr_name, attr_len, IDENTIFIER_POINTER (attr),
2074 ident_len))
2075 break;
2076 list = TREE_CHAIN (list);
2077 }
2078
2079 return list;
2080}
5d9ae53d 2081
0764dc85
JJ
2082/* Similarly but with also attribute namespace. */
2083
2084tree
2085private_lookup_attribute (const char *attr_ns, const char *attr_name,
2086 size_t attr_ns_len, size_t attr_len, tree list)
2087{
2088 while (list)
2089 {
2090 tree attr = get_attribute_name (list);
2091 size_t ident_len = IDENTIFIER_LENGTH (attr);
2092 if (cmp_attribs (attr_name, attr_len, IDENTIFIER_POINTER (attr),
2093 ident_len))
2094 {
2095 tree ns = get_attribute_namespace (list);
2096 if (ns == NULL_TREE)
2097 {
88f04e90 2098 if (attr_ns_len == 0)
0764dc85
JJ
2099 break;
2100 }
2101 else if (attr_ns)
2102 {
2103 ident_len = IDENTIFIER_LENGTH (ns);
88f04e90
JJ
2104 if (attr_ns_len == 0)
2105 {
2106 if (cmp_attribs ("gnu", strlen ("gnu"),
2107 IDENTIFIER_POINTER (ns), ident_len))
2108 break;
2109 }
2110 else if (cmp_attribs (attr_ns, attr_ns_len,
2111 IDENTIFIER_POINTER (ns), ident_len))
0764dc85
JJ
2112 break;
2113 }
2114 }
2115 list = TREE_CHAIN (list);
2116 }
2117
2118 return list;
2119}
2120
79a2c428
MS
2121/* Return true if the function decl or type NODE has been declared
2122 with attribute ANAME among attributes ATTRS. */
2123
2124static bool
2125has_attribute (tree node, tree attrs, const char *aname)
2126{
2127 if (!strcmp (aname, "const"))
2128 {
2129 if (DECL_P (node) && TREE_READONLY (node))
2130 return true;
2131 }
2132 else if (!strcmp (aname, "malloc"))
2133 {
2134 if (DECL_P (node) && DECL_IS_MALLOC (node))
2135 return true;
2136 }
2137 else if (!strcmp (aname, "noreturn"))
2138 {
2139 if (DECL_P (node) && TREE_THIS_VOLATILE (node))
2140 return true;
2141 }
2142 else if (!strcmp (aname, "nothrow"))
2143 {
2144 if (TREE_NOTHROW (node))
2145 return true;
2146 }
2147 else if (!strcmp (aname, "pure"))
2148 {
2149 if (DECL_P (node) && DECL_PURE_P (node))
2150 return true;
2151 }
2152
2153 return lookup_attribute (aname, attrs);
2154}
2155
2156/* Return the number of mismatched function or type attributes between
2157 the "template" function declaration TMPL and DECL. The word "template"
2158 doesn't necessarily refer to a C++ template but rather a declaration
2159 whose attributes should be matched by those on DECL. For a non-zero
2160 return value set *ATTRSTR to a string representation of the list of
2161 mismatched attributes with quoted names.
2162 ATTRLIST is a list of additional attributes that SPEC should be
2163 taken to ultimately be declared with. */
2164
2165unsigned
2166decls_mismatched_attributes (tree tmpl, tree decl, tree attrlist,
2167 const char* const blacklist[],
2168 pretty_printer *attrstr)
2169{
2170 if (TREE_CODE (tmpl) != FUNCTION_DECL)
2171 return 0;
2172
2173 /* Avoid warning if either declaration or its type is deprecated. */
2174 if (TREE_DEPRECATED (tmpl)
2175 || TREE_DEPRECATED (decl))
2176 return 0;
2177
2178 const tree tmpls[] = { tmpl, TREE_TYPE (tmpl) };
2179 const tree decls[] = { decl, TREE_TYPE (decl) };
2180
2181 if (TREE_DEPRECATED (tmpls[1])
2182 || TREE_DEPRECATED (decls[1])
2183 || TREE_DEPRECATED (TREE_TYPE (tmpls[1]))
2184 || TREE_DEPRECATED (TREE_TYPE (decls[1])))
2185 return 0;
2186
2187 tree tmpl_attrs[] = { DECL_ATTRIBUTES (tmpl), TYPE_ATTRIBUTES (tmpls[1]) };
2188 tree decl_attrs[] = { DECL_ATTRIBUTES (decl), TYPE_ATTRIBUTES (decls[1]) };
2189
2190 if (!decl_attrs[0])
2191 decl_attrs[0] = attrlist;
2192 else if (!decl_attrs[1])
2193 decl_attrs[1] = attrlist;
2194
2195 /* Avoid warning if the template has no attributes. */
2196 if (!tmpl_attrs[0] && !tmpl_attrs[1])
2197 return 0;
2198
2199 /* Avoid warning if either declaration contains an attribute on
2200 the white list below. */
2201 const char* const whitelist[] = {
2202 "error", "warning"
2203 };
2204
2205 for (unsigned i = 0; i != 2; ++i)
ca32b29e 2206 for (unsigned j = 0; j != ARRAY_SIZE (whitelist); ++j)
79a2c428
MS
2207 if (lookup_attribute (whitelist[j], tmpl_attrs[i])
2208 || lookup_attribute (whitelist[j], decl_attrs[i]))
2209 return 0;
2210
2211 /* Put together a list of the black-listed attributes that the template
2212 is declared with and the declaration is not, in case it's not apparent
2213 from the most recent declaration of the template. */
2214 unsigned nattrs = 0;
2215
2216 for (unsigned i = 0; blacklist[i]; ++i)
2217 {
29d24852
MS
2218 /* Attribute leaf only applies to extern functions. Avoid mentioning
2219 it when it's missing from a static declaration. */
2220 if (!TREE_PUBLIC (decl)
2221 && !strcmp ("leaf", blacklist[i]))
2222 continue;
2223
79a2c428
MS
2224 for (unsigned j = 0; j != 2; ++j)
2225 {
2226 if (!has_attribute (tmpls[j], tmpl_attrs[j], blacklist[i]))
2227 continue;
2228
dea78431 2229 bool found = false;
79a2c428
MS
2230 unsigned kmax = 1 + !!decl_attrs[1];
2231 for (unsigned k = 0; k != kmax; ++k)
2232 {
2233 if (has_attribute (decls[k], decl_attrs[k], blacklist[i]))
dea78431
AO
2234 {
2235 found = true;
2236 break;
2237 }
2238 }
79a2c428 2239
dea78431
AO
2240 if (!found)
2241 {
79a2c428
MS
2242 if (nattrs)
2243 pp_string (attrstr, ", ");
2244 pp_begin_quote (attrstr, pp_show_color (global_dc->printer));
2245 pp_string (attrstr, blacklist[i]);
2246 pp_end_quote (attrstr, pp_show_color (global_dc->printer));
2247 ++nattrs;
2248 }
dea78431
AO
2249
2250 break;
79a2c428
MS
2251 }
2252 }
2253
2254 return nattrs;
2255}
2256
2257/* Issue a warning for the declaration ALIAS for TARGET where ALIAS
2258 specifies either attributes that are incompatible with those of
2259 TARGET, or attributes that are missing and that declaring ALIAS
2260 with would benefit. */
2261
2262void
2263maybe_diag_alias_attributes (tree alias, tree target)
2264{
2265 /* Do not expect attributes to match between aliases and ifunc
2266 resolvers. There is no obvious correspondence between them. */
2267 if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)))
2268 return;
2269
2270 const char* const blacklist[] = {
2271 "alloc_align", "alloc_size", "cold", "const", "hot", "leaf", "malloc",
2272 "nonnull", "noreturn", "nothrow", "pure", "returns_nonnull",
2273 "returns_twice", NULL
2274 };
2275
2276 pretty_printer attrnames;
2277 if (warn_attribute_alias > 1)
2278 {
2279 /* With -Wattribute-alias=2 detect alias declarations that are more
2280 restrictive than their targets first. Those indicate potential
2281 codegen bugs. */
2282 if (unsigned n = decls_mismatched_attributes (alias, target, NULL_TREE,
2283 blacklist, &attrnames))
2284 {
2285 auto_diagnostic_group d;
2286 if (warning_n (DECL_SOURCE_LOCATION (alias),
2287 OPT_Wattribute_alias_, n,
2288 "%qD specifies more restrictive attribute than "
2289 "its target %qD: %s",
2290 "%qD specifies more restrictive attributes than "
2291 "its target %qD: %s",
2292 alias, target, pp_formatted_text (&attrnames)))
2293 inform (DECL_SOURCE_LOCATION (target),
2294 "%qD target declared here", alias);
2295 return;
2296 }
2297 }
2298
2299 /* Detect alias declarations that are less restrictive than their
2300 targets. Those suggest potential optimization opportunities
2301 (solved by adding the missing attribute(s) to the alias). */
2302 if (unsigned n = decls_mismatched_attributes (target, alias, NULL_TREE,
2303 blacklist, &attrnames))
2304 {
2305 auto_diagnostic_group d;
2306 if (warning_n (DECL_SOURCE_LOCATION (alias),
2307 OPT_Wmissing_attributes, n,
2308 "%qD specifies less restrictive attribute than "
2309 "its target %qD: %s",
2310 "%qD specifies less restrictive attributes than "
2311 "its target %qD: %s",
2312 alias, target, pp_formatted_text (&attrnames)))
2313 inform (DECL_SOURCE_LOCATION (target),
2314 "%qD target declared here", alias);
2315 }
2316}
2317
6450f073
MS
2318/* Initialize a mapping RWM for a call to a function declared with
2319 attribute access in ATTRS. Each attribute positional operand
2320 inserts one entry into the mapping with the operand number as
2321 the key. */
b825a228
MS
2322
2323void
6450f073 2324init_attr_rdwr_indices (rdwr_map *rwm, tree attrs)
b825a228 2325{
6450f073 2326 if (!attrs)
b825a228
MS
2327 return;
2328
6450f073 2329 for (tree access = attrs;
b825a228
MS
2330 (access = lookup_attribute ("access", access));
2331 access = TREE_CHAIN (access))
2332 {
2333 /* The TREE_VALUE of an attribute is a TREE_LIST whose TREE_VALUE
2334 is the attribute argument's value. */
2335 tree mode = TREE_VALUE (access);
6450f073
MS
2336 if (!mode)
2337 return;
2338
2339 /* The (optional) list of VLA bounds. */
2340 tree vblist = TREE_CHAIN (mode);
b825a228 2341 mode = TREE_VALUE (mode);
6450f073
MS
2342 if (TREE_CODE (mode) != STRING_CST)
2343 continue;
b825a228
MS
2344 gcc_assert (TREE_CODE (mode) == STRING_CST);
2345
c6503fa9
MS
2346 if (vblist)
2347 vblist = nreverse (copy_list (TREE_VALUE (vblist)));
2348
6450f073 2349 for (const char *m = TREE_STRING_POINTER (mode); *m; )
b825a228
MS
2350 {
2351 attr_access acc = { };
2352
6450f073
MS
2353 /* Skip the internal-only plus sign. */
2354 if (*m == '+')
2355 ++m;
2356
2357 acc.str = m;
2358 acc.mode = acc.from_mode_char (*m);
2359 acc.sizarg = UINT_MAX;
2360
2361 const char *end;
2362 acc.ptrarg = strtoul (++m, const_cast<char**>(&end), 10);
2363 m = end;
2364
2365 if (*m == '[')
b825a228 2366 {
6450f073
MS
2367 /* Forms containing the square bracket are internal-only
2368 (not specified by an attribute declaration), and used
2369 for various forms of array and VLA parameters. */
2370 acc.internal_p = true;
2371
2372 /* Search to the closing bracket and look at the preceding
2373 code: it determines the form of the most significant
2374 bound of the array. Others prior to it encode the form
2375 of interior VLA bounds. They're not of interest here. */
2376 end = strchr (m, ']');
2377 const char *p = end;
2378 gcc_assert (p);
2379
2380 while (ISDIGIT (p[-1]))
2381 --p;
2382
2383 if (ISDIGIT (*p))
2384 {
2385 /* A digit denotes a constant bound (as in T[3]). */
2386 acc.static_p = p[-1] == 's';
2387 acc.minsize = strtoull (p, NULL, 10);
2388 }
2389 else if (' ' == p[-1])
2390 {
2391 /* A space denotes an ordinary array of unspecified bound
2392 (as in T[]). */
2393 acc.minsize = 0;
2394 }
2395 else if ('*' == p[-1] || '$' == p[-1])
2396 {
2397 /* An asterisk denotes a VLA. When the closing bracket
2398 is followed by a comma and a dollar sign its bound is
2399 on the list. Otherwise it's a VLA with an unspecified
2400 bound. */
757ba665 2401 acc.static_p = p[-2] == 's';
6450f073
MS
2402 acc.minsize = HOST_WIDE_INT_M1U;
2403 }
2404
2405 m = end + 1;
b825a228
MS
2406 }
2407
b825a228
MS
2408 if (*m == ',')
2409 {
6450f073
MS
2410 ++m;
2411 do
2412 {
2413 if (*m == '$')
2414 {
2415 ++m;
3599ecb6 2416 if (!acc.size && vblist)
6450f073
MS
2417 {
2418 /* Extract the list of VLA bounds for the current
2419 parameter, store it in ACC.SIZE, and advance
2420 to the list of bounds for the next VLA parameter.
2421 */
2422 acc.size = TREE_VALUE (vblist);
2423 vblist = TREE_CHAIN (vblist);
2424 }
2425 }
2426
2427 if (ISDIGIT (*m))
2428 {
2429 /* Extract the positional argument. It's absent
2430 for VLAs whose bound doesn't name a function
2431 parameter. */
2432 unsigned pos = strtoul (m, const_cast<char**>(&end), 10);
2433 if (acc.sizarg == UINT_MAX)
2434 acc.sizarg = pos;
2435 m = end;
2436 }
2437 }
2438 while (*m == '$');
2439 }
2440
2441 acc.end = m;
2442
2443 bool existing;
2444 auto &ref = rwm->get_or_insert (acc.ptrarg, &existing);
2445 if (existing)
2446 {
2447 /* Merge the new spec with the existing. */
2448 if (acc.minsize == HOST_WIDE_INT_M1U)
2449 ref.minsize = HOST_WIDE_INT_M1U;
2450
2451 if (acc.sizarg != UINT_MAX)
2452 ref.sizarg = acc.sizarg;
2453
2454 if (acc.mode)
2455 ref.mode = acc.mode;
b825a228
MS
2456 }
2457 else
6450f073 2458 ref = acc;
b825a228
MS
2459
2460 /* Unconditionally add an entry for the required pointer
2461 operand of the attribute, and one for the optional size
2462 operand when it's specified. */
b825a228
MS
2463 if (acc.sizarg != UINT_MAX)
2464 rwm->put (acc.sizarg, acc);
2465 }
2466 }
2467}
2468
6450f073
MS
2469/* Return the access specification for a function parameter PARM
2470 or null if the current function has no such specification. */
2471
2472attr_access *
2473get_parm_access (rdwr_map &rdwr_idx, tree parm,
2474 tree fndecl /* = current_function_decl */)
2475{
2476 tree fntype = TREE_TYPE (fndecl);
2477 init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
2478
2479 if (rdwr_idx.is_empty ())
2480 return NULL;
2481
2482 unsigned argpos = 0;
2483 tree fnargs = DECL_ARGUMENTS (fndecl);
2484 for (tree arg = fnargs; arg; arg = TREE_CHAIN (arg), ++argpos)
2485 if (arg == parm)
2486 return rdwr_idx.get (argpos);
2487
2488 return NULL;
2489}
2490
2491/* Return the internal representation as STRING_CST. Internal positional
2492 arguments are zero-based. */
2493
2494tree
2495attr_access::to_internal_string () const
2496{
2497 return build_string (end - str, str);
2498}
2499
2500/* Return the human-readable representation of the external attribute
2501 specification (as it might appear in the source code) as STRING_CST.
2502 External positional arguments are one-based. */
2503
2504tree
2505attr_access::to_external_string () const
2506{
2507 char buf[80];
2508 gcc_assert (mode != access_deferred);
2509 int len = snprintf (buf, sizeof buf, "access (%s, %u",
2510 mode_names[mode], ptrarg + 1);
2511 if (sizarg != UINT_MAX)
2512 len += snprintf (buf + len, sizeof buf - len, ", %u", sizarg + 1);
2513 strcpy (buf + len, ")");
2514 return build_string (len + 2, buf);
2515}
2516
2517/* Return the number of specified VLA bounds and set *nunspec to
2518 the number of unspecified ones (those designated by [*]). */
2519
2520unsigned
2521attr_access::vla_bounds (unsigned *nunspec) const
2522{
c6503fa9 2523 unsigned nbounds = 0;
6450f073 2524 *nunspec = 0;
c6503fa9
MS
2525 /* STR points to the beginning of the specified string for the current
2526 argument that may be followed by the string for the next argument. */
2527 for (const char* p = strchr (str, ']'); p && *p != '['; --p)
2528 {
2529 if (*p == '*')
2530 ++*nunspec;
2531 else if (*p == '$')
2532 ++nbounds;
2533 }
2534 return nbounds;
6450f073
MS
2535}
2536
0718336a
MS
2537/* Reset front end-specific attribute access data from ATTRS.
2538 Called from the free_lang_data pass. */
2539
2540/* static */ void
2541attr_access::free_lang_data (tree attrs)
2542{
2543 for (tree acs = attrs; (acs = lookup_attribute ("access", acs));
2544 acs = TREE_CHAIN (acs))
2545 {
2546 tree vblist = TREE_VALUE (acs);
2547 vblist = TREE_CHAIN (vblist);
2548 if (!vblist)
2549 continue;
2550
0718336a
MS
2551 for (vblist = TREE_VALUE (vblist); vblist; vblist = TREE_CHAIN (vblist))
2552 {
2553 tree *pvbnd = &TREE_VALUE (vblist);
2554 if (!*pvbnd || DECL_P (*pvbnd))
2555 continue;
2556
2557 /* VLA bounds that are expressions as opposed to DECLs are
2558 only used in the front end. Reset them to keep front end
2559 trees leaking into the middle end (see pr97172) and to
2560 free up memory. */
2561 *pvbnd = NULL_TREE;
2562 }
2563 }
ea5a82df
MS
2564
2565 for (tree argspec = attrs; (argspec = lookup_attribute ("arg spec", argspec));
2566 argspec = TREE_CHAIN (argspec))
2567 {
2568 /* Same as above. */
2569 tree *pvblist = &TREE_VALUE (argspec);
2570 *pvblist = NULL_TREE;
2571 }
0718336a 2572}
6450f073
MS
2573
2574/* Defined in attr_access. */
2575constexpr char attr_access::mode_chars[];
2576constexpr char attr_access::mode_names[][11];
2577
2578/* Format an array, including a VLA, pointed to by TYPE and used as
2579 a function parameter as a human-readable string. ACC describes
2580 an access to the parameter and is used to determine the outermost
2581 form of the array including its bound which is otherwise obviated
2582 by its decay to pointer. Return the formatted string. */
2583
2584std::string
2585attr_access::array_as_string (tree type) const
2586{
2587 std::string typstr;
2588
2589 if (type == error_mark_node)
2590 return std::string ();
2591
2592 if (this->str)
2593 {
e808f3fd
MS
2594 /* For array parameters (but not pointers) create a temporary array
2595 type that corresponds to the form of the parameter including its
6450f073
MS
2596 qualifiers even though they apply to the pointer, not the array
2597 type. */
2598 const bool vla_p = minsize == HOST_WIDE_INT_M1U;
2599 tree eltype = TREE_TYPE (type);
6450f073 2600 tree index_type = NULL_TREE;
e808f3fd 2601
6450f073
MS
2602 if (minsize == HOST_WIDE_INT_M1U)
2603 {
2604 /* Determine if this is a VLA (an array whose most significant
2605 bound is nonconstant and whose access string has "$]" in it)
2606 extract the bound expression from SIZE. */
2607 const char *p = end;
7dbc7ad5 2608 for ( ; p != str && *p-- != ']'; );
6450f073 2609 if (*p == '$')
2c8bffa1
MS
2610 /* SIZE may have been cleared. Use it with care. */
2611 index_type = build_index_type (size ? TREE_VALUE (size) : size);
6450f073 2612 }
7dbc7ad5 2613 else if (minsize)
6450f073
MS
2614 index_type = build_index_type (size_int (minsize - 1));
2615
e808f3fd 2616 tree arat = NULL_TREE;
6450f073
MS
2617 if (static_p || vla_p)
2618 {
2619 tree flag = static_p ? integer_one_node : NULL_TREE;
2620 /* Hack: there's no language-independent way to encode
2621 the "static" specifier or the "*" notation in an array type.
e808f3fd
MS
2622 Add a "fake" attribute to have the pretty-printer add "static"
2623 or "*". The "[static N]" notation is only valid in the most
2624 significant bound but [*] can be used for any bound. Because
2625 [*] is represented the same as [0] this hack only works for
2626 the most significant bound like static and the others are
2627 rendered as [0]. */
2628 arat = build_tree_list (get_identifier ("array"), flag);
6450f073
MS
2629 }
2630
e808f3fd
MS
2631 const int quals = TYPE_QUALS (type);
2632 type = build_array_type (eltype, index_type);
2633 type = build_type_attribute_qual_variant (type, arat, quals);
6450f073
MS
2634 }
2635
2636 /* Format the type using the current pretty printer. The generic tree
2637 printer does a terrible job. */
2638 pretty_printer *pp = global_dc->printer->clone ();
2639 pp_printf (pp, "%qT", type);
2640 typstr = pp_formatted_text (pp);
2641 delete pp;
2642
6450f073
MS
2643 return typstr;
2644}
79a2c428 2645
5d9ae53d
MS
2646#if CHECKING_P
2647
2648namespace selftest
2649{
2650
5d9ae53d
MS
2651/* Self-test to verify that each attribute exclusion is symmetric,
2652 meaning that if attribute A is encoded as incompatible with
2653 attribute B then the opposite relationship is also encoded.
2654 This test also detects most cases of misspelled attribute names
2655 in exclusions. */
2656
2657static void
2658test_attribute_exclusions ()
2659{
5b33cf3a
RS
2660 using excl_hash_traits = pair_hash<nofree_string_hash, nofree_string_hash>;
2661
5d9ae53d
MS
2662 /* Iterate over the array of attribute tables first (with TI0 as
2663 the index) and over the array of attribute_spec in each table
2664 (with SI0 as the index). */
7fa24687 2665 hash_set<excl_hash_traits> excl_set;
5d9ae53d 2666
7fa24687
RS
2667 for (auto scoped_array : attribute_tables)
2668 for (auto scoped_attributes : scoped_array)
2669 for (const attribute_spec &attribute : scoped_attributes->attributes)
2670 {
2671 const attribute_spec::exclusions *excl = attribute.exclude;
5d9ae53d 2672
7fa24687
RS
2673 /* Skip each attribute that doesn't define exclusions. */
2674 if (!excl)
2675 continue;
5d9ae53d 2676
7fa24687
RS
2677 /* Skip standard (non-GNU) attributes, since currently the
2678 exclusions are implicitly for GNU attributes only.
2679 Also, C++ likely and unlikely get rewritten to gnu::hot
2680 and gnu::cold, so symmetry isn't necessary there. */
2681 if (!scoped_attributes->ns)
2682 continue;
5d9ae53d 2683
7fa24687 2684 const char *attr_name = attribute.name;
5d9ae53d 2685
7fa24687
RS
2686 /* Iterate over the set of exclusions for every attribute
2687 (with EI0 as the index) adding the exclusions defined
2688 for each to the set. */
2689 for (size_t ei0 = 0; excl[ei0].name; ++ei0)
2690 {
2691 const char *excl_name = excl[ei0].name;
5d9ae53d 2692
7fa24687
RS
2693 if (!strcmp (attr_name, excl_name))
2694 continue;
5d9ae53d 2695
7fa24687
RS
2696 excl_set.add ({ attr_name, excl_name });
2697 }
2698 }
5d9ae53d
MS
2699
2700 /* Traverse the set of mutually exclusive pairs of attributes
2701 and verify that they are symmetric. */
7fa24687
RS
2702 for (auto excl_pair : excl_set)
2703 if (!excl_set.contains ({ excl_pair.second, excl_pair.first }))
2704 {
2705 /* An exclusion for an attribute has been found that
2706 doesn't have a corresponding exclusion in the opposite
2707 direction. */
2708 char desc[120];
2709 sprintf (desc, "'%s' attribute exclusion '%s' must be symmetric",
2710 excl_pair.first, excl_pair.second);
2711 fail (SELFTEST_LOCATION, desc);
2712 }
5d9ae53d
MS
2713}
2714
2715void
d5148d4f 2716attribs_cc_tests ()
5d9ae53d
MS
2717{
2718 test_attribute_exclusions ();
2719}
2720
2721} /* namespace selftest */
2722
2723#endif /* CHECKING_P */
3956f514
RS
2724
2725#include "gt-attribs.h"