Skip to content

Commit a0b9367

Browse files
committed
Prevent misleading undefined value warnings for defelem magic
This could warn within a function was called with a parameter that was a hash element based on an undef key that didn't exist when that parameter was referenced. This also warns more usefully at the point of call.
1 parent 09d9a88 commit a0b9367

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

mg.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2616,7 +2616,8 @@ Perl_defelem_target(pTHX_ SV *sv, MAGIC *mg)
26162616
if (LvTARGLEN(sv)) {
26172617
if (mg->mg_obj) {
26182618
SV * const ahv = LvTARG(sv);
2619-
HE * const he = hv_fetch_ent(MUTABLE_HV(ahv), mg->mg_obj, FALSE, 0);
2619+
SV * const index_sv = SvOK(mg->mg_obj) ? mg->mg_obj : &PL_sv_no;
2620+
HE * const he = hv_fetch_ent(MUTABLE_HV(ahv), index_sv, FALSE, 0);
26202621
if (he)
26212622
targ = HeVAL(he);
26222623
}

t/lib/warnings/mg

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,54 @@ Use of uninitialized value $3 in oct at - line 3.
7979
use warnings 'uninitialized';
8080
$ENV{FOO} = undef; # should not warn
8181
EXPECT
82+
########
83+
# NAME Use of uninitialized value $_[0] in defined operator
84+
# github 22423
85+
use warnings 'uninitialized';
86+
sub f { defined $_[0] }
87+
my $s;
88+
my %h;
89+
f($h{$s});
90+
EXPECT
91+
Use of uninitialized value $s in hash element at - line 6.
92+
########
93+
# NAME Use of uninitialized value $_[0] in defined operator (tied)
94+
# github 22423
95+
# should we allow tied hashes to distinguish between undef and ""
96+
# without warning? For now test the current behaviour
97+
use v5.36;
98+
++$|;
99+
sub f { defined $_[0] }
100+
my $s;
101+
tie my %h, "Foo";
102+
f($h{$s});
103+
$h{+undef} = 1;
104+
$h{""} = 2;
105+
say $h{+undef};
106+
f($h{$s});
107+
108+
package Foo;
109+
110+
sub TIEHASH {
111+
bless {}, shift;
112+
}
113+
sub STORE {
114+
my ($self, $index, $val) = @_;
115+
$self->{defined $index ? $index : "+undef"} = $val;
116+
}
117+
sub FETCH {
118+
my ($self, $index) = @_;
119+
$self->{defined $index ? $index : "+undef"};
120+
}
121+
sub EXISTS {
122+
my ($self, $index) = @_;
123+
exists $self->{defined $index ? $index : "+undef"};
124+
}
125+
126+
EXPECT
127+
Use of uninitialized value $s in hash element at - line 9.
128+
Use of uninitialized value in hash element at - line 10.
129+
Use of uninitialized value in hash element at - line 12.
130+
1
131+
Use of uninitialized value $s in hash element at - line 13.
132+

0 commit comments

Comments
 (0)