Skip to content

Commit

Permalink
regex sets: fix Solaris optimiser bug
Browse files Browse the repository at this point in the history
[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().
  • Loading branch information
iabyn committed Mar 12, 2016
1 parent 6de23f8 commit d9cb841
Showing 1 changed file with 16 additions and 1 deletion.
17 changes: 16 additions & 1 deletion regcomp.c
Expand Up @@ -15122,7 +15122,22 @@ S_handle_regex_sets(pTHX_ RExC_state_t *pRExC_state, SV** return_invlist,
* 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
Expand Down

0 comments on commit d9cb841

Please sign in to comment.