diff options
author | Jason Merrill <jason@redhat.com> | 2018-04-27 11:00:53 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2018-04-27 11:00:53 -0400 |
commit | 6d0e87b25ee21493d4f47bb39aee3e2d33cb08d9 (patch) | |
tree | df50d3a40a9ba75887fd0d79d59d06b3940f8dc9 | |
parent | 4bdc2738ce61b5f380930f670709ed9e9cd7cf2a (diff) | |
download | gcc-6d0e87b25ee21493d4f47bb39aee3e2d33cb08d9.zip gcc-6d0e87b25ee21493d4f47bb39aee3e2d33cb08d9.tar.gz gcc-6d0e87b25ee21493d4f47bb39aee3e2d33cb08d9.tar.bz2 |
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
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 8 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 28 |
3 files changed, 35 insertions, 10 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 149262c..9fd5266 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +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. diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index a3735a1..0f045e2 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 24a206a..19db315 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); } |