diff --git a/Makefile b/Makefile
index a01f208bad29fdcc4a0942874fb92d351cd620f2..70a15efacb6554e74a7df739671ef14190299f0e 100644
--- a/Makefile
+++ b/Makefile
@@ -464,7 +464,8 @@ ARCH_AFLAGS :=
 ARCH_CFLAGS :=
 -include arch/$(ARCH)/Makefile
 
-KBUILD_CFLAGS	+= $(call cc-option,-fno-delete-null-pointer-checks,)
+# XXX unsuppported by clang
+#KBUILD_CFLAGS	+= $(call cc-option,-fno-delete-null-pointer-checks,)
 
 ifdef CONFIG_CC_OPTIMIZE_NONE
 KBUILD_CFLAGS	+= -O0 $(call cc-disable-warning,maybe-uninitialized,)
diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile
index 5ec8266dbb9053af6977de6d999d8760e84129d2..7073823f983d2f732ab482e5730e65eea6db9447 100644
--- a/arch/sparc/Makefile
+++ b/arch/sparc/Makefile
@@ -1 +1,6 @@
-ARCH_CFLAGS = -mcpu=v8
+# gcc (7.2.0)
+ARCH_CFLAGS = -mcpu=leon3 -mfix-gr712rc
+# gcc (4.x)
+#ARCH_CFLAGS = -mcpu=v8 -mfix-gr712rc
+# clang
+#ARCH_CFLAGS = -mcpu=gr712rc
diff --git a/arch/sparc/include/asm/thread.h b/arch/sparc/include/asm/thread.h
index 0e8b431f387dacd7374a9c66afe78ed4adab21f3..c34aa506ef6b238d09fb49bec9d110e99c1f25a3 100644
--- a/arch/sparc/include/asm/thread.h
+++ b/arch/sparc/include/asm/thread.h
@@ -36,10 +36,11 @@ struct thread_info {
 	int			softirq_count;
 	int			hardirq_count;
 
-	uint32_t __unused;
+	/* bcc is stupid and does not respect the aligned attribute */
+	int			unused;
 
 	/* Context switch saved kernel state. */
-	unsigned long ksp;	/* ... ksp __attribute__ ((aligned (8))); */
+	unsigned long ksp __attribute__ ((aligned (8)));
 	unsigned long kpc;
 	unsigned long kpsr;
 	unsigned long kwim;
diff --git a/arch/sparc/kernel/bootmem.c b/arch/sparc/kernel/bootmem.c
index 26241a7ef5255e7439be01ecfd58e4a09725360a..c5f20aca66cbeaad0769da82d042c93963daf145 100644
--- a/arch/sparc/kernel/bootmem.c
+++ b/arch/sparc/kernel/bootmem.c
@@ -251,7 +251,27 @@ void bootmem_init(void)
 
 
 	/* now add the remaining memory banks */
+
+	/**
+	 * XXX bcc2 (sparc-gaisler-elf-gcc) 7.2.0 screws this up by swallowing
+	 * a cmp; bne sequence after the call to page_map_add and placing
+	 * the required ret; restore sequence along with some instructions
+	 * for one of the BUG() related printks lower down in the remaining
+	 * instruction. The function consequently never returns, and partially
+	 * removing sections of this loop results in apparent random BUG()s,
+	 * because all of the generated instructions are ordered to the end of
+	 * the function. The reason appears to be some flawed optimisation
+	 * heuristic, because the problem goes away, when SPARC_PHYS_BANKS
+	 * is set to a value > 0, which means that sp_banks will have
+	 * more than a single entry and the check of base_pfn vs the
+	 * bank's base address results in the rest of the loop being taken.
+	 */
+#define BCC2_IS_RETARDED
+#ifdef BCC2_IS_RETARDED
+	for (i = 0; i <= SPARC_PHYS_BANKS; i++) {
+#else
 	for (i = 0; sp_banks[i].num_bytes != 0; i++) {
+#endif
 
 		BUG_ON(i > SPARC_PHYS_BANKS);
 
diff --git a/arch/sparc/kernel/ttable.S b/arch/sparc/kernel/ttable.S
index 6d8648114d08f2d9125812fe62177f72fde69217..9ee891551c42fcc89d772864865df66c3f80bc8c 100644
--- a/arch/sparc/kernel/ttable.S
+++ b/arch/sparc/kernel/ttable.S
@@ -131,14 +131,14 @@ mna_trap_handler:
 fpe_trap_handler:
 	.global tag_overflow_trap_handler
 tag_overflow_trap_handler:
-	.global mna_trap_handler
-mna_trap_handler:
+#	.global mna_trap_handler /* CLANG! */
+#mna_trap_handler:
 	.global cpdis_trap_handler
 cpdis_trap_handler:
 	.global cpex_trap_handler
 cpex_trap_handler:
-	.global fpe_trap_handler
-fpe_trap_handler:
+#	.global fpe_trap_handler
+#fpe_trap_handler:
 	.global hw_div0_trap_handler
 hw_div0_trap_handler:
 	.global nmi_entry
diff --git a/include/kernel/kthread.h b/include/kernel/kthread.h
index 2f860ecc11909591d7ce3cca2dd3c0e8e3d3c35c..9a2d141e7e985f1ee78c2cf27bc5bb45cc5ec40a 100644
--- a/include/kernel/kthread.h
+++ b/include/kernel/kthread.h
@@ -69,6 +69,12 @@ struct task_struct {
 
 	struct sched_attr		attr;
 
+
+	/* bcc is SO extremely stupid, it misaligns 64-bit types and generates
+	 * ldd's to laod them; also, it does not respect the aligned attribute
+	 */
+	int				unused;
+
 	ktime				runtime; /* remaining runtime in this period  */
 	ktime				wakeup; /* start of next period */
 	ktime				deadline; /* deadline of current period */
diff --git a/include/kernel/types.h b/include/kernel/types.h
index 25948df9d4d2adb87ccd1812ba1e88f52c68f139..09df928aba7fa4668549b353f0d36e4c93fc9ce6 100644
--- a/include/kernel/types.h
+++ b/include/kernel/types.h
@@ -28,6 +28,8 @@
 #if defined(GCC_VERSION) && (GCC_VERSION >= 40402)
 #include <stdint.h>
 #else
+#include <stdint.h>
+#if 0 /* XXX need CLANG FIX */
 /* this must do... */
 typedef unsigned long uintptr_t;
 typedef   signed long  intptr_t;
@@ -52,7 +54,7 @@ compile_time_assert(sizeof(uint16_t) == 2, TYPES_UINT16_SIZE_INVALID);
 compile_time_assert(sizeof( int16_t) == 2, TYPES__INT16_SIZE_INVALID);
 compile_time_assert(sizeof(uint8_t)  == 1, TYPES_UINT_8_SIZE_INVALID);
 compile_time_assert(sizeof( int8_t)  == 1, TYPES__INT_8_SIZE_INVALID);
-
+#endif
 #endif
 
 #ifndef __SIZEOF_LONG__
diff --git a/lib/vsnprintf.c b/lib/vsnprintf.c
index 746328f2f0f59e244a22a958d41e62532bec0f8e..695a81c28c7c830b333803935b77b444e33e01ae 100644
--- a/lib/vsnprintf.c
+++ b/lib/vsnprintf.c
@@ -265,7 +265,7 @@ static size_t eval_flags(const char *fmt, struct fmt_spec *spec)
 
 static size_t eval_width(const char *fmt, struct fmt_spec *spec, va_list *args)
 {
-	int w;
+	int w = 0;
 
 	char *end;