Skip Menu |
Report information
Id: 132584
Status: open
Priority: 0/
Queue: perl5

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

Operating System: (no value)
PatchStatus: (no value)
Severity: low
Type: core
Perl Version: 5.27.6
Fixed In: (no value)



Subject: in-place sort retains blessedness
From: zefram [...] fysh.org
Date: Fri, 15 Dec 2017 08:00:54 +0000
To: perlbug [...] perl.org
CC: zefram [...] fysh.org
Download (untitled) / with headers
text/plain 4.1k
This is a bug report for perl from zefram@fysh.org, generated with the help of perlbug 1.41 running under perl 5.27.6. ----------------------------------------------------------------- [Please describe your issue here] Suppose I have an array of which an element is blessed. (That is, the element scalar itself is blessed; the element is not a reference to a blessed thing.) List assignment of the array to itself would of course drop the blessedness, by virtue of copying the blessed scalar's value to a fresh, unblessed scalar. But if I assign the result of a sort on the array back to the array, blessedness remains: $ perl -lwe '@a = qw(a b c); bless(\$a[1]); print ref(\$a[1]); @a = sort @a; print ref(\$a[1]); @a = ((), sort @a); print ref(\$a[1])' main main SCALAR Obviously this is another fault of the in-place sort optimisation, similar to the recently-rectified treatment of weak references. [Please do not change anything below this line] ----------------------------------------------------------------- --- Flags: category=core severity=low --- Site configuration information for perl 5.27.6: Configured by zefram at Tue Nov 21 05:42:59 GMT 2017. Summary of my perl5 (revision 5 version 27 subversion 6) 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.43-2+deb8u2 (2017-06-26) x86_64 gnulinux ' config_args='-des -Dprefix=/home/zefram/usr/perl/perl_install/perl-5.27.6-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.27.6-i64-f52/lib/5.27.6/x86_64-linux-thread-multi/CORE' cccdlflags='-fPIC' lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector-strong' --- @INC for perl 5.27.6: /home/zefram/usr/perl/perl_install/perl-5.27.6-i64-f52/lib/site_perl/5.27.6/x86_64-linux-thread-multi /home/zefram/usr/perl/perl_install/perl-5.27.6-i64-f52/lib/site_perl/5.27.6 /home/zefram/usr/perl/perl_install/perl-5.27.6-i64-f52/lib/5.27.6/x86_64-linux-thread-multi /home/zefram/usr/perl/perl_install/perl-5.27.6-i64-f52/lib/5.27.6 --- Environment for perl 5.27.6: HOME=/home/zefram LANG (unset) LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/home/zefram/usr/perl/perl_install/perl-5.27.6-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
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 1.1k
On Fri, 15 Dec 2017 00:01:36 -0800, zefram@fysh.org wrote: Show quoted text
> > This is a bug report for perl from zefram@fysh.org, > generated with the help of perlbug 1.41 running under perl 5.27.6. > > > ----------------------------------------------------------------- > [Please describe your issue here] > > Suppose I have an array of which an element is blessed. (That is, the > element scalar itself is blessed; the element is not a reference to a > blessed thing.) List assignment of the array to itself would of > course > drop the blessedness, by virtue of copying the blessed scalar's value > to a fresh, unblessed scalar. But if I assign the result of a sort on > the array back to the array, blessedness remains: > > $ perl -lwe '@a = qw(a b c); bless(\$a[1]); print ref(\$a[1]); @a = > sort @a; print ref(\$a[1]); @a = ((), sort @a); print ref(\$a[1])' > main > main > SCALAR > > Obviously this is another fault of the in-place sort optimisation, > similar to the recently-rectified treatment of weak references. >
We already have the infrastructure to unbless-in-place. See S_curse in sv.c. That could be used in fixing this. -- Father Chrysostomos
Date: Fri, 15 Dec 2017 22:37:42 +0000
To: perl5-porters [...] perl.org
Subject: Re: [perl #132584] in-place sort retains blessedness
From: Zefram <zefram [...] fysh.org>
Download (untitled) / with headers
text/plain 667b
Father Chrysostomos via RT wrote: Show quoted text
>We already have the infrastructure to unbless-in-place.
Doing that would not be correct, because of DESTROY methods. S_curse() does call the DESTROY method; it would be wrong not to call it at all. But it is inevitably called on a reference to the actual blessed object, which it may mutate. One cannot rely on the object still containing its former value after being cursed. The DESTROY method also has the opportunity to store another reference to the object somewhere, so one can't rely on still having the only reference to it. To avoid mutation, sort will have to use the newSVsv() slow path for blessed scalars. -zefram


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