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][RFC] Fix PR33724, fix PR19382 differently


PR33724 is about us generating two incompatible TYPE_POINTER_TO types
to unsigned char.  The type-checking code doesn't really know which one
to check against.  The different pointer-to types were introduced by
the fix for PR19382.

In the following patch there are two possible fixes/workarounds for
the problem.  The first patch to tree.c arranges to put the
ref-all pointer-to type last in the list of TYPE_POINTER_TO types
(this is just a workaround, I think it is fundamentally bogus to have
two incompatible pointer-to types).  The second patch to builtins.c
reverts the fix for PR19382 and instantiates a different fix following
the reasoning in the audit trail of said PR that the transformation
is only valid for alias set zero unsigned char types.

Personally I would chose the builtin.c fix (and for stage1 disallow
multiple TYPE_POINTER_TO types completely), but - any other opinions?

Thanks,
Richard.

2007-10-10  Richard Guenther  <rguenther@suse.de>

	PR middle-end/33724
	* tree.c (build_pointer_type_for_mode): Queue TYPE_REF_CAN_ALIAS_ALL
	pointers at the end of the TYPE_POINTER_TO chain.

	Revert
	2005-10-04  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>

	PR ada/19382
	* builtins.c (fold_builtin_memcmp): When constructing the pointer
	type used to access data in the inlined length == 1 case, use
	build_pointer_type_for_mode with CAN_ALIAS_ALL set to true.
	(fold_builtin_strcmp, fold_builtin_strncmp): Likewise.

	* builtins.c (fold_builtin_memcmp): Instead disable the
	transformation if the alias set of unsigned char is not zero.
	(fold_builtin_strcmp, fold_builtin_strncmp): Likewise.

Index: tree.c
===================================================================
*** tree.c	(revision 129199)
--- tree.c	(working copy)
*************** build_pointer_type_for_mode (tree to_typ
*** 5419,5426 ****
    TREE_TYPE (t) = to_type;
    TYPE_MODE (t) = mode;
    TYPE_REF_CAN_ALIAS_ALL (t) = can_alias_all;
!   TYPE_NEXT_PTR_TO (t) = TYPE_POINTER_TO (to_type);
!   TYPE_POINTER_TO (to_type) = t;
  
    if (TYPE_STRUCTURAL_EQUALITY_P (to_type))
      SET_TYPE_STRUCTURAL_EQUALITY (t);
--- 5419,5437 ----
    TREE_TYPE (t) = to_type;
    TYPE_MODE (t) = mode;
    TYPE_REF_CAN_ALIAS_ALL (t) = can_alias_all;
! 
!   /* Queue ref-all pointer-to types after existing ones.  */
!   if (can_alias_all
!       && TYPE_POINTER_TO (to_type) != NULL_TREE)
!     {
!       TYPE_NEXT_PTR_TO (t) = TYPE_NEXT_PTR_TO (TYPE_POINTER_TO (to_type));
!       TYPE_NEXT_PTR_TO (TYPE_POINTER_TO (to_type)) = t;
!     }
!   else
!     {
!       TYPE_NEXT_PTR_TO (t) = TYPE_POINTER_TO (to_type);
!       TYPE_POINTER_TO (to_type) = t;
!     }
  
    if (TYPE_STRUCTURAL_EQUALITY_P (to_type))
      SET_TYPE_STRUCTURAL_EQUALITY (t);
Index: builtins.c
===================================================================
*** builtins.c	(revision 129199)
--- builtins.c	(working copy)
*************** fold_builtin_memcmp (tree arg1, tree arg
*** 8955,8966 ****
  
    /* If len parameter is one, return an expression corresponding to
       (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
!   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
      {
        tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
!       tree cst_uchar_ptr_node
! 	= build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
! 
        tree ind1 = fold_convert (integer_type_node,
  				build1 (INDIRECT_REF, cst_uchar_node,
  					fold_convert (cst_uchar_ptr_node,
--- 8955,8965 ----
  
    /* If len parameter is one, return an expression corresponding to
       (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
!   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1
!       && get_alias_set (unsigned_char_type_node) == 0)
      {
        tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
!       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
        tree ind1 = fold_convert (integer_type_node,
  				build1 (INDIRECT_REF, cst_uchar_node,
  					fold_convert (cst_uchar_ptr_node,
*************** fold_builtin_strcmp (tree arg1, tree arg
*** 9006,9017 ****
      }
  
    /* If the second arg is "", return *(const unsigned char*)arg1.  */
!   if (p2 && *p2 == '\0')
      {
        tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
!       tree cst_uchar_ptr_node
! 	= build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
! 
        return fold_convert (integer_type_node,
  			   build1 (INDIRECT_REF, cst_uchar_node,
  				   fold_convert (cst_uchar_ptr_node,
--- 9005,9015 ----
      }
  
    /* If the second arg is "", return *(const unsigned char*)arg1.  */
!   if (p2 && *p2 == '\0'
!       && get_alias_set (unsigned_char_type_node) == 0)
      {
        tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
!       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
        return fold_convert (integer_type_node,
  			   build1 (INDIRECT_REF, cst_uchar_node,
  				   fold_convert (cst_uchar_ptr_node,
*************** fold_builtin_strcmp (tree arg1, tree arg
*** 9019,9030 ****
      }
  
    /* If the first arg is "", return -*(const unsigned char*)arg2.  */
!   if (p1 && *p1 == '\0')
      {
        tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
!       tree cst_uchar_ptr_node
! 	= build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
! 
        tree temp = fold_convert (integer_type_node,
  				build1 (INDIRECT_REF, cst_uchar_node,
  					fold_convert (cst_uchar_ptr_node,
--- 9017,9027 ----
      }
  
    /* If the first arg is "", return -*(const unsigned char*)arg2.  */
!   if (p1 && *p1 == '\0'
!       && get_alias_set (unsigned_char_type_node) == 0)
      {
        tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
!       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
        tree temp = fold_convert (integer_type_node,
  				build1 (INDIRECT_REF, cst_uchar_node,
  					fold_convert (cst_uchar_ptr_node,
*************** fold_builtin_strncmp (tree arg1, tree ar
*** 9075,9086 ****
       return *(const unsigned char*)arg1.  */
    if (p2 && *p2 == '\0'
        && TREE_CODE (len) == INTEGER_CST
!       && tree_int_cst_sgn (len) == 1)
      {
        tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
!       tree cst_uchar_ptr_node
! 	= build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
! 
        return fold_convert (integer_type_node,
  			   build1 (INDIRECT_REF, cst_uchar_node,
  				   fold_convert (cst_uchar_ptr_node,
--- 9072,9082 ----
       return *(const unsigned char*)arg1.  */
    if (p2 && *p2 == '\0'
        && TREE_CODE (len) == INTEGER_CST
!       && tree_int_cst_sgn (len) == 1
!       && get_alias_set (unsigned_char_type_node) == 0)
      {
        tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
!       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
        return fold_convert (integer_type_node,
  			   build1 (INDIRECT_REF, cst_uchar_node,
  				   fold_convert (cst_uchar_ptr_node,
*************** fold_builtin_strncmp (tree arg1, tree ar
*** 9091,9102 ****
       return -*(const unsigned char*)arg2.  */
    if (p1 && *p1 == '\0'
        && TREE_CODE (len) == INTEGER_CST
!       && tree_int_cst_sgn (len) == 1)
      {
        tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
!       tree cst_uchar_ptr_node
! 	= build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
! 
        tree temp = fold_convert (integer_type_node,
  				build1 (INDIRECT_REF, cst_uchar_node,
  					fold_convert (cst_uchar_ptr_node,
--- 9087,9097 ----
       return -*(const unsigned char*)arg2.  */
    if (p1 && *p1 == '\0'
        && TREE_CODE (len) == INTEGER_CST
!       && tree_int_cst_sgn (len) == 1
!       && get_alias_set (unsigned_char_type_node) == 0)
      {
        tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
!       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
        tree temp = fold_convert (integer_type_node,
  				build1 (INDIRECT_REF, cst_uchar_node,
  					fold_convert (cst_uchar_ptr_node,
*************** fold_builtin_strncmp (tree arg1, tree ar
*** 9106,9117 ****
  
    /* If len parameter is one, return an expression corresponding to
       (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
!   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
      {
        tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
!       tree cst_uchar_ptr_node
! 	= build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
! 
        tree ind1 = fold_convert (integer_type_node,
  				build1 (INDIRECT_REF, cst_uchar_node,
  					fold_convert (cst_uchar_ptr_node,
--- 9101,9111 ----
  
    /* If len parameter is one, return an expression corresponding to
       (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
!   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1
!       && get_alias_set (unsigned_char_type_node) == 0)
      {
        tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
!       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
        tree ind1 = fold_convert (integer_type_node,
  				build1 (INDIRECT_REF, cst_uchar_node,
  					fold_convert (cst_uchar_ptr_node,
Index: testsuite/gcc.dg/pr33724.c
===================================================================
*** testsuite/gcc.dg/pr33724.c	(revision 0)
--- testsuite/gcc.dg/pr33724.c	(revision 0)
***************
*** 0 ****
--- 1,20 ----
+ /* { dg-do compile } */
+ 
+ /* We ICEd with type-checking enabled.  */
+ 
+ struct xt_entry_target {
+   char name[1];
+ };
+ struct ipt_entry {
+   unsigned char elems[1];
+ };
+ void match_different(const unsigned char *);
+ int dump_entry(struct xt_entry_target *t)
+ {
+   return __builtin_strcmp (t->name, "");
+ }
+ void is_same(const struct ipt_entry *a)
+ {
+   match_different(a->elems);
+ }
+ 


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