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]

Re: PATCH for division by zero in template arguments


>>>>> "Jason" == Jason Merrill <jason@cygnus.com> writes:

>>>>> Mark Mitchell <mark@markmitchell.com> writes:

    >> Here's a fix for your problem.  Jason, OK?

    Jason> No.  The GCC policy is to handle division by zero at
    Jason> runtime.  This is especially important for reals, where
    Jason> division by zero may be deliberate, to generate a NaN.

OK.  Still, since programs that divide by a constant 0 are ill-formed,
not merely undefined, I think this should be a pedwarn.  I also think
the result of the operation should not be marked TREE_CONSTANT, since
it's not: it's a run-time division.

Here's a patch to that effect.

-- 
Mark Mitchell 			mark@markmitchell.com
Mark Mitchell Consulting	http://www.markmitchell.com

1998-06-16  Mark Mitchell  <mark@markmitchell.com>

	* typeck.c (build_binary_op_nodefault): Make dividing by a
	constant zero a pedwarn, rather than a warning.  And don't
	treat such expressions as constants.

Index: testsuite/g++.old-deja/g++.pt/crash10.C
===================================================================
RCS file: crash10.C
diff -N crash10.C
*** /dev/null	Mon Dec 31 20:00:00 1979
--- crash10.C	Tue Jun 16 14:25:33 1998
***************
*** 0 ****
--- 1,11 ----
+ // Build don't link:
+ 
+ template<int M, int N>
+ class GCD {
+ public:
+   enum { val = (N == 0) ? M : GCD<N, M % N>::val }; 
+ };
+ 
+ main() {
+   GCD< 1, 0 >::val; // ERROR - division
+ }
Index: typeck.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/typeck.c,v
retrieving revision 1.84
diff -c -p -r1.84 typeck.c
*** typeck.c	1998/06/17 02:07:28	1.84
--- typeck.c	1998/06/17 18:40:25
*************** build_binary_op_nodefault (code, orig_op
*** 3225,3230 ****
--- 3225,3234 ----
    /* Nonzero means set RESULT_TYPE to the common type of the args.  */
    int common = 0;
  
+   /* Nonzero means the result of the expression is not constant,
+      even if all the operands are.  */
+   int cannot_be_constant = 0;
+ 
    /* Apply default conversions.  */
    if (code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR
        || code == TRUTH_OR_EXPR || code == TRUTH_ORIF_EXPR
*************** build_binary_op_nodefault (code, orig_op
*** 3296,3306 ****
  	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
  	      || code1 == COMPLEX_TYPE))
  	{
! 	  if (TREE_CODE (op1) == INTEGER_CST && integer_zerop (op1))
! 	    cp_warning ("division by zero in `%E / 0'", op0);
! 	  else if (TREE_CODE (op1) == REAL_CST && real_zerop (op1))
! 	    cp_warning ("division by zero in `%E / 0.'", op0);
! 	      
  	  if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE))
  	    resultcode = RDIV_EXPR;
  	  else
--- 3300,3312 ----
  	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
  	      || code1 == COMPLEX_TYPE))
  	{
! 	  if ((TREE_CODE (op1) == INTEGER_CST && integer_zerop (op1))
! 	      || (TREE_CODE (op1) == REAL_CST && real_zerop (op1))) 
! 	    {
! 	      cp_pedwarn ("division by zero in `%E / 0'", op0);
! 	      cannot_be_constant = 1;
! 	    }
! 
  	  if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE))
  	    resultcode = RDIV_EXPR;
  	  else
*************** build_binary_op_nodefault (code, orig_op
*** 3353,3363 ****
  
      case TRUNC_MOD_EXPR:
      case FLOOR_MOD_EXPR:
!       if (code1 == INTEGER_TYPE && integer_zerop (op1))
! 	cp_warning ("division by zero in `%E % 0'", op0);
!       else if (code1 == REAL_TYPE && real_zerop (op1))
! 	cp_warning ("division by zero in `%E % 0.'", op0);
!       
        if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
  	{
  	  /* Although it would be tempting to shorten always here, that loses
--- 3359,3371 ----
  
      case TRUNC_MOD_EXPR:
      case FLOOR_MOD_EXPR:
!       if ((code1 == INTEGER_TYPE && integer_zerop (op1))
! 	  || (code1 == REAL_TYPE && real_zerop (op1)))
! 	{
! 	  cp_pedwarn ("division by zero in `%E / 0'", op0);
! 	  cannot_be_constant = 1;
! 	}
! 
        if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
  	{
  	  /* Although it would be tempting to shorten always here, that loses
*************** build_binary_op_nodefault (code, orig_op
*** 3951,3958 ****
      register tree folded;
  
      folded = fold (result);
!     if (folded == result)
!       TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1);
      if (final_type != 0)
        return cp_convert (final_type, folded);
      return folded;
--- 3959,3967 ----
      register tree folded;
  
      folded = fold (result);
!     if (folded == result) 
!       TREE_CONSTANT (folded) = (!cannot_be_constant &&
! 				TREE_CONSTANT (op0) & TREE_CONSTANT (op1));
      if (final_type != 0)
        return cp_convert (final_type, folded);
      return folded;


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