Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.85k stars 523 forks source link

Misparsed nested assignment of expression to lexical #1169

Closed p5pRT closed 20 years ago

p5pRT commented 24 years ago

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

Searchable as RT2137$

p5pRT commented 24 years ago

From jtobey@ne.mediaone.net

This is a bug report for perl from jtobey@​feynman.localnet\, generated with the help of perlbug 1.27 running under perl v5.5.650.


The following program unexpectedly prints "undefined"​:

  my ($x\, $y);   $z = 1;   $x = $y = 1 + $z;   print "undefined" unless defined $y;

This behavior affects Perl 5.00563 and 5.5.560\, but not 5.00503. It happens only if $x and $y are both declared with "my"\, and the right side of the assignment is a compound expression (not just "1" or "$z").

The deparsed output is interesting​:

  $ perl -MO=Deparse -e 'my ($x\, $y); $x = $y = 1 + $z;'   my($x\, $y);   $x = 1 + $z;   -e syntax OK

-John



Site configuration information for perl v5.5.650​:

Configured by jtobey at Fri Feb 11 02​:13​:31 EST 2000.

Summary of my perl5 (revision 5.0 version 5 subversion 650) configuration​:   Platform​:   osname=linux\, osvers=2.2.14pre16\, archname=i686-linux   uname='linux feynman 2.2.14pre16 #1 thu dec 23 19​:33​:36 est 1999 i686 unknown '   config_args='-Dcc=gcc -Dprefix=/usr/local -Doptimize=-g -O2 -ders'   hint=recommended\, useposix=true\, d_sigaction=define   usethreads=undef use5005threads=undef useithreads=undef   usesocks=undef useperlio=undef d_sfio=undef   use64bits=undef uselargefiles=define usemultiplicity=undef   Compiler​:   cc='gcc'\, optimize='-g -O2'\, gccversion=2.95.2 19991109 (Debian GNU/Linux)   cppflags='-Dbool=char -DHAS_BOOL -DDEBUGGING -fno-strict-aliasing -I/usr/local/include'   ccflags ='-Dbool=char -DHAS_BOOL -DDEBUGGING -fno-strict-aliasing -I/usr/local/include'   stdchar='char'\, d_stdstdio=define\, usevfork=false   intsize=4\, longsize=4\, ptrsize=4\, doublesize=8   d_longlong=define\, longlongsize=8\, d_longdbl=define\, longdblsize=12   alignbytes=4\, usemymalloc=n\, prototype=define   Linker and Libraries​:   ld='gcc'\, ldflags =' -L/usr/local/lib'   libpth=/usr/local/lib /lib /usr/lib   libs=-lnsl -lndbm -lgdbm -ldbm -ldb -ldl -lm -lc -lposix -lcrypt   libc=/lib/libc-2.1.2.so\, so=so\, useshrplib=false\, libperl=libperl.a   Dynamic Linking​:   dlsrc=dl_dlopen.xs\, dlext=so\, d_dlsymun=undef\, ccdlflags='-rdynamic'   cccdlflags='-fpic'\, lddlflags='-shared -L/usr/local/lib'

Locally applied patches​:  


@​INC for perl v5.5.650​:   /usr/local/lib/perl5/5.5.650/i686-linux   /usr/local/lib/perl5/5.5.650   /usr/local/lib/perl5/site_perl/5.5.650/i686-linux   /usr/local/lib/perl5/site_perl/5.5.650   /usr/local/lib/perl5/site_perl/5.005/i686-linux   /usr/local/lib/perl5/site_perl/5.005   /usr/local/lib/perl5/site_perl   .


Environment for perl v5.5.650​:   HOME=/home/jtobey   LANG (unset)   LANGUAGE (unset)   LD_LIBRARY_PATH (unset)   LOGDIR (unset)   PATH=/home/jtobey/bin​:/jtobey/local/bin​:/usr/local/bin​:/bin​:/usr/bin​:/usr/X11R6/bin​:/usr/local/sbin​:/usr/sbin​:/sbin   PERL_BADLANG (unset)   SHELL=/bin/bash

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

John Tobey writes​:

my \($x\, $y\);
$z = 1;
$x = $y = 1 \+ $z;
print "undefined" unless defined $y;

This behavior affects Perl 5.00563 and 5.5.560\, but not 5.00503. It happens only if $x and $y are both declared with "my"\, and the right side of the assignment is a compound expression (not just "1" or "$z").

The deparsed output is interesting​:

$ perl \-MO=Deparse \-e 'my \($x\, $y\); $x = $y = 1 \+ $z;'
my\($x\, $y\);
$x = 1 \+ $z;
\-e syntax OK

Oups\, the optimizer was removing the assignment *twice* for the same operation.

Sorry\, Ilya

Inline Patch ```diff --- ./t/op/lex_assign.t~ Sun Jan 2 15:44:26 2000 +++ ./t/op/lex_assign.t Fri Feb 11 17:46:25 2000 @@ -24,7 +24,7 @@ sub subb {"in s"} @INPUT = ; @simple_input = grep /^\s*\w+\s*\$\w+\s*[#\n]/, @INPUT; -print "1..", (9 + @INPUT + @simple_input), "\n"; +print "1..", (10 + @INPUT + @simple_input), "\n"; $ord = 0; sub wrn {"@_"} @@ -95,6 +95,18 @@ print "ok $ord\n"; print "ok $ord\n"; } + +# Chains of assignments + +my ($l1, $l2, $l3, $l4); +my $zzzz = 12; +$zzz1 = $l1 = $l2 = $zzz2 = $l3 = $l4 = 1 + $zzzz; + +$ord++; +print "# $zzz1 = $l1 = $l2 = $zzz2 = $l3 = $l4 = 13\nnot " + unless $zzz1 == 13 and $zzz2 == 13 and $l1 == 13 + and $l2 == 13 and $l3 == 13 and $l4 == 13; +print "ok $ord\n"; for (@INPUT) { $ord++; --- ./op.c~ Tue Feb 1 15:29:47 2000 +++ ./op.c Fri Feb 11 17:28:53 2000 @@ -5694,7 +5694,9 @@ Perl_ck_sassign(pTHX_ OP *o) OP *kid = cLISTOPo->op_first; /* has a disposable target? */ if ((PL_opargs[kid->op_type] & OA_TARGLEX) - && !(kid->op_flags & OPf_STACKED)) + && !(kid->op_flags & OPf_STACKED) + /* Cannot steal the second time! */ + && !(kid->op_private & OPpTARGET_MY)) { OP *kkid = kid->op_sibling; ```