This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
fix middle-end/17397
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 14 Sep 2004 19:20:55 -0700
- Subject: fix middle-end/17397
In the beginning, fold_builtin_strlen constructs
<indirect_ref <char>
<addr_expr <char *>
<var_decl <char []> s>>>
which, according to the rules we have in check_pointer_types, is fine.
Then the VLA code comes along and replaces this, during gimplifcation, with
<indirect_ref <char>
<addr_expr <char *>
<indirect_ref <char []>
<var_decl <char (*)[]> s.1>>>
which is also fine. But gimplify_addr_expr didn't take into account the
possible type change that occurs from stripping addr_expr+indirect_ref
and simplifies to
<indirect_ref <char>
<var_decl <char (*)[]> s.1>>
which is not fine, and check_pointer_types_r catches the mistake.
Fixed by detecting the case (and with assertions, *only* that case), and
adds a cast as appropriate, so we get
<indirect_ref <char>
<nop_expr <char *>
<var_decl <char (*)[]> s.1>>>
which is as good a fix as any, I think.
Bootstrapped and tested on i686-linux.
r~
* gimplify.c (gimplify_addr_expr): Don't inadvertently change types
while folding <ADDR_EXPR <INDIRECT_REF X>>.
Index: gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gimplify.c,v
retrieving revision 2.76
diff -c -p -d -r2.76 gimplify.c
*** gimplify.c 11 Sep 2004 00:25:00 -0000 2.76
--- gimplify.c 15 Sep 2004 02:07:35 -0000
*************** typedef struct gimple_temp_hash_elt
*** 74,79 ****
--- 74,82 ----
/* Forward declarations. */
static enum gimplify_status gimplify_compound_expr (tree *, tree *, bool);
+ #ifdef ENABLE_CHECKING
+ static bool cpt_same_type (tree a, tree b);
+ #endif
/* Return a hash value for a formal temporary table entry. */
*************** gimplify_addr_expr (tree *expr_p, tree *
*** 3051,3062 ****
switch (TREE_CODE (op0))
{
case INDIRECT_REF:
/* Check if we are dealing with an expression of the form '&*ptr'.
While the front end folds away '&*ptr' into 'ptr', these
expressions may be generated internally by the compiler (e.g.,
builtins like __builtin_va_end). */
! *expr_p = TREE_OPERAND (op0, 0);
! ret = GS_OK;
break;
case VIEW_CONVERT_EXPR:
--- 3054,3087 ----
switch (TREE_CODE (op0))
{
case INDIRECT_REF:
+ do_indirect_ref:
/* Check if we are dealing with an expression of the form '&*ptr'.
While the front end folds away '&*ptr' into 'ptr', these
expressions may be generated internally by the compiler (e.g.,
builtins like __builtin_va_end). */
! /* Caution: the silent array decomposition semantics we allow for
! ADDR_EXPR means we can't always discard the pair. */
! {
! tree op00 = TREE_OPERAND (op0, 0);
! tree t_expr = TREE_TYPE (expr);
! tree t_op00 = TREE_TYPE (op00);
!
! if (!lang_hooks.types_compatible_p (t_expr, t_op00))
! {
! #ifdef ENABLE_CHECKING
! tree t_op0 = TREE_TYPE (op0);
! gcc_assert (TREE_CODE (t_op0) == ARRAY_TYPE
! && POINTER_TYPE_P (t_expr)
! && cpt_same_type (TREE_TYPE (t_op0),
! TREE_TYPE (t_expr))
! && POINTER_TYPE_P (t_op00)
! && cpt_same_type (t_op0, TREE_TYPE (t_op00)));
! #endif
! op00 = fold_convert (TREE_TYPE (expr), op00);
! }
! *expr_p = op00;
! ret = GS_OK;
! }
break;
case VIEW_CONVERT_EXPR:
*************** gimplify_addr_expr (tree *expr_p, tree *
*** 3079,3092 ****
is_gimple_addressable, fb_either);
if (ret != GS_ERROR)
{
! /* The above may have made an INDIRECT_REF (e.g, Ada's NULL_EXPR),
! so check for it here. It's not worth checking for the other
! cases above. */
! if (TREE_CODE (TREE_OPERAND (expr, 0)) == INDIRECT_REF)
! {
! *expr_p = TREE_OPERAND (TREE_OPERAND (expr, 0), 0);
! break;
! }
/* Make sure TREE_INVARIANT, TREE_CONSTANT, and TREE_SIDE_EFFECTS
is set properly. */
--- 3104,3115 ----
is_gimple_addressable, fb_either);
if (ret != GS_ERROR)
{
! op0 = TREE_OPERAND (expr, 0);
!
! /* For various reasons, the gimplification of the expression
! may have made a new INDIRECT_REF. */
! if (TREE_CODE (op0) == INDIRECT_REF)
! goto do_indirect_ref;
/* Make sure TREE_INVARIANT, TREE_CONSTANT, and TREE_SIDE_EFFECTS
is set properly. */
Index: testsuite/gcc.c-torture/compile/pr17397.c
===================================================================
RCS file: testsuite/gcc.c-torture/compile/pr17397.c
diff -N testsuite/gcc.c-torture/compile/pr17397.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.c-torture/compile/pr17397.c 15 Sep 2004 02:07:38 -0000
***************
*** 0 ****
--- 1,12 ----
+ /* ICE due to invalid GIMPLE created during strlen simplification. */
+
+ extern unsigned long strlen (__const char *__s);
+ extern void bar ();
+ extern int cols;
+
+ void foo (void)
+ {
+ char s[cols + 2];
+ if (strlen (s) > 0)
+ bar ();
+ }