aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-19 21:53:24 +0200
committerlemon <lsof@mailbox.org>2022-08-19 21:53:24 +0200
commit58d8abf355c1543ec6afd99189848634f51f6273 (patch)
tree4b5cc6827480023e268549c316eb43a4ad052027
parent21151f70a82f10d30b74f2965c19fab78adca430 (diff)
fix memory bug
-rw-r--r--src/cffc.hff1
-rw-r--r--src/common.hff4
-rw-r--r--src/parse.cff43
-rw-r--r--src/vec.hff2
4 files changed, 40 insertions, 10 deletions
diff --git a/src/cffc.hff b/src/cffc.hff
index 53b4db5..abc00ae 100644
--- a/src/cffc.hff
+++ b/src/cffc.hff
@@ -121,6 +121,7 @@ struct Expan;
struct Parser {
fp *FILE,
alloc *Allocator,
+ tlalloc *Allocator,
curfile *const u8,
curfn *Fn,
curenv *Env,
diff --git a/src/common.hff b/src/common.hff
index 187fbf3..6b63334 100644
--- a/src/common.hff
+++ b/src/common.hff
@@ -18,7 +18,7 @@ defmacro assert {
defmacro foreach(x, i, a, &body) [
{
let $a = a;
- for let i = 0; i < $a.#len; ++i {
+ for let i = 0z; i < $a.#len; ++i {
let x = $a[i];
{ body }
}
@@ -28,7 +28,7 @@ defmacro foreach(x, i, a, &body) [
defmacro foreach_ptr(x, i, a, &body) [
{
let $a = a;
- for let i = 0; i < $a.#len; ++i {
+ for let i = 0z; i < $a.#len; ++i {
let x = &$a[i];
{ body }
}
diff --git a/src/parse.cff b/src/parse.cff
index 1ea05d5..c3831ef 100644
--- a/src/parse.cff
+++ b/src/parse.cff
@@ -832,7 +832,7 @@ fn parseexpandtepl(P *Parser, tepl *Tepl) *const Type {
let loc = container_of(tepl, Decl, u.Tepl).loc;
while !lexmatch(P, &tok, '>') {
let par = &tepl.params[i];
- let toks [#]Tok = (as(*Tok)P.alloc->alloc(sizeof Tok, alignof Tok))[0::1];
+ let toks [#]Tok = (as(*Tok)P.tlalloc->alloc(sizeof Tok, alignof Tok))[0::1];
switch par.u {
case Ty;
toks[0] = { :typearg, P.curloc, parsetype(P), .u: { .ident: par.name }};
@@ -893,7 +893,6 @@ fn parseexpandtepl(P *Parser, tepl *Tepl) *const Type {
let arg = &tpargs[i];
switch cache.args[i] {
case Ty ty;
- efmt("cmp %t %t\n",ty,arg.Ty);
if ty != arg.Ty {
continue #'search;
}
@@ -922,7 +921,7 @@ fn parseexpandtepl(P *Parser, tepl *Tepl) *const Type {
free(tpargs.#ptr);
return cache.ty;
}
- let env = mkenv(tepl.env, P.alloc);
+ let env = mkenv(tepl.env, P.tlalloc);
with_tmpchange(P.curenv, env) {
let decl *Decl #?;
let expan Expan = {
@@ -935,11 +934,10 @@ fn parseexpandtepl(P *Parser, tepl *Tepl) *const Type {
P.peektok = :None;
envfree(env);
(as(*Type)ty).u.Agg.tpargs = tpargs;
- cache = P.alloc->alloc(sizeof(*cache), alignof(*cache));
+ cache = P.tlalloc->alloc(sizeof(*cache), alignof(*cache));
cache.next = tepl.cache;
cache.args = tpargs;
cache.ty = ty;
- efmt("new %s %p %t %p\n", tname, tepl, tpargs[0].Ty, tpargs[0].Ty);
tepl.cache = cache;
return ty;
}
@@ -1111,12 +1109,16 @@ fn parseaggini(P *Parser, loc Loc, ty *const Type) Expr {
iota = (fld - ty.u.Agg.flds.#ptr) + 1;
} else {
if iota >= ty.u.Agg.flds.#len {
- fatal(P, tok.loc, "excess elements in struct initializer");
+ fatal(P, tok.loc, "excess elements in %t struct initializer", ty);
}
fld = &ty.u.Agg.flds[iota++];
}
P.targty = fld.ty;
ex = parseexpr(P);
+ if !typematchestarg(fld.ty, ex.ty) {
+ err(P, ex.loc, "incompatible element `%s' type in %t initializer (%t, expected %t)",
+ fld.name, ty, ex.ty, fld.ty);
+ }
flds->push(fld);
exs->push(ex);
if !lexmatch(P, &tok, ',') {
@@ -1387,6 +1389,27 @@ fn pexprimary(P *Parser) Expr {
}
ex = { tok.loc, ty_usize, :IntLit { ty.align }};
+ case :kw_offsetof;
+ lexexpect(P, '(');
+ let ty = parsetype(P);
+ lexexpect(P, ',');
+ let off = 0z;
+ for ;; {
+ let name = (tok = lexexpect(P, :ident)).u.ident;
+ let fld = findaggfield(ty, name);
+ if fld == #null {
+ fatal(P, tok.loc, "%t has no such field %qT", ty, tok);
+ }
+ off += fld.off;
+ ty = fld.ty;
+ if !lexmatch(P, #null, '.') {
+ lexmatch(P, #null, ',');
+ lexexpect(P, ')');
+ break;
+ }
+ }
+ ex = { tok.loc, ty_usize, :IntLit { off }};
+
case '(';
if lexmatch(P, &tok, :kw_do) {
let st = parseblock0(P);
@@ -2467,6 +2490,7 @@ fn doimport(P *Parser, loc Loc, path *const u8) [#]Decl {
let P2 Parser #?;
parser_init(&P2, rpath);
P2.is_header = #t;
+ P2.tlalloc = P.tlalloc;
P2.alloc = P.alloc;
let decls = parse4import(&P2);
@@ -2766,6 +2790,11 @@ fn parsedecls(P *Parser, loc Loc, yield DeclYielder, yarg *void, toplevel bool)
let name = lexexpects(P, :ident, "macro name").u.ident;
decl = parsemacro(P, tok.loc, name);
+ case lexmatch(P, &tok, :kw_typedef);
+ let name = lexexpects(P, :ident, "typedef name").u.ident;
+ decl = putdecl(P, tok.loc, { name, tok.loc, .u: :Ty(parsetype(P)) });
+ lexexpect(P, ';');
+
case else;
if (tok = lexpeek(P)).t == :ident {
let decl = finddecl(P, tok.u.ident);
@@ -2805,7 +2834,7 @@ extern fn parse(P *Parser) [#]Decl {
let aralloc = Arena {};
let alloc = Allocator { &aralloc, &Arena:allocf, #null };
let decls Vec<Decl> = {};
- P.alloc = &alloc;
+ P.alloc = (P.tlalloc = &alloc);
P.curenv = mkenv(#null, P.alloc);
if primenv == #null {
primenv = mkenv(#null, P.alloc);
diff --git a/src/vec.hff b/src/vec.hff
index 4d877d8..acb5e07 100644
--- a/src/vec.hff
+++ b/src/vec.hff
@@ -52,7 +52,7 @@ struct Vec<T> {
defmacro vec_each(x, i, v, &body) [
{
let $v = v;
- for let i = 0; i < $v.len; ++i {
+ for let i = 0u; i < $v.len; ++i {
let x = $v.dat[i];
{ body }
}