Mailing List Archive

void context flipflop behaves inconsistently
This is a bug report for perl from zefram@fysh.org,
generated with the help of perlbug 1.44 running under perl 5.37.10.


-----------------------------------------------------------------
<!--[Please describe your issue here]-->

Putting a flip\/flop construct into void context\, twice\:

```
$ perl -le 'sub { !print(1)..!print(2); 1 }->(); [sub { !print(3)..!print(4); 1 }->()]'
1
3
4
```

Although both flip\/flop constructs are statically in void context\, and
both operands of both constructs always evaluate to false\, they\'re
behaving differently in respect of which operands they evaluate\. The
difference is the context in which the subroutines containing them are
called\, something that should have no effect\.

The problem is that the flagging of the constructs for
statically\-determined void context is done incompletely\. Each
construct has three significant ops in addition to the operand ops\:
range\, flip\, and flop\. At runtime all three ops need to agree on what
context the construct is in\, or at least on whether it\'s list
context\, so that they can consistently behave as either the range
operator \(in list context\) or the flip\/flop operator \(in scalar or
void context\)\. When the construct is statically put into list or
scalar context\, all three ops get flagged identically\. But when
statically put into void context\, only the flop op gets flagged\, and
so the range and flip ops think they\'re in dynamically\-determined
context\.

So in the test case above\, the sub called in void context gets the
correct behaviour\, consistently operating as the flip\/flop operator\.
The sub called in list context gets a mixture of behaviours\, with the
range and flip ops doing their part for a range operator \(hence
evaluating both operands\)\, and the flop op doing its part of the
flip\/flop operator\. This actually breaks stack discipline\, because
the flop op is expecting one operand on the stack rather than two\, but
because it\'s in void context the messed up stack contents are
immediately discarded\. Some other erroneous behaviour is visible by
using more complex operand expressions and sequences of calls that vary
the calling context\.

<!--[Please do not change anything below this line]-->
<!------------------------------------------------------------------- -->


---
**Flags**
- category=core
- severity=low
---
**Perl configuration**
```
This perlbug was built using Perl 5.32.1 - Fri Sep 24 16:10:58 UTC 2021
It is being executed now by Perl 5.37.10 - Tue Mar 21 14:35:23 GMT 2023.

Site configuration information for perl 5.37.10:

Configured by zefram at Tue Mar 21 14:35:23 GMT 2023.

Summary of my perl5 (revision 5 version 37 subversion 10) configuration:

Platform:
osname=linux
osvers=5.10.0-21-amd64
archname=x86_64-linux-thread-multi
uname='linux barba.rous.org 5.10.0-21-amd64 #1 smp debian 5.10.162-1 (2023-01-21) x86_64 gnulinux '
config_args='-des -Dprefix=/home/zefram/usr/perl/perl_install/perl-5.37.10-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
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='10.2.1 20210110'
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/x86_64-linux-gnu /usr/lib /lib/x86_64-linux-gnu /lib
libs=-lpthread -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc
perllibs=-lpthread -ldl -lm -lcrypt -lutil -lc
libc=libc-2.31.so
so=so
useshrplib=true
libperl=libperl.so
gnulibc_version='2.31'
Dynamic Linking:
dlsrc=dl_dlopen.xs
dlext=so
d_dlsymun=undef
ccdlflags='-Wl,-E -Wl,-rpath,/home/zefram/usr/perl/perl_install/perl-5.37.10-i64-f52/lib/5.37.10/x86_64-linux-thread-multi/CORE'
cccdlflags='-fPIC'
lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector-strong'


---
@INC for perl 5.37.10:
/home/zefram/usr/perl/perl_install/perl-5.37.10-i64-f52/lib/site_perl/5.37.10/x86_64-linux-thread-multi
/home/zefram/usr/perl/perl_install/perl-5.37.10-i64-f52/lib/site_perl/5.37.10
/home/zefram/usr/perl/perl_install/perl-5.37.10-i64-f52/lib/5.37.10/x86_64-linux-thread-multi
/home/zefram/usr/perl/perl_install/perl-5.37.10-i64-f52/lib/5.37.10

---
Environment for perl 5.37.10:
HOME=/home/zefram
LANG (unset)
LANGUAGE (unset)
LD_LIBRARY_PATH (unset)
LOGDIR (unset)
PATH=/home/zefram/usr/perl/perl_install/perl-5.37.10-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
PERL_BADLANG (unset)
SHELL=/usr/bin/zsh
```