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

Owner: Nobody
Requestors: joshuamy [at] gmail.com
Cc:
AdminCc:

Operating System: (no value)
PatchStatus: (no value)
Severity: low
Type: unknown
Perl Version: (no value)
Fixed In:
  • 5.28.1
  • 5.29.1



Date: Fri, 13 Jul 2018 13:24:05 +1000
Subject: index() optimisation in when clause fails
From: Joshua <joshuamy [...] gmail.com>
To: perlbug [...] perl.org
Download (untitled) / with headers
text/plain 4.2k
Perl 5.28 introduced a index() optimisation when comparing to -1 (or indirectly, eg. >= 0).

When this optimisation is triggered in a `when` clause, it warns, eg.

    use v5.28;
    use warnings;
    no warnings 'experimental::smartmatch';

    my $s ='foo';

    given ($s) {
        when ( index($s, 'f') > -1 ) { say "Contains 'f'" }
    }

This gives the warning: Argument "foo" isn't numeric in smart match. Due to the failure it never enters the block. The same problem does not trigger inside an if clause.

Current work-around is to force numeric evaluation, ie.

    when ( 0 + index($s, 'f') > -1 ) { ... }

This is a regression, issue does not occur under 5.26.

-----------------------------------------------------------------
---
Flags:
    category=core
    severity=low
---
Site configuration information for perl 5.28.0:

Configured by joshua at Tue Jul 10 10:15:19 AEST 2018.

Summary of my perl5 (revision 5 version 28 subversion 0) configuration:
  
  Platform:
    osname=linux
    osvers=2.6.32-696.23.1.el6.x86_64
    archname=x86_64-linux-multi
    uname='linux spawn 2.6.32-696.23.1.el6.x86_64 #1 smp tue mar 13 22:44:18 utc 2018 x86_64 x86_64 x86_64 gnulinux '
    config_args='-Dprefix=/usr/tools/plenv/versions/5.28.0 -de -Dversiononly -Duseshrplib -Dusemultiplicity -Dotherlibdirs=/usr/tools/lib/perl5 -A'eval:scriptdir=/usr/tools/plenv/versions/5.28.0/bin''
    hint=recommended
    useposix=true
    d_sigaction=define
    useithreads=undef
    usemultiplicity=define
    use64bitint=define
    use64bitall=define
    uselongdouble=undef
    usemymalloc=n
    default_inc_excludes_dot=define
    bincompat5005=undef
  Compiler:
    cc='cc'
    ccflags ='-fwrapv -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2'
    optimize='-O2'
    cppflags='-fwrapv -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
    ccversion=''
    gccversion='4.4.7 20120313 (Red Hat 4.4.7-18)'
    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 -L/usr/local/lib'
    libpth=/usr/local/lib /usr/lib /lib/../lib64 /usr/lib/../lib64 /lib /lib64 /usr/lib64 /usr/local/lib64
    libs=-lpthread -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc
    perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
    libc=libc-2.12.so
    so=so
    useshrplib=true
    libperl=libperl.so
    gnulibc_version='2.12'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs
    dlext=so
    d_dlsymun=undef
    ccdlflags='-Wl,-E -Wl,-rpath,/usr/tools/plenv/versions/5.28.0/lib/perl5/5.28.0/x86_64-linux-multi/CORE'
    cccdlflags='-fPIC'
    lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector'

Locally applied patches:
    Devel::PatchPerl 1.52

---
@INC for perl 5.28.0:
    /usr/tools/lib/perl5
    /usr/tools/plenv/versions/5.28.0/lib/perl5/site_perl/5.28.0/x86_64-linux-multi
    /usr/tools/plenv/versions/5.28.0/lib/perl5/site_perl/5.28.0
    /usr/tools/plenv/versions/5.28.0/lib/perl5/5.28.0/x86_64-linux-multi
    /usr/tools/plenv/versions/5.28.0/lib/perl5/5.28.0
    /usr/tools/lib/perl5

---
Environment for perl 5.28.0:
    HOME=/home/joshua
    LANG=en_US.UTF-8
    LANGUAGE (unset)
    LD_LIBRARY_PATH=/usr/local/lib
    LOGDIR (unset)
    PATH=/usr/tools/plenv/versions/5.28.0/bin:/usr/tools/plenv/libexec:/usr/tools/plenv/plugins/perl-build/bin:/usr/tools/plenv/plugins/plenv-update/bin:/usr/tools/luaenv/shims:/usr/tools/luaenv/bin:/usr/tools/rbenv/shims:/usr/tools/rbenv/bin:/usr/tools/pyenv/shims:/usr/tools/pyenv/bin:/usr/tools/plenv/shims:/usr/tools/plenv/bin:/usr/tools/perl6/bin:/usr/tools/perl6/share/perl6/site/bin:/usr/tools/smalltalk/bin:/usr/tools/postgres/bin:/usr/tools/tmux/bin:/usr/tools/nim/bin:/usr/tools/vim/bin:/usr/tools/bin:/usr/local/bin:/bin:/usr/bin:/home/joshua/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/joshua/bin
    PERL5LIB=/usr/tools/lib/perl5
    PERLDOC_PAGER=less -+C -E
    PERL_BADLANG (unset)
    SHELL=/bin/zsh

To: perl5-porters [...] perl.org
Subject: Re: [perl #133368] index() optimisation in when clause fails
Date: Sat, 14 Jul 2018 11:08:12 +0100
From: Dave Mitchell <davem [...] iabyn.com>
Download (untitled) / with headers
text/plain 1.8k
On Thu, Jul 12, 2018 at 08:24:27PM -0700, Joshua (via RT) wrote: Show quoted text
> Perl 5.28 introduced a index() optimisation when comparing to -1 (or > indirectly, eg. >= 0). > > When this optimisation is triggered in a `when` clause, it warns, eg. > > use v5.28; > use warnings; > no warnings 'experimental::smartmatch'; > > my $s ='foo'; > > given ($s) { > when ( index($s, 'f') > -1 ) { say "Contains 'f'" } > } > > This gives the warning: Argument "foo" isn't numeric in smart match. Due to > the failure it never enters the block. The same problem does not trigger > inside an if clause.
Now fixed in blead with the following. A good candidate for backporting to 5.28.x. commit 6b877bbd2c071b3e0659fab552a74dc2ff7e08fb Author: David Mitchell <davem@iabyn.com> AuthorDate: Sat Jul 14 10:47:04 2018 +0100 Commit: David Mitchell <davem@iabyn.com> CommitDate: Sat Jul 14 10:59:25 2018 +0100 treat when(index() > -1) as a boolean expression RT #133368 when(X) is normally compiled as when($_ ~~ X) *except* when X appears to be a boolean expression, in which case it's used directly. 5.28.0 introduced an optimisation whereby comparisons involving index like index(...) != -1 eliminated the comparison, and pp_index() returned a boolean value directly. This defeated the 'look for a boolean op' mechanism, and so when(index(...) != -1) and similar were being incorrectly compiled as when($_ ~~ (index(...) != -1)) -- "But Sidley Park is already a picture, and a most amiable picture too. The slopes are green and gentle. The trees are companionably grouped at intervals that show them to advantage. The rill is a serpentine ribbon unwound from the lake peaceably contained by meadows on which the right amount of sheep are tastefully arranged." -- Lady Croom, "Arcadia"
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 181b
This was fixed in blead by commit 6b877bbd2c071b3e0659fab552a74dc2ff7e08fb, and back-ported to 5.28.1 by commit 9fcae9f15ece3ecae8ea65355fc7b66fad0b8e31. Awaiting release in 5.30.0.
Download (untitled) / with headers
text/plain 313b
Thank you for filing this report. You have helped make Perl better. With the release today of Perl 5.30.0, this and 160 other issues have been resolved. Perl 5.30.0 may be downloaded via: https://metacpan.org/release/XSAWYERX/perl-5.30.0 If you find that the problem persists, feel free to reopen this ticket.


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