Commit 27c825c5 by Jason Merrill Committed by Jason Merrill

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
parent b2c5d6f1
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> 2017-09-08 Eric Botcazou <ebotcazou@adacore.com>
PR target/81988 PR target/81988
......
...@@ -959,8 +959,9 @@ build_decl_attribute_variant (tree ddecl, tree attribute) ...@@ -959,8 +959,9 @@ build_decl_attribute_variant (tree ddecl, tree attribute)
Record such modified types already made so we don't make duplicates. */ Record such modified types already made so we don't make duplicates. */
tree 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)) if (! attribute_list_equal (TYPE_ATTRIBUTES (ttype), attribute))
{ {
tree ntype; tree ntype;
...@@ -983,6 +984,11 @@ build_type_attribute_qual_variant (tree ttype, tree attribute, int quals) ...@@ -983,6 +984,11 @@ build_type_attribute_qual_variant (tree ttype, tree attribute, int quals)
} }
ttype = build_qualified_type (ttype, TYPE_UNQUALIFIED); 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); ntype = build_distinct_type_copy (ttype);
TYPE_ATTRIBUTES (ntype) = attribute; TYPE_ATTRIBUTES (ntype) = attribute;
...@@ -1000,6 +1006,9 @@ build_type_attribute_qual_variant (tree ttype, tree attribute, int quals) ...@@ -1000,6 +1006,9 @@ build_type_attribute_qual_variant (tree ttype, tree attribute, int quals)
TYPE_CANONICAL (ntype) = TYPE_CANONICAL (ttype); TYPE_CANONICAL (ntype) = TYPE_CANONICAL (ttype);
ttype = build_qualified_type (ntype, quals); 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) else if (TYPE_QUALS (ttype) != quals)
ttype = build_qualified_type (ttype, quals); ttype = build_qualified_type (ttype, quals);
......
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> 2017-09-06 Jason Merrill <jason@redhat.com>
PR c++/82053 - ICE with default argument in lambda in template PR c++/82053 - ICE with default argument in lambda in template
......
...@@ -99,6 +99,8 @@ extern void cp_register_dumps (gcc::dump_manager *); ...@@ -99,6 +99,8 @@ extern void cp_register_dumps (gcc::dump_manager *);
#define LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE cxx_builtin_function_ext_scope #define LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE cxx_builtin_function_ext_scope
#undef LANG_HOOKS_TYPE_HASH_EQ #undef LANG_HOOKS_TYPE_HASH_EQ
#define LANG_HOOKS_TYPE_HASH_EQ cxx_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 #undef LANG_HOOKS_MISSING_NORETURN_OK_P
#define LANG_HOOKS_MISSING_NORETURN_OK_P cp_missing_noreturn_ok_p #define LANG_HOOKS_MISSING_NORETURN_OK_P cp_missing_noreturn_ok_p
#undef LANG_HOOKS_BLOCK_MAY_FALLTHRU #undef LANG_HOOKS_BLOCK_MAY_FALLTHRU
......
...@@ -6963,6 +6963,7 @@ extern tree convert_bitfield_to_declared_type (tree); ...@@ -6963,6 +6963,7 @@ extern tree convert_bitfield_to_declared_type (tree);
extern tree cp_save_expr (tree); extern tree cp_save_expr (tree);
extern bool cast_valid_in_integral_constant_expression_p (tree); extern bool cast_valid_in_integral_constant_expression_p (tree);
extern bool cxx_type_hash_eq (const_tree, const_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 void cxx_print_statistics (void);
extern bool maybe_warn_zero_as_null_pointer_constant (tree, location_t); extern bool maybe_warn_zero_as_null_pointer_constant (tree, location_t);
......
...@@ -4626,6 +4626,21 @@ cxx_type_hash_eq (const_tree typea, const_tree typeb) ...@@ -4626,6 +4626,21 @@ cxx_type_hash_eq (const_tree typea, const_tree typeb)
TYPE_RAISES_EXCEPTIONS (typeb), ce_exact); 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 /* Apply FUNC to all language-specific sub-trees of TP in a pre-order
traversal. Called from walk_tree. */ traversal. Called from walk_tree. */
......
...@@ -186,6 +186,7 @@ extern tree lhd_unit_size_without_reusable_padding (tree); ...@@ -186,6 +186,7 @@ extern tree lhd_unit_size_without_reusable_padding (tree);
lhd_omp_firstprivatize_type_sizes lhd_omp_firstprivatize_type_sizes
#define LANG_HOOKS_OMP_MAPPABLE_TYPE lhd_omp_mappable_type #define LANG_HOOKS_OMP_MAPPABLE_TYPE lhd_omp_mappable_type
#define LANG_HOOKS_TYPE_HASH_EQ NULL #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_ARRAY_DESCR_INFO NULL
#define LANG_HOOKS_GET_SUBRANGE_BOUNDS NULL #define LANG_HOOKS_GET_SUBRANGE_BOUNDS NULL
#define LANG_HOOKS_GET_TYPE_BIAS NULL #define LANG_HOOKS_GET_TYPE_BIAS NULL
...@@ -211,6 +212,7 @@ extern tree lhd_unit_size_without_reusable_padding (tree); ...@@ -211,6 +212,7 @@ extern tree lhd_unit_size_without_reusable_padding (tree);
LANG_HOOKS_OMP_FIRSTPRIVATIZE_TYPE_SIZES, \ LANG_HOOKS_OMP_FIRSTPRIVATIZE_TYPE_SIZES, \
LANG_HOOKS_OMP_MAPPABLE_TYPE, \ LANG_HOOKS_OMP_MAPPABLE_TYPE, \
LANG_HOOKS_TYPE_HASH_EQ, \ LANG_HOOKS_TYPE_HASH_EQ, \
LANG_HOOKS_COPY_LANG_QUALIFIERS, \
LANG_HOOKS_GET_ARRAY_DESCR_INFO, \ LANG_HOOKS_GET_ARRAY_DESCR_INFO, \
LANG_HOOKS_GET_SUBRANGE_BOUNDS, \ LANG_HOOKS_GET_SUBRANGE_BOUNDS, \
LANG_HOOKS_GET_TYPE_BIAS, \ LANG_HOOKS_GET_TYPE_BIAS, \
......
...@@ -123,6 +123,10 @@ struct lang_hooks_for_types ...@@ -123,6 +123,10 @@ struct lang_hooks_for_types
FUNCTION_TYPE or METHOD_TYPE. */ FUNCTION_TYPE or METHOD_TYPE. */
bool (*type_hash_eq) (const_tree, const_tree); 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 /* Return TRUE if TYPE uses a hidden descriptor and fills in information
for the debugger about the array bounds, strides, etc. */ for the debugger about the array bounds, strides, etc. */
bool (*get_array_descr_info) (const_tree, struct array_descr_info *); bool (*get_array_descr_info) (const_tree, struct array_descr_info *);
......
// 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) ...@@ -13220,9 +13220,7 @@ verify_type (const_tree t)
debug_tree (ct); debug_tree (ct);
error_found = true; error_found = true;
} }
/* FIXME: this is violated by the C++ FE as discussed in PR70029, when if (TYPE_MAIN_VARIANT (t) == t && ct && TYPE_MAIN_VARIANT (ct) != ct)
FUNCTION_*_QUALIFIED flags are set. */
if (0 && TYPE_MAIN_VARIANT (t) == t && ct && TYPE_MAIN_VARIANT (ct) != ct)
{ {
error ("TYPE_CANONICAL of main variant is not main variant"); error ("TYPE_CANONICAL of main variant is not main variant");
debug_tree (ct); debug_tree (ct);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment