From: Gurusamy Sarathy Date: Sun, 5 Mar 2000 04:30:02 +0000 (+0000) Subject: scan_num() sticks to UVs rather than IVs (now -2147483648 doesn't X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=9b0e499bcdd1e62b4ead7739d3482d056b5ac3dc;p=p5sagit%2Fp5-mst-13.2.git scan_num() sticks to UVs rather than IVs (now -2147483648 doesn't end up being promoted to an NV) p4raw-id: //depot/perl@5533 --- diff --git a/pp.c b/pp.c index ebfe985..fcae1e4 100644 --- a/pp.c +++ b/pp.c @@ -1391,9 +1391,23 @@ PP(pp_negate) dTOPss; if (SvGMAGICAL(sv)) mg_get(sv); - if (SvIOKp(sv) && !SvNOKp(sv) && !SvPOKp(sv) && SvIVX(sv) != IV_MIN) - SETi(-SvIVX(sv)); - else if (SvNIOKp(sv)) + if (SvIOKp(sv) && !SvNOKp(sv) && !SvPOKp(sv)) { + if (SvIsUV(sv)) { + if (SvIVX(sv) == IV_MIN) { + SETi(SvIVX(sv)); /* special case: -((UV)IV_MAX+1) == IV_MIN */ + RETURN; + } + else if (SvUVX(sv) <= IV_MAX) { + SETi(-SvUVX(sv)); + RETURN; + } + } + else if (SvIVX(sv) != IV_MIN) { + SETi(-SvIVX(sv)); + RETURN; + } + } + if (SvNIOKp(sv)) SETn(-SvNV(sv)); else if (SvPOKp(sv)) { STRLEN len; diff --git a/t/op/inc.t b/t/op/inc.t index e5a2a92..f59115e 100755 --- a/t/op/inc.t +++ b/t/op/inc.t @@ -1,9 +1,6 @@ #!./perl - -# $RCSfile$ - -print "1..6\n"; +print "1..12\n"; # Verify that addition/subtraction properly upgrade to doubles. # These tests are only significant on machines with 32 bit longs, @@ -50,3 +47,51 @@ if ($a == -2147483649) {print "ok 6\n"} else {print "not ok 6\n";} + +$a = 2147483648; +$a = -$a; +$c=$a--; +if ($a == -2147483649) + {print "ok 7\n"} +else + {print "not ok 7\n";} + +$a = 2147483648; +$a = -$a; +$c=--$a; +if ($a == -2147483649) + {print "ok 8\n"} +else + {print "not ok 8\n";} + +$a = 2147483648; +$a = -$a; +$a=$a-1; +if ($a == -2147483649) + {print "ok 9\n"} +else + {print "not ok 9\n";} + +$a = 2147483648; +$b = -$a; +$c=$b--; +if ($b == -$a-1) + {print "ok 10\n"} +else + {print "not ok 10\n";} + +$a = 2147483648; +$b = -$a; +$c=--$b; +if ($b == -$a-1) + {print "ok 11\n"} +else + {print "not ok 11\n";} + +$a = 2147483648; +$b = -$a; +$b=$b-1; +if ($b == -(++$a)) + {print "ok 12\n"} +else + {print "not ok 12\n";} diff --git a/toke.c b/toke.c index 79ee972..8a21303 100644 --- a/toke.c +++ b/toke.c @@ -5640,7 +5640,7 @@ S_checkcomma(pTHX_ register char *s, char *name, char *what) STATIC SV * S_new_constant(pTHX_ char *s, STRLEN len, const char *key, SV *sv, SV *pv, - const char *type) + const char *type) { dSP; HV *table = GvHV(PL_hintgv); /* ^H */ @@ -5700,8 +5700,7 @@ S_new_constant(pTHX_ char *s, STRLEN len, const char *key, SV *sv, SV *pv, SPAGAIN ; /* Check the eval first */ - if (!PL_in_eval && SvTRUE(ERRSV)) - { + if (!PL_in_eval && SvTRUE(ERRSV)) { STRLEN n_a; sv_catpv(ERRSV, "Propagated"); yyerror(SvPV(ERRSV, n_a)); /* Duplicates the message inside eval */ @@ -5724,9 +5723,9 @@ S_new_constant(pTHX_ char *s, STRLEN len, const char *key, SV *sv, SV *pv, why2 = key; sv = res; goto report; - } + } - return res; + return res; } STATIC char * @@ -6684,7 +6683,7 @@ Perl_scan_num(pTHX_ char *start) register char *s = start; /* current position in buffer */ register char *d; /* destination in temp buffer */ register char *e; /* end of temp buffer */ - IV tryiv; /* used to see if it can be an IV */ + UV tryuv; /* used to see if it can be an UV */ NV value; /* number read, as a double */ SV *sv = Nullsv; /* place to put the converted number */ bool floatit; /* boolean: int or float? */ @@ -6954,9 +6953,9 @@ Perl_scan_num(pTHX_ char *start) Note: if floatit is true, then we don't need to do the conversion at all. */ - tryiv = I_V(value); - if (!floatit && (NV)tryiv == value) - sv_setiv(sv, tryiv); + tryuv = U_V(value); + if (!floatit && (NV)tryuv == value) + sv_setuv(sv, tryuv); else sv_setnv(sv, value); if ( floatit ? (PL_hints & HINT_NEW_FLOAT) :