shithub: femtolisp

Download patch

ref: 46828171bff7566180e8d0ae1b30debe1aa47fb9
parent: c1bc93f9dea696db60cd0c191ba8ad35deaff8f4
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Mon Jan 6 13:33:14 EST 2025

enable more warnings, fix a bunch of them

--- a/3rd/brieflz/brieflz.c
+++ b/3rd/brieflz/brieflz.c
@@ -27,10 +27,7 @@
 
 #include "brieflz.h"
 
-#if _MSC_VER >= 1400
-#  include <intrin.h>
-#  define BLZ_BUILTIN_MSVC
-#elif defined(__clang__) && defined(__has_builtin)
+#if defined(__clang__) && defined(__has_builtin)
 #  if __has_builtin(__builtin_clz)
 #    define BLZ_BUILTIN_GCC
 #  endif
--- a/3rd/mp/mpaux.c
+++ b/3rd/mp/mpaux.c
@@ -145,7 +145,7 @@
 	new = mpnew(Dbits*old->size);
 	new->sign = old->sign;
 	new->top = old->top;
-	new->flags = old->flags & ~(MPstatic|MPfield);
+	new->flags = old->flags & ~(MPstatic);
 	memmove(new->p, old->p, Dbytes*old->top);
 	return new;
 }
@@ -160,7 +160,7 @@
 	new->sign = old->sign;
 	new->top = old->top;
 	new->flags &= ~MPnorm;
-	new->flags |= old->flags & ~(MPstatic|MPfield);
+	new->flags |= old->flags & ~(MPstatic);
 	memmove(new->p, old->p, Dbytes*old->top);
 }
 
--- a/3rd/mp/mpcmp.c
+++ b/3rd/mp/mpcmp.c
@@ -24,5 +24,5 @@
 	int sign;
 
 	sign = (b1->sign - b2->sign) >> 1;	// -1, 0, 1
-	return sign | (sign&1)-1 & mpmagcmp(b1, b2)*b1->sign;
+	return sign | (((sign&1)-1) & mpmagcmp(b1, b2)*b1->sign);
 }
--- a/3rd/mp/mpdiv.c
+++ b/3rd/mp/mpdiv.c
@@ -21,10 +21,10 @@
 	}
 
 	// division by one or small powers of two
-	if(divisor->top == 1 && (divisor->p[0] & divisor->p[0]-1) == 0){
+	if(divisor->top == 1 && (divisor->p[0] & (divisor->p[0]-1)) == 0){
 		int64_t r = 0;
 		if(dividend->top > 0)
-			r = (int64_t)dividend->sign * (dividend->p[0] & divisor->p[0]-1);
+			r = (int64_t)dividend->sign * (dividend->p[0] & (divisor->p[0]-1));
 		if(quotient != nil){
 			sign = divisor->sign;
 			for(s = 0; ((divisor->p[0] >> s) & 1) == 0; s++)
--- a/3rd/mp/mpfmt.c
+++ b/3rd/mp/mpfmt.c
@@ -16,7 +16,7 @@
 	for(p = b->p+b->top-1; p >= b->p; p--){
 		x = *p;
 		for(i = Dbits-s; i >= 0; i -= s){
-			j = x >> i & sn - 1;
+			j = x >> i & (sn - 1);
 			if(j != 0 || out != buf){
 				if(out >= eout)
 					return -1;
--- a/3rd/mp/mplogic.c
+++ b/3rd/mp/mplogic.c
@@ -31,7 +31,7 @@
 		t = b1;
 		b1 = b2;
 		b2 = t;
-		fl = fl >> 2 & 0x03 | fl << 2 & 0x0c | fl & 0x30;
+		fl = (fl >> 2 & 0x03) | (fl << 2 & 0x0c) | (fl & 0x30);
 	}
 	mpbits(sum, b1->top*Dbits+1);
 	dp1 = b1->p;
--- a/3rd/mp/mpmod.c
+++ b/3rd/mp/mpmod.c
@@ -9,9 +9,7 @@
 
 	sign = x->sign;
 	ns = sign < 0 && n == r ? mpcopy(n) : n;
-	if((n->flags & MPfield) == 0
-	|| ((Mfield*)n)->reduce((Mfield*)n, x, r) != 0)
-		mpdiv(x, n, nil, r);
+	mpdiv(x, n, nil, r);
 	if(sign < 0){
 		mpmagsub(ns, r, r);
 		if(ns != n) mpfree(ns);
--- a/3rd/mp/mptod.c
+++ b/3rd/mp/mptod.c
@@ -16,12 +16,12 @@
 	if(sf > 1024) return a->sign < 0 ? D_NINF : D_PINF;
 	i = a->top - 1;
 	v = a->p[i];
-	n = sf & Dbits - 1;
-	n |= n - 1 & Dbits;
+	n = sf & (Dbits - 1);
+	n |= (n - 1) & Dbits;
 	r = 0;
 	if(n > 54){
 		s = n - 54;
-		r = v & (1ULL<<s) - 1;
+		r = v & ((1ULL<<s) - 1);
 		v >>= s;
 	}
 	while(n < 54){
@@ -36,9 +36,9 @@
 		}else{
 			v <<= m;
 		}
-		s = Dbits - m & Dbits - 1;
+		s = (Dbits - m) & (Dbits - 1);
 		v |= w >> s;
-		r = w & (1ULL<<s) - 1;
+		r = w & ((1ULL<<s) - 1);
 		n += m;
 	}
 	if((v & 3) == 1){
@@ -55,7 +55,7 @@
 			return a->sign < 0 ? D_NINF : D_PINF;
 	}
 	x.lo = v;
-	x.hi = (uint32_t)(v >> 32) & (1<<20) - 1 | (sf + 1022) << 20 | a->sign & 1U<<31;
+	x.hi = ((uint32_t)(v >> 32) & ((1<<20) - 1)) | (sf + 1022) << 20 | (a->sign & 1U<<31);
 	return x.x;
 }
 
@@ -75,7 +75,7 @@
 		mpassign(mpzero, a);
 		return a;
 	}
-	v = x.lo | (uint64_t)(x.hi & (1<<20) - 1) << 32 | 1ULL<<52;
+	v = x.lo | (uint64_t)(x.hi & ((1<<20) - 1)) << 32 | 1ULL<<52;
 	if(e < 1075){
 		v += (1ULL<<(1074 - e)) - (~v >> (1075 - e) & 1);
 		v >>= 1075 - e;
--- a/3rd/mp/mpvectscmp.c
+++ b/3rd/mp/mpvectscmp.c
@@ -10,12 +10,12 @@
 		v = 0;
 		while(alen > blen)
 			v |= a[--alen];
-		m = p = (-v^v|v)>>(Dbits-1);
+		m = p = ((-v^v)|v)>>(Dbits-1);
 	} else if(blen > alen){
 		v = 0;
 		while(blen > alen)
 			v |= b[--blen];
-		m = (-v^v|v)>>(Dbits-1);
+		m = ((-v^v)|v)>>(Dbits-1);
 		p = m^1;
 	} else
 		m = p = 0;
@@ -24,8 +24,8 @@
 		y = b[alen];
 		z = x - y;
 		x = ~x;
-		v = ((-z^z|z)>>(Dbits-1)) & ~m;
-		p = ((~(x&y|x&z|y&z)>>(Dbits-1)) & v) | (p & ~v);
+		v = (((-z^z)|z)>>(Dbits-1)) & ~m;
+		p = ((~((x&y)|(x&z)|(y&z))>>(Dbits-1)) & v) | (p & ~v);
 		m |= v;
 	}
 	return (p-m) | m;
--- a/3rd/mp/test.c
+++ b/3rd/mp/test.c
@@ -6,7 +6,7 @@
 double D_PNAN, D_NNAN, D_PINF, D_NINF;
 
 static int loops = 1;
-static char str[16][8192];
+static char gstr[16][8192];
 static int istr = -1;
 
 static char *
@@ -14,9 +14,9 @@
 {
 	char *s, *b;
 	bool minus;
-	istr = (istr+1) % nelem(str);
-	b = str[istr];
-	s = mptoa(m, base, b+2, sizeof(str[istr])-2);
+	istr = (istr+1) % nelem(gstr);
+	b = gstr[istr];
+	s = mptoa(m, base, b+2, sizeof(gstr[istr])-2);
 	if(base == 10)
 		return s;
 	minus = s[0] == '-';
@@ -40,9 +40,9 @@
 MP(mpint *m)
 {
 	char *b;
-	istr = (istr+1) % nelem(str);
-	b = str[istr];
-	return mptoa(m, 10, b, sizeof(str[istr]));
+	istr = (istr+1) % nelem(gstr);
+	b = gstr[istr];
+	return mptoa(m, 10, b, sizeof(gstr[istr]));
 }
 
 static int64_t
@@ -59,7 +59,7 @@
 }
 
 static void
-testconv(char *str)
+testconv(const char *str)
 {
 	int i, base[] = {2,8,10,16/*,32,64*/};
 	mpint *b;
@@ -104,7 +104,7 @@
 }
 
 static void
-testshift(char *str)
+testshift(const char *str)
 {
 	mpint *b1, *b2;
 	int i;
@@ -124,7 +124,7 @@
 }
 
 static void
-testaddsub(char *str)
+testaddsub(const char *str)
 {
 	mpint *b1, *b2;
 	int i;
@@ -144,7 +144,7 @@
 }
 
 static void
-testvecdigmuladd(char *str, mpdigit d)
+testvecdigmuladd(const char *str, mpdigit d)
 {
 	mpint *b, *b2;
 	int i;
@@ -169,7 +169,7 @@
 }
 
 static void
-testvecdigmulsub(char *str, mpdigit d)
+testvecdigmulsub(const char *str, mpdigit d)
 {
 	mpint *b, *b2;
 	int i;
@@ -194,7 +194,7 @@
 }
 
 static void
-testmul(char *str)
+testmul(const char *str)
 {
 	mpint *b, *b1, *b2;
 	int64_t now;
@@ -239,7 +239,7 @@
 }
 
 static void
-testdigdiv(char *str, mpdigit d)
+testdigdiv(const char *str, mpdigit d)
 {
 	mpint *b;
 	mpdigit q;
@@ -323,7 +323,7 @@
 }
 
 static void
-testsub1(char *a, char *b)
+testsub1(const char *a, const char *b)
 {
 	mpint *b1, *b2, *b3;
 
@@ -338,7 +338,7 @@
 }
 
 static void
-testmul1(char *a, char *b)
+testmul1(const char *a, const char *b)
 {
 	mpint *b1, *b2, *b3;
 
@@ -353,7 +353,7 @@
 }
 
 static void
-testexp(char *base, char *exp, char *mod)
+testexp(const char *base, const char *exp, const char *mod)
 {
 	mpint *b, *e, *m, *res;
 	int i;
--- a/3rd/mp/test/ld.c
+++ b/3rd/mp/test/ld.c
@@ -45,7 +45,7 @@
 	z = 1;
 	for(i = 0; i < a->n; i++){
 		if(a->b[i]) z = 0;
-		c += 1 ^ a->b[i] & 1;
+		c += 1 ^ (a->b[i] & 1);
 		a->b[i] = c & 1;
 		c >>= 1;
 	}
@@ -95,8 +95,8 @@
 	c = s;
 	memset(b->p, 0, (a->n + Dbits - 1) / Dbits * Dbytes);
 	for(i = 0; i < a->n; i++){
-		c += s ^ a->b[i] & 1;
-		b->p[i / Dbits] |= (mpdigit)(c & 1) << (i & Dbits - 1);
+		c += s ^ (a->b[i] & 1);
+		b->p[i / Dbits] |= (mpdigit)(c & 1) << (i & (Dbits - 1));
 		c >>= 1;
 	}
 	b->top = (a->n + Dbits - 1) / Dbits;
@@ -215,7 +215,7 @@
 
 	if(b->sign > 0){
 		for(i = 0; i < b->top * Dbits; i++)
-			if(ldget(a, i) != (int)(b->p[i / Dbits] >> (i & Dbits - 1) & 1))
+			if(ldget(a, i) != (int)(b->p[i / Dbits] >> (i & (Dbits - 1)) & 1))
 				return 0;
 		for(; i < a->n; i++)
 			if(a->b[i] != 0)
@@ -225,7 +225,7 @@
 		c = 1;
 		for(i = 0; i < b->top * Dbits; i++){
 			c += !ldget(a, i);
-			if((c & 1) != (b->p[i / Dbits] >> (i & Dbits - 1) & 1))
+			if((c & 1) != (b->p[i / Dbits] >> (i & (Dbits - 1)) & 1))
 				return 0;
 			c >>= 1;
 		}
@@ -275,8 +275,8 @@
 	s1 = c1 = a->b[a->n - 1] & 1;
 	s2 = c2 = b->b[b->n - 1] & 1;
 	for(i = 0; i < r; i++){
-		c1 += s1 ^ ldget(a, i) & 1;
-		c2 += s2 ^ ldget(b, i) & 1;
+		c1 += s1 ^ (ldget(a, i) & 1);
+		c2 += s2 ^ (ldget(b, i) & 1);
 		co += (c1 & 1) + (c2 & 1);
 		q->b[i] = co & 1;
 		co >>= 1;
@@ -295,10 +295,10 @@
 	ldbits(q, r);
 	co = 0;
 	s1 = c1 = a->b[a->n - 1] & 1;
-	s2 = c2 = 1 ^ b->b[b->n - 1] & 1;
+	s2 = c2 = 1 ^ (b->b[b->n - 1] & 1);
 	for(i = 0; i < r; i++){
-		c1 += s1 ^ ldget(a, i) & 1;
-		c2 += s2 ^ ldget(b, i) & 1;
+		c1 += s1 ^ (ldget(a, i) & 1);
+		c2 += s2 ^ (ldget(b, i) & 1);
 		co += (c1 & 1) + (c2 & 1);
 		q->b[i] = co & 1;
 		co >>= 1;
--- a/3rd/mt19937-64.c
+++ b/3rd/mt19937-64.c
@@ -85,7 +85,7 @@
     for(; k; k--){
 		m = context->mt[i-1];
 		m = (m ^ (m >> 62)) * 3935559000370003845ULL;
-        context->mt[i] = context->mt[i] ^ m + init_key[j] + j; /* non linear */
+        context->mt[i] = context->mt[i] ^ (m + init_key[j] + j); /* non linear */
         i++;
         j++;
         if(i >= NN){
@@ -98,7 +98,7 @@
     for(k = NN-1; k; k--){
 		m = context->mt[i-1];
 		m = (m ^ (m >> 62)) * 2862933555777941757ULL;
-        context->mt[i] = context->mt[i] ^ m - i; /* non linear */
+        context->mt[i] = context->mt[i] ^ (m - i); /* non linear */
         i++;
         if(i >= NN){
         	context->mt[0] = context->mt[NN-1];
--- a/3rd/utf/rune.c
+++ b/3rd/utf/rune.c
@@ -37,7 +37,7 @@
 	 * one character sequence
 	 *	00000-0007F => T1
 	 */
-	c = *(uint8_t*)str;
+	c = *(const uint8_t*)str;
 	if(c < Tx) {
 		*rune = c;
 		return 1;
@@ -47,7 +47,7 @@
 	 * two character sequence
 	 *	0080-07FF => T2 Tx
 	 */
-	c1 = *(uint8_t*)(str+1) ^ Tx;
+	c1 = *(const uint8_t*)(str+1) ^ Tx;
 	if(c1 & Testx)
 		goto bad;
 	if(c < T3) {
@@ -64,7 +64,7 @@
 	 * three character sequence
 	 *	0800-FFFF => T3 Tx Tx
 	 */
-	c2 = *(uint8_t*)(str+2) ^ Tx;
+	c2 = *(const uint8_t*)(str+2) ^ Tx;
 	if(c2 & Testx)
 		goto bad;
 	if(c < T4) {
@@ -80,7 +80,7 @@
 	 *	10000-10FFFF => T4 Tx Tx Tx
 	 */
 	if(UTFmax >= 4) {
-		c3 = *(uint8_t*)(str+3) ^ Tx;
+		c3 = *(const uint8_t*)(str+3) ^ Tx;
 		if(c3 & Testx)
 			goto bad;
 		if(c < T5) {
@@ -188,7 +188,7 @@
 
 	if(n <= 0)
 		return 0;
-	c = *(uint8_t*)str;
+	c = *(const uint8_t*)str;
 	if(c < Tx)
 		return 1;
 	if(c < T3)
--- a/3rd/utf/utfnlen.c
+++ b/3rd/utf/utfnlen.c
@@ -10,7 +10,7 @@
 
 	es = s + m;
 	for(n = 0; s < es; n++) {
-		c = *(uint8_t*)s;
+		c = *(const uint8_t*)s;
 		if(c < Runeself){
 			if(c == '\0')
 				break;
--- a/cvalues.c
+++ b/cvalues.c
@@ -532,7 +532,7 @@
 		argcount(nargs, 3);
 	cnt = tosize(args[1]);
 	if(cnt < 0)
-		lerrorf(FL_ArgError, "invalid size: %d", cnt);
+		lerrorf(FL_ArgError, "invalid size: %"PRIu64, (uint64_t)cnt);
 
 	fltype_t *type = get_array_type(args[0]);
 	elsize = type->elsz;
@@ -848,7 +848,7 @@
 }
 
 value_t
-cbuiltin(char *name, builtin_t f)
+cbuiltin(const char *name, builtin_t f)
 {
 	cvalue_t *cv;
 	cv = MEM_CALLOC(CVALUE_NWORDS, sizeof(*cv));
--- a/cvalues.h
+++ b/cvalues.h
@@ -42,7 +42,7 @@
 value_t cvalue_compare(value_t a, value_t b);
 value_t cvalue_array_aref(value_t *args);
 value_t cvalue_array_aset(value_t *args);
-value_t cbuiltin(char *name, builtin_t f);
+value_t cbuiltin(const char *name, builtin_t f);
 value_t return_from_uint64(uint64_t Uaccum);
 value_t return_from_int64(int64_t Saccum);
 value_t fl_add_any(value_t *args, uint32_t nargs);
--- a/flisp.c
+++ b/flisp.c
@@ -42,7 +42,7 @@
 value_t FL_stringtypesym, FL_runestringtypesym;
 
 typedef struct {
-	char *name;
+	const char *name;
 	builtin_t fptr;
 }builtinspec_t;
 
@@ -213,8 +213,8 @@
 	sym->type = nil;
 	sym->hash = memhash32(str, len)^0xAAAAAAAA;
 	if(copy){
+		memcpy((char*)(sym+1), str, len+1);
 		sym->name = (const char*)(sym+1);
-		memcpy((char*)sym->name, str, len+1);
 	}else{
 		sym->name = str;
 	}
@@ -1270,7 +1270,7 @@
 	ios_printf(ios_stderr, "heap total     %10"PRIu32"\n", FL(heapsize));
 	ios_printf(ios_stderr, "heap free      %10"PRIu32"\n", (uint32_t)(FL(lim)-FL(curheap)));
 	ios_printf(ios_stderr, "heap used      %10"PRIu32"\n", (uint32_t)(FL(curheap)-FL(fromspace)));
-	ios_printf(ios_stderr, "stack          %10"PRIu32"\n", FL(nstack)*sizeof(value_t));
+	ios_printf(ios_stderr, "stack          %10"PRIu64"\n", (uint64_t)FL(nstack)*sizeof(value_t));
 	ios_printf(ios_stderr, "gc calls       %10"PRIu64"\n", (uint64_t)FL(gccalls));
 	ios_printf(ios_stderr, "max finalizers %10"PRIu32"\n", (uint32_t)FL(maxfinalizers));
 	ios_printf(ios_stderr, "opcodes        %10d\n", N_OPCODES);
--- a/flisp.h
+++ b/flisp.h
@@ -36,14 +36,14 @@
 	T_DOUBLE,
 }numerictype_t;
 
+typedef uintptr_t value_t;
+
 #ifdef BITS64
-typedef uint64_t value_t;
 typedef int64_t fixnum_t;
 #define FIXNUM_BITS 62
 #define TOP_BIT (1ULL<<63)
 #define T_FIXNUM T_INT64
 #else
-typedef uint32_t value_t;
 typedef int32_t fixnum_t;
 #define FIXNUM_BITS 30
 #define TOP_BIT (1U<<31)
@@ -63,10 +63,11 @@
 	fltype_t *type;
 	value_t binding;   // global value binding
 	uint32_t hash;
-	const char *name;
 	uint8_t numtype;
 	uint8_t size;
 	uint8_t flags;
+	uint8_t _dummy;
+	const char *name;
 }symbol_t;
 
 typedef struct {
@@ -220,12 +221,12 @@
 }fl_readstate_t;
 
 typedef struct _ectx_t {
+	fl_readstate_t *rdst;
+	struct _ectx_t *prev;
 	jmp_buf buf;
 	uint32_t sp;
 	uint32_t frame;
 	uint32_t ngchnd;
-	fl_readstate_t *rdst;
-	struct _ectx_t *prev;
 }fl_exception_context_t;
 
 void free_readstate(fl_readstate_t *rs);
@@ -244,7 +245,7 @@
 	else \
 		for(l__ca=1; l__ca; l__ca=0, fl_restorestate(&_ctx))
 
-_Noreturn void lerrorf(value_t e, const char *format, ...);
+_Noreturn void lerrorf(value_t e, const char *format, ...) __printfmt(2, 3);
 void fl_savestate(fl_exception_context_t *_ctx);
 void fl_restorestate(fl_exception_context_t *_ctx);
 _Noreturn void fl_raise(value_t e);
@@ -290,7 +291,7 @@
 
 typedef struct {
 	fltype_t *type;
-	uint8_t _space[1];
+	uint8_t _space[];
 }cprim_t;
 
 typedef struct {
@@ -352,8 +353,6 @@
 
 	size_t malloc_pressure;
 
-	bool grew;
-
 	cvalue_t **finalizers;
 	size_t nfinalizers;
 	size_t maxfinalizers;
@@ -392,6 +391,7 @@
 	int gsnameno;
 
 	bool exiting;
+	bool grew;
 
 	fltype_t *fsotype;
 
--- a/ios.c
+++ b/ios.c
@@ -14,7 +14,7 @@
 void *
 llt_memrchr(const void *s, int c, size_t n)
 {
-	const uint8_t *src = (const uint8_t*)s + n;
+	uint8_t *src = (uint8_t*)s + n;
 	uint8_t uc = c;
 	while(--src >= (uint8_t*)s)
 		if(*src == uc)
@@ -351,7 +351,7 @@
 				ios_flush(s);
 				s->bm = bm_line;
 				n -= linesz;
-				data = (char*)data + linesz;
+				data = (const char*)data + linesz;
 			}
 		}
 		memcpy(s->buf + s->bpos, data, n);
--- a/ios.h
+++ b/ios.h
@@ -31,6 +31,7 @@
 	size_t bpos; // current position in buffer
 	size_t ndirty; // # bytes at &buf[0] that need to be written
 	off_t fpos; // cached file pos
+	ios_loc_t loc;
 	bufmode_t bm;
 	int colnowait;
 
@@ -59,8 +60,6 @@
 	// request durable writes (fsync)
 	// uint8_t durable:1;
 
-	ios_loc_t loc;
-
 	// todo: mutex
 	uint8_t local[IOS_INLSIZE];
 }ios_t;
@@ -104,8 +103,8 @@
 
 /* high-level functions - output */
 int ios_pututf8(ios_t *s, Rune r);
-int ios_printf(ios_t *s, const char *format, ...);
-int ios_vprintf(ios_t *s, const char *format, va_list args);
+int ios_printf(ios_t *s, const char *format, ...) __printfmt(2, 3);
+int ios_vprintf(ios_t *s, const char *format, va_list args) __printfmt(2, 0);
 
 void hexdump(ios_t *dest, const uint8_t *buffer, size_t len, size_t startoffs);
 
--- a/meson.build
+++ b/meson.build
@@ -13,13 +13,28 @@
 )
 
 add_project_arguments(
+	#'-Wcast-align=strict',
+	#'-Wcast-qual',
 	#'-Wconversion',
+	#'-Wfloat-equal',
 	#'-Wsign-conversion',
-	'-Wmissing-prototypes',
+	'-Waggregate-return',
 	'-Werror=odr',
 	'-Werror=strict-aliasing',
-	'-Wno-parentheses',
-	'-Wno-overlength-strings',
+	'-Wformat=2',
+	'-Wint-to-pointer-cast',
+	'-Wmissing-prototypes',
+	'-Wno-format-y2k',
+	'-Wpointer-arith',
+	'-Wpointer-to-int-cast',
+	'-Wredundant-decls',
+	'-Wsequence-point',
+	'-Wshadow',
+	'-Wstrict-prototypes',
+	'-Wundef',
+	'-Wunused-but-set-parameter',
+	'-Wunused-parameter',
+	'-Wwrite-strings',
 	'-D_DEFAULT_SOURCE',
 	'-DCOMPUTED_GOTO',
 	language: 'c',
@@ -62,10 +77,13 @@
 	add_project_arguments(
 		'-D__wchar_t=__please_no_wchar_t_thank_you',
 		'-Wno-gnu-offsetof-extensions',
+		'-Wunused-const-variable',
 		language: 'c',
 	)
 else
 	add_project_arguments(
+		'-Wlogical-op',
+		'-Wunused-const-variable=2',
 		'-Werror=lto-type-mismatch',
 		language: 'c',
 	)
--- a/operators.c
+++ b/operators.c
@@ -59,7 +59,7 @@
 		if(d > 0 && *(int64_t*)dest < 0)  // 0x8000000000000000 is a bitch
 			*(int64_t*)dest = INT64_MAX;
 		break;
-	case T_UINT64: *(uint64_t*)dest = (int64_t)d; break;
+	case T_UINT64: *(uint64_t*)dest = d; break;
 	case T_MPINT:  *(mpint**)dest = dtomp(d, nil); break;
 	case T_FLOAT:  *(float*)dest = d; break;
 	case T_DOUBLE: *(double*)dest = d; break;
--- a/plan9/platform.h
+++ b/plan9/platform.h
@@ -128,6 +128,7 @@
 
 #define __unlikely(x) (x)
 #define __likely(x) (x)
+#define __printfmt(x, y)
 
 typedef s8int int8_t;
 typedef s16int int16_t;
--- a/posix/mp.h
+++ b/posix/mp.h
@@ -50,7 +50,6 @@
 	MPstatic=	0x01,	/* static constant */
 	MPnorm=		0x02,	/* normalization status */
 	MPtimesafe=	0x04,	/* request time invariant computation */
-	MPfield=	0x08,	/* this mpint is a field modulus */
 
 	Dbytes=		sizeof(mpdigit),	/* bytes per digit */
 	Dbits=		Dbytes*8		/* bits per digit */
@@ -90,7 +89,8 @@
 double	mptod(mpint*);			/* double */
 mpint*	dtomp(double, mpint*);
 
-/* divide 2 digits by one */
+/* divide the 2 digit dividend by the one digit divisor and stick in quotient */
+/* we assume that the result is one digit - overflow is all 1's */
 void	mpdigdiv(mpdigit *dividend, mpdigit divisor, mpdigit *quotient);
 
 /* in the following, the result mpint may be */
@@ -163,42 +163,16 @@
 int	mpveccmp(mpdigit *a, int alen, mpdigit *b, int blen);
 int	mpvectscmp(mpdigit *a, int alen, mpdigit *b, int blen);
 
-/* divide the 2 digit dividend by the one digit divisor and stick in quotient */
-/* we assume that the result is one digit - overflow is all 1's */
-void	mpdigdiv(mpdigit *dividend, mpdigit divisor, mpdigit *quotient);
-
 /* playing with magnitudes */
 int	mpmagcmp(mpint *b1, mpint *b2);
 void	mpmagadd(mpint *b1, mpint *b2, mpint *sum);	/* sum = b1+b2 */
 void	mpmagsub(mpint *b1, mpint *b2, mpint *sum);	/* sum = b1+b2 */
 
-/* chinese remainder theorem */
-typedef struct CRTpre	CRTpre;		/* precomputed values for converting */
-					/*  twixt residues and mpint */
-typedef struct CRTres	CRTres;		/* residue form of an mpint */
-
-struct CRTres
-{
-	int	n;		/* number of residues */
-	mpint	*r[1];		/* residues */
-};
-
-CRTpre*	crtpre(int, mpint**);			/* precompute conversion values */
-CRTres*	crtin(CRTpre*, mpint*);			/* convert mpint to residues */
-void	crtout(CRTpre*, CRTres*, mpint*);	/* convert residues to mpint */
-void	crtprefree(CRTpre*);
-void	crtresfree(CRTres*);
-
 /* fast field arithmetic */
 typedef struct Mfield	Mfield;
 
 struct Mfield
 {
-	mpint	m;
+	mpint m;
 	int	(*reduce)(Mfield*, mpint*, mpint*);
 };
-
-mpint *mpfield(mpint*);
-
-Mfield *gmfield(mpint*);
-Mfield *cnfield(mpint*);
--- a/posix/platform.h
+++ b/posix/platform.h
@@ -62,6 +62,7 @@
 #ifdef __GNUC__
 #define __unlikely(x) __builtin_expect(!!(x), 0)
 #define __likely(x) __builtin_expect(!!(x), 1)
+#define __printfmt(x, y) __attribute__((format(printf, x, y)))
 #endif
 
 #define PATHSEP '/'
--- a/print.c
+++ b/print.c
@@ -279,7 +279,7 @@
 print_cons(ios_t *f, value_t v)
 {
 	value_t cd;
-	char *op;
+	const char *op;
 	if(iscons(cdr_(v)) && cdr_(cdr_(v)) == FL_nil &&
 		!ptrhash_has(&FL(printconses), (void*)cdr_(v)) &&
 		(((car_(v) == FL_quote)	    && (op = "'"))  ||
@@ -597,7 +597,10 @@
 		snprintf(format, sizeof(format), "%%.%d%s", dec, num_format);
 	else
 		snprintf(format, sizeof(format), "%%%d.%d%s", width, dec, num_format);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
 	sz = snprintf(s, cnt, format, r);
+#pragma GCC diagnostic pop
 	/* trim trailing zeros from fractions. not when using scientific
 	   notation, since we might have e.g. 1.2000e+100. also not when we
 	   need a specific output width */
@@ -680,7 +683,7 @@
 			ndec = 16;
 		}
 		if(!isfinite(d)){
-			char *rep;
+			const char *rep;
 			if(isnan(d))
 				rep = signbit(d) ? "-nan.0" : "+nan.0";
 			else
--- a/read.c
+++ b/read.c
@@ -361,7 +361,7 @@
 				return (ctx->toktype = TOK_NUM);
 		}
 		ctx->toktype = TOK_SYM;
-		char *name = (strcmp(ctx->buf, "lambda") == 0 || strcmp(ctx->buf, "λ") == 0) ? "λ" : ctx->buf;
+		const char *name = (strcmp(ctx->buf, "lambda") == 0 || strcmp(ctx->buf, "λ") == 0) ? "λ" : ctx->buf;
 		ctx->tokval = strcasecmp(name, "nil") == 0 ? FL_nil : symbol(name, name == ctx->buf);
 	}
 	return ctx->toktype;
--- a/sixel.c
+++ b/sixel.c
@@ -97,7 +97,7 @@
 		argcount(nargs, 2);
 	if(!issixeloutput(args[0]))
 		type_error("sixel-output", args[0]);
-	fso_t *f = value2c(fso_t*, args[0]);
+	fso_t *ftype = value2c(fso_t*, args[0]);
 	bool isrgb = true;
 	size_t len;
 	if(nargs >= 3){
@@ -116,8 +116,8 @@
 	if(!isarray(args[1]))
 		type_error("array", args[1]);
 	len = cvalue_arraylen(args[1]);
-	if(f->numcolors*3 != (int)len)
-		lerrorf(FL_ArgError, "invalid palette: expected %d colors, got %d", f->numcolors, (int)len);
+	if(ftype->numcolors*3 != (int)len)
+		lerrorf(FL_ArgError, "invalid palette: expected %d colors, got %d", ftype->numcolors, (int)len);
 
 	fltype_t *type = cv_class(ptr(args[1]));
 	size_t elsize = type->elsz;
@@ -127,12 +127,12 @@
 	uint8_t out[256*3] = {0};
 	if(isrgb){
 		if(eltype->type == FL_uint8sym || eltype->type == FL_bytesym)
-			memcpy(out, cptr(args[1]), f->numcolors*3);
+			memcpy(out, cptr(args[1]), ftype->numcolors*3);
 		else
 			lerrorf(FL_ArgError, "invalid palette type: expected bytes");
 	}else{
 		uint8_t *pal = cptr(args[1]);
-		for(int i = 0; i < f->numcolors; i++){
+		for(int i = 0; i < ftype->numcolors; i++){
 			float s = (float)conv_to_int32(pal+(i*3+2)*elsize, nt) / 100.0;
 			if(s == 0)
 				out[i*3+0] = out[i*3+1] = out[i*3+2] = 255*(int)conv_to_int32(pal+(i*3+1)*elsize, nt)/100;
@@ -159,7 +159,7 @@
 			}
 		}
 	}
-	sixel_dither_set_palette(f->dither, out);
+	sixel_dither_set_palette(ftype->dither, out);
 
 	return FL_void;
 }
--- a/string.c
+++ b/string.c
@@ -110,8 +110,6 @@
 	return runestr;
 }
 
-extern BUILTIN("buffer", buffer);
-
 BUILTIN("string", string)
 {
 	if(nargs == 1 && fl_isstring(args[0]))
--- a/sys_posix.c
+++ b/sys_posix.c
@@ -29,22 +29,20 @@
 timestring(double s, char *buf, int sz)
 {
 	time_t tme = (time_t)s;
-	char *fmt = "%c"; /* needed to suppress GCC warning */
 	struct tm tm;
 
 	localtime_r(&tme, &tm);
-	strftime(buf, sz, fmt, &tm);
+	strftime(buf, sz, "%c", &tm);
 }
 
 double
 parsetime(const char *s)
 {
-	char *fmt = "%c"; /* needed to suppress GCC warning */
 	char *res;
 	time_t t;
 	struct tm tm;
 
-	res = strptime(s, fmt, &tm);
+	res = strptime(s, "%c", &tm);
 	if(res != nil){
 		/* Not set by strptime(); tells mktime() to determine
 		 * whether daylight saving time is in effect
--- a/terminal_posix.c
+++ b/terminal_posix.c
@@ -82,14 +82,14 @@
 {
 	USED(args);
 	argcount(nargs, 0);
-	struct winsize s;
-	if(ioctl(STDIN_FILENO, TIOCGWINSZ, &s) < 0)
+	struct winsize ws;
+	if(ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) < 0)
 		return FL_f;
 	value_t v = mk_cons(), tex, pix;
 	car_(v) = tex = mk_cons();
-	car_(tex) = fixnum(s.ws_col);
-	cdr_(tex) = mk_cons(); car_(cdr_(tex)) = fixnum(s.ws_row); cdr_(cdr_(tex)) = FL_nil;
-	int x = s.ws_xpixel, y = s.ws_ypixel;
+	car_(tex) = fixnum(ws.ws_col);
+	cdr_(tex) = mk_cons(); car_(cdr_(tex)) = fixnum(ws.ws_row); cdr_(cdr_(tex)) = FL_nil;
+	int x = ws.ws_xpixel, y = ws.ws_ypixel;
 	bool wasraw = inraw;
 	if((x == 0 || y == 0) && isatty(STDOUT_FILENO) && termsetraw(true, cursorvisible) == 0){
 		// FIXME(sigrid): read everything out of stdin first
--- a/utf8.c
+++ b/utf8.c
@@ -189,7 +189,7 @@
 }
 
 char *
-u8_memchr(const char *s, Rune ch, size_t sz, size_t *charn)
+u8_memchr(char *s, Rune ch, size_t sz, size_t *charn)
 {
 	size_t i = 0, lasti = 0;
 	Rune c;
@@ -220,11 +220,11 @@
 int
 u8_isvalid(const char *str, int length)
 {
-	const uint8_t *p, *pend = (uint8_t*)str + length;
+	const uint8_t *p, *pend = (const uint8_t*)str + length;
 	uint8_t c;
 	int ab;
 
-	for(p = (uint8_t*)str; p < pend; p++){
+	for(p = (const uint8_t*)str; p < pend; p++){
 		c = *p;
 		if(c < 128)
 			continue;
--- a/utf8.h
+++ b/utf8.h
@@ -45,7 +45,7 @@
 
 /* same as the above, but searches a buffer of a given size instead of
    a NUL-terminated string. */
-char *u8_memchr(const char *s, Rune ch, size_t sz, size_t *charn);
+char *u8_memchr(char *s, Rune ch, size_t sz, size_t *charn);
 
 /* number of columns occupied by a string */
 size_t u8_strwidth(const char *s);
--- a/vm.inc
+++ b/vm.inc
@@ -350,11 +350,11 @@
 		FL(stack)[FL(sp)-1] = fl_neg(FL(stack)[FL(sp)-1]);
 	}
 	{
-		value_t a, b, c;
+		value_t a, b, q;
 		a = FL(stack)[FL(sp)-2];
 		b = FL(stack)[FL(sp)-1];
-		if(bothfixnums(a, b) && !sadd_overflow(numval(a), numval(b), &c) && fits_fixnum(c)){
-			v = fixnum(c);
+		if(bothfixnums(a, b) && !sadd_overflow(numval(a), numval(b), &q) && fits_fixnum(q)){
+			v = fixnum(q);
 		}else{
 			v = fl_add_any(&FL(stack)[FL(sp)-2], 2);
 		}
@@ -427,11 +427,11 @@
 
 OP(OP_NANP)
 	{
-		value_t x = FL(stack)[FL(sp)-1];
+		value_t q = FL(stack)[FL(sp)-1];
 		v = FL_f;
-		if(iscprim(x)){
-			void *data = cp_data(ptr(x));
-			switch(cp_numtype(ptr(x))){
+		if(iscprim(q)){
+			void *data = cp_data(ptr(q));
+			switch(cp_numtype(ptr(q))){
 			case T_DOUBLE:
 				if(isnan(*(double*)data))
 					v = FL_t;