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] Enable type-checking throughout the compilation


This patch enables the gimple type checking machinery throughout the
compilation pipeline (after I have (again) fixed most of the current
issues).

To pass bootstrap & regtest for all languages the tree-inline.c
hunk is needed for building libstdc++ (the C++ FE passes void * NULL
pointers around with the constructor cloning stuff which may need
fixups - but those do not trigger because the cloned bodies are
not re-gimplified.  This can be removed again after we use the
inliner for C++ constructor cloning).  The verifier hunks for Ada
can go once Eric succeeds in getting rid of the subtype mess, without
the hunks the RTS fails to build.  The Java part was submitted
separately and is awaiting review.

There are some remaining ICEs (I will reply to this mail with full
testresults once they arrive), one OpenMP related, several --combine
ones (ugh) and one ipa-struct-reorg related one (that one is really
broken in the way it patches memory references - see the hint in this
patch).

I'm going to apply the vectorizer PLUS_EXPR check fixups and the
ipa-struct-reorg parts after they passed testing.

I will also file bugreports about the remaining fails once the
patch gets committed.

Full bootstrap & regtest running.

Thus - ok for trunk (given the Java parts are approved)?  I do not
really want to repeat this fix-the-fallout-from-the-last-year
experiment too often ...

Thanks,
Richard.


2009-04-16  Richard Guenther  <rguenther@suse.de>

	* tree-cfg.c (remove_useless_stmts): Verify stmts afterwards.
	(verify_gimple_assign_binary): Work around Ada subtype issues.
	Allow POINTER_PLUS_EXPR-like PLUS_EXPR for vectors.
	(verify_stmts): Dispatch to gimple/type verification code.
	* tree-inline.c (remap_gimple_op_r): Work around C++ FE
	issue with call argument types.

	* ipa-struct-reorg.c (gen_size): Fold the built expressions.
	(create_general_new_stmt): Note that this function is broken.

	java/
	PR java/38374
	* constants.c (build_constants_constructor): Retain the old
	pointer type as valid TYPE_POINTER_TO after patching the
	type of the constant pool decl.

Index: gcc/tree-cfg.c
===================================================================
*** gcc/tree-cfg.c.orig	2009-04-16 14:43:17.000000000 +0200
--- gcc/tree-cfg.c	2009-04-16 15:01:50.000000000 +0200
*************** remove_useless_stmts (void)
*** 2083,2088 ****
--- 2083,2093 ----
        remove_useless_stmts_1 (&gsi, &data);
      }
    while (data.repeat);
+ 
+ #ifdef ENABLE_TYPES_CHECKING
+   verify_types_in_gimple_seq (gimple_body (current_function_decl));
+ #endif
+ 
    return 0;
  }
  
*************** verify_gimple_assign_binary (gimple stmt
*** 3568,3575 ****
--- 3573,3624 ----
  	return false;
        }
  
+     case PLUS_EXPR:
+       {
+ 	/* We use regular PLUS_EXPR for vectors.
+ 	   ???  This just makes the checker happy and may not be what is
+ 	   intended.  */
+ 	if (TREE_CODE (lhs_type) == VECTOR_TYPE
+ 	    && POINTER_TYPE_P (TREE_TYPE (lhs_type)))
+ 	  {
+ 	    if (TREE_CODE (rhs1_type) != VECTOR_TYPE
+ 		|| TREE_CODE (rhs2_type) != VECTOR_TYPE)
+ 	      {
+ 		error ("invalid non-vector operands to vector valued plus");
+ 		return true;
+ 	      }
+ 	    lhs_type = TREE_TYPE (lhs_type);
+ 	    rhs1_type = TREE_TYPE (rhs1_type);
+ 	    rhs2_type = TREE_TYPE (rhs2_type);
+ 	    /* PLUS_EXPR is commutative, so we might end up canonicalizing
+ 	       the pointer to 2nd place.  */
+ 	    if (POINTER_TYPE_P (rhs2_type))
+ 	      {
+ 		tree tem = rhs1_type;
+ 		rhs1_type = rhs2_type;
+ 		rhs2_type = tem;
+ 	      }
+ 	    goto do_pointer_plus_expr_check;
+ 	  }
+       }
+     /* Fallthru.  */
+     case MINUS_EXPR:
+       {
+ 	if (POINTER_TYPE_P (lhs_type)
+ 	    || POINTER_TYPE_P (rhs1_type)
+ 	    || POINTER_TYPE_P (rhs2_type))
+ 	  {
+ 	    error ("invalid (pointer) operands to plus/minus");
+ 	    return true;
+ 	  }
+ 
+ 	/* Continue with generic binary expression handling.  */
+ 	break;
+       }
+ 
      case POINTER_PLUS_EXPR:
        {
+ do_pointer_plus_expr_check:
  	if (!POINTER_TYPE_P (rhs1_type)
  	    || !useless_type_conversion_p (lhs_type, rhs1_type)
  	    || !useless_type_conversion_p (sizetype, rhs2_type))
*************** verify_gimple_assign_binary (gimple stmt
*** 3625,3645 ****
  	 connected to the operand types.  */
        return verify_gimple_comparison (lhs_type, rhs1, rhs2);
  
-     case PLUS_EXPR:
-     case MINUS_EXPR:
-       {
- 	if (POINTER_TYPE_P (lhs_type)
- 	    || POINTER_TYPE_P (rhs1_type)
- 	    || POINTER_TYPE_P (rhs2_type))
- 	  {
- 	    error ("invalid (pointer) operands to plus/minus");
- 	    return true;
- 	  }
- 
- 	/* Continue with generic binary expression handling.  */
- 	break;
-       }
- 
      case WIDEN_SUM_EXPR:
      case WIDEN_MULT_EXPR:
      case VEC_WIDEN_MULT_HI_EXPR:
--- 3674,3679 ----
*************** verify_gimple_assign_binary (gimple stmt
*** 3677,3684 ****
        gcc_unreachable ();
      }
  
!   if (!useless_type_conversion_p (lhs_type, rhs1_type)
!       || !useless_type_conversion_p (lhs_type, rhs2_type))
      {
        error ("type mismatch in binary expression");
        debug_generic_stmt (lhs_type);
--- 3711,3727 ----
        gcc_unreachable ();
      }
  
!   if ((!useless_type_conversion_p (lhs_type, rhs1_type)
!        /* ???  Ada hack.  Subtypes suck.  We leak arithmetics in it a lot
! 	  which breaks the type system.  */
!        && !(INTEGRAL_TYPE_P (rhs1_type)
! 	    && TREE_TYPE (rhs1_type)
! 	    && useless_type_conversion_p (lhs_type, TREE_TYPE (rhs1_type))))
!       || (!useless_type_conversion_p (lhs_type, rhs2_type)
! 	  /* ???  See above.  */
! 	  && !(INTEGRAL_TYPE_P (rhs2_type)
! 	       && TREE_TYPE (rhs2_type)
! 	       && useless_type_conversion_p (lhs_type, TREE_TYPE (rhs2_type)))))
      {
        error ("type mismatch in binary expression");
        debug_generic_stmt (lhs_type);
*************** verify_stmts (void)
*** 4280,4285 ****
--- 4323,4336 ----
  		  err |= true;
  		}
  	    }
+ 
+ #ifdef ENABLE_TYPES_CHECKING
+ 	  if (verify_gimple_phi (phi))
+ 	    {
+ 	      debug_gimple_stmt (phi);
+ 	      err |= true;
+ 	    }
+ #endif
  	}
  
        for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
*************** verify_stmts (void)
*** 4316,4321 ****
--- 4367,4380 ----
  	    }
  
  	  err |= verify_stmt (&gsi);
+ 
+ #ifdef ENABLE_TYPES_CHECKING
+ 	  if (verify_types_in_gimple_stmt (gsi_stmt (gsi)))
+ 	    {
+ 	      debug_gimple_stmt (stmt);
+ 	      err |= true;
+ 	    }
+ #endif
  	  addr = walk_gimple_op (gsi_stmt (gsi), verify_node_sharing, &wi);
  	  if (addr)
  	    {
Index: gcc/tree-inline.c
===================================================================
*** gcc/tree-inline.c.orig	2009-04-16 14:43:17.000000000 +0200
--- gcc/tree-inline.c	2009-04-16 14:46:46.000000000 +0200
*************** remap_gimple_op_r (tree *tp, int *walk_s
*** 705,710 ****
--- 705,717 ----
        gcc_assert (new_decl);
        /* Replace this variable with the copy.  */
        STRIP_TYPE_NOPS (new_decl);
+       /* ???  The C++ frontend uses void * pointer zero to initialize
+          any other type.  This confuses the middle-end type verification.
+ 	 As cloned bodies do not go through gimplification again the fixup
+ 	 there doesn't trigger.  */
+       if (TREE_CODE (new_decl) == INTEGER_CST
+ 	  && !useless_type_conversion_p (TREE_TYPE (*tp), TREE_TYPE (new_decl)))
+ 	new_decl = fold_convert (TREE_TYPE (*tp), new_decl);
        *tp = new_decl;
        *walk_subtrees = 0;
      }
Index: gcc/java/constants.c
===================================================================
*** gcc/java/constants.c.orig	2009-04-16 14:43:17.000000000 +0200
--- gcc/java/constants.c	2009-04-16 14:46:46.000000000 +0200
*************** build_constants_constructor (void)
*** 557,569 ****
--- 557,578 ----
        tree data_decl, tags_decl, tags_type;
        tree max_index = build_int_cst (sizetype, outgoing_cpool->count - 1);
        tree index_type = build_index_type (max_index);
+       tree tem;
  
        /* Add dummy 0'th element of constant pool. */
        tags_list = tree_cons (NULL_TREE, get_tag_node (0), tags_list);
        data_list = tree_cons (NULL_TREE, null_pointer_node, data_list);
    
+       /* Change the type of the decl to have the proper array size.
+          ???  Make sure to transition the old type-pointer-to list to this
+ 	 new type to not invalidate all build address expressions.  */
        data_decl = build_constant_data_ref (false);
+       tem = TYPE_POINTER_TO (TREE_TYPE (data_decl));
+       if (!tem)
+ 	tem = build_pointer_type (TREE_TYPE (data_decl));
+       TYPE_POINTER_TO (TREE_TYPE (data_decl)) = NULL_TREE;
        TREE_TYPE (data_decl) = build_array_type (ptr_type_node, index_type);
+       TYPE_POINTER_TO (TREE_TYPE (data_decl)) = tem;
        DECL_INITIAL (data_decl) = build_constructor_from_list
  				  (TREE_TYPE (data_decl), data_list);
        DECL_SIZE (data_decl) = TYPE_SIZE (TREE_TYPE (data_decl));
Index: gcc/ipa-struct-reorg.c
===================================================================
*** gcc/ipa-struct-reorg.c.orig	2009-04-16 14:43:17.000000000 +0200
--- gcc/ipa-struct-reorg.c	2009-04-16 14:46:46.000000000 +0200
*************** gen_size (tree num, tree type, tree *res
*** 606,618 ****
    if (exact_log2 (struct_size_int) == -1)
      {
        tree size = build_int_cst (TREE_TYPE (num), struct_size_int);
!       new_stmt = gimple_build_assign_with_ops (MULT_EXPR, *res, num, size);
      }
    else
      {
        tree C = build_int_cst (TREE_TYPE (num), exact_log2 (struct_size_int));
   
!       new_stmt = gimple_build_assign_with_ops (LSHIFT_EXPR, *res, num, C);
      }
  
    finalize_stmt (new_stmt);
--- 606,622 ----
    if (exact_log2 (struct_size_int) == -1)
      {
        tree size = build_int_cst (TREE_TYPE (num), struct_size_int);
!       new_stmt = gimple_build_assign (*res, fold_build2 (MULT_EXPR,
! 							 TREE_TYPE (num),
! 							 num, size));
      }
    else
      {
        tree C = build_int_cst (TREE_TYPE (num), exact_log2 (struct_size_int));
   
!       new_stmt = gimple_build_assign (*res, fold_build2 (LSHIFT_EXPR,
! 							 TREE_TYPE (num),
! 							 num, C));
      }
  
    finalize_stmt (new_stmt);
*************** create_general_new_stmt (struct access_s
*** 1291,1296 ****
--- 1295,1302 ----
  	    {
  	      pos = find_pos_in_stmt (new_stmt, var);
  	      gcc_assert (pos);
+ 	      /* ???  This misses adjustments to the type of the
+ 	         INDIRECT_REF we possibly replace the operand of.  */
  	      *pos = new_var;
  	    }      
  	}


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