c-opts.c (c_common_post_options): Set -ffp-contract=off in C standards modes.
authorJoseph Myers <joseph@codesourcery.com>
Wed, 6 Nov 2013 16:52:47 +0000 (16:52 +0000)
committerJoseph Myers <jsm28@gcc.gnu.org>
Wed, 6 Nov 2013 16:52:47 +0000 (16:52 +0000)
c-family:
* c-opts.c (c_common_post_options): Set -ffp-contract=off in C
standards modes.
* c-cppbuiltin.c (cpp_iec_559_value): Consider -ffp-contract=fast
to mean lack of IEEE 754 support.

testsuite:
* gcc.dg/torture/c99-contract-1.c: New test.

From-SVN: r204460

gcc/c-family/ChangeLog
gcc/c-family/c-cppbuiltin.c
gcc/c-family/c-opts.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/c99-contract-1.c [new file with mode: 0644]

index 68929521087b463f4aeee76defbb7051610e8e3d..582aa9383d62f1f5e7fccc060eccab313ad14a64 100644 (file)
@@ -1,3 +1,10 @@
+2013-11-06  Joseph Myers  <joseph@codesourcery.com>
+
+       * c-opts.c (c_common_post_options): Set -ffp-contract=off in C
+       standards modes.
+       * c-cppbuiltin.c (cpp_iec_559_value): Consider -ffp-contract=fast
+       to mean lack of IEEE 754 support.
+
 2013-11-05  Tobias Burnus  <burnus@net-b.de>
 
        * c.opt (-Wdate-time): New option
index 61a124c509c557ff48e0b1f5694ed772c37e9cc9..b9a0f18cd7e5cdc2547a07ce8348996fe5921857 100644 (file)
@@ -726,16 +726,19 @@ cpp_iec_559_value (void)
     ret = 0;
 
   /* In strict C standards conformance mode, consider unpredictable
-     excess precision to mean lack of IEEE 754 support.  ??? The same
-     should apply to unpredictable contraction, but at present
-     standards conformance options do not enable conforming
-     contraction.  For C++, and outside strict conformance mode, do
-     not consider these options to mean lack of IEEE 754 support.  */
+     excess precision to mean lack of IEEE 754 support.  The same
+     applies to unpredictable contraction.  For C++, and outside
+     strict conformance mode, do not consider these options to mean
+     lack of IEEE 754 support.  */
   if (flag_iso
       && !c_dialect_cxx ()
       && TARGET_FLT_EVAL_METHOD != 0
       && flag_excess_precision_cmdline != EXCESS_PRECISION_STANDARD)
     ret = 0;
+  if (flag_iso
+      && !c_dialect_cxx ()
+      && flag_fp_contract_mode == FP_CONTRACT_FAST)
+    ret = 0;
 
   /* Various options are contrary to IEEE 754 semantics.  */
   if (flag_unsafe_math_optimizations
index 2de5425e65473dbe303fcef8bf6392b1371478ee..34fe94de34b3d8c9630a2af23d42ee2fdb21827a 100644 (file)
@@ -827,6 +827,15 @@ c_common_post_options (const char **pfilename)
                                     ? EXCESS_PRECISION_STANDARD
                                     : EXCESS_PRECISION_FAST);
 
+  /* ISO C restricts floating-point expression contraction to within
+     source-language expressions (-ffp-contract=on, currently an alias
+     for -ffp-contract=off).  */
+  if (flag_iso
+      && !c_dialect_cxx ()
+      && (global_options_set.x_flag_fp_contract_mode
+         == (enum fp_contract_mode) 0))
+    flag_fp_contract_mode = FP_CONTRACT_OFF;
+
   /* By default we use C99 inline semantics in GNU99 or C99 mode.  C99
      inline semantics are not supported in GNU89 or C89 mode.  */
   if (flag_gnu89_inline == -1)
index 9d19eb10231f3a2a19c953cff571381dcb799ed6..9668d7393e4bce4a2afa3947723b8980b38ef8b9 100644 (file)
@@ -1,3 +1,7 @@
+2013-11-06  Joseph Myers  <joseph@codesourcery.com>
+
+       * gcc.dg/torture/c99-contract-1.c: New test.
+
 2013-11-06  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/58653
diff --git a/gcc/testsuite/gcc.dg/torture/c99-contract-1.c b/gcc/testsuite/gcc.dg/torture/c99-contract-1.c
new file mode 100644 (file)
index 0000000..6023083
--- /dev/null
@@ -0,0 +1,21 @@
+/* Test floating-point contraction occurs only within source language
+   expressions.  */
+/* { dg-do run } */
+/* { dg-options "-std=c99 -pedantic-errors" } */
+
+extern void abort (void);
+extern void exit (int);
+
+volatile float a = 1 + 0x1p-23f, b = 1 - 0x1p-23f, c = -1;
+
+int
+main (void)
+{
+  float av = a, bv = b, cv = c;
+  float p = av * bv;
+  float r = p + cv;
+  if (r == 0)
+    exit (0);
+  else
+    abort ();
+}