diff options
author | David Mitchell <davem@iabyn.com> | 2016-03-12 09:39:41 +0000 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2016-03-12 10:22:51 +0000 |
commit | d9cb8415c513b2fde359b11064306563502cbdeb (patch) | |
tree | 379d271a98e9ac92235b2deea797498ecc8246e4 /regcomp.c | |
parent | 6de23f80b0db931a33c28fa9eea3c74f533d772b (diff) | |
download | perl-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.c | 17 |
1 files changed, 16 insertions, 1 deletions
@@ -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 |