OSDN Git Service

* tree.c (unsave_expr_now): Avoid recursing into the parts of
[pf3gnuchains/gcc-fork.git] / gcc / libgcc2.c
index 9fcd17e..c32a7e0 100644 (file)
@@ -1483,7 +1483,7 @@ __bb_exit_func (void)
          /* If the file exists, and the number of counts in it is the same,
             then merge them in.  */
             
-         if ((da_file = fopen (ptr->filename, "r")) != NULL)
+         if ((da_file = fopen (ptr->filename, "r")) != 0)
            {
              long n_counts = 0;
              unsigned char tmp;
@@ -1815,8 +1815,8 @@ gopen (char *fn, char *mode)
     return (FILE *) 0;
 
   p = fn + strlen (fn)-1;
-  use_gzip = ((p[-1] == '.' && (p[0] == 'Z' || p[0] == 'z')) ||
-              (p[-2] == '.' && p[-1] == 'g' && p[0] == 'z'));
+  use_gzip = ((p[-1] == '.' && (p[0] == 'Z' || p[0] == 'z'))
+             || (p[-2] == '.' && p[-1] == 'g' && p[0] == 'z'));
 
   if (use_gzip)
     {
@@ -1855,7 +1855,7 @@ gclose (FILE *f)
 {
   struct stat buf;
 
-  if (f != NULL)
+  if (f != 0)
     {
       if (!fstat (fileno (f), &buf) && S_ISFIFO (buf.st_mode))
         return pclose (f);
@@ -2195,15 +2195,15 @@ __bb_trace_func ()
     {
       struct bb_edge **startbucket, **oldnext;
 
-      oldnext = startbucket =
-          & bb_hashbuckets[ (((int) bb_src*8) ^ (int) bb_dst) % BB_BUCKETS ];
+      oldnext = startbucket
+       = & bb_hashbuckets[ (((int) bb_src*8) ^ (int) bb_dst) % BB_BUCKETS ];
       bucket = *startbucket;
 
       for (bucket = *startbucket; bucket; 
            oldnext = &(bucket->next), bucket = *oldnext)
         {
-          if ( bucket->src_addr == bb_src &&
-               bucket->dst_addr == bb_dst )
+          if (bucket->src_addr == bb_src
+             && bucket->dst_addr == bb_dst)
             {
               bucket->count++;
               *oldnext = bucket->next;
@@ -2258,15 +2258,15 @@ __bb_trace_func_ret ()
     {
       struct bb_edge **startbucket, **oldnext;
 
-      oldnext = startbucket =
-          & bb_hashbuckets[ (((int) bb_dst * 8) ^ (int) bb_src) % BB_BUCKETS ];
+      oldnext = startbucket
+       = & bb_hashbuckets[ (((int) bb_dst * 8) ^ (int) bb_src) % BB_BUCKETS ];
       bucket = *startbucket;
 
       for (bucket = *startbucket; bucket; 
            oldnext = &(bucket->next), bucket = *oldnext)
         {
-          if ( bucket->src_addr == bb_dst &&
-               bucket->dst_addr == bb_src )
+          if (bucket->src_addr == bb_dst
+              && bucket->dst_addr == bb_src)
             {
               bucket->count++;
               *oldnext = bucket->next;
@@ -2321,8 +2321,8 @@ __bb_init_file (struct bb *blocks)
   bb_head = blocks;
 
   blocks->flags = 0;
-  if (!bb_func_head ||
-      !(blocks->flags = (char *) malloc (sizeof (char) * blocks->ncounts)))
+  if (!bb_func_head
+      || !(blocks->flags = (char *) malloc (sizeof (char) * blocks->ncounts)))
     return;
 
   for (blk = 0; blk < ncounts; blk++)
@@ -2332,8 +2332,8 @@ __bb_init_file (struct bb *blocks)
     {
       for (p = bb_func_head; p; p = p->next)
         {
-          if (!strcmp (p->funcname, functions[blk]) &&
-              (!p->filename || !strcmp (p->filename, blocks->filename)))
+          if (!strcmp (p->funcname, functions[blk])
+             && (!p->filename || !strcmp (p->filename, blocks->filename)))
             {
               blocks->flags[blk] |= p->mode;
             }
@@ -3022,7 +3022,7 @@ int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
 #ifdef NEED_ATEXIT
 # include <errno.h>
 
-static func_ptr *atexit_chain = NULL;
+static func_ptr *atexit_chain = 0;
 static long atexit_chain_length = 0;
 static volatile long last_atexit_chain_slot = -1;
 
@@ -3032,10 +3032,11 @@ int atexit (func_ptr func)
     {
       atexit_chain_length += 32;
       if (atexit_chain)
-       atexit_chain = realloc (atexit_chain,
-                               atexit_chain_length * sizeof (func_ptr));
+       atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
+                                            * sizeof (func_ptr));
       else
-       atexit_chain = malloc (atexit_chain_length * sizeof (func_ptr));
+       atexit_chain = (func_ptr *) malloc (atexit_chain_length
+                                           * sizeof (func_ptr));
       if (! atexit_chain)
        {
          atexit_chain_length = 0;
@@ -3068,10 +3069,10 @@ exit (int status)
       for ( ; last_atexit_chain_slot-- >= 0; )
        {
          (*atexit_chain[last_atexit_chain_slot + 1]) ();
-         atexit_chain[last_atexit_chain_slot + 1] = NULL;
+         atexit_chain[last_atexit_chain_slot + 1] = 0;
        }
       free (atexit_chain);
-      atexit_chain = NULL;
+      atexit_chain = 0;
     }
 #else /* No NEED_ATEXIT */
   __do_global_dtors ();
@@ -3102,6 +3103,180 @@ EH_TABLE_LOOKUP
 
 #else
 
+void
+__default_terminate ()
+{
+  abort ();
+}
+
+void (*__terminate_func)() = __default_terminate;
+
+void
+__terminate ()
+{
+  (*__terminate_func)();
+}
+
+/* Calls to __sjthrow are generated by the compiler when an exception
+   is raised when using the setjmp/longjmp exception handling codegen
+   method.  */
+
+extern void longjmp (void *, int);
+
+extern void *__eh_type;
+
+static void *top_elt[2];
+void **__dynamic_handler_chain = top_elt;
+
+/* Routine to get the head of the current thread's dynamic handler chain
+   use for exception handling.
+
+   TODO: make thread safe.  */
+
+void ***
+__get_dynamic_handler_chain ()
+{
+  return &__dynamic_handler_chain;
+}
+
+/* This is used to throw an exception when the setjmp/longjmp codegen
+   method is used for exception handling.
+
+   We call __terminate if there are no handlers left (we know this
+   when the dynamic handler chain is top_elt).  Otherwise we run the
+   cleanup actions off the dynamic cleanup stack, and pop the top of
+   the dynamic handler chain, and use longjmp to transfer back to the
+   associated handler.  */
+
+void
+__sjthrow ()
+{
+  void ***dhc = __get_dynamic_handler_chain ();
+  void *jmpbuf;
+  void (*func)(void *, int);
+  void *arg;
+  void ***cleanup;
+
+  /* The cleanup chain is one word into the buffer.  Get the cleanup
+     chain.  */
+  cleanup = (void***)&(*dhc)[1];
+
+  /* If there are any cleanups in the chain, run them now.  */
+  if (cleanup[0])
+    {
+      double store[200];
+      void **buf = (void**)store;
+      buf[1] = 0;
+      buf[0] = (*dhc);
+
+      /* try { */
+#ifdef DONT_USE_BUILTIN_SETJMP
+      if (! setjmp (&buf[2]))
+#else
+      if (! __builtin_setjmp (&buf[2]))
+#endif
+       {
+         *dhc = buf;
+         while (cleanup[0])
+           {
+             func = (void(*)(void*, int))cleanup[0][1];
+             arg = (void*)cleanup[0][2];
+
+             /* Update this before running the cleanup.  */
+             cleanup[0] = (void **)cleanup[0][0];
+
+             (*func)(arg, 2);
+           }
+         *dhc = buf[0];
+       }
+      /* catch (...) */
+      else
+       {
+         __terminate ();
+       }
+    }
+  
+  /* We must call terminate if we try and rethrow an exception, when
+     there is no exception currently active and when there are no
+     handlers left.  */
+  if (! __eh_type || (*dhc) == top_elt)
+    __terminate ();
+    
+  /* Find the jmpbuf associated with the top element of the dynamic
+     handler chain.  The jumpbuf starts two words into the buffer.  */
+  jmpbuf = &(*dhc)[2];
+
+  /* Then we pop the top element off the dynamic handler chain.  */
+  *dhc = (void**)(*dhc)[0];
+
+  /* And then we jump to the handler.  */
+
+#ifdef DONT_USE_BUILTIN_SETJMP
+  longjmp (jmpbuf, 1);
+#else
+  __builtin_longjmp (jmpbuf, 1);
+#endif
+}
+
+/* Run cleanups on the dynamic cleanup stack for the current dynamic
+   handler, then pop the handler off the dynamic handler stack, and
+   then throw.  This is used to skip the first handler, and transfer
+   control to the next handler in the dynamic handler stack.  */
+
+void
+__sjpopnthrow ()
+{
+  void ***dhc = __get_dynamic_handler_chain ();
+  void *jmpbuf;
+  void (*func)(void *, int);
+  void *arg;
+  void ***cleanup;
+
+  /* The cleanup chain is one word into the buffer.  Get the cleanup
+     chain.  */
+  cleanup = (void***)&(*dhc)[1];
+
+  /* If there are any cleanups in the chain, run them now.  */
+  if (cleanup[0])
+    {
+      double store[200];
+      void **buf = (void**)store;
+      buf[1] = 0;
+      buf[0] = (*dhc);
+
+      /* try { */
+#ifdef DONT_USE_BUILTIN_SETJMP
+      if (! setjmp (&buf[2]))
+#else
+      if (! __builtin_setjmp (&buf[2]))
+#endif
+       {
+         *dhc = buf;
+         while (cleanup[0])
+           {
+             func = (void(*)(void*, int))cleanup[0][1];
+             arg = (void*)cleanup[0][2];
+
+             /* Update this before running the cleanup.  */
+             cleanup[0] = (void **)cleanup[0][0];
+
+             (*func)(arg, 2);
+           }
+         *dhc = buf[0];
+       }
+      /* catch (...) */
+      else
+       {
+         __terminate ();
+       }
+    }
+
+  /* Then we pop the top element off the dynamic handler chain.  */
+  *dhc = (void**)(*dhc)[0];
+
+  __sjthrow ();
+}
+
 typedef struct {
   void *start;
   void *end;
@@ -3261,6 +3436,16 @@ __throw ()
 
 void *__eh_pc;
 
+/* See expand_builtin_throw for details.  */
+
+void **__eh_ffetmnpc () {
+  static void *buf[2] = {
+    &__find_first_exception_table_match,
+    &__eh_pc
+  };
+  return buf;
+}
+
 void
 __empty ()
 {