wcc: reject final-band integer overflow; restore rewind columns
This commit is contained in:
@@ -269,6 +269,9 @@ fn skipws(l: *lex) bool = {
|
||||
|
||||
fn parseint(p: *u8, n: u64, base: i32, ok: *bool) u64 = {
|
||||
let v: u64 = 0u64;
|
||||
let b: u64 = base: u64;
|
||||
let cutoff: u64 = ~0u64 / b;
|
||||
let cutlim: u64 = ~0u64 % b;
|
||||
let got: bool = false;
|
||||
let i: u64 = 0u64;
|
||||
for (i < n) {
|
||||
@@ -294,8 +297,11 @@ fn parseint(p: *u8, n: u64, base: i32, ok: *bool) u64 = {
|
||||
};
|
||||
if (d < 0) { *ok = false; return 0u64; };
|
||||
if (d >= base) { *ok = false; return 0u64; };
|
||||
if (v > ~0u64 / (base: u64)) { *ok = false; return 0u64; };
|
||||
v = v * (base: u64) + (d: u64);
|
||||
if (v > cutoff || (v == cutoff && (d: u64) > cutlim)) {
|
||||
*ok = false;
|
||||
return 0u64;
|
||||
};
|
||||
v = v * b + (d: u64);
|
||||
got = true;
|
||||
i += 1u64;
|
||||
};
|
||||
@@ -551,6 +557,7 @@ fn lexnum(l: *lex, start: *pos, out: *tok) void = {
|
||||
if (pc >= 0) {
|
||||
if (isidstart(pc: rune)) {
|
||||
let sb: u64 = l.lpos;
|
||||
let sc: i32 = l.col;
|
||||
for (true) {
|
||||
let cc: i32 = lpeek(l, 0u64);
|
||||
if (cc < 0) { break; };
|
||||
@@ -591,6 +598,7 @@ fn lexnum(l: *lex, start: *pos, out: *tok) void = {
|
||||
out.tsuffix = strings.dup(view);
|
||||
} else {
|
||||
l.lpos = sb;
|
||||
l.col = sc;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -309,3 +309,32 @@ fn checkfloat(src: str, want: u64) void = {
|
||||
checkfloat("1.0e308", 0x7FE1CCF385EBC8A0u64);
|
||||
checkfloat("2.225073858507202e-308", 0x0010000000000001u64);
|
||||
};
|
||||
|
||||
@test fn intfinalband() void = {
|
||||
let src: str = "18446744073709551616";
|
||||
let l: lex;
|
||||
lexinit(&l, "t", src.ptr, src.len: u64);
|
||||
let t: tok;
|
||||
lexnext(&l, &t);
|
||||
assert(!(t.kind != tkind.TK_ERR));
|
||||
assert(!(l.errs != 1));
|
||||
};
|
||||
|
||||
@test fn suffixrewindcols() void = {
|
||||
let src: str = "1foo bar";
|
||||
let l: lex;
|
||||
lexinit(&l, "t", src.ptr, src.len: u64);
|
||||
let t: tok;
|
||||
lexnext(&l, &t);
|
||||
assert(!(t.kind != tkind.TK_INT));
|
||||
assert(!(t.col != 1));
|
||||
assert(!(t.uval != 1u64));
|
||||
lexnext(&l, &t);
|
||||
assert(!(t.kind != tkind.TK_IDENT));
|
||||
assert(!(t.col != 2));
|
||||
assert(!(t.text != "foo"));
|
||||
lexnext(&l, &t);
|
||||
assert(!(t.kind != tkind.TK_IDENT));
|
||||
assert(!(t.col != 6));
|
||||
assert(!(t.text != "bar"));
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user