From: Jason Merrill Date: Wed, 13 Apr 2016 14:33:53 +0000 (-0400) Subject: re PR c++/70615 (ICE on valid code at -O1 and above on x86_64-linux-gnu in add_expr... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9d4099343ab2eec82ddb4faff48b6e04fed5519c;p=gcc.git re PR c++/70615 (ICE on valid code at -O1 and above on x86_64-linux-gnu in add_expr, at tree.c:7870) PR c++/70615 * cp-gimplify.c (cp_genericize_r): Expand PTRMEM_CST here. (cp_gimplify_expr): Not here. From-SVN: r234940 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5696eea0e7e..71538ab64f1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2016-04-13 Jason Merrill + + PR c++/70615 + * cp-gimplify.c (cp_genericize_r): Expand PTRMEM_CST here. + (cp_gimplify_expr): Not here. + 2016-04-12 Patrick Palka PR c++/70610 diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 13f7b7ccbd7..30ac660906d 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -576,11 +576,6 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) switch (code) { - case PTRMEM_CST: - *expr_p = cplus_expand_constant (*expr_p); - ret = GS_OK; - break; - case AGGR_INIT_EXPR: simplify_aggr_init_expr (expr_p); ret = GS_OK; @@ -1388,6 +1383,13 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) || TREE_CODE (stmt) == OMP_SIMD || TREE_CODE (stmt) == OMP_DISTRIBUTE) genericize_omp_for_stmt (stmt_p, walk_subtrees, data); + else if (TREE_CODE (stmt) == PTRMEM_CST) + { + /* By the time we get here we're handing off to the back end, so we don't + need or want to preserve PTRMEM_CST anymore. */ + *stmt_p = cplus_expand_constant (stmt); + *walk_subtrees = 0; + } else if ((flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_VPTR)) && !wtd->no_sanitize_p) diff --git a/gcc/testsuite/g++.dg/opt/ptrmem7.C b/gcc/testsuite/g++.dg/opt/ptrmem7.C new file mode 100644 index 00000000000..7d9e9b17d3d --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/ptrmem7.C @@ -0,0 +1,31 @@ +// PR c++/70615 +// { dg-options -O } + +struct C +{ + virtual void f () {} +}; + +struct B +{ + virtual ~B () {} +}; + +class D : public B, public C +{ +public: + D () {} +}; + +typedef void (C::*FP) (); +typedef void (D::*D_f) (); + +int +main () +{ + D *d = new D (); + C *c = d; + const FP fptr = (FP) & D::f; + (d->*(D_f) fptr) (); + return 0; +}