Work around more MSC optimzer bugs
@@ -220,12 +220,30 @@ mrb_ary_shuffle_bang(mrb_state *mrb, mrb_value ary)
/*
* MSC compiler bug generating invalid instructions with optimization
- * enabled
+ * 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
- volatile mrb_value rr;
- rr = r;
- r = rr;
+ /* 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) {
