diff --git a/meson.build b/meson.build index a7e536ac..451b9dd3 100644 --- a/meson.build +++ b/meson.build @@ -3,7 +3,6 @@ project('taisei', 'c', version : 'v1.4-dev', meson_version : '>=0.53.0', default_options : [ - # Should really be c11, but gnu11 is a safer default because everything is terrible. 'c_std=gnu11', 'default_library=static', @@ -60,7 +59,6 @@ config = configuration_data() taisei_c_args = [ '-Wall', - '-Wpedantic', '-Werror=assume', '-Werror=implicit-function-declaration', @@ -81,10 +79,8 @@ taisei_c_args = [ '-Wfloat-overflow-conversion', '-Wfloat-zero-conversion', '-Wfor-loop-analysis', - '-Wformat-pedantic', '-Wformat-security', '-Wgcc-compat', - '-Wgnu', '-Wignored-qualifiers', '-Winit-self', '-Wlogical-op', @@ -272,7 +268,6 @@ else config.set('TAISEI_BUILDCONF_HAVE_MAX_ALIGN_T', malloc_alignment > 0) endif -config.set('TAISEI_BUILDCONF_USE_GNU_EXTENSIONS', get_option('use_gnu_ext')) config.set('TAISEI_BUILDCONF_HAVE_BUILTIN_POPCOUNTLL', cc.has_function('__builtin_popcountll')) config.set('TAISEI_BUILDCONF_HAVE_BUILTIN_POPCOUNT', cc.has_function('__builtin_popcount')) config.set('TAISEI_BUILDCONF_HAVE_BUILTIN_AVAILABLE', cc.has_function('__builtin_available')) diff --git a/meson_options.txt b/meson_options.txt index db3d41ba..f66390c8 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -190,10 +190,3 @@ option( value : false, description : 'Build shaderc and spirv-cross CLI tools from subprojects even if system versions exist' ) - -option( - 'use_gnu_ext', - type : 'boolean', - value : true, - description : 'Allow use of some GNU C extensions (if supported by compiler)' -) diff --git a/src/dynarray.h b/src/dynarray.h index 7d2ff75c..57dc5f09 100644 --- a/src/dynarray.h +++ b/src/dynarray.h @@ -33,43 +33,26 @@ typedef DYNAMIC_ARRAY_BASE(void) DynamicArray; DynamicArray dyn_array; \ } -#ifdef USE_GNU_EXTENSIONS - #define DYNARRAY_ASSERT_VALID(darr) do { \ - static_assert( \ - __builtin_types_compatible_p(DynamicArray, __typeof__((darr)->dyn_array)), \ - "x->dyn_array must be of DynamicArray type"); \ - static_assert( \ - __builtin_offsetof(__typeof__(*(darr)), dyn_array) == 0, \ - "x->dyn_array must be the first member in struct"); \ - } while(0) -#else - #define DYNARRAY_ASSERT_VALID(darr) ((void)0) -#endif +#define DYNARRAY_ASSERT_VALID(darr) do { \ + static_assert( \ + __builtin_types_compatible_p(DynamicArray, __typeof__((darr)->dyn_array)), \ + "x->dyn_array must be of DynamicArray type"); \ + static_assert( \ + __builtin_offsetof(__typeof__(*(darr)), dyn_array) == 0, \ + "x->dyn_array must be the first member in struct"); \ +} while(0) -#ifdef USE_GNU_EXTENSIONS - #define DYNARRAY_CAST_TO_BASE(darr) (__extension__ ({ \ - DYNARRAY_ASSERT_VALID(darr); \ - &NOT_NULL(darr)->dyn_array; \ - })) -#else - #define DYNARRAY_CAST_TO_BASE(darr) (&(darr)->dyn_array) -#endif +#define DYNARRAY_CAST_TO_BASE(darr) ({ \ + DYNARRAY_ASSERT_VALID(darr); \ + &NOT_NULL(darr)->dyn_array; \ +}) -#ifdef USE_GNU_EXTENSIONS - #define DYNARRAY_CHECK_ELEMENT_TYPE(darr, elem) do { \ - static_assert( \ - __builtin_types_compatible_p(__typeof__(elem), __typeof__(*(darr)->data)), \ - "Dynamic array element type mismatch" \ - ); \ - } while(0) -#else - #define DYNARRAY_CHECK_ELEMENT_TYPE(darr, elem) do { \ - static_assert( \ - sizeof(elem) == sizeof(*(darr)->data), \ - "Dynamic array element size mismatch" \ - ); \ - } while(0) -#endif +#define DYNARRAY_CHECK_ELEMENT_TYPE(darr, elem) do { \ + static_assert( \ + __builtin_types_compatible_p(__typeof__(elem), __typeof__(*(darr)->data)), \ + "Dynamic array element type mismatch" \ + ); \ +} while(0) #define DYNARRAY_ELEM_SIZE(darr) sizeof(*(darr)->data) @@ -97,15 +80,10 @@ dynarray_size_t _dynarray_prepare_append_with_min_capacity(dynarray_size_t sizeo #define _dynarray_append_with_min_capacity(darr, min_capacity) \ dynarray_get_ptr(darr, _dynarray_dispatch_func(prepare_append_with_min_capacity, darr, min_capacity)) -#ifdef USE_GNU_EXTENSIONS - #define dynarray_append_with_min_capacity(darr, min_capacity) (__extension__ ({ \ - assume((darr) != NULL); \ - _dynarray_append_with_min_capacity((darr), min_capacity); \ - })) -#else - #define dynarray_append_with_min_capacity(darr, min_capacity) \ - _dynarray_append_with_min_capacity((darr), min_capacity) -#endif +#define dynarray_append_with_min_capacity(darr, min_capacity) ({ \ + __auto_type _darr2 = NOT_NULL(darr); \ + dynarray_get_ptr(_darr2, _dynarray_dispatch_func(prepare_append_with_min_capacity, _darr2, min_capacity)); \ +}) #define dynarray_append(darr) \ dynarray_append_with_min_capacity(darr, 2) @@ -121,23 +99,22 @@ void _dynarray_compact(dynarray_size_t sizeof_element, DynamicArray *darr) attr_ } \ } while(0) -#ifdef USE_GNU_EXTENSIONS - #define dynarray_get_ptr(darr, idx) (__extension__ ({ \ - DYNARRAY_ASSERT_VALID(darr); \ - __auto_type _darr = NOT_NULL(darr); \ - dynarray_size_t _darr_idx = (idx); \ - assume(_darr_idx >= 0); \ - assume(_darr_idx < _darr->num_elements); \ - NOT_NULL((darr)->data + _darr_idx); \ - })) -#else - #define dynarray_get_ptr(darr, idx) ((darr)->data + (idx)) -#endif +#define dynarray_get_ptr(darr, idx) ({ \ + DYNARRAY_ASSERT_VALID(darr); \ + __auto_type _darr = NOT_NULL(darr); \ + dynarray_size_t _darr_idx = (idx); \ + assume(_darr_idx >= 0); \ + assume(_darr_idx < _darr->num_elements); \ + NOT_NULL((darr)->data + _darr_idx); \ +}) -#define dynarray_get(darr, idx) (*dynarray_get_ptr(darr, idx)) +#define dynarray_get(darr, idx) (*dynarray_get_ptr(darr, idx)) #define dynarray_set(darr, idx, ...) ((*dynarray_get_ptr(darr, idx)) = (__VA_ARGS__)) -void _dynarray_set_elements(dynarray_size_t sizeof_element, DynamicArray *darr, dynarray_size_t num_elements, void *elements) attr_nonnull_all; +void _dynarray_set_elements( + dynarray_size_t sizeof_element, DynamicArray *darr, + dynarray_size_t num_elements, void *elements +) attr_nonnull_all; #define dynarray_set_elements(darr, num_elements, elements) do { \ DYNARRAY_ASSERT_VALID(darr); \ DYNARRAY_CHECK_ELEMENT_TYPE(darr, *(elements)); \ @@ -145,24 +122,23 @@ void _dynarray_set_elements(dynarray_size_t sizeof_element, DynamicArray *darr, } while(0) typedef bool (*dynarray_filter_predicate_t)(const void *pelem, void *userdata); -void _dynarray_filter(dynarray_size_t sizeof_element, DynamicArray *darr, dynarray_filter_predicate_t predicate, void *userdata) attr_nonnull(2, 3); +void _dynarray_filter( + dynarray_size_t sizeof_element, DynamicArray *darr, + dynarray_filter_predicate_t predicate, void *userdata +) attr_nonnull(2, 3); #define dynarray_filter(darr, predicate, userdata) \ _dynarray_dispatch_func(filter, darr, predicate, userdata) -#ifdef USE_GNU_EXTENSIONS - #define dynarray_indexof(darr, pelem) (__extension__ ({ \ - DYNARRAY_ASSERT_VALID(darr); \ - __auto_type _darr = NOT_NULL(darr); \ - __auto_type _darr_pelem = NOT_NULL(pelem); \ - DYNARRAY_CHECK_ELEMENT_TYPE(_darr, *(_darr_pelem)); \ - intptr_t _darr_idx = (intptr_t)(_darr_pelem - _darr->data); \ - assume(_darr_idx >= 0); \ - assume(_darr_idx < _darr->num_elements); \ - (dynarray_size_t)_darr_idx; \ - })) -#else - #define dynarray_indexof(darr, pelem) ((intptr_t)((pelem) - (darr)->data)) -#endif +#define dynarray_indexof(darr, pelem) ({ \ + DYNARRAY_ASSERT_VALID(darr); \ + __auto_type _darr = NOT_NULL(darr); \ + __auto_type _darr_pelem = NOT_NULL(pelem); \ + DYNARRAY_CHECK_ELEMENT_TYPE(_darr, *(_darr_pelem)); \ + intptr_t _darr_idx = (intptr_t)(_darr_pelem - _darr->data); \ + assume(_darr_idx >= 0); \ + assume(_darr_idx < _darr->num_elements); \ + (dynarray_size_t)_darr_idx; \ +}) #define _dynarray_foreach_iter MACROHAX_ADDLINENUM(_dynarray_foreach_iter) #define _dynarray_foreach_ignored MACROHAX_ADDLINENUM(_dynarray_foreach_ignored) @@ -179,9 +155,18 @@ void _dynarray_filter(dynarray_size_t sizeof_element, DynamicArray *darr, dynarr } while(0) #define dynarray_foreach_elem(_darr, _pelem_var, ...) \ - dynarray_foreach(_darr, attr_unused dynarray_size_t _dynarray_foreach_ignored, _pelem_var, __VA_ARGS__) + dynarray_foreach( \ + _darr, \ + attr_unused dynarray_size_t _dynarray_foreach_ignored, \ + _pelem_var, \ + __VA_ARGS__ \ + ) #define dynarray_foreach_idx(_darr, _cntr_var, ...) \ - dynarray_foreach(_darr, _cntr_var, attr_unused void *_dynarray_foreach_ignored, __VA_ARGS__) + dynarray_foreach(_darr, \ + _cntr_var, \ + attr_unused void *_dynarray_foreach_ignored, \ + __VA_ARGS__ \ + ) #endif // IGUARD_dynarray_h diff --git a/src/entity.h b/src/entity.h index a8601242..66c7f76a 100644 --- a/src/entity.h +++ b/src/entity.h @@ -125,15 +125,11 @@ INLINE const char *ent_type_name(EntityType type) { } } -#ifdef USE_GNU_EXTENSIONS - #define ENT_CAST(ent, typename) (__extension__ ({ \ - __auto_type _ent = ent; \ - assert(_ent->type == ENT_TYPE_ID(typename)); \ - UNION_CAST(EntityInterface*, typename*, _ent); \ - })) -#else - #define ENT_CAST(ent, typename) UNION_CAST(EntityInterface*, typename*, (ent)); -#endif +#define ENT_CAST(ent, typename) ({ \ + __auto_type _ent = ent; \ + assert(_ent->type == ENT_TYPE_ID(typename)); \ + UNION_CAST(EntityInterface*, typename*, _ent); \ +}) void ent_init(void); void ent_shutdown(void); diff --git a/src/eventloop/executor_emscripten.c b/src/eventloop/executor_emscripten.c index 5d941872..7bcf0a08 100644 --- a/src/eventloop/executor_emscripten.c +++ b/src/eventloop/executor_emscripten.c @@ -79,7 +79,7 @@ void eventloop_run(void) { em_handle_resize_event, NULL, EPRIO_SYSTEM, MAKE_TAISEI_EVENT(TE_VIDEO_MODE_CHANGED) }); - (__extension__ EM_ASM({ + EM_ASM({ Module['onFirstFrame'](); - })); + }); } diff --git a/src/list.h b/src/list.h index 31b7c949..d28896c7 100644 --- a/src/list.h +++ b/src/list.h @@ -101,42 +101,36 @@ ListContainer* list_wrap_container(void *data) attr_returns_allocated; // type-generic macros -#ifdef USE_GNU_EXTENSIONS - // thorough safeguard +#define LIST_CAST(expr) ({ \ + static_assert(__builtin_types_compatible_p( \ + ListInterface, __typeof__((*(expr)).list_interface)), \ + "struct must implement ListInterface (use the LIST_INTERFACE macro)"); \ + static_assert(__builtin_offsetof(__typeof__(*(expr)), list_interface) == 0, \ + "list_interface must be the first member in struct"); \ + CASTPTR_ASSUME_ALIGNED((expr), List); \ +}) - #define LIST_CAST(expr) (__extension__ ({ \ - static_assert(__builtin_types_compatible_p(ListInterface, __typeof__((*(expr)).list_interface)), \ - "struct must implement ListInterface (use the LIST_INTERFACE macro)"); \ - static_assert(__builtin_offsetof(__typeof__(*(expr)), list_interface) == 0, \ - "list_interface must be the first member in struct"); \ - CASTPTR_ASSUME_ALIGNED((expr), List); \ - })) +#define LIST_CAST_2(expr) ({ \ + static_assert(__builtin_types_compatible_p(\ + ListInterface, __typeof__((**(expr)).list_interface)), \ + "struct must implement ListInterface (use the LIST_INTERFACE macro)"); \ + static_assert(__builtin_offsetof(__typeof__(**(expr)), list_interface) == 0, \ + "list_interface must be the first member in struct"); \ + (void)ASSUME_ALIGNED(*(expr), alignof(List)); \ + (List**)(expr); \ +}) - #define LIST_CAST_2(expr) (__extension__ ({ \ - static_assert(__builtin_types_compatible_p(ListInterface, __typeof__((**(expr)).list_interface)), \ - "struct must implement ListInterface (use the LIST_INTERFACE macro)"); \ - static_assert(__builtin_offsetof(__typeof__(**(expr)), list_interface) == 0, \ - "list_interface must be the first member in struct"); \ - (void)ASSUME_ALIGNED(*(expr), alignof(List)); \ - (List**)(expr); \ - })) +#define LIST_ANCHOR_CAST(expr) ({ \ + static_assert(__builtin_types_compatible_p(\ + ListAnchorInterface, __typeof__((*(expr)).list_anchor_interface)), \ + "struct must implement ListAnchorInterface (use the LIST_ANCHOR_INTERFACE macro)"); \ + static_assert(__builtin_offsetof(__typeof__(*(expr)), list_anchor_interface) == 0, \ + "list_anchor_interface must be the first member in struct"); \ + CASTPTR_ASSUME_ALIGNED((expr), ListAnchor); \ +}) - #define LIST_ANCHOR_CAST(expr) (__extension__ ({ \ - static_assert(__builtin_types_compatible_p(ListAnchorInterface, __typeof__((*(expr)).list_anchor_interface)), \ - "struct must implement ListAnchorInterface (use the LIST_ANCHOR_INTERFACE macro)"); \ - static_assert(__builtin_offsetof(__typeof__(*(expr)), list_anchor_interface) == 0, \ - "list_anchor_interface must be the first member in struct"); \ - CASTPTR_ASSUME_ALIGNED((expr), ListAnchor); \ - })) - - #define LIST_CAST_RETURN(e_typekey, e_return) CASTPTR_ASSUME_ALIGNED((e_return), __typeof__(*(e_typekey))) -#else - // basic safeguard - #define LIST_CAST(expr) ((void)sizeof((*(expr)).list_interface), (List*)(expr)) - #define LIST_CAST_2(expr) ((void)sizeof((**(expr)).list_interface), (List**)(expr)) - #define LIST_ANCHOR_CAST(expr) ((void)sizeof((*(expr)).list_anchor_interface), (ListAnchor*)(expr)) - #define LIST_CAST_RETURN(e_typekey, e_return) (void*)(e_return) -#endif +#define LIST_CAST_RETURN(e_typekey, e_return) \ + CASTPTR_ASSUME_ALIGNED((e_return), __typeof__(*(e_typekey))) #define list_insert(dest,elem) \ (LIST_CAST_RETURN(elem, list_insert(LIST_CAST_2(dest), LIST_CAST(elem)))) diff --git a/src/util/assert.c b/src/util/assert.c index a97b4894..314aa9c2 100644 --- a/src/util/assert.c +++ b/src/util/assert.c @@ -26,8 +26,8 @@ void _ts_assert_fail(const char *cond, const char *func, const char *file, int l #ifdef __EMSCRIPTEN__ #include void _emscripten_trap(void) { - (__extension__ EM_ASM({ + EM_ASM({ throw new Error("You just activated my trap card!"); - })); + }); } #endif diff --git a/src/util/compat.h b/src/util/compat.h index 95706a54..185fad4a 100644 --- a/src/util/compat.h +++ b/src/util/compat.h @@ -76,12 +76,9 @@ #define PRAGMA(p) _Pragma(#p) -#ifdef RNG_API_CHECK - #undef TAISEI_BUILDCONF_USE_GNU_EXTENSIONS - #undef USE_GNU_EXTENSIONS -#endif - #ifndef __GNUC__ // clang defines this too + #pragma Unsupported compiler, expect nothing to work + #define __attribute__(...) #define __extension__ #define UNREACHABLE @@ -91,9 +88,6 @@ #define LIKELY(x) (bool)(x) #define UNLIKELY(x) (bool)(x) #else - #ifdef TAISEI_BUILDCONF_USE_GNU_EXTENSIONS - #define USE_GNU_EXTENSIONS - #endif #define UNREACHABLE __builtin_unreachable() #define DIAGNOSTIC(x) PRAGMA(GCC diagnostic x) @@ -292,32 +286,23 @@ typedef _Complex double cmplx; #define INLINE static inline attr_must_inline __attribute__((gnu_inline)) -#ifdef USE_GNU_EXTENSIONS - #define ASSUME_ALIGNED(expr, alignment) (__extension__ ({ \ - static_assert(__builtin_constant_p(alignment), ""); \ - __auto_type _assume_aligned_ptr = (expr); \ - assert(((uintptr_t)_assume_aligned_ptr & ((alignment) - 1)) == 0); \ - __builtin_assume_aligned(_assume_aligned_ptr, (alignment)); \ - })) -#else - #define ASSUME_ALIGNED(expr, alignment) (expr) -#endif +#define ASSUME_ALIGNED(expr, alignment) ({ \ + static_assert(__builtin_constant_p(alignment), ""); \ + __auto_type _assume_aligned_ptr = (expr); \ + assert(((uintptr_t)_assume_aligned_ptr & ((alignment) - 1)) == 0); \ + __builtin_assume_aligned(_assume_aligned_ptr, (alignment)); \ +}) #define UNION_CAST(_from_type, _to_type, _expr) \ ((union { _from_type f; _to_type t; }) { .f = (_expr) }).t -// #define CASTPTR_ASSUME_ALIGNED(expr, type) UNION_CAST(void*, type*, ASSUME_ALIGNED(expr, alignof(type))) #define CASTPTR_ASSUME_ALIGNED(expr, type) ((type*)ASSUME_ALIGNED((expr), alignof(type))) -#ifdef USE_GNU_EXTENSIONS - #define NOT_NULL(expr) (__extension__ ({ \ - __auto_type _assume_not_null_ptr = (expr); \ - assume(_assume_not_null_ptr != NULL); \ - _assume_not_null_ptr; \ - })) -#else - #define NOT_NULL(expr) (expr) -#endif +#define NOT_NULL(expr) ({ \ + __auto_type _assume_not_null_ptr = (expr); \ + assume(_assume_not_null_ptr != NULL); \ + _assume_not_null_ptr; \ +}) #ifdef __SWITCH__ #include "../arch_switch.h" diff --git a/src/util/miscmath.c b/src/util/miscmath.c index 4d148f65..79bd0375 100644 --- a/src/util/miscmath.c +++ b/src/util/miscmath.c @@ -506,7 +506,7 @@ uint64_t _umuldiv64_slow(uint64_t x, uint64_t multiplier, uint64_t divisor) { INLINE uint64_t _umuldiv64(uint64_t x, uint64_t multiplier, uint64_t divisor) { #if defined(TAISEI_BUILDCONF_HAVE_INT128) - __extension__ typedef unsigned __int128 uint128_t; + typedef unsigned __int128 uint128_t; return ((uint128_t)x * (uint128_t)multiplier) / divisor; #elif defined(TAISEI_BUILDCONF_HAVE_LONG_DOUBLE) #define UMULDIV64_SANITY_CHECK diff --git a/src/vfs/sync_emscripten.c b/src/vfs/sync_emscripten.c index 379d0c22..4b5dbaec 100644 --- a/src/vfs/sync_emscripten.c +++ b/src/vfs/sync_emscripten.c @@ -36,7 +36,7 @@ void vfs_sync_callback(bool is_load, char *error, CallChain *next) { void vfs_sync(VFSSyncMode mode, CallChain next) { CallChain *cc = memdup(&next, sizeof(next)); - __extension__ (EM_ASM({ + EM_ASM({ SyncFS($0, $1); - }, (mode == VFS_SYNC_LOAD), cc)); + }, (mode == VFS_SYNC_LOAD), cc); }