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