summaryrefslogtreecommitdiff
path: root/regcomp.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2016-03-12 09:39:41 +0000
committerDavid Mitchell <davem@iabyn.com>2016-03-12 10:22:51 +0000
commitd9cb8415c513b2fde359b11064306563502cbdeb (patch)
tree379d271a98e9ac92235b2deea797498ecc8246e4 /regcomp.c
parent6de23f80b0db931a33c28fa9eea3c74f533d772b (diff)
downloadperl-d9cb8415c513b2fde359b11064306563502cbdeb.tar.gz
regex sets: fix Solaris optimiser bug
[perl #127455] On Solaris with -DDEBUGGING, re/regex_sets.t was failing to compile. This appears to be due to an optimiser bug. The code in question looked like: handle_operand: top_index = av_tindex_nomg(stack); if (top_index - fence >= 0) { ... } printf()ing the value of fence after the av_tindex_nomg() showed that its value was corrupted (compared with its expected value based on a different platform with the same debugging print). However, putting a another printf prior to the av_tindex_nomg() call not only displayed the correct value, but caused the later printf() to also display the correct value. It seems that merely accessing fence prior to av_tindex_nomg() avoids the corruption. Simplifying the av_tindex_nomg(), the bad behaviour could be reduced to: if (!stack) { __assert( "" , "", 1); } Putting a printf after this gave a corrupted fence; a printf before made everything work. So this workaround commit just makes sure that fence is accessed prior to calling av_tindex_nomg().
Diffstat (limited to 'regcomp.c')
-rw-r--r--regcomp.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/regcomp.c b/regcomp.c
index ffee749388..e1dc3c8b36 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -15122,7 +15122,22 @@ redo_curchar:
* stack, we have to check if it is a !. But first, the code above
* may have altered the stack in the time since we earlier set
* 'top_index'. */
- top_index = av_tindex_nomg(stack);
+
+ {
+ /* Work round an optimiser bug in Solaris Studio 12.3:
+ * for some reason, the presence of the __assert() in
+ * av_tindex_nomg() causes the value of fence to get
+ * corrupted, even though the assert is never called. So
+ * save the value then restore afterwards.
+ * Note that in fact merely accessing the value of fence
+ * prior to the statement containing the assert is enough
+ * to make the bug go away.
+ */
+ IV f = fence;
+ top_index = av_tindex_nomg(stack);
+ fence = f;
+ }
+
if (top_index - fence >= 0) {
/* If the top entry on the stack is an operator, it had better
* be a '!', otherwise the entry below the top operand should