Indicate the slow path of Check_Type never return [Bug #18062]

Though this call to `rb_check_type` is just to raise an exception
and never return actually, it can return at least formally.  That
means a caller function looks like it will access `flags` even in
the special-const cases, and some optimizers may unify the access
with the same access just following the call, and re-order it
before the guard.
This commit is contained in:
Nobuyoshi Nakada 2021-08-12 10:30:42 +09:00
parent 5534698b84
commit 573eef7c89
No known key found for this signature in database
GPG Key ID: 7CD2805BFA3770C6

View File

@ -30,6 +30,7 @@
#include "ruby/internal/constant_p.h"
#include "ruby/internal/core/rbasic.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/error.h"
#include "ruby/internal/has/builtin.h"
#include "ruby/internal/special_consts.h"
#include "ruby/internal/stdbool.h"
@ -156,6 +157,11 @@ RB_BUILTIN_TYPE(VALUE obj)
{
RBIMPL_ASSERT_OR_ASSUME(! RB_SPECIAL_CONST_P(obj));
#if 0 && defined __GNUC__ && !defined __clang__
/* Don't move the access to `flags` before the preceding
* RB_SPECIAL_CONST_P check. */
__asm volatile("": : :"memory");
#endif
VALUE ret = RBASIC(obj)->flags & RUBY_T_MASK;
return RBIMPL_CAST((enum ruby_value_type)ret);
}
@ -350,7 +356,7 @@ Check_Type(VALUE v, enum ruby_value_type t)
return;
slowpath: /* <- :TODO: mark this label as cold. */
rb_check_type(v, t);
rb_unexpected_type(v, t);
}
#endif /* RBIMPL_VALUE_TYPE_H */