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]

Re: PR middle-end/30017 (ICE in C++ size hook)


> 
> I think returning NULL_TREE would be OK.  You should then make expr_size
> and int_expr_size abort, if they get NULL.  But, you could use the hook
> directly while folding, and only do the simplification to a block copy
> if you get a non-NULL value.

OK, I am testing the attached patch that should do the trick
(and in addition it replaces operands_equal_p with tree_int_cst_equal in
the test validating the size as I don't think the size and signedness of
operand should matter.  It already has the nice property of reutrning
false when operandis NULL).

Honza

	* cp/cp-objcp-common.c (cp_expr_size): Return NULL in the case
	size is undefined.
	* builtins.c (fold_builtin_memory_op): Check that expr_size match.
	* explow.c (expr_size, int_expr_size): Assert that size is non_NULL.
Index: cp/cp-objcp-common.c
===================================================================
*** cp/cp-objcp-common.c	(revision 119467)
--- cp/cp-objcp-common.c	(working copy)
*************** cp_expr_size (tree exp)
*** 82,104 ****
        /* The backend should not be interested in the size of an expression
  	 of a type with both of these set; all copies of such types must go
  	 through a constructor or assignment op.  */
!       gcc_assert (!TYPE_HAS_COMPLEX_INIT_REF (type)
! 		  || !TYPE_HAS_COMPLEX_ASSIGN_REF (type)
! 		  /* But storing a CONSTRUCTOR isn't a copy.  */
! 		  || TREE_CODE (exp) == CONSTRUCTOR
! 		  /* And, the gimplifier will sometimes make a copy of
! 		     an aggregate.  In particular, for a case like:
! 
! 			struct S { S(); };
! 			struct X { int a; S s; };
! 			X x = { 0 };
! 
! 		     the gimplifier will create a temporary with
! 		     static storage duration, perform static
! 		     initialization of the temporary, and then copy
! 		     the result.  Since the "s" subobject is never
! 		     constructed, this is a valid transformation.  */
! 		  || CP_AGGREGATE_TYPE_P (type));
  
        /* This would be wrong for a type with virtual bases, but they are
  	 caught by the assert above.  */
--- 82,105 ----
        /* The backend should not be interested in the size of an expression
  	 of a type with both of these set; all copies of such types must go
  	 through a constructor or assignment op.  */
!       if (!TYPE_HAS_COMPLEX_INIT_REF (type)
! 	  || !TYPE_HAS_COMPLEX_ASSIGN_REF (type)
! 	  /* But storing a CONSTRUCTOR isn't a copy.  */
! 	  || TREE_CODE (exp) == CONSTRUCTOR
! 	  /* And, the gimplifier will sometimes make a copy of
! 	     an aggregate.  In particular, for a case like:
! 
! 		struct S { S(); };
! 		struct X { int a; S s; };
! 		X x = { 0 };
! 
! 	     the gimplifier will create a temporary with
! 	     static storage duration, perform static
! 	     initialization of the temporary, and then copy
! 	     the result.  Since the "s" subobject is never
! 	     constructed, this is a valid transformation.  */
! 	  || CP_AGGREGATE_TYPE_P (type))
! 	return NULL;
  
        /* This would be wrong for a type with virtual bases, but they are
  	 caught by the assert above.  */
Index: builtins.c
===================================================================
*** builtins.c	(revision 119467)
--- builtins.c	(working copy)
*************** fold_builtin_memory_op (tree arglist, tr
*** 8202,8209 ****
  	  || !TYPE_SIZE_UNIT (desttype)
  	  || TREE_CODE (TYPE_SIZE_UNIT (srctype)) != INTEGER_CST
  	  || TREE_CODE (TYPE_SIZE_UNIT (desttype)) != INTEGER_CST
! 	  || !operand_equal_p (TYPE_SIZE_UNIT (srctype), len, 0)
! 	  || !operand_equal_p (TYPE_SIZE_UNIT (desttype), len, 0))
  	return 0;
  
        if (get_pointer_alignment (dest, BIGGEST_ALIGNMENT) 
--- 8202,8209 ----
  	  || !TYPE_SIZE_UNIT (desttype)
  	  || TREE_CODE (TYPE_SIZE_UNIT (srctype)) != INTEGER_CST
  	  || TREE_CODE (TYPE_SIZE_UNIT (desttype)) != INTEGER_CST
! 	  || !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len)
! 	  || !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
  	return 0;
  
        if (get_pointer_alignment (dest, BIGGEST_ALIGNMENT) 
*************** fold_builtin_memory_op (tree arglist, tr
*** 8218,8223 ****
--- 8218,8225 ----
        srcvar = build_fold_indirect_ref (src);
        if (TREE_THIS_VOLATILE (srcvar))
  	return 0;
+       if (!tree_int_cst_equal (lang_hooks.expr_size (srcvar), len))
+ 	return 0;
        /* With memcpy, it is possible to bypass aliasing rules, so without
           this check i. e. execute/20060930-2.c would be misoptimized, because
  	 it use conflicting alias set to hold argument for the memcpy call.
*************** fold_builtin_memory_op (tree arglist, tr
*** 8233,8238 ****
--- 8235,8242 ----
        destvar = build_fold_indirect_ref (dest);
        if (TREE_THIS_VOLATILE (destvar))
  	return 0;
+       if (!tree_int_cst_equal (lang_hooks.expr_size (destvar), len))
+ 	return 0;
        if (!var_decl_component_p (destvar))
  	return 0;
  
Index: explow.c
===================================================================
*** explow.c	(revision 119467)
--- explow.c	(working copy)
*************** expr_size (tree exp)
*** 245,251 ****
    if (TREE_CODE (exp) == WITH_SIZE_EXPR)
      size = TREE_OPERAND (exp, 1);
    else
!     size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (lang_hooks.expr_size (exp), exp);
  
    return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), 0);
  }
--- 245,255 ----
    if (TREE_CODE (exp) == WITH_SIZE_EXPR)
      size = TREE_OPERAND (exp, 1);
    else
!     {
!       size = lang_hooks.expr_size (exp);
!       gcc_assert (size);
!       size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, exp);
!     }
  
    return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), 0);
  }
*************** int_expr_size (tree exp)
*** 261,267 ****
    if (TREE_CODE (exp) == WITH_SIZE_EXPR)
      size = TREE_OPERAND (exp, 1);
    else
!     size = lang_hooks.expr_size (exp);
  
    if (size == 0 || !host_integerp (size, 0))
      return -1;
--- 265,274 ----
    if (TREE_CODE (exp) == WITH_SIZE_EXPR)
      size = TREE_OPERAND (exp, 1);
    else
!     {
!       size = lang_hooks.expr_size (exp);
!       gcc_assert (size);
!     }
  
    if (size == 0 || !host_integerp (size, 0))
      return -1;


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