This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix type correctness of fold_indirect_ref
- From: Richard Guenther <rguenth at tat dot physik dot uni-tuebingen dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 15 May 2005 19:43:09 +0200
- Subject: [PATCH] Fix type correctness of fold_indirect_ref
This patch fixes type correctness issues in fold_indirect_ref as
suggested by Roger.
Bootstrapped and tested on x86_64-unknown-linux-gnu for C and C++
with no regressions apart from
FAIL: g++.dg/opt/temp1.C execution test
which is an optimization test supposed to be performed by
gimplify_modify_expr_rhs:
case INDIRECT_REF:
{
/* If we have code like
*(const A*)(A*)&x
where the type of "x" is a (possibly cv-qualified variant
of "A"), treat the entire expression as identical to "x".
This kind of code arises in C++ when an object is bound
to a const reference, and if "x" is a TARGET_EXPR we want
to take advantage of the optimization below. */
tree t = fold_indirect_ref (*from_p);
if (t != *from_p)
{
*from_p = t;
ret = GS_OK;
}
else
ret = GS_UNHANDLED;
break;
}
but the changed fold_indirect_ref is not able to perform the required
transformation. I agree with Roger that this may be a candidate for
a routine with less strict type requirements.
Ok for mainline?
Thanks,
Richard.
2005-05-15 Richard Guenther <rguenth@gcc.gnu.org>
* fold-const.c (fold_indirect_ref_1): Add type argument;
make sure the resulting expression is of this type.
(build_fold_indirect_ref, fold_indirect_ref): Adjust callers.
Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.580
diff -c -3 -p -r1.580 fold-const.c
*** fold-const.c 14 May 2005 15:42:01 -0000 1.580
--- fold-const.c 15 May 2005 17:29:30 -0000
*************** build_fold_addr_expr (tree t)
*** 11396,11409 ****
return build_fold_addr_expr_with_type (t, build_pointer_type (TREE_TYPE (t)));
}
! /* Given a pointer value T, return a simplified version of an indirection
! through T, or NULL_TREE if no simplification is possible. */
static tree
! fold_indirect_ref_1 (tree t)
{
! tree type = TREE_TYPE (TREE_TYPE (t));
! tree sub = t;
tree subtype;
STRIP_NOPS (sub);
--- 11396,11409 ----
return build_fold_addr_expr_with_type (t, build_pointer_type (TREE_TYPE (t)));
}
! /* Given a pointer value OP0 and a type TYPE, return a simplified version
! of an indirection through OP0, or NULL_TREE if no simplification is
! possible. */
static tree
! fold_indirect_ref_1 (tree type, tree op0)
{
! tree sub = op0;
tree subtype;
STRIP_NOPS (sub);
*************** fold_indirect_ref_1 (tree t)
*** 11416,11426 ****
tree op = TREE_OPERAND (sub, 0);
tree optype = TREE_TYPE (op);
/* *&p => p */
! if (lang_hooks.types_compatible_p (type, optype))
return op;
/* *(foo *)&fooarray => fooarray[0] */
else if (TREE_CODE (optype) == ARRAY_TYPE
! && lang_hooks.types_compatible_p (type, TREE_TYPE (optype)))
{
tree type_domain = TYPE_DOMAIN (optype);
tree min_val = size_zero_node;
--- 11416,11426 ----
tree op = TREE_OPERAND (sub, 0);
tree optype = TREE_TYPE (op);
/* *&p => p */
! if (type == optype)
return op;
/* *(foo *)&fooarray => fooarray[0] */
else if (TREE_CODE (optype) == ARRAY_TYPE
! && type == TREE_TYPE (optype))
{
tree type_domain = TYPE_DOMAIN (optype);
tree min_val = size_zero_node;
*************** fold_indirect_ref_1 (tree t)
*** 11432,11438 ****
/* *(foo *)fooarrptr => (*fooarrptr)[0] */
if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
! && lang_hooks.types_compatible_p (type, TREE_TYPE (TREE_TYPE (subtype))))
{
tree type_domain;
tree min_val = size_zero_node;
--- 11432,11438 ----
/* *(foo *)fooarrptr => (*fooarrptr)[0] */
if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
! && type == TREE_TYPE (TREE_TYPE (subtype)))
{
tree type_domain;
tree min_val = size_zero_node;
*************** fold_indirect_ref_1 (tree t)
*** 11452,11463 ****
tree
build_fold_indirect_ref (tree t)
{
! tree sub = fold_indirect_ref_1 (t);
if (sub)
return sub;
else
! return build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t);
}
/* Given an INDIRECT_REF T, return either T or a simplified version. */
--- 11452,11464 ----
tree
build_fold_indirect_ref (tree t)
{
! tree type = TREE_TYPE (TREE_TYPE (t));
! tree sub = fold_indirect_ref_1 (type, t);
if (sub)
return sub;
else
! return build1 (INDIRECT_REF, type, t);
}
/* Given an INDIRECT_REF T, return either T or a simplified version. */
*************** build_fold_indirect_ref (tree t)
*** 11465,11471 ****
tree
fold_indirect_ref (tree t)
{
! tree sub = fold_indirect_ref_1 (TREE_OPERAND (t, 0));
if (sub)
return sub;
--- 11466,11472 ----
tree
fold_indirect_ref (tree t)
{
! tree sub = fold_indirect_ref_1 (TREE_TYPE (t), TREE_OPERAND (t, 0));
if (sub)
return sub;