Skip to content

Commit 6edc33d

Browse files
t-a-kkhwilliamson
authored andcommitted
pp.c, pp_hot.c: Reorder SvXV_nomg() to fetch operands in left-to-right order
Some binary (2-operand) operators, notably arithmetic add (+) and subtract (-), used to fetch its RHS operand first then LHS one, so they would issue "use of uninitialized value" warnings in right-to-left order: % perl -wle 'print $a + $b' Use of uninitialized value $b in addition (+) at -e line 1. Use of uninitialized value $a in addition (+) at -e line 1. 0 % I think this is not intuitive for users, as "perlop" says that "Perl has a general rule that the operands of an operator are evaluated in left-to-right order." (3-operand case is more surprising; "print $a + $b + $c" will warn in the order $b, $a, $c.) This change reverses the operand fetch order in these operators to issue warnings in left-to-right order. t/lib/warnings/9uninit: Reorder expected warnings in left-to-right order. pod/perldelta.pod: Add perldelta entry for this change.
1 parent d349122 commit 6edc33d

File tree

4 files changed

+80
-79
lines changed

4 files changed

+80
-79
lines changed

pod/perldelta.pod

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,14 @@ XXX Changes (i.e. rewording) of diagnostic messages go here
220220

221221
XXX Describe change here
222222

223+
=item *
224+
225+
L<Use of uninitialized value%s|perldiag/"Use of uninitialized value%s">
226+
227+
This warning was issued in the reverse order (right-to-left) when both
228+
operands of a binary operator are uninitialized values. This is now
229+
fixed to be consistent with evaluation order of operands.
230+
223231
=back
224232

225233
=head1 Utility Changes

pp.c

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,8 +1483,8 @@ PP(pp_multiply)
14831483
} /* SvIOK(svr) */
14841484
#endif
14851485
{
1486-
NV right = SvNV_nomg(svr);
14871486
NV left = SvNV_nomg(svl);
1487+
NV right = SvNV_nomg(svr);
14881488
NV result = left * right;
14891489

14901490
#if defined(__sgi) && defined(USE_LONG_DOUBLE) && LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_BE && NVSIZE == 16
@@ -1611,8 +1611,8 @@ PP(pp_divide)
16111611
} /* one operand wasn't SvIOK */
16121612
#endif /* PERL_TRY_UV_DIVIDE */
16131613
{
1614-
NV right = SvNV_nomg(svr);
16151614
NV left = SvNV_nomg(svl);
1615+
NV right = SvNV_nomg(svr);
16161616
#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan)
16171617
if (! Perl_isnan(right) && right == 0.0)
16181618
#else
@@ -2061,14 +2061,10 @@ PP(pp_subtract)
20612061
useleft = USE_LEFT(svl);
20622062
#endif
20632063
{
2064-
NV value = SvNV_nomg(svr);
2065-
2066-
if (!useleft) {
2067-
/* left operand is undef, treat as zero - value */
2068-
TARGn(-value, 1);
2069-
goto ret;
2070-
}
2071-
TARGn(SvNV_nomg(svl) - value, 1);
2064+
/* If left operand is undef, treat as zero - value */
2065+
NV value = useleft ? SvNV_nomg(svl) : 0.0;
2066+
value -= SvNV_nomg(svr);
2067+
TARGn(value, 1);
20722068
goto ret;
20732069
}
20742070

@@ -2356,8 +2352,8 @@ Perl_do_ncmp(pTHX_ SV* const left, SV * const right)
23562352
}
23572353
#endif
23582354
{
2359-
NV const rnv = SvNV_nomg(right);
23602355
NV const lnv = SvNV_nomg(left);
2356+
NV const rnv = SvNV_nomg(right);
23612357

23622358
#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan)
23632359
if (Perl_isnan(lnv) || Perl_isnan(rnv)) {
@@ -2888,8 +2884,8 @@ PP(pp_i_multiply)
28882884
if (rpp_try_AMAGIC_2(mult_amg, AMGf_assign))
28892885
return NORMAL;
28902886

2891-
IV right = SvIV_nomg(PL_stack_sp[0]);
28922887
IV left = SvIV_nomg(PL_stack_sp[-1]);
2888+
IV right = SvIV_nomg(PL_stack_sp[0]);
28932889

28942890
TARGi((IV)((UV)left * (UV)right), 1);
28952891
rpp_replace_2_1_NN(targ);
@@ -2910,10 +2906,10 @@ PP(pp_i_divide)
29102906
SV *left = PL_stack_sp[-1];
29112907

29122908
{
2909+
IV num = SvIV_nomg(left);
29132910
IV value = SvIV_nomg(right);
29142911
if (value == 0)
29152912
DIE(aTHX_ "Illegal division by zero");
2916-
IV num = SvIV_nomg(left);
29172913

29182914
/* avoid FPE_INTOVF on some platforms when num is IV_MIN */
29192915
if (value == -1)
@@ -2936,8 +2932,8 @@ PP(pp_i_modulo)
29362932
if (rpp_try_AMAGIC_2(modulo_amg, AMGf_assign))
29372933
return NORMAL;
29382934

2939-
IV right = SvIV_nomg(PL_stack_sp[0]);
29402935
IV left = SvIV_nomg(PL_stack_sp[-1]);
2936+
IV right = SvIV_nomg(PL_stack_sp[0]);
29412937

29422938
{
29432939
if (!right)
@@ -2962,9 +2958,9 @@ PP(pp_i_add)
29622958
if (rpp_try_AMAGIC_2(add_amg, AMGf_assign))
29632959
return NORMAL;
29642960

2965-
IV right = SvIV_nomg(PL_stack_sp[0]);
29662961
SV *leftsv = PL_stack_sp[-1];
29672962
IV left = USE_LEFT(leftsv) ? SvIV_nomg(leftsv) : 0;
2963+
IV right = SvIV_nomg(PL_stack_sp[0]);
29682964

29692965
TARGi((IV)((UV)left + (UV)right), 1);
29702966
rpp_replace_2_1_NN(targ);
@@ -2981,9 +2977,9 @@ PP(pp_i_subtract)
29812977
if (rpp_try_AMAGIC_2(subtr_amg, AMGf_assign))
29822978
return NORMAL;
29832979

2984-
IV right = SvIV_nomg(PL_stack_sp[0]);
29852980
SV *leftsv = PL_stack_sp[-1];
29862981
IV left = USE_LEFT(leftsv) ? SvIV_nomg(leftsv) : 0;
2982+
IV right = SvIV_nomg(PL_stack_sp[0]);
29872983

29882984
TARGi((IV)((UV)left - (UV)right), 1);
29892985
rpp_replace_2_1_NN(targ);
@@ -2996,8 +2992,8 @@ PP(pp_i_lt)
29962992
if (rpp_try_AMAGIC_2(lt_amg, 0))
29972993
return NORMAL;
29982994

2999-
IV right = SvIV_nomg(PL_stack_sp[0]);
30002995
IV left = SvIV_nomg(PL_stack_sp[-1]);
2996+
IV right = SvIV_nomg(PL_stack_sp[0]);
30012997

30022998
rpp_replace_2_IMM_NN(boolSV(left < right));
30032999
return NORMAL;
@@ -3009,8 +3005,8 @@ PP(pp_i_gt)
30093005
if (rpp_try_AMAGIC_2(gt_amg, 0))
30103006
return NORMAL;
30113007

3012-
IV right = SvIV_nomg(PL_stack_sp[0]);
30133008
IV left = SvIV_nomg(PL_stack_sp[-1]);
3009+
IV right = SvIV_nomg(PL_stack_sp[0]);
30143010

30153011
rpp_replace_2_IMM_NN(boolSV(left > right));
30163012
return NORMAL;
@@ -3022,8 +3018,8 @@ PP(pp_i_le)
30223018
if (rpp_try_AMAGIC_2(le_amg, 0))
30233019
return NORMAL;
30243020

3025-
IV right = SvIV_nomg(PL_stack_sp[0]);
30263021
IV left = SvIV_nomg(PL_stack_sp[-1]);
3022+
IV right = SvIV_nomg(PL_stack_sp[0]);
30273023

30283024
rpp_replace_2_IMM_NN(boolSV(left <= right));
30293025
return NORMAL;
@@ -3035,8 +3031,8 @@ PP(pp_i_ge)
30353031
if (rpp_try_AMAGIC_2(ge_amg, 0))
30363032
return NORMAL;
30373033

3038-
IV right = SvIV_nomg(PL_stack_sp[0]);
30393034
IV left = SvIV_nomg(PL_stack_sp[-1]);
3035+
IV right = SvIV_nomg(PL_stack_sp[0]);
30403036

30413037
rpp_replace_2_IMM_NN(boolSV(left >= right));
30423038
return NORMAL;
@@ -3048,8 +3044,8 @@ PP(pp_i_eq)
30483044
if (rpp_try_AMAGIC_2(eq_amg, 0))
30493045
return NORMAL;
30503046

3051-
IV right = SvIV_nomg(PL_stack_sp[0]);
30523047
IV left = SvIV_nomg(PL_stack_sp[-1]);
3048+
IV right = SvIV_nomg(PL_stack_sp[0]);
30533049

30543050
rpp_replace_2_IMM_NN(boolSV(left == right));
30553051
return NORMAL;
@@ -3061,8 +3057,8 @@ PP(pp_i_ne)
30613057
if (rpp_try_AMAGIC_2(ne_amg, 0))
30623058
return NORMAL;
30633059

3064-
IV right = SvIV_nomg(PL_stack_sp[0]);
30653060
IV left = SvIV_nomg(PL_stack_sp[-1]);
3061+
IV right = SvIV_nomg(PL_stack_sp[0]);
30663062

30673063
rpp_replace_2_IMM_NN(boolSV(left != right));
30683064
return NORMAL;
@@ -3075,8 +3071,8 @@ PP(pp_i_ncmp)
30753071
if (rpp_try_AMAGIC_2(ncmp_amg, 0))
30763072
return NORMAL;
30773073

3078-
IV right = SvIV_nomg(PL_stack_sp[0]);
30793074
IV left = SvIV_nomg(PL_stack_sp[-1]);
3075+
IV right = SvIV_nomg(PL_stack_sp[0]);
30803076

30813077

30823078
{
@@ -3122,8 +3118,8 @@ PP(pp_atan2)
31223118
if (rpp_try_AMAGIC_2(atan2_amg, 0))
31233119
return NORMAL;
31243120

3125-
NV right = SvNV_nomg(PL_stack_sp[0]);
31263121
NV left = SvNV_nomg(PL_stack_sp[-1]);
3122+
NV right = SvNV_nomg(PL_stack_sp[0]);
31273123

31283124
TARGn(Perl_atan2(left, right), 1);
31293125
rpp_replace_2_1_NN(targ);

pp_hot.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2007,14 +2007,10 @@ PP(pp_add)
20072007
#endif
20082008

20092009
{
2010-
NV value = SvNV_nomg(svr);
2011-
if (!useleft) {
2012-
/* left operand is undef, treat as zero. + 0.0 is identity. */
2013-
TARGn(value, 1);
2014-
}
2015-
else {
2016-
TARGn(value + SvNV_nomg(svl), 1);
2017-
}
2010+
/* If left operand is undef, treat as zero. */
2011+
NV value = useleft ? SvNV_nomg(svl) : 0.0;
2012+
value += SvNV_nomg(svr);
2013+
TARGn(value, 1);
20182014
}
20192015

20202016
ret:

0 commit comments

Comments
 (0)