aboutsummaryrefslogtreecommitdiff
path: root/gcc/attribs.c
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2021-09-13 10:37:49 -0700
committerIan Lance Taylor <iant@golang.org>2021-09-13 10:37:49 -0700
commite252b51ccde010cbd2a146485d8045103cd99533 (patch)
treee060f101cdc32bf5e520de8e5275db9d4236b74c /gcc/attribs.c
parentf10c7c4596dda99d2ee872c995ae4aeda65adbdf (diff)
parent104c05c5284b7822d770ee51a7d91946c7e56d50 (diff)
downloadgcc-e252b51ccde010cbd2a146485d8045103cd99533.zip
gcc-e252b51ccde010cbd2a146485d8045103cd99533.tar.gz
gcc-e252b51ccde010cbd2a146485d8045103cd99533.tar.bz2
Merge from trunk revision 104c05c5284b7822d770ee51a7d91946c7e56d50.
Diffstat (limited to 'gcc/attribs.c')
-rw-r--r--gcc/attribs.c125
1 files changed, 101 insertions, 24 deletions
diff --git a/gcc/attribs.c b/gcc/attribs.c
index 16c6b12..0d22c20 100644
--- a/gcc/attribs.c
+++ b/gcc/attribs.c
@@ -165,15 +165,12 @@ register_scoped_attributes (const struct attribute_spec *attributes,
static scoped_attributes*
find_attribute_namespace (const char* ns)
{
- unsigned ix;
- scoped_attributes *iter;
-
- FOR_EACH_VEC_ELT (attributes_table, ix, iter)
- if (ns == iter->ns
- || (iter->ns != NULL
+ for (scoped_attributes &iter : attributes_table)
+ if (ns == iter.ns
+ || (iter.ns != NULL
&& ns != NULL
- && !strcmp (iter->ns, ns)))
- return iter;
+ && !strcmp (iter.ns, ns)))
+ return &iter;
return NULL;
}
@@ -520,14 +517,9 @@ decl_attributes (tree *node, tree attributes, int flags,
if (TREE_CODE (*node) == FUNCTION_DECL
&& attributes
&& lookup_attribute ("naked", attributes) != NULL
- && lookup_attribute_spec (get_identifier ("naked")))
- {
- if (lookup_attribute ("noinline", attributes) == NULL)
- attributes = tree_cons (get_identifier ("noinline"), NULL, attributes);
-
- if (lookup_attribute ("noclone", attributes) == NULL)
- attributes = tree_cons (get_identifier ("noclone"), NULL, attributes);
- }
+ && lookup_attribute_spec (get_identifier ("naked"))
+ && lookup_attribute ("noipa", attributes) == NULL)
+ attributes = tree_cons (get_identifier ("noipa"), NULL, attributes);
/* A "noipa" function attribute implies "noinline", "noclone" and "no_icf"
for those targets that support it. */
@@ -1366,6 +1358,83 @@ comp_type_attributes (const_tree type1, const_tree type2)
return targetm.comp_type_attributes (type1, type2);
}
+/* PREDICATE acts as a function of type:
+
+ (const_tree attr, const attribute_spec *as) -> bool
+
+ where ATTR is an attribute and AS is its possibly-null specification.
+ Return a list of every attribute in attribute list ATTRS for which
+ PREDICATE is true. Return ATTRS itself if PREDICATE returns true
+ for every attribute. */
+
+template<typename Predicate>
+tree
+remove_attributes_matching (tree attrs, Predicate predicate)
+{
+ tree new_attrs = NULL_TREE;
+ tree *ptr = &new_attrs;
+ const_tree start = attrs;
+ for (const_tree attr = attrs; attr; attr = TREE_CHAIN (attr))
+ {
+ tree name = get_attribute_name (attr);
+ const attribute_spec *as = lookup_attribute_spec (name);
+ const_tree end;
+ if (!predicate (attr, as))
+ end = attr;
+ else if (start == attrs)
+ continue;
+ else
+ end = TREE_CHAIN (attr);
+
+ for (; start != end; start = TREE_CHAIN (start))
+ {
+ *ptr = tree_cons (TREE_PURPOSE (start),
+ TREE_VALUE (start), NULL_TREE);
+ TREE_CHAIN (*ptr) = NULL_TREE;
+ ptr = &TREE_CHAIN (*ptr);
+ }
+ start = TREE_CHAIN (attr);
+ }
+ gcc_assert (!start || start == attrs);
+ return start ? attrs : new_attrs;
+}
+
+/* If VALUE is true, return the subset of ATTRS that affect type identity,
+ otherwise return the subset of ATTRS that don't affect type identity. */
+
+tree
+affects_type_identity_attributes (tree attrs, bool value)
+{
+ auto predicate = [value](const_tree, const attribute_spec *as) -> bool
+ {
+ return bool (as && as->affects_type_identity) == value;
+ };
+ return remove_attributes_matching (attrs, predicate);
+}
+
+/* Remove attributes that affect type identity from ATTRS unless the
+ same attributes occur in OK_ATTRS. */
+
+tree
+restrict_type_identity_attributes_to (tree attrs, tree ok_attrs)
+{
+ auto predicate = [ok_attrs](const_tree attr,
+ const attribute_spec *as) -> bool
+ {
+ if (!as || !as->affects_type_identity)
+ return true;
+
+ for (tree ok_attr = lookup_attribute (as->name, ok_attrs);
+ ok_attr;
+ ok_attr = lookup_attribute (as->name, TREE_CHAIN (ok_attr)))
+ if (simple_cst_equal (TREE_VALUE (ok_attr), TREE_VALUE (attr)) == 1)
+ return true;
+
+ return false;
+ };
+ return remove_attributes_matching (attrs, predicate);
+}
+
/* Return a type like TTYPE except that its TYPE_ATTRIBUTE
is ATTRIBUTE.
@@ -2049,14 +2118,14 @@ init_attr_rdwr_indices (rdwr_map *rwm, tree attrs)
/* The (optional) list of VLA bounds. */
tree vblist = TREE_CHAIN (mode);
- if (vblist)
- vblist = TREE_VALUE (vblist);
-
mode = TREE_VALUE (mode);
if (TREE_CODE (mode) != STRING_CST)
continue;
gcc_assert (TREE_CODE (mode) == STRING_CST);
+ if (vblist)
+ vblist = nreverse (copy_list (TREE_VALUE (vblist)));
+
for (const char *m = TREE_STRING_POINTER (mode); *m; )
{
attr_access acc = { };
@@ -2231,11 +2300,18 @@ attr_access::to_external_string () const
unsigned
attr_access::vla_bounds (unsigned *nunspec) const
{
+ unsigned nbounds = 0;
*nunspec = 0;
- for (const char* p = strrchr (str, ']'); p && *p != '['; --p)
- if (*p == '*')
- ++*nunspec;
- return list_length (size);
+ /* STR points to the beginning of the specified string for the current
+ argument that may be followed by the string for the next argument. */
+ for (const char* p = strchr (str, ']'); p && *p != '['; --p)
+ {
+ if (*p == '*')
+ ++*nunspec;
+ else if (*p == '$')
+ ++nbounds;
+ }
+ return nbounds;
}
/* Reset front end-specific attribute access data from ATTRS.
@@ -2311,7 +2387,8 @@ attr_access::array_as_string (tree type) const
const char *p = end;
for ( ; p != str && *p-- != ']'; );
if (*p == '$')
- index_type = build_index_type (TREE_VALUE (size));
+ /* SIZE may have been cleared. Use it with care. */
+ index_type = build_index_type (size ? TREE_VALUE (size) : size);
}
else if (minsize)
index_type = build_index_type (size_int (minsize - 1));