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]

[PATCH][no-undefined-overflow][2/2] Basic C frontend support


This enables the C frontend to generate the *NV_EXPR variants for
arithmetic involving undefined overflow (thus, signed and not flag_wrapv).
For pointer arithmetic flag_wrapv doesn't apply (does it?) and I'm not
sure about flag_strict_overflow (what's the difference to flag_wrapv
again?).

Anyway - I expect that this patch gets reverted later and replaced by
proper C frontend support from the frontend maintainers.

Bootstrapped and tested on x86_64-unknown-linux-gnu (C only), applied
to the branch.

Richard.

2009-03-05  Richard Guenther  <rguenther@suse.de>

	* c-common.c (pointer_int_sum): Use *NV_EXPR codes for
	pointer arithmetic.
	* c-typeck.c (build_unary_op): Use NEGATENV_EXPR if
	signed arithmetic has undefined overflow.
	(build_binary_op): Handle *NV_EXPR for recursive invocations.
	If signed arithmetic has undefined overflow use
	PLUSNV_EXPR, MINUSNV_EXPR and MULTNV_EXPR.
	* c-omp.c (c_finish_omp_for): Deal with *NV_EXPR for increments.

Index: trunk/gcc/c-common.c
===================================================================
*** trunk.orig/gcc/c-common.c	2009-03-05 14:58:05.000000000 +0100
--- trunk/gcc/c-common.c	2009-03-05 15:42:12.000000000 +0100
*************** pointer_int_sum (enum tree_code resultco
*** 3287,3300 ****
       type for the pointer operation.  */
    intop = convert (sizetype,
  		   build_binary_op (EXPR_LOCATION (intop),
! 				    MULT_EXPR, intop,
  				    convert (TREE_TYPE (intop), size_exp), 1));
  
    /* Create the sum or difference.  */
    if (resultcode == MINUS_EXPR)
!     intop = fold_build1 (NEGATE_EXPR, sizetype, intop);
  
!   ret = fold_build2 (POINTER_PLUS_EXPR, result_type, ptrop, intop);
  
    fold_undefer_and_ignore_overflow_warnings ();
  
--- 3287,3300 ----
       type for the pointer operation.  */
    intop = convert (sizetype,
  		   build_binary_op (EXPR_LOCATION (intop),
! 				    MULTNV_EXPR, intop,
  				    convert (TREE_TYPE (intop), size_exp), 1));
  
    /* Create the sum or difference.  */
    if (resultcode == MINUS_EXPR)
!     intop = fold_build1 (NEGATENV_EXPR, sizetype, intop);
  
!   ret = fold_build2 (POINTER_PLUSNV_EXPR, result_type, ptrop, intop);
  
    fold_undefer_and_ignore_overflow_warnings ();
  
Index: trunk/gcc/c-typeck.c
===================================================================
*** trunk.orig/gcc/c-typeck.c	2009-03-05 14:58:05.000000000 +0100
--- trunk/gcc/c-typeck.c	2009-03-05 15:42:12.000000000 +0100
*************** build_unary_op (location_t location,
*** 3260,3265 ****
--- 3260,3272 ----
  
    if (argtype == 0)
      argtype = TREE_TYPE (arg);
+ 
+   if (!flag_wrapv
+       && TREE_CODE (argtype) == INTEGER_TYPE
+       && !TYPE_UNSIGNED (argtype)
+       && code == NEGATE_EXPR)
+     code = NEGATENV_EXPR;
+ 
    ret = require_constant_value ? fold_build1_initializer (code, argtype, arg)
  			       : fold_build1 (code, argtype, arg);
   return_build_unary_op:
*************** build_binary_op (location_t location, en
*** 8104,8109 ****
--- 8111,8117 ----
    switch (code)
      {
      case PLUS_EXPR:
+     case PLUSNV_EXPR:
        /* Handle the pointer + int case.  */
        if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
  	{
*************** build_binary_op (location_t location, en
*** 8120,8125 ****
--- 8128,8134 ----
        break;
  
      case MINUS_EXPR:
+     case MINUSNV_EXPR:
        /* Subtraction of two similar pointers.
  	 We must subtract them as integers, then divide by object size.  */
        if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
*************** build_binary_op (location_t location, en
*** 8139,8144 ****
--- 8148,8154 ----
        break;
  
      case MULT_EXPR:
+     case MULTNV_EXPR:
        common = 1;
        break;
  
*************** build_binary_op (location_t location, en
*** 8563,8568 ****
--- 8573,8590 ----
    if (build_type == NULL_TREE)
      build_type = result_type;
  
+   if (TREE_CODE (build_type) == INTEGER_TYPE
+       && !TYPE_UNSIGNED (build_type)
+       && !flag_wrapv)
+     {
+       if (resultcode == PLUS_EXPR)
+ 	resultcode = PLUSNV_EXPR;
+       else if (resultcode == MINUS_EXPR)
+ 	resultcode = MINUSNV_EXPR;
+       else if (resultcode == MULT_EXPR)
+ 	resultcode = MULTNV_EXPR;
+     }
+ 
    /* Treat expressions in initializers specially as they can't trap.  */
    ret = require_constant_value ? fold_build2_initializer (resultcode,
  							  build_type,
Index: trunk/gcc/c-omp.c
===================================================================
*** trunk.orig/gcc/c-omp.c	2009-01-29 17:14:52.000000000 +0100
--- trunk/gcc/c-omp.c	2009-03-05 15:44:09.000000000 +0100
*************** c_finish_omp_for (location_t locus, tree
*** 375,387 ****
  		break;
  	      if (TREE_OPERAND (incr, 1) == decl)
  		break;
! 	      if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
  		  && (TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl
  		      || TREE_OPERAND (TREE_OPERAND (incr, 1), 1) == decl))
  		incr_ok = true;
! 	      else if ((TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR
! 			|| (TREE_CODE (TREE_OPERAND (incr, 1))
! 			    == POINTER_PLUS_EXPR))
  		       && TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl)
  		incr_ok = true;
  	      else
--- 375,386 ----
  		break;
  	      if (TREE_OPERAND (incr, 1) == decl)
  		break;
! 	      if (PLUS_EXPR_P (TREE_OPERAND (incr, 1))
  		  && (TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl
  		      || TREE_OPERAND (TREE_OPERAND (incr, 1), 1) == decl))
  		incr_ok = true;
! 	      else if ((MINUS_EXPR_P (TREE_OPERAND (incr, 1))
! 			|| POINTER_PLUS_EXPR_P (TREE_OPERAND (incr, 1)))
  		       && TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl)
  		incr_ok = true;
  	      else


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