re PR middle-end/22127 (register window not preserved after getcontext call)
authorEric Botcazou <ebotcazou@libertysurf.fr>
Thu, 10 Nov 2005 16:58:56 +0000 (17:58 +0100)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Thu, 10 Nov 2005 16:58:56 +0000 (16:58 +0000)
PR middle-end/22127
* calls.c (special_function_p): Set ECF_RETURNS_TWICE for getcontext.

From-SVN: r106739

gcc/ChangeLog
gcc/calls.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/sparc-getcontext-1.c [new file with mode: 0644]

index 9e133b12073a0f1a98f32ca31dfcf5469397ec3e..9465d8060a2bd042db4613b6a89e7e67381a55e6 100644 (file)
@@ -1,3 +1,8 @@
+2005-11-10  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       PR middle-end/22127
+       * calls.c (special_function_p): Set ECF_RETURNS_TWICE for getcontext.
+
 2005-11-10  Eric Botcazou  <ebotcazou@adacore.com>
 
        * tree.c (int_fits_type_p): Only look at the base type
index 7dbc21fe4153b60fac2757d689806da065fc05a1..1a680ae5159cd2391758f3be7e24a41f35cb9214 100644 (file)
@@ -527,7 +527,9 @@ special_function_p (tree fndecl, int flags)
       else if ((tname[0] == 'q' && tname[1] == 's'
                && ! strcmp (tname, "qsetjmp"))
               || (tname[0] == 'v' && tname[1] == 'f'
-                  && ! strcmp (tname, "vfork")))
+                  && ! strcmp (tname, "vfork"))
+              || (tname[0] == 'g' && tname[1] == 'e'
+                  && !strcmp (tname, "getcontext")))
        flags |= ECF_RETURNS_TWICE;
 
       else if (tname[0] == 'l' && tname[1] == 'o'
index 2adff3475eea34e9b1f5a0bc8c2bc71d847ba48d..7d3254f58b4959d9457b5cdc33038525d5987aa6 100644 (file)
@@ -1,3 +1,7 @@
+2005-11-10  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       * gcc.dg/sparc-getcontext-1.c: New test.
+
 2005-11-09  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc.dg/ifcvt-fabs-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/sparc-getcontext-1.c b/gcc/testsuite/gcc.dg/sparc-getcontext-1.c
new file mode 100644 (file)
index 0000000..762804c
--- /dev/null
@@ -0,0 +1,118 @@
+/* PR middle-end/22127 */
+/* Testcase by <akr@m17n.org> */
+
+/* [ dg-do run { target sparc*-sun-solaris2.* } } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O" } */
+
+typedef unsigned int size_t;
+extern int printf(const char *, ...);
+typedef unsigned char uint8_t;
+typedef unsigned int uint32_t;
+typedef unsigned int uint_t;
+typedef char *caddr_t;
+typedef int greg_t;
+typedef greg_t gregset_t[19];
+struct rwindow {
+ greg_t rw_local[8];
+ greg_t rw_in[8];
+};
+typedef struct gwindows {
+ int wbcnt;
+ greg_t *spbuf[31];
+ struct rwindow wbuf[31];
+} gwindows_t;
+struct fpu {
+ union {
+  uint32_t fpu_regs[32];
+  double fpu_dregs[16];
+ } fpu_fr;
+ struct fq *fpu_q;
+ uint32_t fpu_fsr;
+ uint8_t fpu_qcnt;
+ uint8_t fpu_q_entrysize;
+ uint8_t fpu_en;
+};
+typedef struct fpu fpregset_t;
+typedef struct {
+ unsigned int xrs_id;
+ caddr_t xrs_ptr;
+} xrs_t;
+typedef struct {
+ gregset_t gregs;
+ gwindows_t *gwins;
+ fpregset_t fpregs;
+ xrs_t xrs;
+ long filler[19];
+} mcontext_t;
+typedef struct {
+ unsigned int __sigbits[4];
+} sigset_t;
+typedef struct sigaltstack {
+ void *ss_sp;
+ size_t ss_size;
+ int ss_flags;
+} stack_t;
+typedef struct ucontext ucontext_t;
+struct ucontext {
+ uint_t uc_flags;
+ ucontext_t *uc_link;
+ sigset_t uc_sigmask;
+ stack_t uc_stack;
+ mcontext_t uc_mcontext;
+ long uc_filler[23];
+};
+extern int getcontext(ucontext_t *);
+extern int setcontext(const ucontext_t *);
+
+int flag;
+ucontext_t cont;
+int pad[100];
+typedef void (*fun_t)(int);
+fun_t p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12;
+
+int global;
+
+extern void abort(void);
+
+void h1(int v)
+{
+  global = v;
+}
+
+void h2(int v)
+{
+  if (v != 1)
+    abort();
+}
+
+void f(void)
+{
+  flag = 1;
+  setcontext(&cont);
+}
+
+int g(void)
+{
+  int ret;
+
+  flag = 0;
+  getcontext(&cont);
+  ret = flag;
+  if (ret == 0) {
+    h1 (flag);
+    p0 = p1 = p2 = p3 = p4 = p5 = p6 = p7 = p8 = h1;
+    f();
+    p0(ret); p1(ret); p2(ret); p3(ret); p4(ret); p5(ret); p6(ret); p7(ret); p8(ret);
+  }
+  else {
+    h2 (flag);
+  }
+  return ret;
+}
+
+int main(void)
+{
+  g();
+  return 0;
+}