c-cppbuiltin.c (builtin_define_float_constants): Add fp_cast parameter, pass to built...
authorCarlos O'Donell <carlos@codesourcery.com>
Tue, 13 Dec 2005 05:12:32 +0000 (05:12 +0000)
committerCarlos O'Donell <carlos@gcc.gnu.org>
Tue, 13 Dec 2005 05:12:32 +0000 (05:12 +0000)
2005-12-13  Carlos O'Donell <carlos@codesourcery.com>

gcc/

* c-cppbuiltin.c (builtin_define_float_constants): Add
fp_cast parameter, pass to builtin_define_with_hex_fp_value.
Define __FLT_HAS_DENORM__, __DBL_HAS_DENORM__, __LDBL_HAS_DENORM__.
(builtin_define_with_hex_fp_value): Use fp_cast when building macro.
(c_cpp_builtins): If flag_single_precision_constant then set fp_cast
to "((double)%sL)" otherwise "%s".

gcc/testsuite/

* gcc.dg/single-precision-constant.c: New test.

libstdc++-v3/

* include/std/std_limits.h (struct numeric_limits):
Use __DBL_HAS_DENORM__, __FLT_HAS_DENORM__, __LDBL_HAS_DENORM__.

From-SVN: r108458

gcc/ChangeLog
gcc/c-cppbuiltin.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/single-precision-constant.c [new file with mode: 0644]
libstdc++-v3/ChangeLog
libstdc++-v3/include/std/std_limits.h

index 40c61d90666a0c5b174353dfffe1f9d84319c656..222bda496232fd646a1def6e1d4394b8c79266cb 100644 (file)
@@ -1,3 +1,12 @@
+2005-12-13  Carlos O'Donell <carlos@codesourcery.com>
+
+       * c-cppbuiltin.c (builtin_define_float_constants): Add
+       fp_cast parameter, pass to builtin_define_with_hex_fp_value.
+       Define __FLT_HAS_DENORM__, __DBL_HAS_DENORM__, __LDBL_HAS_DENORM__.
+       (builtin_define_with_hex_fp_value): Use fp_cast when building macro.
+       (c_cpp_builtins): If flag_single_precision_constant then set fp_cast
+       to "((double)%sL)" otherwise "%s".
+
 2005-12-13  Paul Brook  <paul@codesourcery.com>
 
        * config/arm/bpabi.h (SUBTARGET_EXTRA_ASM_SPEC): Pass -meabi=gnu for
index e0d6189200953c16e819ef3744d245c01e9ae19a..dc87980df1925e00e726c67c90866a626dcaf440 100644 (file)
@@ -53,11 +53,14 @@ static void builtin_define_with_value_n (const char *, const char *,
 static void builtin_define_with_int_value (const char *, HOST_WIDE_INT);
 static void builtin_define_with_hex_fp_value (const char *, tree,
                                              int, const char *,
+                                             const char *,
                                              const char *);
 static void builtin_define_stdint_macros (void);
 static void builtin_define_type_max (const char *, tree, int);
 static void builtin_define_type_precision (const char *, tree);
-static void builtin_define_float_constants (const char *, const char *,
+static void builtin_define_float_constants (const char *, 
+                                           const char *,
+                                           const char *,
                                            tree);
 static void define__GNUC__ (void);
 
@@ -68,9 +71,13 @@ builtin_define_type_precision (const char *name, tree type)
   builtin_define_with_int_value (name, TYPE_PRECISION (type));
 }
 
-/* Define the float.h constants for TYPE using NAME_PREFIX and FP_SUFFIX.  */
+/* Define the float.h constants for TYPE using NAME_PREFIX, FP_SUFFIX,
+   and FP_CAST. */
 static void
-builtin_define_float_constants (const char *name_prefix, const char *fp_suffix, tree type)
+builtin_define_float_constants (const char *name_prefix, 
+                               const char *fp_suffix, 
+                               const char *fp_cast, 
+                               tree type)
 {
   /* Used to convert radix-based values to base 10 values in several cases.
 
@@ -208,13 +215,13 @@ builtin_define_float_constants (const char *name_prefix, const char *fp_suffix,
       }
   }
   sprintf (name, "__%s_MAX__", name_prefix);
-  builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
+  builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix, fp_cast);
 
   /* The minimum normalized positive floating-point number,
      b**(emin-1).  */
   sprintf (name, "__%s_MIN__", name_prefix);
   sprintf (buf, "0x1p%d", (fmt->emin - 1) * fmt->log2_b);
-  builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
+  builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix, fp_cast);
 
   /* The difference between 1 and the least value greater than 1 that is
      representable in the given floating point type, b**(1-p).  */
@@ -225,7 +232,7 @@ builtin_define_float_constants (const char *name_prefix, const char *fp_suffix,
       sprintf (buf, "0x1p%d", (fmt->emin - fmt->p) * fmt->log2_b);
     else      
       sprintf (buf, "0x1p%d", (1 - fmt->p) * fmt->log2_b);
-  builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
+  builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix, fp_cast);
 
   /* For C++ std::numeric_limits<T>::denorm_min.  The minimum denormalized
      positive floating-point number, b**(emin-p).  Zero for formats that
@@ -235,7 +242,7 @@ builtin_define_float_constants (const char *name_prefix, const char *fp_suffix,
     {
       sprintf (buf, "0x1p%d", (fmt->emin - fmt->p) * fmt->log2_b);
       builtin_define_with_hex_fp_value (name, type, decimal_dig,
-                                       buf, fp_suffix);
+                                       buf, fp_suffix, fp_cast);
     }
   else
     {
@@ -243,6 +250,9 @@ builtin_define_float_constants (const char *name_prefix, const char *fp_suffix,
       builtin_define_with_value (name, buf, 0);
     }
 
+  sprintf (name, "__%s_HAS_DENORM__", name_prefix);
+  builtin_define_with_value (name, fmt->has_denorm ? "1" : "0", 0);
+
   /* For C++ std::numeric_limits<T>::has_infinity.  */
   sprintf (name, "__%s_HAS_INFINITY__", name_prefix);
   builtin_define_with_int_value (name,
@@ -382,9 +392,16 @@ c_cpp_builtins (cpp_reader *pfile)
   builtin_define_with_int_value ("__FLT_EVAL_METHOD__",
                                 TARGET_FLT_EVAL_METHOD);
 
-  builtin_define_float_constants ("FLT", "F", float_type_node);
-  builtin_define_float_constants ("DBL", "", double_type_node);
-  builtin_define_float_constants ("LDBL", "L", long_double_type_node);
+  builtin_define_float_constants ("FLT", "F", "%s", float_type_node);
+  /* Cast the double precision constants when single precision constants are
+     specified. The correct result is computed by the compiler when using 
+     macros that include a cast. This has the side-effect of making the value 
+     unusable in const expressions. */
+  if (flag_single_precision_constant)
+    builtin_define_float_constants ("DBL", "L", "((double)%s)", double_type_node);
+  else
+    builtin_define_float_constants ("DBL", "", "%s", double_type_node);
+  builtin_define_float_constants ("LDBL", "L", "%s", long_double_type_node);
 
   /* For use in assembly language.  */
   builtin_define_with_value ("__REGISTER_PREFIX__", REGISTER_PREFIX, 0);
@@ -580,10 +597,12 @@ builtin_define_with_int_value (const char *macro, HOST_WIDE_INT value)
 static void
 builtin_define_with_hex_fp_value (const char *macro,
                                  tree type ATTRIBUTE_UNUSED, int digits,
-                                 const char *hex_str, const char *fp_suffix)
+                                 const char *hex_str, 
+                                 const char *fp_suffix,
+                                 const char *fp_cast)
 {
   REAL_VALUE_TYPE real;
-  char dec_str[64], buf[256];
+  char dec_str[64], buf1[256], buf2[256];
 
   /* Hex values are really cool and convenient, except that they're
      not supported in strict ISO C90 mode.  First, the "p-" sequence
@@ -598,8 +617,13 @@ builtin_define_with_hex_fp_value (const char *macro,
   real_from_string (&real, hex_str);
   real_to_decimal (dec_str, &real, sizeof (dec_str), digits, 0);
 
-  sprintf (buf, "%s=%s%s", macro, dec_str, fp_suffix);
-  cpp_define (parse_in, buf);
+  /* Assemble the macro in the following fashion
+     macro = fp_cast [dec_str fp_suffix] */
+  sprintf (buf1, "%s%s", dec_str, fp_suffix);
+  sprintf (buf2, fp_cast, buf1);
+  sprintf (buf1, "%s=%s", macro, buf2);
+  
+  cpp_define (parse_in, buf1);
 }
 
 /* Define MAX for TYPE based on the precision of the type.  IS_LONG is
index e8b94ae9adbd78604031316b47479e3b8e3de527..2bd0541e453b362b1215b19dde9ac9eef1e33112 100644 (file)
@@ -1,3 +1,7 @@
+2005-12-13  Carlos O'Donell <carlos@codesourcery.com>
+
+       * gcc.dg/single-precision-constant.c: New test.
+
 2005-12-13  Alan Modra  <amodra@bigpond.net.au>
 
        * gcc.dg/980523-1.c, gcc.dg/980526-1.c, gcc.dg/20020103-1.c,
diff --git a/gcc/testsuite/gcc.dg/single-precision-constant.c b/gcc/testsuite/gcc.dg/single-precision-constant.c
new file mode 100644 (file)
index 0000000..877e4d7
--- /dev/null
@@ -0,0 +1,19 @@
+/* Test that double precision constants are correctly handled 
+   when code is compiled with -fsingle-precision-constant */
+/* Origin: Carlos O'Donell <carlos@codesourcery.com> */
+/* { dg-do run } */
+/* { dg-options "-fsingle-precision-constant" } */
+#include <math.h>
+#include <float.h>
+
+int main (void)
+{
+  int result = 0;
+  double local_DBL_MAX = DBL_MAX; 
+  double local_DBL_MIN = DBL_MIN;
+  if (isinf (local_DBL_MAX))
+    result |= 1;
+  if (local_DBL_MIN <= 0.0)
+    result |= 1;
+  return result;
+}
index 6e28250af1914185fe0f55b6dbd29e089df4932c..92111797df6ea05bf78cd216992ecc51cce0bfac 100644 (file)
@@ -1,3 +1,8 @@
+2005-12-13  Carlos O'Donell <carlos@codesourcery.com>
+
+       * include/std/std_limits.h (struct numeric_limits):
+       Use __DBL_HAS_DENORM__, __FLT_HAS_DENORM__, __LDBL_HAS_DENORM__.
+
 2005-12-10  Paolo Carlini  <pcarlini@suse.de>
 
        * include/ext/sso_string_base.h (__sso_string_base<>::_M_compare):
index e7c33e5866b3e188c96401195321320f4a3d5dce..7643dcfe230ca54eb955ba73a25bbc0bbf7e05bc 100644 (file)
@@ -1,6 +1,7 @@
 // The template and inlines for the -*- C++ -*- numeric_limits classes.
 
-// Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005 
+// Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -1007,7 +1008,7 @@ namespace std
       static const bool has_quiet_NaN = __FLT_HAS_QUIET_NAN__;
       static const bool has_signaling_NaN = has_quiet_NaN;
       static const float_denorm_style has_denorm
-       = bool(__FLT_DENORM_MIN__) ? denorm_present : denorm_absent;
+       = bool(__FLT_HAS_DENORM__) ? denorm_present : denorm_absent;
       static const bool has_denorm_loss = __glibcxx_float_has_denorm_loss;
 
       static float infinity() throw()
@@ -1064,7 +1065,7 @@ namespace std
       static const bool has_quiet_NaN = __DBL_HAS_QUIET_NAN__;
       static const bool has_signaling_NaN = has_quiet_NaN;
       static const float_denorm_style has_denorm
-       = bool(__DBL_DENORM_MIN__) ? denorm_present : denorm_absent;
+       = bool(__DBL_HAS_DENORM__) ? denorm_present : denorm_absent;
       static const bool has_denorm_loss = __glibcxx_double_has_denorm_loss;
 
       static double infinity() throw()
@@ -1121,7 +1122,7 @@ namespace std
       static const bool has_quiet_NaN = __LDBL_HAS_QUIET_NAN__;
       static const bool has_signaling_NaN = has_quiet_NaN;
       static const float_denorm_style has_denorm
-       = bool(__LDBL_DENORM_MIN__) ? denorm_present : denorm_absent;
+       = bool(__LDBL_HAS_DENORM__) ? denorm_present : denorm_absent;
       static const bool has_denorm_loss
        = __glibcxx_long_double_has_denorm_loss;