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

no warning for my $a = 1 if 0; #11252

Open
p5pRT opened this issue Apr 12, 2011 · 12 comments
Open

no warning for my $a = 1 if 0; #11252

p5pRT opened this issue Apr 12, 2011 · 12 comments

Comments

@p5pRT
Copy link

p5pRT commented Apr 12, 2011

Migrated from rt.perl.org#88384 (status was 'open')

Searchable as RT88384$

@p5pRT
Copy link
Author

p5pRT commented Apr 12, 2011

From @nwc10

Created by @nwc10

$ ./perl -we 'my $a if 0'
Deprecated use of my() in false conditional at -e line 1.
$ ./perl -we 'my $a = 1 if 0'
$

Presumably the latter should warn too.

(not a regression)

Nicholas Clark

Perl Info

Flags:
    category=core
    severity=low

Site configuration information for perl 5.14.0:

Configured by nick at Tue Apr 12 08:53:08 BST 2011.

Summary of my perl5 (revision 5 version 14 subversion 0) configuration:
  Derived from: eac006c9b5f4ca1954ec680fed91d18a53c763e1
  Platform:
    osname=linux, osvers=2.6.35.4, archname=x86_64-linux-thread-multi
    uname='linux eris 2.6.35.4 #4 smp tue sep 21 09:54:22 bst 2010 x86_64 gnulinux '
    config_args='-Dusedevel=y -Dcc=ccache gcc -Dld=gcc -Ubincompat5005 -Uinstallusrbinperl -Dcf_email=nick@ccl4.org -Dperladmin=nick@ccl4.org -Dinc_version_list=  -Dinc_version_list_init=0 -Umad -DDEBUGGING -Doptimize=-g -Dusethreads -Uuselongdouble -Uuse64bitall -Uusemymalloc -Duseperlio -Dprefix=~/Sandpit/snap5.9.x-v5.13.11-414-geac006c -Uusevendorprefix -Uvendorprefix=~/Sandpit/snap5.9.x-v5.13.11-414-geac006c -Dinstallman1dir=none -Dinstallman3dir=none -Uuserelocatableinc -de'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=define, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='ccache gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-g',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.3.2', gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='gcc', ldflags =' -fstack-protector -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib /lib64 /usr/lib64
    libs=-lnsl -ldb -ldl -lm -lcrypt -lutil -lpthread -lc
    perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    libc=/lib/libc-2.7.so, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.7'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -g -L/usr/local/lib -fstack-protector'

Locally applied patches:
    RC0


@INC for perl 5.14.0:
    lib
    /home/nick/Sandpit/snap5.9.x-v5.13.11-414-geac006c/lib/perl5/site_perl/5.14.0/x86_64-linux-thread-multi
    /home/nick/Sandpit/snap5.9.x-v5.13.11-414-geac006c/lib/perl5/site_perl/5.14.0
    /home/nick/Sandpit/snap5.9.x-v5.13.11-414-geac006c/lib/perl5/5.14.0/x86_64-linux-thread-multi
    /home/nick/Sandpit/snap5.9.x-v5.13.11-414-geac006c/lib/perl5/5.14.0
    .


Environment for perl 5.14.0:
    HOME=/home/nick
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/nick/bin:/usr/local/bin:/usr/bin:/bin:/usr/games:/usr/local/sbin:/sbin:/usr/sbin
    PERL_BADLANG (unset)
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Jun 24, 2012

From @doy

Pushed a fix for this to doy/false_conditional, but this is triggering
cases like

  if (FALSE_CONSTANT and my $foo = $bar) {
  ...;
  }

which doesn't seem to be a useful thing to warn for. Unfortunately, it
has an identical optree. Should this kind of construct also be
deprecated? Or are we going to need to find a different way to catch this?

@p5pRT
Copy link
Author

p5pRT commented Jun 24, 2012

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

@p5pRT
Copy link
Author

p5pRT commented Jun 25, 2012

From @ikegami

On Sun, Jun 24, 2012 at 5​:56 AM, Jesse Luehrs via RT <
perlbug-followup@​perl.org> wrote​:

Pushed a fix for this to doy/false_conditional, but this is triggering
cases like

if (FALSE_CONSTANT and my $foo = $bar) {
...;
}

which doesn't seem to be a useful thing to warn for. Unfortunately, it
has an identical optree. Should this kind of construct also be
deprecated? Or are we going to need to find a different way to catch this?

There's a scope around "if" statements that limit the visibility of
variables declared in the conditional, but it's a fake scope. It doesn't
actually exist at run-time, which means variables get destroyed later than
expected.

It seems to me that if that is fixed, the optree would become
distinguishable.

@p5pRT
Copy link
Author

p5pRT commented Jun 25, 2012

From @davidnicol

is there a risk of wrecking old code that uses the C<my (...) if 0> state hack?

@p5pRT
Copy link
Author

p5pRT commented Jun 26, 2012

From @ikegami

On Mon, Jun 25, 2012 at 7​:58 PM, David Nicol <davidnicol@​gmail.com> wrote​:

is there a risk of wrecking old code that uses the C<my (...) if 0> state
hack?

I suggested a change to the "if" statement only, not the "if" statement
modifier. Like you point out, there could be problems if you do.

@p5pRT
Copy link
Author

p5pRT commented Jun 28, 2012

From @nwc10

On Sun, Jun 24, 2012 at 02​:56​:55AM -0700, Jesse Luehrs via RT wrote​:

Pushed a fix for this to doy/false_conditional, but this is triggering
cases like

if (FALSE_CONSTANT and my $foo = $bar) {
...;
}

which doesn't seem to be a useful thing to warn for. Unfortunately, it
has an identical optree. Should this kind of construct also be
deprecated? Or are we going to need to find a different way to catch this?

I don't think that it deserves to be deprecated. The scoping is different.
my $c = 1 if 0; creates a "static" variable that is in scope in code
that is not optimised away

$ perl -we 'use strict; my $c = 1 if 0; print $c'
Use of uninitialized value $c in print at -e line 1.

Whereas 0 and my $c = 1 doesn't create $c outside of the eliminated block.

$ perl -we 'use strict; if (0 and my $c = 1) {}; print $c'
Global symbol "$c" requires explicit package name at -e line 1.
Execution of -e aborted due to compilation errors.

op.h has this​:

/* Private for OP_CONST */
#define OPpCONST_NOVER 2 /* no 6; */
#define OPpCONST_SHORTCIRCUIT 4 /* eg the constant 5 in (5 || foo) */
#define OPpCONST_STRICT 8 /* bareword subject to strict 'subs' */
#define OPpCONST_ENTERED 16 /* Has been entered as symbol. */
#define OPpCONST_BARE 64 /* Was a bare word (filehandle?). */

Is OPpCONST_SHORTCIRCUIT true on the constant?

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Jun 28, 2012

From @doy

On Thu, Jun 28, 2012 at 12​:20​:19PM +0100, Nicholas Clark wrote​:

On Sun, Jun 24, 2012 at 02​:56​:55AM -0700, Jesse Luehrs via RT wrote​:

Pushed a fix for this to doy/false_conditional, but this is triggering
cases like

if (FALSE_CONSTANT and my $foo = $bar) {
...;
}

which doesn't seem to be a useful thing to warn for. Unfortunately, it
has an identical optree. Should this kind of construct also be
deprecated? Or are we going to need to find a different way to catch this?

I don't think that it deserves to be deprecated. The scoping is different.
my $c = 1 if 0; creates a "static" variable that is in scope in code
that is not optimised away

$ perl -we 'use strict; my $c = 1 if 0; print $c'
Use of uninitialized value $c in print at -e line 1.

Whereas 0 and my $c = 1 doesn't create $c outside of the eliminated block.

$ perl -we 'use strict; if (0 and my $c = 1) {}; print $c'
Global symbol "$c" requires explicit package name at -e line 1.
Execution of -e aborted due to compilation errors.

I agree, which is why I didn't merge the branch.

op.h has this​:

/* Private for OP_CONST */
#define OPpCONST_NOVER 2 /* no 6; */
#define OPpCONST_SHORTCIRCUIT 4 /* eg the constant 5 in (5 || foo) */
#define OPpCONST_STRICT 8 /* bareword subject to strict 'subs' */
#define OPpCONST_ENTERED 16 /* Has been entered as symbol. */
#define OPpCONST_BARE 64 /* Was a bare word (filehandle?). */

Is OPpCONST_SHORTCIRCUIT true on the constant?

It's actually true in both cases - the same part of the code that does
this test also sets that flag unconditionally. This test is happening in
inside newLOGOP when an OP_AND is compiled, because "$foo if $bar" is
translated into "$bar and $foo" by the parser itself​:

  | expr IF expr
  { $$ = newLOGOP(OP_AND, 0, $3, $1);
  TOKEN_GETMAD($2,$$,'i');
  }

-doy

@p5pRT
Copy link
Author

p5pRT commented Jun 28, 2012

From @doy

On Thu, Jun 28, 2012 at 01​:35​:14PM -0500, Jesse Luehrs wrote​:

op.h has this​:

/* Private for OP_CONST */
#define OPpCONST_NOVER 2 /* no 6; */
#define OPpCONST_SHORTCIRCUIT 4 /* eg the constant 5 in (5 || foo) */
#define OPpCONST_STRICT 8 /* bareword subject to strict 'subs' */
#define OPpCONST_ENTERED 16 /* Has been entered as symbol. */
#define OPpCONST_BARE 64 /* Was a bare word (filehandle?). */

Is OPpCONST_SHORTCIRCUIT true on the constant?

It's actually true in both cases - the same part of the code that does
this test also sets that flag unconditionally. This test is happening in
inside newLOGOP when an OP_AND is compiled, because "$foo if $bar" is
translated into "$bar and $foo" by the parser itself​:

    |       expr IF expr
                    \{ $$ = newLOGOP\(OP\_AND\, 0\, $3\, $1\);
                      TOKEN\_GETMAD\($2\,$$\,'i'\);
                    \}

It does strike me though that we could just differentiate there
directly, by having the parser set an op flag in that case. I don't
think OPf_SPECIAL is used for OP_AND yet? Let me try that.

-doy

@p5pRT
Copy link
Author

p5pRT commented Jun 28, 2012

From @doy

On Thu, Jun 28, 2012 at 01​:40​:29PM -0500, Jesse Luehrs wrote​:

On Thu, Jun 28, 2012 at 01​:35​:14PM -0500, Jesse Luehrs wrote​:

op.h has this​:

/* Private for OP_CONST */
#define OPpCONST_NOVER 2 /* no 6; */
#define OPpCONST_SHORTCIRCUIT 4 /* eg the constant 5 in (5 || foo) */
#define OPpCONST_STRICT 8 /* bareword subject to strict 'subs' */
#define OPpCONST_ENTERED 16 /* Has been entered as symbol. */
#define OPpCONST_BARE 64 /* Was a bare word (filehandle?). */

Is OPpCONST_SHORTCIRCUIT true on the constant?

It's actually true in both cases - the same part of the code that does
this test also sets that flag unconditionally. This test is happening in
inside newLOGOP when an OP_AND is compiled, because "$foo if $bar" is
translated into "$bar and $foo" by the parser itself​:

    |       expr IF expr
                    \{ $$ = newLOGOP\(OP\_AND\, 0\, $3\, $1\);
                      TOKEN\_GETMAD\($2\,$$\,'i'\);
                    \}

It does strike me though that we could just differentiate there
directly, by having the parser set an op flag in that case. I don't
think OPf_SPECIAL is used for OP_AND yet? Let me try that.

So I tried this (and updated the branch), but this still isn't quite
right - now cases like "0 and my $foo" are not warned for, even outside
of an if block. This really does have to happen elsewhere, I think - we
need to be able to say "is the entire scope of this declaration going to
be optimized away by the parent op?", and we can't do that from the
point where the OP_AND is created. I'm not really sure how to go about
changing that though/​:

-doy

@p5pRT
Copy link
Author

p5pRT commented Sep 24, 2012

From @cpansprout

On Thu Jun 28 14​:32​:27 2012, doy@​tozt.net wrote​:

On Thu, Jun 28, 2012 at 01​:40​:29PM -0500, Jesse Luehrs wrote​:

On Thu, Jun 28, 2012 at 01​:35​:14PM -0500, Jesse Luehrs wrote​:

op.h has this​:

/* Private for OP_CONST */
#define OPpCONST_NOVER 2 /* no 6; */
#define OPpCONST_SHORTCIRCUIT 4 /* eg the constant 5 in (5 ||
foo) */
#define OPpCONST_STRICT 8 /* bareword subject to strict 'subs' */
#define OPpCONST_ENTERED 16 /* Has been entered as symbol. */
#define OPpCONST_BARE 64 /* Was a bare word (filehandle?). */

Is OPpCONST_SHORTCIRCUIT true on the constant?

It's actually true in both cases - the same part of the code that does
this test also sets that flag unconditionally. This test is
happening in
inside newLOGOP when an OP_AND is compiled, because "$foo if $bar" is
translated into "$bar and $foo" by the parser itself​:

    |       expr IF expr
                    \{ $$ = newLOGOP\(OP\_AND\, 0\, $3\, $1\);
                      TOKEN\_GETMAD\($2\,$$\,'i'\);
                    \}

It does strike me though that we could just differentiate there
directly, by having the parser set an op flag in that case. I don't
think OPf_SPECIAL is used for OP_AND yet? Let me try that.

So I tried this (and updated the branch), but this still isn't quite
right - now cases like "0 and my $foo" are not warned for, even outside
of an if block. This really does have to happen elsewhere, I think - we
need to be able to say "is the entire scope of this declaration going to
be optimized away by the parent op?", and we can't do that from the
point where the OP_AND is created. I'm not really sure how to go about
changing that though/​:

I know more about this now than before implementing lexical subs, so I
actually have a suggestion​:

The mexpr and texpr rules in perly.y are probably where you want to set
a flag. Those rules are used only inside keyword(...){}.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Sep 24, 2012

From @cpansprout

On Mon Sep 24 00​:06​:59 2012, sprout wrote​:

On Thu Jun 28 14​:32​:27 2012, doy@​tozt.net wrote​:

On Thu, Jun 28, 2012 at 01​:40​:29PM -0500, Jesse Luehrs wrote​:

On Thu, Jun 28, 2012 at 01​:35​:14PM -0500, Jesse Luehrs wrote​:

op.h has this​:

/* Private for OP_CONST */
#define OPpCONST_NOVER 2 /* no 6; */
#define OPpCONST_SHORTCIRCUIT 4 /* eg the constant 5 in (5 ||
foo) */
#define OPpCONST_STRICT 8 /* bareword subject to strict 'subs' */
#define OPpCONST_ENTERED 16 /* Has been entered as symbol. */
#define OPpCONST_BARE 64 /* Was a bare word (filehandle?). */

Is OPpCONST_SHORTCIRCUIT true on the constant?

It's actually true in both cases - the same part of the code
that does
this test also sets that flag unconditionally. This test is
happening in
inside newLOGOP when an OP_AND is compiled, because "$foo if
$bar" is
translated into "$bar and $foo" by the parser itself​:

    |       expr IF expr
                    \{ $$ = newLOGOP\(OP\_AND\, 0\, $3\, $1\);
                      TOKEN\_GETMAD\($2\,$$\,'i'\);
                    \}

It does strike me though that we could just differentiate there
directly, by having the parser set an op flag in that case. I don't
think OPf_SPECIAL is used for OP_AND yet? Let me try that.

So I tried this (and updated the branch), but this still isn't quite
right - now cases like "0 and my $foo" are not warned for, even outside
of an if block. This really does have to happen elsewhere, I think - we
need to be able to say "is the entire scope of this declaration going to
be optimized away by the parent op?", and we can't do that from the
point where the OP_AND is created. I'm not really sure how to go about
changing that though/​:

I know more about this now than before implementing lexical subs, so I
actually have a suggestion​:

The mexpr and texpr rules in perly.y are probably where you want to set
a flag. Those rules are used only inside keyword(...){}.

Actually, that won’t help, as it will be too late.

--

Father Chrysostomos

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

No branches or pull requests

3 participants