# Copyright (C) 2016, 2017, 2018, 2019, 2020, 2021  Stefan Vargyas
# 
# This file is part of Json-Type.
# 
# Json-Type is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# Json-Type is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with Json-Type.  If not, see <http://www.gnu.org/licenses/>.
# 
--- lib/Makefile
+++ lib/Makefile
@@ -21,6 +21,9 @@
 
 GCC_STD := gnu99
 CFLAGS := -Wall -Wextra \
+          -Wno-gnu-designator \
+          -Wno-unused-local-typedef \
+          -Wno-tautological-constant-out-of-range-compare \
           -std=${GCC_STD} -g -I. -I.. \
           -fPIC -fvisibility=hidden \
           -DPROGRAM=${PROGRAM}
--- lib/bit-set.h
+++ lib/bit-set.h
@@ -399,13 +399,15 @@
     struct                                  \
     {                                       \
         struct bit_set_t set;               \
-        uchar_t ptr[BIT_SET_PTR_SIZE(s)];   \
+        uchar_t* ptr;                       \
     } v ## _bs__;                           \
     const size_t v ## _sz__ = (s);          \
+    v ## _bs__.ptr = BIT_SET_PTR_SIZE(s)    \
+        ? alloca(BIT_SET_PTR_SIZE(s))       \
+        : NULL;                             \
 
 #define BIT_SET_ALLOC_AUTO_(s, v)           \
     ({                                      \
-        ASSERT(sizeof(v.ptr) == (s));       \
         v.ptr;                              \
     })
 #define BIT_SET_INIT_AUTO(v)                \
--- lib/bit-set.mk
+++ lib/bit-set.mk
@@ -19,6 +19,9 @@
 
 GCC_STD := gnu99
 CFLAGS := -Wall -Wextra \
+          -Wno-gnu-designator \
+          -Wno-unused-local-typedef \
+          -Wno-tautological-constant-out-of-range-compare \
           -std=${GCC_STD} -g -I. -I.. \
           -fdata-sections -ffunction-sections -Wl,--gc-sections \
           -fPIC -fvisibility=hidden \
--- lib/common.h
+++ lib/common.h
@@ -111,17 +111,16 @@
     do {} while (0)
 #endif
 
-#if !CONFIG_ERROR_FUNCTION_ATTRIBUTE
-#error we need GCC to support the 'error' function attribute
-#else
-#define STATIC(E)                                   \
-    ({                                              \
-        extern int __attribute__                    \
-            ((error("assertion failed: '" #E "'"))) \
-            static_assert();                        \
-        (void) ((E) ? 0 : static_assert());         \
+#define STATIC__(A, B) A ## _ ## B
+#define STATIC_(A, B)  STATIC__(A, B)
+#define STATIC(E)                    \
+    ({                               \
+        typedef char STATIC_(        \
+            static_assertion_failed, \
+            __COUNTER__)             \
+            [(E) ? 1 : -1];          \
+        (void) 0;                    \
     })
-#endif
 
 void fatal_error(const char* fmt, ...)
     PRINTF(1)
--- lib/json-litex.c
+++ lib/json-litex.c
@@ -2759,9 +2759,12 @@
         t = bin->right;
         bin->right = bin->left;
         bin->left = t;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wenum-conversion"
         bin->op =
             JSON_LITEX_EXPR_CMP_OP_REVERSE(
                 bin->op);
+#pragma GCC diagnostic pop
     }
 
     a = json_litex_expr_ast_gen_code_visit(
@@ -2774,7 +2777,10 @@
     json_litex_expr_backpatch_ast_attr(
             expr, &a);
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wenum-conversion"
     JSON_LITEX_EXPR_GEN_NODE(cmp_op, bin->op);
+#pragma GCC diagnostic pop
 
     return JSON_LITEX_EXPR_AST_ATTR(
         true, 0, 0);
@@ -3294,8 +3300,11 @@
     r = JSON_LITEX_EXPR_AST_STACK_POP();
     l = JSON_LITEX_EXPR_AST_STACK_TOP_REF();
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wenum-conversion"
     *l = JSON_LITEX_EXPR_AST_IMPL_NEW_NODE_POS(
             bin_op, right = r, left = *l, op = val);
+#pragma GCC diagnostic pop
 
     return true;
 }
@@ -7173,7 +7182,10 @@
          json_litex_print_repr_opts_quotes + 0 ==
             pretty_print_repr_print_quotes);
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wenum-conversion"
     pretty_print_repr(file, str, strulen(str), opts);
+#pragma GCC diagnostic pop
 }
 
 union json_litex_node_pack_t
@@ -10664,8 +10676,11 @@
         SHR_ERR(wrong_lib_version) ==
         DYN_ERR(wrong_lib_version) + 1);
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wenum-conversion"
     enum json_litex_lib_shared_lib_error_type_t r =
         error->type;
+#pragma GCC diagnostic pop
 
     if (error->type == DYN_ERR(symbol_not_found)) {
         ASSERT(error->sym < 2);
--- lib/json-litex.mk
+++ lib/json-litex.mk
@@ -37,6 +37,8 @@
 
 GCC_STD := gnu99
 CFLAGS := -Wall -Wextra \
+          -Wno-unused-local-typedef \
+          -Wno-tautological-constant-out-of-range-compare \
           -std=${GCC_STD} -g -I. -I.. -I${PCRE2_INCLUDE} \
           -fPIC -fvisibility=hidden -shared -fdata-sections -ffunction-sections \
           -Wl,--gc-sections -Wl,--entry=json_litex_filter_main \
--- lib/json-type.c
+++ lib/json-type.c
@@ -6811,7 +6811,10 @@
         json_type_any_array_type + 0 ==
         json_type_ruler_basic_array_type);
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wenum-conversion"
     n = json_type_lib_new_any_node(lib, pos, val);
+#pragma GCC diagnostic pop
 
     JSON_TYPE_LIB_STACK_PUSH_NODE(n);
 }
@@ -9147,8 +9150,11 @@
         SHR_ERR(wrong_lib_version) ==
         DYN_ERR(wrong_lib_version) + 1);
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wenum-conversion"
     enum json_type_lib_shared_lib_error_type_t r =
         error->type;
+#pragma GCC diagnostic pop
 
     if (error->type == DYN_ERR(symbol_not_found)) {
         ASSERT(error->sym < 2);
--- lib/test-common.mk
+++ lib/test-common.mk
@@ -25,6 +25,9 @@
 
 GCC_STD := gnu99
 CFLAGS := -Wall -Wextra \
+          -Wno-gnu-designator \
+          -Wno-unused-local-typedef \
+          -Wno-tautological-constant-out-of-range-compare \
           -std=${GCC_STD} -g -I. -I.. \
           -fdata-sections -ffunction-sections -Wl,--gc-sections \
           -fPIC -fvisibility=hidden \
--- lib/test-filter.mk
+++ lib/test-filter.mk
@@ -19,6 +19,8 @@
 
 GCC_STD := gnu99
 CFLAGS := -Wall -Wextra \
+          -Wno-unused-local-typedef \
+          -Wno-tautological-constant-out-of-range-compare \
           -std=${GCC_STD} -g -I. -I.. \
           -fPIC -fvisibility=hidden -shared \
           -fdata-sections -ffunction-sections -Wl,--gc-sections \
@@ -33,6 +35,9 @@
 DEP  := test-filter
 BIN  := ${PROGRAM}
 
-include common.mk
+ifdef SANITIZE
+override undefine SANITIZE
+endif
 
+include common.mk
 
--- test/libs/common-litex.mk
+++ test/libs/common-litex.mk
@@ -45,6 +45,8 @@
 GCC_STD := gnu99
 CFLAGS := -Wall -Wextra -std=${GCC_STD} -I. \
           -I${JSON_TYPE_HOME} -I${JSON_TYPE_HOME}/lib \
+          -Wno-unused-local-typedef \
+          -Wno-tautological-constant-out-of-range-compare \
           -fPIC -fvisibility=hidden -g -shared \
           -fdata-sections -ffunction-sections -Wl,--gc-sections \
           -Wl,--entry=${subst -,_,${MODULE}}_main \
--- test/libs/common-type.mk
+++ test/libs/common-type.mk
@@ -27,6 +27,8 @@
 GCC_STD := gnu99
 CFLAGS := -Wall -Wextra -std=${GCC_STD} -I. \
           -I${JSON_TYPE_HOME} -I${JSON_TYPE_HOME}/lib \
+          -Wno-unused-local-typedef \
+          -Wno-tautological-constant-out-of-range-compare \
           -fPIC -fvisibility=hidden -g -shared \
           -fdata-sections -ffunction-sections -Wl,--gc-sections \
           -Wl,--entry=${subst -,_,${MODULE}}_main \
--- src/Makefile
+++ src/Makefile
@@ -22,6 +22,9 @@
 
 GCC_STD := gnu99
 CFLAGS := -Wall -Wextra \
+          -Wno-gnu-designator \
+          -Wno-unused-local-typedef \
+          -Wno-tautological-constant-out-of-range-compare \
           -std=${GCC_STD} -g -I.. -I. \
           -DPROGRAM=${PROGRAM} \
           -DLIBRARY=${LIBRARY}
--- src/common.c
+++ src/common.c
@@ -192,11 +192,14 @@
 void pos_error_header(
     const char* file, size_t line, size_t col)
 {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-extra-args"
     error_fmt(
         false,
         line && col ? "%s:%zu:%zu: " : "%s: ",
         file ? file : stdin_name,
         line, col);
+#pragma GCC diagnostic pop
 }
 
 void pos_error(
--- src/common.h
+++ src/common.h
@@ -88,17 +88,16 @@
     do {} while (0)
 #endif
 
-#if !CONFIG_ERROR_FUNCTION_ATTRIBUTE
-#error we need GCC to support the 'error' function attribute
-#else
-#define STATIC(E)                                   \
-    ({                                              \
-        extern int __attribute__                    \
-            ((error("assertion failed: '" #E "'"))) \
-            static_assert();                        \
-        (void) ((E) ? 0 : static_assert());         \
+#define STATIC__(A, B) A ## _ ## B
+#define STATIC_(A, B)  STATIC__(A, B)
+#define STATIC(E)                    \
+    ({                               \
+        typedef char STATIC_(        \
+            static_assertion_failed, \
+            __COUNTER__)             \
+            [(E) ? 1 : -1];          \
+        (void) 0;                    \
     })
-#endif
 
 extern const char stdin_name[];
 
