aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos O'Donell <carlos@codesourcery.com>2005-12-14 22:01:32 +0000
committerCarlos O'Donell <carlos@codesourcery.com>2005-12-14 22:01:32 +0000
commit5b3e2ec85af0b6d7d4624398cbdaea18912fa921 (patch)
treed61dc44b459fad935a6f74ff53eeac5707671333
parent97b386c28ae57cf124e20f0d816ff1cf1faceab6 (diff)
2005-12-10 Carlos O'Donell <carlos@codesourcery.com>csl/arm-2005q3-2
* 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. * include/std/std_limits.h (struct numeric_limits): Use __FLT_HAS_DENORM__, __DBL_HAS_DENORM__, __LDBL_HAS_DENORM__. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/csl-arm-branch@108541 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--ChangeLog.csl-arm12
-rw-r--r--gcc/c-cppbuiltin.c54
-rw-r--r--gcc/testsuite/gcc.dg/single-precision-constant.c19
-rw-r--r--libstdc++-v3/include/std/std_limits.h9
4 files changed, 75 insertions, 19 deletions
diff --git a/ChangeLog.csl-arm b/ChangeLog.csl-arm
index 1b6a6b31902..36c4e9a4039 100644
--- a/ChangeLog.csl-arm
+++ b/ChangeLog.csl-arm
@@ -1,3 +1,15 @@
+2005-12-10 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.
+ * include/std/std_limits.h (struct numeric_limits):
+ Use __FLT_HAS_DENORM__, __DBL_HAS_DENORM__, __LDBL_HAS_DENORM__.
+
2005-10-25 Paul Brook <paul@codesourcery.com>
* libstdc++-v3/libsupc++/vec.cc (__aeabi_atexit): Remove.
diff --git a/gcc/c-cppbuiltin.c b/gcc/c-cppbuiltin.c
index 6ce5588afe7..d46451066b1 100644
--- a/gcc/c-cppbuiltin.c
+++ b/gcc/c-cppbuiltin.c
@@ -1,5 +1,5 @@
/* Define builtin-in macros for the C family front ends.
- Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GCC.
@@ -51,10 +51,13 @@ 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_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);
@@ -65,9 +68,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.
@@ -205,19 +212,19 @@ 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). */
sprintf (name, "__%s_EPSILON__", name_prefix);
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
@@ -227,7 +234,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
{
@@ -235,6 +242,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,
@@ -357,9 +367,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);
@@ -535,10 +552,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
@@ -553,8 +572,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
diff --git a/gcc/testsuite/gcc.dg/single-precision-constant.c b/gcc/testsuite/gcc.dg/single-precision-constant.c
new file mode 100644
index 00000000000..877e4d74d67
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/single-precision-constant.c
@@ -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;
+}
diff --git a/libstdc++-v3/include/std/std_limits.h b/libstdc++-v3/include/std/std_limits.h
index 7f96647f95d..041a3718c08 100644
--- a/libstdc++-v3/include/std/std_limits.h
+++ b/libstdc++-v3/include/std/std_limits.h
@@ -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
@@ -993,7 +994,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
- = __FLT_DENORM_MIN__ ? denorm_present : denorm_absent;
+ = __FLT_HAS_DENORM__ ? denorm_present : denorm_absent;
static const bool has_denorm_loss = __glibcxx_float_has_denorm_loss;
static float infinity() throw()
@@ -1049,7 +1050,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
- = __DBL_DENORM_MIN__ ? denorm_present : denorm_absent;
+ = __DBL_HAS_DENORM__ ? denorm_present : denorm_absent;
static const bool has_denorm_loss = __glibcxx_double_has_denorm_loss;
static double infinity() throw()
@@ -1105,7 +1106,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
- = __LDBL_DENORM_MIN__ ? denorm_present : denorm_absent;
+ = __LDBL_HAS_DENORM__ ? denorm_present : denorm_absent;
static const bool has_denorm_loss
= __glibcxx_long_double_has_denorm_loss;