From b6f86387bc37999314bedc84c7c6e81cf2aa5dcc Mon Sep 17 00:00:00 2001 From: jason Date: Fri, 27 Apr 2018 15:00:53 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@259712 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 9 +++++++++ gcc/cp/cvt.c | 8 +++++--- gcc/cp/typeck.c | 28 +++++++++++++++++++++------- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 149262c4786..9fd52669e97 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2018-04-27 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. + 2018-04-27 Nathan Sidwell * typeck.c (convert_ptrmem): Move local var decls to initialization. diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index a3735a1cffe..0f045e2ab12 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -601,14 +601,16 @@ cp_fold_convert (tree type, tree expr) 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); diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 24a206a2511..19db3154e81 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -3042,6 +3042,17 @@ build_ptrmemfunc_access_expr (tree ptrmem, tree member_name) 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 @@ -8511,7 +8522,7 @@ build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p, { 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); } @@ -8531,12 +8542,15 @@ build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p, /* 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); } -- 2.11.4.GIT