Patchwork Fix interpret_float on imaginary with -std=c99 and excess precision (PR c/47473)

login
register
mail settings
Submitter Jakub Jelinek
Date Jan. 26, 2011, 7:34 p.m.
Message ID <20110126193422.GJ2724@tyan-ft48-01.lab.bos.redhat.com>
Download mbox | patch
Permalink /patch/80543/
State New
Headers show

Comments

Jakub Jelinek - Jan. 26, 2011, 7:34 p.m.
Hi!

For 1.0iF interpret_float was incorrectly returning EXCESS_PRECISION_EXPR
with type float instead of _Complex float (with correct subexpression
COMPLEX_EXPR with _Complex long double type).  This bug confused later on
other parts of the FE (e.g. in an expression containing a scalar on one side
and this complex on another side none of the type codes were COMPLEX_TYPE).

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

2011-01-26  Jakub Jelinek  <jakub@redhat.com>

	PR c/47473
	* c-lex.c (interpret_float): If CPP_N_IMAGINARY, ensure
	EXCESS_PRECISION_EXPR is created with COMPLEX_TYPE instead of
	REAL_TYPE.

	* gcc.dg/torture/pr47473.c: New test.


	Jakub
Joseph S. Myers - Jan. 26, 2011, 8:02 p.m.
On Wed, 26 Jan 2011, Jakub Jelinek wrote:

> 2011-01-26  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR c/47473
> 	* c-lex.c (interpret_float): If CPP_N_IMAGINARY, ensure
> 	EXCESS_PRECISION_EXPR is created with COMPLEX_TYPE instead of
> 	REAL_TYPE.
> 
> 	* gcc.dg/torture/pr47473.c: New test.

OK.

Patch

--- gcc/c-family/c-lex.c.jj	2010-12-02 13:14:58.000000000 +0100
+++ gcc/c-family/c-lex.c	2011-01-26 15:57:07.750402034 +0100
@@ -752,8 +752,15 @@  interpret_float (const cpp_token *token,
   /* Create a node with determined type and value.  */
   value = build_real (const_type, real);
   if (flags & CPP_N_IMAGINARY)
-    value = build_complex (NULL_TREE, convert (const_type, integer_zero_node),
-			   value);
+    {
+      value = build_complex (NULL_TREE, convert (const_type,
+						 integer_zero_node), value);
+      if (type != const_type)
+	{
+	  const_type = TREE_TYPE (value);
+	  type = build_complex_type (type);
+	}
+    }
 
   if (type != const_type)
     value = build1 (EXCESS_PRECISION_EXPR, type, value);
--- gcc/testsuite/gcc.dg/torture/pr47473.c.jj	2011-01-26 16:11:55.255764078 +0100
+++ gcc/testsuite/gcc.dg/torture/pr47473.c	2011-01-26 16:14:08.537651972 +0100
@@ -0,0 +1,14 @@ 
+/* PR c/47473 */
+/* { dg-do run } */
+/* { dg-options "-std=c99" } */
+
+int
+main (void)
+{
+  long double _Complex w = 0.2L - 0.3iL;
+  w = w * (0.3L - (0.0F + 1.0iF) * 0.9L);
+  if (__builtin_fabsl (__real__ w + 0.21L) > 0.001L
+      || __builtin_fabsl (__imag__ w + 0.27L) > 0.001L)
+    __builtin_abort ();
+  return 0;
+}