aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2009-05-03 19:57:32 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2009-05-03 19:57:32 +0000
commit255d3827b4ecd22efa38467bf52a9ee24f96afb5 (patch)
treec4e6b2079d241859aabc7e14a7760df92602eee4 /gcc
parent16c337707b0c71829fcad74fdc82d85b1f103eaf (diff)
downloadgcc-255d3827b4ecd22efa38467bf52a9ee24f96afb5.zip
gcc-255d3827b4ecd22efa38467bf52a9ee24f96afb5.tar.gz
gcc-255d3827b4ecd22efa38467bf52a9ee24f96afb5.tar.bz2
re PR c/39983 (ICE: type mismatch in address expression)
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 * gcc.c-torture/compile/pr39983.c: New testcase. From-SVN: r147083
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/builtins.c47
-rw-r--r--gcc/c-common.c4
-rw-r--r--gcc/c-gimplify.c15
-rw-r--r--gcc/c-typeck.c15
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr39983.c17
7 files changed, 80 insertions, 36 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 581b3b5..5ac28eb 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 067e311..e3c91dc 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -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)
diff --git a/gcc/c-common.c b/gcc/c-common.c
index d877c0f..ff8e83a 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -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)
diff --git a/gcc/c-gimplify.c b/gcc/c-gimplify.c
index a361e90..9cb4a0b 100644
--- a/gcc/c-gimplify.c
+++ b/gcc/c-gimplify.c
@@ -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;
}
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index 88eb96a..f00e0db 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -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);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index fe172c5..ded72e9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..6708121
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr39983.c
@@ -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;
+}
+