--- old/CHANGELOG	2015-07-15 12:31:17.000000000 -0700
+++ new/CHANGELOG	2017-04-12 16:50:33.223293674 -0700
@@ -6,3 +6,6 @@
 
 2015-07-15: 2.3: Fixed typos in documentation.txt.
 
+2017-04-12: 2.4: Changed behavior of mul() when sizeof(long)==sizeof(long long).
+                 Compensated for recent brain damage in GCC.
+
--- old/Makefile	2010-08-12 16:56:12.000000000 -0700
+++ new/Makefile	2017-04-12 16:48:18.755288222 -0700
@@ -1,6 +1,8 @@
 #!/usr/bin/make
 CC=gcc
 CFLAGS=-O2 -Wall -Werror
+# If you're using a recent version of GCC, enable this to fix its braindamage:
+PRELOADCFLAGS=-Wno-unused-value
 SRCS=bytefunc.c cons.c integer.c main.c nil.c preload.c quote.c rawfunc.c stream.c string.c throw.c util.c vm.c word.c
 LIBS=
 LISPS=compiler.lisp functions.lisp macroexpand.lisp optimizer.lisp
@@ -17,7 +19,7 @@
 	$(CC) $(CFLAGS) -o $@ $(SRCS:%.c=$(BUILDDIR)%.o) $(LIBS)
 
 $(BUILDDIR)preload.o : preload.c lisp.h $(LISPS:%.lisp=$(BUILDDIR)%.c)
-	$(CC) $(CFLAGS) -I$(BUILDDIR) -c -o $@ $<
+	$(CC) $(CFLAGS) $(PRELOADCFLAGS) -I$(BUILDDIR) -c -o $@ $<
 
 $(BUILDDIR)vm.o : vm.c lisp.h vm.h opcodes.c
 	$(CC) $(CFLAGS) -c -o $@ $<
--- old/integer.c	2010-08-12 16:03:21.000000000 -0700
+++ new/integer.c	2017-04-12 16:28:21.003209533 -0700
@@ -1,4 +1,11 @@
-/* integer.c   by Michael Thorpe   2010-08-12 */
+/* integer.c   by Michael Thorpe   2017-04-12 */
+
+/* If this is defined, we forbid multiplication operands that won't fit in a
+ * signed int and require that a signed int be no more than half the size of
+ * a signed long. Otherwise, we require that long long be at least twice the
+ * size of long. If neither of those work for you, you'll need to implement
+ * your own multiplication overflow detecting algorithm. */
+#define RESTRICTED_MULTIPLICATION
 
 #include <ctype.h>
 #include <limits.h>
@@ -23,6 +30,7 @@
 		DECREF(a);
 		return(throwtypeerror(b));
 	}
+/* FIXME: This has undefined behavior on overflow: */
 	result=a->value.i+b->value.i;
 	if((a->value.i^result)<0 && (b->value.i^result)<0)
 		overflow=1;
@@ -114,6 +122,7 @@
 		DECREF(b);
 		return(throw(INCREF(divideby0error),a));
 	}
+/* FIXME: Does this have undefined behavior on overflow? */
 	result=a->value.i/b->value.i;
 	DECREF(a);
 	DECREF(b);
@@ -136,14 +145,21 @@
 		DECREF(a);
 		return(throwtypeerror(b));
 	}
+#ifdef RESTRICTED_MULTIPLICATION
+	if(a->value.i<INT_MIN || INT_MAX<a->value.i) {
+		DECREF(b);
+		return(throwrangecheck(a));
+	}
+	if(b->value.i<INT_MIN || INT_MAX<b->value.i) {
+		DECREF(a);
+		return(throwrangecheck(b));
+	}
+	result=a->value.i*b->value.i;
+#else
 	result=a->value.i*(signed long long)b->value.i;
+#endif
 	if(result<LONG_MIN || LONG_MAX<result)
 		overflow=1;
-/* Sanity check to make sure the above will catch real overflows.  If this
- * fails for you, you'll need to implement some other method of overflow
- * checking. */
-	if(sizeof(result) < 2*sizeof(a->value.i))
-		overflow=1;
 	DECREF(a);
 	DECREF(b);
 	r=new_object(&integer_objtype);
@@ -195,7 +211,8 @@
 		DECREF(a);
 		return(throwtypeerror(b));
 	}
-	result=a->value.i - b->value.i;
+/* FIXME: This has undefined behavior on overflow: */
+	result=a->value.i-b->value.i;
 	if((a->value.i^b->value.i)<0 && (a->value.i^result)<0)
 		overflow=1;
 	DECREF(a);
@@ -226,6 +243,19 @@
 	if(!(divideby0error=new_word("divide-by-zero",14))
 	|| !(overflowerror=new_word("overflow",8)))
 		return(1);
+/* Sanity check to make sure mul() will catch overflows.  If this fails for
+ * you, you'll need to implement some method of overflow checking. */
+#ifdef RESTRICTED_MULTIPLICATION
+	if(sizeof(signed long) < 2*sizeof(signed int)) {
+		fprintf(stderr,"long isn't twice as big as int on this machine\n");
+		return(1);
+	}
+#else
+	if(sizeof(signed long long) < 2*sizeof(signed long)) {
+		fprintf(stderr,"longlong isn't twice as big as long on this machine\n");
+		return(1);
+	}
+#endif
 	return(0);
 }
 
--- old/vm.c	2010-08-11 12:04:53.000000000 -0700
+++ new/vm.c	2017-04-12 16:49:39.899291675 -0700
@@ -1,4 +1,4 @@
-/* vm.c   by Michael Thorpe   2010-07-11 */
+/* vm.c   by Michael Thorpe   2017-04-12 */
 
 #include <stdlib.h>
 #include "lisp.h"
@@ -594,9 +594,8 @@
 				goto handle_exception;
 			}
 			o2=CAR(o);
-			INCREF(o2);
+			c->stack[c->sp++]=INCREF(o2);
 			DECREF(o);
-			c->stack[c->sp++]=o2;
 			break;
 		case OP_CDR:
 			if(oparg)
@@ -608,9 +607,8 @@
 				goto handle_exception;
 			}
 			o2=CDR(o);
-			INCREF(o2);
+			c->stack[c->sp++]=INCREF(o2);
 			DECREF(o);
-			c->stack[c->sp++]=o2;
 			break;
 		case OP_QUOTE:
 			if(oparg)
--- old/word.c	2010-06-23 12:53:47.000000000 -0700
+++ new/word.c	2017-04-12 16:49:59.575292662 -0700
@@ -1,4 +1,4 @@
-/* word.c   by Michael Thorpe   2010-06-23 */
+/* word.c   by Michael Thorpe   2017-04-12 */
 
 #include <assert.h>
 #include <stdio.h>
@@ -59,8 +59,7 @@
 		return(throw(INCREF(already_defined_error),name));
 	}
 	name->value.word.value=val;
-	INCREF(name); /* Having a defined value counts as a reference */
-	return(name);
+	return(INCREF(name)); /* Having a defined value counts as a reference */
 }
 
 obj *lookup(obj *name) {
