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

Re: [tree-ssa]: Invalid GIMPLE generated by C++ front end


On Wed, 13 Aug 2003 15:53:41 -0400, Daniel Berlin <dberlin@dberlin.org> wrote:

> I've been seeing expressions like  T.2 = (char * const &)&<UVbbd0>
> generated by the C++ FE lately (compiling string-inst.cc on darwin, for
> instance).
>
> Are these actually valid GIMPLE?

No.  I ran into a similar crash recently; the problem turned out to be with
the inliner inserting nops during &* elimination.  I've attached a patch
below.  Does it fix your bug?

> Going by the grammar, they aren't, and they are causing PTA to miss some
> variables because they fail is_gimple_modify_expr.

Incidentally, I'm in the process of converting all of the gimplification
predicates to only check the tree code in most cases, since that's all I
care about during gimplification.  The underlying nodes will already have
been massaged into the right form by recursive gimplification.

But your comment brings up the possibility that other passes will want to
be able to check whether or not a transformation leaves the code in gimple
form.  Is this what you need?  If so, would calling back into gimplify_expr
be a reasonable alternative (if it worked)?

*** tree-inline.c.~1~	2003-08-12 13:41:34.000000000 -0400
--- tree-inline.c	2003-08-12 15:39:46.000000000 -0400
*************** copy_body_r (tree *tp, int *walk_subtree
*** 460,465 ****
--- 464,480 ----
  	      if (TREE_CODE (value) == INDIRECT_REF)
  		{
  		  *tp = convert (TREE_TYPE (*tp), TREE_OPERAND (value, 0));
+ 		  if (TREE_CODE (*tp) == NOP_EXPR)
+ 		    {
+ 		      if (POINTER_TYPE_P (TREE_TYPE (*tp))
+ 			  && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (*tp, 0)))
+ 			  && (TREE_TYPE (TREE_TYPE (*tp))
+ 			      == TREE_TYPE (TREE_TYPE (TREE_OPERAND (*tp, 0)))))
+ 			/* Strip a conversion between pointer and reference.  */
+ 			*tp = TREE_OPERAND (*tp, 0);
+ 		      else if (keep_function_tree_in_gimple_form (id->decl))
+ 			abort ();
+ 		    }
  		  return copy_body_r (tp, walk_subtrees, data);
  		}
  	    }
*************** copy_body_r (tree *tp, int *walk_subtree
*** 478,485 ****
  	      STRIP_NOPS (value);
  	      if (TREE_CODE (value) == ADDR_EXPR)
  		{
! 		  *tp = (tree) n->value;
! 		  return copy_body_r (tp, walk_subtrees, data);
  		}
  	    }
  	}
--- 493,506 ----
  	      STRIP_NOPS (value);
  	      if (TREE_CODE (value) == ADDR_EXPR)
  		{
! 		  if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (value, 0)))
! 		      == TYPE_MAIN_VARIANT (TREE_TYPE (*tp)))
! 		    {
! 		      *tp = TREE_OPERAND (value, 0);
! 		      return copy_body_r (tp, walk_subtrees, data);
! 		    }
! 		  else if (keep_function_tree_in_gimple_form (id->decl))
! 		    abort ();
  		}
  	    }
  	}

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