summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2000-07-07 19:55:29 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2000-07-07 19:55:29 +0000
commit6e9acf75c0033b72c7b3ac1095302c28fb1835e1 (patch)
treefdedd15c9880042d1b946a1ccf10f032757ff7b1
parentd34352df7a1c0b284e22b8927e15f3bddd0fd64c (diff)
downloadgcc-6e9acf75c0033b72c7b3ac1095302c28fb1835e1.tar.gz
* sibcall.c (uses_addressof): Add INMEM argument, check for
current_function_internal_arg_pointer outside of MEM rtxs in addition to ADDRESSOFs. (sequence_uses_addressof): Update caller. * gcc.c-torture/execute/20000706-1.c: New test. * gcc.c-torture/execute/20000706-2.c: New test. * gcc.c-torture/execute/20000706-3.c: New test. * gcc.c-torture/execute/20000706-4.c: New test. * gcc.c-torture/execute/20000706-5.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@34906 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/sibcall.c34
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20000706-1.c31
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20000706-2.c31
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20000706-3.c27
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20000706-4.c22
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20000706-5.c28
8 files changed, 178 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b197ef5c561..41df73bce62 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2000-07-07 Jakub Jelinek <jakub@redhat.com>
+
+ * sibcall.c (uses_addressof): Add INMEM argument, check for
+ current_function_internal_arg_pointer outside of MEM rtxs in addition
+ to ADDRESSOFs.
+ (sequence_uses_addressof): Update caller.
+
2000-07-07 Zack Weinberg <zack@wolery.cumb.org>
* tradcpp.c (initialize_builtins): Honor NO_BUILTIN_SIZE_TYPE
diff --git a/gcc/sibcall.c b/gcc/sibcall.c
index 8387bf5d79b..120b6410db2 100644
--- a/gcc/sibcall.c
+++ b/gcc/sibcall.c
@@ -37,7 +37,7 @@ static rtx skip_copy_to_return_value PARAMS ((rtx, rtx, rtx));
static rtx skip_use_of_return_value PARAMS ((rtx, enum rtx_code));
static rtx skip_stack_adjustment PARAMS ((rtx));
static rtx skip_jump_insn PARAMS ((rtx));
-static int uses_addressof PARAMS ((rtx));
+static int uses_addressof PARAMS ((rtx, int));
static int sequence_uses_addressof PARAMS ((rtx));
static void purge_reg_equiv_notes PARAMS ((void));
@@ -235,12 +235,18 @@ skip_jump_insn (orig_insn)
return orig_insn;
}
-/* Scan the rtx X for an ADDRESSOF expressions. Return nonzero if an ADDRESSOF
- expresion is found, else return zero. */
+/* Scan the rtx X for ADDRESSOF expressions or
+ current_function_internal_arg_pointer registers.
+ INMEM argument should be 1 if we're looking at inner part of some
+ MEM expression, otherwise 0.
+ Return nonzero if an ADDRESSOF expresion is found or if
+ current_function_internal_arg_pointer is found outside of some MEM
+ expression, else return zero. */
static int
-uses_addressof (x)
+uses_addressof (x, inmem)
rtx x;
+ int inmem;
{
RTX_CODE code;
int i, j;
@@ -254,19 +260,25 @@ uses_addressof (x)
if (code == ADDRESSOF)
return 1;
+ if (x == current_function_internal_arg_pointer && ! inmem)
+ return 1;
+
+ if (code == MEM)
+ return uses_addressof (XEXP (x, 0), 1);
+
/* Scan all subexpressions. */
fmt = GET_RTX_FORMAT (code);
for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
{
if (*fmt == 'e')
{
- if (uses_addressof (XEXP (x, i)))
+ if (uses_addressof (XEXP (x, i), inmem))
return 1;
}
else if (*fmt == 'E')
{
for (j = 0; j < XVECLEN (x, i); j++)
- if (uses_addressof (XVECEXP (x, i, j)))
+ if (uses_addressof (XVECEXP (x, i, j), inmem))
return 1;
}
}
@@ -274,8 +286,10 @@ uses_addressof (x)
}
/* Scan the sequence of insns in SEQ to see if any have an ADDRESSOF
- rtl expression. If an ADDRESSOF expression is found, return nonzero,
- else return zero.
+ rtl expression or current_function_internal_arg_pointer occurences
+ not enclosed within a MEM. If an ADDRESSOF expression or
+ current_function_internal_arg_pointer is found, return nonzero, otherwise
+ return zero.
This function handles CALL_PLACEHOLDERs which contain multiple sequences
of insns. */
@@ -304,8 +318,8 @@ sequence_uses_addressof (seq)
&& sequence_uses_addressof (XEXP (PATTERN (insn), 2)))
return 1;
}
- else if (uses_addressof (PATTERN (insn))
- || (REG_NOTES (insn) && uses_addressof (REG_NOTES (insn))))
+ else if (uses_addressof (PATTERN (insn), 0)
+ || (REG_NOTES (insn) && uses_addressof (REG_NOTES (insn), 0)))
return 1;
}
return 0;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 41337577793..e50a96c720a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2000-07-07 Jakub Jelinek <jakub@redhat.com>
+
+ * gcc.c-torture/execute/20000706-1.c: New test.
+ * gcc.c-torture/execute/20000706-2.c: New test.
+ * gcc.c-torture/execute/20000706-3.c: New test.
+ * gcc.c-torture/execute/20000706-4.c: New test.
+ * gcc.c-torture/execute/20000706-5.c: New test.
+
2000-07-06 Nathan Sidwell <nathan@codesourcery.com>
* g++.old-deja/g++.pt/instantiate7.C: New test.
diff --git a/gcc/testsuite/gcc.c-torture/execute/20000706-1.c b/gcc/testsuite/gcc.c-torture/execute/20000706-1.c
new file mode 100644
index 00000000000..e8eb28581ff
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20000706-1.c
@@ -0,0 +1,31 @@
+extern void abort(void);
+extern void exit(int);
+
+struct baz {
+ int a, b, c, d, e;
+};
+
+void bar(struct baz *x, int f, int g, int h, int i, int j)
+{
+ if (x->a != 1 || x->b != 2 || x->c != 3 || x->d != 4 || x->e != 5 ||
+ f != 6 || g != 7 || h != 8 || i != 9 || j != 10)
+ abort();
+}
+
+void foo(struct baz x, char **y)
+{
+ bar(&x,6,7,8,9,10);
+}
+
+int main()
+{
+ struct baz x;
+
+ x.a = 1;
+ x.b = 2;
+ x.c = 3;
+ x.d = 4;
+ x.e = 5;
+ foo(x,(char **)0);
+ exit(0);
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20000706-2.c b/gcc/testsuite/gcc.c-torture/execute/20000706-2.c
new file mode 100644
index 00000000000..faf2137111a
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20000706-2.c
@@ -0,0 +1,31 @@
+extern void abort(void);
+extern void exit(int);
+
+struct baz {
+ int a, b, c, d, e;
+};
+
+void bar(struct baz *x, int f, int g, int h, int i, int j)
+{
+ if (x->a != 1 || x->b != 2 || x->c != 3 || x->d != 4 || x->e != 5 ||
+ f != 6 || g != 7 || h != 8 || i != 9 || j != 10)
+ abort();
+}
+
+void foo(char *z, struct baz x, char *y)
+{
+ bar(&x,6,7,8,9,10);
+}
+
+int main()
+{
+ struct baz x;
+
+ x.a = 1;
+ x.b = 2;
+ x.c = 3;
+ x.d = 4;
+ x.e = 5;
+ foo((char *)0,x,(char *)0);
+ exit(0);
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20000706-3.c b/gcc/testsuite/gcc.c-torture/execute/20000706-3.c
new file mode 100644
index 00000000000..b5758d9abb0
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20000706-3.c
@@ -0,0 +1,27 @@
+extern void abort(void);
+extern void exit(int);
+
+int c;
+
+void baz(int *p)
+{
+ c = *p;
+}
+
+void bar(int b)
+{
+ if (c != 1 || b != 2)
+ abort();
+}
+
+void foo(int a, int b)
+{
+ baz(&a);
+ bar(b);
+}
+
+int main()
+{
+ foo(1, 2);
+ exit(0);
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20000706-4.c b/gcc/testsuite/gcc.c-torture/execute/20000706-4.c
new file mode 100644
index 00000000000..01cc879c34a
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20000706-4.c
@@ -0,0 +1,22 @@
+extern void abort(void);
+extern void exit(int);
+
+int *c;
+
+void bar(int b)
+{
+ if (*c != 1 || b != 2)
+ abort();
+}
+
+void foo(int a, int b)
+{
+ c = &a;
+ bar(b);
+}
+
+int main()
+{
+ foo(1, 2);
+ exit(0);
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20000706-5.c b/gcc/testsuite/gcc.c-torture/execute/20000706-5.c
new file mode 100644
index 00000000000..18756f29ddc
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20000706-5.c
@@ -0,0 +1,28 @@
+extern void abort(void);
+extern void exit(int);
+
+struct baz { int a, b, c; };
+
+struct baz *c;
+
+void bar(int b)
+{
+ if (c->a != 1 || c->b != 2 || c->c != 3 || b != 4)
+ abort();
+}
+
+void foo(struct baz a, int b)
+{
+ c = &a;
+ bar(b);
+}
+
+int main()
+{
+ struct baz a;
+ a.a = 1;
+ a.b = 2;
+ a.c = 3;
+ foo(a, 4);
+ exit(0);
+}