Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

\$ prototype does not make a unary function #10457

Closed
p5pRT opened this issue Jun 20, 2010 · 8 comments
Closed

\$ prototype does not make a unary function #10457

p5pRT opened this issue Jun 20, 2010 · 8 comments

Comments

@p5pRT
Copy link

p5pRT commented Jun 20, 2010

Migrated from rt.perl.org#75904 (status was 'resolved')

Searchable as RT75904$

@p5pRT
Copy link
Author

p5pRT commented Jun 20, 2010

From @cpansprout

$ perl -le' sub foo($) { print "foo" }; foo $_, exit'
foo
$ perl -le' sub foo(\$) { print "foo" }; foo $_, exit'
Too many arguments for main​::foo at -e line 1, at EOF
Execution of -e aborted due to compilation errors.

So it looks as though the parser does not consider it unary, but op.c
does.


Flags​:
  category=core
  severity=low


Site configuration information for perl 5.13.1​:

Configured by sprout at Tue Jun 15 06​:25​:06 PDT 2010.

Summary of my perl5 (revision 5 version 13 subversion 1 patch
v5.13.1-196-gee84a79) configuration​:
  Snapshot of​: ee84a79
  Platform​:
  osname=darwin, osvers=10.0.0, archname=darwin-2level
  uname='darwin pint.local 10.0.0 darwin kernel version 10.0.0​: fri
jul 31 22​:47​:34 pdt 2009; root​:xnu-1456.1.25~1release_i386 i386 '
  config_args='-de -Dusedevel -DDEBUGGING'
  hint=recommended, useposix=true, d_sigaction=define
  useithreads=undef, usemultiplicity=undef
  useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
  use64bitint=undef, use64bitall=undef, uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='cc', ccflags ='-fno-common -DPERL_DARWIN -no-cpp-precomp -
DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/
include',
  optimize='-O3 -g',
  cppflags='-no-cpp-precomp -fno-common -DPERL_DARWIN -no-cpp-
precomp -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/
usr/local/include'
  ccversion='', gccversion='4.2.1 (Apple Inc. build 5646)',
gccosandvers=''
  intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
  d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
  ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
  alignbytes=8, prototype=define
  Linker and Libraries​:
  ld='env MACOSX_DEPLOYMENT_TARGET=10.3 cc', ldflags =' -fstack-
protector -L/usr/local/lib'
  libpth=/usr/local/lib /usr/lib
  libs=-ldbm -ldl -lm -lutil -lc
  perllibs=-ldl -lm -lutil -lc
  libc=/usr/lib/libc.dylib, so=dylib, useshrplib=false,
libperl=libperl.a
  gnulibc_version=''
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=bundle, d_dlsymun=undef, ccdlflags=' '
  cccdlflags=' ', lddlflags=' -bundle -undefined dynamic_lookup -L/
usr/local/lib -fstack-protector'

Locally applied patches​:


@​INC for perl 5.13.1​:
  /usr/local/lib/perl5/site_perl/5.13.1/darwin-2level
  /usr/local/lib/perl5/site_perl/5.13.1
  /usr/local/lib/perl5/5.13.1/darwin-2level
  /usr/local/lib/perl5/5.13.1
  /usr/local/lib/perl5/site_perl
  .


Environment for perl 5.13.1​:
  DYLD_LIBRARY_PATH (unset)
  HOME=/Users/sprout
  LANG=en_US.UTF-8
  LANGUAGE (unset)
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)
  PATH=/usr/bin​:/bin​:/usr/sbin​:/sbin​:/usr/local/bin​:/usr/X11/bin​:/
usr/local/bin
  PERL_BADLANG (unset)
  SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Jul 25, 2010

From @cpansprout

On Jun 20, 2010, at 2​:32 PM, Father Chrysostomos wrote​:

$ perl -le' sub foo($) { print "foo" }; foo $_, exit'
foo
$ perl -le' sub foo(\$) { print "foo" }; foo $_, exit'
Too many arguments for main​::foo at -e line 1, at EOF
Execution of -e aborted due to compilation errors.

So it looks as though the parser does not consider it unary, but op.c does.

This problem is worse than I thought. It applies to these prototypes as well​:

*
\sigil
\[...]
;$
;*
;\sigil
;\[...]

This means that the following functions, among others, cannot be overridden by subs that parse the same way​:

fileno (*)
chdir (;$)
close (;*)
dbmclose (\%)
tied (\[$@​%*])
pop (;\@​)

The attached patch fixes these. I hope no-one minds the space-out ‘if’ condition. I just find it *much* easier to read that way.

@p5pRT
Copy link
Author

p5pRT commented Jul 25, 2010

From @cpansprout

Inline Patch
--- blead/toke.c	2010-07-17 18:51:14.000000000 -0700
+++ blead-ref-proto/toke.c	2010-07-19 22:03:26.000000000 -0700
@@ -6493,10 +6493,27 @@ Perl_yylex(pTHX)
 			const char *proto = SvPV_const(MUTABLE_SV(cv), protolen);
 			if (!protolen)
 			    TERM(FUNC0SUB);
-			if ((*proto == '$' || *proto == '_') && proto[1] == '\0')
-			    OPERATOR(UNIOPSUB);
 			while (*proto == ';')
 			    proto++;
+			if (
+			    (
+			        (
+			            *proto == '$' || *proto == '_'
+			         || *proto == '*'
+			        )
+			     && proto[1] == '\0'
+			    )
+			 || (
+			     *proto == '\\' && proto[1] && proto[2] == '\0'
+			    )
+			)
+			    OPERATOR(UNIOPSUB);
+			if (*proto == '\\' && proto[1] == '[') {
+			    const char *p = proto + 2;
+			    while(*p && *p != ']')
+				++p;
+			    if(*p == ']' && !p[1]) OPERATOR(UNIOPSUB);
+			}
 			if (*proto == '&' && *s == '{') {
 			    if (PL_curstash)
 				sv_setpvs(PL_subname, "__ANON__");
--- blead/t/comp/proto.t	2009-11-19 08:51:40.000000000 -0800
+++ blead-ref-proto/t/comp/proto.t	2010-07-19 21:32:28.000000000 -0700
@@ -18,7 +18,7 @@ BEGIN {
 # strict
 use strict;
 
-print "1..153\n";
+print "1..160\n";
 
 my $i = 1;
 
@@ -651,3 +651,28 @@ print "ok ", $i++, "\n";
 eval 'sub bug (\[%@]) {  } my $array = [0 .. 1]; bug %$array;';
 print "not " unless $@ =~ /Not a HASH reference/;
 print "ok ", $i++, "\n";
+
+# [perl #75904]
+# Test that the following prototypes make subs parse as unary functions:
+#  * \sigil \[...] ;$ ;* ;\sigil ;\[...]
+print "not "
+ unless eval 'sub uniproto1 (*) {} uniproto1 $_, 1' or warn $@;
+print "ok ", $i++, "\n";
+print "not "
+ unless eval 'sub uniproto2 (\$) {} uniproto2 $_, 1' or warn $@;
+print "ok ", $i++, "\n";
+print "not "
+ unless eval 'sub uniproto3 (\[$%]) {} uniproto3 %_, 1' or warn $@;
+print "ok ", $i++, "\n";
+print "not "
+ unless eval 'sub uniproto4 (;$) {} uniproto4 $_, 1' or warn $@;
+print "ok ", $i++, "\n";
+print "not "
+ unless eval 'sub uniproto5 (;*) {} uniproto5 $_, 1' or warn $@;
+print "ok ", $i++, "\n";
+print "not "
+ unless eval 'sub uniproto6 (;\@) {} uniproto6 @_, 1' or warn $@;
+print "ok ", $i++, "\n";
+print "not "
+ unless eval 'sub uniproto7 (;\[$%@]) {} uniproto7 @_, 1' or warn $@;
+print "ok ", $i++, "\n";

@p5pRT
Copy link
Author

p5pRT commented Jul 27, 2010

From @rgarcia

On 25 July 2010 21​:43, Father Chrysostomos <sprout@​cpan.org> wrote​:

On Jun 20, 2010, at 2​:32 PM, Father Chrysostomos wrote​:

$ perl -le' sub foo($) { print "foo" }; foo $_, exit'
foo
$ perl -le' sub foo(\$) { print "foo" }; foo $_, exit'
Too many arguments for main​::foo at -e line 1, at EOF
Execution of -e aborted due to compilation errors.

So it looks as though the parser does not consider it unary, but op.c does.

This problem is worse than I thought. It applies to these prototypes as well​:

*
\sigil
\[...]
;$
;*
;\sigil
;\[...]

This means that the following functions, among others, cannot be overridden by subs that parse the same way​:

fileno (*)
chdir (;$)
close (;*)
dbmclose (\%)
tied (\[$@​%*])
pop (;\@​)

The attached patch fixes these. I hope no-one minds the space-out ‘if’ condition. I just find it *much* easier to read that way.

The patch looks good and the result is more consistent parsing. Also,
I believe that it's not really breaking backwards compatibility, since
it turns previous parse errors into valid constructs (right?)

Opinions ? Should I apply ?

@p5pRT
Copy link
Author

p5pRT commented Jul 27, 2010

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Jul 27, 2010

From @rafl

Rafael Garcia-Suarez <rgs@​consttype.org> writes​:

On 25 July 2010 21​:43, Father Chrysostomos <sprout@​cpan.org> wrote​:
The patch looks good and the result is more consistent parsing. Also,
I believe that it's not really breaking backwards compatibility, since
it turns previous parse errors into valid constructs (right?)

Opinions ? Should I apply ?

It also looks good to me, passes all tests, and does fix an actual
problem. I'm all for this being applied.

@p5pRT
Copy link
Author

p5pRT commented Aug 11, 2010

From @rgs

Thanks, applied to bleadperl as 649d02d

@p5pRT
Copy link
Author

p5pRT commented Aug 11, 2010

@rgs - Status changed from 'open' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant