On 2017-07-23, at 4:14 PM, John David Anglin wrote:

> Perl_custom_op_get_field (my_perl=0x1e3008, o=0x5aee38, field=XOPe_xop_peep)
>    at op.c:14853
> 14853       if (!he && PL_custom_op_names &&
> (gdb)
> 14879           if(field == XOPe_xop_ptr) {
> (gdb)
> 14902                   switch(field) {
> (gdb)
> 14884                   switch(field) {

Gcc optimizes the two switch statements in Perl_custom_op_get_field() into one. 
 It appears the
address of xop gets lost when xop points to xop_null.

The attached patch seems to work around the problem compiling op.c.  This would 
appear to be
a generic gcc bug.

I also removed the hppa optimization hack for compiling op.c.  It no longer 
seems to work as the
last -O option is -O2.  Adrian's optimization work around changed the last 
optimization to -O0.

Maybe the patch will also fix the sh build.

Dave
--
John David Anglin       dave.ang...@bell.net


Index: perl-5.26.0/op.c
===================================================================
--- perl-5.26.0.orig/op.c
+++ perl-5.26.0/op.c
@@ -14832,6 +14832,7 @@ Perl_custom_op_get_field(pTHX_ const OP
     SV *keysv;
     HE *he = NULL;
     XOP *xop;
+    XOPRETANY any;
 
     static const XOP xop_null = { 0, 0, 0, 0, 0 };
 
@@ -14874,58 +14875,37 @@ Perl_custom_op_get_field(pTHX_ const OP
        else
            xop = INT2PTR(XOP *, SvIV(HeVAL(he)));
     }
-    {
-       XOPRETANY any;
-       if(field == XOPe_xop_ptr) {
-           any.xop_ptr = xop;
-       } else {
-           const U32 flags = XopFLAGS(xop);
-           if(flags & field) {
-               switch(field) {
-               case XOPe_xop_name:
-                   any.xop_name = xop->xop_name;
-                   break;
-               case XOPe_xop_desc:
-                   any.xop_desc = xop->xop_desc;
-                   break;
-               case XOPe_xop_class:
-                   any.xop_class = xop->xop_class;
-                   break;
-               case XOPe_xop_peep:
-                   any.xop_peep = xop->xop_peep;
-                   break;
-               default:
-                   NOT_REACHED; /* NOTREACHED */
-                   break;
-               }
-           } else {
-               switch(field) {
-               case XOPe_xop_name:
-                   any.xop_name = XOPd_xop_name;
-                   break;
-               case XOPe_xop_desc:
-                   any.xop_desc = XOPd_xop_desc;
-                   break;
-               case XOPe_xop_class:
-                   any.xop_class = XOPd_xop_class;
-                   break;
-               case XOPe_xop_peep:
-                   any.xop_peep = XOPd_xop_peep;
-                   break;
-               default:
-                   NOT_REACHED; /* NOTREACHED */
-                   break;
-               }
-           }
+
+    if(field == XOPe_xop_ptr) {
+        any.xop_ptr = xop;
+    } else {
+        const U32 flags = XopFLAGS(xop);
+        switch(field) {
+        case XOPe_xop_name:
+            any.xop_name = (flags & field) ? xop->xop_name : XOPd_xop_name;
+            break;
+        case XOPe_xop_desc:
+            any.xop_desc = (flags & field) ? xop->xop_desc : XOPd_xop_desc;
+            break;
+        case XOPe_xop_class:
+            any.xop_class = (flags & field) ? xop->xop_class : XOPd_xop_class;
+            break;
+        case XOPe_xop_peep:
+            any.xop_peep = (flags & field) ? xop->xop_peep : XOPd_xop_peep;
+            break;
+        default:
+            NOT_REACHED; /* NOTREACHED */
+            break;
        }
-        /* On some platforms (HP-UX, IA64) gcc emits a warning for this 
function:
-         * op.c: In function 'Perl_custom_op_get_field':
-         * op.c:...: warning: 'any.xop_name' may be used uninitialized in this 
function [-Wmaybe-uninitialized]
-         * This is because on those platforms (with -DEBUGGING) NOT_REACHED
-         * expands to assert(0), which expands to ((0) ? (void)0 :
-         * __assert(...)), and gcc doesn't know that __assert can never 
return. */
-       return any;
     }
+
+    /* On some platforms (HP-UX, IA64) gcc emits a warning for this function:
+     * op.c: In function 'Perl_custom_op_get_field':
+     * op.c:...: warning: 'any.xop_name' may be used uninitialized in this 
function [-Wmaybe-uninitialized]
+     * This is because on those platforms (with -DEBUGGING) NOT_REACHED
+     * expands to assert(0), which expands to ((0) ? (void)0 :
+     * __assert(...)), and gcc doesn't know that __assert can never return. */
+    return any;
 }
 
 /*

Reply via email to