shithub: scc

Download patch

ref: 43909706d4a5f8145a95b87737b82b06eddb2c98
parent: 11fc427207a2472e5309ce0ea2258b5ad4a2ef16
parent: c91781cb539c8c8d9bf20a37671f3451e24eb8ea
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Wed Jul 13 04:07:59 EDT 2016

Merge branch 'master' into qbe

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -382,8 +382,10 @@
 extern void expect(unsigned tok);
 extern void discard(void);
 extern int addinput(char *fname);
+extern void allocinput(char *fname, FILE *fp, char *line);
+extern void delinput(void);
 extern void setsafe(int type);
-extern void ilex(char *fname);
+extern void ilex(void);
 #define accept(t) ((yytoken == (t)) ? next() : 0)
 
 /* code.c */
@@ -418,7 +420,7 @@
 extern int expand(char *begin, Symbol *sym);
 extern void incdir(char *dir);
 extern void outcpp(void);
-extern Symbol *defmacro(char *s);
+extern void defdefine(char *macro, char *val);
 extern void undefmacro(char *s);
 
 /*
--- a/cc1/cpp.c
+++ b/cc1/cpp.c
@@ -13,6 +13,7 @@
 
 static char *argp, *macroname;
 static unsigned arglen;
+static unsigned ncmdlines;
 static Symbol *symline, *symfile;
 static unsigned char ifstatus[NR_COND];
 static int ninclude;
@@ -21,30 +22,20 @@
 unsigned cppctx;
 int disexpand;
 
-Symbol *
-defmacro(char *s)
+void
+defdefine(char *macro, char *val)
 {
-	char *p, *q;
-	Symbol *sym;
-	char def[] = "=1";
+	char *def, *fmt = "#define %s %s";
 
-	if ((p = strchr(s, '=')) == NULL)
-		p = def;
-	*p++='\0';
-	q = xmalloc(strlen(p) + 4);
-	sprintf(q, "-1#%s", p);
+	if (!val)
+		val = "";
+	def = xmalloc(strlen(fmt) + strlen(macro) + strlen(val));
 
-	sym = lookup(NS_CPP, s);
-	if (sym->flags & SDECLARED) {
-		warn("'%s' redefined");
-		free(sym->u.s);
-	} else {
-		install(NS_CPP, sym);
-		sym->flags |= SDECLARED|SSTRING;
-	}
-
-	sym->u.s = q;
-	return sym;
+	sprintf(def, fmt, macro, val);
+	allocinput("command-line", NULL, def);
+	input->nline = ++ncmdlines;
+	cpp();
+	delinput();
 }
 
 void
@@ -56,7 +47,7 @@
 void
 icpp(void)
 {
-	static char sdate[17], stime[14];
+	static char sdate[14], stime[11];
 	struct tm *tm;
 	time_t t;
 	static char **bp, *list[] = {
@@ -81,20 +72,25 @@
 		{NULL, 0, 0}
 	};
 
+	keywords(keys, NS_CPPCLAUSES);
+
 	t = time(NULL);
 	tm = localtime(&t);
-	strftime(sdate, sizeof(sdate), "-1#\"%b %d %Y\"", tm);
-	strftime(stime, sizeof(stime), "-1#\"%H:%M:%S\"", tm);
-	defmacro("__DATE__")->u.s = sdate;
-	defmacro("__TIME__")->u.s = stime;
+	strftime(sdate, sizeof(sdate), "\"%b %d %Y\"", tm);
+	strftime(stime, sizeof(stime), "\"%H:%M:%S\"", tm);
+	defdefine("__DATE__", sdate);
+	defdefine("__TIME__", stime);
+	defdefine("__STDC_VERSION__", "199409L");
+	defdefine("__LINE__", NULL);
+	defdefine("__FILE__", NULL);
 
-	defmacro("__STDC_VERSION__")->u.s = "-1#199409L";
-	symline = defmacro("__LINE__");
-	symfile = defmacro("__FILE__");
+	symline = lookup(NS_CPP, "__LINE__");
+	symfile = lookup(NS_CPP, "__FILE__");
 
 	for (bp = list; *bp; ++bp)
-		defmacro(*bp)->u.s = "-1#1";
-	keywords(keys, NS_CPPCLAUSES);
+		defdefine(*bp, NULL);
+
+	ncmdlines = 0;
 }
 
 static void
@@ -163,7 +159,9 @@
 	n = 0;
 	argp = buffer;
 	arglen = INPUTSIZ;
-	if (yytoken != ')') {
+	if (ahead() == ')') {
+		next();
+	} else {
 		do {
 			*listp++ = argp;
 			parameter();
@@ -573,7 +571,7 @@
 	next();
 	if (!strcmp(yytext, "GCC"))
 		warn(magic);
-	warn("ignoring pragma '%s'", input->begin);
+	warn("ignoring pragma '%s'", yytext);
 	*input->p = '\0';
 	next();
 }
--- a/cc1/lex.c
+++ b/cc1/lex.c
@@ -22,16 +22,18 @@
 static int safe, eof;
 Input *input;
 
-static void
-allocinput(char *fname, FILE *fp)
+void
+allocinput(char *fname, FILE *fp, char *line)
 {
-	Input *ip;
+	Input *ip = xmalloc(sizeof(Input));
 
-	ip = xmalloc(sizeof(Input));
-	ip->fname = xstrdup(fname);
-	ip->p = ip->begin = ip->line = xmalloc(INPUTSIZ);
-	ip->p[0] = '\0';
+	if (!line) {
+		line = xmalloc(INPUTSIZ);
+		line[0] = '\0';
+	}
+	ip->p = ip->begin = ip->line = line;
 	ip->nline = 0;
+	ip->fname = xstrdup(fname);
 	ip->next = input;
 	ip->fp = fp;
 	input = ip;
@@ -38,7 +40,7 @@
 }
 
 void
-ilex(char *fname)
+ilex(void)
 {
 	static struct keyword keys[] = {
 		{"auto", SCLASS, AUTO},
@@ -78,18 +80,6 @@
 		{"while", WHILE, WHILE},
 		{NULL, 0, 0},
 	};
-	FILE *fp;
-
-	if (!fname) {
-		fp = stdin;
-		fname = "<stdin>";
-	} else {
-		if ((fp = fopen(fname, "r")) == NULL) {
-			die("error: failed to open input file '%s': %s",
-			    fname, strerror(errno));
-		}
-	}
-	allocinput(fname, fp);
 	keywords(keys, NS_KEYWORD);
 }
 
@@ -98,21 +88,29 @@
 {
 	FILE *fp;
 
-	if ((fp = fopen(fname, "r")) == NULL)
-		return 0;
-	allocinput(fname, fp);
+	if (fname) {
+		if ((fp = fopen(fname, "r")) == NULL)
+			return 0;
+	} else {
+		fp = stdin;
+		fname = "<stdin>";
+	}
+	allocinput(fname, fp, NULL);
 	return 1;
 }
 
-static void
+void
 delinput(void)
 {
 	Input *ip = input;
 
-	if (!ip->next)
-		eof = 1;
-	if (fclose(ip->fp))
-		die("error: failed to read from input file '%s'", ip->fname);
+	if (ip->fp) {
+		if (fclose(ip->fp))
+			die("error: failed to read from input file '%s'",
+			    ip->fname);
+		if (!ip->next)
+			eof = 1;
+	}
 	if (eof)
 		return;
 	input = ip->next;
@@ -130,14 +128,12 @@
 static int
 readchar(void)
 {
+	FILE *fp = input->fp;
 	int c;
-	FILE *fp;
 
-repeat:
-	if (eof)
+	if (eof || !fp)
 		return 0;
-	fp = input->fp;
-
+repeat:
 	switch (c = getc(fp)) {
 	case EOF:
 		c = '\0';
--- a/cc1/main.c
+++ b/cc1/main.c
@@ -29,6 +29,19 @@
 }
 
 static void
+defmacro(char *macro)
+{
+	char *p = strchr(macro, '=');
+
+	if (p)
+		*p++ = '\0';
+	else
+		p = "1";
+
+	defdefine(macro, p);
+}
+
+static void
 usage(void)
 {
 	die(!strcmp(name, "cpp") ?
@@ -46,6 +59,7 @@
 
 	atexit(clean);
 	icpp();
+	ilex();
 
 	/* if run as cpp, only run the preprocessor */
 	name = (cp = strrchr(*argv, '/')) ? cp + 1 : *argv;
@@ -88,7 +102,10 @@
 	for (i = 0; i < uflags.n; ++i)
 		undefmacro(uflags.s[i]);
 
-	ilex(*argv);
+	if (!addinput(*argv)) {
+		die("error: failed to open input file '%s': %s",
+		    *argv, strerror(errno));
+	}
 	if (onlycpp) {
 		outcpp();
 	} else {
--- /dev/null
+++ b/cc1/tests/test064.c
@@ -1,0 +1,32 @@
+/* See LICENSE file for copyright and license details. */
+
+/*
+name: TEST064
+description: Test function alike macro without parenthesis
+error:
+output:
+G5	I	F	"main
+{
+\
+S1	"	#N2	#N1
+M2	I	"f	#N0
+A6	S1	"s
+	A6	M2	.I	#I0	:I
+	h	A6	M2	.I
+}
+*/
+
+#define x f
+#define y() f
+
+typedef struct { int f; } S;
+
+int
+main()
+{
+	S s;
+	
+	s.x = 0;
+	return s.y();
+}
+
--- a/cc2/parser.c
+++ b/cc2/parser.c
@@ -329,7 +329,8 @@
 {
 	Node *np = newnode(u.op);
 
-	eval(strtok(NULL, "\t\n"));
+	if (token = strtok(NULL, "\t\n"))
+		eval(token);
 	if (!empty())
 		np->left = pop();
 	push(np);
--- a/driver/posix/Makefile
+++ b/driver/posix/Makefile
@@ -7,7 +7,7 @@
 
 all: scc
 
-$(OBJS): ../../inc/cc.h
+$(OBJS): ../../inc/cc.h ../../inc/arg.h
 
 ../../lib/libcc.a:
 	cd ../../lib && $(MAKE) -e
--- a/driver/posix/scc.c
+++ b/driver/posix/scc.c
@@ -1,5 +1,6 @@
 /* See LICENSE file for copyright and license details. */
 #define _POSIX_SOURCE
+#define _XOPEN_SOURCE 500
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
@@ -48,7 +49,9 @@
 };
 
 char *argv0;
-static char *arch, *outfile;
+static char *arch, *objfile, *outfile;
+static char *tmpdir;
+static size_t tmpdirln;
 static struct items objtmp, objout;
 static int Eflag, Sflag, cflag, kflag, sflag;
 
@@ -134,30 +137,35 @@
 }
 
 static char *
-outfilename(char *path, char *ext)
+outfname(char *path, char *type)
 {
-	char *new, *name, *dot;
-	size_t newsz, nameln;
-	int n;
+	char *new, sep, *p;
+	size_t newsz, pathln;
+	int tmpfd, n;
 
-	if (!(name = strrchr(path, '/')))
-		name = path;
-	else
-		++name;
+	if (path) {
+		sep = '.';
+		if (p = strrchr(path, '/'))
+			path = p + 1;
+		pathln = strlen(path);
+		if (p = strrchr(path, '.'))
+			pathln -= strlen(p);
+	} else {
+		sep = '/';
+		type = "scc-XXXXXX";
+		path = tmpdir;
+		pathln = tmpdirln;
+	}
 
-	nameln = strlen(name);
-
-	if (!(dot = strrchr(name, '.')))
-		dot = &name[nameln];
-
-	nameln = nameln - strlen(dot);
-	newsz  = nameln + strlen(ext) + 1 + 1;
-
+	newsz = pathln + 1 + strlen(type) + 1;
 	new = xmalloc(newsz);
-
-	n = snprintf(new, newsz, "%.*s.%s", nameln, name, ext);
+	n = snprintf(new, newsz, "%.*s%c%s", pathln, path, sep, type);
 	if (n < 0 || n >= newsz)
 		die("scc: wrong output filename");
+	if ((tmpfd = mkstemp(new)) < 0 && errno != EINVAL)
+		die("scc: could not create output file '%s': %s",
+		    new, strerror(errno));
+	close(tmpfd);
 
 	return new;
 }
@@ -172,27 +180,27 @@
 
 	switch (tool) {
 	case TEEIR:
-		t->outfile = outfilename(infile, "ir");
+		t->outfile = outfname(infile, "ir");
 		addarg(tool, t->outfile);
 		break;
 	case TEEQBE:
-		t->outfile = outfilename(infile, "qbe");
+		t->outfile = outfname(infile, "qbe");
 		addarg(tool, t->outfile);
 		break;
 	case TEEAS:
-		t->outfile = outfilename(infile, "as");
+		t->outfile = outfname(infile, "as");
 		addarg(tool, t->outfile);
 		break;
 	case AS:
-		t->outfile = outfile ? outfile : outfilename(infile, "o");
+		if (cflag && outfile) {
+			objfile = outfile;
+		} else {
+			objfile = (cflag || kflag) ? infile : NULL;
+			objfile = outfname(objfile, "o");
+		}
+		t->outfile = xstrdup(objfile);
 		addarg(tool, t->outfile);
 		break;
-	case LD:
-		for (i = 0; i < objtmp.n; ++i)
-			addarg(tool, xstrdup(objtmp.s[i]));
-		for (i = 0; i < objout.n; ++i)
-			addarg(tool, xstrdup(objout.s[i]));
-		break;
 	case STRIP:
 		if (cflag || kflag) {
 			for (i = 0; i < objout.n; ++i)
@@ -298,16 +306,20 @@
 			t->pid = 0;
 		}
 	}
+	if (failed < LAST_TOOL) {
+		unlink(objfile);
+		free(objfile);
+		objfile = NULL;
+		return 0;
+	}
 
-	return failed == LAST_TOOL;
+	return 1;
 }
 
-static void
-build(char *file)
+static int
+buildfile(char *file, int tool)
 {
-	int tool = toolfor(file), nexttool;
-	struct items *objs = (tool == LD || cflag || kflag) ?
-	                       &objout : &objtmp;
+	int nexttool;
 
 	for (; tool < LAST_TOOL; tool = nexttool) {
 		switch (tool) {
@@ -346,27 +358,61 @@
 		spawn(settool(inittool(tool), file, nexttool));
 	}
 
-	if (validatetools())
-		newitem(objs, outfilename(file, "o"));
+	return validatetools();
 }
 
 static void
+build(struct items *chain, int link)
+{
+	int i, tool;
+
+	if (link)
+		inittool(LD);
+
+	for (i = 0; i < chain->n; ++i) {
+		if (!strcmp(chain->s[i], "-l")) {
+			if (link) {
+				addarg(LD, xstrdup(chain->s[i++]));
+				addarg(LD, xstrdup(chain->s[i]));
+			} else {
+				++i;
+			}
+			continue;
+		}
+		tool = toolfor(chain->s[i]);
+		if (tool == LD) {
+			if (link)
+				addarg(LD, xstrdup(chain->s[i]));
+			continue;
+		}
+		if (buildfile(chain->s[i], tool)) {
+			if (link)
+				addarg(LD, xstrdup(objfile));
+			newitem((!link || kflag) ? &objout : &objtmp, objfile);
+		}
+	}
+}
+
+static void
 usage(void)
 {
 	die("usage: scc [-D def[=val]]... [-U def]... [-I dir]... "
 	    "[-L dir]... [-l dir]...\n"
-	    "           [-ksw] [-m arch] [-E|-S] [-o outfile] file...\n"
+	    "           [-gksw] [-m arch] [-E|-S] [-o outfile] file...\n"
 	    "       scc [-D def[=val]]... [-U def]... [-I dir]... "
 	    "[-L dir]... [-l dir]...\n"
-	    "           [-ksw] [-m arch] [-E|-S] -c file...\n"
+	    "           [-gksw] [-m arch] [-E|-S] -c file...\n"
 	    "       scc [-D def[=val]]... [-U def]... [-I dir]... "
 	    "[-L dir]... [-l dir]...\n"
-	    "           [-ksw] [-m arch] -c -o outfile file");
+	    "           [-gksw] [-m arch] -c -o outfile file");
 }
 
 int
 main(int argc, char *argv[])
 {
+	struct items linkchain = { .n = 0, };
+	int link;
+
 	atexit(terminate);
 
 	arch = getenv("ARCH");
@@ -398,12 +444,16 @@
 	case 'c':
 		cflag = 1;
 		break;
+	case 'g':
+		addarg(AS, "-g");
+		addarg(LD, "-g");
+		break;
 	case 'k':
 		kflag = 1;
 		break;
 	case 'l':
-		addarg(LD, "-l");
-		addarg(LD, EARGF(usage()));
+		newitem(&linkchain, "-l");
+		newitem(&linkchain, EARGF(usage()));
 		break;
 	case 'm':
 		arch = EARGF(usage());
@@ -423,19 +473,29 @@
 		break;
 	default:
 		usage();
+	} ARGOPERAND {
+operand:
+		newitem(&linkchain, ARGOP());
 	} ARGEND
 
-	if (Eflag && (Sflag || kflag) || argc > 1 && cflag && outfile || !argc)
+	for (; *argv; --argc, ++argv)
+		goto operand;
+
+	if (Eflag && (Sflag || kflag) || linkchain.n == 0 ||
+	    linkchain.n > 1 && cflag && outfile)
 		usage();
 
-	for (; *argv; ++argv)
-		build(*argv);
+	if (!(tmpdir = getenv("TMPDIR")) || !tmpdir[0])
+		tmpdir = ".";
+	tmpdirln = strlen(tmpdir);
 
-	if (Eflag || Sflag)
+	build(&linkchain, (link = !(Eflag || Sflag || cflag)));
+
+	if (!(link || cflag))
 		return failure;
 
-	if (!cflag && !failure) {
-		spawn(settool(inittool(LD), NULL, LAST_TOOL));
+	if (link && !failure) {
+		spawn(settool(LD, NULL, LAST_TOOL));
 		validatetools();
 	}
 
--- a/inc/arg.h
+++ b/inc/arg.h
@@ -9,57 +9,59 @@
 extern char *argv0;
 
 /* use main(int argc, char *argv[]) */
-#define ARGBEGIN	for (argv0 = *argv, argv++, argc--;\
-					argv[0] && argv[0][0] == '-'\
-					&& argv[0][1];\
-					argc--, argv++) {\
-				char argc_;\
-				char **argv_;\
-				int brk_;\
-				if (argv[0][1] == '-' && argv[0][2] == '\0') {\
-					argv++;\
-					argc--;\
-					break;\
-				}\
-				for (brk_ = 0, argv[0]++, argv_ = argv;\
-						argv[0][0] && !brk_;\
-						argv[0]++) {\
-					if (argv_ != argv)\
-						break;\
-					argc_ = argv[0][0];\
-					switch (argc_)
+#define ARGBEGIN \
+for (argv0 = *argv, argv++, argc--;\
+     argv[0];\
+     argc--, argv++) {\
+	if (argv[0][0] == '-') {\
+		char argc_;\
+		char **argv_;\
+		int brk_;\
+		if (argv[0][1] == '-' && argv[0][2] == '\0') {\
+			argv++;\
+			argc--;\
+			break;\
+		}\
+		for (brk_ = 0, argv[0]++, argv_ = argv;\
+		     argv[0][0] && !brk_;\
+		     argv[0]++) {\
+			if (argv_ != argv)\
+				break;\
+			argc_ = argv[0][0];\
+			switch (argc_)
 
-/* Handles obsolete -NUM syntax */
-#define ARGNUM				case '0':\
-					case '1':\
-					case '2':\
-					case '3':\
-					case '4':\
-					case '5':\
-					case '6':\
-					case '7':\
-					case '8':\
-					case '9'
+#define ARGOPERAND \
+		}\
+	} else if (argv[0][0] != '\0') {\
+		{
 
-#define ARGEND			}\
-			}
+#define ARGEND \
+		}\
+	} else {\
+		break;\
+	}\
+}
 
-#define ARGC()		argc_
+#define ARGC() argc_
 
-#define ARGNUMF()	(brk_ = 1, estrtonum(argv[0], 0, INT_MAX))
+#define ARGOP() argv[0]
 
-#define EARGF(x)	((argv[0][1] == '\0' && argv[1] == NULL)?\
-				((x), abort(), (char *)0) :\
-				(brk_ = 1, (argv[0][1] != '\0')?\
-					(&argv[0][1]) :\
-					(argc--, argv++, argv[0])))
+#define ARGNUMF() (brk_ = 1, estrtonum(argv[0], 0, INT_MAX))
 
-#define ARGF()		((argv[0][1] == '\0' && argv[1] == NULL)?\
-				(char *)0 :\
-				(brk_ = 1, (argv[0][1] != '\0')?\
-					(&argv[0][1]) :\
-					(argc--, argv++, argv[0])))
+#define EARGF(x) \
+((argv[0][1] == '\0' && argv[1] == NULL) ?\
+    ((x), abort(), (char *)0) :\
+    (brk_ = 1, (argv[0][1] != '\0') ?\
+        (&argv[0][1]) :\
+        (argc--, argv++, argv[0])))
 
-#define LNGARG()	&argv[0][0]
+#define ARGF() \
+((argv[0][1] == '\0' && argv[1] == NULL)?\
+    (char *)0 :\
+    (brk_ = 1, (argv[0][1] != '\0')?\
+        (&argv[0][1]) :\
+        (argc--, argv++, argv[0])))
+
+#define LNGARG() &argv[0][0]
 
 #endif
--- a/libc/include/amd64-sysv/stdlib.h
+++ b/libc/include/amd64-sysv/stdlib.h
@@ -48,7 +48,7 @@
 extern void abs(int x);
 /* div_t div(int num, int denom); */
 extern long labs(long int x);
-/* ldiv_t ldiv(long int number, long int denom);
+/* ldiv_t ldiv(long int number, long int denom); */
 
 extern int rand(void);
 extern void srand(unsigned seed);
--- a/libc/include/i386-sysv/stdlib.h
+++ b/libc/include/i386-sysv/stdlib.h
@@ -48,7 +48,7 @@
 extern void abs(int x);
 /* div_t div(int num, int denom); */
 extern long labs(long int x);
-/* ldiv_t ldiv(long int number, long int denom);
+/* ldiv_t ldiv(long int number, long int denom); */
 
 extern int rand(void);
 extern void srand(unsigned seed);
--- a/libc/include/qbe/stdlib.h
+++ b/libc/include/qbe/stdlib.h
@@ -48,7 +48,7 @@
 extern void abs(int x);
 /* div_t div(int num, int denom); */
 extern long labs(long int x);
-/* ldiv_t ldiv(long int number, long int denom);
+/* ldiv_t ldiv(long int number, long int denom); */
 
 extern int rand(void);
 extern void srand(unsigned seed);
--- a/libc/include/z80/stdlib.h
+++ b/libc/include/z80/stdlib.h
@@ -48,7 +48,7 @@
 extern void abs(int x);
 /* div_t div(int num, int denom); */
 extern long labs(long int x);
-/* ldiv_t ldiv(long int number, long int denom);
+/* ldiv_t ldiv(long int number, long int denom); */
 
 extern int rand(void);
 extern void srand(unsigned seed);
--- /dev/null
+++ b/tests/0070-cppif.c
@@ -1,0 +1,19 @@
+
+#if 1
+int x = 0;
+#endif
+
+#if 0
+int x = 1;
+#if 1
+ X
+#endif
+#ifndef AAA
+ X
+#endif
+#endif
+
+int main()
+{
+	return x;
+}
--- /dev/null
+++ b/tests/0071-cppelif.c
@@ -1,0 +1,14 @@
+
+#if 0
+X
+#elif 1
+int x = 0;
+#else
+X
+#endif
+
+int
+main()
+{
+	return x;
+}
--- /dev/null
+++ b/tests/0072-cppelif.c
@@ -1,0 +1,14 @@
+
+#if 0
+X
+#elif 0
+X
+#elif 1
+int x = 0;
+#endif
+
+int
+main()
+{
+	return x;
+}
--- /dev/null
+++ b/tests/0073-ifndef.c
@@ -1,0 +1,17 @@
+
+
+#ifndef DEF
+int x = 0;
+#endif
+
+#define DEF
+
+#ifndef DEF
+X
+#endif
+
+int
+main()
+{
+	return x;
+}
--- /dev/null
+++ b/tests/0074-undef.c
@@ -1,0 +1,13 @@
+
+#define X 1
+#undef X
+
+#ifdef X
+FAIL
+#endif
+
+int
+main()
+{
+	return 0;
+}
--- /dev/null
+++ b/tests/0075-ptraddasn.c
@@ -1,0 +1,15 @@
+
+int
+main()
+{
+	int arr[2];
+	int *p;
+	
+	p = &arr[0];
+	p += 1;
+	*p = 123;
+	
+	if(arr[1] != 123)
+		return 1;
+	return 0;
+}
--- /dev/null
+++ b/tests/0076-ptrsubasn.c
@@ -1,0 +1,15 @@
+
+int
+main()
+{
+	int arr[2];
+	int *p;
+	
+	p = &arr[1];
+	p -= 1;
+	*p = 123;
+	
+	if(arr[0] != 123)
+		return 1;
+	return 0;
+}
--- /dev/null
+++ b/tests/0077-defined.c
@@ -1,0 +1,33 @@
+
+#if defined X
+X
+#endif
+
+#if defined(X)
+X
+#endif
+
+#if X
+X
+#endif
+
+#define X 0
+
+#if X
+X
+#endif
+
+#if defined(X)
+int x = 0;
+#endif
+
+#undef X
+#define X 1
+
+#if X
+int
+main()
+{
+	return 0;
+}
+#endif
--- /dev/null
+++ b/tests/0078-dirifexpr.c
@@ -1,0 +1,171 @@
+
+#if (-2) != -2
+#error fail
+#endif
+
+#if (0 || 0) != 0
+#error fail
+#endif
+
+#if (1 || 0) != 1
+#error fail
+#endif
+
+#if (1 || 1) != 1
+#error fail
+#endif
+
+#if (0 && 0) != 0
+#error fail
+#endif
+
+#if (1 && 0) != 0
+#error fail
+#endif
+
+#if (0 && 1) != 0
+#error fail
+#endif
+
+#if (1 && 1) != 1
+#error fail
+#endif
+
+#if (0xf0 | 1) != 0xf1
+#error fail
+#endif
+
+#if (0xf0 & 1) != 0
+#error fail
+#endif
+
+#if (0xf0 & 0x1f) != 0x10
+#error fail
+#endif
+
+#if (1 ^ 1) != 0
+#error fail
+#endif
+
+#if (1 == 1) != 1
+#error fail
+#endif
+
+#if (1 == 0) != 0
+#error fail
+#endif
+
+#if (1 != 1) != 0
+#error fail
+#endif
+
+#if (0 != 1) != 1
+#error fail
+#endif
+
+#if (0 > 1) != 0
+#error fail
+#endif
+
+#if (0 < 1) != 1
+#error fail
+#endif
+
+#if (0 > -1) != 1
+#error fail
+#endif
+
+#if (0 < -1) != 0
+#error fail
+#endif
+
+#if (0 >= 1) != 0
+#error fail
+#endif
+
+#if (0 <= 1) != 1
+#error fail
+#endif
+
+#if (0 >= -1) != 1
+#error fail
+#endif
+
+#if (0 <= -1) != 0
+#error fail
+#endif
+
+#if (0 < 0) != 0
+#error fail
+#endif
+
+#if (0 <= 0) != 1
+#error fail
+#endif
+
+#if (0 > 0) != 0
+#error fail
+#endif
+
+#if (0 >= 0) != 1
+#error fail
+#endif
+
+#if (1 << 1) != 2
+#error fail
+#endif
+
+#if (2 >> 1) != 1
+#error fail
+#endif
+
+#if (2 + 1) != 3
+#error fail
+#endif
+
+#if (2 - 3) != -1
+#error fail
+#endif
+
+#if (2 * 3) != 6
+#error fail
+#endif
+
+#if (6 / 3) != 2
+#error fail
+#endif
+
+#if (7 % 3) != 1
+#error fail
+#endif
+
+#if (2+2*3+2) != 10
+#error fail
+#endif
+
+#if ((2+2)*(3+2)) != 20
+#error fail
+#endif
+
+#if (2 + 2 + 2 + 2 == 2 + 2 * 3) != 1
+#error fail
+#endif
+
+#if (1,2,3) != 3
+#error fail
+#endif
+
+#if (0 ? 1 : 3) != 3
+#error fail
+#endif
+
+#if (1 ? 3 : 1) != 3
+#error fail
+#endif
+
+int
+main()
+{
+	return 0;
+}
+
--- /dev/null
+++ b/tests/0079-cond.c
@@ -1,0 +1,10 @@
+
+int
+main()
+{
+	if(0 ? 1 : 0)
+		return 1;
+	if(1 ? 0 : 1)
+		return 2;
+	return 0;
+}
--- /dev/null
+++ b/tests/0080-arrays.c
@@ -1,0 +1,49 @@
+
+int
+foo(int x[100])
+{
+	int y[100];
+	int *p;
+	
+	y[0] = 2000;
+	
+	if(x[0] != 1000)
+	{
+		return 1;
+	}
+	
+	p = x;
+	
+	if(p[0] != 1000)
+	{
+		return 2;
+	}
+	
+	p = y;
+	
+	if(p[0] != 2000)
+	{
+		return 3;
+	}
+	
+	if(sizeof(x) != sizeof(void*))
+	{
+		return 4;
+	}
+	
+	if(sizeof(y) <= sizeof(x))
+	{
+		return 5;
+	}
+	
+	return 0;
+}
+
+int
+main()
+{
+	int x[100];
+	x[0] = 1000;
+	
+	return foo(x);
+}