diff --git a/contrib/linux-kernel/Makefile b/contrib/linux-kernel/Makefile
index d4a7e6c6938147254958d2ae1f1d11a2008e3212..f79de67925966ccc4425376d2d0e4cdb3f874e39 100644
--- a/contrib/linux-kernel/Makefile
+++ b/contrib/linux-kernel/Makefile
@@ -39,6 +39,7 @@ libzstd:
 		-DSTATIC_BMI2=0 \
 		-DZSTD_ADDRESS_SANITIZER=0 \
 		-DZSTD_MEMORY_SANITIZER=0 \
+		-DZSTD_DATAFLOW_SANITIZER=0 \
 		-DZSTD_COMPRESS_HEAPMODE=1 \
 		-UZSTD_NO_INLINE \
 		-UNO_PREFETCH \
@@ -88,9 +89,16 @@ import-upstream:
 	rm $(LINUX)/lib/zstd/common/xxhash.*
 	rm $(LINUX)/lib/zstd/compress/zstdmt_*
 
+DEBUGFLAGS= -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
+            -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \
+            -Wstrict-prototypes -Wundef -Wpointer-arith \
+            -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \
+            -Wredundant-decls -Wmissing-prototypes -Wc++-compat \
+	    -Wimplicit-fallthrough
+
 .PHONY: test
 test: libzstd
-	$(MAKE) -C test run-test CFLAGS="-O3 $(CFLAGS)" -j
+	$(MAKE) -C test run-test CFLAGS="-O3 $(CFLAGS) $(DEBUGFLAGS) -Werror" -j
 
 .PHONY: clean
 clean:
diff --git a/contrib/linux-kernel/test/include/asm/unaligned.h b/contrib/linux-kernel/test/include/asm/unaligned.h
index 02c2d74f30138aa509095e11141d153ac8722e85..86ec4ca38991c385721b5e867ab31f59c2be1a63 100644
--- a/contrib/linux-kernel/test/include/asm/unaligned.h
+++ b/contrib/linux-kernel/test/include/asm/unaligned.h
@@ -20,6 +20,7 @@ static unsigned _isLittleEndian(void)
 {
     const union { uint32_t u; uint8_t c[4]; } one = { 1 };
     assert(_IS_LITTLE_ENDIAN == one.c[0]);
+    (void)one;
     return _IS_LITTLE_ENDIAN;
 }
 
diff --git a/contrib/linux-kernel/test/include/linux/xxhash.h b/contrib/linux-kernel/test/include/linux/xxhash.h
index 0a43bb275f3b333360fdc6c568fcfb825af1a255..7e92a706e7eb29a46a20b329aa30c407704df53d 100644
--- a/contrib/linux-kernel/test/include/linux/xxhash.h
+++ b/contrib/linux-kernel/test/include/linux/xxhash.h
@@ -124,11 +124,10 @@ XXH_API uint64_t xxh64(const void *input, size_t length, uint64_t seed);
 static inline unsigned long xxhash(const void *input, size_t length,
 				   uint64_t seed)
 {
-#if BITS_PER_LONG == 64
-       return xxh64(input, length, seed);
-#else
-       return xxh32(input, length, seed);
-#endif
+	if (sizeof(size_t) == 8)
+		return xxh64(input, length, seed);
+	else
+		return xxh32(input, length, seed);
 }
 
 /*-****************************
diff --git a/contrib/linux-kernel/test/static_test.c b/contrib/linux-kernel/test/static_test.c
index 50c594c77d7c474f971b5ed4d17ca6a7a17b870f..d2b8b5a322cb5c9617d4d2208e40dfbaee44a0bd 100644
--- a/contrib/linux-kernel/test/static_test.c
+++ b/contrib/linux-kernel/test/static_test.c
@@ -28,17 +28,19 @@ static const char kEmptyZstdFrame[] = {
     0x28, 0xb5, 0x2f, 0xfd, 0x24, 0x00, 0x01, 0x00, 0x00, 0x99, 0xe9, 0xd8, 0x51
 };
 
-static void test_decompress_unzstd() {
+static void test_decompress_unzstd(void) {
     fprintf(stderr, "Testing decompress unzstd... ");
     {
         size_t const wkspSize = zstd_dctx_workspace_bound();
         void* wksp = malloc(wkspSize);
-        CONTROL(wksp != NULL);
         ZSTD_DCtx* dctx = zstd_init_dctx(wksp, wkspSize);
+        CONTROL(wksp != NULL);
         CONTROL(dctx != NULL);
-        size_t const dSize = zstd_decompress_dctx(dctx, NULL, 0, kEmptyZstdFrame, sizeof(kEmptyZstdFrame));
-        CONTROL(!zstd_is_error(dSize));
-        CONTROL(dSize == 0);
+        {
+          size_t const dSize = zstd_decompress_dctx(dctx, NULL, 0, kEmptyZstdFrame, sizeof(kEmptyZstdFrame));
+          CONTROL(!zstd_is_error(dSize));
+          CONTROL(dSize == 0);
+        }
         free(wksp);
     }
     fprintf(stderr, "Ok\n");
diff --git a/contrib/linux-kernel/test/test.c b/contrib/linux-kernel/test/test.c
index 9064be7936aa7e995e6ae96b20889358a311a492..6cd1730bb3a23293cdc9749be0e5f0384ae2988a 100644
--- a/contrib/linux-kernel/test/test.c
+++ b/contrib/linux-kernel/test/test.c
@@ -30,15 +30,15 @@ typedef struct {
   size_t compSize;
 } test_data_t;
 
-test_data_t create_test_data(void) {
+static test_data_t create_test_data(void) {
   test_data_t data;
   data.dataSize = 128 * 1024;
-  data.data = malloc(data.dataSize);
+  data.data = (char*)malloc(data.dataSize);
   CONTROL(data.data != NULL);
-  data.data2 = malloc(data.dataSize);
+  data.data2 = (char*)malloc(data.dataSize);
   CONTROL(data.data2 != NULL);
   data.compSize = zstd_compress_bound(data.dataSize);
-  data.comp = malloc(data.compSize);
+  data.comp = (char*)malloc(data.compSize);
   CONTROL(data.comp != NULL);
   memset(data.data, 0, data.dataSize);
   return data;
@@ -54,26 +54,27 @@ static void free_test_data(test_data_t const *data) {
 #define MAX(a, b) ((a) > (b) ? (a) : (b))
 
 static void test_btrfs(test_data_t const *data) {
-  fprintf(stderr, "testing btrfs use cases... ");
   size_t const size = MIN(data->dataSize, 128 * 1024);
+  fprintf(stderr, "testing btrfs use cases... ");
   for (int level = -1; level < 16; ++level) {
     zstd_parameters params = zstd_get_params(level, size);
-    CONTROL(params.cParams.windowLog <= 17);
     size_t const workspaceSize =
         MAX(zstd_cstream_workspace_bound(&params.cParams),
             zstd_dstream_workspace_bound(size));
     void *workspace = malloc(workspaceSize);
-    CONTROL(workspace != NULL);
 
     char const *ip = data->data;
     char const *iend = ip + size;
     char *op = data->comp;
     char *oend = op + data->compSize;
+
+    CONTROL(params.cParams.windowLog <= 17);
+    CONTROL(workspace != NULL);
     {
       zstd_cstream *cctx = zstd_init_cstream(&params, size, workspace, workspaceSize);
-      CONTROL(cctx != NULL);
       zstd_out_buffer out = {NULL, 0, 0};
       zstd_in_buffer in = {NULL, 0, 0};
+      CONTROL(cctx != NULL);
       for (;;) {
         if (in.pos == in.size) {
           in.src = ip;
@@ -108,9 +109,9 @@ static void test_btrfs(test_data_t const *data) {
     oend = op + size;
     {
       zstd_dstream *dctx = zstd_init_dstream(1ULL << params.cParams.windowLog, workspace, workspaceSize);
-      CONTROL(dctx != NULL);
       zstd_out_buffer out = {NULL, 0, 0};
       zstd_in_buffer in = {NULL, 0, 0};
+      CONTROL(dctx != NULL);
       for (;;) {
         if (in.pos == in.size) {
           in.src = ip;
@@ -125,15 +126,16 @@ static void test_btrfs(test_data_t const *data) {
           out.pos = 0;
           op += out.size;
         }
-
-        size_t const ret = zstd_decompress_stream(dctx, &out, &in);
-        CONTROL(!zstd_is_error(ret));
-        if (ret == 0) {
-          break;
+        {
+          size_t const ret = zstd_decompress_stream(dctx, &out, &in);
+          CONTROL(!zstd_is_error(ret));
+          if (ret == 0) {
+            break;
+          }
         }
       }
     }
-    CONTROL(op - data->data2 == data->dataSize);
+    CONTROL((size_t)(op - data->data2) == data->dataSize);
     CONTROL(!memcmp(data->data, data->data2, data->dataSize));
     free(workspace);
   }
@@ -141,14 +143,14 @@ static void test_btrfs(test_data_t const *data) {
 }
 
 static void test_decompress_unzstd(test_data_t const *data) {
-    fprintf(stderr, "Testing decompress unzstd... ");
     size_t cSize;
+    fprintf(stderr, "Testing decompress unzstd... ");
     {
         zstd_parameters params = zstd_get_params(19, 0);
         size_t const wkspSize = zstd_cctx_workspace_bound(&params.cParams);
         void* wksp = malloc(wkspSize);
-        CONTROL(wksp != NULL);
         zstd_cctx* cctx = zstd_init_cctx(wksp, wkspSize);
+        CONTROL(wksp != NULL);
         CONTROL(cctx != NULL);
         cSize = zstd_compress_cctx(cctx, data->comp, data->compSize, data->data, data->dataSize, &params);
         CONTROL(!zstd_is_error(cSize));
@@ -157,19 +159,21 @@ static void test_decompress_unzstd(test_data_t const *data) {
     {
         size_t const wkspSize = zstd_dctx_workspace_bound();
         void* wksp = malloc(wkspSize);
-        CONTROL(wksp != NULL);
         zstd_dctx* dctx = zstd_init_dctx(wksp, wkspSize);
+        CONTROL(wksp != NULL);
         CONTROL(dctx != NULL);
-        size_t const dSize = zstd_decompress_dctx(dctx, data->data2, data->dataSize, data->comp, cSize);
-        CONTROL(!zstd_is_error(dSize));
-        CONTROL(dSize == data->dataSize);
+        {
+          size_t const dSize = zstd_decompress_dctx(dctx, data->data2, data->dataSize, data->comp, cSize);
+          CONTROL(!zstd_is_error(dSize));
+          CONTROL(dSize == data->dataSize);
+        }
         CONTROL(!memcmp(data->data, data->data2, data->dataSize));
         free(wksp);
     }
     fprintf(stderr, "Ok\n");
 }
 
-static void test_f2fs() {
+static void test_f2fs(void) {
   fprintf(stderr, "testing f2fs uses... ");
   CONTROL(zstd_min_clevel() < 0);
   CONTROL(zstd_max_clevel() == 22);
@@ -182,7 +186,7 @@ static void __attribute__((noinline)) use(void *x) {
   asm volatile("" : "+r"(x));
 }
 
-static void __attribute__((noinline)) set_stack() {
+static void __attribute__((noinline)) set_stack(void) {
 
   char stack[8192];
   g_stack = stack;
@@ -190,14 +194,16 @@ static void __attribute__((noinline)) set_stack() {
   use(g_stack);
 }
 
-static void __attribute__((noinline)) check_stack() {
+static void __attribute__((noinline)) check_stack(void) {
   size_t cleanStack = 0;
   while (cleanStack < 8192 && g_stack[cleanStack] == 0x33) {
     ++cleanStack;
   }
-  size_t const stackSize = 8192 - cleanStack;
-  fprintf(stderr, "Maximum stack size: %zu\n", stackSize);
-  CONTROL(stackSize <= 2048 + 512);
+  {
+    size_t const stackSize = 8192 - cleanStack;
+    fprintf(stderr, "Maximum stack size: %zu\n", stackSize);
+    CONTROL(stackSize <= 2048 + 512);
+  }
 }
 
 static void test_stack_usage(test_data_t const *data) {
diff --git a/lib/decompress/huf_decompress.c b/lib/decompress/huf_decompress.c
index 128b08019c480c536d717daf9b52f9e677c438db..1a77139ee3ce517de63e924d0c6d0396a455ee65 100644
--- a/lib/decompress/huf_decompress.c
+++ b/lib/decompress/huf_decompress.c
@@ -47,7 +47,9 @@
  * Disable when MSAN is enabled.
  */
 #if defined(__linux__) || defined(__linux) || defined(__APPLE__)
-# if ZSTD_MEMORY_SANITIZER || ZSTD_DATAFLOW_SANITIZER
+# if ZSTD_MEMORY_SANITIZER
+#  define HUF_ASM_SUPPORTED 0
+# elif ZSTD_DATAFLOW_SANITIZER
 #  define HUF_ASM_SUPPORTED 0
 # else
 #  define HUF_ASM_SUPPORTED 1