# Copyright (C) 2016, 2017, 2018, 2019  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,8 @@
 
 GCC_STD := gnu99
 CFLAGS := -Wall -Wextra \
+          -Wno-gnu-designator \
+          -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,8 @@
 
 GCC_STD := gnu99
 CFLAGS := -Wall -Wextra \
+          -Wno-gnu-designator \
+          -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
@@ -2783,9 +2783,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(
@@ -2800,7 +2803,10 @@
 
     n = json_litex_expr_new_node(expr);
     n->type = json_litex_expr_node_cmp_op;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wenum-conversion"
     n->node.cmp_op = bin->op;
+#pragma GCC diagnostic pop
 
     return JSON_LITEX_EXPR_AST_ATTR(
         true, 0, 0);
@@ -3314,7 +3320,10 @@
     n->type = json_litex_expr_ast_node_bin_op;
     n->bin_op.right = r;
     n->bin_op.left = *l;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wenum-conversion"
     n->bin_op.op = val;
+#pragma GCC diagnostic pop
     n->pos = *pos;
 
     *l = n;
@@ -7136,7 +7145,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
@@ -10351,8 +10363,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,7 @@
 
 GCC_STD := gnu99
 CFLAGS := -Wall -Wextra \
+          -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
@@ -6805,7 +6805,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);
 }
@@ -9141,8 +9144,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,8 @@
 
 GCC_STD := gnu99
 CFLAGS := -Wall -Wextra \
+          -Wno-gnu-designator \
+          -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,7 @@
 
 GCC_STD := gnu99
 CFLAGS := -Wall -Wextra \
+          -Wno-tautological-constant-out-of-range-compare \
           -std=${GCC_STD} -g -I. -I.. \
           -fPIC -fvisibility=hidden -shared \
           -fdata-sections -ffunction-sections -Wl,--gc-sections \
--- src/Makefile
+++ src/Makefile
@@ -22,6 +22,8 @@
 
 GCC_STD := gnu99
 CFLAGS := -Wall -Wextra \
+          -Wno-gnu-designator \
+          -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[];
 
