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