diff options
author | Ian Bolton <ian.bolton@arm.com> | 2010-08-19 08:27:59 +0000 |
---|---|---|
committer | Ramana Radhakrishnan <ramana@gcc.gnu.org> | 2010-08-19 08:27:59 +0000 |
commit | c92f1823b0f338f196da7586af13fd93b5a950ef (patch) | |
tree | 3a7046701b34c0d55f7149dc9e54e1e7a08448d0 /gcc | |
parent | f096c02afcfad5fbb2e0021af89520c3745084e5 (diff) | |
download | gcc-c92f1823b0f338f196da7586af13fd93b5a950ef.zip gcc-c92f1823b0f338f196da7586af13fd93b5a950ef.tar.gz gcc-c92f1823b0f338f196da7586af13fd93b5a950ef.tar.bz2 |
For Ian Bolton <ian.bolton@arm.com>
2010-08-19 Ian Bolton <ian.bolton@arm.com>
PR target/45070
* gcc.c-torture/execute/pr45070.c: New.
* config/arm/arm.c (arm_output_epilogue): Ensure that return
value of size 1-3 is handled correctly.
From-SVN: r163367
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr45070.c | 52 |
4 files changed, 65 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4711095..ff0e2c0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2010-08-19 Ian Bolton <ian.bolton@arm.com> + PR target/45070 + * config/arm/arm.c (arm_output_epilogue): Ensure that return + value of size 1-3 is handled correctly. + +2010-08-19 Ian Bolton <ian.bolton@arm.com> + * tree-switch-conversion.c (gen_inbound_check): Ensure that the type for the conditional has wide enough range. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index f6148a7..5ed16a8 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -14467,7 +14467,8 @@ arm_output_epilogue (rtx sibling) && !crtl->tail_call_emit) { unsigned long mask; - mask = (1 << (arm_size_return_regs() / 4)) - 1; + /* Preserve return values, of any size. */ + mask = (1 << ((arm_size_return_regs() + 3) / 4)) - 1; mask ^= 0xf; mask &= ~saved_regs_mask; reg = 0; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index afd8b99..f4d145a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2010-08-19 Ian Bolton <ian.bolton@arm.com> + PR target/45070 + * gcc.c-torture/execute/pr45070.c: New. + +2010-08-19 Ian Bolton <ian.bolton@arm.com> + * g++.dg/pr44328.C: New test. 2010-08-19 Tobias Burnus <burnus@net-b.de> diff --git a/gcc/testsuite/gcc.c-torture/execute/pr45070.c b/gcc/testsuite/gcc.c-torture/execute/pr45070.c new file mode 100644 index 0000000..95ff77a --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr45070.c @@ -0,0 +1,52 @@ +/* PR45070 */ +extern void abort(void); + +struct packed_ushort { + unsigned short ucs; +} __attribute__((packed)); + +struct source { + int pos, length; + int flag; +}; + +static void __attribute__((noinline)) fetch(struct source *p) +{ + p->length = 128; +} + +static struct packed_ushort __attribute__((noinline)) next(struct source *p) +{ + struct packed_ushort rv; + + if (p->pos >= p->length) { + if (p->flag) { + p->flag = 0; + fetch(p); + return next(p); + } + p->flag = 1; + rv.ucs = 0xffff; + return rv; + } + rv.ucs = 0; + return rv; +} + +int main(void) +{ + struct source s; + int i; + + s.pos = 0; + s.length = 0; + s.flag = 0; + + for (i = 0; i < 16; i++) { + struct packed_ushort rv = next(&s); + if ((i == 0 && rv.ucs != 0xffff) + || (i > 0 && rv.ucs != 0)) + abort(); + } + return 0; +} |