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

@ -734,7 +734,7 @@
(printf "#define RET_NOTHING { SET_GC_VARIABLE_STACK((void **)__gc_var_stack__[0]); return; }\n")
;; A non-value return inserted at the end of a void-returning function:
(printf "#define RET_NOTHING_AT_END { SET_GC_VARIABLE_STACK((void **)__gc_var_stack__[0]); }\n")
;; Declare a temp variable to hold the return value of the indicated type:
(printf (if callee-restore?
"#define DECL_RET_SAVE(type) type __ret__val__;\n"

View File

@ -252,11 +252,25 @@ extern "C"
{
#endif
#if defined(MZ_DECLARE_NORETURN) && defined(__GNUC__)
#define NORETURN __attribute__((__noreturn__))
#if !defined(NORETURN)
#if defined(__GNUC__) || defined(__clang__)
#define NORETURN __attribute__((noreturn))
#elif defined(_MSC_VER)
#define NORETURN __declspec(noreturn)
#else
#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: */
#define MZ_CAN_ACCESS_THREAD_LOCAL_DIRECTLY
@ -1670,7 +1684,7 @@ MZ_EXTERN Scheme_Object *scheme_eval_waiting;
#endif
#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);
# define scheme_jit_setjmp(b) (scheme_jit_setjmp_prepare(b), scheme_call_mz_setjmp((b)->jb))
#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_context_length(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 *emergency_error_display_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 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);
@ -227,7 +227,7 @@ Scheme_Config *scheme_init_error_escape_proc(Scheme_Config *config)
if (!def_error_esc_proc) {
REGISTER_SO(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",
0, 0);
}
@ -926,7 +926,7 @@ void scheme_init_logger_config() {
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)
{
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);
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),
"nested-exception-handler",
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_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),
"nested-exception-handler",
1, 1);
@ -3346,9 +3346,9 @@ def_error_value_string_proc(int argc, Scheme_Object *argv[])
return scheme_make_sized_utf8_string(s, l);
}
static Scheme_Object *
static NORETURN void
def_error_escape_proc(int argc, Scheme_Object *argv[])
{
{
Scheme_Object *prompt;
Scheme_Thread *p = scheme_current_thread;
@ -3361,8 +3361,6 @@ def_error_escape_proc(int argc, Scheme_Object *argv[])
p->cjs.val = scheme_void_proc;
}
scheme_longjmp(scheme_error_buf, 1);
return scheme_void; /* Never get here */
}
static Scheme_Object *
@ -4405,7 +4403,7 @@ scheme_raise_exn(int id, ...)
1);
}
static Scheme_Object *
static NORETURN void
def_exn_handler(int argc, Scheme_Object *argv[])
{
char *s;
@ -4432,8 +4430,6 @@ def_exn_handler(int argc, Scheme_Object *argv[])
}
call_error(s, len, argv[0]);
return scheme_void;
}
static Scheme_Object *
@ -4445,7 +4441,7 @@ init_exn_handler(int argc, Scheme_Object *argv[])
1, NULL, NULL, 0);
}
static Scheme_Object *
static NORETURN void
nested_exn_handler(void *old_exn, int argc, Scheme_Object *argv[])
{
Scheme_Object *arg = argv[0], *orig_arg = SCHEME_CDR((Scheme_Object *)old_exn);
@ -4496,13 +4492,11 @@ nested_exn_handler(void *old_exn, int argc, Scheme_Object *argv[])
msg, mlen,
orig_raisetype,
orig_msg, orig_mlen);
call_error(buffer, blen, scheme_false);
return scheme_void;
call_error(buffer, blen, scheme_false);
}
static void *do_raise_inside_barrier(void)
static NORETURN void *do_raise_inside_barrier(void)
{
Scheme_Object *arg;
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_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),
"nested-exception-handler",
1, 1);
@ -4570,11 +4564,9 @@ static void *do_raise_inside_barrier(void)
} else {
/* return from uncaught-exception handler */
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
@ -4612,13 +4604,15 @@ do_raise(Scheme_Object *arg, int need_debug, int eb)
p->ku.k.p1 = arg;
if (eb)
if (eb) {
scheme_top_level_do(do_raise_inside_barrier, 1);
UNREACHABLE;
}
else
do_raise_inside_barrier();
}
static void
static NORETURN void
sch_raise(int argc, Scheme_Object *argv[])
{
if ((argc > 1) && SCHEME_FALSEP(argv[1]))
@ -4781,7 +4775,7 @@ void scheme_init_exn_config(void)
{
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);
}

View File

@ -62,6 +62,7 @@
[l (regexp-replace #rx"^XFORM_NONGCING " l "")]
[l (regexp-replace #rx"^XFORM_NONGCING_NONALIASING " l "")]
[l (regexp-replace #rx"^MZ_EXTERN " l "")]
[l (regexp-replace #rx"^NORETURN " l "")]
[l (regexp-replace #rx"^THREAD_LOCAL " l "")]
[l2 (regexp-replace #rx"^volatile " l "")]
[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 */
/*========================================================================*/
MZ_EXTERN void scheme_signal_error(const char *msg, ...) NORETURN;
MZ_EXTERN void scheme_raise_exn(int exnid, ...) NORETURN;
MZ_EXTERN NORETURN void scheme_signal_error(const char *msg, ...);
MZ_EXTERN NORETURN void scheme_raise_exn(int exnid, ...);
MZ_EXTERN void scheme_warning(char *msg, ...);
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_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 void scheme_wrong_count_m(const char *name, int minc, int maxc, int argc, Scheme_Object **argv, int is_method) NORETURN;
MZ_EXTERN void scheme_case_lambda_wrong_count(const char *name, int argc, Scheme_Object **argv, int is_method, int count, ...) NORETURN;
MZ_EXTERN void scheme_wrong_type(const char *name, const char *expected, int which, int argc, Scheme_Object **argv) NORETURN;
MZ_EXTERN void scheme_wrong_contract(const char *name, const char *expected, int which, int argc, Scheme_Object **argv) NORETURN;
MZ_EXTERN void scheme_wrong_field_type(Scheme_Object *c_name, const char *expected, Scheme_Object *o) NORETURN;
MZ_EXTERN void scheme_wrong_field_contract(Scheme_Object *c_name, const char *expected, Scheme_Object *o) NORETURN;
MZ_EXTERN void scheme_arg_mismatch(const char *name, const char *msg, Scheme_Object *o) NORETURN;
MZ_EXTERN void scheme_contract_error(const char *name, const char *msg, ...) NORETURN;
MZ_EXTERN void scheme_wrong_return_arity(const char *where, int expected, int got, Scheme_Object **argv, const char *context_detail, ...) NORETURN;
MZ_EXTERN void scheme_unbound_global(Scheme_Bucket *b) NORETURN;
MZ_EXTERN NORETURN void scheme_wrong_count(const char *name, int minc, int maxc, int argc, Scheme_Object **argv);
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 NORETURN void scheme_case_lambda_wrong_count(const char *name, int argc, Scheme_Object **argv, int is_method, int count, ...);
MZ_EXTERN NORETURN void scheme_wrong_type(const char *name, const char *expected, int which, int argc, Scheme_Object **argv);
MZ_EXTERN NORETURN void scheme_wrong_contract(const char *name, const char *expected, int which, int argc, Scheme_Object **argv);
MZ_EXTERN NORETURN void scheme_wrong_field_type(Scheme_Object *c_name, const char *expected, Scheme_Object *o);
MZ_EXTERN NORETURN void scheme_wrong_field_contract(Scheme_Object *c_name, const char *expected, Scheme_Object *o);
MZ_EXTERN NORETURN void scheme_arg_mismatch(const char *name, const char *msg, Scheme_Object *o);
MZ_EXTERN NORETURN void scheme_contract_error(const char *name, const char *msg, ...);
MZ_EXTERN NORETURN void scheme_wrong_return_arity(const char *where, int expected, int got, Scheme_Object **argv, const char *context_detail, ...);
MZ_EXTERN NORETURN void scheme_unbound_global(Scheme_Bucket *b);
MZ_EXTERN Scheme_Object *scheme_dynamic_wind(void (*pre)(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 */
/*========================================================================*/
void (*scheme_signal_error)(const char *msg, ...) NORETURN;
void (*scheme_raise_exn)(int exnid, ...) NORETURN;
void (*scheme_signal_error)(const char *msg, ...);
void (*scheme_raise_exn)(int exnid, ...);
void (*scheme_warning)(char *msg, ...);
void (*scheme_raise)(Scheme_Object *exn);
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_test)(char *str);
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_m)(const char *name, int minc, int maxc, int argc, Scheme_Object **argv, int is_method) NORETURN;
void (*scheme_case_lambda_wrong_count)(const char *name, int argc, Scheme_Object **argv, int is_method, int count, ...) NORETURN;
void (*scheme_wrong_type)(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) NORETURN;
void (*scheme_wrong_field_type)(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) NORETURN;
void (*scheme_arg_mismatch)(const char *name, const char *msg, Scheme_Object *o) NORETURN;
void (*scheme_contract_error)(const char *name, const char *msg, ...) NORETURN;
void (*scheme_wrong_return_arity)(const char *where, int expected, int got, Scheme_Object **argv, const char *context_detail, ...) NORETURN;
void (*scheme_unbound_global)(Scheme_Bucket *b) 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);
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);
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);
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);
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, ...);
void (*scheme_unbound_global)(Scheme_Bucket *b);
Scheme_Object *(*scheme_dynamic_wind)(void (*pre)(void *),
Scheme_Object *(* volatile act)(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_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);