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]

fix middle-end/17397


In the beginning, fold_builtin_strlen constructs

	<indirect_ref <char>
	  <addr_expr <char *>
	    <var_decl <char []> s>>>

which, according to the rules we have in check_pointer_types, is fine.
Then the VLA code comes along and replaces this, during gimplifcation, with

	<indirect_ref <char>
	  <addr_expr <char *>
	    <indirect_ref <char []>
	      <var_decl <char (*)[]> s.1>>>

which is also fine.  But gimplify_addr_expr didn't take into account the
possible type change that occurs from stripping addr_expr+indirect_ref
and simplifies to

	<indirect_ref <char>
	  <var_decl <char (*)[]> s.1>>

which is not fine, and check_pointer_types_r catches the mistake.

Fixed by detecting the case (and with assertions, *only* that case), and
adds a cast as appropriate, so we get

	<indirect_ref <char>
	  <nop_expr <char *>
	    <var_decl <char (*)[]> s.1>>>

which is as good a fix as any, I think.

Bootstrapped and tested on i686-linux.


r~


	* gimplify.c (gimplify_addr_expr): Don't inadvertently change types
	while folding <ADDR_EXPR <INDIRECT_REF X>>.

Index: gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gimplify.c,v
retrieving revision 2.76
diff -c -p -d -r2.76 gimplify.c
*** gimplify.c	11 Sep 2004 00:25:00 -0000	2.76
--- gimplify.c	15 Sep 2004 02:07:35 -0000
*************** typedef struct gimple_temp_hash_elt
*** 74,79 ****
--- 74,82 ----
  
  /* Forward declarations.  */
  static enum gimplify_status gimplify_compound_expr (tree *, tree *, bool);
+ #ifdef ENABLE_CHECKING
+ static bool cpt_same_type (tree a, tree b);
+ #endif
  
  
  /* Return a hash value for a formal temporary table entry.  */
*************** gimplify_addr_expr (tree *expr_p, tree *
*** 3051,3062 ****
    switch (TREE_CODE (op0))
      {
      case INDIRECT_REF:
        /* Check if we are dealing with an expression of the form '&*ptr'.
  	 While the front end folds away '&*ptr' into 'ptr', these
  	 expressions may be generated internally by the compiler (e.g.,
  	 builtins like __builtin_va_end).  */
!       *expr_p = TREE_OPERAND (op0, 0);
!       ret = GS_OK;
        break;
  
      case VIEW_CONVERT_EXPR:
--- 3054,3087 ----
    switch (TREE_CODE (op0))
      {
      case INDIRECT_REF:
+     do_indirect_ref:
        /* Check if we are dealing with an expression of the form '&*ptr'.
  	 While the front end folds away '&*ptr' into 'ptr', these
  	 expressions may be generated internally by the compiler (e.g.,
  	 builtins like __builtin_va_end).  */
!       /* Caution: the silent array decomposition semantics we allow for
! 	 ADDR_EXPR means we can't always discard the pair.  */
!       {
! 	tree op00 = TREE_OPERAND (op0, 0);
! 	tree t_expr = TREE_TYPE (expr);
! 	tree t_op00 = TREE_TYPE (op00);
! 
!         if (!lang_hooks.types_compatible_p (t_expr, t_op00))
! 	  {
! #ifdef ENABLE_CHECKING
! 	    tree t_op0 = TREE_TYPE (op0);
! 	    gcc_assert (TREE_CODE (t_op0) == ARRAY_TYPE
! 			&& POINTER_TYPE_P (t_expr)
! 			&& cpt_same_type (TREE_TYPE (t_op0),
! 					  TREE_TYPE (t_expr))
! 			&& POINTER_TYPE_P (t_op00)
! 			&& cpt_same_type (t_op0, TREE_TYPE (t_op00)));
! #endif
! 	    op00 = fold_convert (TREE_TYPE (expr), op00);
! 	  }
!         *expr_p = op00;
!         ret = GS_OK;
!       }
        break;
  
      case VIEW_CONVERT_EXPR:
*************** gimplify_addr_expr (tree *expr_p, tree *
*** 3079,3092 ****
  			   is_gimple_addressable, fb_either);
        if (ret != GS_ERROR)
  	{
! 	  /* The above may have made an INDIRECT_REF (e.g, Ada's NULL_EXPR),
! 	     so check for it here.  It's not worth checking for the other
! 	     cases above.  */
! 	  if (TREE_CODE (TREE_OPERAND (expr, 0)) == INDIRECT_REF)
! 	    {
! 	      *expr_p = TREE_OPERAND (TREE_OPERAND (expr, 0), 0);
! 	      break;
! 	    }
  
  	  /* Make sure TREE_INVARIANT, TREE_CONSTANT, and TREE_SIDE_EFFECTS
  	     is set properly.  */
--- 3104,3115 ----
  			   is_gimple_addressable, fb_either);
        if (ret != GS_ERROR)
  	{
! 	  op0 = TREE_OPERAND (expr, 0);
! 
! 	  /* For various reasons, the gimplification of the expression
! 	     may have made a new INDIRECT_REF.  */
! 	  if (TREE_CODE (op0) == INDIRECT_REF)
! 	    goto do_indirect_ref;
  
  	  /* Make sure TREE_INVARIANT, TREE_CONSTANT, and TREE_SIDE_EFFECTS
  	     is set properly.  */
Index: testsuite/gcc.c-torture/compile/pr17397.c
===================================================================
RCS file: testsuite/gcc.c-torture/compile/pr17397.c
diff -N testsuite/gcc.c-torture/compile/pr17397.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.c-torture/compile/pr17397.c	15 Sep 2004 02:07:38 -0000
***************
*** 0 ****
--- 1,12 ----
+ /* ICE due to invalid GIMPLE created during strlen simplification.  */
+ 
+ extern unsigned long strlen (__const char *__s);
+ extern void bar ();
+ extern int cols;
+ 
+ void foo (void)
+ {
+   char s[cols + 2];
+   if (strlen (s) > 0)
+     bar ();
+ }


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