2009-05-03 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 3 May 2009 19:57:32 +0000 (19:57 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 3 May 2009 19:57:32 +0000 (19:57 +0000)
PR c/39983
* c-typeck.c (array_to_pointer_conversion): Do not built
ADDR_EXPRs of arrays of pointer-to-element type.
* c-gimplify.c (c_gimplify_expr): Revert change fixing
up wrong ADDR_EXPRs after-the-fact.
* c-common.c (strict_aliasing_warning): Strip pointer
conversions for obtaining the original type.
* builtins.c (fold_builtin_memset): Handle array types.
(fold_builtin_memory_op): Handle folded POINTER_PLUS_EXPRs
and array types

* gcc.c-torture/compile/pr39983.c: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@147083 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/builtins.c
gcc/c-common.c
gcc/c-gimplify.c
gcc/c-typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr39983.c [new file with mode: 0644]

index 581b3b5..5ac28eb 100644 (file)
@@ -1,5 +1,18 @@
 2009-05-03  Richard Guenther  <rguenther@suse.de>
 
+       PR c/39983
+       * c-typeck.c (array_to_pointer_conversion): Do not built
+       ADDR_EXPRs of arrays of pointer-to-element type.
+       * c-gimplify.c (c_gimplify_expr): Revert change fixing
+       up wrong ADDR_EXPRs after-the-fact.
+       * c-common.c (strict_aliasing_warning): Strip pointer
+       conversions for obtaining the original type.
+       * builtins.c (fold_builtin_memset): Handle array types.
+       (fold_builtin_memory_op): Handle folded POINTER_PLUS_EXPRs
+       and array types
+
+2009-05-03  Richard Guenther  <rguenther@suse.de>
+
        PR middle-end/23329
        * tree-ssa.c (useless_type_conversion_p_1): Use get_deref_alias_set.
        Do not lose casts from array types with unknown extent to array
index 067e311..e3c91dc 100644 (file)
@@ -8737,7 +8737,7 @@ var_decl_component_p (tree var)
 static tree
 fold_builtin_memset (tree dest, tree c, tree len, tree type, bool ignore)
 {
-  tree var, ret;
+  tree var, ret, etype;
   unsigned HOST_WIDE_INT length, cval;
 
   if (! validate_arg (dest, POINTER_TYPE)
@@ -8764,15 +8764,19 @@ fold_builtin_memset (tree dest, tree c, tree len, tree type, bool ignore)
   if (TREE_THIS_VOLATILE (var))
     return NULL_TREE;
 
-  if (!INTEGRAL_TYPE_P (TREE_TYPE (var))
-      && !POINTER_TYPE_P (TREE_TYPE (var)))
+  etype = TREE_TYPE (var);
+  if (TREE_CODE (etype) == ARRAY_TYPE)
+    etype = TREE_TYPE (etype);
+
+  if (!INTEGRAL_TYPE_P (etype)
+      && !POINTER_TYPE_P (etype))
     return NULL_TREE;
 
   if (! var_decl_component_p (var))
     return NULL_TREE;
 
   length = tree_low_cst (len, 1);
-  if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (var))) != length
+  if (GET_MODE_SIZE (TYPE_MODE (etype)) != length
       || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
         < (int) length)
     return NULL_TREE;
@@ -8794,8 +8798,10 @@ fold_builtin_memset (tree dest, tree c, tree len, tree type, bool ignore)
       cval |= (cval << 31) << 1;
     }
 
-  ret = build_int_cst_type (TREE_TYPE (var), cval);
-  ret = build2 (MODIFY_EXPR, TREE_TYPE (var), var, ret);
+  ret = build_int_cst_type (etype, cval);
+  var = build_fold_indirect_ref (fold_convert (build_pointer_type (etype),
+                                              dest));
+  ret = build2 (MODIFY_EXPR, etype, var, ret);
   if (ignore)
     return ret;
 
@@ -8947,8 +8953,37 @@ fold_builtin_memory_op (tree dest, tree src, tree len, tree type, bool ignore, i
         Perhaps we ought to inherit type from non-VOID argument here?  */
       STRIP_NOPS (src);
       STRIP_NOPS (dest);
+      /* As we fold (void *)(p + CST) to (void *)p + CST undo this here.  */
+      if (TREE_CODE (src) == POINTER_PLUS_EXPR)
+       {
+         tree tem = TREE_OPERAND (src, 0);
+         STRIP_NOPS (tem);
+         if (tem != TREE_OPERAND (src, 0))
+           src = build1 (NOP_EXPR, TREE_TYPE (tem), src);
+       }
+      if (TREE_CODE (dest) == POINTER_PLUS_EXPR)
+       {
+         tree tem = TREE_OPERAND (dest, 0);
+         STRIP_NOPS (tem);
+         if (tem != TREE_OPERAND (dest, 0))
+           dest = build1 (NOP_EXPR, TREE_TYPE (tem), dest);
+       }
       srctype = TREE_TYPE (TREE_TYPE (src));
+      if (srctype
+         && TREE_CODE (srctype) == ARRAY_TYPE)
+       {
+         srctype = TREE_TYPE (srctype);
+         STRIP_NOPS (src);
+         src = build1 (NOP_EXPR, build_pointer_type (srctype), src);
+       }
       desttype = TREE_TYPE (TREE_TYPE (dest));
+      if (desttype
+         && TREE_CODE (desttype) == ARRAY_TYPE)
+       {
+         desttype = TREE_TYPE (desttype);
+         STRIP_NOPS (dest);
+         dest = build1 (NOP_EXPR, build_pointer_type (desttype), dest);
+       }
       if (!srctype || !desttype
          || !TYPE_SIZE_UNIT (srctype)
          || !TYPE_SIZE_UNIT (desttype)
index d877c0f..ff8e83a 100644 (file)
@@ -1762,6 +1762,10 @@ warn_logical_operator (location_t location, enum tree_code code,
 bool
 strict_aliasing_warning (tree otype, tree type, tree expr)
 {
+  /* Strip pointer conversion chains and get to the correct original type.  */
+  STRIP_NOPS (expr);
+  otype = TREE_TYPE (expr);
+
   if (!(flag_strict_aliasing
        && POINTER_TYPE_P (type)
        && POINTER_TYPE_P (otype)
index a361e90..9cb4a0b 100644 (file)
@@ -196,20 +196,5 @@ c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
       && !warn_init_self)
     TREE_NO_WARNING (DECL_EXPR_DECL (*expr_p)) = 1;
 
-  /* The C frontend is the only one producing &ARRAY with pointer-to-element
-     type.  This is invalid in gimple, so produce a properly typed
-     ADDR_EXPR instead and wrap a conversion around it.  */
-  if (code == ADDR_EXPR
-      && TREE_CODE (TREE_TYPE (TREE_OPERAND (*expr_p, 0))) == ARRAY_TYPE
-      && !lang_hooks.types_compatible_p (TREE_TYPE (TREE_TYPE (*expr_p)),
-                                        TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
-    {
-      tree type = TREE_TYPE (*expr_p);
-      TREE_TYPE (*expr_p)
-       = build_pointer_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0)));
-      *expr_p = build1 (NOP_EXPR, type, *expr_p);
-      return GS_OK;
-    }
-
   return GS_UNHANDLED;
 }
index 88eb96a..f00e0db 100644 (file)
@@ -1634,21 +1634,6 @@ array_to_pointer_conversion (tree exp)
   if (TREE_CODE (exp) == INDIRECT_REF)
     return convert (ptrtype, TREE_OPERAND (exp, 0));
 
-  if (TREE_CODE (exp) == VAR_DECL)
-    {
-      /* We are making an ADDR_EXPR of ptrtype.  This is a valid
-        ADDR_EXPR because it's the best way of representing what
-        happens in C when we take the address of an array and place
-        it in a pointer to the element type.  */
-      adr = build1 (ADDR_EXPR, ptrtype, exp);
-      if (!c_mark_addressable (exp))
-       return error_mark_node;
-      TREE_SIDE_EFFECTS (adr) = 0;   /* Default would be, same as EXP.  */
-      return adr;
-    }
-
-  /* This way is better for a COMPONENT_REF since it can
-     simplify the offset for a component.  */
   adr = build_unary_op (EXPR_LOCATION (exp), ADDR_EXPR, exp, 1);
   return convert (ptrtype, adr);
 }
index fe172c5..ded72e9 100644 (file)
@@ -1,3 +1,8 @@
+2009-05-03  Richard Guenther  <rguenther@suse.de>
+
+       PR c/39983
+       * gcc.c-torture/compile/pr39983.c: New testcase.
+
 2009-05-03  Joseph Myers  <joseph@codesourcery.com>
 
        * gcc.dg/c99-complex-3.c: New test.
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr39983.c b/gcc/testsuite/gcc.c-torture/compile/pr39983.c
new file mode 100644 (file)
index 0000000..6708121
--- /dev/null
@@ -0,0 +1,17 @@
+typedef struct {
+    int *p;
+} *A;
+
+extern const int a[1];
+extern const int b[1];
+
+void foo()
+{
+  A x;
+  A y;
+  static const int * const c[] = { b };
+
+  x->p = (int*)c[0];
+  y->p = (int*)a;
+}
+