This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/8861] [3.3/3.4 regression] [ABI] mangling floating point literal in template arg expression


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 ();


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]