aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIan Bolton <ian.bolton@arm.com>2010-08-19 08:27:59 +0000
committerRamana Radhakrishnan <ramana@gcc.gnu.org>2010-08-19 08:27:59 +0000
commitc92f1823b0f338f196da7586af13fd93b5a950ef (patch)
tree3a7046701b34c0d55f7149dc9e54e1e7a08448d0 /gcc
parentf096c02afcfad5fbb2e0021af89520c3745084e5 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/config/arm/arm.c3
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr45070.c52
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;
+}