Thread overview
[Issue 1773] New: excessively long integer literal
Jan 08, 2008
d-bugmail
Jan 16, 2008
d-bugmail
Jan 18, 2008
d-bugmail
Jan 18, 2008
d-bugmail
Feb 16, 2008
d-bugmail
Feb 23, 2008
d-bugmail
Sep 03, 2008
d-bugmail
January 08, 2008
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


-- 

January 16, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1773


bugzilla@digitalmars.com changed:

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




------- Comment #1 from bugzilla@digitalmars.com  2008-01-16 04:57 -------
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.


-- 

January 18, 2008
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




------- Comment #2 from aplee@primus.ca  2008-01-17 21:06 -------
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.


-- 

January 18, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1773





------- Comment #3 from aplee@primus.ca  2008-01-17 22:14 -------
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.


-- 

February 16, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1773


bugzilla@digitalmars.com changed:

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




------- Comment #4 from bugzilla@digitalmars.com  2008-02-16 06:06 -------
Fixed dmd 1.026 and 2.010


-- 

February 23, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1773


aplee@primus.ca changed:

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




------- Comment #5 from aplee@primus.ca  2008-02-23 07:35 -------
$ 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.


-- 

September 03, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=1773


bugzilla@digitalmars.com changed:

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




------- Comment #6 from bugzilla@digitalmars.com  2008-09-03 01:34 -------
Fixed dmd 1.035 and 2.019


--