From: Jakub Jelinek Date: Fri, 7 Jul 2000 19:55:29 +0000 (+0200) Subject: sibcall.c (uses_addressof): Add INMEM argument... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f5afd9e924c198f8a01a92bb40ff48be87525ab1;p=gcc.git sibcall.c (uses_addressof): Add INMEM argument... * 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. From-SVN: r34906 --- 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 + + * 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 * 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 + + * 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 * 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); +}