This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/8861] [3.3/3.4 regression] [ABI] mangling floating point literal in template arg expression
- From: "zack at codesourcery dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 8 Jun 2003 21:32:47 -0000
- Subject: [Bug c++/8861] [3.3/3.4 regression] [ABI] mangling floating point literal in template arg expression
- References: <20021207125600.8861.catherin@ca.ibm.com>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=8861
------- Additional Comments From zack@codesourcery.com 2003-06-08 21:32 -------
Subject: Re: PATCH: mangling floating point literal in
template arg expression
Here's a revised patch. Line numbers may be offset -- I have some
other experimental changes in mangle.c right now. Differences from
the previous: leading zeroes are stripped; provide backward
compatibility with 3.3 under -fabi-version=1. There is no hope for
backward compatibility with 3.2.
zw
* mangle.c (write_real_cst): New function. Implement
ABI-correct mangling of floating point numbers in template
parameters when -fabi-version=2.
(write_template_arg_literal): Use it.
===================================================================
Index: mangle.c
--- mangle.c 3 Apr 2003 03:45:48 -0000 1.68
+++ mangle.c 8 Jun 2003 21:29:13 -0000
@@ -175,6 +176,7 @@ static int hwint_to_ascii PARAMS ((unsig
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 +1263,70 @@ write_integer_cst (cst)
}
}
+/* Write out a floating-point literal.
+
+ "Floating-point literals are encoded using a fixed-length
+ lowercase hexadecimal string corresponding to the internal
+ representation (IEEE on Itanium), high-order bytes first,
+ without leading zeroes. For example: "Lf bf800000 E" is
+ -1.0f on Itanium."
+
+ 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. Leading zeroes are supposed to be skipped, which
+ requires a certain amount of care. */
+ if (FLOAT_WORDS_BIG_ENDIAN)
+ i = 0, limit = words, dir = 1;
+ else
+ i = words - 1, limit = -1, dir = -1;
+
+ for (; i != limit; i += dir)
+ if (target_real[i] != 0)
+ break;
+
+ if (i == limit)
+ return; /* 0.0 is mangled as the empty string */
+
+ sprintf (buffer, "%lx", target_real[i]);
+ write_chars (buffer, strlen (buffer));
+ i += dir;
+
+ for (; i != limit; i += dir)
+ {
+ sprintf (buffer, "%08lx", target_real[i]);
+ write_chars (buffer, 8);
+ }
+ }
+ else
+ {
+ /* In G++ 3.2 the REAL_VALUE_TYPE was written out literally. */
+ 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 +2159,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 +2186,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 ();