aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2018-04-27 11:00:53 -0400
committerJason Merrill <jason@gcc.gnu.org>2018-04-27 11:00:53 -0400
commit6d0e87b25ee21493d4f47bb39aee3e2d33cb08d9 (patch)
treedf50d3a40a9ba75887fd0d79d59d06b3940f8dc9 /gcc
parent4bdc2738ce61b5f380930f670709ed9e9cd7cf2a (diff)
downloadgcc-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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/cvt.c8
-rw-r--r--gcc/cp/typeck.c28
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);
}