On Thursday 25 September 2008 00:09:37 Moritz Lenz wrote: > As of today (and r31404) Rakudo's 'make spectest_regression' produces > compile time errors in three files, all of which are related to integer > overflow. > > To reproduce: > $ cd languages/perl6 > $ make spectest_regression > $ ../../parrot perl6.pbc t/spec/S03-operators/arith.rakudo > add_1_const:Integer overflow '2147483648' > current instr.: 'parrot;PCT::HLLCompiler;evalpmc' pc 744 > (src/PCT/HLLCompiler.pir:448) > called from Sub 'parrot;PCT::HLLCompiler;compile' pc 438 > (src/PCT/HLLCompiler.pir:303) > [...] > > I suspect it might be this commit: > > r31402 | chromatic | 2008-09-25 07:30:31 +0200 (Thu, 25 Sep 2008) | 7 lines > > [src] Expanded float precision to 15 digits from 6. One side effect is > that float output no longer always has six digits after the dot; this drops > trailing > zeroes. Most of the changes are to tests which expected specific output > formats. > > The sprintf format %.15g should be portable, but watch the smokes. See RT > #59006, reported by Patrick Michaud.
I suspect it is too. I can't figure out what in PCT is the culprit (something related to printing floats), but here's an IMCC patch which avoids overflow by autopromoting I regs which would overflow to N regs. There's a further refactoring opportunity in here, but I'd like to see if this works first. -- c
=== compilers/imcc/pbc.c ================================================================== --- compilers/imcc/pbc.c (revision 31446) +++ compilers/imcc/pbc.c (local) @@ -1478,8 +1478,9 @@ if (r->type & VT_CONSTP) r = r->reg; - if (r->name[0] == '0' && (r->name[1] == 'x' || r->name[1] == 'X')) + if (r->name[0] == '0' && (r->name[1] == 'x' || r->name[1] == 'X')) { i = strtoul(r->name+2, 0, 16); + } else if (r->name[0] == '0' && (r->name[1] == 'O' || r->name[1] == 'o')) i = strtoul(r->name+2, 0, 8); @@ -1501,6 +1502,32 @@ return i; } +INTVAL +int_reg_does_not_overflow(PARROT_INTERP, ARGIN(const SymReg *r)) +{ + INTVAL i; + + errno = 0; + + if (r->type & VT_CONSTP) + r = r->reg; + + if (r->name[0] == '0' && (r->name[1] == 'x' || r->name[1] == 'X')) { + i = strtoul(r->name + 2, 0, 16); + } + + else if (r->name[0] == '0' && (r->name[1] == 'O' || r->name[1] == 'o')) + i = strtoul(r->name + 2, 0, 8); + + else if (r->name[0] == '0' && (r->name[1] == 'b' || r->name[1] == 'B')) + i = strtoul(r->name + 2, 0, 2); + + else + i = strtol(r->name, 0, 10); + + return errno ? 0 : 1; +} + /* =item C<static void make_pmc_const> @@ -1557,7 +1584,13 @@ switch (r->set) { case 'I': - r->color = IMCC_int_from_reg(interp, r); + if (int_reg_does_not_overflow(interp, r)) { + r->color = IMCC_int_from_reg(interp, r); + } + else { + r->set = 'N'; + r->color = add_const_num(interp, r->name); + } break; case 'S': if (r->type & VT_CONSTP) === compilers/imcc/pbc.h ================================================================== --- compilers/imcc/pbc.h (revision 31446) +++ compilers/imcc/pbc.h (local) @@ -34,6 +34,10 @@ __attribute__nonnull__(1) __attribute__nonnull__(2); +INTVAL int_reg_does_not_overflow(PARROT_INTERP, ARGIN(const SymReg *r)) + __attribute__nonnull__(1) + __attribute__nonnull__(2); + PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL STRING * IMCC_string_from_reg(PARROT_INTERP, ARGIN(const SymReg *r))