aboutsummaryrefslogtreecommitdiff
path: root/gcc/attribs.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2018-02-15 11:54:12 -0500
committerJason Merrill <jason@gcc.gnu.org>2018-02-15 11:54:12 -0500
commit5cedffbc3249a3f14ea57567a5f089d502cad8d3 (patch)
tree1478e723a54aba8f641e33069ff42a56ef1984c1 /gcc/attribs.c
parente72f7e3e763c1091c0007a851f252f13310f6255 (diff)
downloadgcc-5cedffbc3249a3f14ea57567a5f089d502cad8d3.zip
gcc-5cedffbc3249a3f14ea57567a5f089d502cad8d3.tar.gz
gcc-5cedffbc3249a3f14ea57567a5f089d502cad8d3.tar.bz2
PR c++/84314 - ICE with templates and fastcall attribute.
* attribs.c (build_type_attribute_qual_variant): Don't clobber TYPE_CANONICAL on an existing type. From-SVN: r257695
Diffstat (limited to 'gcc/attribs.c')
-rw-r--r--gcc/attribs.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/gcc/attribs.c b/gcc/attribs.c
index 140863b..caa30b9 100644
--- a/gcc/attribs.c
+++ b/gcc/attribs.c
@@ -1143,19 +1143,29 @@ build_type_attribute_qual_variant (tree otype, tree attribute, int quals)
ttype = (lang_hooks.types.copy_lang_qualifiers
(ttype, TYPE_MAIN_VARIANT (otype)));
- ntype = build_distinct_type_copy (ttype);
+ tree dtype = ntype = build_distinct_type_copy (ttype);
TYPE_ATTRIBUTES (ntype) = attribute;
hashval_t hash = type_hash_canon_hash (ntype);
ntype = type_hash_canon (hash, ntype);
- /* If the target-dependent attributes make NTYPE different from
- its canonical type, we will need to use structural equality
- checks for this type. */
- if (TYPE_STRUCTURAL_EQUALITY_P (ttype)
- || !comp_type_attributes (ntype, ttype))
- SET_TYPE_STRUCTURAL_EQUALITY (ntype);
+ if (ntype != dtype)
+ /* This variant was already in the hash table, don't mess with
+ TYPE_CANONICAL. */;
+ else if (TYPE_STRUCTURAL_EQUALITY_P (ttype)
+ || !comp_type_attributes (ntype, ttype))
+ {
+ /* If the target-dependent attributes make NTYPE different from
+ its canonical type, we will need to use structural equality
+ checks for this type.
+
+ But make sure we don't get here for stripping attributes from a
+ type; the no-attribute type might not need structural comparison,
+ and it should have been in the hash table already. */
+ gcc_assert (attribute);
+ SET_TYPE_STRUCTURAL_EQUALITY (ntype);
+ }
else if (TYPE_CANONICAL (ntype) == ntype)
TYPE_CANONICAL (ntype) = TYPE_CANONICAL (ttype);