summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-random/src/random.c
diff options
context:
space:
mode:
authorHiroshi Mimaki <[email protected]>2020-08-06 17:38:20 +0900
committerHiroshi Mimaki <[email protected]>2020-08-06 17:38:20 +0900
commit7f8d38bbbe89dadab9d296c76f094c56aabca9f4 (patch)
tree10c79fb00ab3378a34abba9b4ce1d01a1b7cefd6 /mrbgems/mruby-random/src/random.c
parent1a9bdfcde5fd7c91e756747ba0565f29385115a7 (diff)
parent11cc7bed96551fcceca5cabc1527fd944835a1a0 (diff)
downloadmruby-7f8d38bbbe89dadab9d296c76f094c56aabca9f4.tar.gz
mruby-7f8d38bbbe89dadab9d296c76f094c56aabca9f4.zip
Merge master.
Diffstat (limited to 'mrbgems/mruby-random/src/random.c')
-rw-r--r--mrbgems/mruby-random/src/random.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/mrbgems/mruby-random/src/random.c b/mrbgems/mruby-random/src/random.c
index 515c0707a..10c81b946 100644
--- a/mrbgems/mruby-random/src/random.c
+++ b/mrbgems/mruby-random/src/random.c
@@ -218,6 +218,34 @@ mrb_ary_shuffle_bang(mrb_state *mrb, mrb_value ary)
mrb_value r = mrb_nil_value();
rand_state *random;
+ /*
+ * MSC compiler bug generating invalid instructions with optimization
+ * enabled. MSC errantly uses a hardcoded value with optimizations on
+ * when using a fixed value from a union.
+ * Creating a temp volatile variable and reassigning back to the original
+ * value tricks the compiler to not perform this optimization;
+ */
+#if defined _MSC_VER && _MSC_VER >= 1923
+ /* C++ will not cast away volatile easily, so we cannot do something like
+ * volatile mrb_value rr = r; r = (mrb_value)rr; with C++.
+ * That cast does work with C.
+ * We also have to trick the compiler to not optimize away the const_cast entirely
+ * by creating and manipulating an intermediate volatile pointer.
+ */
+ volatile mrb_value *v_r;
+ volatile mrb_int ii;
+ mrb_value *p_r;
+ v_r = &r;
+ ii = 2;
+ v_r = v_r + 2;
+#if defined __cplusplus
+ p_r = const_cast<mrb_value*>(v_r - ii);
+#else
+ p_r = (mrb_value*)v_r - ii;
+#endif
+ r = *p_r;
+#endif
+
if (RARRAY_LEN(ary) > 1) {
mrb_get_args(mrb, "|o", &r);