diff options
| author | 2022-08-19 21:53:24 +0200 | |
|---|---|---|
| committer | 2022-08-19 21:53:24 +0200 | |
| commit | 58d8abf355c1543ec6afd99189848634f51f6273 (patch) | |
| tree | 4b5cc6827480023e268549c316eb43a4ad052027 | |
| parent | 21151f70a82f10d30b74f2965c19fab78adca430 (diff) | |
fix memory bug
| -rw-r--r-- | src/cffc.hff | 1 | ||||
| -rw-r--r-- | src/common.hff | 4 | ||||
| -rw-r--r-- | src/parse.cff | 43 | ||||
| -rw-r--r-- | src/vec.hff | 2 |
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 } } |