diff options
author | Ian Lance Taylor <iant@golang.org> | 2021-09-13 10:37:49 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2021-09-13 10:37:49 -0700 |
commit | e252b51ccde010cbd2a146485d8045103cd99533 (patch) | |
tree | e060f101cdc32bf5e520de8e5275db9d4236b74c /gcc/attribs.c | |
parent | f10c7c4596dda99d2ee872c995ae4aeda65adbdf (diff) | |
parent | 104c05c5284b7822d770ee51a7d91946c7e56d50 (diff) | |
download | gcc-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.c | 125 |
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)); |