commit 33141db27c405bbec69efaa2808b502d091c36e8 parent 36a1eef62de6d85631e2f6ae728620dec34454cc Author: Roberto E. Vargas Caballero <k0ga@shike2.net> Date: Fri, 29 May 2026 13:19:29 +0200 Merge remote-tracking branch 'origin/master' Diffstat:
24 files changed, 258 insertions(+), 178 deletions(-)
diff --git a/scripts/build/tool/gcov.mk b/scripts/build/tool/gcov.mk @@ -1,6 +1,9 @@ +include $(BUILDDIR)/tool/gnu.mk + PROFILE_CFLAGS = -fprofile-arcs -ftest-coverage PROFILE_LDLIBS = -lgcov -include $(BUILDDIR)/tool/gnu.mk + +SCC = $(CROSS_COMPILE)$(COMP) coverage: FORCE mkdir -p coverage diff --git a/src/cmd/scc-cc/cc1/cc1.h b/src/cmd/scc-cc/cc1/cc1.h @@ -553,7 +553,7 @@ Arch *i386_sysv(void); */ extern struct yystype yylval; extern char yytext[]; -extern int yytoken; +extern int yytoken, yyspace; extern unsigned short yylen; extern int disexpand, disstring; extern unsigned cppctx; diff --git a/src/cmd/scc-cc/cc1/cpp.c b/src/cmd/scc-cc/cc1/cpp.c @@ -142,6 +142,13 @@ unterminated: mp->sym->name); } +static int +cppspace(int c) +{ + return c == ' ' || c == '\t' || c == '\v' || + c == '\n' || c == '\f' || c == '\r'; +} + static char * parameter(Macro *mp, int n) { @@ -170,9 +177,9 @@ parameter(Macro *mp, int n) begin = mp->arg; end = begin + mp->argsiz; - while (begin < end && isspace(*begin)) + while (begin < end && cppspace(*begin)) begin++; - while (end > begin && isspace(*end)) + while (end > begin && cppspace(end[-1])) end--; siz = end - begin; @@ -249,12 +256,12 @@ concatoper(char *def, char *cur) { char *s; - for (s = cur + 4; isspace(*s); ++s) + for (s = cur + 4; cppspace(*s); ++s) ; if (*s == CONCAT) return 1; - for (s = cur; s > def && isspace(s[-1]); --s) + for (s = cur; s > def && cppspace(s[-1]); --s) ; if (s > def && s[-1] == CONCAT) return 1; @@ -263,6 +270,82 @@ concatoper(char *def, char *cur) } static int +stringoper(char **bpp, int *sizep, char *arg) +{ + int c, esc, delim, siz; + char *bp; + + bp = *bpp; + siz = *sizep; + + if (siz < 3) + return 0; + + esc = delim = 0; + + *bp++ = '"'; + while ((c = *arg++) != '\0') { + switch (c) { + case '\'': + case '"': + if (!esc) { + if (!delim) + delim = c; + else if (delim == c) + delim = 0; + } + + if (c == '"') { + if (siz < 4) + return 0; + *bp++ = '\\'; + siz--; + } else { + if (siz < 3) + return 0; + } + + *bp++ = c; + siz--; + break; + case '\\': + if (!delim) + goto copy; + if (siz < 4) + return 0; + *bp++ = '\\'; + *bp++ = '\\'; + siz -= 2; + + if (!esc) { + esc = 1; + continue; + } + break; + default: + if (!delim && cppspace(c)) { + while (cppspace(*arg)) + ++arg; + c = ' '; + } + copy: + if (siz < 3) + return 0; + *bp++ = c; + siz--; + break; + } + esc = 0; + } + *bp++ = '"'; + + *bpp = bp; + *sizep = siz; + + return 1; +} + +static int expandarg(char *arg, char *def, char *curdef, char *buf, int bufsiz) { int siz; @@ -279,15 +362,24 @@ expandarg(char *arg, char *def, char *curdef, char *buf, int bufsiz) } } else { addinput(IPARAM, arg, FAIL); - for (siz = 0; next() != EOFTOK; siz += yylen+1) { + for (siz = 0; ; siz += yylen) { + yyspace = '\0'; + if (next() == EOFTOK) + break; if (yylen > bufsiz-2) { siz = -1; break; } + + if (yyspace) { + *buf++ = ' '; + bufsiz--; + siz++; + } + memcpy(buf, yytext, yylen); - bufsiz -= yylen + 1; + bufsiz -= yylen; buf += yylen; - *buf++ = ' '; } delinput(); @@ -341,9 +433,9 @@ copymacro(Macro *mp) case CONCAT: /* token concatenation operator */ DBG("MACRO concat"); - while (bp[-1] == ' ') + while (cppspace(bp[-1])) --bp, ++bufsiz; - while (s[1] == ' ') + while (cppspace(s[1])) ++s; break; case STRINGIZE: @@ -352,26 +444,8 @@ copymacro(Macro *mp) arg = mp->arglist[atoi(s += 2)]; s += 2; - if (bufsiz < 3) + if (!stringoper(&bp, &bufsiz, arg)) goto expansion_too_long; - - *bp++ = '"'; - while ((c = *arg++) != '\0') { - if (c == '"') { - if (bufsiz < 3) - goto expansion_too_long; - *bp++ = '\\'; - *bp++ = '"'; - bufsiz -= 2; - } else { - if (bufsiz < 2) - goto expansion_too_long; - *bp++ = c; - bufsiz--; - } - } - *bp++ = '"'; - break; case MACROPAR: /* parameter substitution */ @@ -569,7 +643,7 @@ getdefs(Symbol *args[NR_MACROARG], int nargs, char *buffer, size_t bufsiz) char c, *bp, *s, *p; int len, id, token, prevc, ispar; - while (isspace(*input->p)) + while (cppspace(*input->p)) ++input->p; bp = buffer; @@ -585,6 +659,8 @@ getdefs(Symbol *args[NR_MACROARG], int nargs, char *buffer, size_t bufsiz) ++input->p; } else { c = token = STRINGIZE; + while (cppspace(input->p[1])) + ++input->p; } } else if (c == '"' || c == '\'' || c == '_' || isalpha(c)) { next(); @@ -634,7 +710,7 @@ end_loop: yytoken = EOFTOK; if (prevc == CONCAT) goto wrong_concat; - for ( ; bp > buffer && isspace(bp[-1]); --bp); + for ( ; bp > buffer && cppspace(bp[-1]); --bp); ; *bp = '\0'; return 1; @@ -1077,7 +1153,7 @@ cpp(void) int ns; char *p; - for (p = input->p; isspace(*p); ++p) + for (p = input->p; cppspace(*p); ++p) ; if (*p != '#') { diff --git a/src/cmd/scc-cc/cc1/init.c b/src/cmd/scc-cc/cc1/init.c @@ -31,14 +31,21 @@ int disstring; static long long arydesig(Type *tp, Init *ip) { + long long npos; Node *np; if (tp->op != ARY) errorp("array index in non-array initializer"); + next(); - np = iconstexpr(); - npos = np->sym->u.i; + if ((np = iconstexpr()) == NULL) { + errorp("array index in initializer not of integer type"); + npos = 0; + } else { + npos = np->sym->u.i; + } + if (npos < 0 || (tp->prop & TDEFINED) && npos >= tp->n.elem) { errorp("array index in initializer exceeds array bounds"); npos = 0; diff --git a/src/cmd/scc-cc/cc1/lex.c b/src/cmd/scc-cc/cc1/lex.c @@ -20,7 +20,7 @@ int yytoken; struct yystype yylval; char yytext[STRINGSIZ+3]; unsigned short yylen; -int lexmode = CCMODE; +int yyspace, lexmode = CCMODE; unsigned lineno; char filenam[FILENAME_MAX]; @@ -1024,19 +1024,19 @@ skipspaces(void) for (;;) { switch (c = *input->p) { - case '\n': - if (lexmode == CPPMODE) - goto return_byte; - ++input->p; case '\0': if (!moreinput()) return EOF; break; + case '\n': case ' ': case '\t': case '\v': case '\r': case '\f': + yyspace = c; + if (c == '\n' && lexmode == CPPMODE) + goto return_byte; ++input->p; break; default: diff --git a/src/cmd/scc-cc/cc2/qbe/code.c b/src/cmd/scc-cc/cc2/qbe/code.c @@ -424,7 +424,9 @@ writeout(void) (p->type.flags & AGGRF) ? "" : ".val"); sep = ","; } - printf("%s)\n{\n", (curfun->type.flags&ELLIPS) ? ", ..." : ""); + printf("%s)\n{\n@%s.body\n", + (curfun->type.flags&ELLIPS) ? ", ..." : "", + curfun->name); /* emit assembler instructions */ for (pc = prog; pc; pc = pc->next) { diff --git a/src/cmd/scc-make/rules.c b/src/cmd/scc-make/rules.c @@ -87,13 +87,20 @@ cleanup(Target *tp) } static int -depends(char *target, char *dep) +depends(char *dep, char *target) { + int i; - Target **p, *tp = lookup(target); + char *dname; + Target **p, *tp; + + if (strcmp(target, dep) == 0) + return 1; + tp = lookup(dep); for (p = tp->deps; p && *p; ++p) { - if (strcmp((*p)->name, target) == 0) + dname = (*p)->name; + if (depends(dname, target)) return 1; } diff --git a/src/cmd/scc-ranlib.c b/src/cmd/scc-ranlib.c @@ -28,7 +28,6 @@ static long nsymbols; static int status, artype, nolib; static char *filename, *membname; static Symdef *htab[NR_SYMDEF], *head; -static long offset, oldsize; char *argv0; static void @@ -85,7 +84,7 @@ lookup(char *name) } static int -newsymbol(Symbol *sym) +newsymbol(Symbol *sym, long off) { Symdef *np; @@ -103,7 +102,7 @@ newsymbol(Symbol *sym) break; case 'U': np->type = sym->type; - np->offset = offset; + np->offset = off; break; default: if (sym->type != 'C') { @@ -139,8 +138,6 @@ newmember(FILE *fp, long off) Obj *obj; Symbol sym; - offset = off; - t = objprobe(fp, NULL); if (t == -1 || artype != -1 && artype != t) { nolib = 1; @@ -160,7 +157,7 @@ newmember(FILE *fp, long off) } for (i = 0; getsym(obj, &i, &sym); i++) { - if (!newsymbol(&sym)) + if (!newsymbol(&sym, off)) goto error; } @@ -174,13 +171,13 @@ error: static int readsyms(FILE *fp) { - long cur, off; + long idxsiz, cur, off; char memb[SARNAM+1]; nolib = 0; artype = -1; nsymbols = 0; - oldsize = 0; + idxsiz = 0; if (!archive(fp)) { error("file format not recognized"); @@ -192,7 +189,7 @@ readsyms(FILE *fp) goto corrupted; if (strcmp(memb, "/") == 0 || strcmp(memb, "__.SYMDEF") == 0) { - oldsize = off; + idxsiz = off; cur += off; } @@ -208,7 +205,7 @@ readsyms(FILE *fp) default: membname = memb; if (objprobe(fp, NULL) != -1) - newmember(fp, cur); + newmember(fp, cur - idxsiz); membname = NULL; fseek(fp, cur, SEEK_SET); fseek(fp, off, SEEK_CUR); @@ -316,7 +313,7 @@ ranlib(char *fname) size = sizeof(struct ar_hdr) + prop.size + (prop.size & 1); for (i = 0; i < nsymbols; i++) - offs[i] += size - oldsize; + offs[i] += size; /* Second pass: rewrite index with corrected offsets */ rewind(idx); diff --git a/src/libc/Makefile b/src/libc/Makefile @@ -24,8 +24,5 @@ all: $(DIRS) +@$(MAKE) $(TARGET) $(LIBC): $(OBJS) - $(AR) $(PROJ_ARFLAGS) $(LIBC) $? - $(RL) $(PROJ_RLFLAGS) $(LIBC) - -$(BINDIR)/gcc-scc: gcc-scc.sh - cp gcc-scc.sh $@ + $(AR) $(ARFLAGS) $(LIBC) $? + $(RL) $(RLFLAGS) $(LIBC) diff --git a/src/libc/gcc-scc.sh b/src/libc/gcc-scc.sh @@ -1,89 +0,0 @@ -#!/bin/sh - -set -e - -while getopts gr:O:a:s:o:c o -do - case $o in - g) - g=-g - ;; - O) - opti=-O1 - ;; - r) - root=$OPTARG - ;; - a) - abi=$OPTARG - ;; - s) - sys=$OPTARG - ;; - o) - out=$OPTARG - ;; - c) - onlycc=1 - ;; - *) - echo >&2 "usage: gcc-scc [-o outfile] [-c] [-r root] [-a abi] [-s sys] file" - exit 1 - ;; - esac -done -shift $((OPTIND-1)) - -sys=${sys:-`uname | tr 'A-Z' 'a-z'`} -abi=${abi:-amd64} -out=${out:-a.out} -root=${root:-${SCCPREFIX:-`dirname $0`/..}} -inc=$root/include/scc -arch_inc=$inc/bits/$abi -sys_inc=$inc/bits/$sys -sys_arch_inc=$inc/bits/$sys/$abi -lib=$root/lib/scc/${abi}-${sys} -crt=$root/lib/scc/${abi}-${sys}/crt.o -obj=${1%.c}.o -cc=${CROSS_COMPILE}cc -ld=${CROSS_COMPILE}ld - -case `uname` in -OpenBSD) - nopie=-no-pie - ;; -esac - -includes="-nostdinc -I$inc -I$arch_inc -I$sys_inc -I$sys_arch_inc" -cflags="$opti -std=c99 -w -fno-pie -fno-stack-protector -ffreestanding -static" -ldflags="-z nodefaultlib -static -L$lib" - -if test ${onlycc:-0} -eq 1 -then - $cc $cflags $includes -c "$@" -else - for i - do - case $i in - *.c) - $cc $g $cflags $includes -c "$i" - ;; - esac - done - - # convert *.c args to *.o while correctly maintaing IFS chars - for i - do - shift - case $i in - *.c) - set -- "$@" "${i%c}o" - ;; - *) - set -- "$@" "$i" - ;; - esac - done - - $ld $g $ldflags $nopie $crt "$@" -lc -lcrt -o "$out" -fi diff --git a/src/libc/rules.mk b/src/libc/rules.mk @@ -1,12 +1,4 @@ -CPPINCLUDES =\ - -I$(INCDIR)\ - -I$(INCDIR)/bits/$(SYS)\ - -I$(INCDIR)/bits/$(ARCH)\ - -I$(INCDIR)/bits/$(SYS)/$(ARCH)\ - -MORE_ARFLAGS = -u -MORE_CFLAGS = $(TOOL_LIBC_CFLAGS) $(NOPIE_CFLAGS) -CC=$(SCC) +CC = $(SCC) -t $(SYS) -a $(ARCH) AR=$(SCC_AR) RANLIB=$(SCC_RANLIB) @@ -23,7 +15,7 @@ _sys_errlist.c: $(SYSERRNO) ../../mkerrstr $(SYSERRNO) _sys_errlist.$O: _sys_errlist.c - $(CC) $(PROJ_CFLAGS) -c -o $@ _sys_errlist.c + $(CC) $(CFLAGS) -c -o $@ _sys_errlist.c $(CRT): crt.$O cp crt.$O $@ @@ -34,7 +26,7 @@ clean-libc: FORCE rm -f *.5? *.6? *.7? *.8? *.z *.q .c.$O: - $(CC) $(PROJ_CFLAGS) -o $@ -c $< + $(CC) $(CFLAGS) -o $@ -c $< .s.$O: $(AS) $(PROJ_ASFLAGS) $< -o $@ diff --git a/src/libc/stdio/tmpnam.c b/src/libc/stdio/tmpnam.c @@ -11,18 +11,20 @@ char * tmpnam(char *s) { static char tmpl[] = _TMPNAME; - char *p; + char *p, *beg; - for (;;) { - for (p = tmpl; *p && *p != '9'; ++p) + + for (beg = tmpl; *beg < '0' || *beg > '9'; ++beg) + ; + + do { + for (p = beg; *p == '9'; *p++ = '0') ; if (*p == '\0') return NULL; ++*p; + } while (_access(tmpl, F_OK) == 0); - if (_access(tmpl, F_OK) != 0) - break; - } if (s) strcpy(s, tmpl); return tmpl; diff --git a/tests/cc/error/0041-iconst.c b/tests/cc/error/0041-iconst.c @@ -0,0 +1,17 @@ +/* +PATTERN: +0041-iconst.c:16: error: 'POS2' undeclared +0041-iconst.c:16: error: array index in initializer not of integer type +. +*/ + +enum { + POS0, + POS1, +}; + +int a[] = { + [POS0] = 1, + [POS1] = 2, + [POS2] = 3, +}; diff --git a/tests/cc/error/Makefile b/tests/cc/error/Makefile @@ -1,8 +1,9 @@ .POSIX: -ROOT=../../.. -SCCPREFIX=$(ROOT) -CC=$(EXEC) $(ROOT)/bin/scc cc +PROJECTDIR = ../../.. +include $(PROJECTDIR)/scripts/rules.mk + +CC=$(SCC) all: @CC='$(CC)' ./runtests.sh scc-tests.lst diff --git a/tests/cc/error/scc-tests.lst b/tests/cc/error/scc-tests.lst @@ -38,3 +38,4 @@ 0038-void.c 0039-struct.c 0040-vararg.c +0041-iconst.c diff --git a/tests/cc/error/update.sh b/tests/cc/error/update.sh @@ -5,7 +5,7 @@ update() for i do (echo '/^PATTERN/+;/^\./-c' - scc $CFLAGS -W -c $i 2>&1 + ../../../bin/scc $CFLAGS -W -c $i 2>&1 printf ".\nw\n" echo w) | ed -s $i diff --git a/tests/cc/execute/.gitignore b/tests/cc/execute/.gitignore @@ -2,6 +2,3 @@ test.log tests.h tmp_*.c a.out -0270-union -0271-struct -0272-div diff --git a/tests/cc/execute/0273-cpp.c b/tests/cc/execute/0273-cpp.c @@ -0,0 +1,35 @@ +#define a(x) # x + +static char *s = a ( 3 +2); + +static int +cmp(char *s1, char *s2) +{ + while (*s1 && *s2 && *s1 == *s2) + ++s1, ++s2; + return *s1 == '\0' && *s2 == '\0'; +} + +int +main(void) +{ + if (!cmp(a(3), "3")) + return 1; + if (!cmp(a( 3 ), "3")) + return 2; + if (!cmp(a( 3 2 ), "3 2")) + return 3; + if (!cmp(s, "3 2")) + return 4; + if (!cmp(a("3 2 1\n"), "\"3 2 1\\n\"")) + return 5; + if (!cmp(a('\n'), "'\\n'")) + return 6; + if (!cmp(a('"'), "'\"'")) + return 6; + if (!cmp(a(: @\n), ": @\n")) + return 7; + + return 0; +} diff --git a/tests/cc/execute/0274-loop.c b/tests/cc/execute/0274-loop.c @@ -0,0 +1,8 @@ +int +main() +{ + do { + } while (0); + + return 0; +} diff --git a/tests/cc/execute/Makefile b/tests/cc/execute/Makefile @@ -5,6 +5,8 @@ include $(PROJECTDIR)/scripts/rules.mk CC=$(SCC) PROJ_CFLAGS = $(CFLAGS) +PROJ_LDFLAGS= $(LDFLAGS) +PROJ_LDLIBS = all: @CC='$(CC)' ./runtests.sh scc-tests.lst diff --git a/tests/cc/execute/scc-tests.lst b/tests/cc/execute/scc-tests.lst @@ -190,7 +190,7 @@ 0197-cppcomment.c 0198-nullcpp.c 0199-voidpcast.c -0200-cpp.c [TODO] +0200-cpp.c 0201-cpp.c 0202-variadic.c 0203-comment.c @@ -263,3 +263,5 @@ 0270-union.c 0271-struct.c 0272-div.c +0273-cpp.c +0274-loop.c diff --git a/tests/libc/execute/0098-tmpfil.c b/tests/libc/execute/0098-tmpfil.c @@ -52,7 +52,7 @@ test2(void) max = TMP_MAX - 2; if (max > FOPEN_MAX) - max = FOPEN_MAX; + max = FOPEN_MAX - 3; if (max > 32) max = 32; diff --git a/tests/libc/execute/Makefile b/tests/libc/execute/Makefile @@ -7,9 +7,6 @@ PROJ_CFLAGS = $(CFLAGS) PROJ_LDFLAGS = $(LDFLAGS) CC=$(SCC) -# Uncomment following line to use gcc to test the libc -# CC = $(BINDIR)/gcc-scc - all: @CC='$(CC)' \ CFLAGS='$(PROJ_CFLAGS)' \ diff --git a/tests/make/execute/0110-loop.sh b/tests/make/execute/0110-loop.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +trap 'rm -f $tmp1' EXIT +trap 'exit $?' INT TERM HUP + +tmp1=tmp1.$$ + +$EXEC scc make -f - <<'EOF' > $tmp1 2>&1 +all: target1 + +target1: target2 + @echo target1 + +target2: target3 + @echo target2 + +target3: target1 + @echo target3 +EOF + +diff $tmp1 - <<EOF +make: warning: <stdin>:11: circular dependency target3 <- target1 dropped +target3 +target2 +target1 +EOF