diff options
author | Richard Guenther <rguenther@suse.de> | 2009-05-03 19:57:32 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2009-05-03 19:57:32 +0000 |
commit | 255d3827b4ecd22efa38467bf52a9ee24f96afb5 (patch) | |
tree | c4e6b2079d241859aabc7e14a7760df92602eee4 /gcc | |
parent | 16c337707b0c71829fcad74fdc82d85b1f103eaf (diff) | |
download | gcc-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/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/builtins.c | 47 | ||||
-rw-r--r-- | gcc/c-common.c | 4 | ||||
-rw-r--r-- | gcc/c-gimplify.c | 15 | ||||
-rw-r--r-- | gcc/c-typeck.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/pr39983.c | 17 |
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; +} + |