summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pp_hot.c17
-rw-r--r--t/lib/warnings/9uninit2
-rw-r--r--t/lib/warnings/pp_hot2
-rwxr-xr-xt/op/tie.t7
4 files changed, 23 insertions, 5 deletions
diff --git a/pp_hot.c b/pp_hot.c
index 813b606b0b..312eef7854 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -148,11 +148,14 @@ PP(pp_concat)
dPOPTOPssrl;
bool lbyte;
STRLEN rlen;
- const char *rpv = SvPV_const(right, rlen); /* mg_get(right) happens here */
- const bool rbyte = !DO_UTF8(right);
+ const char *rpv;
+ bool rbyte;
bool rcopied = FALSE;
if (TARG == right && right != left) {
+ /* mg_get(right) may happen here ... */
+ rpv = SvPV_const(right, rlen);
+ rbyte = !DO_UTF8(right);
right = sv_2mortal(newSVpvn(rpv, rlen));
rpv = SvPV_const(right, rlen); /* no point setting UTF-8 here */
rcopied = TRUE;
@@ -171,14 +174,22 @@ PP(pp_concat)
else { /* TARG == left */
STRLEN llen;
SvGETMAGIC(left); /* or mg_get(left) may happen here */
- if (!SvOK(TARG))
+ if (!SvOK(TARG)) {
+ if (left == right && ckWARN(WARN_UNINITIALIZED))
+ report_uninit(right);
sv_setpvn(left, "", 0);
+ }
(void)SvPV_nomg_const(left, llen); /* Needed to set UTF8 flag */
lbyte = !DO_UTF8(left);
if (IN_BYTES)
SvUTF8_off(TARG);
}
+ /* or mg_get(right) may happen here */
+ if (!rcopied) {
+ rpv = SvPV_const(right, rlen);
+ rbyte = !DO_UTF8(right);
+ }
if (lbyte != rbyte) {
if (lbyte)
sv_utf8_upgrade_nomg(TARG);
diff --git a/t/lib/warnings/9uninit b/t/lib/warnings/9uninit
index 023f85773d..07fffa87eb 100644
--- a/t/lib/warnings/9uninit
+++ b/t/lib/warnings/9uninit
@@ -625,8 +625,8 @@ Use of uninitialized value $m1 in glob elem at - line 5.
Use of uninitialized value $g1 in subroutine prototype at - line 6.
Use of uninitialized value $g1 in bless at - line 7.
Use of uninitialized value $m1 in quoted execution (``, qx) at - line 8.
-Use of uninitialized value $g1 in concatenation (.) or string at - line 10.
Use of uninitialized value $m1 in concatenation (.) or string at - line 10.
+Use of uninitialized value $g1 in concatenation (.) or string at - line 10.
########
use warnings 'uninitialized';
my ($m1);
diff --git a/t/lib/warnings/pp_hot b/t/lib/warnings/pp_hot
index 070aaf0aa5..a0b9b10139 100644
--- a/t/lib/warnings/pp_hot
+++ b/t/lib/warnings/pp_hot
@@ -267,8 +267,8 @@ $x .= $y; # should warn once
$y .= $y; # should warn once
EXPECT
Use of uninitialized value $x in concatenation (.) or string at - line 5.
-Use of uninitialized value $y in concatenation (.) or string at - line 6.
Use of uninitialized value $x in concatenation (.) or string at - line 6.
+Use of uninitialized value $y in concatenation (.) or string at - line 6.
Use of uninitialized value $y in concatenation (.) or string at - line 7.
Use of uninitialized value $y in concatenation (.) or string at - line 8.
########
diff --git a/t/op/tie.t b/t/op/tie.t
index 1fe37e1624..8cb45398ad 100755
--- a/t/op/tie.t
+++ b/t/op/tie.t
@@ -578,3 +578,10 @@ tie $h, "main";
print $h,"\n";
EXPECT
3.3
+########
+sub TIESCALAR { bless {} }
+sub FETCH { shift()->{i} ++ }
+tie $h, "main";
+print $h.$h;
+EXPECT
+01