+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>
* typeck.c (convert_ptrmem): Move local var decls to initialization.
tree conv;
if (TREE_TYPE (expr) == type)
conv = expr;
- else if (TREE_CODE (expr) == PTRMEM_CST
- || (TREE_CODE (expr) == CONSTRUCTOR
- && TYPE_PTRMEMFUNC_P (type)))
+ else if (TREE_CODE (expr) == PTRMEM_CST)
{
/* Avoid wrapping a PTRMEM_CST in NOP_EXPR. */
conv = copy_node (expr);
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
{
conv = fold_convert (type, expr);
tree ptrmem_type;
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
build_class_member_access_expr. It does not work to use that
routine directly because it expects the object to be of class
{
if (same_type_p (to_type, pfn_type))
return pfn;
- else if (integer_zerop (n))
+ else if (integer_zerop (n) && TREE_CODE (pfn) != CONSTRUCTOR)
return build_reinterpret_cast (to_type, pfn,
complain);
}
/* Just adjust the DELTA field. */
gcc_assert (same_type_ignoring_top_level_qualifiers_p
(TREE_TYPE (delta), ptrdiff_type_node));
- if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta)
- n = cp_build_binary_op (input_location,
- LSHIFT_EXPR, n, integer_one_node,
- complain);
- delta = cp_build_binary_op (input_location,
- PLUS_EXPR, delta, n, complain);
+ if (!integer_zerop (n))
+ {
+ if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta)
+ n = cp_build_binary_op (input_location,
+ LSHIFT_EXPR, n, integer_one_node,
+ complain);
+ delta = cp_build_binary_op (input_location,
+ PLUS_EXPR, delta, n, complain);
+ }
return build_ptrmemfunc1 (to_type, delta, npfn);
}