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

Fatalize my() in false conditional in perl-5.30 #16702

Closed
p5pRT opened this issue Sep 25, 2018 · 17 comments
Labels
Milestone

Comments

@p5pRT
Copy link
Collaborator

@p5pRT p5pRT commented Sep 25, 2018

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

Searchable as RT133543$

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Sep 25, 2018

From @jkeenan

I am here creating a ticket for an item mentioned on the mailing list​:
the fatalization of my() in false conditional. (I haven't found an
existing RT for this item, though there does exist a META ticket.)

According to the perl-5.28.0 source code, the following deprecation is
scheduled for perl-5.30​:

#####
op.c-8260- && o2->op_private & OPpLVAL_INTRO
op.c-8261- && !(o2->op_private & OPpPAD_STATE))
op.c-8262- {
op.c-8263- Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED),
op.c-8264- "Deprecated use of my() in
false conditional. "
op.c​:8265​: "This will be a fatal error in
Perl 5.30");
op.c-8266- }
op.c-8267-
op.c-8268- *otherp = NULL;
op.c-8269- if (cstop->op_type == OP_CONST)
op.c-8270- cstop->op_private |= OPpCONST_SHORTCIRCUIT;
#####

And that entails revision of this documentation​:

#####
pod/perldiag.pod-2016-
pod/perldiag.pod-2017-(F) In a here document construct like C<<<FOO>,
the label C<FOO> is too
pod/perldiag.pod-2018-long for Perl to handle. You have to be seriously
twisted to write code
pod/perldiag.pod-2019-that triggers this error.
pod/perldiag.pod-2020-
pod/perldiag.pod​:2021​:=item Deprecated use of my() in false conditional.
This will be a fatal error in Perl 5.30
pod/perldiag.pod-2022-
pod/perldiag.pod-2023-(D deprecated) You used a declaration similar to
C<my $x if 0>. There
pod/perldiag.pod-2024-has been a long-standing bug in Perl that causes a
lexical variable
pod/perldiag.pod-2025-not to be cleared at scope exit when its
declaration includes a false
pod/perldiag.pod-2026-conditional. Some people have exploited this bug
to achieve a kind of
--
pod/perldiag.pod-2038-lexicals that are initialized only once (see
L<feature>)​:
pod/perldiag.pod-2039-
pod/perldiag.pod-2040- sub f { state $x; return $x++ }
pod/perldiag.pod-2041-
pod/perldiag.pod-2042-This use of C<my()> in a false conditional has
been deprecated since
pod/perldiag.pod​:2043​:Perl 5.10, and it will become a fatal error in
Perl 5.30.
pod/perldiag.pod-2044-
pod/perldiag.pod-2045-=item DESTROY created new reference to dead object
'%s'
pod/perldiag.pod-2046-
pod/perldiag.pod-2047-(F) A DESTROY() method created a new reference to
the object which is
pod/perldiag.pod-2048-just being DESTROYed. Perl is confused, and
prefers to abort rather
#####

I will attach patches which constitute a (crude) first pass at
implementing this fatalization. This will be smoke-testing in a branch
which I will push as soon as I get an RT number.

Thank you very much.
Jim Keenan

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Sep 25, 2018

From @jkeenan

Summary of my perl5 (revision 5 version 29 subversion 4) configuration​:
  Derived from​: b64ae69
  Platform​:
  osname=linux
  osvers=4.15.0-34-generic
  archname=x86_64-linux
  uname='linux zareason 4.15.0-34-generic #37-ubuntu smp mon aug 27 15​:21​:48 utc 2018 x86_64 x86_64 x86_64 gnulinux '
  config_args='-des -Dusedevel'
  hint=recommended
  useposix=true
  d_sigaction=define
  useithreads=undef
  usemultiplicity=undef
  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-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
  optimize='-O2'
  cppflags='-fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include'
  ccversion=''
  gccversion='7.3.0'
  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/gcc/x86_64-linux-gnu/7/include-fixed /usr/include/x86_64-linux-gnu /usr/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib /lib64 /usr/lib64
  libs=-lpthread -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc
  perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
  libc=libc-2.27.so
  so=so
  useshrplib=false
  libperl=libperl.a
  gnulibc_version='2.27'
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs
  dlext=so
  d_dlsymun=undef
  ccdlflags='-Wl,-E'
  cccdlflags='-fPIC'
  lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector-strong'

Characteristics of this binary (from libperl)​:
  Compile-time options​:
  HAS_TIMES
  PERLIO_LAYERS
  PERL_COPY_ON_WRITE
  PERL_DONT_CREATE_GVSV
  PERL_MALLOC_WRAP
  PERL_OP_PARENT
  PERL_PRESERVE_IVUV
  PERL_USE_DEVEL
  USE_64_BIT_ALL
  USE_64_BIT_INT
  USE_LARGE_FILES
  USE_LOCALE
  USE_LOCALE_COLLATE
  USE_LOCALE_CTYPE
  USE_LOCALE_NUMERIC
  USE_LOCALE_TIME
  USE_PERLIO
  USE_PERL_ATOF
  Locally applied patches​:
  uncommitted-changes
  Built under linux
  Compiled at Sep 25 2018 15​:06​:39
  %ENV​:
  PERL2DIR="/home/jkeenan/gitwork/perl2"
  PERLBREW_HOME="/home/jkeenan/.perlbrew"
  PERLBREW_MANPATH="/home/jkeenan/perl5/perlbrew/perls/perl-5.28.0/man"
  PERLBREW_PATH="/home/jkeenan/perl5/perlbrew/bin​:/home/jkeenan/perl5/perlbrew/perls/perl-5.28.0/bin"
  PERLBREW_PERL="perl-5.28.0"
  PERLBREW_ROOT="/home/jkeenan/perl5/perlbrew"
  PERLBREW_SHELLRC_VERSION="0.84"
  PERLBREW_VERSION="0.84"
  PERL_WORKDIR="/home/jkeenan/gitwork/perl"
  @​INC​:
  lib
  /usr/local/lib/perl5/site_perl/5.29.4/x86_64-linux
  /usr/local/lib/perl5/site_perl/5.29.4
  /usr/local/lib/perl5/5.29.4/x86_64-linux
  /usr/local/lib/perl5/5.29.4

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Sep 25, 2018

From @jkeenan

On Tue, 25 Sep 2018 19​:58​:32 GMT, jkeenan@​pobox.com wrote​:

I am here creating a ticket for an item mentioned on the mailing list​:
the fatalization of my() in false conditional. (I haven't found an
existing RT for this item, though there does exist a META ticket.)

According to the perl-5.28.0 source code, the following deprecation is
scheduled for perl-5.30​:

#####
op.c-8260- && o2->op_private & OPpLVAL_INTRO
op.c-8261- && !(o2->op_private & OPpPAD_STATE))
op.c-8262- {
op.c-8263- Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED),
op.c-8264- "Deprecated use of my() in
false conditional. "
op.c​:8265​: "This will be a fatal error in
Perl 5.30");
op.c-8266- }
op.c-8267-
op.c-8268- *otherp = NULL;
op.c-8269- if (cstop->op_type == OP_CONST)
op.c-8270- cstop->op_private |= OPpCONST_SHORTCIRCUIT;
#####

And that entails revision of this documentation​:

#####
pod/perldiag.pod-2016-
pod/perldiag.pod-2017-(F) In a here document construct like C<<<FOO>,
the label C<FOO> is too
pod/perldiag.pod-2018-long for Perl to handle. You have to be seriously
twisted to write code
pod/perldiag.pod-2019-that triggers this error.
pod/perldiag.pod-2020-
pod/perldiag.pod​:2021​:=item Deprecated use of my() in false conditional.
This will be a fatal error in Perl 5.30
pod/perldiag.pod-2022-
pod/perldiag.pod-2023-(D deprecated) You used a declaration similar to
C<my $x if 0>. There
pod/perldiag.pod-2024-has been a long-standing bug in Perl that causes a
lexical variable
pod/perldiag.pod-2025-not to be cleared at scope exit when its
declaration includes a false
pod/perldiag.pod-2026-conditional. Some people have exploited this bug
to achieve a kind of
--
pod/perldiag.pod-2038-lexicals that are initialized only once (see
L<feature>)​:
pod/perldiag.pod-2039-
pod/perldiag.pod-2040- sub f { state $x; return $x++ }
pod/perldiag.pod-2041-
pod/perldiag.pod-2042-This use of C<my()> in a false conditional has
been deprecated since
pod/perldiag.pod​:2043​:Perl 5.10, and it will become a fatal error in
Perl 5.30.
pod/perldiag.pod-2044-
pod/perldiag.pod-2045-=item DESTROY created new reference to dead object
'%s'
pod/perldiag.pod-2046-
pod/perldiag.pod-2047-(F) A DESTROY() method created a new reference to
the object which is
pod/perldiag.pod-2048-just being DESTROYed. Perl is confused, and
prefers to abort rather
#####

I will attach patches which constitute a (crude) first pass at
implementing this fatalization. This will be smoke-testing in a branch
which I will push as soon as I get an RT number.

Thank you very much.
Jim Keenan

Smoke-testing branch​:

smoke-me/jkeenan/133543-my-false-conditional

Patches attached.

Thank you very much.
--
James E Keenan (jkeenan@​cpan.org)

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Sep 25, 2018

From @jkeenan

133543-0001-Implement-scheduled-fatalization-of-my-in-false-cond.patch
From 3dc9e310219a210aad9a0cadbd4c9b9f691fcbf5 Mon Sep 17 00:00:00 2001
From: James E Keenan <jkeenan@cpan.org>
Date: Tue, 25 Sep 2018 15:28:46 -0400
Subject: [PATCH 1/2] Implement scheduled fatalization of my() in false
 conditional

op.c: substitute exception for warning.  Move documentation in perldiag
from W to F.  Remove tests for warnings for such statements.

TODO: Create equivalent unit tests for fatal errors.

TODO: What RT is this connected to?
---
 op.c              |  4 ++++
 pod/perldiag.pod  | 24 ++++++++++++++++++++++++
 t/lib/warnings/op | 14 --------------
 3 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/op.c b/op.c
index d0dcffbecb..ad59f43f8c 100644
--- a/op.c
+++ b/op.c
@@ -8260,9 +8260,13 @@ S_new_logop(pTHX_ I32 type, I32 flags, OP** firstp, OP** otherp)
 		&& o2->op_private & OPpLVAL_INTRO
 		&& !(o2->op_private & OPpPAD_STATE))
 	    {
+            /*
 		Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED),
                                 "Deprecated use of my() in false conditional. "
                                 "This will be a fatal error in Perl 5.30");
+                                */
+        Perl_croak(aTHX_ "This use of my() in false conditional is "
+                          "no longer allowed");
 	    }
 
 	    *otherp = NULL;
diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index 2c1fe74a87..fa18450087 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -6109,6 +6109,30 @@ a dirhandle.  Check your control flow.
 (W unopened) You tried to use the tell() function on a filehandle that
 was either never opened or has since been closed.
 
+=item This use of my() in false conditional is no longer allowed
+
+(F) You used a declaration similar to C<my $x if 0>.  There
+has been a long-standing bug in Perl that causes a lexical variable
+not to be cleared at scope exit when its declaration includes a false
+conditional.  Some people have exploited this bug to achieve a kind of
+static variable.  Since we intend to fix this bug, we don't want people
+relying on this behavior.  You can achieve a similar static effect by
+declaring the variable in a separate block outside the function, eg
+
+    sub f { my $x if 0; return $x++ }
+
+becomes
+
+    { my $x; sub f { return $x++ } }
+
+Beginning with perl 5.10.0, you can also use C<state> variables to have
+lexicals that are initialized only once (see L<feature>):
+
+    sub f { state $x; return $x++ }
+
+This use of C<my()> in a false conditional was deprecated beginning in
+Perl 5.10 and became a fatal error in Perl 5.30.
+
 =item That use of $[ is unsupported
 
 (F) Assignment to C<$[> is now strictly circumscribed, and interpreted
diff --git a/t/lib/warnings/op b/t/lib/warnings/op
index 54e2e3de20..c193d47837 100644
--- a/t/lib/warnings/op
+++ b/t/lib/warnings/op
@@ -1675,13 +1675,6 @@ Useless localization of match position at - line 49.
 Useless localization of vec at - line 50.
 ########
 # op.c
-my $x1 if 0;
-my @x2 if 0;
-my %x3 if 0;
-my ($x4) if 0;
-my ($x5,@x6, %x7) if 0;
-0 && my $z1;
-0 && my (%z2);
 # these shouldn't warn
 our $x if 0;
 our $x unless 0;
@@ -1690,13 +1683,6 @@ if (my $w2) { $a=1 }
 if ($a && (my $w3 = 1)) {$a = 2}
 
 EXPECT
-Deprecated use of my() in false conditional. This will be a fatal error in Perl 5.30 at - line 2.
-Deprecated use of my() in false conditional. This will be a fatal error in Perl 5.30 at - line 3.
-Deprecated use of my() in false conditional. This will be a fatal error in Perl 5.30 at - line 4.
-Deprecated use of my() in false conditional. This will be a fatal error in Perl 5.30 at - line 5.
-Deprecated use of my() in false conditional. This will be a fatal error in Perl 5.30 at - line 6.
-Deprecated use of my() in false conditional. This will be a fatal error in Perl 5.30 at - line 7.
-Deprecated use of my() in false conditional. This will be a fatal error in Perl 5.30 at - line 8.
 ########
 # op.c
 $[ = 1;
-- 
2.17.1

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Sep 25, 2018

From @jkeenan

133543-0002-Test-for-expected-error-messages-for-my-in-false-con.patch
From c5941fb0024f03fd78e1822edeba718226a87903 Mon Sep 17 00:00:00 2001
From: James E Keenan <jkeenan@cpan.org>
Date: Tue, 25 Sep 2018 15:55:10 -0400
Subject: [PATCH 2/2] Test for expected error messages for my() in false
 conditional.

---
 t/op/my.t | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/t/op/my.t b/t/op/my.t
index 35211068d7..59c9087d1d 100644
--- a/t/op/my.t
+++ b/t/op/my.t
@@ -154,5 +154,21 @@ is( $@, '', "eval of my() passes");
 eval 'my($a,$b),$x,my($c,$d)';
 pass("RT #126844");
 
+# RT # to come
+my @false_conditionals = (
+    'my $x1 if 0;',
+    'my @x2 if 0;',
+    'my %x3 if 0;',
+    'my ($x4) if 0;',
+    'my ($x5,@x6, %x7) if 0;',
+    '0 && my $z1;',
+    '0 && my (%z2);',
+);
+for my $fc (@false_conditionals) {
+    eval $fc;
+    like( $@, qr/^This use of my\(\) in false conditional is no longer allowed/,
+        "my() in false conditional");
+}
+
 #Variable number of tests due to the way the while/for loops are tested now
 done_testing();
-- 
2.17.1

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Sep 25, 2018

From [Unknown Contact. See original ticket]

On Tue, 25 Sep 2018 19​:58​:32 GMT, jkeenan@​pobox.com wrote​:

I am here creating a ticket for an item mentioned on the mailing list​:
the fatalization of my() in false conditional. (I haven't found an
existing RT for this item, though there does exist a META ticket.)

According to the perl-5.28.0 source code, the following deprecation is
scheduled for perl-5.30​:

#####
op.c-8260- && o2->op_private & OPpLVAL_INTRO
op.c-8261- && !(o2->op_private & OPpPAD_STATE))
op.c-8262- {
op.c-8263- Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED),
op.c-8264- "Deprecated use of my() in
false conditional. "
op.c​:8265​: "This will be a fatal error in
Perl 5.30");
op.c-8266- }
op.c-8267-
op.c-8268- *otherp = NULL;
op.c-8269- if (cstop->op_type == OP_CONST)
op.c-8270- cstop->op_private |= OPpCONST_SHORTCIRCUIT;
#####

And that entails revision of this documentation​:

#####
pod/perldiag.pod-2016-
pod/perldiag.pod-2017-(F) In a here document construct like C<<<FOO>,
the label C<FOO> is too
pod/perldiag.pod-2018-long for Perl to handle. You have to be seriously
twisted to write code
pod/perldiag.pod-2019-that triggers this error.
pod/perldiag.pod-2020-
pod/perldiag.pod​:2021​:=item Deprecated use of my() in false conditional.
This will be a fatal error in Perl 5.30
pod/perldiag.pod-2022-
pod/perldiag.pod-2023-(D deprecated) You used a declaration similar to
C<my $x if 0>. There
pod/perldiag.pod-2024-has been a long-standing bug in Perl that causes a
lexical variable
pod/perldiag.pod-2025-not to be cleared at scope exit when its
declaration includes a false
pod/perldiag.pod-2026-conditional. Some people have exploited this bug
to achieve a kind of
--
pod/perldiag.pod-2038-lexicals that are initialized only once (see
L<feature>)​:
pod/perldiag.pod-2039-
pod/perldiag.pod-2040- sub f { state $x; return $x++ }
pod/perldiag.pod-2041-
pod/perldiag.pod-2042-This use of C<my()> in a false conditional has
been deprecated since
pod/perldiag.pod​:2043​:Perl 5.10, and it will become a fatal error in
Perl 5.30.
pod/perldiag.pod-2044-
pod/perldiag.pod-2045-=item DESTROY created new reference to dead object
'%s'
pod/perldiag.pod-2046-
pod/perldiag.pod-2047-(F) A DESTROY() method created a new reference to
the object which is
pod/perldiag.pod-2048-just being DESTROYed. Perl is confused, and
prefers to abort rather
#####

I will attach patches which constitute a (crude) first pass at
implementing this fatalization. This will be smoke-testing in a branch
which I will push as soon as I get an RT number.

Thank you very much.
Jim Keenan

Smoke-testing branch​:

smoke-me/jkeenan/133543-my-false-conditional

Patches attached.

Thank you very much.
--
James E Keenan (jkeenan@​cpan.org)

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Sep 26, 2018

From @jkeenan

On Tue, 25 Sep 2018 20​:03​:34 GMT, jkeenan wrote​:

On Tue, 25 Sep 2018 19​:58​:32 GMT, jkeenan@​pobox.com wrote​:

I am here creating a ticket for an item mentioned on the mailing list​:
the fatalization of my() in false conditional. (I haven't found an
existing RT for this item, though there does exist a META ticket.)

According to the perl-5.28.0 source code, the following deprecation is
scheduled for perl-5.30​:

#####
op.c-8260- && o2->op_private & OPpLVAL_INTRO
op.c-8261- && !(o2->op_private & OPpPAD_STATE))
op.c-8262- {
op.c-8263- Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED),
op.c-8264- "Deprecated use of my() in
false conditional. "
op.c​:8265​: "This will be a fatal error in
Perl 5.30");
op.c-8266- }
op.c-8267-
op.c-8268- *otherp = NULL;
op.c-8269- if (cstop->op_type == OP_CONST)
op.c-8270- cstop->op_private |= OPpCONST_SHORTCIRCUIT;
#####

And that entails revision of this documentation​:

#####
pod/perldiag.pod-2016-
pod/perldiag.pod-2017-(F) In a here document construct like C<<<FOO>,
the label C<FOO> is too
pod/perldiag.pod-2018-long for Perl to handle. You have to be seriously
twisted to write code
pod/perldiag.pod-2019-that triggers this error.
pod/perldiag.pod-2020-
pod/perldiag.pod​:2021​:=item Deprecated use of my() in false conditional.
This will be a fatal error in Perl 5.30
pod/perldiag.pod-2022-
pod/perldiag.pod-2023-(D deprecated) You used a declaration similar to
C<my $x if 0>. There
pod/perldiag.pod-2024-has been a long-standing bug in Perl that causes a
lexical variable
pod/perldiag.pod-2025-not to be cleared at scope exit when its
declaration includes a false
pod/perldiag.pod-2026-conditional. Some people have exploited this bug
to achieve a kind of
--
pod/perldiag.pod-2038-lexicals that are initialized only once (see
L<feature>)​:
pod/perldiag.pod-2039-
pod/perldiag.pod-2040- sub f { state $x; return $x++ }
pod/perldiag.pod-2041-
pod/perldiag.pod-2042-This use of C<my()> in a false conditional has
been deprecated since
pod/perldiag.pod​:2043​:Perl 5.10, and it will become a fatal error in
Perl 5.30.
pod/perldiag.pod-2044-
pod/perldiag.pod-2045-=item DESTROY created new reference to dead object
'%s'
pod/perldiag.pod-2046-
pod/perldiag.pod-2047-(F) A DESTROY() method created a new reference to
the object which is
pod/perldiag.pod-2048-just being DESTROYed. Perl is confused, and
prefers to abort rather
#####

I will attach patches which constitute a (crude) first pass at
implementing this fatalization. This will be smoke-testing in a branch
which I will push as soon as I get an RT number.

Thank you very much.
Jim Keenan

Smoke-testing branch​:

smoke-me/jkeenan/133543-my-false-conditional

I realize that the branch I created yesterday was forked from another branch rather than from blead.

I have created a new branch (with the same name) based off blead. In this branch I have refined the tests a bit but have made no further changes to op.c.

Patches attached.

Better patches attached.

Thank you very much.

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Sep 26, 2018

From @jkeenan

133543-0001-Implement-scheduled-fatalization-of-my-in-false-cond.patch
From ebcefe3eec2fc12fcb7d3c494efb33515cd02391 Mon Sep 17 00:00:00 2001
From: James E Keenan <jkeenan@cpan.org>
Date: Tue, 25 Sep 2018 15:28:46 -0400
Subject: [PATCH 1/2] Implement scheduled fatalization of my() in false
 conditional

op.c: substitute exception for warning.  Move documentation in perldiag
from W to F.  Remove tests for warnings for such statements.
---
 op.c              |  5 ++---
 pod/perldiag.pod  | 39 +++++++++++++++++++++++++++++++++++++++
 t/lib/warnings/op | 14 --------------
 3 files changed, 41 insertions(+), 17 deletions(-)

diff --git a/op.c b/op.c
index 03f066dfc6..146407ba70 100644
--- a/op.c
+++ b/op.c
@@ -8260,9 +8260,8 @@ S_new_logop(pTHX_ I32 type, I32 flags, OP** firstp, OP** otherp)
 		&& o2->op_private & OPpLVAL_INTRO
 		&& !(o2->op_private & OPpPAD_STATE))
 	    {
-		Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED),
-                                "Deprecated use of my() in false conditional. "
-                                "This will be a fatal error in Perl 5.30");
+        Perl_croak(aTHX_ "This use of my() in false conditional is "
+                          "no longer allowed");
 	    }
 
 	    *otherp = NULL;
diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index 17b96caad1..2c063685c0 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -6110,6 +6110,21 @@ a dirhandle.  Check your control flow.
 (W unopened) You tried to use the tell() function on a filehandle that
 was either never opened or has since been closed.
 
+=item That use of $[ is unsupported
+
+(F) Assignment to C<$[> is now strictly circumscribed, and interpreted
+as a compiler directive.  You may say only one of
+
+    $[ = 0;
+    $[ = 1;
+    ...
+    local $[ = 0;
+    local $[ = 1;
+    ...
+
+This is to prevent the problem of one module changing the array base out
+from under another module inadvertently.  See L<perlvar/$[> and L<arybase>.
+
 =item The alpha_assertions feature is experimental
 
 (S experimental::alpha_assertions) This feature is experimental
@@ -6198,6 +6213,30 @@ key traversal, but this Perl has been compiled without it.  You should
 report this warning to the relevant upstream party, or recompile perl
 with default options.
 
+=item This use of my() in false conditional is no longer allowed
+
+(F) You used a declaration similar to C<my $x if 0>.  There
+has been a long-standing bug in Perl that causes a lexical variable
+not to be cleared at scope exit when its declaration includes a false
+conditional.  Some people have exploited this bug to achieve a kind of
+static variable.  Since we intend to fix this bug, we don't want people
+relying on this behavior.  You can achieve a similar static effect by
+declaring the variable in a separate block outside the function, eg
+
+    sub f { my $x if 0; return $x++ }
+
+becomes
+
+    { my $x; sub f { return $x++ } }
+
+Beginning with perl 5.10.0, you can also use C<state> variables to have
+lexicals that are initialized only once (see L<feature>):
+
+    sub f { state $x; return $x++ }
+
+This use of C<my()> in a false conditional was deprecated beginning in
+Perl 5.10 and became a fatal error in Perl 5.30.
+
 =item times not implemented
 
 (F) Your version of the C library apparently doesn't do times().  I
diff --git a/t/lib/warnings/op b/t/lib/warnings/op
index a2a1e2e3fa..85297836d2 100644
--- a/t/lib/warnings/op
+++ b/t/lib/warnings/op
@@ -1675,13 +1675,6 @@ Useless localization of match position at - line 49.
 Useless localization of vec at - line 50.
 ########
 # op.c
-my $x1 if 0;
-my @x2 if 0;
-my %x3 if 0;
-my ($x4) if 0;
-my ($x5,@x6, %x7) if 0;
-0 && my $z1;
-0 && my (%z2);
 # these shouldn't warn
 our $x if 0;
 our $x unless 0;
@@ -1690,13 +1683,6 @@ if (my $w2) { $a=1 }
 if ($a && (my $w3 = 1)) {$a = 2}
 
 EXPECT
-Deprecated use of my() in false conditional. This will be a fatal error in Perl 5.30 at - line 2.
-Deprecated use of my() in false conditional. This will be a fatal error in Perl 5.30 at - line 3.
-Deprecated use of my() in false conditional. This will be a fatal error in Perl 5.30 at - line 4.
-Deprecated use of my() in false conditional. This will be a fatal error in Perl 5.30 at - line 5.
-Deprecated use of my() in false conditional. This will be a fatal error in Perl 5.30 at - line 6.
-Deprecated use of my() in false conditional. This will be a fatal error in Perl 5.30 at - line 7.
-Deprecated use of my() in false conditional. This will be a fatal error in Perl 5.30 at - line 8.
 ########
 # op.c
 use warnings 'void';
-- 
2.17.1

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Sep 26, 2018

From @jkeenan

133543-0002-Test-for-expected-error-messages-for-my-in-false-con.patch
From f5ad196364e0930e46cc2bb734949030406896c7 Mon Sep 17 00:00:00 2001
From: James E Keenan <jkeenan@cpan.org>
Date: Tue, 25 Sep 2018 15:55:10 -0400
Subject: [PATCH 2/2] Test for expected error messages for my() in false
 conditional.

Make new tests more self-documenting.

For: RT 133543
---
 t/op/my.t | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/t/op/my.t b/t/op/my.t
index 35211068d7..5ac382cfe7 100644
--- a/t/op/my.t
+++ b/t/op/my.t
@@ -154,5 +154,21 @@ is( $@, '', "eval of my() passes");
 eval 'my($a,$b),$x,my($c,$d)';
 pass("RT #126844");
 
+# RT # 133543
+my @false_conditionals = (
+    'my $x1 if 0;',
+    'my @x2 if 0;',
+    'my %x3 if 0;',
+    'my ($x4) if 0;',
+    'my ($x5,@x6, %x7) if 0;',
+    '0 && my $z1;',
+    '0 && my (%z2);',
+);
+for (my $i=0; $i<=$#false_conditionals; $i++) {
+    eval $false_conditionals[$i];
+    like( $@, qr/^This use of my\(\) in false conditional is no longer allowed/,
+        "RT #133543: my() in false conditional: $false_conditionals[$i]");
+}
+
 #Variable number of tests due to the way the while/for loops are tested now
 done_testing();
-- 
2.17.1

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Sep 26, 2018

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

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Sep 29, 2018

From @jkeenan

On Wed, 26 Sep 2018 14​:34​:08 GMT, jkeenan wrote​:

On Tue, 25 Sep 2018 20​:03​:34 GMT, jkeenan wrote​:

On Tue, 25 Sep 2018 19​:58​:32 GMT, jkeenan@​pobox.com wrote​:

I am here creating a ticket for an item mentioned on the mailing
list​:
the fatalization of my() in false conditional. (I haven't found an
existing RT for this item, though there does exist a META ticket.)

According to the perl-5.28.0 source code, the following deprecation
is
scheduled for perl-5.30​:

#####
op.c-8260- && o2->op_private & OPpLVAL_INTRO
op.c-8261- && !(o2->op_private & OPpPAD_STATE))
op.c-8262- {
op.c-8263- Perl_ck_warner_d(aTHX_
packWARN(WARN_DEPRECATED),
op.c-8264- "Deprecated use of my()
in
false conditional. "
op.c​:8265​: "This will be a fatal
error in
Perl 5.30");
op.c-8266- }
op.c-8267-
op.c-8268- *otherp = NULL;
op.c-8269- if (cstop->op_type == OP_CONST)
op.c-8270- cstop->op_private |= OPpCONST_SHORTCIRCUIT;
#####

And that entails revision of this documentation​:

#####
pod/perldiag.pod-2016-
pod/perldiag.pod-2017-(F) In a here document construct like
C<<<FOO>,
the label C<FOO> is too
pod/perldiag.pod-2018-long for Perl to handle. You have to be
seriously
twisted to write code
pod/perldiag.pod-2019-that triggers this error.
pod/perldiag.pod-2020-
pod/perldiag.pod​:2021​:=item Deprecated use of my() in false
conditional.
This will be a fatal error in Perl 5.30
pod/perldiag.pod-2022-
pod/perldiag.pod-2023-(D deprecated) You used a declaration
similar to
C<my $x if 0>. There
pod/perldiag.pod-2024-has been a long-standing bug in Perl that
causes a
lexical variable
pod/perldiag.pod-2025-not to be cleared at scope exit when its
declaration includes a false
pod/perldiag.pod-2026-conditional. Some people have exploited
this bug
to achieve a kind of
--
pod/perldiag.pod-2038-lexicals that are initialized only once (see
L<feature>)​:
pod/perldiag.pod-2039-
pod/perldiag.pod-2040- sub f { state $x; return $x++ }
pod/perldiag.pod-2041-
pod/perldiag.pod-2042-This use of C<my()> in a false conditional
has
been deprecated since
pod/perldiag.pod​:2043​:Perl 5.10, and it will become a fatal error
in
Perl 5.30.
pod/perldiag.pod-2044-
pod/perldiag.pod-2045-=item DESTROY created new reference to dead
object
'%s'
pod/perldiag.pod-2046-
pod/perldiag.pod-2047-(F) A DESTROY() method created a new
reference to
the object which is
pod/perldiag.pod-2048-just being DESTROYed. Perl is confused, and
prefers to abort rather
#####

I will attach patches which constitute a (crude) first pass at
implementing this fatalization. This will be smoke-testing in a
branch
which I will push as soon as I get an RT number.

Thank you very much.
Jim Keenan

Smoke-testing branch​:

smoke-me/jkeenan/133543-my-false-conditional

I realize that the branch I created yesterday was forked from another
branch rather than from blead.

I have created a new branch (with the same name) based off blead. In
this branch I have refined the tests a bit but have made no further
changes to op.c.

Patches attached.

Better patches attached.

Could the most recent version of each patch (or the smoke-me/jkeenan/133543-my-false-conditional branch) be evaluated with respect to​:

* Use of the Perl_croak function

* Choice of warning message

* Performing the fatalization scheduled for perl-5.30

Thank you very much.
--
James E Keenan (jkeenan@​cpan.org)

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Oct 3, 2018

From @jkeenan

On Sat, 29 Sep 2018 23​:37​:03 GMT, jkeenan wrote​:

On Wed, 26 Sep 2018 14​:34​:08 GMT, jkeenan wrote​:

On Tue, 25 Sep 2018 20​:03​:34 GMT, jkeenan wrote​:

On Tue, 25 Sep 2018 19​:58​:32 GMT, jkeenan@​pobox.com wrote​:

I am here creating a ticket for an item mentioned on the mailing
list​:
the fatalization of my() in false conditional. (I haven't found
an
existing RT for this item, though there does exist a META
ticket.)

According to the perl-5.28.0 source code, the following
deprecation
is
scheduled for perl-5.30​:

#####
op.c-8260- && o2->op_private & OPpLVAL_INTRO
op.c-8261- && !(o2->op_private & OPpPAD_STATE))
op.c-8262- {
op.c-8263- Perl_ck_warner_d(aTHX_
packWARN(WARN_DEPRECATED),
op.c-8264- "Deprecated use of
my()
in
false conditional. "
op.c​:8265​: "This will be a fatal
error in
Perl 5.30");
op.c-8266- }
op.c-8267-
op.c-8268- *otherp = NULL;
op.c-8269- if (cstop->op_type == OP_CONST)
op.c-8270- cstop->op_private |= OPpCONST_SHORTCIRCUIT;
#####

And that entails revision of this documentation​:

#####
pod/perldiag.pod-2016-
pod/perldiag.pod-2017-(F) In a here document construct like
C<<<FOO>,
the label C<FOO> is too
pod/perldiag.pod-2018-long for Perl to handle. You have to be
seriously
twisted to write code
pod/perldiag.pod-2019-that triggers this error.
pod/perldiag.pod-2020-
pod/perldiag.pod​:2021​:=item Deprecated use of my() in false
conditional.
This will be a fatal error in Perl 5.30
pod/perldiag.pod-2022-
pod/perldiag.pod-2023-(D deprecated) You used a declaration
similar to
C<my $x if 0>. There
pod/perldiag.pod-2024-has been a long-standing bug in Perl that
causes a
lexical variable
pod/perldiag.pod-2025-not to be cleared at scope exit when its
declaration includes a false
pod/perldiag.pod-2026-conditional. Some people have exploited
this bug
to achieve a kind of
--
pod/perldiag.pod-2038-lexicals that are initialized only once
(see
L<feature>)​:
pod/perldiag.pod-2039-
pod/perldiag.pod-2040- sub f { state $x; return $x++ }
pod/perldiag.pod-2041-
pod/perldiag.pod-2042-This use of C<my()> in a false conditional
has
been deprecated since
pod/perldiag.pod​:2043​:Perl 5.10, and it will become a fatal error
in
Perl 5.30.
pod/perldiag.pod-2044-
pod/perldiag.pod-2045-=item DESTROY created new reference to dead
object
'%s'
pod/perldiag.pod-2046-
pod/perldiag.pod-2047-(F) A DESTROY() method created a new
reference to
the object which is
pod/perldiag.pod-2048-just being DESTROYed. Perl is confused,
and
prefers to abort rather
#####

I will attach patches which constitute a (crude) first pass at
implementing this fatalization. This will be smoke-testing in a
branch
which I will push as soon as I get an RT number.

Thank you very much.
Jim Keenan

Smoke-testing branch​:

smoke-me/jkeenan/133543-my-false-conditional

I realize that the branch I created yesterday was forked from another
branch rather than from blead.

I have created a new branch (with the same name) based off blead. In
this branch I have refined the tests a bit but have made no further
changes to op.c.

Patches attached.

Better patches attached.

Could the most recent version of each patch (or the smoke-
me/jkeenan/133543-my-false-conditional branch) be evaluated with
respect to​:

* Use of the Perl_croak function

* Choice of warning message

* Performing the fatalization scheduled for perl-5.30

Warnocked. Pushed to blead in commit 1f692f6.

Please continue to review with respect to the 3 criteria mentioned in the previous post.

I'm taking this ticket for the purpose of closing it within 7 days unless we get objections.

Thank you very much.
--
James E Keenan (jkeenan@​cpan.org)

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Oct 10, 2018

@jkeenan - Status changed from 'open' to 'pending release'

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Dec 13, 2018

From andreas@guldstrand.info

Hi,

This code still does not cause an error even on latest blead perl​:

my $x = 0 if 0;

/ Andreas G

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Dec 13, 2018

From @jkeenan

Hi,

This code still does not cause an error even on latest blead perl​:

my $x = 0 if 0;

/ Andreas G

If I recall correctly, we were not able to fatalize *all* instances of
'my' in false conditional. The error message was therefore deliberately
worded to start with 'This'.

#####
This use of my() in false conditional is no longer allowed
#####

Thank you very much.
Jim Keenan

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented May 22, 2019

From @khwilliamson

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.

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented May 22, 2019

@khwilliamson - Status changed from 'pending release' to 'resolved'

@p5pRT p5pRT closed this May 22, 2019
@toddr toddr added this to the 5.30.0 milestone Oct 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.