3f1b01
From 07319fdbb283f93cb655c3106b5237cbc7272038 Mon Sep 17 00:00:00 2001
3f1b01
From: Tomasz Konojacki <me@xenu.pl>
3f1b01
Date: Wed, 30 Dec 2020 14:03:02 +0100
3f1b01
Subject: [PATCH] op.c: croak on "my $_" when "use utf8" is in effect
3f1b01
MIME-Version: 1.0
3f1b01
Content-Type: text/plain; charset=UTF-8
3f1b01
Content-Transfer-Encoding: 8bit
3f1b01
3f1b01
Fixes #18449
3f1b01
3f1b01
Signed-off-by: Petr Písař <ppisar@redhat.com>
3f1b01
---
3f1b01
 op.c         | 16 +++++++++-------
3f1b01
 t/op/mydef.t | 11 +++++++++--
3f1b01
 2 files changed, 18 insertions(+), 9 deletions(-)
3f1b01
3f1b01
diff --git a/op.c b/op.c
3f1b01
index b2e12dd0c0..dce844d297 100644
3f1b01
--- a/op.c
3f1b01
+++ b/op.c
3f1b01
@@ -730,6 +730,7 @@ PADOFFSET
3f1b01
 Perl_allocmy(pTHX_ const char *const name, const STRLEN len, const U32 flags)
3f1b01
 {
3f1b01
     PADOFFSET off;
3f1b01
+    bool is_idfirst, is_default;
3f1b01
     const bool is_our = (PL_parser->in_my == KEY_our);
3f1b01
 
3f1b01
     PERL_ARGS_ASSERT_ALLOCMY;
3f1b01
@@ -738,14 +739,15 @@ Perl_allocmy(pTHX_ const char *const name, const STRLEN len, const U32 flags)
3f1b01
 	Perl_croak(aTHX_ "panic: allocmy illegal flag bits 0x%" UVxf,
3f1b01
 		   (UV)flags);
3f1b01
 
3f1b01
+    is_idfirst = flags & SVf_UTF8
3f1b01
+        ? isIDFIRST_utf8_safe((U8*)name + 1, name + len)
3f1b01
+        : isIDFIRST_A(name[1]);
3f1b01
+
3f1b01
+    /* $_, @_, etc. */
3f1b01
+    is_default = len == 2 && name[1] == '_';
3f1b01
+
3f1b01
     /* complain about "my $<special_var>" etc etc */
3f1b01
-    if (   len
3f1b01
-        && !(  is_our
3f1b01
-            || isALPHA(name[1])
3f1b01
-            || (   (flags & SVf_UTF8)
3f1b01
-                && isIDFIRST_utf8_safe((U8 *)name+1, name + len))
3f1b01
-            || (name[1] == '_' && len > 2)))
3f1b01
-    {
3f1b01
+    if (!is_our && (!is_idfirst || is_default)) {
3f1b01
         const char * const type =
3f1b01
               PL_parser->in_my == KEY_sigvar ? "subroutine signature" :
3f1b01
               PL_parser->in_my == KEY_state  ? "\"state\""     : "\"my\"";
3f1b01
diff --git a/t/op/mydef.t b/t/op/mydef.t
3f1b01
index 42a81d9ab0..225ce98e51 100644
3f1b01
--- a/t/op/mydef.t
3f1b01
+++ b/t/op/mydef.t
3f1b01
@@ -6,10 +6,17 @@ BEGIN {
3f1b01
     set_up_inc('../lib');
3f1b01
 }
3f1b01
 
3f1b01
-plan tests => 1;
3f1b01
-
3f1b01
 use strict;
3f1b01
 
3f1b01
 eval 'my $_';
3f1b01
 like $@, qr/^Can't use global \$_ in "my" at /;
3f1b01
 
3f1b01
+{
3f1b01
+    # using utf8 allows $_ to be declared with 'my'
3f1b01
+    # GH #18449
3f1b01
+    use utf8;
3f1b01
+    eval 'my $_;';
3f1b01
+    like $@, qr/^Can't use global \$_ in "my" at /;
3f1b01
+}
3f1b01
+
3f1b01
+done_testing;
3f1b01
-- 
3f1b01
2.26.2
3f1b01