Fix a lot of warnings with -O3 and 32bit builds

This commit is contained in:
Andrei Alexeyev 2019-02-02 13:25:06 +02:00
parent 9424ba1b4e
commit e959fbc5f7
No known key found for this signature in database
GPG key ID: 363707CD4C7FE8A4
12 changed files with 121 additions and 52 deletions

View file

@ -24,6 +24,7 @@ config = configuration_data()
taisei_c_args = cc.get_supported_arguments(
'-Wall',
'-Wpedantic',
'-Werror=assume',
'-Werror=implicit-function-declaration',
#

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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) {

View file

@ -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);
}

View file

@ -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) {

View file

@ -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);

View file

@ -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) {

View file

@ -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

View file

@ -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

View file

@ -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) {