Commit 6d0e87b2 by Jason Merrill Committed by Jason Merrill

PR c++/85545 - ICE with noexcept PMF conversion.

	* cvt.c (cp_fold_convert): Pass PMF CONSTRUCTORs to
	build_ptrmemfunc.
	* typeck.c (build_ptrmemfunc): Don't build a NOP_EXPR for zero
	adjustment.
	(build_ptrmemfunc_access_expr): Special-case CONSTRUCTORs.

From-SVN: r259712
parent 4bdc2738
2018-04-27 Jason Merrill <jason@redhat.com>
PR c++/85545 - ICE with noexcept PMF conversion.
* cvt.c (cp_fold_convert): Pass PMF CONSTRUCTORs to
build_ptrmemfunc.
* typeck.c (build_ptrmemfunc): Don't build a NOP_EXPR for zero
adjustment.
(build_ptrmemfunc_access_expr): Special-case CONSTRUCTORs.
2018-04-27 Nathan Sidwell <nathan@acm.org> 2018-04-27 Nathan Sidwell <nathan@acm.org>
* typeck.c (convert_ptrmem): Move local var decls to initialization. * typeck.c (convert_ptrmem): Move local var decls to initialization.
......
...@@ -601,14 +601,16 @@ cp_fold_convert (tree type, tree expr) ...@@ -601,14 +601,16 @@ cp_fold_convert (tree type, tree expr)
tree conv; tree conv;
if (TREE_TYPE (expr) == type) if (TREE_TYPE (expr) == type)
conv = expr; conv = expr;
else if (TREE_CODE (expr) == PTRMEM_CST else if (TREE_CODE (expr) == PTRMEM_CST)
|| (TREE_CODE (expr) == CONSTRUCTOR
&& TYPE_PTRMEMFUNC_P (type)))
{ {
/* Avoid wrapping a PTRMEM_CST in NOP_EXPR. */ /* Avoid wrapping a PTRMEM_CST in NOP_EXPR. */
conv = copy_node (expr); conv = copy_node (expr);
TREE_TYPE (conv) = type; TREE_TYPE (conv) = type;
} }
else if (TREE_CODE (expr) == CONSTRUCTOR
&& TYPE_PTRMEMFUNC_P (type))
conv = build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr,
true, false, tf_warning_or_error);
else else
{ {
conv = fold_convert (type, expr); conv = fold_convert (type, expr);
......
...@@ -3042,6 +3042,17 @@ build_ptrmemfunc_access_expr (tree ptrmem, tree member_name) ...@@ -3042,6 +3042,17 @@ build_ptrmemfunc_access_expr (tree ptrmem, tree member_name)
tree ptrmem_type; tree ptrmem_type;
tree member; tree member;
if (TREE_CODE (ptrmem) == CONSTRUCTOR)
{
unsigned int ix;
tree index, value;
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ptrmem),
ix, index, value)
if (index && DECL_P (index) && DECL_NAME (index) == member_name)
return value;
gcc_unreachable ();
}
/* This code is a stripped down version of /* This code is a stripped down version of
build_class_member_access_expr. It does not work to use that build_class_member_access_expr. It does not work to use that
routine directly because it expects the object to be of class routine directly because it expects the object to be of class
...@@ -8511,7 +8522,7 @@ build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p, ...@@ -8511,7 +8522,7 @@ build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p,
{ {
if (same_type_p (to_type, pfn_type)) if (same_type_p (to_type, pfn_type))
return pfn; return pfn;
else if (integer_zerop (n)) else if (integer_zerop (n) && TREE_CODE (pfn) != CONSTRUCTOR)
return build_reinterpret_cast (to_type, pfn, return build_reinterpret_cast (to_type, pfn,
complain); complain);
} }
...@@ -8531,12 +8542,15 @@ build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p, ...@@ -8531,12 +8542,15 @@ build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p,
/* Just adjust the DELTA field. */ /* Just adjust the DELTA field. */
gcc_assert (same_type_ignoring_top_level_qualifiers_p gcc_assert (same_type_ignoring_top_level_qualifiers_p
(TREE_TYPE (delta), ptrdiff_type_node)); (TREE_TYPE (delta), ptrdiff_type_node));
if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta) if (!integer_zerop (n))
n = cp_build_binary_op (input_location, {
LSHIFT_EXPR, n, integer_one_node, if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta)
complain); n = cp_build_binary_op (input_location,
delta = cp_build_binary_op (input_location, LSHIFT_EXPR, n, integer_one_node,
PLUS_EXPR, delta, n, complain); complain);
delta = cp_build_binary_op (input_location,
PLUS_EXPR, delta, n, complain);
}
return build_ptrmemfunc1 (to_type, delta, npfn); return build_ptrmemfunc1 (to_type, delta, npfn);
} }
......
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