From de3e931df7abdc3ee22dbb7543e86af6d00ee899 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?= Date: Wed, 24 Jun 2020 16:23:59 +0900 Subject: [PATCH] add UNREACHABLE_RETURN Not every compilers understand that rb_raise does not return. When a function does not end with a return statement, such compilers can issue warnings. We would better tell them about reachabilities. --- error.c | 1 + file.c | 1 + io.c | 2 ++ numeric.c | 1 + object.c | 7 ++++++- proc.c | 2 ++ process.c | 1 + range.c | 2 ++ signal.c | 1 + string.c | 2 ++ thread.c | 1 + time.c | 1 + variable.c | 2 ++ vm_eval.c | 1 + 14 files changed, 24 insertions(+), 1 deletion(-) diff --git a/error.c b/error.c index 5cb808fb44..ce936ac568 100644 --- a/error.c +++ b/error.c @@ -930,6 +930,7 @@ rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type) const char *expected = data_type->wrap_struct_name; rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected %s)", actual, expected); + UNREACHABLE_RETURN(NULL); } /* exception classes */ diff --git a/file.c b/file.c index ccfb3c1850..f9237b042a 100644 --- a/file.c +++ b/file.c @@ -5433,6 +5433,7 @@ rb_f_test(int argc, VALUE *argv, VALUE _) else { rb_raise(rb_eArgError, "unknown command \"\\x%02X\"", cmd); } + UNREACHABLE_RETURN(Qundef); } diff --git a/io.c b/io.c index 36099d89ad..21bf79796a 100644 --- a/io.c +++ b/io.c @@ -4199,6 +4199,7 @@ rb_io_each_codepoint(VALUE io) invalid: rb_raise(rb_eArgError, "invalid byte sequence in %s", rb_enc_name(enc)); + UNREACHABLE_RETURN(Qundef); } /* @@ -5578,6 +5579,7 @@ rb_io_modestr_fmode(const char *modestr) error: rb_raise(rb_eArgError, "invalid access mode %s", modestr); + UNREACHABLE_RETURN(Qundef); } int diff --git a/numeric.c b/numeric.c index f0c45fa6ce..b883b30440 100644 --- a/numeric.c +++ b/numeric.c @@ -4013,6 +4013,7 @@ fix_pow_inverted(VALUE x, VALUE minusb) { if (x == INT2FIX(0)) { rb_num_zerodiv(); + UNREACHABLE_RETURN(Qundef); } else { VALUE y = rb_int_pow(x, minusb); diff --git a/object.c b/object.c index fd7d02ba0d..c4a0d3c7ee 100644 --- a/object.c +++ b/object.c @@ -2574,6 +2574,7 @@ rb_mod_const_get(int argc, VALUE *argv, VALUE mod) wrong_name: rb_name_err_raise(wrong_constant_name, mod, name); + UNREACHABLE_RETURN(Qundef); } /* @@ -2752,6 +2753,7 @@ rb_mod_const_defined(int argc, VALUE *argv, VALUE mod) wrong_name: rb_name_err_raise(wrong_constant_name, mod, name); + UNREACHABLE_RETURN(Qundef); } /* @@ -2904,6 +2906,7 @@ rb_mod_const_source_location(int argc, VALUE *argv, VALUE mod) wrong_name: rb_name_err_raise(wrong_constant_name, mod, name); + UNREACHABLE_RETURN(Qundef); } /* @@ -3607,8 +3610,10 @@ rb_cstr_to_dbl_raise(const char *p, int badcheck, int raise, int *error) return d; bad: - if (raise) + if (raise) { rb_invalid_str(q, "Float()"); + UNREACHABLE_RETURN(nan("")); + } else { if (error) *error = 1; return 0.0; diff --git a/proc.c b/proc.c index 27806306ab..eb3e4bb73e 100644 --- a/proc.c +++ b/proc.c @@ -549,6 +549,7 @@ bind_local_variable_get(VALUE bindval, VALUE sym) undefined: rb_name_err_raise("local variable `%1$s' is not defined for %2$s", bindval, sym); + UNREACHABLE_RETURN(Qundef); } /* @@ -2021,6 +2022,7 @@ rb_obj_singleton_method(VALUE obj, VALUE vid) /* undef: */ rb_name_err_raise("undefined singleton method `%1$s' for `%2$s'", obj, vid); + UNREACHABLE_RETURN(Qundef); } /* diff --git a/process.c b/process.c index a0b8467879..cd53030e9e 100644 --- a/process.c +++ b/process.c @@ -1900,6 +1900,7 @@ check_exec_redirect_fd(VALUE v, int iskey) wrong: rb_raise(rb_eArgError, "wrong exec redirect"); + UNREACHABLE_RETURN(Qundef); } static VALUE diff --git a/range.c b/range.c index b00800b3fb..1903b0c1f8 100644 --- a/range.c +++ b/range.c @@ -836,6 +836,7 @@ range_each_bignum_endless(VALUE beg) for (;; beg = rb_big_plus(beg, INT2FIX(1))) { rb_yield(beg); } + UNREACHABLE; } RBIMPL_ATTR_NORETURN() @@ -847,6 +848,7 @@ range_each_fixnum_endless(VALUE beg) } range_each_bignum_endless(LONG2NUM(RUBY_FIXNUM_MAX + 1)); + UNREACHABLE; } static VALUE diff --git a/signal.c b/signal.c index d479ca90dc..daf0123d4f 100644 --- a/signal.c +++ b/signal.c @@ -274,6 +274,7 @@ signm2signo(VALUE *sig_ptr, int negative, int exit, int *prefix_ptr) } rb_raise(rb_eArgError, "unsupported signal `%.*s%"PRIsVALUE"'", prefix, signame_prefix, vsig); + UNREACHABLE_RETURN(0); } static const char* diff --git a/string.c b/string.c index 903222e0e4..8bcc6bb9c8 100644 --- a/string.c +++ b/string.c @@ -3015,6 +3015,7 @@ rb_enc_cr_str_buf_cat(VALUE str, const char *ptr, long len, incompatible: rb_raise(rb_eEncCompatError, "incompatible character encodings: %s and %s", rb_enc_name(str_enc), rb_enc_name(ptr_enc)); + UNREACHABLE_RETURN(Qundef); } VALUE @@ -9679,6 +9680,7 @@ rb_str_crypt(VALUE str, VALUE salt) short_salt: rb_raise(rb_eArgError, "salt too short (need >=2 bytes)"); + UNREACHABLE_RETURN(Qundef); } diff --git a/thread.c b/thread.c index 33377359d1..e463b72a41 100644 --- a/thread.c +++ b/thread.c @@ -5175,6 +5175,7 @@ exec_recursive(VALUE (*func) (VALUE, VALUE, int), VALUE obj, VALUE pairid, VALUE rb_raise(rb_eTypeError, "invalid inspect_tbl pair_list " "for %+"PRIsVALUE" in %+"PRIsVALUE, sym, rb_thread_current()); + UNREACHABLE_RETURN(Qundef); } /* diff --git a/time.c b/time.c index 457fac9748..ca571c80cd 100644 --- a/time.c +++ b/time.c @@ -5434,6 +5434,7 @@ end_submicro: ; invalid_format: rb_raise(rb_eTypeError, "marshaled time format differ"); + UNREACHABLE_RETURN(Qundef); } /* :nodoc: */ diff --git a/variable.c b/variable.c index 362ccddc13..4d62361fd0 100644 --- a/variable.c +++ b/variable.c @@ -277,6 +277,7 @@ rb_path_to_class(VALUE pathname) undefined_class: rb_raise(rb_eArgError, "undefined class/module % "PRIsVALUE, rb_str_subseq(pathname, 0, p-path)); + UNREACHABLE_RETURN(Qundef); } VALUE @@ -3347,6 +3348,7 @@ rb_mod_remove_cvar(VALUE mod, VALUE name) not_defined: rb_name_err_raise("class variable %1$s not defined for %2$s", mod, name); + UNREACHABLE_RETURN(Qundef); } VALUE diff --git a/vm_eval.c b/vm_eval.c index 98352ba545..db63dcda62 100644 --- a/vm_eval.c +++ b/vm_eval.c @@ -846,6 +846,7 @@ method_missing(VALUE obj, ID id, int argc, const VALUE *argv, enum method_missin return result; missing: raise_method_missing(ec, argc, argv, obj, call_status | MISSING_MISSING); + UNREACHABLE_RETURN(Qundef); } #ifndef MJIT_HEADER