S_regmatch(): work around Solaris optimiser bug
authorDavid Mitchell <davem@iabyn.com>
Mon, 4 Apr 2016 12:27:35 +0000 (13:27 +0100)
committerDavid Mitchell <davem@iabyn.com>
Mon, 4 Apr 2016 13:32:51 +0000 (14:32 +0100)
commitc5d7841e4eb4cac218f8e76e74844b681396e3b2
tree3447a5526a93d6b434bab415aace3bb425de69c3
parentda44b70c4102d945d69b12cd6f1852ed80e0e8d8
S_regmatch(): work around Solaris optimiser bug

Recently these test scripts started failing on Solaris i386 with
-Duse64bitall:

    re/charset.t
    re/subst.t
    re/substT.t
    re/subst_wamp.t

The first failure is due to a Solaris Studio optimiser bug; this commit
works around that failure. It may or may not also fix the other failures
(all tests pass now on the development box I was using, but I didn't
confirm whether the other tests failed before the fix).

The basic problem is that within the main while loop in S_regmatch(),
the expression PL_charclass['\n'] returns the wrong value.

Looking at the disassembled code, it appears that looking up this value
just before the while loop correctly does it by getting the address of the
global array PL_charclass, adding 40 to it (ord('\n')*sizeof(U32)), then
dereffing it.

Within the loop however, it just reads the value from a local var. The
optimiser is under the misapprehension that this value has previously been
read in and assigned to a local var, but it certainly hasn't been at the
point where the while loop is first entered.

This commit works round the problem on builds with -Duse64bitall and the
bad version of Solaris Studio compiler (12.3), by making a copy of
PL_charclass's address.

This is a bit of hack. For one thing, I don't know whether other versions
of the compiler also need this workaround.

The failures were seen on a 32-bit system with -Duse64bitall: this created
a 64-bit executable (i.e. with 64-bit pointers) with the -m64 compiler
flag. I would speculate that the bug in the compiler relates to to
this particular circumstance (i.e. the bug might not appear for a build
done on a 64-bit OS host with or without -Duse64bitall).
regexec.c