scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit 0ba2857c34b46d5b56c3b6077fc1e268711cb16b
parent 727dee0878e0036d92a89229ee6df24427c655fa
Author: Roberto E. Vargas Caballero <k0ga@shike2.net>
Date:   Mon, 13 Apr 2026 23:56:37 +0200

Merge remote-tracking branch 'origin/master'

Diffstat:
Mscripts/mkdep | 5+++++
Msrc/cmd/scc-cc/cc1/cc1.h | 2+-
Msrc/cmd/scc-cc/cc1/cpp.c | 6+++---
Msrc/cmd/scc-cc/cc1/decl.c | 9++++++---
Msrc/cmd/scc-cc/cc1/expr.c | 8++++----
Msrc/cmd/scc-cc/cc1/init.c | 2+-
Msrc/cmd/scc-cc/cc1/stmt.c | 2+-
Msrc/cmd/scc-cc/cc2/Makefile | 1+
Msrc/cmd/scc-cc/cc2/cc2.h | 2+-
Msrc/cmd/scc-cc/cc2/cfg.c | 28++++++++++++++--------------
Msrc/cmd/scc-cc/cc2/qbe/cgen.c | 13++++++-------
Msrc/cmd/scc-cc/cc2/sethi.c | 42+++++++++++++++++++++---------------------
Msrc/libc/assert/Makefile | 1+
Msrc/libc/ctype/Makefile | 1+
Msrc/libc/locale/Makefile | 1+
Msrc/libc/string/Makefile | 1+
Msrc/libc/wchar/Makefile | 1+
Msrc/libmach/coff32/coff32getsym.c | 4++--
Msrc/libmach/elf/elfgetsym.c | 8++++----
Atests/cc/execute/0268-string.c | 17+++++++++++++++++
Atests/cc/execute/0269-extern.c | 17+++++++++++++++++
Mtests/cc/execute/scc-tests.lst | 2++
Mtests/libc/execute/0053-wmemcmp.c | 0
23 files changed, 111 insertions(+), 62 deletions(-)

diff --git a/scripts/mkdep b/scripts/mkdep @@ -11,6 +11,11 @@ tmp=$$.tmp printf "\n#deps\n" for i in *.c do + if test "$i" = '*.c' + then + continue + fi + file=`basename $i | sed 's/\.c$/.o/'` dir=`dirname $i` diff --git a/src/cmd/scc-cc/cc1/cc1.h b/src/cmd/scc-cc/cc1/cc1.h @@ -511,7 +511,7 @@ unsigned long long ones(int); /* expr.c */ Node *decay(Node *), *negate(Node *np), *assign(void); Node *convert(Node *, Type *, int); -Node *constexpr(void), *condexpr(int), *expr(void); +Node *iconstexpr(void), *condexpr(int), *expr(void); int isnodecmp(int); int negop(int); int cmpnode(Node *, unsigned long long); diff --git a/src/cmd/scc-cc/cc1/cpp.c b/src/cmd/scc-cc/cc1/cpp.c @@ -542,8 +542,8 @@ getpars(Symbol *args[NR_MACROARG]) return NR_MACROARG; } - if ((sym = install(NS_IDEN, sym)) == NULL) { - errorp("duplicated macro parameter '%s'", yytext); + if (!install(NS_MACROPAR, sym)) { + errorp("duplicated macro parameter '%s'", sym->name); } else { sym->flags |= SUSED; args[n++] = sym; @@ -920,7 +920,7 @@ ifclause(int negate, int isifdef) killsym(sym); } else { /* TODO: catch recovery here */ - if ((expr = constexpr()) == NULL) { + if ((expr = iconstexpr()) == NULL) { cpperror("parameter of #if is not an integer constant expression"); return; } diff --git a/src/cmd/scc-cc/cc1/decl.c b/src/cmd/scc-cc/cc1/decl.c @@ -158,7 +158,7 @@ arydcl(struct declarators *dp) } if (yytoken != ']') { - if ((np = constexpr()) == NULL) { + if ((np = iconstexpr()) == NULL) { errorp("invalid storage size"); } else { if ((n = np->sym->u.i) <= 0) { @@ -260,6 +260,9 @@ redcl(Symbol *sym, Type *tp, int sclass) } sym->flags = flags; + if (!(sym->type->prop & TDEFINED) && tp->prop & TDEFINED) + sym->type = tp; + return sym; redeclaration: @@ -884,7 +887,7 @@ enumdcl(void) toomany = 1; } if (accept('=')) { - Node *np = constexpr(); + Node *np = iconstexpr(); if (np == NULL) errorp("invalid enumeration value"); @@ -935,7 +938,7 @@ field(struct decl *dcl) Node *np; long long n; - if ((np = constexpr()) == NULL) { + if ((np = iconstexpr()) == NULL) { unexpected(); n = 0; } else { diff --git a/src/cmd/scc-cc/cc1/expr.c b/src/cmd/scc-cc/cc1/expr.c @@ -831,7 +831,7 @@ no_pars: } static Type * -typeof(Node *np) +gettype(Node *np) { Node *new; Type *tp; @@ -893,7 +893,7 @@ sizeexp(void) Type *tp; if (!accept('(')) - return typeof(unary()); + return gettype(unary()); switch (yytoken) { case TYPE: @@ -904,7 +904,7 @@ sizeexp(void) default: np = expr(); expect(')'); - tp = typeof(postfix(np)); + tp = gettype(postfix(np)); break; } @@ -1217,7 +1217,7 @@ expr(void) } Node * -constexpr(void) +iconstexpr(void) { Node *np; diff --git a/src/cmd/scc-cc/cc1/init.c b/src/cmd/scc-cc/cc1/init.c @@ -37,7 +37,7 @@ arydesig(Type *tp, Init *ip) if (tp->op != ARY) errorp("array index in non-array initializer"); next(); - np = constexpr(); + np = iconstexpr(); npos = np->sym->u.i; if (npos < 0 || (tp->prop & TDEFINED) && npos >= tp->n.elem) { errorp("array index in initializer exceeds array bounds"); diff --git a/src/cmd/scc-cc/cc1/stmt.c b/src/cmd/scc-cc/cc1/stmt.c @@ -283,7 +283,7 @@ Case(Symbol *lbreak, Symbol *lcont, Switch *sw) Symbol *label; expect(CASE); - if ((np = constexpr()) == NULL) + if ((np = iconstexpr()) == NULL) errorp("case label does not reduce to an integer constant"); if (!sw) { errorp("case label not within a switch statement"); diff --git a/src/cmd/scc-cc/cc2/Makefile b/src/cmd/scc-cc/cc2/Makefile @@ -4,6 +4,7 @@ DIRS =\ amd64-sysv\ arm64-sysv\ i386-sysv\ + riscv64-sysv\ qbe\ qbe_amd64-sysv\ qbe_arm64-sysv\ diff --git a/src/cmd/scc-cc/cc2/cc2.h b/src/cmd/scc-cc/cc2/cc2.h @@ -230,7 +230,7 @@ struct block { int id; int printed, visited; Node *entryp, *exitp; - Block *true, *false; + Block *btrue, *bfalse; Swtch *swtch; Block *next; }; diff --git a/src/cmd/scc-cc/cc2/cfg.c b/src/cmd/scc-cc/cc2/cfg.c @@ -43,18 +43,18 @@ prbb(Block *bb) assert(bb->id != -1); bb->printed = 1; - if (bb->true) { + if (bb->btrue) { fprintf(stderr, "\t%d -> %d [label=\"true\"]\n", - bb->id, bb->true->id); + bb->id, bb->btrue->id); } - if (bb->false) { + if (bb->bfalse) { fprintf(stderr, "\t%d -> %d [label=\"false\"]\n", - bb->id, bb->false->id); + bb->id, bb->bfalse->id); } - prbb(bb->true); - prbb(bb->false); + prbb(bb->btrue); + prbb(bb->bfalse); swt = bb->swtch; if (!swt) @@ -116,7 +116,7 @@ newbb(Node *np) bb->entryp = np; bb->exitp = NULL; bb->swtch = NULL; - bb->true = bb->false = NULL; + bb->btrue = bb->bfalse = NULL; bb->id = cfg.nr++; bb->visited = 0; cfg.cur = bb; @@ -135,7 +135,7 @@ mkcfg(Node *np) if (np->flags & BBEXIT) { cfg.cur->exitp = np; - cfg.cur->true = np->next->bb; + cfg.cur->btrue = np->next->bb; } switch (np->op) { @@ -146,16 +146,16 @@ mkcfg(Node *np) cfg.exitb = cfg.cur; break; case ORET: - cfg.cur->true = laststmt->bb; + cfg.cur->btrue = laststmt->bb; break; case OBSWITCH: cfg.cur->swtch = np->u.swtch; - cfg.cur->true = NULL; + cfg.cur->btrue = NULL; break; case OBRANCH: - cfg.cur->false = np->next->bb; + cfg.cur->bfalse = np->next->bb; case OJMP: - cfg.cur->true = jtargetbb(np); + cfg.cur->btrue = jtargetbb(np); break; } @@ -225,8 +225,8 @@ visit(Block *bb) if (!bb || bb->visited) return; bb->visited = 1; - visit(bb->true); - visit(bb->false); + visit(bb->btrue); + visit(bb->bfalse); swt = bb->swtch; if (!swt) diff --git a/src/cmd/scc-cc/cc2/qbe/cgen.c b/src/cmd/scc-cc/cc2/qbe/cgen.c @@ -532,7 +532,6 @@ rhs(Node *np) Node *phi, *l = np->left, *r = np->right; Type *tp; int cmp, sign, size, isfloat, op; - Symbol *true, *false; tp = &np->type; @@ -627,7 +626,7 @@ rhs(Node *np) static Node * cgen(Node *np) { - Node true, false, *p, *next; + Node ntrue, nfalse, *p, *next; setlabel(np->label); switch (np->op) { @@ -639,8 +638,8 @@ cgen(Node *np) case OEFUN: break; case OJMP: - label2node(&true, np->u.sym); - code(ASJMP, NULL, &true, NULL); + label2node(&ntrue, np->u.sym); + code(ASJMP, NULL, &ntrue, NULL); break; case OBRANCH: /* @@ -653,9 +652,9 @@ cgen(Node *np) if (!next->label) labelstmt(next, NULL); - label2node(&true, np->u.sym); - label2node(&false, np->next->label); - code(ASBRANCH, rhs(np->left), &true, &false); + label2node(&ntrue, np->u.sym); + label2node(&nfalse, np->next->label); + code(ASBRANCH, rhs(np->left), &ntrue, &nfalse); break; case ORET: p = (np->left) ? rhs(np->left) : NULL; diff --git a/src/cmd/scc-cc/cc2/sethi.c b/src/cmd/scc-cc/cc2/sethi.c @@ -30,30 +30,30 @@ branchnode(Node *cond, Symbol *sym) } static Node * -bool(Node *cond, Symbol *true, Symbol *false) +boolean(Node *cond, Symbol *strue, Symbol *sfalse) { Symbol *label; Node *p, *l = cond->left, *r = cond->right; switch (cond->op) { case ONEG: - l = bool(l, false, true); + l = boolean(l, sfalse, strue); break; case OAND: label = newlabel(); - l = bool(l, label, false); + l = boolean(l, label, sfalse); prestmt(labelstmt(NULL, label)); - r = bool(r, true, false); + r = boolean(r, strue, sfalse); break; case OOR: label = newlabel(); - l = bool(l, true, label); + l = boolean(l, strue, label); prestmt(labelstmt(NULL, label)); - r = bool(r, true, false); + r = boolean(r, strue, sfalse); break; default: - prestmt(branchnode(cond, true)); - prestmt(branchnode(NULL, false)); + prestmt(branchnode(cond, strue)); + prestmt(branchnode(NULL, sfalse)); return NULL; } @@ -67,13 +67,13 @@ logicexpr(Node *np) { Node *tmpvar, *p, *zero, *one; Type *tp = &np->type; - Symbol *true, *false, *phi, *tmpsym; + Symbol *strue, *sfalse, *phi, *tmpsym; - true = newlabel(); - false = newlabel(); + strue = newlabel(); + sfalse = newlabel(); phi = newlabel(); - bool(np, true, false); + boolean(np, strue, sfalse); tmpvar = tmpnode(tp, NULL); tmpsym = tmpvar->u.sym; @@ -81,12 +81,12 @@ logicexpr(Node *np) one = constnode(NULL, 1, tp); p = assignnode(tp, tmpnode(tp, tmpsym), one); - prestmt(labelstmt(p, true)); + prestmt(labelstmt(p, strue)); prestmt(branchnode(NULL, phi)); p = assignnode(tp, tmpnode(tp, tmpsym), zero); - prestmt(labelstmt(p, false)); + prestmt(labelstmt(p, sfalse)); prestmt(labelstmt(NULL, phi)); @@ -110,24 +110,24 @@ ternary(Node *np) { Type *tp; Node *tmpvar, *colon, *p; - Symbol *tmpsym, *true, *false, *phi; + Symbol *tmpsym, *strue, *sfalse, *phi; - true = newlabel(); - false = newlabel(); + strue = newlabel(); + sfalse = newlabel(); phi = newlabel(); - bool(np->left, true, false); + boolean(np->left, strue, sfalse); tp = &np->type; colon = np->right; tmpvar = tmpnode(tp, NULL); tmpsym = tmpvar->u.sym; - prestmt(labelstmt(NULL, true)); + prestmt(labelstmt(NULL, strue)); p = assignnode(tp, tmpnode(tp, tmpsym), sethi(colon->left)); prestmt(p); prestmt(branchnode(NULL, phi)); - prestmt(labelstmt(NULL, false)); + prestmt(labelstmt(NULL, sfalse)); p = assignnode(tp, tmpnode(tp, tmpsym), sethi(colon->right)); prestmt(p); @@ -180,7 +180,7 @@ sethi(Node *np) return np; } - bool(np->left, np->u.sym, next->label); + boolean(np->left, np->u.sym, next->label); np->u.sym->refcnt--; return NULL; case OCOMMA: diff --git a/src/libc/assert/Makefile b/src/libc/assert/Makefile @@ -2,6 +2,7 @@ PROJECTDIR =../../.. include $(PROJECTDIR)/scripts/rules.mk include ../rules.mk +CC=$(SCC) OBJS =\ __assert.$O\ diff --git a/src/libc/ctype/Makefile b/src/libc/ctype/Makefile @@ -2,6 +2,7 @@ PROJECTDIR =../../.. include $(PROJECTDIR)/scripts/rules.mk include ../rules.mk +CC=$(SCC) OBJS =\ ctype.$O\ diff --git a/src/libc/locale/Makefile b/src/libc/locale/Makefile @@ -2,6 +2,7 @@ PROJECTDIR =../../.. include $(PROJECTDIR)/scripts/rules.mk include ../rules.mk +CC=$(SCC) OBJS =\ localeconv.$O\ diff --git a/src/libc/string/Makefile b/src/libc/string/Makefile @@ -3,6 +3,7 @@ PROJECTDIR =../../.. include $(PROJECTDIR)/scripts/rules.mk include ../rules.mk +CC=$(SCC) OBJS =\ memchr.$O\ diff --git a/src/libc/wchar/Makefile b/src/libc/wchar/Makefile @@ -2,6 +2,7 @@ PROJECTDIR =../../.. include $(PROJECTDIR)/scripts/rules.mk include ../rules.mk +CC=$(SCC) OBJS =\ btowc.$O\ diff --git a/src/libmach/coff32/coff32getsym.c b/src/libmach/coff32/coff32getsym.c @@ -9,7 +9,7 @@ #include "fun.h" static int -typeof(Coff32 *coff, SYMENT *ent) +gettype(Coff32 *coff, SYMENT *ent) { int c; SCNHDR *scn; @@ -73,7 +73,7 @@ coff32getsym(Obj *obj, int *idx, Symbol *sym) ent = &ep->u.sym; sym->name = coff32str(coff, ent); - sym->type = typeof(coff, ent); + sym->type = gettype(coff, ent); sym->stype = SYMOBJECT; sym->value = ent->n_value; sym->size = (sym->type == 'C') ? ent->n_value : 0; diff --git a/src/libmach/elf/elfgetsym.c b/src/libmach/elf/elfgetsym.c @@ -13,7 +13,7 @@ #include "fun.h" static int -typeof(Elf *elf, Elfsym *ent, char *name) +gettype(Elf *elf, Elfsym *ent, char *name) { int c, bind, weak; unsigned long flags, type; @@ -70,7 +70,7 @@ typeof(Elf *elf, Elfsym *ent, char *name) } static int -stypeof(Elfsym *ent) +sgettype(Elfsym *ent) { switch (ELF_ST_TYPE(ent->info)) { case STT_OBJECT: @@ -113,8 +113,8 @@ elfgetsym(Obj *obj, int *idx, Symbol *sym) } // assert(strlen(sym->name) > 0); - sym->type = typeof(elf, ent, sym->name); - sym->stype = stypeof(ent); + sym->type = gettype(elf, ent, sym->name); + sym->stype = sgettype(ent); sym->value = ent->value; sym->size = ent->size; sym->index = *idx = n; diff --git a/tests/cc/execute/0268-string.c b/tests/cc/execute/0268-string.c @@ -0,0 +1,17 @@ +unsigned char s1[] = "hello"; +signed char s2[] = "Hello"; +char s3[] = "Hello World!"; + +int +main() +{ + if (s1[1] != s2[1] || s1[1] != s3[1]) + return 1; + if (s1[2] != s2[2] || s1[2] != s3[2]) + return 2; + if (s1[3] != s2[3] || s1[3] != s3[3]) + return 3; + if (s1[4] != s2[4] || s1[4] != s3[4]) + return 4; + return 0; +} diff --git a/tests/cc/execute/0269-extern.c b/tests/cc/execute/0269-extern.c @@ -0,0 +1,17 @@ +extern unsigned char tbl[]; + +unsigned char tbl[8] = { + 1, 0, 2, 0, +}; + +unsigned char c = 3; + +int +main(void) +{ + if (tbl[0] != 1 || tbl[2] != 2) + return 1; + if (tbl[4] != 0) + return 2; + return 0; +} diff --git a/tests/cc/execute/scc-tests.lst b/tests/cc/execute/scc-tests.lst @@ -258,3 +258,5 @@ 0265-wchar.c 0266-wchar.c 0267-wchar.c +0268-string.c +0269-extern.c diff --git a/tests/libc/execute/0053-wmemcmp.c b/tests/libc/execute/0053-wmemcmp.c