autoconf-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

changing "configure" to default to "gcc -g -O2 -fwrapv ..."


From: Paul Eggert
Subject: changing "configure" to default to "gcc -g -O2 -fwrapv ..."
Date: Tue, 19 Dec 2006 23:38:56 -0800
User-agent: Gnus/5.1008 (Gnus v5.10.8) Emacs/21.4 (gnu/linux)

Here's a patch that would allow programs to avoid running afoul of
unexpected gotchas with signed integer overflow when being compiled by
GCC using the default compilation flags.  It also attempts to document
the issue.  Comments?

2006-12-19  Paul Eggert  <address@hidden>

        * NEWS: configure now defaults to gcc -g -O2 -fwrapv.  This partly
        attacks the problem reported by Ralf Wildenhues in
        <http://lists.gnu.org/archive/html/bug-gnulib/2006-12/msg00084.html>
        and in <http://gcc.gnu.org/ml/gcc/2006-12/msg00459.html>.
        * doc/autoconf.texi (C Compiler, C++ Compiler):
        (Objective C Compiler): Mention -fwrapv.
        (Loop Induction, Signed Integer Divison): New sections.
        * lib/autoconf/c.m4 (_AC_PROG_CC_G, _AC_PROG_CXX_G):
        (_AC_PROG_OBJC_G): Default to -O2 -fwrapv if GCC, not
        merely to -O2.

Index: NEWS
===================================================================
RCS file: /cvsroot/autoconf/autoconf/NEWS,v
retrieving revision 1.422
diff -u -r1.422 NEWS
--- NEWS        19 Dec 2006 05:41:18 -0000      1.422
+++ NEWS        20 Dec 2006 07:37:11 -0000
@@ -1,5 +1,10 @@
 * Major changes in Autoconf 2.61b (????-??-??)

+** When using GCC, autoconf-generated 'configure' scripts now
+   default to "gcc -g -O2 -fwrapv" instead of to "gcc -g -O2".
+   This better supports the common C idiom where signed integer
+   overflow wraps around.
+
 ** Warnings are now generated by default when an installer invokes
    'configure' with an unknown --enable-* or --with-* option.
    These warnings can be disabled with the new AC_DISABLE_OPTION_CHECKING
Index: doc/autoconf.texi
===================================================================
RCS file: /cvsroot/autoconf/autoconf/doc/autoconf.texi,v
retrieving revision 1.1120
diff -u -r1.1120 autoconf.texi
--- doc/autoconf.texi   18 Dec 2006 20:10:05 -0000      1.1120
+++ doc/autoconf.texi   20 Dec 2006 07:37:12 -0000
@@ -6355,9 +6355,11 @@

 If using the @acronym{GNU} C compiler, set shell variable @code{GCC} to
 @samp{yes}.  If output variable @code{CFLAGS} was not already set, set
-it to @option{-g -O2} for the @acronym{GNU} C compiler (@option{-O2} on systems
-where @acronym{GCC} does not accept @option{-g}), or @option{-g} for
+it to @option{-g -O2 -fwrapv} for the @acronym{GNU} C compiler (omitting
address@hidden and @option{-fwrapv} on installations that do not accept these
+options), or @option{-g} for
 other compilers.
address@hidden Overflow}, for why @option{-fwrapv} is used here.
 @end defmac

 @defmac AC_PROG_CC_C_O
@@ -6690,9 +6692,11 @@

 If using the @acronym{GNU} C++ compiler, set shell variable @code{GXX} to
 @samp{yes}.  If output variable @code{CXXFLAGS} was not already set, set
-it to @option{-g -O2} for the @acronym{GNU} C++ compiler (@option{-O2} on
-systems where G++ does not accept @option{-g}), or @option{-g} for other
+it to @option{-g -O2 -fwrapv} for the @acronym{GNU} C++ compiler (omitting
address@hidden and @option{-fwrapv} on installations that do not accept these
+options), or @option{-g} for other
 compilers.
address@hidden Overflow}, for why @option{-fwrapv} is used here.
 @end defmac

 @defmac AC_PROG_CXXCPP
@@ -6744,9 +6748,11 @@

 If using the @acronym{GNU} Objective C compiler, set shell variable
 @code{GOBJC} to @samp{yes}.  If output variable @code{OBJCFLAGS} was not
-already set, set it to @option{-g -O2} for the @acronym{GNU} Objective C
-compiler (@option{-O2} on systems where @command{gcc} does not accept
address@hidden), or @option{-g} for other compilers.
+already set, set it to @option{-g -O2 -fwrapv} for the @acronym{GNU}
+Objective C compiler (omitting @option{-g} and @option{-fwrapv} on
+installations that do not accept these options), or @option{-g} for
+other compilers.
address@hidden Overflow}, for why @option{-fwrapv} is used here.
 @end defmac

 @defmac AC_PROG_OBJCCPP
@@ -14946,7 +14952,104 @@
 wraps around modulo a power of two, using two's complement arithmetic,
 so long as you cast the resulting value
 to an integer type or store it into an integer variable.  Such programs
-are portable to the vast majority of modern platforms.  However, signed
+are generally portable to the vast majority of modern platforms, if you
+use conservative optimization flags, with one main exception: signed
+integer division.
+
address@hidden
+* Loop Induction::             Loops with replaced induction variables
+* Signed Integer Division::    @code{INT_MIN / -1} and @code{INT_MIN % -1}
address@hidden menu
+
address@hidden Loop Induction
address@hidden Loop Induction and Integer Overflow
address@hidden loop induction
+
+Compilers sometimes generate code that is incompatible with wraparound
+integer arithmetic.  When this happens, it occurs mostly due to loop
+induction.
+
+For an example of loop induction, consider the following contrived
+function @code{sumc}:
+
address@hidden
+int
+sumc (int lo, int hi)
address@hidden
+  int sum = 0;
+  int i;
+  for (i = lo; i <= hi; i++)
+    sum ^= i * 100;
+  return sum;
address@hidden
address@hidden example
+
address@hidden
+To avoid multiplying by 100 each time through the loop, an optimizing
+compiler might internally transform @code{sumc} to the equivalent of the
+following:
+
address@hidden
+int
+transformed_sumc (int lo, int hi)
address@hidden
+  int sum = 0;
+  int hic = hi * 100;
+  int ic;
+  for (ic = lo * 100; ic <= hic; ic += 100)
+    sum ^= ic;
+  return sum;
address@hidden
address@hidden example
+
address@hidden
+If integer overflow is defined to wrap around modulo a power of two,
+this transformation is invalid when @code{INT_MAX / 100 < hi}, because
+then the overflow in computing expressions like @code{hi * 100} causes
+the expression @code{i <= hi} to yield a different value from the
+transformed expression @code{ic <= hic}.
+
+For this reason, compilers that use loop induction and similar
+techniques often do not support reliable wraparound arithmetic when a
+loop induction variable like @code{ic} is involved.  Since loop
+induction variables are generated by the compiler, and are not visible
+in the source code, it is not always trivial to say whether the problem
+affects your code.
+
+Hardly any code actually depends on wraparound arithmetic in cases like
+these, so in practice these loop induction optimizations are often
+useful.  However, @acronym{GCC} currently does not have an easy way to
+enable useful loop induction optimizations without also breaking common
+code that works on traditional C implementations.  For example:
+
address@hidden
+int j;
+for (j = 1; 0 < j; j *= 2)
+  test (j);
address@hidden example
+
address@hidden
+Here, the code is attempting to iterate through all powers of two that
address@hidden can represent, but @acronym{GCC}'s loop induction
+optimization can turn this into an infinite loop.
+
+To work around this problem, Autoconf-generated @command{configure}
+scripts by default compile with @option{-O2 -fwrapv} when using
address@hidden (assuming @acronym{GCC} is modern enough to support
address@hidden).  The @option{-fwrapv} option requires @command{GCC}
+to implement wraparound arithmetic for signed integers.  In some cases
address@hidden makes code faster and in some cases slower, but the
+important thing is that it leads to better-defined behavior that matches
+longstanding C tradition, so it is less likely to break existing code.
+
+An installer can override this default by specifying @code{CFLAGS} when
+invoking @command{configure}.
+
address@hidden Signed Integer Division
address@hidden Signed Integer Division and Integer Overflow
address@hidden division, integer
+
+Overflow in signed
 integer division is not always harmless: for example, on CPUs of the
 i386 family, dividing @code{INT_MIN} by @code{-1} yields a SIGFPE signal
 which by default terminates the program.  Worse, taking the remainder
Index: lib/autoconf/c.m4
===================================================================
RCS file: /cvsroot/autoconf/autoconf/lib/autoconf/c.m4,v
retrieving revision 1.242
diff -u -r1.242 c.m4
--- lib/autoconf/c.m4   7 Dec 2006 06:39:40 -0000       1.242
+++ lib/autoconf/c.m4   20 Dec 2006 07:37:12 -0000
@@ -598,15 +598,15 @@
    ac_c_werror_flag=$ac_save_c_werror_flag])
 if test "$ac_test_CFLAGS" = set; then
   CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
-  if test "$GCC" = yes; then
-    CFLAGS="-g -O2"
-  else
-    CFLAGS="-g"
-  fi
 else
   if test "$GCC" = yes; then
-    CFLAGS="-O2"
+    CFLAGS='-O2 -fwrapv'
+    _AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], [], [CFLAGS='-O2'])
+    if test $ac_cv_prog_cc_g = yes; then
+      CFLAGS="-g $CFLAGS"
+    fi
+  elif test $ac_cv_prog_cc_g = yes; then
+    CFLAGS='-g'
   else
     CFLAGS=
   fi
@@ -844,6 +844,21 @@
     CXXFLAGS=
   fi
 fi[]dnl
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS='-O2 -fwrapv'
+    _AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], [], [CXXFLAGS='-O2'])
+    if test $ac_cv_prog_cxx_g = yes; then
+      CXXFLAGS="-g $CXXFLAGS"
+    fi
+  elif test $ac_cv_prog_cxx_g = yes; then
+    CXXFLAGS='-g'
+  else
+    CXXFLAGS=
+  fi
+fi[]dnl
 ])# _AC_PROG_CXX_G


@@ -1000,15 +1015,15 @@
    ac_objc_werror_flag=$ac_save_objc_werror_flag])
 if test "$ac_test_OBJCFLAGS" = set; then
   OBJCFLAGS=$ac_save_OBJCFLAGS
-elif test $ac_cv_prog_objc_g = yes; then
-  if test "$GOBJC" = yes; then
-    OBJCFLAGS="-g -O2"
-  else
-    OBJCFLAGS="-g"
-  fi
 else
   if test "$GOBJC" = yes; then
-    OBJCFLAGS="-O2"
+    OBJCFLAGS='-O2 -fwrapv'
+    _AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], [], [OBJCFLAGS='-O2'])
+    if test $ac_cv_prog_objc_g = yes; then
+      OBJCFLAGS="-g $OBJCFLAGS"
+    fi
+  elif test $ac_cv_prog_objc_g = yes; then
+    OBJCFLAGS='-g'
   else
     OBJCFLAGS=
   fi




reply via email to

[Prev in Thread] Current Thread [Next in Thread]