Thanks for reporting the problem.

On 04/14/2017 02:27 PM, Gavin Smith wrote:
> /opt/solarisstudio12.3/bin/c99 -Xc -D_XPG6 -DHAVE_CONFIG_H -I. -I../..
> -D_REENTRANT  -I/opt/csw/include -c -o regex.o regex.c
> "regex_internal.h", line 105: warning: macro redefined: gettext

That's odd. Where was the gettext macro originally defined?

> "regex_internal.h", line 734: warning: token-less macro argument

This warns about the use of a C99-ism in code that is protected by "#if 199901L <= __STDC_VERSION__", so it must be a false alarm, and you're right tno not worry about it.

> Assembler: "/tmp/yabeAAAiUaidC", line 19010 : Value out of range
>         "/tmp/yabeAAAiUaidC", line 19031 : Value out of range

Ouch. This appears to be a compiler bug, as a compiler should never generate invalid assembly-language code. I cannot reproduce the problem on Solaris 10 sparc (32-bit) with Oracle Developer Studio 12.5. You are on Solaris 10 x86 (32-bit) and are using 12.3. Do you observe the same compiler bug with 12.5 or 12.6 beta? If so, I suggest reporting it as a bug to Oracle.

What happens if you compile with -xO2?

Although I cannot reproduce the problem in my environment, I think I see why it's happening. I installed the attached patches into Gnulib; do they fix your problem?
>From 3c20784ac87d0f0748a86f3bc6f06e18694658da Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@penguin.cs.ucla.edu>
Date: Fri, 14 Apr 2017 17:38:58 -0700
Subject: [PATCH 1/2] intprops: port to Oracle Studio 12.3 x86

Problem reported by Gavin Smith in:
http://lists.gnu.org/archive/html/bug-gnulib/2017-04/msg00049.html
* lib/intprops.h (_GL_INT_OP_WRAPV_VIA_UNSIGNED):
Convert unsigned to signed via the usual rather than the standard way,
to avoid a compiler bug in Oracle Studio 12.3 x86.
---
 ChangeLog      |  9 +++++++++
 lib/intprops.h | 41 +++++++++++++++++++++++++++++------------
 2 files changed, 38 insertions(+), 12 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index ae1a8bd..97d1e59 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2017-04-14  Paul Eggert  <egg...@penguin.cs.ucla.edu>
+
+	intprops: port to Oracle Studio 12.3 x86
+	Problem reported by Gavin Smith in:
+	http://lists.gnu.org/archive/html/bug-gnulib/2017-04/msg00049.html
+	* lib/intprops.h (_GL_INT_OP_WRAPV_VIA_UNSIGNED):
+	Convert unsigned to signed via the usual rather than the standard way,
+	to avoid a compiler bug in Oracle Studio 12.3 x86.
+
 2017-04-08  Paul Eggert  <egg...@cs.ucla.edu>
 
 	getopt: prefer - to _ in new file names
diff --git a/lib/intprops.h b/lib/intprops.h
index eb06b69..220b509 100644
--- a/lib/intprops.h
+++ b/lib/intprops.h
@@ -442,17 +442,34 @@ verify (TYPE_WIDTH (unsigned int) == UINT_WIDTH);
   ((overflow (a, b) \
     || (EXPR_SIGNED ((a) op (b)) && ((a) op (b)) < (tmin)) \
     || (tmax) < ((a) op (b))) \
-   ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t, tmin, tmax), 1) \
-   : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t, tmin, tmax), 0))
-
-/* Return A <op> B, where the operation is given by OP.  Use the
-   unsigned type UT for calculation to avoid overflow problems.
-   Convert the result to type T without overflow by subtracting TMIN
-   from large values before converting, and adding it afterwards.
-   Compilers can optimize all the operations except OP.  */
-#define _GL_INT_OP_WRAPV_VIA_UNSIGNED(a, b, op, ut, t, tmin, tmax) \
-  (((ut) (a) op (ut) (b)) <= (tmax) \
-   ? (t) ((ut) (a) op (ut) (b)) \
-   : ((t) (((ut) (a) op (ut) (b)) - (tmin)) + (tmin)))
+   ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 1) \
+   : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 0))
+
+/* Return A <op> B, where the operation is given by OP.  Return the
+   low-order bits of the mathematically-correct answer.  Use the
+   unsigned type UT for calculation to avoid undefined behavior on
+   signed integer overflow.  Assume that conversion to the result type
+   T yields the low-order bits in the usual way.  UT and T are the
+   same width, T is two's complement, and there is no padding or trap
+   representations.
+
+   According to the C standard, converting UT to T yields an
+   implementation-defined result or signal for values outside T's range.
+   So, the standard way to convert UT to T is to subtract TMIN from
+   greater-than-TMAX values before converting them to T, and to add
+   TMIN afterwards, where TMIN and TMAX are T's extrema.
+   However, in practice there is no need to subtract and add TMIN.
+   E.g., GCC converts to signed integers in the usual way; see:
+   https://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html
+   All other known C compilers are similar to GCC in this respect.
+   Furthermore, Oracle Studio Studio 12.3 x86 has a bug when
+   implementing the standard way; see:
+   http://lists.gnu.org/archive/html/bug-gnulib/2017-04/msg00049.html
+
+   So, implement this operation in the usual way rather than in
+   the standard way.  */
+
+#define _GL_INT_OP_WRAPV_VIA_UNSIGNED(a, b, op, ut, t) \
+  ((t) ((ut) (a) op (ut) (b)))
 
 #endif /* _GL_INTPROPS_H */
-- 
2.9.3

>From 931d22eb17dca7efc9c355176fe3303d3ab33bb9 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@penguin.cs.ucla.edu>
Date: Fri, 14 Apr 2017 18:55:42 -0700
Subject: [PATCH 2/2] intprops: try to avoid tickling similar bugs

* lib/intprops.h (_GL_INT_OP_CALC): Document that UT no longer
needs to be the same width as T; it can be wider.
Change callers so that UT is at least as wide as unsigned int,
as I suspect that this is less likely to run into compiler bugs.
---
 ChangeLog      |  6 ++++++
 lib/intprops.h | 19 +++++++++----------
 2 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 97d1e59..5ed1517 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2017-04-14  Paul Eggert  <egg...@penguin.cs.ucla.edu>
 
+	intprops: try to avoid tickling similar bugs
+	* lib/intprops.h (_GL_INT_OP_CALC): Document that UT no longer
+	needs to be the same width as T; it can be wider.
+	Change callers so that UT is at least as wide as unsigned int,
+	as I suspect that this is less likely to run into compiler bugs.
+
 	intprops: port to Oracle Studio 12.3 x86
 	Problem reported by Gavin Smith in:
 	http://lists.gnu.org/archive/html/bug-gnulib/2017-04/msg00049.html
diff --git a/lib/intprops.h b/lib/intprops.h
index 220b509..ca8740d 100644
--- a/lib/intprops.h
+++ b/lib/intprops.h
@@ -389,10 +389,10 @@ verify (TYPE_WIDTH (unsigned int) == UINT_WIDTH);
    (_Generic \
     (*(r), \
      signed char: \
-       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned char, \
+       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
                         signed char, SCHAR_MIN, SCHAR_MAX), \
      short int: \
-       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned short int, \
+       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
                         short int, SHRT_MIN, SHRT_MAX), \
      int: \
        _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
@@ -406,10 +406,10 @@ verify (TYPE_WIDTH (unsigned int) == UINT_WIDTH);
 #else
 # define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) \
    (sizeof *(r) == sizeof (signed char) \
-    ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned char, \
+    ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
                        signed char, SCHAR_MIN, SCHAR_MAX) \
     : sizeof *(r) == sizeof (short int) \
-    ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned short int, \
+    ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
                        short int, SHRT_MIN, SHRT_MAX) \
     : sizeof *(r) == sizeof (int) \
     ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
@@ -431,9 +431,8 @@ verify (TYPE_WIDTH (unsigned int) == UINT_WIDTH);
 
 /* Store the low-order bits of A <op> B into *R, where the operation
    is given by OP.  Use the unsigned type UT for calculation to avoid
-   overflow problems.  *R's type is T, with extremal values TMIN and
-   TMAX.  T must be a signed integer type.  Return 1 if the result
-   overflows.  */
+   overflow problems.  *R's type is T, with extrema TMIN and TMAX.
+   T must be a signed integer type.  Return 1 if the result overflows.  */
 #define _GL_INT_OP_CALC(a, b, r, op, overflow, ut, t, tmin, tmax) \
   (sizeof ((a) op (b)) < sizeof (t) \
    ? _GL_INT_OP_CALC1 ((t) (a), (t) (b), r, op, overflow, ut, t, tmin, tmax) \
@@ -449,9 +448,9 @@ verify (TYPE_WIDTH (unsigned int) == UINT_WIDTH);
    low-order bits of the mathematically-correct answer.  Use the
    unsigned type UT for calculation to avoid undefined behavior on
    signed integer overflow.  Assume that conversion to the result type
-   T yields the low-order bits in the usual way.  UT and T are the
-   same width, T is two's complement, and there is no padding or trap
-   representations.
+   T yields the low-order bits in the usual way.  UT is at least as
+   wide as T and is no narrower than unsigned int, T is two's
+   complement, and there is no padding or trap representations.
 
    According to the C standard, converting UT to T yields an
    implementation-defined result or signal for values outside T's range.
-- 
2.9.3

Reply via email to