summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorfakuivan <fakuivan@gmail.com>2024-06-18 01:53:41 -0300
committerGitHub <noreply@github.com>2024-06-18 06:53:41 +0200
commit33f5ce80d69ae06878da0b9161c4ee93d5bb0861 (patch)
tree8f781c177134d69c28ec59f2af42b3a25ec00d91
parent4867931af36467c1882fc01d235fbab67c12bb16 (diff)
downloadNim-33f5ce80d69ae06878da0b9161c4ee93d5bb0861.tar.gz
Fix NIM_STATIC_ASSERT_AUX being redefined on different lines (#23729)
fixes #17247

This generates a new NIM_STATIC_ASSERT_AUX variable for each line that
NIM_STATIC_ASSERT is called from.

While this can solve all existing issues in the current code base, this
method is not effective for multiple asserts on a single line.
-rw-r--r--lib/nimbase.h12
1 files changed, 8 insertions, 4 deletions
diff --git a/lib/nimbase.h b/lib/nimbase.h
index 2204987db..c66be40c2 100644
--- a/lib/nimbase.h
+++ b/lib/nimbase.h
@@ -272,11 +272,15 @@ __EMSCRIPTEN__
 #elif defined(__cplusplus)
 #define NIM_STATIC_ASSERT(x, msg) static_assert((x), msg)
 #else
-#define NIM_STATIC_ASSERT(x, msg) typedef int NIM_STATIC_ASSERT_AUX[(x) ? 1 : -1];
+#define _NIM_STATIC_ASSERT_FINAL(x, append_name) typedef int NIM_STATIC_ASSERT_AUX ## append_name[(x) ? 1 : -1];
+#define _NIM_STATIC_ASSERT_STAGE_3(x, line)      _NIM_STATIC_ASSERT_FINAL(x, _AT_LINE_##line)
+#define _NIM_STATIC_ASSERT_STAGE_2(x, line)      _NIM_STATIC_ASSERT_STAGE_3(x, line)
+#define NIM_STATIC_ASSERT(x, msg)                _NIM_STATIC_ASSERT_STAGE_2(x,__LINE__)
 // On failure, your C compiler will say something like:
-//   "error: 'NIM_STATIC_ASSERT_AUX' declared as an array with a negative size"
-// we could use a better fallback to also show line number, using:
-// http://www.pixelbeat.org/programming/gcc/static_assert.html
+//   "error: 'NIM_STATIC_ASSERT_AUX_AT_LINE_XXX' declared as an array with a negative size"
+// Adding the line number helps to avoid redefinitions which are not allowed in
+// old GCC versions, however the order of evaluation for __LINE__ is a little tricky,
+// hence all the helper macros. See https://stackoverflow.com/a/3385694 for more info.
 #endif
 
 /* C99 compiler? */