summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20041211-1.c13
-rw-r--r--gcc/tree-inline.c24
4 files changed, 48 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c792108f3f9..e12edaf40d9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2004-12-13 Alexandre Oliva <aoliva@redhat.com>
+
+ PR tree-opt/16951
+ * tree-inline.c (setup_one_parameter): Don't directly map a
+ parameter to the address of another variable of the same
+ function.
+
2004-13-12 Steven Bosscher <stevenb@suse.de>
* basic-block.h (PROP_POSTRELOAD): Do not include PROP_AUTOINC, we
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8dd7e1c95fa..647411ef7fe 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2004-12-13 Alexandre Oliva <aoliva@redhat.com>
+
+ PR tree-opt/16951
+ * gcc.c-torture/compile/20041211-1.c: New.
+
2004-12-12 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
PR middle-end/17564
diff --git a/gcc/testsuite/gcc.c-torture/compile/20041211-1.c b/gcc/testsuite/gcc.c-torture/compile/20041211-1.c
new file mode 100644
index 00000000000..5b9c1d069d9
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20041211-1.c
@@ -0,0 +1,13 @@
+/* PR tree-optimization/16951 */
+
+void dummy_use(const char *p);
+
+__inline void f(const char *const p) {
+ const char q;
+ dummy_use(p);
+ f(&q);
+}
+
+void crash() {
+ f(0);
+}
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 29740df72b0..db2b2361874 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -655,6 +655,22 @@ copy_body (inline_data *id)
return body;
}
+/* Return true if VALUE is an ADDR_EXPR of an automatic variable
+ defined in function FN, or of a data member thereof. */
+
+static bool
+self_inlining_addr_expr (tree value, tree fn)
+{
+ tree var;
+
+ if (TREE_CODE (value) != ADDR_EXPR)
+ return false;
+
+ var = get_base_address (TREE_OPERAND (value, 0));
+
+ return var && lang_hooks.tree_inlining.auto_var_in_fn_p (var, fn);
+}
+
static void
setup_one_parameter (inline_data *id, tree p, tree value, tree fn,
tree *init_stmts, tree *vars, bool *gimplify_init_stmts_p)
@@ -679,7 +695,13 @@ setup_one_parameter (inline_data *id, tree p, tree value, tree fn,
It is not big deal to prohibit constant propagation here as
we will constant propagate in DOM1 pass anyway. */
if (is_gimple_min_invariant (value)
- && lang_hooks.types_compatible_p (TREE_TYPE (value), TREE_TYPE (p)))
+ && lang_hooks.types_compatible_p (TREE_TYPE (value), TREE_TYPE (p))
+ /* We have to be very careful about ADDR_EXPR. Make sure
+ the base variable isn't a local variable of the inlined
+ function, e.g., when doing recursive inlining, direct or
+ mutually-recursive or whatever, which is why we don't
+ just test whether fn == current_function_decl. */
+ && ! self_inlining_addr_expr (value, fn))
{
insert_decl_map (id, p, value);
return;