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
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)
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;
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;
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)
&& !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;
}
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);
}