Skip to content

m// resets $_[0] when sub is called from s///e #23362

Closed as not planned
Closed as not planned
@DabeDotCom

Description

@DabeDotCom

Description
Yes, this is contrived, but say I have something like: my $line = "123"; $line =~ s/ (.*) / foo($1) /e;

i.e., Assign $line, then substitute its contents with the results of foo(...)

Now let's say foo() looks like:

sub foo {
    die "Not A Whole Number" unless $_[0] =~ /^\d+$/;   # Guard

    # Else...
    my $num = shift;    # or my ($num, $arg, $platypus) = @_; or whatever...
    warn "Doing fancy stuff with num=$num\n";
    999 - $num;   # Super Fancy Stuff...
}

When called, Perl aliases the first argument — in this case, the $1 capture from the s///e regex — to the first element of @_. Then, the regex in the guard matches, and since it has no captures, it clears $1... But that's the same $1 that's aliased in $_[0], so now the first element of our argument list becomes undef... «sad»

Steps to Reproduce

perl -E 'sub foo {               $_[0] }; say "OK" =~ s/(.*)/ foo($1) /er'     # OKAY
perl -E 'sub foo {          m//; $_[0] }; say "OK" =~ s/(.*)/ foo($1) /er'     # FAIL!
perl -E 'sub foo {          m//; $_[0] }; say "OK" =~ s/(.*)/ foo("$1") /er'   # OKAY
perl -E 'sub foo {          m//; $_[0] }; say "OK" =~ s/(.*)/ foo( my $x = $1 ) /er'  # OKAY
perl -E 'sub foo {          m//; $_[0] }; say "OK" =~ s/(.*)/ $_ = $1; foo($_) /er'   # OKAY
perl -E 'sub foo (_) {      m//; $_[0] }; say "OK" =~ s/(.*)/ $_ = $1; foo     /er'   # OKAY
perl -E 'sub foo { @_ = @_; m//; $_[0] }; say "OK" =~ s/(.*)/ foo($1) /er'     # 😒 OK
perl -E 'sub foo {          m//; $_[0] }; say foo("OK")'   # OKAY, not in s///e

Also:

docker run --rm -it perl:5.40.2 perl -E 'sub foo { m//; $_[0] }; say "OK" =~ s/(.*)/ foo($1) /er'   # FAIL!

Expected behavior
I would expect @_ to receive a copy of $1 (et al) with pass-by-value semantics, not by-reference (especially since it's non-modifiable, anyway...)

Perl configuration
Stock /usr/bin/perl on MacOS 15.5 Sequoia

Summary of my perl5 (revision 5 version 34 subversion 1) configuration:
   
  Platform:
    osname=darwin
    osvers=24.0
    archname=darwin-thread-multi-2level
    uname='darwin ln86f.p1s.plx.sd.apple.com 24.0 darwin kernel version 23.0.0: thu feb 1 13:18:34 pst 2024; root:xnu-10002.1.11.100.4~1development_x86_64 x86_64 '
    config_args='-ds -e -Dprefix=/usr -Dccflags=-g  -pipe  -Dldflags= -Dman3ext=3pm -Duseithreads -Duseshrplib -Dinc_version_list=none -Dcc=cc'
    hint=recommended
    useposix=true
    d_sigaction=define
    useithreads=define
    usemultiplicity=define
    use64bitint=define
    use64bitall=define
    uselongdouble=undef
    usemymalloc=n
    default_inc_excludes_dot=define
  Compiler:
    cc='cc'
    ccflags =' -g -pipe -fno-strict-aliasing -fstack-protector-strong -DPERL_USE_SAFE_PUTENV'
    optimize='-Os'
    cppflags='-g -pipe -fno-strict-aliasing -fstack-protector-strong'
    ccversion=''
    gccversion='Apple LLVM 17.0.0 (clang-1700.0.13.5) [+internal-os]'
    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'
    libpth=/AppleInternal/Library/BuildRoots/1c8f7852-1ca9-11f0-b28b-226177e5bb69/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.5.Internal.sdk/usr/local/lib /AppleInternal/Library/BuildRoots/1c8f7852-1ca9-11f0-b28b-226177e5bb69/Applications/Xcode.app/Contents/Developer/Toolchains/OSX15.5.xctoolchain/usr/lib/clang/17/lib /AppleInternal/Library/BuildRoots/1c8f7852-1ca9-11f0-b28b-226177e5bb69/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.5.Internal.sdk/usr/lib /AppleInternal/Library/BuildRoots/1c8f7852-1ca9-11f0-b28b-226177e5bb69/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib /usr/lib /usr/local/lib
    libs= 
    perllibs=
    libc=
    so=dylib
    useshrplib=true
    libperl=libperl.dylib
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dlopen.xs
    dlext=bundle
    d_dlsymun=undef
    ccdlflags=' '
    cccdlflags=' '
    lddlflags=' -bundle -undefined dynamic_lookup -fstack-protector-strong'


Characteristics of this binary (from libperl): 
  Compile-time options:
    HAS_TIMES
    MULTIPLICITY
    PERLIO_LAYERS
    PERL_COPY_ON_WRITE
    PERL_DONT_CREATE_GVSV
    PERL_IMPLICIT_CONTEXT
    PERL_MALLOC_WRAP
    PERL_OP_PARENT
    PERL_PRESERVE_IVUV
    PERL_USE_SAFE_PUTENV
    USE_64_BIT_ALL
    USE_64_BIT_INT
    USE_ITHREADS
    USE_LARGE_FILES
    USE_LOCALE
    USE_LOCALE_COLLATE
    USE_LOCALE_CTYPE
    USE_LOCALE_NUMERIC
    USE_LOCALE_TIME
    USE_PERLIO
    USE_PERL_ATOF
    USE_REENTRANT_API
    USE_THREAD_SAFE_LOCALE
  Locally applied patches:
    /Library/Perl/Updates/<version> comes before system perl directories
    installprivlib and installarchlib points to the Updates directory
  Built under darwin
  Compiled at Apr 18 2025 20:20:39
  @INC:
    /Library/Perl/5.34/darwin-thread-multi-2level
    /Library/Perl/5.34
    /Network/Library/Perl/5.34/darwin-thread-multi-2level
    /Network/Library/Perl/5.34
    /Library/Perl/Updates/5.34.1/darwin-thread-multi-2level
    /Library/Perl/Updates/5.34.1
    /System/Library/Perl/5.34/darwin-thread-multi-2level
    /System/Library/Perl/5.34
    /System/Library/Perl/Extras/5.34/darwin-thread-multi-2level
    /System/Library/Perl/Extras/5.34

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions