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

syntax errors for unsigned literals longer than 128 bits #11105

Closed
ScottPJones opened this issue May 2, 2015 · 12 comments
Closed

syntax errors for unsigned literals longer than 128 bits #11105

ScottPJones opened this issue May 2, 2015 · 12 comments
Labels
kind:breaking This change will break code needs decision A decision on this change is needed parser Language parsing and surface syntax

Comments

@ScottPJones
Copy link
Contributor

If you have hexadecimal literal, normally it produces an unsigned value, whose size is dependent on the length of the literal.
However, if you go past 128 bits (32 hex digits), then it will switch to a signed number, which could possibly lead to hard to find bugs.
For example:

julia> ~0x00000000000000000000000000000000
0xffffffffffffffffffffffffffffffff

julia> ~0x000000000000000000000000000000000
-1

I believe this at least deserves a warning from the compiler (a point I tried to raise in #11081, only to have the title of my issue changed out from under me and then have it closed)

@pao pao changed the title Undocumented and inconsistent consequence of hexadecimal literals being promoted from UInt128 to BigInt Extending hex literal switches from UInt128 to (signed) BigInt May 2, 2015
@pao pao added domain:docs This change adds or pertains to documentation needs decision A decision on this change is needed kind:breaking This change will break code labels May 2, 2015
@JeffBezanson
Copy link
Sponsor Member

I agree this should be a syntax error.

@JeffBezanson JeffBezanson added parser Language parsing and surface syntax and removed domain:docs This change adds or pertains to documentation labels May 2, 2015
@ScottPJones
Copy link
Contributor Author

@JeffBezanson Error, or warning (or do you not do warnings in Julia?)
There are definitely cases where it would be nice to define a BigInt literal as hex... but maybe there's some workaround?

@pao
Copy link
Member

pao commented May 3, 2015

big"0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"should probably be made to work if it doesn't already.

@ihnorton
Copy link
Member

ihnorton commented May 3, 2015

warn("foo")

@ScottPJones
Copy link
Contributor Author

@pao big"0xfffff....." works just fine, so people have an out if they really understand it will be signed... thx

@ScottPJones
Copy link
Contributor Author

@ihnorton Thanks! Now I just need to figure out where to put the warn!
warn("Hexadecimal literal constant $(hex(value)) has overflowed a UInt128, and has been promoted to a signed BigInt. To avoid this warning, use big\"0x...\"")
Does that seem OK?

@JeffBezanson
Copy link
Sponsor Member

I try to avoid warnings. I think it's better to be decisive and make it an error, or allow it. Warnings just mean you later need to add -Werror, and then people need to write coding guidelines telling people to use it :)

@tkelman
Copy link
Contributor

tkelman commented May 3, 2015

+1 for syntax error, bigints from literals make it harder to deploy a Julia runtime without needing gmp.

@ScottPJones
Copy link
Contributor Author

@JeffBezanson Good point... can somebody please either tell me (at least in the general direction) where I'd fix this to give a syntax error, or else fix it themselves? (I'd rather just fix it myself, I'll learn more, and you can do more important stuff)

@ScottPJones
Copy link
Contributor Author

@JeffBezanson I noticed this problem also occurs for octal literals? Shall I add an error there as well? I've found where the problem is in julia-parser.scm, and will fix and submit a PR shortly

@ScottPJones
Copy link
Contributor Author

@JeffBezanson I see that it is also for binary literals, but I ran into a problem... any help would be appreciated...

      ;; n is #f for integers > typemax(UInt64)
      (cond (is-hex-float-literal (double n))
            ((eq? pred char-hex?) (fix-uint-neg neg (sized-uint-literal n s 4)))
            ((eq? pred char-oct?) (fix-uint-neg neg (sized-uint-oct-literal n s)))
            ((eq? pred char-bin?) (fix-uint-neg neg (sized-uint-literal n s 1)))
            (is-float32-literal   (float n))
            (n (if (and (integer? n) (> n 9223372036854775807))
                   `(macrocall @int128_str ,s)
                   n))
            ((within-int128? s) `(macrocall @int128_str ,s))
            (else `(macrocall @big_str ,s))))))

(define (fix-uint-neg neg n)
  (if neg
      (if (large-number? n)
          `(call - ,(maybe-negate '- n))
          `(call - ,n))
      n))

(define (sized-uint-literal n s b)
  (let* ((i (if (eqv? (string.char s 0) #\-) 3 2))
         (l (* (- (length s) i) b)))
    (cond ((<= l 8)   (uint8  n))
          ((<= l 16)  (uint16 n))
          ((<= l 32)  (uint32 n))
          ((<= l 64)  (uint64 n))
          ((<= l 128) `(macrocall @uint128_str ,s))
          (else       (error "Hex or binary literal too large for UInt128")))))

I think the problem is that it is trying to always do:

`(call - ,n)`

but it doesn't like the error call...

I get this:

julia> 0x123412341234123412341234123413241234214123412342341234
julia(38321,0x7fff7c1d3300) malloc: *** mach_vm_map(size=237494511603712) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
ERROR: syntax: Hex or binary literal too large for UInt128

Thanks in advance for help from anybody!

@StefanKarpinski StefanKarpinski changed the title Extending hex literal switches from UInt128 to (signed) BigInt syntax errors for hex & oct literals longer than 128 bits May 4, 2015
@ScottPJones
Copy link
Contributor Author

This issue is also for binary literals, going from unsigned to signed...

julia> 0b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
0xffffffffffffffffffffffffffffffff
julia> 0b111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
680564733841876926926749214863536422911
julia> ~(0b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111)
0x00000000000000000000000000000000
julia> ~(0b111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111)
-680564733841876926926749214863536422912

@StefanKarpinski StefanKarpinski changed the title syntax errors for hex & oct literals longer than 128 bits syntax errors for unsigned literals longer than 128 bits May 4, 2015
ScottPJones added a commit to ScottPJones/julia that referenced this issue May 4, 2015
jakebolewski added a commit that referenced this issue May 6, 2015
#11105 Add syntax errors for unsigned literals > UInt128
mbauman pushed a commit to mbauman/julia that referenced this issue Jun 6, 2015
tkelman pushed a commit to tkelman/julia that referenced this issue Jun 6, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind:breaking This change will break code needs decision A decision on this change is needed parser Language parsing and surface syntax
Projects
None yet
Development

No branches or pull requests

5 participants