From: Jason Merrill Date: Fri, 8 Sep 2017 22:39:17 +0000 (-0400) Subject: PR c++/70029 - ICE with ref-qualifier and -flto X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=27c825c5cca3243f293aee29a4abeb22242d4d2b;p=gcc.git PR c++/70029 - ICE with ref-qualifier and -flto PR c++/70029 - ICE with ref-qualifier and -flto gcc/ * langhooks.h (struct lang_hooks_for_types): Add copy_lang_qualifiers. * attribs.c (build_type_attribute_qual_variant): Use it. * langhooks-def.h (LANG_HOOKS_COPY_LANG_QUALIFIERS): Default to NULL. (LANG_HOOKS_FOR_TYPES_INITIALIZER): Use it. * tree.c (verify_type): Re-enable TYPE_CANONICAL main variant check. gcc/cp/ * tree.c (cxx_copy_lang_qualifiers): New. * cp-tree.h: Declare it. * cp-objcp-common.h: Define LANG_HOOKS_COPY_LANG_QUALIFIERS. From-SVN: r251911 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e4163aa5f16..b9b04565d28 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2017-09-08 Jason Merrill + + PR c++/70029 - ICE with ref-qualifier and -flto + * langhooks.h (struct lang_hooks_for_types): Add + copy_lang_qualifiers. + * attribs.c (build_type_attribute_qual_variant): Use it. + * langhooks-def.h (LANG_HOOKS_COPY_LANG_QUALIFIERS): Default to + NULL. + (LANG_HOOKS_FOR_TYPES_INITIALIZER): Use it. + * tree.c (verify_type): Re-enable TYPE_CANONICAL main variant check. + 2017-09-08 Eric Botcazou PR target/81988 diff --git a/gcc/attribs.c b/gcc/attribs.c index faa0649e190..b8f58a74596 100644 --- a/gcc/attribs.c +++ b/gcc/attribs.c @@ -959,8 +959,9 @@ build_decl_attribute_variant (tree ddecl, tree attribute) Record such modified types already made so we don't make duplicates. */ tree -build_type_attribute_qual_variant (tree ttype, tree attribute, int quals) +build_type_attribute_qual_variant (tree otype, tree attribute, int quals) { + tree ttype = otype; if (! attribute_list_equal (TYPE_ATTRIBUTES (ttype), attribute)) { tree ntype; @@ -983,6 +984,11 @@ build_type_attribute_qual_variant (tree ttype, tree attribute, int quals) } ttype = build_qualified_type (ttype, TYPE_UNQUALIFIED); + if (lang_hooks.types.copy_lang_qualifiers + && otype != TYPE_MAIN_VARIANT (otype)) + ttype = (lang_hooks.types.copy_lang_qualifiers + (ttype, TYPE_MAIN_VARIANT (otype))); + ntype = build_distinct_type_copy (ttype); TYPE_ATTRIBUTES (ntype) = attribute; @@ -1000,6 +1006,9 @@ build_type_attribute_qual_variant (tree ttype, tree attribute, int quals) TYPE_CANONICAL (ntype) = TYPE_CANONICAL (ttype); ttype = build_qualified_type (ntype, quals); + if (lang_hooks.types.copy_lang_qualifiers + && otype != TYPE_MAIN_VARIANT (otype)) + ttype = lang_hooks.types.copy_lang_qualifiers (ttype, otype); } else if (TYPE_QUALS (ttype) != quals) ttype = build_qualified_type (ttype, quals); diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6c4a31d7850..730a2dace19 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2017-09-08 Jason Merrill + + PR c++/70029 - ICE with ref-qualifier and -flto + * tree.c (cxx_copy_lang_qualifiers): New. + * cp-tree.h: Declare it. + * cp-objcp-common.h: Define LANG_HOOKS_COPY_LANG_QUALIFIERS. + 2017-09-06 Jason Merrill PR c++/82053 - ICE with default argument in lambda in template diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h index 10fcdf324fc..3e4cc9c5d4c 100644 --- a/gcc/cp/cp-objcp-common.h +++ b/gcc/cp/cp-objcp-common.h @@ -99,6 +99,8 @@ extern void cp_register_dumps (gcc::dump_manager *); #define LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE cxx_builtin_function_ext_scope #undef LANG_HOOKS_TYPE_HASH_EQ #define LANG_HOOKS_TYPE_HASH_EQ cxx_type_hash_eq +#undef LANG_HOOKS_COPY_LANG_QUALIFIERS +#define LANG_HOOKS_COPY_LANG_QUALIFIERS cxx_copy_lang_qualifiers #undef LANG_HOOKS_MISSING_NORETURN_OK_P #define LANG_HOOKS_MISSING_NORETURN_OK_P cp_missing_noreturn_ok_p #undef LANG_HOOKS_BLOCK_MAY_FALLTHRU diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index a0e31d3d19d..a57de335f1a 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6963,6 +6963,7 @@ extern tree convert_bitfield_to_declared_type (tree); extern tree cp_save_expr (tree); extern bool cast_valid_in_integral_constant_expression_p (tree); extern bool cxx_type_hash_eq (const_tree, const_tree); +extern tree cxx_copy_lang_qualifiers (const_tree, const_tree); extern void cxx_print_statistics (void); extern bool maybe_warn_zero_as_null_pointer_constant (tree, location_t); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 12c31fb8342..f387f38639b 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -4626,6 +4626,21 @@ cxx_type_hash_eq (const_tree typea, const_tree typeb) TYPE_RAISES_EXCEPTIONS (typeb), ce_exact); } +/* Copy the language-specific type variant modifiers from TYPEB to TYPEA. For + C++, these are the exception-specifier and ref-qualifier. */ + +tree +cxx_copy_lang_qualifiers (const_tree typea, const_tree typeb) +{ + tree type = CONST_CAST_TREE (typea); + if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE) + { + type = build_exception_variant (type, TYPE_RAISES_EXCEPTIONS (typeb)); + type = build_ref_qualified_type (type, type_memfn_rqual (typeb)); + } + return type; +} + /* Apply FUNC to all language-specific sub-trees of TP in a pre-order traversal. Called from walk_tree. */ diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h index ea2006ccec5..61b081bd7cc 100644 --- a/gcc/langhooks-def.h +++ b/gcc/langhooks-def.h @@ -186,6 +186,7 @@ extern tree lhd_unit_size_without_reusable_padding (tree); lhd_omp_firstprivatize_type_sizes #define LANG_HOOKS_OMP_MAPPABLE_TYPE lhd_omp_mappable_type #define LANG_HOOKS_TYPE_HASH_EQ NULL +#define LANG_HOOKS_COPY_LANG_QUALIFIERS NULL #define LANG_HOOKS_GET_ARRAY_DESCR_INFO NULL #define LANG_HOOKS_GET_SUBRANGE_BOUNDS NULL #define LANG_HOOKS_GET_TYPE_BIAS NULL @@ -211,6 +212,7 @@ extern tree lhd_unit_size_without_reusable_padding (tree); LANG_HOOKS_OMP_FIRSTPRIVATIZE_TYPE_SIZES, \ LANG_HOOKS_OMP_MAPPABLE_TYPE, \ LANG_HOOKS_TYPE_HASH_EQ, \ + LANG_HOOKS_COPY_LANG_QUALIFIERS, \ LANG_HOOKS_GET_ARRAY_DESCR_INFO, \ LANG_HOOKS_GET_SUBRANGE_BOUNDS, \ LANG_HOOKS_GET_TYPE_BIAS, \ diff --git a/gcc/langhooks.h b/gcc/langhooks.h index 88f6f71b559..b0c9829a6cd 100644 --- a/gcc/langhooks.h +++ b/gcc/langhooks.h @@ -123,6 +123,10 @@ struct lang_hooks_for_types FUNCTION_TYPE or METHOD_TYPE. */ bool (*type_hash_eq) (const_tree, const_tree); + /* If non-NULL, return TYPE1 with any language-specific modifiers copied from + TYPE2. */ + tree (*copy_lang_qualifiers) (const_tree, const_tree); + /* Return TRUE if TYPE uses a hidden descriptor and fills in information for the debugger about the array bounds, strides, etc. */ bool (*get_array_descr_info) (const_tree, struct array_descr_info *); diff --git a/gcc/testsuite/g++.dg/lto/pr70029_0.C b/gcc/testsuite/g++.dg/lto/pr70029_0.C new file mode 100644 index 00000000000..9c8c31cf68b --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr70029_0.C @@ -0,0 +1,10 @@ +// PR c++/70029 +// { dg-lto-do assemble } + +struct A +{ + A(); + int foo() && __attribute__ ((__warn_unused_result__)) { return 0; } +}; + +A a; diff --git a/gcc/tree.c b/gcc/tree.c index 7a70eb7760d..721330a4a49 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -13220,9 +13220,7 @@ verify_type (const_tree t) debug_tree (ct); error_found = true; } - /* FIXME: this is violated by the C++ FE as discussed in PR70029, when - FUNCTION_*_QUALIFIED flags are set. */ - if (0 && TYPE_MAIN_VARIANT (t) == t && ct && TYPE_MAIN_VARIANT (ct) != ct) + if (TYPE_MAIN_VARIANT (t) == t && ct && TYPE_MAIN_VARIANT (ct) != ct) { error ("TYPE_CANONICAL of main variant is not main variant"); debug_tree (ct);