From fc158ab464fd58aec17aa590bc2022f539fefc5a Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Sat, 30 May 2020 19:29:42 -0700 Subject: bug: temporary removal of musl lib to isolate malloc bug --- Makefile | 10 +++--- sys/cmd/cc/ast.c | 96 +++++++++++++++++++++++++++++++++++++------------------ sys/cmd/cc/bits.c | 4 +-- sys/cmd/cc/cc.c | 3 ++ sys/cmd/cc/cc.h | 10 ++++-- sys/cmd/cc/lex.c | 1 + sys/cmd/cc/pp.c | 1 + 7 files changed, 84 insertions(+), 41 deletions(-) diff --git a/Makefile b/Makefile index d36cd09..f76ac8c 100644 --- a/Makefile +++ b/Makefile @@ -12,15 +12,15 @@ OBJ_DIR := build TST_DIR := test # C runtime library -CINIT := $(LIB_DIR)/crt/crt1.o $(LIB_DIR)/crt/x86_64/crti.o `gcc --print-file-name=crtbeginS.o` -CFINI := `gcc --print-file-name=crtendS.o` $(LIB_DIR)/crt/x86_64/crtn.o +# CINIT := $(LIB_DIR)/crt/crt1.o $(LIB_DIR)/crt/x86_64/crti.o `gcc --print-file-name=crtbeginS.o` +# CFINI := `gcc --print-file-name=crtendS.o` $(LIB_DIR)/crt/x86_64/crtn.o # Flags, Libraries and Includes CFLAGS := -g -march=native -fno-strict-aliasing -fwrapv -fms-extensions -STATIC := -static -nodefaultlibs -nostartfiles +# STATIC := -static -nodefaultlibs -nostartfiles AFLAGS := -f elf64 -INCS := -isystem $(INC_DIR)/vendor/libc -I $(INC_DIR) -ELIBS := -L$(LIB_DIR) -lc +INCS := -I $(INC_DIR) #-isystem $(INC_DIR)/vendor/libc +ELIBS := #-L$(LIB_DIR) #-lc # Named generic rules (must be evaluated lazily) COMPILE = @echo "CC "$@;\ diff --git a/sys/cmd/cc/ast.c b/sys/cmd/cc/ast.c index f5d7a42..4c81509 100644 --- a/sys/cmd/cc/ast.c +++ b/sys/cmd/cc/ast.c @@ -106,6 +106,7 @@ getdtor(Parser *p) panicf("dtor stack overflow"); p->dt->name = getname(p); + p->dt->ptr = (Ptr){ 0 }; return p->dt++; } @@ -275,10 +276,12 @@ static Expr *expr(Parser *, Lexer *); static error blkstmt(Parser *, Lexer *, Stmt **); -#define MAKEX(x, state) alloc((x)), (x)->kind = X##state + // ----------------------------------------------------------------------- // expressions +#define MAKEX(x, state) alloc((x)), (x)->kind = X##state + static Expr* primary(Parser *p, Lexer *lx) @@ -295,14 +298,16 @@ primary(Parser *p, Lexer *lx) MAKEX(x, ident); x->pos.beg = b; x->pos.end = lx->pos; - return x; + x->name = t.val.s; + break; case Alit: MAKEX(x, lit); x->pos.beg = b; x->pos.end = lx->pos; x->val.kind = t.kind & ~Vmask; - return x; + x->val.v = t.val; + break; case Alparen: advance(p, lx); @@ -312,13 +317,14 @@ primary(Parser *p, Lexer *lx) errorat(lx->pos, "unterminated paren expression"); goto Bad; } - advance(p, lx); - return x; + break; default: - ; + panicf("unreachable"); } - panicf("unreachable"); + + advance(p, lx); + return x; Bad: errorat(lx->pos, "unable to parse operand expression"); return nil; @@ -418,8 +424,9 @@ Key1: } movearray(x->init.k, k, n); movearray(x->init.v, a, x->init.n); + return x; Bad: - errorat(t.pos, "could not parse initilaizer list"); + errorat(t.pos, "could not parse initializer list"); return nil; } @@ -485,6 +492,7 @@ postfix(Parser *p, Lexer *lx) } x = primary(p, lx); + t = peek(p, 0); for (;;) { b = x->pos.beg; switch (t.kind) { @@ -567,15 +575,13 @@ postfix(Parser *p, Lexer *lx) } movearray(y->call.arg, a, y->call.n); Endfunc: - advance(p, lx); y->pos.end = lx->pos; x = y, y = nil; break; default: - ; + return x; } - t = advance(p, lx); } return x; @@ -616,6 +622,7 @@ unary(Parser *p, Lexer *lx) case Ainc: MAKEX(x, preinc); goto Prefix; case Adec: MAKEX(x, predec); /* fallthrough */ Prefix: + advance(p, lx); x->pos.beg = t.pos; x->unary.pre = unary(p, lx); x->pos.end = x->unary.pre->pos.end; @@ -628,6 +635,7 @@ unary(Parser *p, Lexer *lx) case Aadd: MAKEX(x, plus); goto Unary; case Asub: MAKEX(x, minus); /* fallthrough */ Unary: + advance(p, lx); x->pos.beg = t.pos; x->unary.pre = cast(p, lx); x->pos.end = x->unary.pre->pos.end; @@ -648,14 +656,24 @@ unary(Parser *p, Lexer *lx) t = advance(p, lx); x->info.type = 0; x->info.of.type = typename(p, lx, &x->info.of.qual); - break; + + t = peek(p, 0); + if (nomatch(t, Arparen)) { + errorat(t.pos, "missing paren for size/alignof statement"); + goto Bad; + } + advance(p, lx); + return x; } - x->info.type = 0; + x->info.type = 1; x->info.x = unary(p, lx); + return x; + default: ; } + /* fallthrough */ default: return postfix(p, lx); } @@ -669,12 +687,12 @@ cast(Parser *p, Lexer *lx) { Expr *x; Token t; - t = peek(p, 0); - if (t.kind == Alparen) { + if (t.kind == Alparen && istypename(p, peek(p,1))) { t = advance(p, lx); MAKEX(x, cast); + x->pos.beg = t.pos; x->cast.to.type = typename(p, lx, &x->cast.to.qual); if (!x->cast.to.type) { @@ -689,11 +707,11 @@ cast(Parser *p, Lexer *lx) } advance(p, lx); - x->cast.x = unary(p, lx); + x->cast.x = cast(p, lx); x->pos.beg = lx->pos; return x; } - return cast(p, lx); + return unary(p, lx); Bad: errorat(lx->pos, "failed to parse cast expression"); @@ -742,22 +760,24 @@ binary(Parser *p, Lexer *lx, int prec) { Token t; int k, np; - Expr *l, *r, *x; + Expr *l, *x; l = cast(p, lx); for (;;) { t = peek(p, 0); k = t.kind; - np = prectab[t.kind]; + np = prectab[k]; if (np < prec) - return x; + return l; alloc(x); + t = advance(p, lx); + x->pos.beg = l->pos.beg; x->kind = optab[k]; x->binary.l = l; - x->binary.r = r = binary(p, lx, np + 1); - x->pos.end = r->pos.end; + x->binary.r = binary(p, lx, np + 1); + x->pos.end = x->binary.r->pos.end; l = x; } @@ -788,6 +808,8 @@ ternary(Parser *p, Lexer *lx) x->kind = Xternary; x->cond.c = y; x->cond.t = expr(p, lx); + + t = peek(p, 0); if (nomatch(t, Acolon)) { errorat(t.pos, "ternary expression missing ':'"); goto Bad; @@ -808,6 +830,8 @@ ternary(Parser *p, Lexer *lx) case Alsftasn: MAKEX(y, lsftasn); goto Assign; case Arsftasn: MAKEX(y, rsftasn); goto Assign; Assign: + advance(p, lx); + y->asn.l = x; y->asn.r = ternary(p, lx); x = y; @@ -882,7 +906,7 @@ stmt(Parser *p, Lexer *lx) } if (k == Akeywd) { - if ((Kauto <= k && k <= Katomic) || (Ksigned <= k && k <= Klong)) { + if ((Kauto <= t.val.i && t.val.i <= Ktypedef) || (Kconst <= t.val.i && t.val.i <= Kenum)) { Tdecl: return (Node *)decl(p, lx); } @@ -1068,6 +1092,7 @@ stmt(Parser *p, Lexer *lx) errorat(t.pos, "missing semicolon after return statement"); goto Bad; } + advance(p, lx); break; case Kcase: @@ -1127,9 +1152,15 @@ stmt(Parser *p, Lexer *lx) default: Texpr: - t = advance(p, lx); s->kind = Sexpr; s->x = expr(p, lx); + + t = peek(p, 0); + if (nomatch(t, Asemi)) { + errorat(t.pos, "missing semicolon after statement expression"); + goto Bad; + } + advance(p, lx); } s->pos.end = lx->pos; @@ -1153,13 +1184,13 @@ blkstmt(Parser *p, Lexer *lx, Stmt **s) (*s)->pos.beg = lx->pos; t = peek(p, 0); - if (nomatch(t, Albrakt)) + if (nomatch(t, Albrace)) goto Bad; t = advance(p, lx); len = 0, cap = 20; ns = malloc(cap*sizeof(*ns)); - while (t.kind != Arbrakt) { + while (t.kind != Arbrace) { if (cap == len) { cap += 20; ns = realloc(ns, cap*sizeof(*ns)); @@ -1167,6 +1198,7 @@ blkstmt(Parser *p, Lexer *lx, Stmt **s) ns[len++] = stmt(p, lx); t = peek(p, 0); } + advance(p, lx); (*s)->pos.end = lx->pos; (*s)->blk.n = len; @@ -1367,7 +1399,7 @@ basetype(Parser *p, Lexer *lx, uint64 *s) return 0; } - m = (((*s<<32)>>32) & ~(MaskQul | MaskMem | MaskFcn)); + m = (((*s<<32)>>32) & ~(MaskQul|MaskMem|MaskFcn)); for (n = 0; n < arrlen(validtypespec); n++) { if (validtypespec[n] == m) { if (indextypespec[n] < 0) { @@ -1618,11 +1650,12 @@ spec(Parser *p, Lexer *lx, uint64 *spec) t = advance(p, lx); /* NOTE: This depends on the enum order. KEEP IN SYNC */ tag = aggrfunc[i](p, lx, name, 1 << (n+1)); - if (t = peek(p, 0), nomatch(t, Arbrace)) { errorat(t.pos, "invalid token %s in aggregate/enum declaration", tokens[t.kind]); goto Bad; } + /* high bits encode the type index */ + s |= (uint64)tag << 32; } if (name) declaretag(p, tag, name); @@ -2005,11 +2038,12 @@ decl(Parser *p, Lexer *lx) alloc(d->body); if (!attop(p)) { - errorat(lx->pos, "nested function declarations"); + errorat(lx->pos, "nested function declarations are illegal"); goto Bad; } - if (d->kind != 0) { - errorat(lx->pos, "attempting to define a function for a variable declaration"); + + if (C.type.info[d->type].kind != Tfunc) { + errorat(lx->pos, "attempted to define function body for non function type"); goto Bad; } diff --git a/sys/cmd/cc/bits.c b/sys/cmd/cc/bits.c index 479ddbb..4b405dc 100644 --- a/sys/cmd/cc/bits.c +++ b/sys/cmd/cc/bits.c @@ -99,14 +99,14 @@ Type basetypes[] = { #define TYPE(a, ...) __VA_ARGS__, #define X(a, b) a -uint64 validtypespec[40] = { +uint64 validtypespec[38] = { TYPES Tstruct, Tunion, Tenum, Tname, }; #undef X #define X(a, b) b -int indextypespec[40] = { +int indextypespec[38] = { TYPES -1, -1, -1, -1, }; diff --git a/sys/cmd/cc/cc.c b/sys/cmd/cc/cc.c index 24bc9e0..da4c4ed 100644 --- a/sys/cmd/cc/cc.c +++ b/sys/cmd/cc/cc.c @@ -94,6 +94,7 @@ END: // ----------------------------------------------------------------------- // type interning +/* TODO: intern types for memory savings */ int type() { @@ -263,6 +264,8 @@ initlx(Lexer *lx) lx->new = lx->iostk; lx->new->link = nil; memset(lx->iostk, 0, sizeof(lx->iostk)); + + lx->sym = (SymTab){ 0 }; } void diff --git a/sys/cmd/cc/cc.h b/sys/cmd/cc/cc.h index da45b18..d030b91 100644 --- a/sys/cmd/cc/cc.h +++ b/sys/cmd/cc/cc.h @@ -409,9 +409,13 @@ struct Expr uint32 qual; uint32 type; union { + string name; struct { uint64 kind; - union Val; + union { + union Val; + union Val v; + }; } val; struct { int n; @@ -699,8 +703,8 @@ struct Type extern Type pointer; extern Type basetypes[24]; /* mandated by C standard */ -extern uint64 validtypespec[40]; -extern int indextypespec[40]; +extern uint64 validtypespec[38]; +extern int indextypespec[38]; struct Scope { diff --git a/sys/cmd/cc/lex.c b/sys/cmd/cc/lex.c index cb65aa0..97e19e4 100644 --- a/sys/cmd/cc/lex.c +++ b/sys/cmd/cc/lex.c @@ -759,6 +759,7 @@ Dispatch: } io = makeio(lx, sym->name); io->rdr.end += expandmacro(lx, sym, io->b); + printf("EXPANDED %s: %s\n", sym->name, io->rdr.beg); *io->rdr.end++ = EOF; pushio(lx, io); goto GetByte; diff --git a/sys/cmd/cc/pp.c b/sys/cmd/cc/pp.c index 4d7c643..57c3501 100644 --- a/sys/cmd/cc/pp.c +++ b/sys/cmd/cc/pp.c @@ -882,6 +882,7 @@ ppinc(Lexer *lx) strcpy(lx->buf, C.inc.dir[i]); strcat(lx->buf, "/"); + if (strcmp(lx->buf, "./") == 0) lx->buf[0] = '\0'; strcat(lx->buf, s); -- cgit v1.2.1