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