Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test failures due to integer overflow #340

Closed
p6rt opened this issue Sep 25, 2008 · 10 comments
Closed

Test failures due to integer overflow #340

p6rt opened this issue Sep 25, 2008 · 10 comments

Comments

@p6rt
Copy link

p6rt commented Sep 25, 2008

Migrated from rt.perl.org#59308 (status was 'resolved')

Searchable as RT59308$

@p6rt
Copy link
Author

p6rt commented Sep 25, 2008

From @moritz

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.

Cheers,
Moritz

--
Moritz Lenz
http://moritz.faui2k3.org/ | http://perl-6.de/

@p6rt
Copy link
Author

p6rt commented Sep 25, 2008

From @chromatic

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

@p6rt
Copy link
Author

p6rt commented Sep 25, 2008

From @chromatic

autopromote_int_to_num_IMCC.patch
=== 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))

@p6rt
Copy link
Author

p6rt commented Sep 25, 2008

The RT System itself - Status changed from 'new' to 'open'

@p6rt
Copy link
Author

p6rt commented Sep 25, 2008

From @pmichaud

On Thu, Sep 25, 2008 at 02​:01​:22PM -0700, chromatic wrote​:

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.

I suspect it is too. I can't figure out what in PCT is the culprit
(something related to printing floats),

Floats that are integer values greater than 2147483647 but less than
1e+15 don't have a decimal point or 'e' notation when they stringify,
so when IMCC gets a hold of them it carps about integers being out
of range.

Oddly, placing an 'L' at the end of the value seems to solve things​:

  assign $P0, 999999999999999 # IMCC integer overflow
  assign $P0, 999999999999999L # works

I was working on having PCT recognize floats in this range and
then adding the 'L' when needed, but autopromoting I constants
to N constants seems like the right thing to do here.

More in a bit.

Pm

@p6rt
Copy link
Author

p6rt commented Sep 25, 2008

From @pmichaud

Here's a patch that gets PCT to avoid generating the constants
that IMCC can't handle, S03-operators/arith.t passes with this
patch. (I'm not in a place where I can do a full spectest_regression,
so I'm leaving the patch here for someone else to apply and test.)

Pm

@p6rt
Copy link
Author

p6rt commented Sep 25, 2008

From @pmichaud

pct-constants.patch
Index: compilers/pct/src/PAST/Compiler.pir
===================================================================
--- compilers/pct/src/PAST/Compiler.pir	(revision 31421)
+++ compilers/pct/src/PAST/Compiler.pir	(working copy)
@@ -1977,20 +1977,39 @@
     returns = $S0
   have_returns:
 
-    .local string valflags
+    .local string valflags, valstr
     $P0 = get_global '%valflags'
     valflags = $P0[returns]
 
     $I0 = index valflags, 'e'
-    if $I0 < 0 goto escape_done
-    value = self.'escape'(value)
-  escape_done:
+    if $I0 < 0 goto valstr_value
+    valstr = self.'escape'(value)
+    goto valstr_done
+  valstr_value:
+    ##  get the PIR representation of the value
+    valstr = value
+    ##  IMCC can't handle integer constants outside of 
+    ##  -2147483648..2147483647, so if we get one we add a decimal
+    ##  to force IMCC to parse it as a Float.
+    ##  skip over leading minus sign
+    $S0 = substr valstr, 0, 1
+    $I0 = iseq $S0, '-'
+    ##  see if rest of string is all digits, if not, leave valstr alone
+    $I1 = length valstr
+    $I0 = find_not_cclass .CCLASS_NUMERIC, valstr, $I0, $I1
+    if $I1 != $I0 goto valstr_done
+    ##  it's an integer, now see if value is in -2147483648..2147483647
+    if value < -2147483648. goto valstr_float
+    if value <  2147483648. goto valstr_done
+  valstr_float:
+    valstr = concat valstr, '.'
+  valstr_done:
 
     .local string rtype
     rtype = options['rtype']
     $I0 = index valflags, rtype
     if $I0 < 0 goto result_pmc
-    ops.'result'(value)
+    ops.'result'(valstr)
     .return (ops)
 
   result_pmc:
@@ -1998,7 +2017,7 @@
     result = self.'unique'('$P')
     returns = self.'escape'(returns)
     ops.'push_pirop'('new', result, returns)
-    ops.'push_pirop'('assign', result, value)
+    ops.'push_pirop'('assign', result, valstr)
     ops.'result'(result)
     .return (ops)
 .end

@p6rt
Copy link
Author

p6rt commented Sep 25, 2008

From @moritz

On Thu Sep 25 15​:49​:06 2008, pmichaud wrote​:

Here's a patch that gets PCT to avoid generating the constants
that IMCC can't handle, S03-operators/arith.t passes with this
patch. (I'm not in a place where I can do a full spectest_regression,
so I'm leaving the patch here for someone else to apply and test.)

Since chromatic's r31422 'make spectest_regression' works fine again, so
I can't really tell if this patch has any effect.

(with this patch all parrot and PGE tests still pass, except the "no
trailing ws" one which is easy to fix).

So I'm leaving it for you to decide what do with it.

@p6rt
Copy link
Author

p6rt commented Mar 29, 2009

From @moritz

On Thu Sep 25 15​:49​:06 2008, pmichaud wrote​:

Here's a patch that gets PCT to avoid generating the constants
that IMCC can't handle, S03-operators/arith.t passes with this
patch. (I'm not in a place where I can do a full spectest_regression,
so I'm leaving the patch here for someone else to apply and test.)

What's the status of this ticket? From the Rakudo side everything looks
fine, if there are no complaints I'd close it in a few days.

Cheers,
Moritz

@p6rt
Copy link
Author

p6rt commented Jun 25, 2009

@moritz - Status changed from 'open' to 'resolved'

@p6rt p6rt closed this as completed Jun 25, 2009
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant