diff options
author | Jason Merrill <jason@redhat.com> | 2017-09-08 18:39:17 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2017-09-08 18:39:17 -0400 |
commit | 27c825c5cca3243f293aee29a4abeb22242d4d2b (patch) | |
tree | d4c20252428e4348fc569284133594067d73b3c8 | |
parent | b2c5d6f1d2a71374bcd8277a0697490582bc03a8 (diff) | |
download | gcc-27c825c5cca3243f293aee29a4abeb22242d4d2b.zip gcc-27c825c5cca3243f293aee29a4abeb22242d4d2b.tar.gz gcc-27c825c5cca3243f293aee29a4abeb22242d4d2b.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/attribs.c | 11 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/cp-objcp-common.h | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/tree.c | 15 | ||||
-rw-r--r-- | gcc/langhooks-def.h | 2 | ||||
-rw-r--r-- | gcc/langhooks.h | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lto/pr70029_0.C | 10 | ||||
-rw-r--r-- | gcc/tree.c | 4 |
10 files changed, 63 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e4163aa..b9b0456 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2017-09-08 Jason Merrill <jason@redhat.com> + + 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 <ebotcazou@adacore.com> PR target/81988 diff --git a/gcc/attribs.c b/gcc/attribs.c index faa0649..b8f58a7 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 6c4a31d..730a2da 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2017-09-08 Jason Merrill <jason@redhat.com> + + 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 <jason@redhat.com> 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 10fcdf3..3e4cc9c 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 a0e31d3..a57de33 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 12c31fb..f387f38 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 ea2006c..61b081b 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 88f6f71..b0c9829 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 0000000..9c8c31c --- /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; @@ -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); |