diff options
| author | Rory OConnell <[email protected]> | 2020-06-29 14:25:59 -0700 |
|---|---|---|
| committer | Rory OConnell <[email protected]> | 2020-06-29 14:25:59 -0700 |
| commit | 3cf48713a2d39e624e9b755bfcfae6fb51a861c9 (patch) | |
| tree | 6c767dd06de89ca06f6690b0bd2d1200e5b9d004 /mrbgems/mruby-random | |
| parent | 6d5652114e2105b1e9d81b353b3c9335ca3b4dd5 (diff) | |
| download | mruby-3cf48713a2d39e624e9b755bfcfae6fb51a861c9.tar.gz mruby-3cf48713a2d39e624e9b755bfcfae6fb51a861c9.zip | |
Work around more MSC optimzer bugs
Diffstat (limited to 'mrbgems/mruby-random')
| -rw-r--r-- | mrbgems/mruby-random/src/random.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/mrbgems/mruby-random/src/random.c b/mrbgems/mruby-random/src/random.c index 55bea5713..10c81b946 100644 --- a/mrbgems/mruby-random/src/random.c +++ b/mrbgems/mruby-random/src/random.c @@ -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) { |
