Proper cross-platform no return annotations for error functions (#2709)

Ensures proper noreturn annotations for error functions. Implemented
cross-platform unreachable annotation. No warnings in tested clang or
gcc with default flags. Tested as well on MacOS and Windows.
This commit is contained in:
Paulo Matos 2019-07-03 08:31:18 +02:00 committed by GitHub
parent 0ffb16bce3
commit e26d2e11d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 66 additions and 57 deletions

View File

@ -252,11 +252,25 @@ extern "C"
{ {
#endif #endif
#if defined(MZ_DECLARE_NORETURN) && defined(__GNUC__) #if !defined(NORETURN)
#define NORETURN __attribute__((__noreturn__)) #if defined(__GNUC__) || defined(__clang__)
#define NORETURN __attribute__((noreturn))
#elif defined(_MSC_VER)
#define NORETURN __declspec(noreturn)
#else #else
#define NORETURN #define NORETURN
#endif #endif /* defined(__GNUC__) || defined(__clang__) */
#endif /* !defined(NORETURN) */
#if !defined(UNREACHABLE)
#if defined(__GNUC__) || defined(__clang__)
#define UNREACHABLE __builtin_unreachable()
#elif defined(_MSC_VER)
#define UNREACHABLE __assume(0)
#else
#define UNREACHABLE
#endif /* defined(__GNUC__) || defined(__clang__) */
#endif /* !defined(NORETURN) */
/* Allowed by all configurations, currently: */ /* Allowed by all configurations, currently: */
#define MZ_CAN_ACCESS_THREAD_LOCAL_DIRECTLY #define MZ_CAN_ACCESS_THREAD_LOCAL_DIRECTLY
@ -1670,7 +1684,7 @@ MZ_EXTERN Scheme_Object *scheme_eval_waiting;
#endif #endif
#ifdef MZ_USE_JIT #ifdef MZ_USE_JIT
MZ_EXTERN void scheme_jit_longjmp(mz_jit_jmp_buf b, int v); MZ_EXTERN NORETURN void scheme_jit_longjmp(mz_jit_jmp_buf b, int v);
MZ_EXTERN void scheme_jit_setjmp_prepare(mz_jit_jmp_buf b); MZ_EXTERN void scheme_jit_setjmp_prepare(mz_jit_jmp_buf b);
# define scheme_jit_setjmp(b) (scheme_jit_setjmp_prepare(b), scheme_call_mz_setjmp((b)->jb)) # define scheme_jit_setjmp(b) (scheme_jit_setjmp_prepare(b), scheme_call_mz_setjmp((b)->jb))
#else #else

View File

@ -90,7 +90,7 @@ static Scheme_Object *exe_yield_handler(int, Scheme_Object *[]);
static Scheme_Object *error_print_width(int, Scheme_Object *[]); static Scheme_Object *error_print_width(int, Scheme_Object *[]);
static Scheme_Object *error_print_context_length(int, Scheme_Object *[]); static Scheme_Object *error_print_context_length(int, Scheme_Object *[]);
static Scheme_Object *error_print_srcloc(int, Scheme_Object *[]); static Scheme_Object *error_print_srcloc(int, Scheme_Object *[]);
static Scheme_Object *def_error_escape_proc(int, Scheme_Object *[]); static NORETURN void def_error_escape_proc(int, Scheme_Object *[]);
static Scheme_Object *def_error_display_proc(int, Scheme_Object *[]); static Scheme_Object *def_error_display_proc(int, Scheme_Object *[]);
static Scheme_Object *emergency_error_display_proc(int, Scheme_Object *[]); static Scheme_Object *emergency_error_display_proc(int, Scheme_Object *[]);
static Scheme_Object *def_error_value_string_proc(int, Scheme_Object *[]); static Scheme_Object *def_error_value_string_proc(int, Scheme_Object *[]);
@ -115,7 +115,7 @@ static Scheme_Object *log_reader_p(int argc, Scheme_Object *argv[]);
static int log_reader_get(Scheme_Object *ch, Scheme_Schedule_Info *sinfo); static int log_reader_get(Scheme_Object *ch, Scheme_Schedule_Info *sinfo);
static NORETURN void do_raise(Scheme_Object *arg, int need_debug, int barrier); static NORETURN void do_raise(Scheme_Object *arg, int need_debug, int barrier);
static Scheme_Object *nested_exn_handler(void *old_exn, int argc, Scheme_Object *argv[]); static NORETURN void nested_exn_handler(void *old_exn, int argc, Scheme_Object *argv[]);
static void update_want_level(Scheme_Logger *logger, Scheme_Object *name); static void update_want_level(Scheme_Logger *logger, Scheme_Object *name);
@ -227,7 +227,7 @@ Scheme_Config *scheme_init_error_escape_proc(Scheme_Config *config)
if (!def_error_esc_proc) { if (!def_error_esc_proc) {
REGISTER_SO(def_error_esc_proc); REGISTER_SO(def_error_esc_proc);
def_error_esc_proc = def_error_esc_proc =
scheme_make_prim_w_arity(def_error_escape_proc, scheme_make_prim_w_arity((Scheme_Prim *)def_error_escape_proc,
"default-error-escape-handler", "default-error-escape-handler",
0, 0); 0, 0);
} }
@ -926,7 +926,7 @@ void scheme_init_logger_config() {
scheme_set_root_param(MZCONFIG_LOGGER, (Scheme_Object *)scheme_main_logger); scheme_set_root_param(MZCONFIG_LOGGER, (Scheme_Object *)scheme_main_logger);
} }
static void static NORETURN void
call_error(char *buffer, int len, Scheme_Object *exn) call_error(char *buffer, int len, Scheme_Object *exn)
{ {
if (scheme_current_thread->constant_folding) { if (scheme_current_thread->constant_folding) {
@ -960,7 +960,7 @@ call_error(char *buffer, int len, Scheme_Object *exn)
escape_handler = scheme_get_param(orig_config, MZCONFIG_ERROR_ESCAPE_HANDLER); escape_handler = scheme_get_param(orig_config, MZCONFIG_ERROR_ESCAPE_HANDLER);
v = scheme_make_byte_string_without_copying("error display handler"); v = scheme_make_byte_string_without_copying("error display handler");
v = scheme_make_closed_prim_w_arity(nested_exn_handler, v = scheme_make_closed_prim_w_arity((Scheme_Closed_Prim *)nested_exn_handler,
scheme_make_pair(v, exn), scheme_make_pair(v, exn),
"nested-exception-handler", "nested-exception-handler",
1, 1); 1, 1);
@ -1000,7 +1000,7 @@ call_error(char *buffer, int len, Scheme_Object *exn)
} }
v = scheme_make_byte_string_without_copying("error escape handler"); v = scheme_make_byte_string_without_copying("error escape handler");
v = scheme_make_closed_prim_w_arity(nested_exn_handler, v = scheme_make_closed_prim_w_arity((Scheme_Closed_Prim *)nested_exn_handler,
scheme_make_pair(v, exn), scheme_make_pair(v, exn),
"nested-exception-handler", "nested-exception-handler",
1, 1); 1, 1);
@ -3346,7 +3346,7 @@ def_error_value_string_proc(int argc, Scheme_Object *argv[])
return scheme_make_sized_utf8_string(s, l); return scheme_make_sized_utf8_string(s, l);
} }
static Scheme_Object * static NORETURN void
def_error_escape_proc(int argc, Scheme_Object *argv[]) def_error_escape_proc(int argc, Scheme_Object *argv[])
{ {
Scheme_Object *prompt; Scheme_Object *prompt;
@ -3361,8 +3361,6 @@ def_error_escape_proc(int argc, Scheme_Object *argv[])
p->cjs.val = scheme_void_proc; p->cjs.val = scheme_void_proc;
} }
scheme_longjmp(scheme_error_buf, 1); scheme_longjmp(scheme_error_buf, 1);
return scheme_void; /* Never get here */
} }
static Scheme_Object * static Scheme_Object *
@ -4405,7 +4403,7 @@ scheme_raise_exn(int id, ...)
1); 1);
} }
static Scheme_Object * static NORETURN void
def_exn_handler(int argc, Scheme_Object *argv[]) def_exn_handler(int argc, Scheme_Object *argv[])
{ {
char *s; char *s;
@ -4432,8 +4430,6 @@ def_exn_handler(int argc, Scheme_Object *argv[])
} }
call_error(s, len, argv[0]); call_error(s, len, argv[0]);
return scheme_void;
} }
static Scheme_Object * static Scheme_Object *
@ -4445,7 +4441,7 @@ init_exn_handler(int argc, Scheme_Object *argv[])
1, NULL, NULL, 0); 1, NULL, NULL, 0);
} }
static Scheme_Object * static NORETURN void
nested_exn_handler(void *old_exn, int argc, Scheme_Object *argv[]) nested_exn_handler(void *old_exn, int argc, Scheme_Object *argv[])
{ {
Scheme_Object *arg = argv[0], *orig_arg = SCHEME_CDR((Scheme_Object *)old_exn); Scheme_Object *arg = argv[0], *orig_arg = SCHEME_CDR((Scheme_Object *)old_exn);
@ -4498,11 +4494,9 @@ nested_exn_handler(void *old_exn, int argc, Scheme_Object *argv[])
orig_msg, orig_mlen); orig_msg, orig_mlen);
call_error(buffer, blen, scheme_false); call_error(buffer, blen, scheme_false);
return scheme_void;
} }
static void *do_raise_inside_barrier(void) static NORETURN void *do_raise_inside_barrier(void)
{ {
Scheme_Object *arg; Scheme_Object *arg;
Scheme_Object *v, *p[1], *h, *marks; Scheme_Object *v, *p[1], *h, *marks;
@ -4526,7 +4520,7 @@ static void *do_raise_inside_barrier(void)
} }
v = scheme_make_byte_string_without_copying("exception handler"); v = scheme_make_byte_string_without_copying("exception handler");
v = scheme_make_closed_prim_w_arity(nested_exn_handler, v = scheme_make_closed_prim_w_arity((Scheme_Closed_Prim *)nested_exn_handler,
scheme_make_pair(v, arg), scheme_make_pair(v, arg),
"nested-exception-handler", "nested-exception-handler",
1, 1); 1, 1);
@ -4570,11 +4564,9 @@ static void *do_raise_inside_barrier(void)
} else { } else {
/* return from uncaught-exception handler */ /* return from uncaught-exception handler */
p[0] = scheme_false; p[0] = scheme_false;
return nested_exn_handler(scheme_make_pair(scheme_false, arg), 1, p); nested_exn_handler(scheme_make_pair(scheme_false, arg), 1, p);
} }
} }
return scheme_void;
} }
static void static void
@ -4612,13 +4604,15 @@ do_raise(Scheme_Object *arg, int need_debug, int eb)
p->ku.k.p1 = arg; p->ku.k.p1 = arg;
if (eb) if (eb) {
scheme_top_level_do(do_raise_inside_barrier, 1); scheme_top_level_do(do_raise_inside_barrier, 1);
UNREACHABLE;
}
else else
do_raise_inside_barrier(); do_raise_inside_barrier();
} }
static void static NORETURN void
sch_raise(int argc, Scheme_Object *argv[]) sch_raise(int argc, Scheme_Object *argv[])
{ {
if ((argc > 1) && SCHEME_FALSEP(argv[1])) if ((argc > 1) && SCHEME_FALSEP(argv[1]))
@ -4781,7 +4775,7 @@ void scheme_init_exn_config(void)
{ {
Scheme_Object *h; Scheme_Object *h;
h = scheme_make_prim_w_arity(def_exn_handler, "default-exception-handler", 1, 1); h = scheme_make_prim_w_arity((Scheme_Prim *)def_exn_handler, "default-exception-handler", 1, 1);
scheme_set_root_param(MZCONFIG_INIT_EXN_HANDLER, h); scheme_set_root_param(MZCONFIG_INIT_EXN_HANDLER, h);
} }

View File

@ -62,6 +62,7 @@
[l (regexp-replace #rx"^XFORM_NONGCING " l "")] [l (regexp-replace #rx"^XFORM_NONGCING " l "")]
[l (regexp-replace #rx"^XFORM_NONGCING_NONALIASING " l "")] [l (regexp-replace #rx"^XFORM_NONGCING_NONALIASING " l "")]
[l (regexp-replace #rx"^MZ_EXTERN " l "")] [l (regexp-replace #rx"^MZ_EXTERN " l "")]
[l (regexp-replace #rx"^NORETURN " l "")]
[l (regexp-replace #rx"^THREAD_LOCAL " l "")] [l (regexp-replace #rx"^THREAD_LOCAL " l "")]
[l2 (regexp-replace #rx"^volatile " l "")] [l2 (regexp-replace #rx"^volatile " l "")]
[volatile (if (equal? l l2) "" "volatile ")] [volatile (if (equal? l l2) "" "volatile ")]

View File

@ -197,8 +197,8 @@ MZ_EXTERN Scheme_On_Atomic_Timeout_Proc scheme_set_on_atomic_timeout(Scheme_On_A
/* error handling */ /* error handling */
/*========================================================================*/ /*========================================================================*/
MZ_EXTERN void scheme_signal_error(const char *msg, ...) NORETURN; MZ_EXTERN NORETURN void scheme_signal_error(const char *msg, ...);
MZ_EXTERN void scheme_raise_exn(int exnid, ...) NORETURN; MZ_EXTERN NORETURN void scheme_raise_exn(int exnid, ...);
MZ_EXTERN void scheme_warning(char *msg, ...); MZ_EXTERN void scheme_warning(char *msg, ...);
MZ_EXTERN void scheme_raise(Scheme_Object *exn); MZ_EXTERN void scheme_raise(Scheme_Object *exn);
@ -221,17 +221,17 @@ MZ_EXTERN void scheme_glib_log_message(const char *log_domain, int log_level, co
MZ_EXTERN void *scheme_glib_log_message_test(char *str); MZ_EXTERN void *scheme_glib_log_message_test(char *str);
MZ_EXTERN void scheme_out_of_memory_abort(); MZ_EXTERN void scheme_out_of_memory_abort();
MZ_EXTERN void scheme_wrong_count(const char *name, int minc, int maxc, int argc, Scheme_Object **argv) NORETURN; MZ_EXTERN NORETURN void scheme_wrong_count(const char *name, int minc, int maxc, int argc, Scheme_Object **argv);
MZ_EXTERN void scheme_wrong_count_m(const char *name, int minc, int maxc, int argc, Scheme_Object **argv, int is_method) NORETURN; MZ_EXTERN NORETURN void scheme_wrong_count_m(const char *name, int minc, int maxc, int argc, Scheme_Object **argv, int is_method);
MZ_EXTERN void scheme_case_lambda_wrong_count(const char *name, int argc, Scheme_Object **argv, int is_method, int count, ...) NORETURN; MZ_EXTERN NORETURN void scheme_case_lambda_wrong_count(const char *name, int argc, Scheme_Object **argv, int is_method, int count, ...);
MZ_EXTERN void scheme_wrong_type(const char *name, const char *expected, int which, int argc, Scheme_Object **argv) NORETURN; MZ_EXTERN NORETURN void scheme_wrong_type(const char *name, const char *expected, int which, int argc, Scheme_Object **argv);
MZ_EXTERN void scheme_wrong_contract(const char *name, const char *expected, int which, int argc, Scheme_Object **argv) NORETURN; MZ_EXTERN NORETURN void scheme_wrong_contract(const char *name, const char *expected, int which, int argc, Scheme_Object **argv);
MZ_EXTERN void scheme_wrong_field_type(Scheme_Object *c_name, const char *expected, Scheme_Object *o) NORETURN; MZ_EXTERN NORETURN void scheme_wrong_field_type(Scheme_Object *c_name, const char *expected, Scheme_Object *o);
MZ_EXTERN void scheme_wrong_field_contract(Scheme_Object *c_name, const char *expected, Scheme_Object *o) NORETURN; MZ_EXTERN NORETURN void scheme_wrong_field_contract(Scheme_Object *c_name, const char *expected, Scheme_Object *o);
MZ_EXTERN void scheme_arg_mismatch(const char *name, const char *msg, Scheme_Object *o) NORETURN; MZ_EXTERN NORETURN void scheme_arg_mismatch(const char *name, const char *msg, Scheme_Object *o);
MZ_EXTERN void scheme_contract_error(const char *name, const char *msg, ...) NORETURN; MZ_EXTERN NORETURN void scheme_contract_error(const char *name, const char *msg, ...);
MZ_EXTERN void scheme_wrong_return_arity(const char *where, int expected, int got, Scheme_Object **argv, const char *context_detail, ...) NORETURN; MZ_EXTERN NORETURN void scheme_wrong_return_arity(const char *where, int expected, int got, Scheme_Object **argv, const char *context_detail, ...);
MZ_EXTERN void scheme_unbound_global(Scheme_Bucket *b) NORETURN; MZ_EXTERN NORETURN void scheme_unbound_global(Scheme_Bucket *b);
MZ_EXTERN Scheme_Object *scheme_dynamic_wind(void (*pre)(void *), MZ_EXTERN Scheme_Object *scheme_dynamic_wind(void (*pre)(void *),
Scheme_Object *(* volatile act)(void *), Scheme_Object *(* volatile act)(void *),

View File

@ -138,8 +138,8 @@ Scheme_On_Atomic_Timeout_Proc (*scheme_set_on_atomic_timeout)(Scheme_On_Atomic_T
/*========================================================================*/ /*========================================================================*/
/* error handling */ /* error handling */
/*========================================================================*/ /*========================================================================*/
void (*scheme_signal_error)(const char *msg, ...) NORETURN; void (*scheme_signal_error)(const char *msg, ...);
void (*scheme_raise_exn)(int exnid, ...) NORETURN; void (*scheme_raise_exn)(int exnid, ...);
void (*scheme_warning)(char *msg, ...); void (*scheme_warning)(char *msg, ...);
void (*scheme_raise)(Scheme_Object *exn); void (*scheme_raise)(Scheme_Object *exn);
int (*scheme_log_level_p)(Scheme_Logger *logger, int level); int (*scheme_log_level_p)(Scheme_Logger *logger, int level);
@ -159,17 +159,17 @@ void (*scheme_log_warning)(char *buffer);
void (*scheme_glib_log_message)(const char *log_domain, int log_level, const char *message, void *user_data); void (*scheme_glib_log_message)(const char *log_domain, int log_level, const char *message, void *user_data);
void *(*scheme_glib_log_message_test)(char *str); void *(*scheme_glib_log_message_test)(char *str);
void (*scheme_out_of_memory_abort)(); void (*scheme_out_of_memory_abort)();
void (*scheme_wrong_count)(const char *name, int minc, int maxc, int argc, Scheme_Object **argv) NORETURN; void (*scheme_wrong_count)(const char *name, int minc, int maxc, int argc, Scheme_Object **argv);
void (*scheme_wrong_count_m)(const char *name, int minc, int maxc, int argc, Scheme_Object **argv, int is_method) NORETURN; void (*scheme_wrong_count_m)(const char *name, int minc, int maxc, int argc, Scheme_Object **argv, int is_method);
void (*scheme_case_lambda_wrong_count)(const char *name, int argc, Scheme_Object **argv, int is_method, int count, ...) NORETURN; void (*scheme_case_lambda_wrong_count)(const char *name, int argc, Scheme_Object **argv, int is_method, int count, ...);
void (*scheme_wrong_type)(const char *name, const char *expected, int which, int argc, Scheme_Object **argv) NORETURN; void (*scheme_wrong_type)(const char *name, const char *expected, int which, int argc, Scheme_Object **argv);
void (*scheme_wrong_contract)(const char *name, const char *expected, int which, int argc, Scheme_Object **argv) NORETURN; void (*scheme_wrong_contract)(const char *name, const char *expected, int which, int argc, Scheme_Object **argv);
void (*scheme_wrong_field_type)(Scheme_Object *c_name, const char *expected, Scheme_Object *o) NORETURN; void (*scheme_wrong_field_type)(Scheme_Object *c_name, const char *expected, Scheme_Object *o);
void (*scheme_wrong_field_contract)(Scheme_Object *c_name, const char *expected, Scheme_Object *o) NORETURN; void (*scheme_wrong_field_contract)(Scheme_Object *c_name, const char *expected, Scheme_Object *o);
void (*scheme_arg_mismatch)(const char *name, const char *msg, Scheme_Object *o) NORETURN; void (*scheme_arg_mismatch)(const char *name, const char *msg, Scheme_Object *o);
void (*scheme_contract_error)(const char *name, const char *msg, ...) NORETURN; void (*scheme_contract_error)(const char *name, const char *msg, ...);
void (*scheme_wrong_return_arity)(const char *where, int expected, int got, Scheme_Object **argv, const char *context_detail, ...) NORETURN; void (*scheme_wrong_return_arity)(const char *where, int expected, int got, Scheme_Object **argv, const char *context_detail, ...);
void (*scheme_unbound_global)(Scheme_Bucket *b) NORETURN; void (*scheme_unbound_global)(Scheme_Bucket *b);
Scheme_Object *(*scheme_dynamic_wind)(void (*pre)(void *), Scheme_Object *(*scheme_dynamic_wind)(void (*pre)(void *),
Scheme_Object *(* volatile act)(void *), Scheme_Object *(* volatile act)(void *),
void (* volatile post)(void *), void (* volatile post)(void *),

View File

@ -3392,7 +3392,7 @@ void scheme_rktio_error(const char *name, const char *what);
void scheme_non_fixnum_result(const char *name, Scheme_Object *o); void scheme_non_fixnum_result(const char *name, Scheme_Object *o);
void scheme_raise_out_of_memory(const char *where, const char *msg, ...); NORETURN void scheme_raise_out_of_memory(const char *where, const char *msg, ...);
char *scheme_make_srcloc_string(Scheme_Object *stx, intptr_t *len); char *scheme_make_srcloc_string(Scheme_Object *stx, intptr_t *len);