This is the mail archive of the gcc-patches@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]

[3.4 Committed] PR21709: ICE folding complex division


The following patch resolves PR middle-end/21709 which is an ICE on
valid regression against the 3.4 branch, caused by missing NULL
pointer checks in fold-const.c's const_binop.

The problem is that if we're honoring floating point exceptions,
attempts to fold 1.0/0.0 using const_binop returns a NULL_TREE.
Hence the complex division case in const_binop needs to check the
return values, before passing invalid operands to build_complex,
which then triggers the crash.  I also took the opportunity to
tidy up the code a little, hopefully making it a bit more readable
and reducing the number of conditional jumps.

The same code exists on mainline and the 4.0 branch, but is currently
latent as we now process complex operations slightly differently.  I
propose to also apply this patch to mainline to prevent problems from
resurfacing, but leave gcc-4_0-branch as it is (as the problem is
safely latent until someone finds a way to trigger this bug there).


The following patch has been tested on i686-pc-linux-gnu on both
mainline and the gcc-3_4-branch, with a full "make bootstrap", all
default languages, and regression tested with a top-level "make -k
check" with no new failures.

Shortly to be committed to both mainline and the gcc-3_4-branch.



2005-05-25  Roger Sayle  <roger@eyesopen.com>

	PR middle-end/21709
	* fold-const.c (const_binop): Check for division by zero during
	complex division.

        * gcc.dg/pr21709-1.c: New test case.


Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.322.2.16
diff -c -3 -p -r1.322.2.16 fold-const.c
*** fold-const.c	11 Feb 2005 21:12:48 -0000	1.322.2.16
--- fold-const.c	24 May 2005 17:59:15 -0000
*************** const_binop (enum tree_code code, tree a
*** 1467,1499 ****

  	case RDIV_EXPR:
  	  {
  	    tree magsquared
  	      = const_binop (PLUS_EXPR,
  			     const_binop (MULT_EXPR, r2, r2, notrunc),
  			     const_binop (MULT_EXPR, i2, i2, notrunc),
  			     notrunc);

! 	    t = build_complex (type,
! 			       const_binop
! 			       (INTEGRAL_TYPE_P (TREE_TYPE (r1))
! 				? TRUNC_DIV_EXPR : RDIV_EXPR,
! 				const_binop (PLUS_EXPR,
! 					     const_binop (MULT_EXPR, r1, r2,
! 							  notrunc),
! 					     const_binop (MULT_EXPR, i1, i2,
! 							  notrunc),
! 					     notrunc),
! 				magsquared, notrunc),
! 			       const_binop
! 			       (INTEGRAL_TYPE_P (TREE_TYPE (r1))
! 				? TRUNC_DIV_EXPR : RDIV_EXPR,
! 				const_binop (MINUS_EXPR,
! 					     const_binop (MULT_EXPR, i1, r2,
! 							  notrunc),
! 					     const_binop (MULT_EXPR, r1, i2,
! 							  notrunc),
! 					     notrunc),
! 				magsquared, notrunc));
  	  }
  	  break;

--- 1467,1502 ----

  	case RDIV_EXPR:
  	  {
+ 	    tree t1, t2, real, imag;
  	    tree magsquared
  	      = const_binop (PLUS_EXPR,
  			     const_binop (MULT_EXPR, r2, r2, notrunc),
  			     const_binop (MULT_EXPR, i2, i2, notrunc),
  			     notrunc);

! 	    t1 = const_binop (PLUS_EXPR,
! 			      const_binop (MULT_EXPR, r1, r2, notrunc),
! 			      const_binop (MULT_EXPR, i1, i2, notrunc),
! 			      notrunc);
! 	    t2 = const_binop (MINUS_EXPR,
! 			      const_binop (MULT_EXPR, i1, r2, notrunc),
! 			      const_binop (MULT_EXPR, r1, i2, notrunc),
! 			      notrunc);
!
! 	    if (INTEGRAL_TYPE_P (TREE_TYPE (r1)))
! 	      {
! 		real = const_binop (TRUNC_DIV_EXPR, t1, magsquared, notrunc);
! 		imag = const_binop (TRUNC_DIV_EXPR, t2, magsquared, notrunc);
! 	      }
! 	    else
! 	      {
! 		real = const_binop (RDIV_EXPR, t1, magsquared, notrunc);
! 		imag = const_binop (RDIV_EXPR, t2, magsquared, notrunc);
! 		if (!real || !imag)
! 		  return NULL_TREE;
! 	      }
!
! 	    t = build_complex (type, real, imag);
  	  }
  	  break;


/* PR middle-end/21709 */
/* { dg-do compile } */
/* { dg-options "-O2" } */

double _Complex f(void) { return 1.0iF / 0.0; }



Roger
--


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