fix some codegen bugs: NIM_BOOL, NIM_STATIC_ASSERT, --passc:-std=... (etc) (#13798)

* fix cgen bool D20200328T203812
* --passc:std=c++17 (etc) now works instead of silently ignored
* document caveats for NIM_NIL
This commit is contained in:
Timothee Cour 2020-04-07 06:17:30 -07:00 • committed by GitHub
commit ab5e26c53c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 110 additions and 54 deletions

View file

@ -262,6 +262,21 @@ __AVR__
#include <limits.h>
#include <stddef.h>
// define NIM_STATIC_ASSERT
// example use case: CT sizeof for importc types verification
// where we have {.completeStruct.} (or lack of {.incompleteStruct.})
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L)
#define NIM_STATIC_ASSERT(x, msg) _Static_assert((x), msg)
#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];
// 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
#endif
/* C99 compiler? */
#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901))
# define HAVE_STDINT_H
@ -288,34 +303,40 @@ __AVR__
namespace USE_NIM_NAMESPACE {
#endif
// preexisting check, seems paranoid, maybe remove
#if defined(NIM_TRUE) || defined(NIM_FALSE) || defined(NIM_BOOL)
#error "nim reserved preprocessor macros clash"
#endif
/* bool types (C++ has it): */
#ifdef __cplusplus
# ifndef NIM_TRUE
# define NIM_TRUE true
# endif
# ifndef NIM_FALSE
# define NIM_FALSE false
# endif
# define NIM_BOOL bool
#define NIM_BOOL bool
#elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901)
// see #13798: to avoid conflicts for code emitting `#include <stdbool.h>`
#define NIM_BOOL _Bool
#else
typedef unsigned char NIM_BOOL; // best effort
#endif
NIM_STATIC_ASSERT(sizeof(NIM_BOOL) == 1, ""); // check whether really needed
#define NIM_TRUE true
#define NIM_FALSE false
#ifdef __cplusplus
# if __cplusplus >= 201103L
# /* nullptr is more type safe (less implicit conversions than 0) */
# define NIM_NIL nullptr
# else
# /* consider using NULL if comment below for NIM_NIL doesn't apply to C++ */
# // both `((void*)0)` and `NULL` would cause codegen to emit
# // error: assigning to 'Foo *' from incompatible type 'void *'
# // but codegen could be fixed if need. See also potential caveat regarding
# // NULL.
# // However, `0` causes other issues, see #13798
# define NIM_NIL 0
# endif
#else
# ifdef bool
# define NIM_BOOL bool
# else
typedef unsigned char NIM_BOOL;
# endif
# ifndef NIM_TRUE
# define NIM_TRUE ((NIM_BOOL) 1)
# endif
# ifndef NIM_FALSE
# define NIM_FALSE ((NIM_BOOL) 0)
# endif
# include <stdbool.h>
# define NIM_NIL ((void*)0) /* C's NULL is fucked up in some C compilers, so
the generated code does not rely on it anymore */
#endif
@ -516,10 +537,8 @@ static inline void GCGuard (void *ptr) { asm volatile ("" :: "X" (ptr)); }
# define GC_GUARD
#endif
/* Test to see if Nim and the C compiler agree on the size of a pointer.
On disagreement, your C compiler will say something like:
"error: 'Nim_and_C_compiler_disagree_on_target_architecture' declared as an array with a negative size" */
typedef int Nim_and_C_compiler_disagree_on_target_architecture[sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof(NI)*8 ? 1 : -1];
// Test to see if Nim and the C compiler agree on the size of a pointer.
NIM_STATIC_ASSERT(sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof(NI)*8, "");
#ifdef USE_NIM_NAMESPACE
}