On 10/23/19 6:35 PM, Jakub Jelinek wrote:
Hi!
For middle-end pointer conversions are useless, which means the gimplifier
can change the type of the value being gimplified.
gimplify_call_expr is careful about this and remembers the fnptrtype early
before gimplification and
else
/* Remember the original function type. */
CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
CALL_EXPR_FN (*expr_p));
it at the end if needed, but my cp_gimplify_expr changes didn't do that
(and unfortunately got backported to 9.x already).
The following patch fixes it similarly to what gimplify_call_expr uses.
I haven't changed gimplify_to_rvalue to do that, as it is quite specific to
the CALL_EXPR_FN, while there is just one caller right now, if more are
added, most likely they won't need such behavior or it might be even
harmful, because the NOP_EXPR then is not is_gimple_val.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk and 9.3?
OK.
2019-10-23 Jakub Jelinek <ja...@redhat.com>
PR c++/92201
* cp-gimplify.c (cp_gimplify_expr): If gimplify_to_rvalue changes the
function pointer type, re-add cast to the original one.
* g++.dg/other/pr92201.C: New test.
--- gcc/cp/cp-gimplify.c.jj 2019-10-18 00:16:09.905545389 +0200
+++ gcc/cp/cp-gimplify.c 2019-10-23 20:49:30.255410883 +0200
@@ -838,11 +838,17 @@ cp_gimplify_expr (tree *expr_p, gimple_s
&& CALL_EXPR_FN (*expr_p)
&& cp_get_callee_fndecl_nofold (*expr_p) == NULL_TREE)
{
+ tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
enum gimplify_status t
= gimplify_to_rvalue (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
is_gimple_call_addr);
if (t == GS_ERROR)
ret = GS_ERROR;
+ /* GIMPLE considers most pointer conversion useless, but for
+ calls we actually care about the exact function pointer type. */
+ else if (TREE_TYPE (CALL_EXPR_FN (*expr_p)) != fnptrtype)
+ CALL_EXPR_FN (*expr_p)
+ = build1 (NOP_EXPR, fnptrtype, CALL_EXPR_FN (*expr_p));
}
if (!CALL_EXPR_FN (*expr_p))
/* Internal function call. */;
--- gcc/testsuite/g++.dg/other/pr92201.C.jj 2019-10-23 20:59:41.375139038
+0200
+++ gcc/testsuite/g++.dg/other/pr92201.C 2019-10-23 20:58:33.068175381
+0200
@@ -0,0 +1,7 @@
+// PR c++/92201
+
+int
+foo (void (*p) ())
+{
+ return (*reinterpret_cast<int (*)()> (p)) ();
+}
Jakub