www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 1773] New: excessively long integer literal

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1773

           Summary: excessively long integer literal
           Product: D
           Version: 1.020
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla digitalmars.com
        ReportedBy: aplee primus.ca


An excessively long integer literal is accepted by the compiler, as show in
this simple example, where a LargeInt struct instance is declared with a
capacity of 256 bits:

LargeInt!(256) v = 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF;

Under the hood, this assignment uses the opAssign overload I created for ulong.
Obviously, ulong is only 64 bits in size, and only the lowest 64 bits of the
"v" variable get set to 1, while the upper bits remain at 0. Also obvious is
that a 256-bit integer literal is not supposed to be supported. The prioblem is
that this code is accepted by the compiler, leading to beleive that all 256
bits are set to 1 when in reality they aren't.

I experimented a little bit and found that 0xf_ffff_ffff_ffff_ffff also
compiled, but 0x1_0000_0000_0000_0000 did not compile.

This is with gdc 0.24, using dmd 1.020


-- 
Jan 07 2008
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1773


bugzilla digitalmars.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |WORKSFORME





I get:
    test.d(1): integer overflow
for:
    ulong v = 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF;
I could not reproduce the problem (I don't have your definition of LargeInt())
with dmd 1.025.


-- 
Jan 16 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1773


aplee primus.ca changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|WORKSFORME                  |
            Version|1.020                       |1.025





Sorry, LargeInt is not necessary. I have found that the problem is only with
dmd (or gdc) on linux:

$ ./dmd
Digital Mars D Compiler v1.025
...
$ cat t.d
ulong v = 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF;
ulong v = 0x1_0000_0000_0000_0000;
void main() {}
$ ./dmd t.d
t.d(2): integer overflow

Line 1 was not rejected by the compiler. On Windows, both lines are rejected.


-- 
Jan 17 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1773






I have been able to characterize the problem further by running a piece of the
lexer as a standalone C program:

#include <stdio.h>
#include <stdint.h>
void main() {
  int cnt = 17;
  uint64_t n;
  int r = 16, d;
  printf("Walter's parsing 0xF_FFFF_FFFF_FFFF_FFFF\n");
  n = 0;
  cnt = 17;
  while(cnt--) {
    d = 15; // 0xF_FFFF_FFFF_FFFF_FFFF;
    if (d >= r) break;
    printf("Condition value %llu < %llu\n",n * r + d,n);
    if (n * r + d < n) {
      printf("Overflow\n");
      break;
    }
    n = n * r + d;
    printf("%0d: n = %llu\n",cnt,n);
  }
  printf("Walter's parsing 0x1_0000_0000_0000_0000\n");
  n = 0;
  cnt = 17;
  while(cnt--) {
    if (cnt == 16) d = 1; // 0x1_0000_0000_0000_0000;
    else d = 0;
    if (d >= r) break;
    printf("Condition value %llu < %llu\n",n * r + d,n);
    if (n * r + d < n) {
      printf("Overflow\n");
      break;
    }
    n = n * r + d;
    printf("%0d: n = %llu\n",cnt,n);
  }
}

In running this program which mimics the parsing of the two integer literals
shown above, the problem becomes obvious. It is in the conditional. I do not
know the solution yet.


-- 
Jan 17 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1773


bugzilla digitalmars.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|REOPENED                    |RESOLVED
         Resolution|                            |FIXED





Fixed dmd 1.026 and 2.010


-- 
Feb 16 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1773


aplee primus.ca changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|FIXED                       |





$ cat t.d
ulong v1 = 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF;
ulong v2 = 0x1_0000_0000_0000_0000;
ulong v3 = 0x1_FFFF_FFFF_FFFF_FFFF;
ulong v4 = 0x7_FFFF_FFFF_FFFF_FFFF;
ulong v5 = 0x1_0000_FFFF_FFFF_FFFF;
void main() {}
$ ./dmd t.d
t.d(1): integer overflow
t.d(2): integer overflow
t.d(5): integer overflow
$ ./dmd -v
Digital Mars D Compiler v1.026

v3 and v4 are also overflows but D does not see that.

The problem is that any input stream that fills in the r*n+d will all 1s is
going to be a problem. I was not able to come up with a solution different than
the one explained in the strtol.c file which can be found everywhere on the
internet, which uses a cutoff value between legal numbers and illegal numbers.


-- 
Feb 23 2008
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1773


bugzilla digitalmars.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|REOPENED                    |RESOLVED
         Resolution|                            |FIXED





Fixed dmd 1.035 and 2.019


-- 
Sep 02 2008