From 573eef7c897ff938539270e605445da13093d664 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 12 Aug 2021 10:30:42 +0900 Subject: 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. --- include/ruby/internal/value_type.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/include/ruby/internal/value_type.h b/include/ruby/internal/value_type.h index 52b284cb4a..1b4c651719 100644 --- a/include/ruby/internal/value_type.h +++ b/include/ruby/internal/value_type.h @@ -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 */ -- cgit v1.2.3