aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZack Weinberg <zack@gcc.gnu.org>2003-06-09 18:47:40 +0000
committerZack Weinberg <zack@gcc.gnu.org>2003-06-09 18:47:40 +0000
commit94d3ea58ff99483cba839ec978f65da745b209d0 (patch)
treebd2d94cde7a0a25aec7bf7173ff72d09ff6c8bf4
parentb14e185fc8fabfe13dca42e9aa7c2990958f64c6 (diff)
downloadgcc-94d3ea58ff99483cba839ec978f65da745b209d0.zip
gcc-94d3ea58ff99483cba839ec978f65da745b209d0.tar.gz
gcc-94d3ea58ff99483cba839ec978f65da745b209d0.tar.bz2
re PR c++/8861 ([ABI] mangling floating point literal in template arg expression)
PR 8861 * mangle.c (write_real_cst): New function. Implement ABI-compliant mangling of floating-point literals when -fabi-version>=2; provide backward compatibility with 3.3 when -fabi-version=1 (with warning). Clarify commentary. (write_template_arg_literal): Use write_real_cst. From-SVN: r67670
-rw-r--r--gcc/cp/ChangeLog15
-rw-r--r--gcc/cp/mangle.c92
2 files changed, 81 insertions, 26 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ad74fd5..417fb86 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2003-06-09 Zack Weinberg <zack@codesourcery.com>
+
+ PR 8861
+ * mangle.c (write_real_cst): New function. Implement
+ ABI-compliant mangling of floating-point literals when
+ -fabi-version>=2; provide backward compatibility with 3.3 when
+ -fabi-version=1 (with warning). Clarify commentary.
+ (write_template_arg_literal): Use write_real_cst.
+
2003-06-07 Andreas Jaeger <aj@suse.de>
* cp/decl.c (xref_tag): Remove undefined macro NONNESTED_CLASSES.
@@ -23,11 +32,11 @@ Thu Jun 5 18:33:40 CEST 2003 Jan Hubicka <jh@suse.cz>
2003-06-03 Jason Merrill <jason@redhat.com>
- * cp/cp-tree.h (CP_AGGREGATE_TYPE_P): Accept vectors.
+ * cp/cp-tree.h (CP_AGGREGATE_TYPE_P): Accept vectors.
- * cp/decl.c (reshape_init): Handle vectors.
+ * cp/decl.c (reshape_init): Handle vectors.
- * testsuite/g++.dg/init/array10.C: New.
+ * testsuite/g++.dg/init/array10.C: New.
2003-06-03 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index a105db1..343cca5 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -175,6 +175,7 @@ static int hwint_to_ascii PARAMS ((unsigned HOST_WIDE_INT, unsigned int, char *,
static void write_number PARAMS ((unsigned HOST_WIDE_INT, int,
unsigned int));
static void write_integer_cst PARAMS ((tree));
+static void write_real_cst PARAMS ((tree));
static void write_identifier PARAMS ((const char *));
static void write_special_name_constructor PARAMS ((tree));
static void write_special_name_destructor PARAMS ((tree));
@@ -1192,6 +1193,72 @@ write_integer_cst (cst)
}
}
+/* Write out a floating-point literal.
+
+ "Floating-point literals are encoded using the bit pattern of the
+ target processor's internal representation of that number, as a
+ fixed-length lowercase hexadecimal string, high-order bytes first
+ (even if the target processor would store low-order bytes first).
+ The "n" prefix is not used for floating-point literals; the sign
+ bit is encoded with the rest of the number.
+
+ Here are some examples, assuming the IEEE standard representation
+ for floating point numbers. (Spaces are for readability, not
+ part of the encoding.)
+
+ 1.0f Lf 3f80 0000 E
+ -1.0f Lf bf80 0000 E
+ 1.17549435e-38f Lf 0080 0000 E
+ 1.40129846e-45f Lf 0000 0001 E
+ 0.0f Lf 0000 0000 E"
+
+ Caller is responsible for the Lx and the E. */
+static void
+write_real_cst (value)
+ tree value;
+{
+ if (abi_version_at_least (2))
+ {
+ long target_real[4]; /* largest supported float */
+ char buffer[9]; /* eight hex digits in a 32-bit number */
+ int i, limit, dir;
+
+ tree type = TREE_TYPE (value);
+ int words = GET_MODE_BITSIZE (TYPE_MODE (type)) / 32;
+
+ real_to_target (target_real, &TREE_REAL_CST (value),
+ TYPE_MODE (type));
+
+ /* The value in target_real is in the target word order,
+ so we must write it out backward if that happens to be
+ little-endian. write_number cannot be used, it will
+ produce uppercase. */
+ if (FLOAT_WORDS_BIG_ENDIAN)
+ i = 0, limit = words, dir = 1;
+ else
+ i = words - 1, limit = -1, dir = -1;
+
+ for (; i != limit; i += dir)
+ {
+ sprintf (buffer, "%08lx", target_real[i]);
+ write_chars (buffer, 8);
+ }
+ }
+ else
+ {
+ /* In G++ 3.3 and before the REAL_VALUE_TYPE was written out
+ literally. Note that compatibility with 3.2 is impossible,
+ because the old floating-point emulator used a different
+ format for REAL_VALUE_TYPE. */
+ size_t i;
+ for (i = 0; i < sizeof (TREE_REAL_CST (value)); ++i)
+ write_number (((unsigned char *) &TREE_REAL_CST (value))[i],
+ /*unsigned_p*/ 1,
+ /*base*/ 16);
+ G.need_abi_warning = 1;
+ }
+}
+
/* Non-terminal <identifier>.
<identifier> ::= </unqualified source code identifier> */
@@ -2024,11 +2091,7 @@ write_expression (expr)
"Literal arguments, e.g. "A<42L>", are encoded with their type
and value. Negative integer values are preceded with "n"; for
example, "A<-42L>" becomes "1AILln42EE". The bool value false is
- encoded as 0, true as 1. If floating-point arguments are accepted
- as an extension, their values should be encoded using a
- fixed-length lowercase hexadecimal string corresponding to the
- internal representation (IEEE on IA-64), high-order bytes first,
- without leading zeroes. For example: "Lfbff000000E" is -1.0f." */
+ encoded as 0, true as 1." */
static void
write_template_arg_literal (value)
@@ -2055,24 +2118,7 @@ write_template_arg_literal (value)
write_integer_cst (value);
}
else if (TREE_CODE (value) == REAL_CST)
- {
-#ifdef CROSS_COMPILE
- static int explained;
-
- if (!explained)
- {
- sorry ("real-valued template parameters when cross-compiling");
- explained = 1;
- }
-#else
- size_t i;
- for (i = 0; i < sizeof (TREE_REAL_CST (value)); ++i)
- write_number (((unsigned char *)
- &TREE_REAL_CST (value))[i],
- /*unsigned_p=*/1,
- 16);
-#endif
- }
+ write_real_cst (value);
else
abort ();