Fix: empty @_ when calling empty-proto subs without parens
Graham Barr [Fri, 3 Jan 1997 21:29:04 +0000 (21:29 +0000)]
Graham Barr wrote:

<snip>

> OK, so I thought that prototypes in Socket.pm (which is probably
> a good idea) could help here, but... guess what the following
> script outputs
>
> sub fred ()
> {
>  warn join(" ",@_);
> }
>
> fred;
> @_ = qw(a b c);
> &fred;
> fred;
> __END__
>
> It outputs ...
>
> Warning: something's wrong at yyy line 3.
> a b c at yyy line 3.
> a b c at yyy line 3.
>
> OK I can belive the second one as it has the & style call (which
> the pod states overrides prototypes) but I was very amazed at
> the last call.
>
> Is this a bug ?? I think so as the pod suggests that a sub defined
> as
>
> sub mytime ();
>
> and a statement such as
>
>   mytime +2;
>
> will by the same as
>
>  mytime() + 2
>
> but this is not the case, it seems it would be
>
>  &mytime(@_) + 2
>

OK, here is a patch which fixes this. It requires a modification
to perly.y and perly.c (I cannot re-generate perly.c here
but it is a simple fix)

it chamges the output of the above script to

Warning: something's wrong at yyy line 3.
Warning: something's wrong at yyy line 3.
a b c at yyy line 3.

perly.c
perly.y

diff --git a/perly.c b/perly.c
index 6ff2f58..50a28ff 100644 (file)
--- a/perly.c
+++ b/perly.c
@@ -2097,7 +2097,7 @@ case 141:
 break;
 case 142:
 #line 531 "perly.y"
-{ yyval.opval = newUNOP(OP_ENTERSUB, 0,
+{ yyval.opval = newUNOP(OP_ENTERSUB, OPf_STACKED,
                                scalar(yyvsp[0].opval)); }
 break;
 case 143:
diff --git a/perly.y b/perly.y
index a281dff..30ae76f 100644 (file)
--- a/perly.y
+++ b/perly.y
@@ -528,7 +528,7 @@ term        :       term ASSIGNOP term
        |       FUNC0 '(' ')'
                        { $$ = newOP($1, 0); }
        |       FUNC0SUB
-                       { $$ = newUNOP(OP_ENTERSUB, 0,
+                       { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
                                scalar($1)); }
        |       FUNC1 '(' ')'
                        { $$ = newOP($1, OPf_SPECIAL); }