]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/attribs.cc
ada: Improve attribute exclusion handling
[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"
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
ab442df7 678 && targetm.target_option.valid_attribute_p (*node, NULL_TREE,
5779e713 679 current_target_pragma, 0))
ab442df7 680 {
5779e713
MM
681 tree cur_attr = lookup_attribute ("target", attributes);
682 tree opts = copy_list (current_target_pragma);
ab442df7
MM
683
684 if (! cur_attr)
5779e713 685 attributes = tree_cons (get_identifier ("target"), opts, attributes);
ab442df7
MM
686 else
687 TREE_VALUE (cur_attr) = chainon (opts, TREE_VALUE (cur_attr));
688 }
689
61044492
JZ
690 /* A "naked" function attribute implies "noinline" and "noclone" for
691 those targets that support it. */
692 if (TREE_CODE (*node) == FUNCTION_DECL
70e41a6a 693 && attributes
036ea399 694 && lookup_attribute ("naked", attributes) != NULL
49984049
ML
695 && lookup_attribute_spec (get_identifier ("naked"))
696 && lookup_attribute ("noipa", attributes) == NULL)
697 attributes = tree_cons (get_identifier ("noipa"), NULL, attributes);
61044492 698
036ea399
JJ
699 /* A "noipa" function attribute implies "noinline", "noclone" and "no_icf"
700 for those targets that support it. */
701 if (TREE_CODE (*node) == FUNCTION_DECL
702 && attributes
703 && lookup_attribute ("noipa", attributes) != NULL
704 && lookup_attribute_spec (get_identifier ("noipa")))
705 {
706 if (lookup_attribute ("noinline", attributes) == NULL)
707 attributes = tree_cons (get_identifier ("noinline"), NULL, attributes);
708
709 if (lookup_attribute ("noclone", attributes) == NULL)
710 attributes = tree_cons (get_identifier ("noclone"), NULL, attributes);
711
712 if (lookup_attribute ("no_icf", attributes) == NULL)
713 attributes = tree_cons (get_identifier ("no_icf"), NULL, attributes);
714 }
715
5fd9b178 716 targetm.insert_attributes (*node, &attributes);
bb9f8221 717
5d9ae53d
MS
718 /* Note that attributes on the same declaration are not necessarily
719 in the same order as in the source. */
1bf32c11 720 for (tree attr = attributes; attr; attr = TREE_CHAIN (attr))
bb9f8221 721 {
1bf32c11
MP
722 tree ns = get_attribute_namespace (attr);
723 tree name = get_attribute_name (attr);
724 tree args = TREE_VALUE (attr);
bb9f8221 725 tree *anode = node;
4849deb1
JJ
726 const struct attribute_spec *spec
727 = lookup_scoped_attribute_spec (ns, name);
f9ceed32 728 int fn_ptr_quals = 0;
3acef2ae 729 tree fn_ptr_tmp = NULL_TREE;
1bf32c11 730 const bool cxx11_attr_p = cxx11_attribute_p (attr);
bb9f8221
RK
731
732 if (spec == NULL)
733 {
a1ad0d84
MP
734 if (!(flags & (int) ATTR_FLAG_BUILT_IN)
735 && !attr_namespace_ignored_p (ns))
e28d52cf 736 {
1bf32c11 737 if (ns == NULL_TREE || !cxx11_attr_p)
e28d52cf
DS
738 warning (OPT_Wattributes, "%qE attribute directive ignored",
739 name);
04b2fb5b
JJ
740 else if ((flag_openmp || flag_openmp_simd)
741 && is_attribute_p ("omp", ns)
742 && is_attribute_p ("directive", name)
743 && (VAR_P (*node)
744 || TREE_CODE (*node) == FUNCTION_DECL))
745 continue;
e28d52cf
DS
746 else
747 warning (OPT_Wattributes,
748 "%<%E::%E%> scoped attribute directive ignored",
749 ns, name);
750 }
bb9f8221
RK
751 continue;
752 }
54aa6b58 753 else
bb9f8221 754 {
54aa6b58
MS
755 int nargs = list_length (args);
756 if (nargs < spec->min_length
757 || (spec->max_length >= 0
758 && nargs > spec->max_length))
759 {
ade1e0d5 760 auto_diagnostic_group d;
54aa6b58
MS
761 error ("wrong number of arguments specified for %qE attribute",
762 name);
763 if (spec->max_length < 0)
764 inform (input_location, "expected %i or more, found %i",
765 spec->min_length, nargs);
2ec6489d
JJ
766 else if (spec->min_length == spec->max_length)
767 inform (input_location, "expected %i, found %i",
768 spec->min_length, nargs);
54aa6b58
MS
769 else
770 inform (input_location, "expected between %i and %i, found %i",
771 spec->min_length, spec->max_length, nargs);
772 continue;
773 }
bb9f8221 774 }
23b43207 775 gcc_assert (is_attribute_p (spec->name, name));
bb9f8221
RK
776
777 if (spec->decl_required && !DECL_P (*anode))
778 {
779 if (flags & ((int) ATTR_FLAG_DECL_NEXT
780 | (int) ATTR_FLAG_FUNCTION_NEXT
781 | (int) ATTR_FLAG_ARRAY_NEXT))
782 {
783 /* Pass on this attribute to be tried again. */
5d9ae53d
MS
784 tree attr = tree_cons (name, args, NULL_TREE);
785 returned_attrs = chainon (returned_attrs, attr);
bb9f8221
RK
786 continue;
787 }
788 else
789 {
4f1e4960
JM
790 warning (OPT_Wattributes, "%qE attribute does not apply to types",
791 name);
bb9f8221
RK
792 continue;
793 }
794 }
795
dd4dc3cd
RK
796 /* If we require a type, but were passed a decl, set up to make a
797 new type and update the one in the decl. ATTR_FLAG_TYPE_IN_PLACE
798 would have applied if we'd been passed a type, but we cannot modify
799 the decl's type in place here. */
bb9f8221 800 if (spec->type_required && DECL_P (*anode))
dd4dc3cd
RK
801 {
802 anode = &TREE_TYPE (*anode);
26c87b1a 803 flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
dd4dc3cd 804 }
bb9f8221 805
f0a90c7d
AO
806 if (spec->function_type_required
807 && !FUNC_OR_METHOD_TYPE_P (*anode))
bb9f8221
RK
808 {
809 if (TREE_CODE (*anode) == POINTER_TYPE
ca2007a9 810 && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (*anode)))
bb9f8221 811 {
3acef2ae
JM
812 /* OK, this is a bit convoluted. We can't just make a copy
813 of the pointer type and modify its TREE_TYPE, because if
814 we change the attributes of the target type the pointer
815 type needs to have a different TYPE_MAIN_VARIANT. So we
816 pull out the target type now, frob it as appropriate, and
817 rebuild the pointer type later.
818
c22cacf3
MS
819 This would all be simpler if attributes were part of the
820 declarator, grumble grumble. */
3acef2ae 821 fn_ptr_tmp = TREE_TYPE (*anode);
f9ceed32 822 fn_ptr_quals = TYPE_QUALS (*anode);
3acef2ae
JM
823 anode = &fn_ptr_tmp;
824 flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
bb9f8221
RK
825 }
826 else if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
827 {
828 /* Pass on this attribute to be tried again. */
5d9ae53d
MS
829 tree attr = tree_cons (name, args, NULL_TREE);
830 returned_attrs = chainon (returned_attrs, attr);
bb9f8221
RK
831 continue;
832 }
833
834 if (TREE_CODE (*anode) != FUNCTION_TYPE
835 && TREE_CODE (*anode) != METHOD_TYPE)
836 {
5c498b10 837 warning (OPT_Wattributes,
4f1e4960
JM
838 "%qE attribute only applies to function types",
839 name);
bb9f8221
RK
840 continue;
841 }
842 }
843
b9e75696
JM
844 if (TYPE_P (*anode)
845 && (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
ca2007a9 846 && COMPLETE_TYPE_P (*anode))
b9e75696
JM
847 {
848 warning (OPT_Wattributes, "type attributes ignored after type is already defined");
849 continue;
850 }
851
5d9ae53d
MS
852 bool no_add_attrs = false;
853
bffc6270
MS
854 /* Check for exclusions with other attributes on the current
855 declation as well as the last declaration of the same
856 symbol already processed (if one exists). Detect and
857 reject incompatible attributes. */
858 bool built_in = flags & ATTR_FLAG_BUILT_IN;
859 if (spec->exclude
e2a71816
JJ
860 && (flag_checking || !built_in)
861 && !error_operand_p (last_decl))
bffc6270
MS
862 {
863 /* Always check attributes on user-defined functions.
864 Check them on built-ins only when -fchecking is set.
865 Ignore __builtin_unreachable -- it's both const and
866 noreturn. */
867
868 if (!built_in
869 || !DECL_P (*anode)
cb1180d5 870 || DECL_BUILT_IN_CLASS (*anode) != BUILT_IN_NORMAL
bffc6270 871 || (DECL_FUNCTION_CODE (*anode) != BUILT_IN_UNREACHABLE
d2423144 872 && DECL_FUNCTION_CODE (*anode) != BUILT_IN_UNREACHABLE_TRAP
bffc6270
MS
873 && (DECL_FUNCTION_CODE (*anode)
874 != BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE)))
875 {
876 bool no_add = diag_attr_exclusions (last_decl, *anode, name, spec);
877 if (!no_add && anode != node)
878 no_add = diag_attr_exclusions (last_decl, *node, name, spec);
879 no_add_attrs |= no_add;
880 }
881 }
882
533241c6
JJ
883 if (no_add_attrs
884 /* Don't add attributes registered just for -Wno-attributes=foo::bar
885 purposes. */
886 || attribute_ignored_p (attr))
bffc6270
MS
887 continue;
888
bb9f8221 889 if (spec->handler != NULL)
e28d52cf 890 {
1bf32c11 891 int cxx11_flag = (cxx11_attr_p ? ATTR_FLAG_CXX11 : 0);
e28d52cf 892
5d9ae53d 893 /* Pass in an array of the current declaration followed
6450f073
MS
894 by the last pushed/merged declaration if one exists.
895 For calls that modify the type attributes of a DECL
896 and for which *ANODE is *NODE's type, also pass in
897 the DECL as the third element to use in diagnostics.
5d9ae53d
MS
898 If the handler changes CUR_AND_LAST_DECL[0] replace
899 *ANODE with its value. */
6450f073
MS
900 tree cur_and_last_decl[3] = { *anode, last_decl };
901 if (anode != node && DECL_P (*node))
902 cur_and_last_decl[2] = *node;
903
5d9ae53d
MS
904 tree ret = (spec->handler) (cur_and_last_decl, name, args,
905 flags|cxx11_flag, &no_add_attrs);
906
ed12749a
JM
907 /* Fix up typedefs clobbered by attribute handlers. */
908 if (TREE_CODE (*node) == TYPE_DECL
909 && anode == &TREE_TYPE (*node)
910 && DECL_ORIGINAL_TYPE (*node)
911 && TYPE_NAME (*anode) == *node
912 && TYPE_NAME (cur_and_last_decl[0]) != *node)
913 {
914 tree t = cur_and_last_decl[0];
915 DECL_ORIGINAL_TYPE (*node) = t;
916 tree tt = build_variant_type_copy (t);
917 cur_and_last_decl[0] = tt;
918 TREE_TYPE (*node) = tt;
919 TYPE_NAME (tt) = *node;
920 }
921
f0a90c7d
AO
922 if (*anode != cur_and_last_decl[0])
923 {
924 /* Even if !spec->function_type_required, allow the attribute
925 handler to request the attribute to be applied to the function
926 type, rather than to the function pointer type, by setting
927 cur_and_last_decl[0] to the function type. */
928 if (!fn_ptr_tmp
929 && POINTER_TYPE_P (*anode)
930 && TREE_TYPE (*anode) == cur_and_last_decl[0]
931 && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (*anode)))
932 {
933 fn_ptr_tmp = TREE_TYPE (*anode);
934 fn_ptr_quals = TYPE_QUALS (*anode);
935 anode = &fn_ptr_tmp;
936 }
937 *anode = cur_and_last_decl[0];
938 }
939
5d9ae53d
MS
940 if (ret == error_mark_node)
941 {
942 warning (OPT_Wattributes, "%qE attribute ignored", name);
943 no_add_attrs = true;
944 }
945 else
946 returned_attrs = chainon (ret, returned_attrs);
947 }
948
1b9191d2
AH
949 /* Layout the decl in case anything changed. */
950 if (spec->type_required && DECL_P (*node)
8813a647 951 && (VAR_P (*node)
67282790
JM
952 || TREE_CODE (*node) == PARM_DECL
953 || TREE_CODE (*node) == RESULT_DECL))
d1838621 954 relayout_decl (*node);
1b9191d2 955
bb9f8221
RK
956 if (!no_add_attrs)
957 {
958 tree old_attrs;
959 tree a;
960
961 if (DECL_P (*anode))
962 old_attrs = DECL_ATTRIBUTES (*anode);
963 else
964 old_attrs = TYPE_ATTRIBUTES (*anode);
965
f8135a5a 966 for (a = find_same_attribute (attr, old_attrs);
bb9f8221 967 a != NULL_TREE;
f8135a5a 968 a = find_same_attribute (attr, TREE_CHAIN (a)))
bb9f8221
RK
969 {
970 if (simple_cst_equal (TREE_VALUE (a), args) == 1)
971 break;
972 }
973
974 if (a == NULL_TREE)
975 {
976 /* This attribute isn't already in the list. */
1bf32c11
MP
977 tree r;
978 /* Preserve the C++11 form. */
979 if (cxx11_attr_p)
980 r = tree_cons (build_tree_list (ns, name), args, old_attrs);
981 else
982 r = tree_cons (name, args, old_attrs);
983
bb9f8221 984 if (DECL_P (*anode))
1bf32c11 985 DECL_ATTRIBUTES (*anode) = r;
bb9f8221 986 else if (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
67214984 987 {
1bf32c11 988 TYPE_ATTRIBUTES (*anode) = r;
67214984
JM
989 /* If this is the main variant, also push the attributes
990 out to the other variants. */
991 if (*anode == TYPE_MAIN_VARIANT (*anode))
992 {
1bf32c11 993 for (tree variant = *anode; variant;
67214984
JM
994 variant = TYPE_NEXT_VARIANT (variant))
995 {
996 if (TYPE_ATTRIBUTES (variant) == old_attrs)
997 TYPE_ATTRIBUTES (variant)
998 = TYPE_ATTRIBUTES (*anode);
f8135a5a
RS
999 else if (!find_same_attribute
1000 (attr, TYPE_ATTRIBUTES (variant)))
67214984
JM
1001 TYPE_ATTRIBUTES (variant) = tree_cons
1002 (name, args, TYPE_ATTRIBUTES (variant));
1003 }
1004 }
1005 }
bb9f8221 1006 else
1bf32c11 1007 *anode = build_type_attribute_variant (*anode, r);
bb9f8221
RK
1008 }
1009 }
3acef2ae
JM
1010
1011 if (fn_ptr_tmp)
1012 {
1013 /* Rebuild the function pointer type and put it in the
1014 appropriate place. */
1015 fn_ptr_tmp = build_pointer_type (fn_ptr_tmp);
f9ceed32
MM
1016 if (fn_ptr_quals)
1017 fn_ptr_tmp = build_qualified_type (fn_ptr_tmp, fn_ptr_quals);
3acef2ae
JM
1018 if (DECL_P (*node))
1019 TREE_TYPE (*node) = fn_ptr_tmp;
3acef2ae 1020 else
298e6adc
NS
1021 {
1022 gcc_assert (TREE_CODE (*node) == POINTER_TYPE);
1023 *node = fn_ptr_tmp;
1024 }
3acef2ae 1025 }
bb9f8221
RK
1026 }
1027
1028 return returned_attrs;
1029}
0a35513e 1030
e28d52cf
DS
1031/* Return TRUE iff ATTR has been parsed by the front-end as a C++-11
1032 attribute.
1033
1034 When G++ parses a C++11 attribute, it is represented as
1035 a TREE_LIST which TREE_PURPOSE is itself a TREE_LIST. TREE_PURPOSE
1036 (TREE_PURPOSE (ATTR)) is the namespace of the attribute, and the
1037 TREE_VALUE (TREE_PURPOSE (ATTR)) is its non-qualified name. Please
1038 use get_attribute_namespace and get_attribute_name to retrieve the
1039 namespace and name of the attribute, as these accessors work with
1040 GNU attributes as well. */
1041
1042bool
1043cxx11_attribute_p (const_tree attr)
1044{
1045 if (attr == NULL_TREE
1046 || TREE_CODE (attr) != TREE_LIST)
1047 return false;
1048
1049 return (TREE_CODE (TREE_PURPOSE (attr)) == TREE_LIST);
1050}
1051
1052/* Return the name of the attribute ATTR. This accessor works on GNU
1053 and C++11 (scoped) attributes.
1054
1055 Please read the comments of cxx11_attribute_p to understand the
1056 format of attributes. */
1057
1058tree
1059get_attribute_name (const_tree attr)
1060{
1061 if (cxx11_attribute_p (attr))
1062 return TREE_VALUE (TREE_PURPOSE (attr));
1063 return TREE_PURPOSE (attr);
1064}
1065
0a35513e
AH
1066/* Subroutine of set_method_tm_attributes. Apply TM attribute ATTR
1067 to the method FNDECL. */
1068
1069void
1070apply_tm_attr (tree fndecl, tree attr)
1071{
1072 decl_attributes (&TREE_TYPE (fndecl), tree_cons (attr, NULL, NULL), 0);
1073}
3b1661a9
ES
1074
1075/* Makes a function attribute of the form NAME(ARG_NAME) and chains
1076 it to CHAIN. */
1077
1078tree
1079make_attribute (const char *name, const char *arg_name, tree chain)
1080{
1081 tree attr_name;
1082 tree attr_arg_name;
1083 tree attr_args;
1084 tree attr;
1085
1086 attr_name = get_identifier (name);
1087 attr_arg_name = build_string (strlen (arg_name), arg_name);
1088 attr_args = tree_cons (NULL_TREE, attr_arg_name, NULL_TREE);
1089 attr = tree_cons (attr_name, attr_args, chain);
1090 return attr;
1091}
1b062c1a
MM
1092
1093\f
1094/* Common functions used for target clone support. */
1095
1096/* Comparator function to be used in qsort routine to sort attribute
1097 specification strings to "target". */
1098
1099static int
1100attr_strcmp (const void *v1, const void *v2)
1101{
1102 const char *c1 = *(char *const*)v1;
1103 const char *c2 = *(char *const*)v2;
1104 return strcmp (c1, c2);
1105}
1106
1107/* ARGLIST is the argument to target attribute. This function tokenizes
1108 the comma separated arguments, sorts them and returns a string which
1109 is a unique identifier for the comma separated arguments. It also
1110 replaces non-identifier characters "=,-" with "_". */
1111
1112char *
1113sorted_attr_string (tree arglist)
1114{
1115 tree arg;
1116 size_t str_len_sum = 0;
1117 char **args = NULL;
1118 char *attr_str, *ret_str;
1119 char *attr = NULL;
1120 unsigned int argnum = 1;
1121 unsigned int i;
1122
1123 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
1124 {
1125 const char *str = TREE_STRING_POINTER (TREE_VALUE (arg));
1126 size_t len = strlen (str);
1127 str_len_sum += len + 1;
1128 if (arg != arglist)
1129 argnum++;
1130 for (i = 0; i < strlen (str); i++)
1131 if (str[i] == ',')
1132 argnum++;
1133 }
1134
1135 attr_str = XNEWVEC (char, str_len_sum);
1136 str_len_sum = 0;
1137 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
1138 {
1139 const char *str = TREE_STRING_POINTER (TREE_VALUE (arg));
1140 size_t len = strlen (str);
1141 memcpy (attr_str + str_len_sum, str, len);
1142 attr_str[str_len_sum + len] = TREE_CHAIN (arg) ? ',' : '\0';
1143 str_len_sum += len + 1;
1144 }
1145
1146 /* Replace "=,-" with "_". */
1147 for (i = 0; i < strlen (attr_str); i++)
1148 if (attr_str[i] == '=' || attr_str[i]== '-')
1149 attr_str[i] = '_';
1150
1151 if (argnum == 1)
1152 return attr_str;
1153
1154 args = XNEWVEC (char *, argnum);
1155
1156 i = 0;
1157 attr = strtok (attr_str, ",");
1158 while (attr != NULL)
1159 {
1160 args[i] = attr;
1161 i++;
1162 attr = strtok (NULL, ",");
1163 }
1164
1165 qsort (args, argnum, sizeof (char *), attr_strcmp);
1166
1167 ret_str = XNEWVEC (char, str_len_sum);
1168 str_len_sum = 0;
1169 for (i = 0; i < argnum; i++)
1170 {
1171 size_t len = strlen (args[i]);
1172 memcpy (ret_str + str_len_sum, args[i], len);
1173 ret_str[str_len_sum + len] = i < argnum - 1 ? '_' : '\0';
1174 str_len_sum += len + 1;
1175 }
1176
1177 XDELETEVEC (args);
1178 XDELETEVEC (attr_str);
1179 return ret_str;
1180}
1181
1182
1183/* This function returns true if FN1 and FN2 are versions of the same function,
1184 that is, the target strings of the function decls are different. This assumes
1185 that FN1 and FN2 have the same signature. */
1186
1187bool
1188common_function_versions (tree fn1, tree fn2)
1189{
1190 tree attr1, attr2;
1191 char *target1, *target2;
1192 bool result;
1193
1194 if (TREE_CODE (fn1) != FUNCTION_DECL
1195 || TREE_CODE (fn2) != FUNCTION_DECL)
1196 return false;
1197
1198 attr1 = lookup_attribute ("target", DECL_ATTRIBUTES (fn1));
1199 attr2 = lookup_attribute ("target", DECL_ATTRIBUTES (fn2));
1200
1201 /* At least one function decl should have the target attribute specified. */
1202 if (attr1 == NULL_TREE && attr2 == NULL_TREE)
1203 return false;
1204
1205 /* Diagnose missing target attribute if one of the decls is already
1206 multi-versioned. */
1207 if (attr1 == NULL_TREE || attr2 == NULL_TREE)
1208 {
1209 if (DECL_FUNCTION_VERSIONED (fn1) || DECL_FUNCTION_VERSIONED (fn2))
1210 {
1211 if (attr2 != NULL_TREE)
1212 {
1213 std::swap (fn1, fn2);
1214 attr1 = attr2;
1215 }
ade1e0d5 1216 auto_diagnostic_group d;
1b062c1a
MM
1217 error_at (DECL_SOURCE_LOCATION (fn2),
1218 "missing %<target%> attribute for multi-versioned %qD",
1219 fn2);
1220 inform (DECL_SOURCE_LOCATION (fn1),
1221 "previous declaration of %qD", fn1);
1222 /* Prevent diagnosing of the same error multiple times. */
1223 DECL_ATTRIBUTES (fn2)
1224 = tree_cons (get_identifier ("target"),
1225 copy_node (TREE_VALUE (attr1)),
1226 DECL_ATTRIBUTES (fn2));
1227 }
1228 return false;
1229 }
1230
1231 target1 = sorted_attr_string (TREE_VALUE (attr1));
1232 target2 = sorted_attr_string (TREE_VALUE (attr2));
1233
1234 /* The sorted target strings must be different for fn1 and fn2
1235 to be versions. */
1236 if (strcmp (target1, target2) == 0)
1237 result = false;
1238 else
1239 result = true;
1240
1241 XDELETEVEC (target1);
1242 XDELETEVEC (target2);
1243
1244 return result;
1245}
1246
1b062c1a
MM
1247/* Make a dispatcher declaration for the multi-versioned function DECL.
1248 Calls to DECL function will be replaced with calls to the dispatcher
1249 by the front-end. Return the decl created. */
1250
1251tree
1252make_dispatcher_decl (const tree decl)
1253{
1254 tree func_decl;
1255 char *func_name;
1256 tree fn_type, func_type;
1b062c1a 1257
871cc215 1258 func_name = xstrdup (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
1b062c1a
MM
1259
1260 fn_type = TREE_TYPE (decl);
1261 func_type = build_function_type (TREE_TYPE (fn_type),
1262 TYPE_ARG_TYPES (fn_type));
1263
1264 func_decl = build_fn_decl (func_name, func_type);
1265 XDELETEVEC (func_name);
1266 TREE_USED (func_decl) = 1;
1267 DECL_CONTEXT (func_decl) = NULL_TREE;
1268 DECL_INITIAL (func_decl) = error_mark_node;
1269 DECL_ARTIFICIAL (func_decl) = 1;
1270 /* Mark this func as external, the resolver will flip it again if
1271 it gets generated. */
1272 DECL_EXTERNAL (func_decl) = 1;
1273 /* This will be of type IFUNCs have to be externally visible. */
1274 TREE_PUBLIC (func_decl) = 1;
1275
1276 return func_decl;
1277}
1278
1279/* Returns true if decl is multi-versioned and DECL is the default function,
1280 that is it is not tagged with target specific optimization. */
1281
1282bool
1283is_function_default_version (const tree decl)
1284{
1285 if (TREE_CODE (decl) != FUNCTION_DECL
1286 || !DECL_FUNCTION_VERSIONED (decl))
1287 return false;
1288 tree attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl));
1289 gcc_assert (attr);
1290 attr = TREE_VALUE (TREE_VALUE (attr));
1291 return (TREE_CODE (attr) == STRING_CST
1292 && strcmp (TREE_STRING_POINTER (attr), "default") == 0);
1293}
314e6352
ML
1294
1295/* Return a declaration like DDECL except that its DECL_ATTRIBUTES
1296 is ATTRIBUTE. */
1297
1298tree
1299build_decl_attribute_variant (tree ddecl, tree attribute)
1300{
1301 DECL_ATTRIBUTES (ddecl) = attribute;
1302 return ddecl;
1303}
1304
1305/* Return a type like TTYPE except that its TYPE_ATTRIBUTE
1306 is ATTRIBUTE and its qualifiers are QUALS.
1307
1308 Record such modified types already made so we don't make duplicates. */
1309
1310tree
27c825c5 1311build_type_attribute_qual_variant (tree otype, tree attribute, int quals)
314e6352 1312{
27c825c5 1313 tree ttype = otype;
314e6352
ML
1314 if (! attribute_list_equal (TYPE_ATTRIBUTES (ttype), attribute))
1315 {
1316 tree ntype;
1317
1318 /* Building a distinct copy of a tagged type is inappropriate; it
1319 causes breakage in code that expects there to be a one-to-one
1320 relationship between a struct and its fields.
1321 build_duplicate_type is another solution (as used in
1322 handle_transparent_union_attribute), but that doesn't play well
1323 with the stronger C++ type identity model. */
ca2007a9 1324 if (RECORD_OR_UNION_TYPE_P (ttype)
314e6352
ML
1325 || TREE_CODE (ttype) == ENUMERAL_TYPE)
1326 {
1327 warning (OPT_Wattributes,
1328 "ignoring attributes applied to %qT after definition",
1329 TYPE_MAIN_VARIANT (ttype));
1330 return build_qualified_type (ttype, quals);
1331 }
1332
1333 ttype = build_qualified_type (ttype, TYPE_UNQUALIFIED);
27c825c5
JM
1334 if (lang_hooks.types.copy_lang_qualifiers
1335 && otype != TYPE_MAIN_VARIANT (otype))
1336 ttype = (lang_hooks.types.copy_lang_qualifiers
1337 (ttype, TYPE_MAIN_VARIANT (otype)));
1338
5cedffbc 1339 tree dtype = ntype = build_distinct_type_copy (ttype);
314e6352
ML
1340
1341 TYPE_ATTRIBUTES (ntype) = attribute;
1342
1343 hashval_t hash = type_hash_canon_hash (ntype);
1344 ntype = type_hash_canon (hash, ntype);
1345
5cedffbc
JM
1346 if (ntype != dtype)
1347 /* This variant was already in the hash table, don't mess with
1348 TYPE_CANONICAL. */;
1349 else if (TYPE_STRUCTURAL_EQUALITY_P (ttype)
1350 || !comp_type_attributes (ntype, ttype))
a5e2a41f
JM
1351 /* If the target-dependent attributes make NTYPE different from
1352 its canonical type, we will need to use structural equality
1353 checks for this type.
1354
1355 We shouldn't get here for stripping attributes from a type;
1356 the no-attribute type might not need structural comparison. But
1357 we can if was discarded from type_hash_table. */
1358 SET_TYPE_STRUCTURAL_EQUALITY (ntype);
314e6352
ML
1359 else if (TYPE_CANONICAL (ntype) == ntype)
1360 TYPE_CANONICAL (ntype) = TYPE_CANONICAL (ttype);
1361
1362 ttype = build_qualified_type (ntype, quals);
27c825c5
JM
1363 if (lang_hooks.types.copy_lang_qualifiers
1364 && otype != TYPE_MAIN_VARIANT (otype))
1365 ttype = lang_hooks.types.copy_lang_qualifiers (ttype, otype);
314e6352
ML
1366 }
1367 else if (TYPE_QUALS (ttype) != quals)
1368 ttype = build_qualified_type (ttype, quals);
1369
1370 return ttype;
1371}
1372
1373/* Compare two identifier nodes representing attributes.
1374 Return true if they are the same, false otherwise. */
1375
1376static bool
1377cmp_attrib_identifiers (const_tree attr1, const_tree attr2)
1378{
1379 /* Make sure we're dealing with IDENTIFIER_NODEs. */
1380 gcc_checking_assert (TREE_CODE (attr1) == IDENTIFIER_NODE
1381 && TREE_CODE (attr2) == IDENTIFIER_NODE);
1382
1383 /* Identifiers can be compared directly for equality. */
1384 if (attr1 == attr2)
1385 return true;
1386
1387 return cmp_attribs (IDENTIFIER_POINTER (attr1), IDENTIFIER_LENGTH (attr1),
1388 IDENTIFIER_POINTER (attr2), IDENTIFIER_LENGTH (attr2));
1389}
1390
1391/* Compare two constructor-element-type constants. Return 1 if the lists
1392 are known to be equal; otherwise return 0. */
1393
7e71909a 1394bool
314e6352
ML
1395simple_cst_list_equal (const_tree l1, const_tree l2)
1396{
1397 while (l1 != NULL_TREE && l2 != NULL_TREE)
1398 {
1399 if (simple_cst_equal (TREE_VALUE (l1), TREE_VALUE (l2)) != 1)
1400 return false;
1401
1402 l1 = TREE_CHAIN (l1);
1403 l2 = TREE_CHAIN (l2);
1404 }
1405
1406 return l1 == l2;
1407}
1408
1409/* Check if "omp declare simd" attribute arguments, CLAUSES1 and CLAUSES2, are
1410 the same. */
1411
1412static bool
1413omp_declare_simd_clauses_equal (tree clauses1, tree clauses2)
1414{
1415 tree cl1, cl2;
1416 for (cl1 = clauses1, cl2 = clauses2;
1417 cl1 && cl2;
1418 cl1 = OMP_CLAUSE_CHAIN (cl1), cl2 = OMP_CLAUSE_CHAIN (cl2))
1419 {
1420 if (OMP_CLAUSE_CODE (cl1) != OMP_CLAUSE_CODE (cl2))
1421 return false;
1422 if (OMP_CLAUSE_CODE (cl1) != OMP_CLAUSE_SIMDLEN)
1423 {
1424 if (simple_cst_equal (OMP_CLAUSE_DECL (cl1),
1425 OMP_CLAUSE_DECL (cl2)) != 1)
1426 return false;
1427 }
1428 switch (OMP_CLAUSE_CODE (cl1))
1429 {
1430 case OMP_CLAUSE_ALIGNED:
1431 if (simple_cst_equal (OMP_CLAUSE_ALIGNED_ALIGNMENT (cl1),
1432 OMP_CLAUSE_ALIGNED_ALIGNMENT (cl2)) != 1)
1433 return false;
1434 break;
1435 case OMP_CLAUSE_LINEAR:
1436 if (simple_cst_equal (OMP_CLAUSE_LINEAR_STEP (cl1),
1437 OMP_CLAUSE_LINEAR_STEP (cl2)) != 1)
1438 return false;
1439 break;
1440 case OMP_CLAUSE_SIMDLEN:
1441 if (simple_cst_equal (OMP_CLAUSE_SIMDLEN_EXPR (cl1),
1442 OMP_CLAUSE_SIMDLEN_EXPR (cl2)) != 1)
1443 return false;
1444 default:
1445 break;
1446 }
1447 }
1448 return true;
1449}
1450
1451
1452/* Compare two attributes for their value identity. Return true if the
1453 attribute values are known to be equal; otherwise return false. */
1454
1455bool
1456attribute_value_equal (const_tree attr1, const_tree attr2)
1457{
1458 if (TREE_VALUE (attr1) == TREE_VALUE (attr2))
1459 return true;
1460
1461 if (TREE_VALUE (attr1) != NULL_TREE
1462 && TREE_CODE (TREE_VALUE (attr1)) == TREE_LIST
1463 && TREE_VALUE (attr2) != NULL_TREE
1464 && TREE_CODE (TREE_VALUE (attr2)) == TREE_LIST)
1465 {
1466 /* Handle attribute format. */
1467 if (is_attribute_p ("format", get_attribute_name (attr1)))
1468 {
1469 attr1 = TREE_VALUE (attr1);
1470 attr2 = TREE_VALUE (attr2);
1471 /* Compare the archetypes (printf/scanf/strftime/...). */
1472 if (!cmp_attrib_identifiers (TREE_VALUE (attr1), TREE_VALUE (attr2)))
1473 return false;
1474 /* Archetypes are the same. Compare the rest. */
1475 return (simple_cst_list_equal (TREE_CHAIN (attr1),
1476 TREE_CHAIN (attr2)) == 1);
1477 }
1478 return (simple_cst_list_equal (TREE_VALUE (attr1),
1479 TREE_VALUE (attr2)) == 1);
1480 }
1481
bc1a75dd 1482 if (TREE_VALUE (attr1)
314e6352 1483 && TREE_CODE (TREE_VALUE (attr1)) == OMP_CLAUSE
bc1a75dd 1484 && TREE_VALUE (attr2)
314e6352
ML
1485 && TREE_CODE (TREE_VALUE (attr2)) == OMP_CLAUSE)
1486 return omp_declare_simd_clauses_equal (TREE_VALUE (attr1),
1487 TREE_VALUE (attr2));
1488
1489 return (simple_cst_equal (TREE_VALUE (attr1), TREE_VALUE (attr2)) == 1);
1490}
1491
1492/* Return 0 if the attributes for two types are incompatible, 1 if they
1493 are compatible, and 2 if they are nearly compatible (which causes a
1494 warning to be generated). */
1495int
1496comp_type_attributes (const_tree type1, const_tree type2)
1497{
1498 const_tree a1 = TYPE_ATTRIBUTES (type1);
1499 const_tree a2 = TYPE_ATTRIBUTES (type2);
1500 const_tree a;
1501
1502 if (a1 == a2)
1503 return 1;
1504 for (a = a1; a != NULL_TREE; a = TREE_CHAIN (a))
1505 {
1506 const struct attribute_spec *as;
1507 const_tree attr;
1508
df4643f9 1509 as = lookup_attribute_spec (TREE_PURPOSE (a));
314e6352
ML
1510 if (!as || as->affects_type_identity == false)
1511 continue;
1512
f8135a5a 1513 attr = find_same_attribute (a, CONST_CAST_TREE (a2));
314e6352
ML
1514 if (!attr || !attribute_value_equal (a, attr))
1515 break;
1516 }
1517 if (!a)
1518 {
1519 for (a = a2; a != NULL_TREE; a = TREE_CHAIN (a))
1520 {
1521 const struct attribute_spec *as;
1522
df4643f9 1523 as = lookup_attribute_spec (TREE_PURPOSE (a));
314e6352
ML
1524 if (!as || as->affects_type_identity == false)
1525 continue;
1526
f8135a5a 1527 if (!find_same_attribute (a, CONST_CAST_TREE (a1)))
314e6352
ML
1528 break;
1529 /* We don't need to compare trees again, as we did this
1530 already in first loop. */
1531 }
1532 /* All types - affecting identity - are equal, so
1533 there is no need to call target hook for comparison. */
1534 if (!a)
1535 return 1;
1536 }
1537 if (lookup_attribute ("transaction_safe", CONST_CAST_TREE (a)))
1538 return 0;
5c5f0b65
IT
1539 if ((lookup_attribute ("nocf_check", TYPE_ATTRIBUTES (type1)) != NULL)
1540 ^ (lookup_attribute ("nocf_check", TYPE_ATTRIBUTES (type2)) != NULL))
1541 return 0;
f0a90c7d
AO
1542 int strub_ret = strub_comptypes (CONST_CAST_TREE (type1),
1543 CONST_CAST_TREE (type2));
1544 if (strub_ret == 0)
1545 return strub_ret;
314e6352
ML
1546 /* As some type combinations - like default calling-convention - might
1547 be compatible, we have to call the target hook to get the final result. */
f0a90c7d
AO
1548 int target_ret = targetm.comp_type_attributes (type1, type2);
1549 if (target_ret == 0)
1550 return target_ret;
1551 if (strub_ret == 2 || target_ret == 2)
1552 return 2;
1553 if (strub_ret == 1 && target_ret == 1)
1554 return 1;
1555 gcc_unreachable ();
314e6352
ML
1556}
1557
a3317f7b
RS
1558/* PREDICATE acts as a function of type:
1559
1560 (const_tree attr, const attribute_spec *as) -> bool
1561
1562 where ATTR is an attribute and AS is its possibly-null specification.
1563 Return a list of every attribute in attribute list ATTRS for which
1564 PREDICATE is true. Return ATTRS itself if PREDICATE returns true
1565 for every attribute. */
1566
1567template<typename Predicate>
1568tree
1569remove_attributes_matching (tree attrs, Predicate predicate)
1570{
1571 tree new_attrs = NULL_TREE;
1572 tree *ptr = &new_attrs;
1573 const_tree start = attrs;
1574 for (const_tree attr = attrs; attr; attr = TREE_CHAIN (attr))
1575 {
df4643f9 1576 const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attr));
a3317f7b
RS
1577 const_tree end;
1578 if (!predicate (attr, as))
1579 end = attr;
1580 else if (start == attrs)
1581 continue;
1582 else
1583 end = TREE_CHAIN (attr);
1584
1585 for (; start != end; start = TREE_CHAIN (start))
1586 {
1587 *ptr = tree_cons (TREE_PURPOSE (start),
1588 TREE_VALUE (start), NULL_TREE);
1589 TREE_CHAIN (*ptr) = NULL_TREE;
1590 ptr = &TREE_CHAIN (*ptr);
1591 }
1592 start = TREE_CHAIN (attr);
1593 }
1594 gcc_assert (!start || start == attrs);
1595 return start ? attrs : new_attrs;
1596}
1597
1598/* If VALUE is true, return the subset of ATTRS that affect type identity,
1599 otherwise return the subset of ATTRS that don't affect type identity. */
1600
1601tree
1602affects_type_identity_attributes (tree attrs, bool value)
1603{
1604 auto predicate = [value](const_tree, const attribute_spec *as) -> bool
1605 {
1606 return bool (as && as->affects_type_identity) == value;
1607 };
1608 return remove_attributes_matching (attrs, predicate);
1609}
1610
1696fc1e
RS
1611/* Remove attributes that affect type identity from ATTRS unless the
1612 same attributes occur in OK_ATTRS. */
1613
1614tree
1615restrict_type_identity_attributes_to (tree attrs, tree ok_attrs)
1616{
1617 auto predicate = [ok_attrs](const_tree attr,
1618 const attribute_spec *as) -> bool
1619 {
1620 if (!as || !as->affects_type_identity)
1621 return true;
1622
1623 for (tree ok_attr = lookup_attribute (as->name, ok_attrs);
1624 ok_attr;
1625 ok_attr = lookup_attribute (as->name, TREE_CHAIN (ok_attr)))
1626 if (simple_cst_equal (TREE_VALUE (ok_attr), TREE_VALUE (attr)) == 1)
1627 return true;
1628
1629 return false;
1630 };
1631 return remove_attributes_matching (attrs, predicate);
1632}
1633
314e6352
ML
1634/* Return a type like TTYPE except that its TYPE_ATTRIBUTE
1635 is ATTRIBUTE.
1636
1637 Record such modified types already made so we don't make duplicates. */
1638
1639tree
1640build_type_attribute_variant (tree ttype, tree attribute)
1641{
1642 return build_type_attribute_qual_variant (ttype, attribute,
1643 TYPE_QUALS (ttype));
1644}
1645\f
1646/* A variant of lookup_attribute() that can be used with an identifier
1647 as the first argument, and where the identifier can be either
1648 'text' or '__text__'.
1649
1650 Given an attribute ATTR_IDENTIFIER, and a list of attributes LIST,
1651 return a pointer to the attribute's list element if the attribute
1652 is part of the list, or NULL_TREE if not found. If the attribute
1653 appears more than once, this only returns the first occurrence; the
1654 TREE_CHAIN of the return value should be passed back in if further
1655 occurrences are wanted. ATTR_IDENTIFIER must be an identifier but
1656 can be in the form 'text' or '__text__'. */
1657static tree
1658lookup_ident_attribute (tree attr_identifier, tree list)
1659{
1660 gcc_checking_assert (TREE_CODE (attr_identifier) == IDENTIFIER_NODE);
1661
1662 while (list)
1663 {
1664 gcc_checking_assert (TREE_CODE (get_attribute_name (list))
1665 == IDENTIFIER_NODE);
1666
1667 if (cmp_attrib_identifiers (attr_identifier,
1668 get_attribute_name (list)))
1669 /* Found it. */
1670 break;
1671 list = TREE_CHAIN (list);
1672 }
1673
1674 return list;
1675}
1676
1677/* Remove any instances of attribute ATTR_NAME in LIST and return the
1678 modified list. */
1679
1680tree
1681remove_attribute (const char *attr_name, tree list)
1682{
1683 tree *p;
1684 gcc_checking_assert (attr_name[0] != '_');
1685
1686 for (p = &list; *p;)
1687 {
1688 tree l = *p;
1689
1690 tree attr = get_attribute_name (l);
1691 if (is_attribute_p (attr_name, attr))
1692 *p = TREE_CHAIN (l);
1693 else
1694 p = &TREE_CHAIN (l);
1695 }
1696
1697 return list;
1698}
1699
88f04e90
JJ
1700/* Similarly but also match namespace on the removed attributes.
1701 ATTR_NS "" stands for NULL or "gnu" namespace. */
0764dc85
JJ
1702
1703tree
1704remove_attribute (const char *attr_ns, const char *attr_name, tree list)
1705{
1706 tree *p;
1707 gcc_checking_assert (attr_name[0] != '_');
1708 gcc_checking_assert (attr_ns == NULL || attr_ns[0] != '_');
1709
1710 for (p = &list; *p;)
1711 {
1712 tree l = *p;
1713
1714 tree attr = get_attribute_name (l);
88f04e90
JJ
1715 if (is_attribute_p (attr_name, attr)
1716 && is_attribute_namespace_p (attr_ns, l))
0764dc85 1717 {
88f04e90
JJ
1718 *p = TREE_CHAIN (l);
1719 continue;
0764dc85
JJ
1720 }
1721 p = &TREE_CHAIN (l);
1722 }
1723
1724 return list;
1725}
1726
314e6352
ML
1727/* Return an attribute list that is the union of a1 and a2. */
1728
1729tree
1730merge_attributes (tree a1, tree a2)
1731{
1732 tree attributes;
1733
1734 /* Either one unset? Take the set one. */
1735
1736 if ((attributes = a1) == 0)
1737 attributes = a2;
1738
1739 /* One that completely contains the other? Take it. */
1740
1741 else if (a2 != 0 && ! attribute_list_contained (a1, a2))
1742 {
1743 if (attribute_list_contained (a2, a1))
1744 attributes = a2;
1745 else
1746 {
1747 /* Pick the longest list, and hang on the other list. */
1748
1749 if (list_length (a1) < list_length (a2))
1750 attributes = a2, a2 = a1;
1751
1752 for (; a2 != 0; a2 = TREE_CHAIN (a2))
1753 {
1754 tree a;
1755 for (a = lookup_ident_attribute (get_attribute_name (a2),
1756 attributes);
1757 a != NULL_TREE && !attribute_value_equal (a, a2);
1758 a = lookup_ident_attribute (get_attribute_name (a2),
1759 TREE_CHAIN (a)))
1760 ;
1761 if (a == NULL_TREE)
1762 {
1763 a1 = copy_node (a2);
1764 TREE_CHAIN (a1) = attributes;
1765 attributes = a1;
1766 }
1767 }
1768 }
1769 }
1770 return attributes;
1771}
1772
1773/* Given types T1 and T2, merge their attributes and return
1774 the result. */
1775
1776tree
1777merge_type_attributes (tree t1, tree t2)
1778{
1779 return merge_attributes (TYPE_ATTRIBUTES (t1),
1780 TYPE_ATTRIBUTES (t2));
1781}
1782
1783/* Given decls OLDDECL and NEWDECL, merge their attributes and return
1784 the result. */
1785
1786tree
1787merge_decl_attributes (tree olddecl, tree newdecl)
1788{
1789 return merge_attributes (DECL_ATTRIBUTES (olddecl),
1790 DECL_ATTRIBUTES (newdecl));
1791}
1792
bc1a75dd
JJ
1793/* Duplicate all attributes with name NAME in ATTR list to *ATTRS if
1794 they are missing there. */
1795
1796void
1797duplicate_one_attribute (tree *attrs, tree attr, const char *name)
1798{
1799 attr = lookup_attribute (name, attr);
1800 if (!attr)
1801 return;
1802 tree a = lookup_attribute (name, *attrs);
1803 while (attr)
1804 {
1805 tree a2;
1806 for (a2 = a; a2; a2 = lookup_attribute (name, TREE_CHAIN (a2)))
1807 if (attribute_value_equal (attr, a2))
1808 break;
1809 if (!a2)
1810 {
1811 a2 = copy_node (attr);
1812 TREE_CHAIN (a2) = *attrs;
1813 *attrs = a2;
1814 }
1815 attr = lookup_attribute (name, TREE_CHAIN (attr));
1816 }
1817}
1818
1819/* Duplicate all attributes from user DECL to the corresponding
1820 builtin that should be propagated. */
1821
1822void
1823copy_attributes_to_builtin (tree decl)
1824{
1825 tree b = builtin_decl_explicit (DECL_FUNCTION_CODE (decl));
1826 if (b)
1827 duplicate_one_attribute (&DECL_ATTRIBUTES (b),
1828 DECL_ATTRIBUTES (decl), "omp declare simd");
1829}
1830
314e6352
ML
1831#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
1832
1833/* Specialization of merge_decl_attributes for various Windows targets.
1834
1835 This handles the following situation:
1836
1837 __declspec (dllimport) int foo;
1838 int foo;
1839
1840 The second instance of `foo' nullifies the dllimport. */
1841
1842tree
1843merge_dllimport_decl_attributes (tree old, tree new_tree)
1844{
1845 tree a;
1846 int delete_dllimport_p = 1;
1847
1848 /* What we need to do here is remove from `old' dllimport if it doesn't
1849 appear in `new'. dllimport behaves like extern: if a declaration is
1850 marked dllimport and a definition appears later, then the object
1851 is not dllimport'd. We also remove a `new' dllimport if the old list
1852 contains dllexport: dllexport always overrides dllimport, regardless
1853 of the order of declaration. */
1854 if (!VAR_OR_FUNCTION_DECL_P (new_tree))
1855 delete_dllimport_p = 0;
1856 else if (DECL_DLLIMPORT_P (new_tree)
1857 && lookup_attribute ("dllexport", DECL_ATTRIBUTES (old)))
1858 {
1859 DECL_DLLIMPORT_P (new_tree) = 0;
1860 warning (OPT_Wattributes, "%q+D already declared with dllexport "
1861 "attribute: dllimport ignored", new_tree);
1862 }
1863 else if (DECL_DLLIMPORT_P (old) && !DECL_DLLIMPORT_P (new_tree))
1864 {
1865 /* Warn about overriding a symbol that has already been used, e.g.:
1866 extern int __attribute__ ((dllimport)) foo;
1867 int* bar () {return &foo;}
1868 int foo;
1869 */
1870 if (TREE_USED (old))
1871 {
1872 warning (0, "%q+D redeclared without dllimport attribute "
1873 "after being referenced with dll linkage", new_tree);
1874 /* If we have used a variable's address with dllimport linkage,
1875 keep the old DECL_DLLIMPORT_P flag: the ADDR_EXPR using the
1876 decl may already have had TREE_CONSTANT computed.
1877 We still remove the attribute so that assembler code refers
1878 to '&foo rather than '_imp__foo'. */
1879 if (VAR_P (old) && TREE_ADDRESSABLE (old))
1880 DECL_DLLIMPORT_P (new_tree) = 1;
1881 }
1882
1883 /* Let an inline definition silently override the external reference,
1884 but otherwise warn about attribute inconsistency. */
1885 else if (VAR_P (new_tree) || !DECL_DECLARED_INLINE_P (new_tree))
1886 warning (OPT_Wattributes, "%q+D redeclared without dllimport "
1887 "attribute: previous dllimport ignored", new_tree);
1888 }
1889 else
1890 delete_dllimport_p = 0;
1891
1892 a = merge_attributes (DECL_ATTRIBUTES (old), DECL_ATTRIBUTES (new_tree));
1893
1894 if (delete_dllimport_p)
1895 a = remove_attribute ("dllimport", a);
1896
1897 return a;
1898}
1899
1900/* Handle a "dllimport" or "dllexport" attribute; arguments as in
1901 struct attribute_spec.handler. */
1902
1903tree
1904handle_dll_attribute (tree * pnode, tree name, tree args, int flags,
1905 bool *no_add_attrs)
1906{
1907 tree node = *pnode;
1908 bool is_dllimport;
1909
1910 /* These attributes may apply to structure and union types being created,
1911 but otherwise should pass to the declaration involved. */
1912 if (!DECL_P (node))
1913 {
1914 if (flags & ((int) ATTR_FLAG_DECL_NEXT | (int) ATTR_FLAG_FUNCTION_NEXT
1915 | (int) ATTR_FLAG_ARRAY_NEXT))
1916 {
1917 *no_add_attrs = true;
1918 return tree_cons (name, args, NULL_TREE);
1919 }
1920 if (TREE_CODE (node) == RECORD_TYPE
1921 || TREE_CODE (node) == UNION_TYPE)
1922 {
1923 node = TYPE_NAME (node);
1924 if (!node)
1925 return NULL_TREE;
1926 }
1927 else
1928 {
1929 warning (OPT_Wattributes, "%qE attribute ignored",
1930 name);
1931 *no_add_attrs = true;
1932 return NULL_TREE;
1933 }
1934 }
1935
1936 if (!VAR_OR_FUNCTION_DECL_P (node) && TREE_CODE (node) != TYPE_DECL)
1937 {
1938 *no_add_attrs = true;
1939 warning (OPT_Wattributes, "%qE attribute ignored",
1940 name);
1941 return NULL_TREE;
1942 }
1943
1944 if (TREE_CODE (node) == TYPE_DECL
1945 && TREE_CODE (TREE_TYPE (node)) != RECORD_TYPE
1946 && TREE_CODE (TREE_TYPE (node)) != UNION_TYPE)
1947 {
1948 *no_add_attrs = true;
1949 warning (OPT_Wattributes, "%qE attribute ignored",
1950 name);
1951 return NULL_TREE;
1952 }
1953
1954 is_dllimport = is_attribute_p ("dllimport", name);
1955
1956 /* Report error on dllimport ambiguities seen now before they cause
1957 any damage. */
1958 if (is_dllimport)
1959 {
1960 /* Honor any target-specific overrides. */
1961 if (!targetm.valid_dllimport_attribute_p (node))
1962 *no_add_attrs = true;
1963
1964 else if (TREE_CODE (node) == FUNCTION_DECL
1965 && DECL_DECLARED_INLINE_P (node))
1966 {
1967 warning (OPT_Wattributes, "inline function %q+D declared as "
0d7bac69 1968 "dllimport: attribute ignored", node);
314e6352
ML
1969 *no_add_attrs = true;
1970 }
1971 /* Like MS, treat definition of dllimported variables and
1972 non-inlined functions on declaration as syntax errors. */
1973 else if (TREE_CODE (node) == FUNCTION_DECL && DECL_INITIAL (node))
1974 {
1975 error ("function %q+D definition is marked dllimport", node);
1976 *no_add_attrs = true;
1977 }
1978
1979 else if (VAR_P (node))
1980 {
1981 if (DECL_INITIAL (node))
1982 {
1983 error ("variable %q+D definition is marked dllimport",
1984 node);
1985 *no_add_attrs = true;
1986 }
1987
1988 /* `extern' needn't be specified with dllimport.
1989 Specify `extern' now and hope for the best. Sigh. */
1990 DECL_EXTERNAL (node) = 1;
1991 /* Also, implicitly give dllimport'd variables declared within
1992 a function global scope, unless declared static. */
1993 if (current_function_decl != NULL_TREE && !TREE_STATIC (node))
1994 TREE_PUBLIC (node) = 1;
3568d2d5
JJ
1995 /* Clear TREE_STATIC because DECL_EXTERNAL is set, unless
1996 it is a C++ static data member. */
1997 if (DECL_CONTEXT (node) == NULL_TREE
1998 || !RECORD_OR_UNION_TYPE_P (DECL_CONTEXT (node)))
1999 TREE_STATIC (node) = 0;
314e6352
ML
2000 }
2001
2002 if (*no_add_attrs == false)
2003 DECL_DLLIMPORT_P (node) = 1;
2004 }
2005 else if (TREE_CODE (node) == FUNCTION_DECL
2006 && DECL_DECLARED_INLINE_P (node)
2007 && flag_keep_inline_dllexport)
2008 /* An exported function, even if inline, must be emitted. */
2009 DECL_EXTERNAL (node) = 0;
2010
2011 /* Report error if symbol is not accessible at global scope. */
2012 if (!TREE_PUBLIC (node) && VAR_OR_FUNCTION_DECL_P (node))
2013 {
2014 error ("external linkage required for symbol %q+D because of "
2015 "%qE attribute", node, name);
2016 *no_add_attrs = true;
2017 }
2018
2019 /* A dllexport'd entity must have default visibility so that other
2020 program units (shared libraries or the main executable) can see
2021 it. A dllimport'd entity must have default visibility so that
2022 the linker knows that undefined references within this program
2023 unit can be resolved by the dynamic linker. */
2024 if (!*no_add_attrs)
2025 {
2026 if (DECL_VISIBILITY_SPECIFIED (node)
2027 && DECL_VISIBILITY (node) != VISIBILITY_DEFAULT)
2028 error ("%qE implies default visibility, but %qD has already "
2029 "been declared with a different visibility",
2030 name, node);
2031 DECL_VISIBILITY (node) = VISIBILITY_DEFAULT;
2032 DECL_VISIBILITY_SPECIFIED (node) = 1;
2033 }
2034
2035 return NULL_TREE;
2036}
2037
2038#endif /* TARGET_DLLIMPORT_DECL_ATTRIBUTES */
2039
2040/* Given two lists of attributes, return true if list l2 is
2041 equivalent to l1. */
2042
2043int
2044attribute_list_equal (const_tree l1, const_tree l2)
2045{
2046 if (l1 == l2)
2047 return 1;
2048
2049 return attribute_list_contained (l1, l2)
2050 && attribute_list_contained (l2, l1);
2051}
2052
2053/* Given two lists of attributes, return true if list L2 is
2054 completely contained within L1. */
2055/* ??? This would be faster if attribute names were stored in a canonicalized
2056 form. Otherwise, if L1 uses `foo' and L2 uses `__foo__', the long method
2057 must be used to show these elements are equivalent (which they are). */
2058/* ??? It's not clear that attributes with arguments will always be handled
2059 correctly. */
2060
2061int
2062attribute_list_contained (const_tree l1, const_tree l2)
2063{
2064 const_tree t1, t2;
2065
2066 /* First check the obvious, maybe the lists are identical. */
2067 if (l1 == l2)
2068 return 1;
2069
2070 /* Maybe the lists are similar. */
2071 for (t1 = l1, t2 = l2;
2072 t1 != 0 && t2 != 0
2073 && get_attribute_name (t1) == get_attribute_name (t2)
2074 && TREE_VALUE (t1) == TREE_VALUE (t2);
2075 t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
2076 ;
2077
2078 /* Maybe the lists are equal. */
2079 if (t1 == 0 && t2 == 0)
2080 return 1;
2081
2082 for (; t2 != 0; t2 = TREE_CHAIN (t2))
2083 {
2084 const_tree attr;
2085 /* This CONST_CAST is okay because lookup_attribute does not
2086 modify its argument and the return value is assigned to a
2087 const_tree. */
2088 for (attr = lookup_ident_attribute (get_attribute_name (t2),
2089 CONST_CAST_TREE (l1));
2090 attr != NULL_TREE && !attribute_value_equal (t2, attr);
2091 attr = lookup_ident_attribute (get_attribute_name (t2),
2092 TREE_CHAIN (attr)))
2093 ;
2094
2095 if (attr == NULL_TREE)
2096 return 0;
2097 }
2098
2099 return 1;
2100}
13bdca74
ML
2101
2102/* The backbone of lookup_attribute(). ATTR_LEN is the string length
2103 of ATTR_NAME, and LIST is not NULL_TREE.
2104
2105 The function is called from lookup_attribute in order to optimize
2106 for size. */
2107
2108tree
2109private_lookup_attribute (const char *attr_name, size_t attr_len, tree list)
2110{
2111 while (list)
2112 {
2113 tree attr = get_attribute_name (list);
2114 size_t ident_len = IDENTIFIER_LENGTH (attr);
2115 if (cmp_attribs (attr_name, attr_len, IDENTIFIER_POINTER (attr),
2116 ident_len))
2117 break;
2118 list = TREE_CHAIN (list);
2119 }
2120
2121 return list;
2122}
5d9ae53d 2123
0764dc85
JJ
2124/* Similarly but with also attribute namespace. */
2125
2126tree
2127private_lookup_attribute (const char *attr_ns, const char *attr_name,
2128 size_t attr_ns_len, size_t attr_len, tree list)
2129{
2130 while (list)
2131 {
2132 tree attr = get_attribute_name (list);
2133 size_t ident_len = IDENTIFIER_LENGTH (attr);
2134 if (cmp_attribs (attr_name, attr_len, IDENTIFIER_POINTER (attr),
2135 ident_len))
2136 {
2137 tree ns = get_attribute_namespace (list);
2138 if (ns == NULL_TREE)
2139 {
88f04e90 2140 if (attr_ns_len == 0)
0764dc85
JJ
2141 break;
2142 }
2143 else if (attr_ns)
2144 {
2145 ident_len = IDENTIFIER_LENGTH (ns);
88f04e90
JJ
2146 if (attr_ns_len == 0)
2147 {
2148 if (cmp_attribs ("gnu", strlen ("gnu"),
2149 IDENTIFIER_POINTER (ns), ident_len))
2150 break;
2151 }
2152 else if (cmp_attribs (attr_ns, attr_ns_len,
2153 IDENTIFIER_POINTER (ns), ident_len))
0764dc85
JJ
2154 break;
2155 }
2156 }
2157 list = TREE_CHAIN (list);
2158 }
2159
2160 return list;
2161}
2162
79a2c428
MS
2163/* Return true if the function decl or type NODE has been declared
2164 with attribute ANAME among attributes ATTRS. */
2165
2166static bool
2167has_attribute (tree node, tree attrs, const char *aname)
2168{
2169 if (!strcmp (aname, "const"))
2170 {
2171 if (DECL_P (node) && TREE_READONLY (node))
2172 return true;
2173 }
2174 else if (!strcmp (aname, "malloc"))
2175 {
2176 if (DECL_P (node) && DECL_IS_MALLOC (node))
2177 return true;
2178 }
2179 else if (!strcmp (aname, "noreturn"))
2180 {
2181 if (DECL_P (node) && TREE_THIS_VOLATILE (node))
2182 return true;
2183 }
2184 else if (!strcmp (aname, "nothrow"))
2185 {
2186 if (TREE_NOTHROW (node))
2187 return true;
2188 }
2189 else if (!strcmp (aname, "pure"))
2190 {
2191 if (DECL_P (node) && DECL_PURE_P (node))
2192 return true;
2193 }
2194
2195 return lookup_attribute (aname, attrs);
2196}
2197
2198/* Return the number of mismatched function or type attributes between
2199 the "template" function declaration TMPL and DECL. The word "template"
2200 doesn't necessarily refer to a C++ template but rather a declaration
2201 whose attributes should be matched by those on DECL. For a non-zero
2202 return value set *ATTRSTR to a string representation of the list of
2203 mismatched attributes with quoted names.
2204 ATTRLIST is a list of additional attributes that SPEC should be
2205 taken to ultimately be declared with. */
2206
2207unsigned
2208decls_mismatched_attributes (tree tmpl, tree decl, tree attrlist,
2209 const char* const blacklist[],
2210 pretty_printer *attrstr)
2211{
2212 if (TREE_CODE (tmpl) != FUNCTION_DECL)
2213 return 0;
2214
2215 /* Avoid warning if either declaration or its type is deprecated. */
2216 if (TREE_DEPRECATED (tmpl)
2217 || TREE_DEPRECATED (decl))
2218 return 0;
2219
2220 const tree tmpls[] = { tmpl, TREE_TYPE (tmpl) };
2221 const tree decls[] = { decl, TREE_TYPE (decl) };
2222
2223 if (TREE_DEPRECATED (tmpls[1])
2224 || TREE_DEPRECATED (decls[1])
2225 || TREE_DEPRECATED (TREE_TYPE (tmpls[1]))
2226 || TREE_DEPRECATED (TREE_TYPE (decls[1])))
2227 return 0;
2228
2229 tree tmpl_attrs[] = { DECL_ATTRIBUTES (tmpl), TYPE_ATTRIBUTES (tmpls[1]) };
2230 tree decl_attrs[] = { DECL_ATTRIBUTES (decl), TYPE_ATTRIBUTES (decls[1]) };
2231
2232 if (!decl_attrs[0])
2233 decl_attrs[0] = attrlist;
2234 else if (!decl_attrs[1])
2235 decl_attrs[1] = attrlist;
2236
2237 /* Avoid warning if the template has no attributes. */
2238 if (!tmpl_attrs[0] && !tmpl_attrs[1])
2239 return 0;
2240
2241 /* Avoid warning if either declaration contains an attribute on
2242 the white list below. */
2243 const char* const whitelist[] = {
2244 "error", "warning"
2245 };
2246
2247 for (unsigned i = 0; i != 2; ++i)
ca32b29e 2248 for (unsigned j = 0; j != ARRAY_SIZE (whitelist); ++j)
79a2c428
MS
2249 if (lookup_attribute (whitelist[j], tmpl_attrs[i])
2250 || lookup_attribute (whitelist[j], decl_attrs[i]))
2251 return 0;
2252
2253 /* Put together a list of the black-listed attributes that the template
2254 is declared with and the declaration is not, in case it's not apparent
2255 from the most recent declaration of the template. */
2256 unsigned nattrs = 0;
2257
2258 for (unsigned i = 0; blacklist[i]; ++i)
2259 {
29d24852
MS
2260 /* Attribute leaf only applies to extern functions. Avoid mentioning
2261 it when it's missing from a static declaration. */
2262 if (!TREE_PUBLIC (decl)
2263 && !strcmp ("leaf", blacklist[i]))
2264 continue;
2265
79a2c428
MS
2266 for (unsigned j = 0; j != 2; ++j)
2267 {
2268 if (!has_attribute (tmpls[j], tmpl_attrs[j], blacklist[i]))
2269 continue;
2270
dea78431 2271 bool found = false;
79a2c428
MS
2272 unsigned kmax = 1 + !!decl_attrs[1];
2273 for (unsigned k = 0; k != kmax; ++k)
2274 {
2275 if (has_attribute (decls[k], decl_attrs[k], blacklist[i]))
dea78431
AO
2276 {
2277 found = true;
2278 break;
2279 }
2280 }
79a2c428 2281
dea78431
AO
2282 if (!found)
2283 {
79a2c428
MS
2284 if (nattrs)
2285 pp_string (attrstr, ", ");
2286 pp_begin_quote (attrstr, pp_show_color (global_dc->printer));
2287 pp_string (attrstr, blacklist[i]);
2288 pp_end_quote (attrstr, pp_show_color (global_dc->printer));
2289 ++nattrs;
2290 }
dea78431
AO
2291
2292 break;
79a2c428
MS
2293 }
2294 }
2295
2296 return nattrs;
2297}
2298
2299/* Issue a warning for the declaration ALIAS for TARGET where ALIAS
2300 specifies either attributes that are incompatible with those of
2301 TARGET, or attributes that are missing and that declaring ALIAS
2302 with would benefit. */
2303
2304void
2305maybe_diag_alias_attributes (tree alias, tree target)
2306{
2307 /* Do not expect attributes to match between aliases and ifunc
2308 resolvers. There is no obvious correspondence between them. */
2309 if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)))
2310 return;
2311
2312 const char* const blacklist[] = {
2313 "alloc_align", "alloc_size", "cold", "const", "hot", "leaf", "malloc",
2314 "nonnull", "noreturn", "nothrow", "pure", "returns_nonnull",
2315 "returns_twice", NULL
2316 };
2317
2318 pretty_printer attrnames;
2319 if (warn_attribute_alias > 1)
2320 {
2321 /* With -Wattribute-alias=2 detect alias declarations that are more
2322 restrictive than their targets first. Those indicate potential
2323 codegen bugs. */
2324 if (unsigned n = decls_mismatched_attributes (alias, target, NULL_TREE,
2325 blacklist, &attrnames))
2326 {
2327 auto_diagnostic_group d;
2328 if (warning_n (DECL_SOURCE_LOCATION (alias),
2329 OPT_Wattribute_alias_, n,
2330 "%qD specifies more restrictive attribute than "
2331 "its target %qD: %s",
2332 "%qD specifies more restrictive attributes than "
2333 "its target %qD: %s",
2334 alias, target, pp_formatted_text (&attrnames)))
2335 inform (DECL_SOURCE_LOCATION (target),
2336 "%qD target declared here", alias);
2337 return;
2338 }
2339 }
2340
2341 /* Detect alias declarations that are less restrictive than their
2342 targets. Those suggest potential optimization opportunities
2343 (solved by adding the missing attribute(s) to the alias). */
2344 if (unsigned n = decls_mismatched_attributes (target, alias, NULL_TREE,
2345 blacklist, &attrnames))
2346 {
2347 auto_diagnostic_group d;
2348 if (warning_n (DECL_SOURCE_LOCATION (alias),
2349 OPT_Wmissing_attributes, n,
2350 "%qD specifies less restrictive attribute than "
2351 "its target %qD: %s",
2352 "%qD specifies less restrictive attributes than "
2353 "its target %qD: %s",
2354 alias, target, pp_formatted_text (&attrnames)))
2355 inform (DECL_SOURCE_LOCATION (target),
2356 "%qD target declared here", alias);
2357 }
2358}
2359
6450f073
MS
2360/* Initialize a mapping RWM for a call to a function declared with
2361 attribute access in ATTRS. Each attribute positional operand
2362 inserts one entry into the mapping with the operand number as
2363 the key. */
b825a228
MS
2364
2365void
6450f073 2366init_attr_rdwr_indices (rdwr_map *rwm, tree attrs)
b825a228 2367{
6450f073 2368 if (!attrs)
b825a228
MS
2369 return;
2370
6450f073 2371 for (tree access = attrs;
b825a228
MS
2372 (access = lookup_attribute ("access", access));
2373 access = TREE_CHAIN (access))
2374 {
2375 /* The TREE_VALUE of an attribute is a TREE_LIST whose TREE_VALUE
2376 is the attribute argument's value. */
2377 tree mode = TREE_VALUE (access);
6450f073
MS
2378 if (!mode)
2379 return;
2380
2381 /* The (optional) list of VLA bounds. */
2382 tree vblist = TREE_CHAIN (mode);
b825a228 2383 mode = TREE_VALUE (mode);
6450f073
MS
2384 if (TREE_CODE (mode) != STRING_CST)
2385 continue;
b825a228
MS
2386 gcc_assert (TREE_CODE (mode) == STRING_CST);
2387
c6503fa9
MS
2388 if (vblist)
2389 vblist = nreverse (copy_list (TREE_VALUE (vblist)));
2390
6450f073 2391 for (const char *m = TREE_STRING_POINTER (mode); *m; )
b825a228
MS
2392 {
2393 attr_access acc = { };
2394
6450f073
MS
2395 /* Skip the internal-only plus sign. */
2396 if (*m == '+')
2397 ++m;
2398
2399 acc.str = m;
2400 acc.mode = acc.from_mode_char (*m);
2401 acc.sizarg = UINT_MAX;
2402
2403 const char *end;
2404 acc.ptrarg = strtoul (++m, const_cast<char**>(&end), 10);
2405 m = end;
2406
2407 if (*m == '[')
b825a228 2408 {
6450f073
MS
2409 /* Forms containing the square bracket are internal-only
2410 (not specified by an attribute declaration), and used
2411 for various forms of array and VLA parameters. */
2412 acc.internal_p = true;
2413
2414 /* Search to the closing bracket and look at the preceding
2415 code: it determines the form of the most significant
2416 bound of the array. Others prior to it encode the form
2417 of interior VLA bounds. They're not of interest here. */
2418 end = strchr (m, ']');
2419 const char *p = end;
2420 gcc_assert (p);
2421
2422 while (ISDIGIT (p[-1]))
2423 --p;
2424
2425 if (ISDIGIT (*p))
2426 {
2427 /* A digit denotes a constant bound (as in T[3]). */
2428 acc.static_p = p[-1] == 's';
2429 acc.minsize = strtoull (p, NULL, 10);
2430 }
2431 else if (' ' == p[-1])
2432 {
2433 /* A space denotes an ordinary array of unspecified bound
2434 (as in T[]). */
2435 acc.minsize = 0;
2436 }
2437 else if ('*' == p[-1] || '$' == p[-1])
2438 {
2439 /* An asterisk denotes a VLA. When the closing bracket
2440 is followed by a comma and a dollar sign its bound is
2441 on the list. Otherwise it's a VLA with an unspecified
2442 bound. */
757ba665 2443 acc.static_p = p[-2] == 's';
6450f073
MS
2444 acc.minsize = HOST_WIDE_INT_M1U;
2445 }
2446
2447 m = end + 1;
b825a228
MS
2448 }
2449
b825a228
MS
2450 if (*m == ',')
2451 {
6450f073
MS
2452 ++m;
2453 do
2454 {
2455 if (*m == '$')
2456 {
2457 ++m;
3599ecb6 2458 if (!acc.size && vblist)
6450f073
MS
2459 {
2460 /* Extract the list of VLA bounds for the current
2461 parameter, store it in ACC.SIZE, and advance
2462 to the list of bounds for the next VLA parameter.
2463 */
2464 acc.size = TREE_VALUE (vblist);
2465 vblist = TREE_CHAIN (vblist);
2466 }
2467 }
2468
2469 if (ISDIGIT (*m))
2470 {
2471 /* Extract the positional argument. It's absent
2472 for VLAs whose bound doesn't name a function
2473 parameter. */
2474 unsigned pos = strtoul (m, const_cast<char**>(&end), 10);
2475 if (acc.sizarg == UINT_MAX)
2476 acc.sizarg = pos;
2477 m = end;
2478 }
2479 }
2480 while (*m == '$');
2481 }
2482
2483 acc.end = m;
2484
2485 bool existing;
2486 auto &ref = rwm->get_or_insert (acc.ptrarg, &existing);
2487 if (existing)
2488 {
2489 /* Merge the new spec with the existing. */
2490 if (acc.minsize == HOST_WIDE_INT_M1U)
2491 ref.minsize = HOST_WIDE_INT_M1U;
2492
2493 if (acc.sizarg != UINT_MAX)
2494 ref.sizarg = acc.sizarg;
2495
2496 if (acc.mode)
2497 ref.mode = acc.mode;
b825a228
MS
2498 }
2499 else
6450f073 2500 ref = acc;
b825a228
MS
2501
2502 /* Unconditionally add an entry for the required pointer
2503 operand of the attribute, and one for the optional size
2504 operand when it's specified. */
b825a228
MS
2505 if (acc.sizarg != UINT_MAX)
2506 rwm->put (acc.sizarg, acc);
2507 }
2508 }
2509}
2510
6450f073
MS
2511/* Return the access specification for a function parameter PARM
2512 or null if the current function has no such specification. */
2513
2514attr_access *
2515get_parm_access (rdwr_map &rdwr_idx, tree parm,
2516 tree fndecl /* = current_function_decl */)
2517{
2518 tree fntype = TREE_TYPE (fndecl);
2519 init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
2520
2521 if (rdwr_idx.is_empty ())
2522 return NULL;
2523
2524 unsigned argpos = 0;
2525 tree fnargs = DECL_ARGUMENTS (fndecl);
2526 for (tree arg = fnargs; arg; arg = TREE_CHAIN (arg), ++argpos)
2527 if (arg == parm)
2528 return rdwr_idx.get (argpos);
2529
2530 return NULL;
2531}
2532
2533/* Return the internal representation as STRING_CST. Internal positional
2534 arguments are zero-based. */
2535
2536tree
2537attr_access::to_internal_string () const
2538{
2539 return build_string (end - str, str);
2540}
2541
2542/* Return the human-readable representation of the external attribute
2543 specification (as it might appear in the source code) as STRING_CST.
2544 External positional arguments are one-based. */
2545
2546tree
2547attr_access::to_external_string () const
2548{
2549 char buf[80];
2550 gcc_assert (mode != access_deferred);
2551 int len = snprintf (buf, sizeof buf, "access (%s, %u",
2552 mode_names[mode], ptrarg + 1);
2553 if (sizarg != UINT_MAX)
2554 len += snprintf (buf + len, sizeof buf - len, ", %u", sizarg + 1);
2555 strcpy (buf + len, ")");
2556 return build_string (len + 2, buf);
2557}
2558
2559/* Return the number of specified VLA bounds and set *nunspec to
2560 the number of unspecified ones (those designated by [*]). */
2561
2562unsigned
2563attr_access::vla_bounds (unsigned *nunspec) const
2564{
c6503fa9 2565 unsigned nbounds = 0;
6450f073 2566 *nunspec = 0;
c6503fa9
MS
2567 /* STR points to the beginning of the specified string for the current
2568 argument that may be followed by the string for the next argument. */
2569 for (const char* p = strchr (str, ']'); p && *p != '['; --p)
2570 {
2571 if (*p == '*')
2572 ++*nunspec;
2573 else if (*p == '$')
2574 ++nbounds;
2575 }
2576 return nbounds;
6450f073
MS
2577}
2578
0718336a
MS
2579/* Reset front end-specific attribute access data from ATTRS.
2580 Called from the free_lang_data pass. */
2581
2582/* static */ void
2583attr_access::free_lang_data (tree attrs)
2584{
2585 for (tree acs = attrs; (acs = lookup_attribute ("access", acs));
2586 acs = TREE_CHAIN (acs))
2587 {
2588 tree vblist = TREE_VALUE (acs);
2589 vblist = TREE_CHAIN (vblist);
2590 if (!vblist)
2591 continue;
2592
0718336a
MS
2593 for (vblist = TREE_VALUE (vblist); vblist; vblist = TREE_CHAIN (vblist))
2594 {
2595 tree *pvbnd = &TREE_VALUE (vblist);
2596 if (!*pvbnd || DECL_P (*pvbnd))
2597 continue;
2598
2599 /* VLA bounds that are expressions as opposed to DECLs are
2600 only used in the front end. Reset them to keep front end
2601 trees leaking into the middle end (see pr97172) and to
2602 free up memory. */
2603 *pvbnd = NULL_TREE;
2604 }
2605 }
ea5a82df
MS
2606
2607 for (tree argspec = attrs; (argspec = lookup_attribute ("arg spec", argspec));
2608 argspec = TREE_CHAIN (argspec))
2609 {
2610 /* Same as above. */
2611 tree *pvblist = &TREE_VALUE (argspec);
2612 *pvblist = NULL_TREE;
2613 }
0718336a 2614}
6450f073
MS
2615
2616/* Defined in attr_access. */
2617constexpr char attr_access::mode_chars[];
2618constexpr char attr_access::mode_names[][11];
2619
2620/* Format an array, including a VLA, pointed to by TYPE and used as
2621 a function parameter as a human-readable string. ACC describes
2622 an access to the parameter and is used to determine the outermost
2623 form of the array including its bound which is otherwise obviated
2624 by its decay to pointer. Return the formatted string. */
2625
2626std::string
2627attr_access::array_as_string (tree type) const
2628{
2629 std::string typstr;
2630
2631 if (type == error_mark_node)
2632 return std::string ();
2633
2634 if (this->str)
2635 {
e808f3fd
MS
2636 /* For array parameters (but not pointers) create a temporary array
2637 type that corresponds to the form of the parameter including its
6450f073
MS
2638 qualifiers even though they apply to the pointer, not the array
2639 type. */
2640 const bool vla_p = minsize == HOST_WIDE_INT_M1U;
2641 tree eltype = TREE_TYPE (type);
6450f073 2642 tree index_type = NULL_TREE;
e808f3fd 2643
6450f073
MS
2644 if (minsize == HOST_WIDE_INT_M1U)
2645 {
2646 /* Determine if this is a VLA (an array whose most significant
2647 bound is nonconstant and whose access string has "$]" in it)
2648 extract the bound expression from SIZE. */
2649 const char *p = end;
7dbc7ad5 2650 for ( ; p != str && *p-- != ']'; );
6450f073 2651 if (*p == '$')
2c8bffa1
MS
2652 /* SIZE may have been cleared. Use it with care. */
2653 index_type = build_index_type (size ? TREE_VALUE (size) : size);
6450f073 2654 }
7dbc7ad5 2655 else if (minsize)
6450f073
MS
2656 index_type = build_index_type (size_int (minsize - 1));
2657
e808f3fd 2658 tree arat = NULL_TREE;
6450f073
MS
2659 if (static_p || vla_p)
2660 {
2661 tree flag = static_p ? integer_one_node : NULL_TREE;
2662 /* Hack: there's no language-independent way to encode
2663 the "static" specifier or the "*" notation in an array type.
e808f3fd
MS
2664 Add a "fake" attribute to have the pretty-printer add "static"
2665 or "*". The "[static N]" notation is only valid in the most
2666 significant bound but [*] can be used for any bound. Because
2667 [*] is represented the same as [0] this hack only works for
2668 the most significant bound like static and the others are
2669 rendered as [0]. */
2670 arat = build_tree_list (get_identifier ("array"), flag);
6450f073
MS
2671 }
2672
e808f3fd
MS
2673 const int quals = TYPE_QUALS (type);
2674 type = build_array_type (eltype, index_type);
2675 type = build_type_attribute_qual_variant (type, arat, quals);
6450f073
MS
2676 }
2677
2678 /* Format the type using the current pretty printer. The generic tree
2679 printer does a terrible job. */
2680 pretty_printer *pp = global_dc->printer->clone ();
2681 pp_printf (pp, "%qT", type);
2682 typstr = pp_formatted_text (pp);
2683 delete pp;
2684
6450f073
MS
2685 return typstr;
2686}
79a2c428 2687
5d9ae53d
MS
2688#if CHECKING_P
2689
2690namespace selftest
2691{
2692
5d9ae53d
MS
2693/* Self-test to verify that each attribute exclusion is symmetric,
2694 meaning that if attribute A is encoded as incompatible with
2695 attribute B then the opposite relationship is also encoded.
2696 This test also detects most cases of misspelled attribute names
2697 in exclusions. */
2698
2699static void
2700test_attribute_exclusions ()
2701{
5b33cf3a
RS
2702 using excl_hash_traits = pair_hash<nofree_string_hash, nofree_string_hash>;
2703
5d9ae53d
MS
2704 /* Iterate over the array of attribute tables first (with TI0 as
2705 the index) and over the array of attribute_spec in each table
2706 (with SI0 as the index). */
7fa24687 2707 hash_set<excl_hash_traits> excl_set;
5d9ae53d 2708
7fa24687
RS
2709 for (auto scoped_array : attribute_tables)
2710 for (auto scoped_attributes : scoped_array)
2711 for (const attribute_spec &attribute : scoped_attributes->attributes)
2712 {
2713 const attribute_spec::exclusions *excl = attribute.exclude;
5d9ae53d 2714
7fa24687
RS
2715 /* Skip each attribute that doesn't define exclusions. */
2716 if (!excl)
2717 continue;
5d9ae53d 2718
7fa24687
RS
2719 /* Skip standard (non-GNU) attributes, since currently the
2720 exclusions are implicitly for GNU attributes only.
2721 Also, C++ likely and unlikely get rewritten to gnu::hot
2722 and gnu::cold, so symmetry isn't necessary there. */
2723 if (!scoped_attributes->ns)
2724 continue;
5d9ae53d 2725
7fa24687 2726 const char *attr_name = attribute.name;
5d9ae53d 2727
7fa24687
RS
2728 /* Iterate over the set of exclusions for every attribute
2729 (with EI0 as the index) adding the exclusions defined
2730 for each to the set. */
2731 for (size_t ei0 = 0; excl[ei0].name; ++ei0)
2732 {
2733 const char *excl_name = excl[ei0].name;
5d9ae53d 2734
7fa24687
RS
2735 if (!strcmp (attr_name, excl_name))
2736 continue;
5d9ae53d 2737
7fa24687
RS
2738 excl_set.add ({ attr_name, excl_name });
2739 }
2740 }
5d9ae53d
MS
2741
2742 /* Traverse the set of mutually exclusive pairs of attributes
2743 and verify that they are symmetric. */
7fa24687
RS
2744 for (auto excl_pair : excl_set)
2745 if (!excl_set.contains ({ excl_pair.second, excl_pair.first }))
2746 {
2747 /* An exclusion for an attribute has been found that
2748 doesn't have a corresponding exclusion in the opposite
2749 direction. */
2750 char desc[120];
2751 sprintf (desc, "'%s' attribute exclusion '%s' must be symmetric",
2752 excl_pair.first, excl_pair.second);
2753 fail (SELFTEST_LOCATION, desc);
2754 }
5d9ae53d
MS
2755}
2756
2757void
d5148d4f 2758attribs_cc_tests ()
5d9ae53d
MS
2759{
2760 test_attribute_exclusions ();
2761}
2762
2763} /* namespace selftest */
2764
2765#endif /* CHECKING_P */
3956f514
RS
2766
2767#include "gt-attribs.h"