+2009-08-26 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/41163
+ * gimplify.c (gimplify_addr_expr): Canonicalize ADDR_EXPRs if
+ the types to not match.
+ * tree-cfg.c (verify_gimple_assign_single): Adjust ADDR_EXPR
+ verification.
+ * tree-ssa.c (useless_type_conversion_p): Conversions to
+ pointers to unprototyped functions are useless.
+
2009-08-26 Richard Guenther <rguenther@suse.de>
* tree-ssa-structalias.c (create_variable_info_for): Remove
if (TREE_CODE (op0) == INDIRECT_REF)
goto do_indirect_ref;
+ mark_addressable (TREE_OPERAND (expr, 0));
+
+ /* The FEs may end up building ADDR_EXPRs early on a decl with
+ an incomplete type. Re-build ADDR_EXPRs in canonical form
+ here. */
+ if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
+ *expr_p = build_fold_addr_expr (op0);
+
/* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
- recompute_tree_invariant_for_addr_expr (expr);
+ recompute_tree_invariant_for_addr_expr (*expr_p);
+
+ /* If we re-built the ADDR_EXPR add a conversion to the original type
+ if required. */
+ if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
+ *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
- mark_addressable (TREE_OPERAND (expr, 0));
break;
}
+2009-08-26 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/41163
+ * gcc.c-torture/compile/pr41163.c: New testcase.
+ * gcc.dg/pr35899.c: Adjust.
+
2009-08-26 Richard Guenther <rguenther@suse.de>
* gcc.dg/tree-ssa/restrict-4.c: New testcase.
--- /dev/null
+struct option {
+ void *value;
+};
+void parse_options (struct option *);
+void cmd_grep(void)
+{
+ struct option options[] = { { &options } };
+ parse_options(options);
+}
+
int
foo (void)
{
- int a = bar (); /* { dg-error "returning 'void'" } */
+ int a = bar ();
return a;
}
return true;
}
- if (!one_pointer_to_useless_type_conversion_p (lhs_type,
- TREE_TYPE (op)))
+ if (!types_compatible_p (TREE_TYPE (op), TREE_TYPE (TREE_TYPE (rhs1)))
+ && !one_pointer_to_useless_type_conversion_p (TREE_TYPE (rhs1),
+ TREE_TYPE (op)))
{
error ("type mismatch in address expression");
- debug_generic_stmt (lhs_type);
- debug_generic_stmt (TYPE_POINTER_TO (TREE_TYPE (op)));
+ debug_generic_stmt (TREE_TYPE (rhs1));
+ debug_generic_stmt (TREE_TYPE (op));
return true;
}
&& POINTER_TYPE_P (outer_type))
{
/* If the outer type is (void *) or a pointer to an incomplete
- record type, then the conversion is not necessary. */
+ record type or a pointer to an unprototyped function,
+ then the conversion is not necessary. */
if (VOID_TYPE_P (TREE_TYPE (outer_type))
|| (AGGREGATE_TYPE_P (TREE_TYPE (outer_type))
&& TREE_CODE (TREE_TYPE (outer_type)) != ARRAY_TYPE
&& (TREE_CODE (TREE_TYPE (outer_type))
== TREE_CODE (TREE_TYPE (inner_type)))
- && !COMPLETE_TYPE_P (TREE_TYPE (outer_type))))
+ && !COMPLETE_TYPE_P (TREE_TYPE (outer_type)))
+ || ((TREE_CODE (TREE_TYPE (outer_type)) == FUNCTION_TYPE
+ || TREE_CODE (TREE_TYPE (outer_type)) == METHOD_TYPE)
+ && (TREE_CODE (TREE_TYPE (outer_type))
+ == TREE_CODE (TREE_TYPE (inner_type)))
+ && !TYPE_ARG_TYPES (TREE_TYPE (outer_type))
+ && useless_type_conversion_p (TREE_TYPE (TREE_TYPE (outer_type)),
+ TREE_TYPE (TREE_TYPE (inner_type)))))
return true;
/* Do not lose casts to restrict qualified pointers. */