------- Additional Comments From aoliva at gcc dot gnu dot org  2005-04-14 
17:03 -------
Subject: Re: [PR middle-end/20739] lvalue cond-expr gimplification may crash on 
cv-qual diffs

On Apr  4, 2005, Alexandre Oliva <[EMAIL PROTECTED]> wrote:

> If the operands of a cond-expr used as an lvalue differ in cv
> qualification, the front-end adds nop_exprs to add cv qualifiers that
> the gimplifier drops when simplifying &(T const)*v.  The `&' was added
> by gimplify_cond_expr.

> The problem is that gimplify_addr_expr gimplifies its operand in such
> a way that the nop_expr is dropped, and nothing puts it back in, so
> when we test that, in the indirect_ref case in gimplify_addr_expr, the
> types are compatible, the test fails because of the missing
> cv-qualifier in the pointed-to type.  This patch fixes this.

> Ok to install if bootstrap and regtest on amd64-linux-gnu pass?

Bootstrap and regtest pased on amd64-linux-gnu, at least for mainline.
I'm retesting on the branch, since I'm not entirely sure I actually
tested it there.

Index: gcc/ChangeLog
from  Alexandre Oliva  <[EMAIL PROTECTED]>

        PR middle-end/20739
        * gimplify.c (gimplify_addr_expr): Compensate for removal of
        e.g. cv-qualification conversions.

Index: gcc/gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gimplify.c,v
retrieving revision 2.122
diff -u -p -r2.122 gimplify.c
--- gcc/gimplify.c 1 Apr 2005 03:42:41 -0000 2.122
+++ gcc/gimplify.c 4 Apr 2005 11:28:04 -0000
@@ -3229,6 +3232,9 @@ gimplify_addr_expr (tree *expr_p, tree *
         builtins like __builtin_va_end).  */
       /* Caution: the silent array decomposition semantics we allow for
         ADDR_EXPR means we can't always discard the pair.  */
+      /* Gimplification of the ADDR_EXPR operand may drop
+        cv-qualification conversions, so make sure we add them if
+        needed.  */
       {
        tree op00 = TREE_OPERAND (op0, 0);
        tree t_expr = TREE_TYPE (expr);
@@ -3238,9 +3244,9 @@ gimplify_addr_expr (tree *expr_p, tree *
          {
 #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),
+           gcc_assert (POINTER_TYPE_P (t_expr)
+                       && cpt_same_type (TREE_CODE (t_op0) == ARRAY_TYPE
+                                         ? TREE_TYPE (t_op0) : t_op0,
                                          TREE_TYPE (t_expr))
                        && POINTER_TYPE_P (t_op00)
                        && cpt_same_type (t_op0, TREE_TYPE (t_op00)));
Index: gcc/testsuite/ChangeLog
from  Alexandre Oliva  <[EMAIL PROTECTED]>

        PR middle-end/20739
        * gcc.dg/tree-ssa/pr20739.c: New test.

Index: gcc/testsuite/gcc.dg/tree-ssa/pr20739.c
===================================================================
RCS file: gcc/testsuite/gcc.dg/tree-ssa/pr20739.c
diff -N gcc/testsuite/gcc.dg/tree-ssa/pr20739.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/gcc.dg/tree-ssa/pr20739.c 4 Apr 2005 11:28:20 -0000
@@ -0,0 +1,24 @@
+/* PR middle-end/20739 */
+
+/* dg-do compile */
+/* dg-options "-O" */
+
+/* We used to fail to compile this because gimplification dropped the
+   conversion that added the const qualifier to the sub-expression
+   involving baz, and then immediately noticed and reported its
+   absence.  */
+
+typedef struct 
+{ 
+    char chars[5]; 
+} 
+baz_t; 
+ 
+extern baz_t * baz; 
+ 
+extern void foo (baz_t); 
+int 
+bar (const baz_t * ls) 
+{ 
+    foo (ls == 0 ? *(&baz[0]) : *ls); 
+}

-- 
Alexandre Oliva             http://www.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer   [EMAIL PROTECTED], gcc.gnu.org}
Free Software Evangelist  [EMAIL PROTECTED], gnu.org}


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20739

Reply via email to