Skip Menu |
Report information
Id: 132141
Status: resolved
Priority: 0/
Queue: perl5

Owner: Nobody
Requestors: zefram [at] fysh.org
Cc:
AdminCc:

Operating System: (no value)
PatchStatus: (no value)
Severity: medium
Type: core
Perl Version: 5.27.8
Fixed In: (no value)



CC: zefram [...] fysh.org
To: perlbug [...] perl.org
From: zefram [...] fysh.org
Subject: lvalue return broken in signature
Date: Thu, 21 Sep 2017 21:38:04 +0100
Download (untitled) / with headers
text/plain 5.4k
This is a bug report for perl from zefram@fysh.org, generated with the help of perlbug 1.40 running under perl 5.26.0. ----------------------------------------------------------------- [Please describe your issue here] Mixing signatures with lvalue subs: $ perl5.26.0 -Mexperimental=signatures -lwe 'our @a = qw(wibble wobble wabble); sub foo ($i = return substr($a[0], -1, 1)) :lvalue { return substr($a[$i], 1, 1); } print "@a"; foo(2) = "u"; print "@a"; foo() = "y"; print "@a"' wibble wobble wabble wibble wobble wubble Can't return a temporary from lvalue subroutine at -e line 1. Observe that returning a substr() lvalue works fine in the main block of the subroutine body, but it fails when done from a default expression in the signature. Returning from inside the signature is legal, and works fine for non-lvalue subs. The cause is that the substr op gets a flag set at compile time to indicate whether it needs to yield an lvalue, and when it's the child of a return op that flag gets set depending on the CvLVALUE flag, and with attributes being in their present grammatical location that flag doesn't get set early enough to affect compilation of code in the signature. The equivalent code works just fine on the original version of signatures: $ perl5.20.0 -Mexperimental=signatures -lwe 'our @a = qw(wibble wobble wabble); sub foo :lvalue ($i = return substr($a[0], -1, 1)) { return substr($a[$i], 1, 1); } print "@a"; foo(2) = "u"; print "@a"; foo() = "y"; print "@a"' wibble wobble wabble wibble wobble wubble wibbly wobble wubble There are also other ops affected by lvalueness, which will be broken in much the same way. At a quick look, I think the other built-in attributes don't affect anything in this manner, but I'm not entirely sure. Non-built-in attributes aren't applied to a sub early enough for this ordering issue to matter. Of some relevance, last year when we were discussing the possibilities for suppressing @_ where arguments are being accessed in better ways, I suggested using an attribute to control it and processing attributes earlier to let @_ uses be compile-time errors, but then observed that the grammatical swap breaks that plan. See <https://www.nntp.perl.org/group/perl.perl5.porters/2016/04/msg235925.html>. [Please do not change anything below this line] ----------------------------------------------------------------- --- Flags: category=core severity=medium --- Site configuration information for perl 5.26.0: Configured by zefram at Thu Jun 1 13:52:05 BST 2017. Summary of my perl5 (revision 5 version 26 subversion 0) configuration: Platform: osname=linux osvers=3.16.0-4-amd64 archname=x86_64-linux-thread-multi uname='linux barba.rous.org 3.16.0-4-amd64 #1 smp debian 3.16.7-ckt11-1+deb8u6 (2015-11-09) x86_64 gnulinux ' config_args='-des -Dprefix=/home/zefram/usr/perl/perl_install/perl-5.26.0-i64-f52 -Duselargefiles -Dusethreads -Uafs -Ud_csh -Uusesfio -Uusenm -Duseshrplib -Dusedevel -Uversiononly -Ui_db' hint=recommended useposix=true d_sigaction=define useithreads=define usemultiplicity=define use64bitint=define use64bitall=define uselongdouble=undef usemymalloc=n default_inc_excludes_dot=define bincompat5005=undef Compiler: cc='cc' ccflags ='-D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2' optimize='-O2' cppflags='-D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include' ccversion='' gccversion='4.9.2' gccosandvers='' intsize=4 longsize=8 ptrsize=8 doublesize=8 byteorder=12345678 doublekind=3 d_longlong=define longlongsize=8 d_longdbl=define longdblsize=16 longdblkind=3 ivtype='long' ivsize=8 nvtype='double' nvsize=8 Off_t='off_t' lseeksize=8 alignbytes=8 prototype=define Linker and Libraries: ld='cc' ldflags =' -fstack-protector-strong -L/usr/local/lib' libpth=/usr/local/lib /usr/lib/gcc/x86_64-linux-gnu/4.9/include-fixed /usr/include/x86_64-linux-gnu /usr/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib libs=-lpthread -lnsl -ldb -ldl -lm -lcrypt -lutil -lc perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc libc=libc-2.19.so so=so useshrplib=true libperl=libperl.so gnulibc_version='2.19' Dynamic Linking: dlsrc=dl_dlopen.xs dlext=so d_dlsymun=undef ccdlflags='-Wl,-E -Wl,-rpath,/home/zefram/usr/perl/perl_install/perl-5.26.0-i64-f52/lib/5.26.0/x86_64-linux-thread-multi/CORE' cccdlflags='-fPIC' lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector-strong' --- @INC for perl 5.26.0: /home/zefram/usr/perl/perl_install/perl-5.26.0-i64-f52/lib/site_perl/5.26.0/x86_64-linux-thread-multi /home/zefram/usr/perl/perl_install/perl-5.26.0-i64-f52/lib/site_perl/5.26.0 /home/zefram/usr/perl/perl_install/perl-5.26.0-i64-f52/lib/5.26.0/x86_64-linux-thread-multi /home/zefram/usr/perl/perl_install/perl-5.26.0-i64-f52/lib/5.26.0 --- Environment for perl 5.26.0: HOME=/home/zefram LANG (unset) LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/home/zefram/usr/perl/perl_install/perl-5.26.0-i64-f52/bin:/home/zefram/usr/perl/util:/home/zefram/pub/x86_64-unknown-linux-gnu/bin:/home/zefram/pub/common/bin:/usr/bin:/bin:/usr/local/bin:/usr/games PERLDOC=-oman PERL_BADLANG (unset) SHELL=/usr/bin/zsh
Date: Tue, 5 Jun 2018 15:20:27 +0100
From: Dave Mitchell <davem [...] iabyn.com>
Subject: Re: [perl #132141] lvalue return broken in signature
To: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 621b
On Thu, Sep 21, 2017 at 01:38:17PM -0700, Zefram wrote: Show quoted text
> Mixing signatures with lvalue subs: > > $ perl5.26.0 -Mexperimental=signatures -lwe 'our @a = qw(wibble wobble wabble); sub foo ($i = return substr($a[0], -1, 1)) :lvalue { return substr($a[$i], 1, 1); } print "@a"; foo(2) = "u"; print "@a"; foo() = "y"; print "@a"' > wibble wobble wabble > wibble wobble wubble > Can't return a temporary from lvalue subroutine at -e line 1.
Fixed in 5.27.8. Resolving. -- The Enterprise successfully ferries an alien VIP from one place to another without serious incident. -- Things That Never Happen in "Star Trek" #7


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org