Fix a lot of warnings with -O3 and 32bit builds
This commit is contained in:
parent
9424ba1b4e
commit
e959fbc5f7
12 changed files with 121 additions and 52 deletions
|
@ -24,6 +24,7 @@ config = configuration_data()
|
|||
taisei_c_args = cc.get_supported_arguments(
|
||||
'-Wall',
|
||||
'-Wpedantic',
|
||||
'-Werror=assume',
|
||||
'-Werror=implicit-function-declaration',
|
||||
|
||||
#
|
||||
|
|
13
src/entity.h
13
src/entity.h
|
@ -115,20 +115,21 @@ static inline attr_must_inline const char* ent_type_name(EntityType type) {
|
|||
#define ENT_TYPE_ID(typename) (_ENT_TYPEID_##typename)
|
||||
|
||||
#ifdef USE_GNU_EXTENSIONS
|
||||
#define ENT_CAST(ent, typename) (__extension__({ \
|
||||
static_assert(__builtin_types_compatible_p(EntityInterface, __typeof__(*(ent))), \
|
||||
#define ENT_CAST(ent, typename) (__extension__ ({ \
|
||||
__auto_type _ent = ent; \
|
||||
static_assert(__builtin_types_compatible_p(EntityInterface, __typeof__(*(_ent))), \
|
||||
"Expression is not an EntityInterface pointer"); \
|
||||
static_assert(__builtin_types_compatible_p(EntityInterface, __typeof__(((typename){}).entity_interface)), \
|
||||
#typename " doesn't implement EntityInterface"); \
|
||||
static_assert(__builtin_offsetof(typename, entity_interface) == 0, \
|
||||
"entity_interface has non-zero offset in " #typename); \
|
||||
IF_DEBUG(if(ent->type != _ENT_TYPEID_##typename) { \
|
||||
log_fatal("Invalid entity cast from %s to " #typename, ent_type_name(ent->type)); \
|
||||
IF_DEBUG(if(_ent->type != _ENT_TYPEID_##typename) { \
|
||||
log_fatal("Invalid entity cast from %s to " #typename, ent_type_name(_ent->type)); \
|
||||
}); \
|
||||
(typename *)(ent); \
|
||||
CASTPTR_ASSUME_ALIGNED(_ent, typename); \
|
||||
}))
|
||||
#else
|
||||
#define ENT_CAST(ent, typename) ((typename *)(ent))
|
||||
#define ENT_CAST(ent, typename) CASTPTR_ASSUME_ALIGNED(ent, typename)
|
||||
#endif
|
||||
|
||||
void ent_init(void);
|
||||
|
|
73
src/list.h
73
src/list.h
|
@ -11,13 +11,15 @@
|
|||
|
||||
#include "taisei.h"
|
||||
|
||||
#define LIST_ALIGN alignas(alignof(max_align_t))
|
||||
|
||||
typedef struct ListInterface ListInterface;
|
||||
typedef struct List List;
|
||||
typedef struct ListAnchorInterface ListAnchorInterface;
|
||||
typedef struct ListAnchor ListAnchor;
|
||||
typedef struct ListContainer ListContainer;
|
||||
|
||||
#define LIST_INTERFACE_BASE(typename) struct { \
|
||||
#define LIST_INTERFACE_BASE(typename) LIST_ALIGN struct { \
|
||||
typename *next; \
|
||||
typename *prev; \
|
||||
}
|
||||
|
@ -99,84 +101,93 @@ ListContainer* list_wrap_container(void *data) attr_nodiscard;
|
|||
#ifdef USE_GNU_EXTENSIONS
|
||||
// thorough safeguard
|
||||
|
||||
#define LIST_CAST(expr,ptrlevel) (__extension__({ \
|
||||
static_assert(__builtin_types_compatible_p(ListInterface, __typeof__((ptrlevel (expr)).list_interface)), \
|
||||
#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__(ptrlevel (expr)), list_interface) == 0, \
|
||||
static_assert(__builtin_offsetof(__typeof__(*(expr)), list_interface) == 0, \
|
||||
"list_interface must be the first member in struct"); \
|
||||
(List ptrlevel)(expr); \
|
||||
CASTPTR_ASSUME_ALIGNED((expr), List); \
|
||||
}))
|
||||
|
||||
#define LIST_ANCHOR_CAST(expr,ptrlevel) (__extension__({ \
|
||||
static_assert(__builtin_types_compatible_p(ListAnchorInterface, __typeof__((ptrlevel (expr)).list_anchor_interface)), \
|
||||
#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"); \
|
||||
CASTPTR_ASSUME_ALIGNED((expr), List*); \
|
||||
}))
|
||||
|
||||
#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__(ptrlevel (expr)), list_anchor_interface) == 0, \
|
||||
static_assert(__builtin_offsetof(__typeof__(*(expr)), list_anchor_interface) == 0, \
|
||||
"list_anchor_interface must be the first member in struct"); \
|
||||
(ListAnchor ptrlevel)(expr); \
|
||||
CASTPTR_ASSUME_ALIGNED((expr), ListAnchor); \
|
||||
}))
|
||||
|
||||
#define LIST_CAST_RETURN(expr) (__typeof__(expr))
|
||||
#define LIST_CAST_RETURN(e_typekey, e_return) CASTPTR_ASSUME_ALIGNED((e_return), __typeof__(*(e_typekey)))
|
||||
#else
|
||||
// basic safeguard
|
||||
#define LIST_CAST(expr,ptrlevel) ((void)sizeof((ptrlevel (expr)).list_interface), (List ptrlevel)(expr))
|
||||
#define LIST_ANCHOR_CAST(expr,ptrlevel) ((void)sizeof((ptrlevel (expr)).list_anchor_interface), (ListAnchor ptrlevel)(expr))
|
||||
#define LIST_CAST(expr, ptrlevel) ((void)sizeof((*(expr)).list_interface), (List*)(expr))
|
||||
#define LIST_CAST_2(expr, ptrlevel) ((void)sizeof((**(expr)).list_interface), (List**)(expr))
|
||||
#define LIST_ANCHOR_CAST(expr) ((void)sizeof((*(expr)).list_anchor_interface), (ListAnchor*)(expr))
|
||||
// don't even think about adding a void* cast here
|
||||
#define LIST_CAST_RETURN(expr)
|
||||
#define LIST_CAST_RETURN(e_typekey, e_return) (e_return)
|
||||
#endif
|
||||
|
||||
#define list_insert(dest,elem) \
|
||||
(LIST_CAST_RETURN(elem) list_insert(LIST_CAST(dest, **), LIST_CAST(elem, *)))
|
||||
(LIST_CAST_RETURN(elem, list_insert(LIST_CAST_2(dest), LIST_CAST(elem))))
|
||||
|
||||
#define alist_insert(dest,ref,elem) \
|
||||
(LIST_CAST_RETURN(elem) alist_insert(LIST_ANCHOR_CAST(dest, *), LIST_CAST(ref, *), LIST_CAST(elem, *)))
|
||||
(LIST_CAST_RETURN(elem, alist_insert(LIST_ANCHOR_CAST(dest), LIST_CAST(ref), LIST_CAST(elem))))
|
||||
|
||||
#define list_push(dest,elem) \
|
||||
(LIST_CAST_RETURN(elem) list_push(LIST_CAST(dest, **), LIST_CAST(elem, *)))
|
||||
(LIST_CAST_RETURN(elem, list_push(LIST_CAST_2(dest), LIST_CAST(elem))))
|
||||
|
||||
#define alist_push(dest,elem) \
|
||||
(LIST_CAST_RETURN(elem) alist_push(LIST_ANCHOR_CAST(dest, *), LIST_CAST(elem, *)))
|
||||
(LIST_CAST_RETURN(elem, alist_push(LIST_ANCHOR_CAST(dest), LIST_CAST(elem))))
|
||||
|
||||
#define list_append(dest,elem) \
|
||||
(LIST_CAST_RETURN(elem) list_append(LIST_CAST(dest, **), LIST_CAST(elem, *)))
|
||||
(LIST_CAST_RETURN(elem, list_append(LIST_CAST_2(dest), LIST_CAST(elem))))
|
||||
|
||||
#define alist_append(dest,elem) \
|
||||
(LIST_CAST_RETURN(elem) alist_append(LIST_ANCHOR_CAST(dest, *), LIST_CAST(elem, *)))
|
||||
(LIST_CAST_RETURN(elem, alist_append(LIST_ANCHOR_CAST(dest), LIST_CAST(elem))))
|
||||
|
||||
#define list_insert_at_priority_head(dest,elem,prio,prio_func) \
|
||||
(LIST_CAST_RETURN(elem) list_insert_at_priority_head(LIST_CAST(dest, **), LIST_CAST(elem, *), prio, prio_func))
|
||||
(LIST_CAST_RETURN(elem, list_insert_at_priority_head(LIST_CAST_2(dest), LIST_CAST(elem), prio, prio_func)))
|
||||
|
||||
#define alist_insert_at_priority_head(dest,elem,prio,prio_func) \
|
||||
(LIST_CAST_RETURN(elem) alist_insert_at_priority_head(LIST_ANCHOR_CAST(dest, *), LIST_CAST(elem, *), prio, prio_func))
|
||||
(LIST_CAST_RETURN(elem, alist_insert_at_priority_head(LIST_ANCHOR_CAST(dest), LIST_CAST(elem), prio, prio_func)))
|
||||
|
||||
#define list_insert_at_priority_tail(dest,elem,prio,prio_func) \
|
||||
(LIST_CAST_RETURN(elem) list_insert_at_priority_tail(LIST_CAST(dest, **), LIST_CAST(elem, *), prio, prio_func))
|
||||
(LIST_CAST_RETURN(elem, list_insert_at_priority_tail(LIST_CAST_2(dest), LIST_CAST(elem), prio, prio_func)))
|
||||
|
||||
#define alist_insert_at_priority_tail(dest,elem,prio,prio_func) \
|
||||
(LIST_CAST_RETURN(elem) alist_insert_at_priority_tail(LIST_ANCHOR_CAST(dest, *), LIST_CAST(elem, *), prio, prio_func))
|
||||
(LIST_CAST_RETURN(elem, alist_insert_at_priority_tail(LIST_ANCHOR_CAST(dest), LIST_CAST(elem), prio, prio_func)))
|
||||
|
||||
#define list_pop(dest) \
|
||||
(LIST_CAST_RETURN(*(dest)) list_pop(LIST_CAST(dest, **)))
|
||||
(LIST_CAST_RETURN(*(dest), list_pop(LIST_CAST_2(dest))))
|
||||
|
||||
#define alist_pop(dest) \
|
||||
(LIST_CAST_RETURN((dest)->first) alist_pop(LIST_ANCHOR_CAST(dest, *)))
|
||||
(LIST_CAST_RETURN((dest)->first, alist_pop(LIST_ANCHOR_CAST(dest))))
|
||||
|
||||
#define list_unlink(dest,elem) \
|
||||
(LIST_CAST_RETURN(elem) list_unlink(LIST_CAST(dest, **), LIST_CAST(elem, *)))
|
||||
(LIST_CAST_RETURN(elem, list_unlink(LIST_CAST_2(dest), LIST_CAST(elem))))
|
||||
|
||||
#define alist_unlink(dest,elem) \
|
||||
(LIST_CAST_RETURN(elem) alist_unlink(LIST_ANCHOR_CAST(dest, *), LIST_CAST(elem, *)))
|
||||
(LIST_CAST_RETURN(elem, alist_unlink(LIST_ANCHOR_CAST(dest), LIST_CAST(elem))))
|
||||
|
||||
#define list_foreach(dest,callback,arg) \
|
||||
list_foreach(LIST_CAST(dest, **), callback, arg)
|
||||
list_foreach(LIST_CAST_2(dest), callback, arg)
|
||||
|
||||
#define alist_foreach(dest,callback,arg) \
|
||||
alist_foreach(LIST_ANCHOR_CAST(dest, *), callback, arg)
|
||||
alist_foreach(LIST_ANCHOR_CAST(dest), callback, arg)
|
||||
|
||||
#define list_free_all(dest) \
|
||||
list_free_all(LIST_CAST(dest, **))
|
||||
list_free_all(LIST_CAST_2(dest))
|
||||
|
||||
#define alist_free_all(dest) \
|
||||
alist_free_all(LIST_ANCHOR_CAST(dest, *))
|
||||
alist_free_all(LIST_ANCHOR_CAST(dest))
|
||||
|
||||
#endif // LIST_NO_MACROS
|
||||
|
||||
|
|
|
@ -76,4 +76,6 @@ void objpool_get_stats(ObjectPool *pool, ObjectPoolStats *stats);
|
|||
void objpool_memtest(ObjectPool *pool, ObjectInterface *object);
|
||||
size_t objpool_object_size(ObjectPool *pool);
|
||||
|
||||
#define OBJPOOL_ACQUIRE(pool, type) CASTPTR_ASSUME_ALIGNED(objpool_acquire(pool), type)
|
||||
|
||||
#endif // IGUARD_objectpool_h
|
||||
|
|
|
@ -71,11 +71,11 @@ void gl33_framebuffer_attach(Framebuffer *framebuffer, Texture *tex, uint mipmap
|
|||
// need to update draw buffers
|
||||
framebuffer->initialized = false;
|
||||
|
||||
if(tex) {
|
||||
IF_DEBUG(if(tex) {
|
||||
log_debug("%s %s = %s (%ux%u mip %u)", framebuffer->debug_label, attachment_str(attachment), tex->debug_label, tex->params.width, tex->params.height, mipmap);
|
||||
} else {
|
||||
log_debug("%s %s = NULL", framebuffer->debug_label, attachment_str(attachment));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Texture* gl33_framebuffer_get_attachment(Framebuffer *framebuffer, FramebufferAttachment attachment) {
|
||||
|
|
|
@ -479,11 +479,11 @@ static void glcommon_ext_vertex_array_object(void) {
|
|||
log_warn("Extension not supported");
|
||||
}
|
||||
|
||||
static void shim_glClearDepth(GLdouble depthval) {
|
||||
static APIENTRY GLvoid shim_glClearDepth(GLdouble depthval) {
|
||||
glClearDepthf(depthval);
|
||||
}
|
||||
|
||||
static void shim_glClearDepthf(GLfloat depthval) {
|
||||
static APIENTRY GLvoid shim_glClearDepthf(GLfloat depthval) {
|
||||
glClearDepth(depthval);
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,12 @@ static bool check_shader_object_path(const char *path) {
|
|||
|
||||
static void* load_shader_object_begin(const char *path, uint flags) {
|
||||
struct shobj_type *type = get_shobj_type(path);
|
||||
|
||||
if(type == NULL) {
|
||||
log_warn("%s: can not determine shading language and/or shader stage from the filename", path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct shobj_load_data *ldata = calloc(1, sizeof(struct shobj_load_data));
|
||||
|
||||
switch(type->lang) {
|
||||
|
|
11
src/stage.c
11
src/stage.c
|
@ -719,13 +719,12 @@ void stage_loop(StageInfo *stage) {
|
|||
p->unlocked = true;
|
||||
}
|
||||
} else {
|
||||
if(!global.replay_stage) {
|
||||
log_fatal("Attemped to replay a NULL stage");
|
||||
return;
|
||||
}
|
||||
|
||||
ReplayStage *stg = global.replay_stage;
|
||||
log_debug("REPLAY_PLAY mode: %d events, stage: \"%s\"", stg->numevents, stage_get(stg->stage)->title);
|
||||
|
||||
assert(stg != NULL);
|
||||
assert(stage_get(stg->stage) == stage);
|
||||
|
||||
log_debug("REPLAY_PLAY mode: %d events, stage: \"%s\"", stg->numevents, stage->title);
|
||||
|
||||
tsrand_seed_p(&global.rand_game, stg->seed);
|
||||
log_debug("Random seed: %u", stg->seed);
|
||||
|
|
|
@ -315,6 +315,7 @@ int scythe_reset(Enemy *e, int t) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
attr_returns_nonnull
|
||||
static Enemy* find_scythe(void) {
|
||||
for(Enemy *e = global.enemies.first; e; e = e->next) {
|
||||
if(e->visual_rule == Scythe) {
|
||||
|
@ -322,7 +323,7 @@ static Enemy* find_scythe(void) {
|
|||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
UNREACHABLE;
|
||||
}
|
||||
|
||||
static void elly_frequency(Boss *b, int t) {
|
||||
|
|
|
@ -19,12 +19,17 @@ noreturn void _ts_assert_fail(const char *cond, const char *func, const char *fi
|
|||
#define static_assert _Static_assert
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define _assert(cond,uselog)
|
||||
#define _assert(cond, uselog)
|
||||
#define _assume(cond, uselog) ASSUME(cond)
|
||||
#else
|
||||
#define _assert(cond,uselog) ((cond) ? (void)0 : _ts_assert_fail(#cond, __func__, __FILE__, __LINE__, uselog))
|
||||
#define _assert(cond, uselog) ((cond) ? (void)0 : _ts_assert_fail(#cond, __func__, __FILE__, __LINE__, uselog))
|
||||
#define _assume(cond, uselog) _assert(cond, uselog)
|
||||
#endif
|
||||
|
||||
#define assert(cond) _assert(cond, true)
|
||||
#define assert_nolog(cond) _assert(cond, false)
|
||||
|
||||
#define assume(cond) _assume(cond, true)
|
||||
#define assume_nolog(cond) _assume(cond, false)
|
||||
|
||||
#endif // IGUARD_util_assert_h
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include <math.h>
|
||||
#include <complex.h>
|
||||
|
||||
#include "util/assert.h"
|
||||
|
||||
#ifdef __FAST_MATH__
|
||||
#error -ffast-math is prohibited
|
||||
#endif
|
||||
|
@ -63,13 +65,13 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#define PRAGMA(p) _Pragma(#p)
|
||||
|
||||
#ifndef __GNUC__ // clang defines this too
|
||||
#define __attribute__(...)
|
||||
#define __extension__
|
||||
#define PRAGMA(p)
|
||||
#define UNREACHABLE
|
||||
#else
|
||||
#define PRAGMA(p) _Pragma(#p)
|
||||
#define USE_GNU_EXTENSIONS
|
||||
#define UNREACHABLE __builtin_unreachable()
|
||||
#endif
|
||||
|
@ -82,6 +84,22 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#undef ASSUME
|
||||
|
||||
#ifdef __has_builtin
|
||||
#if __has_builtin(__builtin_assume)
|
||||
#define ASSUME(x) __builtin_assume(x)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(ASSUME) && defined(__GNUC__)
|
||||
#define ASSUME(x) do { if(!(x)) { UNREACHABLE; } } while(0)
|
||||
#endif
|
||||
|
||||
#ifndef ASSUME
|
||||
#define ASSUME(x)
|
||||
#endif
|
||||
|
||||
// On windows, use the MinGW implementations of printf and friends instead of the crippled mscrt ones.
|
||||
#ifdef __USE_MINGW_ANSI_STDIO
|
||||
#define FORMAT_ATTR __MINGW_PRINTF_FORMAT
|
||||
|
@ -204,4 +222,25 @@ typedef signed char schar;
|
|||
#define attr_designated_init
|
||||
#endif
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define _ensure_aligned(ptr, alignment) (ptr)
|
||||
#else
|
||||
static inline attr_must_inline
|
||||
void* _ensure_aligned(void *ptr, size_t alignment) {
|
||||
assert(((uintptr_t)ptr & (alignment - 1)) == 0);
|
||||
return ptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_GNU_EXTENSIONS
|
||||
#define ASSUME_ALIGNED(expr, alignment) (__extension__ ({ \
|
||||
assert(__builtin_constant_p(alignment)); \
|
||||
__builtin_assume_aligned(_ensure_aligned((expr), (alignment)), (alignment)); \
|
||||
}))
|
||||
#else
|
||||
#define ASSUME_ALIGNED(expr, alignment) (expr)
|
||||
#endif
|
||||
|
||||
#define CASTPTR_ASSUME_ALIGNED(expr, type) ((type*)ASSUME_ALIGNED((expr), alignof(type)))
|
||||
|
||||
#endif // IGUARD_util_compat_h
|
||||
|
|
|
@ -64,6 +64,7 @@ static zip_int64_t vfs_zipfile_srcfunc(void *userdata, void *data, zip_uint64_t
|
|||
}
|
||||
|
||||
case ZIP_SOURCE_READ: {
|
||||
assume(tls->stream != NULL);
|
||||
ret = SDL_RWread(tls->stream, data, 1, len);
|
||||
|
||||
if(!ret) {
|
||||
|
@ -78,6 +79,8 @@ static zip_int64_t vfs_zipfile_srcfunc(void *userdata, void *data, zip_uint64_t
|
|||
case ZIP_SOURCE_SEEK: {
|
||||
struct zip_source_args_seek *s;
|
||||
s = ZIP_SOURCE_GET_ARGS(struct zip_source_args_seek, data, len, &tls->error);
|
||||
|
||||
assume(tls->stream != NULL);
|
||||
ret = SDL_RWseek(tls->stream, s->offset, s->whence);
|
||||
|
||||
if(ret < 0) {
|
||||
|
@ -89,6 +92,7 @@ static zip_int64_t vfs_zipfile_srcfunc(void *userdata, void *data, zip_uint64_t
|
|||
}
|
||||
|
||||
case ZIP_SOURCE_TELL: {
|
||||
assume(tls->stream != NULL);
|
||||
ret = SDL_RWtell(tls->stream);
|
||||
|
||||
if(ret < 0) {
|
||||
|
|
Loading…
Reference in a new issue