This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][RFC] Fix PR33724, fix PR19382 differently
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 10 Oct 2007 15:17:48 +0200 (CEST)
- Subject: [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);
+ }
+