Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perl -e "1for$[=0" crash #7977

Closed
p5pRT opened this issue Jun 16, 2005 · 18 comments
Closed

perl -e "1for$[=0" crash #7977

p5pRT opened this issue Jun 16, 2005 · 18 comments

Comments

@p5pRT
Copy link

p5pRT commented Jun 16, 2005

Migrated from rt.perl.org#36313 (status was 'resolved')

Searchable as RT36313$

@p5pRT
Copy link
Author

p5pRT commented Jun 16, 2005

From fox@scene.pl

This is a bug report for perl from fox@​scene.pl,
generated with the help of perlbug 1.34 running under perl v5.8.0.


perl -e "1for$[=0" causes a null pointer dereference.



Flags​:
category=core
severity=low


Site configuration information for perl v5.8.0​:

Configured by ActiveState at Mon Mar 31 00​:45​:28 2003.

Summary of my perl5 (revision 5 version 8 subversion 0) configuration​:
Platform​:
osname=MSWin32, osvers=4.0, archname=MSWin32-x86-multi-thread
uname=''
config_args='undef'
hint=recommended, useposix=true, d_sigaction=undef
usethreads=undef use5005threads=undef useithreads=define
usemultiplicity=define
useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
use64bitint=undef use64bitall=undef uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler​:
cc='cl', ccflags ='-nologo -Gf -W3 -MD -Zi -DNDEBUG -O1 -DWIN32 -D_CONSOLE
-DNO_STRICT -DHAVE_DES_FCRYPT -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS
-DUSE_PERLIO -DPERL_MSVCRT_READFIX',
optimize='-MD -Zi -DNDEBUG -O1',
cppflags='-DWIN32'
ccversion='', gccversion='', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=10
ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='__int64',
lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries​:
ld='link', ldflags ='-nologo -nodefaultlib -debug -opt​:ref,icf
-libpath​:"C​:jPerllibCORE" -machine​:x86'
libpth="D​:Program FilesMicrosoft.NETFrameworkSDKLib" "D​:Program
FilesMicrosoft.NetOdbc.Net" "C​:jPerllibCORE"
libs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib
comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib
uuid.lib wsock32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib
msvcrt.lib
perllibs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib
comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib
uuid.lib wsock32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib
msvcrt.lib
libc=msvcrt.lib, so=dll, useshrplib=yes, libperl=perl58.lib
gnulibc_version='undef'
Dynamic Linking​:
dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -debug -opt​:ref,icf
-libpath​:"C​:jPerllibCORE" -machine​:x86'

Locally applied patches​:
ACTIVEPERL_LOCAL_PATCHES_ENTRY


@​INC for perl v5.8.0​:
C​:/j/Perl/lib
C​:/j/Perl/site/lib
.


Environment for perl v5.8.0​:
HOME (unset)
LANG (unset)
LANGUAGE (unset)
LD_LIBRARY_PATH (unset)
LOGDIR (unset)
PATH=C​:WINDOWS;C​:WINDOWSCOMMAND;C​:U;C​:JAVAJDKBIN;C​:CDJGPPBIN;C​:JPERLBIN;C​:JMYSQLBIN;C​:UTEXMFMAINMIKTEXBIN;C​:UGSGS8.11BIN;C​:CCYGWINBIN;C​:WINDOWS;C​:WINDOWSCOMMAND;C​:UANTBIN
PERL_BADLANG (unset)
SHELL (unset)

@p5pRT
Copy link
Author

p5pRT commented Jun 16, 2005

From @schwern

On Thu, Jun 16, 2005 at 03​:54​:18PM -0000, Piotr Fusik wrote​:

perl -e "1for$[=0" causes a null pointer dereference.

Confirmed in 5.8.1RC3, 5.8.6 and bleadperl@​24148 on OS X 10.3

--
Michael G Schwern schwern@​pobox.com http​://www.pobox.com/~schwern
Just call me 'Moron Sugar'.
  http​://www.somethingpositive.net/sp05182002.shtml

@p5pRT
Copy link
Author

p5pRT commented Jun 16, 2005

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Jun 16, 2005

From @smpeters

On Thu, Jun 16, 2005 at 11​:17​:35AM -0700, Michael G Schwern wrote​:

On Thu, Jun 16, 2005 at 03​:54​:18PM -0000, Piotr Fusik wrote​:

perl -e "1for$[=0" causes a null pointer dereference.

Confirmed in 5.8.1RC3, 5.8.6 and bleadperl@​24148 on OS X 10.3

The attached patch prevents the coredump by die'ing instead.
I'm not sure if its the best way to fix this, but checking
to make sure a pointer isn't NULL before using it is usually
a Good Thing (tm). A tweak to the grammar might be the best
long term fix for this problem.

While trying to investigate what the valid syntax for "for"
these days, I did notice that the documentation in perlsyn.pod
and elsewhere is quite out of date.

Steve Peters
steve@​fisharerojo.org

Inline Patch
--- op.c.old    Mon Jun 13 11:52:00 2005
+++ op.c        Thu Jun 16 13:53:26 2005
@@ -3901,6 +3901,10 @@
     I32 iterflags = 0;
     I32 iterpflags = 0;

+    if (!expr) {
+        DIE(aTHX_ "\"for\" missing a conditional expression");
+    }
+
     if (sv) {
        if (sv->op_type == OP_RV2SV) {  /* symbol table variable */
            iterpflags = sv->op_private & OPpOUR_INTRO; /* for our $x () */

@p5pRT
Copy link
Author

p5pRT commented Jun 16, 2005

From @rgarcia

On 6/16/05, Steve Peters <steve@​fisharerojo.org> wrote​:

--- op.c.old Mon Jun 13 11​:52​:00 2005
+++ op.c Thu Jun 16 13​:53​:26 2005
@​@​ -3901,6 +3901,10 @​@​
I32 iterflags = 0;
I32 iterpflags = 0;

+ if (!expr) {
+ DIE(aTHX_ "\"for\" missing a conditional expression");

Surely you jest. for is used quite often to alias a variable to $_,
i.e. without a conditional expression.

However you correctly found the cause of the problem. $[ is a
pragmatic variable and assignment to it happens at compile time and is
optimized away. So expr becomes NULL.

Note that other kinds of similar code segfaults too :

$ perl -e 'if($[=0){print}'
Segmentation fault

I'd rather solve all those cases once and for all.

@p5pRT
Copy link
Author

p5pRT commented Jun 16, 2005

From @Abigail

On Thu, Jun 16, 2005 at 11​:17​:35AM -0700, Michael G Schwern wrote​:

On Thu, Jun 16, 2005 at 03​:54​:18PM -0000, Piotr Fusik wrote​:

perl -e "1for$[=0" causes a null pointer dereference.

Confirmed in 5.8.1RC3, 5.8.6 and bleadperl@​24148 on OS X 10.3

Quite old, actually​:

  $ /opt/perl/5.005/bin/perl -e '1for$[=0'
  Segmentation fault
  $ /opt/perl/5.004_05/bin/perl -e '1for$[=0'
  Segmentation fault
  $

But​:

  $ /opt/perl/5.004_04/bin/perl -e '1for$[=0'
  syntax error at -e line 1, near "1for"
  Execution of -e aborted due to compilation errors.
  $

Abigail

@p5pRT
Copy link
Author

p5pRT commented Jun 16, 2005

From @hvds

Rafael Garcia-Suarez <rgarciasuarez@​gmail.com> wrote​:
:On 6/16/05, Steve Peters <steve@​fisharerojo.org> wrote​:
[snip]
:However you correctly found the cause of the problem. $[ is a
:pragmatic variable and assignment to it happens at compile time and is
:optimized away. So expr becomes NULL.
:
:Note that other kinds of similar code segfaults too :
:
:$ perl -e 'if($[=0){print}'
:Segmentation fault
:
:I'd rather solve all those cases once and for all.

It sounds like the bug is in the optimiser​: if it acts on C< $[ = 0 >
at compile time, it should substitute the resulting value (C< 0 >),
and leave it to other optimisations to refine that further if it is
in void context, or leads to a constant conditional.

Hugo

@p5pRT
Copy link
Author

p5pRT commented Jun 17, 2005

From @smpeters

On Fri, Jun 17, 2005 at 12​:00​:07AM +0100, hv@​crypt.org wrote​:

Rafael Garcia-Suarez <rgarciasuarez@​gmail.com> wrote​:
:On 6/16/05, Steve Peters <steve@​fisharerojo.org> wrote​:
[snip]
:However you correctly found the cause of the problem. $[ is a
:pragmatic variable and assignment to it happens at compile time and is
:optimized away. So expr becomes NULL.
:
:Note that other kinds of similar code segfaults too :
:
:$ perl -e 'if($[=0){print}'
:Segmentation fault
:
:I'd rather solve all those cases once and for all.

It sounds like the bug is in the optimiser​: if it acts on C< $[ = 0 >
at compile time, it should substitute the resulting value (C< 0 >),
and leave it to other optimisations to refine that further if it is
in void context, or leads to a constant conditional.

I see this sort of behavior more when putting the code into a quoted
eval.

  steve@​kirk​:~/sandbox$ perl -le'eval "1 for $[=0"; print $@​'
  Can't modify constant item in scalar assignment at (eval 1) line 2, at EOF

An eval'ed block just SEGVs as the normal code does. At semi-random intervals
this afternoon, I did see some bareword warnings, suggesting some slightly
different results from the optimizer. Of course, I can't seem to make that
happen right now.

Steve Peters
steve@​fisharerojo.org

@p5pRT
Copy link
Author

p5pRT commented Jun 18, 2005

From rick@bort.ca

On Fri, Jun 17, 2005 at 12​:00​:07AM +0100, hv@​crypt.org wrote​:

Rafael Garcia-Suarez <rgarciasuarez@​gmail.com> wrote​:
:
:Note that other kinds of similar code segfaults too :
:
:$ perl -e 'if($[=0){print}'
:Segmentation fault
:
:I'd rather solve all those cases once and for all.

It sounds like the bug is in the optimiser​: if it acts on C< $[ = 0 >
at compile time, it should substitute the resulting value (C< 0 >),
and leave it to other optimisations to refine that further if it is
in void context, or leads to a constant conditional.

This patch should do that. It also fixes this​:

  % perl -wle '($_, $[) = (42);print "$_​:$["'
  Use of uninitialized value in concatenation (.) or string at -e line 1.
  :42

by disallowing it. It now gives​:

  That use of $[ is unsupported at -e line 1.

--
Rick Delaney
rick@​bort.ca

Inline Patch
diff -ruN perl-current/op.c perl-current-dev/op.c
--- perl-current/op.c	2005-06-16 06:15:46.000000000 -0400
+++ perl-current-dev/op.c	2005-06-17 22:00:03.000000000 -0400
@@ -3274,14 +3274,15 @@
 	OP *curop;
 
 	PL_modcount = 0;
-	PL_eval_start = right;	/* Grandfathering $[ assignment here.  Bletch.*/
+	/* Grandfathering $[ assignment here.  Bletch.*/
+	/* Only simple assignments like C<< ($[) = 1 >> are allowed */
+	PL_eval_start = (left->op_type == OP_CONST) ? right : 0;
 	left = mod(left, OP_AASSIGN);
 	if (PL_eval_start)
 	    PL_eval_start = 0;
-	else {
-	    op_free(left);
-	    op_free(right);
-	    return Nullop;
+	else if (left->op_type == OP_CONST) {
+	    /* Result of assignment is always 1 (or we'd be dead already) */
+	    return newSVOP(OP_CONST, 0, newSViv(1));
 	}
 	/* optimise C<my @x = ()> to C<my @x>, and likewise for hashes */
 	if ((left->op_type == OP_PADAV || left->op_type == OP_PADHV)
@@ -3418,8 +3419,7 @@
 	if (PL_eval_start)
 	    PL_eval_start = 0;
 	else {
-	    op_free(o);
-	    return Nullop;
+	    o = newSVOP(OP_CONST, 0, newSViv(PL_compiling.cop_arybase));
 	}
     }
     return o;
diff -ruN perl-current/t/comp/parser.t perl-current-dev/t/comp/parser.t
--- perl-current/t/comp/parser.t	2004-06-24 12:47:01.000000000 -0400
+++ perl-current-dev/t/comp/parser.t	2005-06-17 22:02:54.074228248 -0400
@@ -9,7 +9,7 @@
 }
 
 require "./test.pl";
-plan( tests => 47 );
+plan( tests => 54 );
 
 eval '%@x=0;';
 like( $@, qr/^Can't modify hash dereference in repeat \(x\)/, '%@x=0' );
@@ -168,3 +168,25 @@
     eval q{ sub _ __FILE__ {} };
     like($@, qr/Illegal declaration of subroutine main::_/, "__FILE__ as prototype");
 }
+
+# [perl #36313] perl -e "1for$[=0" crash
+{
+    my $x;
+    $x = 1 for $[ = 0;
+    pass('optimized assignment to $[ used to segfault in scalar context');
+    if (($[) = 0) { $x = 1 }
+    pass('optimized assignment to $[ used to segfault in list context');
+    $x = ($[=2.4);
+    is($x, 2, 'scalar assignment to $[ behaves like other variables');
+    $x = (($[) = 0);
+    is($x, 1, 'list assignment to $[ behaves like other variables');
+    $x = eval q{ ($[, $x) = (0) };
+    like($@, qr/That use of \$\[ is unsupported/,
+             'cannot assign to $[ in a list');
+    eval q{ ($[, $x) = (0, 1) };
+    like($@, qr/That use of \$\[ is unsupported/,
+             'cannot assign list of >1 elements to $[');
+    eval q{ ($[, $x) = () };
+    like($@, qr/That use of \$\[ is unsupported/,
+             'cannot assign list of <1 elements to $[');
+}

@p5pRT
Copy link
Author

p5pRT commented Jun 18, 2005

From @Abigail

On Thu, Jun 16, 2005 at 10​:24​:24PM -0500, Steve Peters wrote​:

I see this sort of behavior more when putting the code into a quoted
eval.

steve@&#8203;kirk&#8203;:\~/sandbox$ perl \-le'eval "1 for $\[=0"; print $@&#8203;'
Can't modify constant item in scalar assignment at \(eval 1\) line 2\, at EOF

An eval'ed block just SEGVs as the normal code does. At semi-random intervals
this afternoon, I did see some bareword warnings, suggesting some slightly
different results from the optimizer. Of course, I can't seem to make that
happen right now.

Well, $[ equals 0, so C&lt;"1 for $[=0"> equals C<1 for 0=0>, which does
give a "Can't modify constant item in scalar assignment" error.

Abigail

@p5pRT
Copy link
Author

p5pRT commented Jun 18, 2005

From rick@bort.ca

On Fri, Jun 17, 2005 at 10​:31​:19PM -0400, Rick Delaney wrote​:

+ eval q{ ($[, $x) = (0, 1) };
+ like($@​, qr/That use of \$\[ is unsupported/,
+ 'cannot assign list of >1 elements to $[');
+ eval q{ ($[, $x) = () };
+ like($@​, qr/That use of \$\[ is unsupported/,
+ 'cannot assign list of <1 elements to $[');
+}

Oops, those last two test cases aren't quite right since they could be
failing because of the multiple scalars on the left. Replacement patch
follows.

--
Rick Delaney
rick@​bort.ca

Inline Patch
diff -ruN perl-current/.patch perl-current-dev/.patch
--- perl-current/.patch	2005-06-18 13:03:29.000000000 -0400
+++ perl-current-dev/.patch	2004-11-03 08:20:39.000000000 -0500
@@ -1 +1 @@
-24895
+23469
diff -ruN perl-current/op.c perl-current-dev/op.c
--- perl-current/op.c	2005-06-16 06:15:46.000000000 -0400
+++ perl-current-dev/op.c	2005-06-17 22:00:03.000000000 -0400
@@ -3274,14 +3274,15 @@
 	OP *curop;
 
 	PL_modcount = 0;
-	PL_eval_start = right;	/* Grandfathering $[ assignment here.  Bletch.*/
+	/* Grandfathering $[ assignment here.  Bletch.*/
+	/* Only simple assignments like C<< ($[) = 1 >> are allowed */
+	PL_eval_start = (left->op_type == OP_CONST) ? right : 0;
 	left = mod(left, OP_AASSIGN);
 	if (PL_eval_start)
 	    PL_eval_start = 0;
-	else {
-	    op_free(left);
-	    op_free(right);
-	    return Nullop;
+	else if (left->op_type == OP_CONST) {
+	    /* Result of assignment is always 1 (or we'd be dead already) */
+	    return newSVOP(OP_CONST, 0, newSViv(1));
 	}
 	/* optimise C<my @x = ()> to C<my @x>, and likewise for hashes */
 	if ((left->op_type == OP_PADAV || left->op_type == OP_PADHV)
@@ -3418,8 +3419,7 @@
 	if (PL_eval_start)
 	    PL_eval_start = 0;
 	else {
-	    op_free(o);
-	    return Nullop;
+	    o = newSVOP(OP_CONST, 0, newSViv(PL_compiling.cop_arybase));
 	}
     }
     return o;
diff -ruN perl-current/t/comp/parser.t perl-current-dev/t/comp/parser.t
--- perl-current/t/comp/parser.t	2004-06-24 12:47:01.000000000 -0400
+++ perl-current-dev/t/comp/parser.t	2005-06-18 17:44:05.324160600 -0400
@@ -9,7 +9,7 @@
 }
 
 require "./test.pl";
-plan( tests => 47 );
+plan( tests => 54 );
 
 eval '%@x=0;';
 like( $@, qr/^Can't modify hash dereference in repeat \(x\)/, '%@x=0' );
@@ -168,3 +168,25 @@
     eval q{ sub _ __FILE__ {} };
     like($@, qr/Illegal declaration of subroutine main::_/, "__FILE__ as prototype");
 }
+
+# [perl #36313] perl -e "1for$[=0" crash
+{
+    my $x;
+    $x = 1 for $[ = 0;
+    pass('optimized assignment to $[ used to segfault in scalar context');
+    if (($[) = 0) { $x = 1 }
+    pass('optimized assignment to $[ used to segfault in list context');
+    $x = ($[=2.4);
+    is($x, 2, 'scalar assignment to $[ behaves like other variables');
+    $x = (($[) = 0);
+    is($x, 1, 'list assignment to $[ behaves like other variables');
+    $x = eval q{ ($[, $x) = (0) };
+    like($@, qr/That use of \$\[ is unsupported/,
+             'cannot assign to $[ in a list');
+    eval q{ ($[) = (0, 1) };
+    like($@, qr/That use of \$\[ is unsupported/,
+             'cannot assign list of >1 elements to $[');
+    eval q{ ($[) = () };
+    like($@, qr/That use of \$\[ is unsupported/,
+             'cannot assign list of <1 elements to $[');
+}

@p5pRT
Copy link
Author

p5pRT commented Jun 19, 2005

From fox@scene.pl

+ $x = 1 for $[ = 0;
+ pass('optimized assignment to $[ used to segfault in scalar context');
+ if (($[) = 0) { $x = 1 }
+ pass('optimized assignment to $[ used to segfault in list context');

Looks like the descriptions of contexts are swapped (i.e. "for" should be
"list", "if" should be "scalar").

Piotr Fusik

@p5pRT
Copy link
Author

p5pRT commented Jun 19, 2005

From rick@bort.ca

On Sun, Jun 19, 2005 at 11​:34​:55AM -0000, Piotr Fusik wrote​:

+ $x = 1 for $[ = 0;
+ pass('optimized assignment to $[ used to segfault in scalar context');
+ if (($[) = 0) { $x = 1 }
+ pass('optimized assignment to $[ used to segfault in list context');

Looks like the descriptions of contexts are swapped (i.e. "for" should be
"list", "if" should be "scalar").

No, the first assignment is in scalar context and the second (with
parentheses) is in list context. But the results of the assignments are
taken in list and scalar contexts, respectively, which I suppose is a
little confusing. I just took the two test cases presented and
arbitrarily made one of them list context. Here's the whole thing again
with the arbitrariness going the other way.

--
Rick Delaney
rick@​bort.ca

Inline Patch
diff -ruN perl-current/op.c perl-current-dev/op.c
--- perl-current/op.c	2005-06-16 06:15:46.000000000 -0400
+++ perl-current-dev/op.c	2005-06-17 22:00:03.000000000 -0400
@@ -3274,14 +3274,15 @@
 	OP *curop;
 
 	PL_modcount = 0;
-	PL_eval_start = right;	/* Grandfathering $[ assignment here.  Bletch.*/
+	/* Grandfathering $[ assignment here.  Bletch.*/
+	/* Only simple assignments like C<< ($[) = 1 >> are allowed */
+	PL_eval_start = (left->op_type == OP_CONST) ? right : 0;
 	left = mod(left, OP_AASSIGN);
 	if (PL_eval_start)
 	    PL_eval_start = 0;
-	else {
-	    op_free(left);
-	    op_free(right);
-	    return Nullop;
+	else if (left->op_type == OP_CONST) {
+	    /* Result of assignment is always 1 (or we'd be dead already) */
+	    return newSVOP(OP_CONST, 0, newSViv(1));
 	}
 	/* optimise C<my @x = ()> to C<my @x>, and likewise for hashes */
 	if ((left->op_type == OP_PADAV || left->op_type == OP_PADHV)
@@ -3418,8 +3419,7 @@
 	if (PL_eval_start)
 	    PL_eval_start = 0;
 	else {
-	    op_free(o);
-	    return Nullop;
+	    o = newSVOP(OP_CONST, 0, newSViv(PL_compiling.cop_arybase));
 	}
     }
     return o;
diff -ruN perl-current/t/comp/parser.t perl-current-dev/t/comp/parser.t
--- perl-current/t/comp/parser.t	2004-06-24 12:47:01.000000000 -0400
+++ perl-current-dev/t/comp/parser.t	2005-06-19 09:41:00.392743456 -0400
@@ -9,7 +9,7 @@
 }
 
 require "./test.pl";
-plan( tests => 47 );
+plan( tests => 54 );
 
 eval '%@x=0;';
 like( $@, qr/^Can't modify hash dereference in repeat \(x\)/, '%@x=0' );
@@ -168,3 +168,25 @@
     eval q{ sub _ __FILE__ {} };
     like($@, qr/Illegal declaration of subroutine main::_/, "__FILE__ as prototype");
 }
+
+# [perl #36313] perl -e "1for$[=0" crash
+{
+    my $x;
+    $x = 1 for ($[) = 0;
+    pass('optimized assignment to $[ used to segfault in list context');
+    if ($[ = 0) { $x = 1 }
+    pass('optimized assignment to $[ used to segfault in scalar context');
+    $x = ($[=2.4);
+    is($x, 2, 'scalar assignment to $[ behaves like other variables');
+    $x = (($[) = 0);
+    is($x, 1, 'list assignment to $[ behaves like other variables');
+    $x = eval q{ ($[, $x) = (0) };
+    like($@, qr/That use of \$\[ is unsupported/,
+             'cannot assign to $[ in a list');
+    eval q{ ($[) = (0, 1) };
+    like($@, qr/That use of \$\[ is unsupported/,
+             'cannot assign list of >1 elements to $[');
+    eval q{ ($[) = () };
+    like($@, qr/That use of \$\[ is unsupported/,
+             'cannot assign list of <1 elements to $[');
+}

@p5pRT
Copy link
Author

p5pRT commented Jun 20, 2005

From fox@scene.pl

> + $x = 1 for $[ = 0;
> + pass('optimized assignment to $[ used to segfault in scalar
context');
> + if (($[) = 0) { $x = 1 }
> + pass('optimized assignment to $[ used to segfault in list
context');
>
> Looks like the descriptions of contexts are swapped (i.e.
"for" should be
> "list", "if" should be "scalar").

No, the first assignment is in scalar context and the second (with
parentheses) is in list context. But the results of the assignments are
taken in list and scalar contexts, respectively, which I suppose is a
little confusing.

I thought "the assignment" is "the = operator". So​:
"for $[ = 0" is scalar assignment in list context.
"if (($[) = 0)" is list assignment in scalar context.
Am I wrong?

Consider this​:
1 for $a + $b
The addition is here obviously in list context (although it is, of course,
scalar addition).

@p5pRT
Copy link
Author

p5pRT commented Jun 20, 2005

From @rgs

Rick Delaney wrote​:

On Sun, Jun 19, 2005 at 11​:34​:55AM -0000, Piotr Fusik wrote​:

+ $x = 1 for $[ = 0;
+ pass('optimized assignment to $[ used to segfault in scalar context');
+ if (($[) = 0) { $x = 1 }
+ pass('optimized assignment to $[ used to segfault in list context');

Looks like the descriptions of contexts are swapped (i.e. "for" should be
"list", "if" should be "scalar").

No, the first assignment is in scalar context and the second (with
parentheses) is in list context. But the results of the assignments are
taken in list and scalar contexts, respectively, which I suppose is a
little confusing. I just took the two test cases presented and
arbitrarily made one of them list context. Here's the whole thing again
with the arbitrariness going the other way.

Thanks, applied as #24901.

@p5pRT
Copy link
Author

p5pRT commented Jun 20, 2005

@rgs - Status changed from 'open' to 'resolved'

@p5pRT p5pRT closed this as completed Jun 20, 2005
@p5pRT
Copy link
Author

p5pRT commented Jun 20, 2005

From @ysth

On Mon, Jun 20, 2005 at 10​:44​:30AM -0000, Piotr Fusik wrote​:

> + $x = 1 for $[ = 0;
> + pass('optimized assignment to $[ used to segfault in scalar
context');
> + if (($[) = 0) { $x = 1 }
> + pass('optimized assignment to $[ used to segfault in list
context');
>
> Looks like the descriptions of contexts are swapped (i.e.
"for" should be
> "list", "if" should be "scalar").

No, the first assignment is in scalar context and the second (with
parentheses) is in list context. But the results of the assignments are
taken in list and scalar contexts, respectively, which I suppose is a
little confusing.

I thought "the assignment" is "the = operator". So​:
"for $[ = 0" is scalar assignment in list context.
"if (($[) = 0)" is list assignment in scalar context.
Am I wrong?

No, you are correct. I believe Rick was speaking imprecisely, meaning
that the first assignment is a scalar assignment and the the second a
list assignment.

@p5pRT
Copy link
Author

p5pRT commented Jun 20, 2005

From rick@bort.ca

On Mon, Jun 20, 2005 at 03​:03​:20AM -0700, Yitzchak Scott-Thoennes wrote​:

On Mon, Jun 20, 2005 at 10​:44​:30AM -0000, Piotr Fusik wrote​:

I thought "the assignment" is "the = operator". So​:
"for $[ = 0" is scalar assignment in list context.
"if (($[) = 0)" is list assignment in scalar context.
Am I wrong?

No, you are correct. I believe Rick was speaking imprecisely, meaning
that the first assignment is a scalar assignment and the the second a
list assignment.

Right. And that's what the tests are meant to, er, test. So they
should probably read

  pass('optimized scalar assignment to $[ used to segfault');
  pass('optimized list assignment to $[ used to segfault');

but I think I've done enough damage. Patches welcome. :-)

--
Rick Delaney
rick@​bort.ca

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant