]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
revert large changes
authorJason Merrill <jason@gcc.gnu.org>
Fri, 21 Nov 1997 21:04:23 +0000 (16:04 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 21 Nov 1997 21:04:23 +0000 (16:04 -0500)
From-SVN: r16655

12 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/cp/ChangeLog
gcc/cp/Make-lang.in
gcc/cp/decl.c
gcc/cp/except.c
gcc/cp/exception.cc
gcc/cp/new.cc
gcc/cp/new1.cc
gcc/cp/new2.cc
gcc/cp/tinfo2.cc
gcc/libgcc2.c

index b94e102ec9f0bf87894d5b240d6dc36ed4be2aa2..f2df07d0752ec5f614ae57c0d515a3387b6f8c76 100644 (file)
@@ -21,10 +21,6 @@ Thu Nov 20 16:11:50 1997  Klaus Kaempf  <kkaempf@progis.de>
 
 Thu Nov 20 14:42:15 1997  Jason Merrill  <jason@yorick.cygnus.com>
 
-       * Makefile.in (LIB2FUNCS): Remove C++ memory management support.
-       * libgcc2.c: Remove __builtin_new, __builtin_vec_new, set_new_handler, 
-       __builtin_delete, and __builtin_vec_delete.
-
        * except.c (output_exception_table): Don't bother with
        __EXCEPTION_END__.
 
index 3779ae2e63626296fa94086a50f8ee88a7c3b5fd..b02f0c6ec0761f284ae18bb9a4b82ba675d13ef2 100644 (file)
@@ -631,8 +631,8 @@ LIB2FUNCS = _muldi3 _divdi3 _moddi3 _udivdi3 _umoddi3 _negdi2 \
     _fixunsdfsi _fixunssfsi _fixunsdfdi _fixdfdi _fixunssfdi _fixsfdi \
     _fixxfdi _fixunsxfdi _floatdixf _fixunsxfsi \
     _fixtfdi _fixunstfdi _floatditf \
-    __gcc_bcmp _varargs __dummy _eprintf \
-    _bb _shtab _clear_cache _trampoline __main _exit \
+    __gcc_bcmp _varargs __dummy _eprintf _op_new _op_vnew _new_handler \
+    _op_delete _op_vdel _bb _shtab _clear_cache _trampoline __main _exit \
     _ctors _eh  _pure
 
 # The files that "belong" in CONFIG_H are deliberately omitted
index 48099a7a822790cbcfffd46b9b31b13152f21610..8a5a8b37d2258a13d817e2a028887a0b0e25ae4f 100644 (file)
@@ -1,31 +1,11 @@
 Fri Nov 21 12:22:07 1997  Jason Merrill  <jason@yorick.cygnus.com>
 
-       * except.c (expand_start_eh_spec): Use the try/catch code.
-       (expand_end_eh_spec): Likewise.  Call __check_eh_spec instead of
-       doing everything inline.
-       (init_exception_processing): throw_type_match now takes
-       const void pointers.
-       * exception.cc (__check_eh_spec): New fn.
-       * inc/exception: Neither terminate nor unexpected return.
-       * decl.c: Make const_ptr_type_node public.
-       * tinfo2.cc (__throw_type_match_rtti): Take the typeinfos constly.
-
        * except.c (expand_start_catch_block): We only need the rethrow
        region for non-sjlj exceptions.
        (expand_end_catch_block): Likewise.  Use outer_context_label_stack.
 
 Thu Nov 20 14:40:17 1997  Jason Merrill  <jason@yorick.cygnus.com>
 
-       * Make-lang.in (CXX_LIB2FUNCS): Add new op new and op delete objs.
-       (various.o): Likewise.
-       * inc/new: Add placement deletes.  Add throw specs for default new.
-       * new.cc (set_new_handler): Move here from libgcc2.
-       * new1.cc (new (nothrow)): Catch a bad_alloc thrown from the handler.
-       (new): Move from libgcc2.  Throw bad_alloc.
-       * new2.cc: Move the rest of the op news and op deletes from libgcc2.
-       * decl.c (init_decl_processing): Update exception specs on new and
-       delete.
-
        * method.c (build_decl_overload_real): Don't mess with global 
        placement delete.
 
index fa0f1dd628937bd8b7cc5fb0f36f0c9941652936..903faffc2aceb6cbce6b352abbe04c3befafc1fc 100644 (file)
@@ -58,8 +58,7 @@ CXX_EXTRA_HEADERS = $(srcdir)/cp/inc/typeinfo $(srcdir)/cp/inc/exception \
        $(srcdir)/cp/inc/new $(srcdir)/cp/inc/new.h
 
 # Extra code to include in libgcc2.
-CXX_LIB2FUNCS = tinfo.o tinfo2.o new.o opnew.o opnewnt.o opvnew.o opvnewnt.o \
-       opdel.o opdelnt.o opvdel.o opvdelnt.o exception.o
+CXX_LIB2FUNCS = tinfo.o tinfo2.o new.o new1.o new2.o exception.o
 CXX_LIB2SRCS = $(srcdir)/cp/new.cc $(srcdir)/cp/new1.cc $(srcdir)/cp/new2.cc \
        $(srcdir)/cp/exception.cc $(srcdir)/cp/tinfo.cc \
        $(srcdir)/cp/tinfo2.cc $(srcdir)/cp/tinfo.h
@@ -148,30 +147,12 @@ exception.o: cc1plus $(srcdir)/cp/exception.cc
 new.o: cc1plus $(srcdir)/cp/new.cc
        $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \
          -c $(srcdir)/cp/new.cc
-opnew.o: cc1plus $(srcdir)/cp/new1.cc
+new1.o: cc1plus $(srcdir)/cp/new1.cc
        $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \
-         -c $(srcdir)/cp/new1.cc -DL_op_new -o opnew.o
-opnewnt.o: cc1plus $(srcdir)/cp/new1.cc
+         -c $(srcdir)/cp/new1.cc
+new2.o: cc1plus $(srcdir)/cp/new2.cc
        $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \
-         -c $(srcdir)/cp/new1.cc -DL_op_newnt -o opnewnt.o
-opvnew.o: cc1plus $(srcdir)/cp/new2.cc
-       $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \
-         -c $(srcdir)/cp/new2.cc -DL_op_vnew -o opvnew.o
-opvnewnt.o: cc1plus $(srcdir)/cp/new2.cc
-       $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \
-         -c $(srcdir)/cp/new2.cc -DL_op_vnewnt -o opvnewnt.o
-opdel.o: cc1plus $(srcdir)/cp/new2.cc
-       $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \
-         -c $(srcdir)/cp/new2.cc -DL_op_delete -o opdel.o
-opdelnt.o: cc1plus $(srcdir)/cp/new2.cc
-       $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \
-         -c $(srcdir)/cp/new2.cc -DL_op_delnt -o opdelnt.o
-opvdel.o: cc1plus $(srcdir)/cp/new2.cc
-       $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \
-         -c $(srcdir)/cp/new2.cc -DL_op_vdel -o opvdel.o
-opvdelnt.o: cc1plus $(srcdir)/cp/new2.cc
-       $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \
-         -c $(srcdir)/cp/new2.cc -DL_op_vdelnt -o opvdelnt.o
+         -c $(srcdir)/cp/new2.cc
 
 # We want to update cplib2.txt if any of the source files change...
 cplib2.txt: $(CXX_LIB2SRCS) $(CXX_EXTRA_HEADERS) cplib2.ready
index c9e5c475ee56e8d4467e35a2ca63c16f6c31dbda..b60f842fa43b8bcc9939368a9c16e18b212b5615 100644 (file)
@@ -239,7 +239,7 @@ tree void_zero_node;
 /* Nodes for types `void *' and `const void *'.  */
 
 tree ptr_type_node;
-tree const_ptr_type_node;
+static tree const_ptr_type_node;
 
 /* Nodes for types `char *' and `const char *'.  */
 
@@ -5577,18 +5577,14 @@ init_decl_processing ()
   /* Now, C++.  */
   current_lang_name = lang_name_cplusplus;
 
-  {
-    tree bad_alloc_type_node = xref_tag
-      (class_type_node, get_identifier ("bad_alloc"), NULL_TREE, 1);
-    tree newtype = build_exception_variant
-      (ptr_ftype_sizetype, build_tree_list (NULL_TREE, bad_alloc_type_node));
-    tree deltype = build_exception_variant
-      (void_ftype_ptr, build_tree_list (NULL_TREE, NULL_TREE));
-    auto_function (ansi_opname[(int) NEW_EXPR], newtype, NOT_BUILT_IN);
-    auto_function (ansi_opname[(int) VEC_NEW_EXPR], newtype, NOT_BUILT_IN);
-    auto_function (ansi_opname[(int) DELETE_EXPR], deltype, NOT_BUILT_IN);
-    auto_function (ansi_opname[(int) VEC_DELETE_EXPR], deltype, NOT_BUILT_IN);
-  }
+  auto_function (ansi_opname[(int) NEW_EXPR], ptr_ftype_sizetype,
+                NOT_BUILT_IN);
+  auto_function (ansi_opname[(int) VEC_NEW_EXPR], ptr_ftype_sizetype,
+                NOT_BUILT_IN);
+  auto_function (ansi_opname[(int) DELETE_EXPR], void_ftype_ptr,
+                NOT_BUILT_IN);
+  auto_function (ansi_opname[(int) VEC_DELETE_EXPR], void_ftype_ptr,
+                NOT_BUILT_IN);
 
   abort_fndecl
     = define_function ("__pure_virtual", void_ftype,
index bd26053dfcef3d343a828eb348d4b6db5ab6e40a..5c2344d43d799140e277f117b749865ccaab8c4e 100644 (file)
@@ -197,7 +197,6 @@ static tree saved_pc;
 
 extern int throw_used;
 extern rtx catch_clauses;
-extern tree const_ptr_type_node;
 
 /* ========================================================================= */
 
@@ -264,8 +263,8 @@ init_exception_processing ()
                        ? "__throw_type_match_rtti"
                        : "__throw_type_match",
                        build_function_type (ptr_type_node,
-                                            tree_cons (NULL_TREE, const_ptr_type_node,
-                                                       tree_cons (NULL_TREE, const_ptr_type_node,
+                                            tree_cons (NULL_TREE, ptr_type_node,
+                                                       tree_cons (NULL_TREE, ptr_type_node,
                                                                   tree_cons (NULL_TREE, ptr_type_node,
                                                                              void_list_node)))),
                        NOT_BUILT_IN, NULL_PTR);
@@ -1021,84 +1020,101 @@ expand_builtin_throw ()
 #endif /* DWARF2_UNWIND_INFO */
 }
 
-/* An exception spec is implemented more or less like:
-
-   try {
-     function body;
-   } catch (...) {
-     void *p[] = { typeid(raises) };
-     __check_eh_spec (p, count);
-   }
-
-   __check_eh_spec in exception.cc handles all the details.  */
 
 void
 expand_start_eh_spec ()
 {
-  expand_start_try_stmts ();
+  expand_eh_region_start ();
 }
 
 static void
 expand_end_eh_spec (raises)
      tree raises;
 {
-  tree tmp, fn, decl, types = NULL_TREE;
-  int count = 0;
-
-  expand_start_all_catch ();
-  expand_start_catch_block (NULL_TREE, NULL_TREE);
+  tree expr, second_try;
+  rtx check = gen_label_rtx ();
+  rtx cont;
+  rtx ret = gen_reg_rtx (Pmode);
+  rtx flag = gen_reg_rtx (TYPE_MODE (integer_type_node));
+  rtx end = gen_label_rtx ();
+
+  expr = make_node (RTL_EXPR);
+  TREE_TYPE (expr) = void_type_node;
+  RTL_EXPR_RTL (expr) = const0_rtx;
+  TREE_SIDE_EFFECTS (expr) = 1;
+  do_pending_stack_adjust ();
+  start_sequence_for_rtl_expr (expr);
+  cont = gen_label_rtx ();
+  emit_move_insn (ret, gen_rtx (LABEL_REF, Pmode, cont));
+  emit_jump (check);
+  emit_label (cont);
+  jumpif (make_tree (integer_type_node, flag), end);
+  do_function_call (Terminate, NULL_TREE, NULL_TREE);
+  assemble_external (TREE_OPERAND (Terminate, 0));
+  emit_barrier ();
+  do_pending_stack_adjust ();
+  RTL_EXPR_SEQUENCE (expr) = get_insns ();
+  end_sequence ();
+  
+  second_try = expr;
 
-  /* Build up an array of type_infos.  */
-  for (; raises && TREE_VALUE (raises); raises = TREE_CHAIN (raises))
-    {
-      types = expr_tree_cons
-       (NULL_TREE, build_eh_type_type (TREE_VALUE (raises)), types);
-      ++count;
-    }
+  expr = make_node (RTL_EXPR);
+  TREE_TYPE (expr) = void_type_node;
+  RTL_EXPR_RTL (expr) = const0_rtx;
+  TREE_SIDE_EFFECTS (expr) = 1;
+  do_pending_stack_adjust ();
+  start_sequence_for_rtl_expr (expr);
 
-  types = build_nt (CONSTRUCTOR, NULL_TREE, types);
-  TREE_HAS_CONSTRUCTOR (types) = 1;
+  cont = gen_label_rtx ();
+  emit_move_insn (ret, gen_rtx (LABEL_REF, Pmode, cont));
+  emit_jump (check);
+  emit_label (cont);
+  jumpif (make_tree (integer_type_node, flag), end);
+  expand_eh_region_start ();
+  do_function_call (Unexpected, NULL_TREE, NULL_TREE);
+  assemble_external (TREE_OPERAND (Unexpected, 0));
+  emit_barrier ();
 
-  /* We can't pass the CONSTRUCTOR directly, so stick it in a variable.  */
-  tmp = build_array_type (const_ptr_type_node, NULL_TREE);
-  decl = build_decl (VAR_DECL, NULL_TREE, tmp);
-  DECL_ARTIFICIAL (decl) = 1;
-  DECL_INITIAL (decl) = types;
-  cp_finish_decl (decl, types, NULL_TREE, 0, 0);
+  expand_eh_region_end (second_try);
+  
+  emit_label (check);
+  emit_move_insn (flag, const1_rtx);
+  cont = gen_label_rtx ();
 
-  decl = decay_conversion (decl);
+  push_eh_info ();
 
-  fn = get_identifier ("__check_eh_spec");
-  if (IDENTIFIER_GLOBAL_VALUE (fn))
-    fn = IDENTIFIER_GLOBAL_VALUE (fn);
-  else
+  while (raises)
     {
-      push_obstacks_nochange ();
-      end_temporary_allocation ();
+      tree exp;
+      tree match_type = TREE_VALUE (raises);
+      
+      if (match_type)
+       {
+         /* check TREE_VALUE (raises) here */
+         exp = get_eh_value ();
+         exp = expr_tree_cons (NULL_TREE,
+                          build_eh_type_type (match_type),
+                          expr_tree_cons (NULL_TREE,
+                                     get_eh_type (),
+                                     expr_tree_cons (NULL_TREE, exp, NULL_TREE)));
+         exp = build_function_call (CatchMatch, exp);
+         assemble_external (TREE_OPERAND (CatchMatch, 0));
+
+         jumpif (exp, cont);
+       }
 
-      tmp = tree_cons
-       (NULL_TREE, integer_type_node, tree_cons
-        (NULL_TREE, TREE_TYPE (decl), void_list_node));
-      tmp = build_function_type        (void_type_node, tmp);
-  
-      fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
-      DECL_EXTERNAL (fn) = 1;
-      TREE_PUBLIC (fn) = 1;
-      DECL_ARTIFICIAL (fn) = 1;
-      TREE_THIS_VOLATILE (fn) = 1;
-      pushdecl_top_level (fn);
-      make_function_rtl (fn);
-      assemble_external (fn);
-      pop_obstacks ();
+      raises = TREE_CHAIN (raises);
     }
-
-  tmp = expr_tree_cons (NULL_TREE, build_int_2 (count, 0), expr_tree_cons
-                       (NULL_TREE, decl, NULL_TREE));
-  tmp = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), tmp);
-  expand_expr (tmp, const0_rtx, VOIDmode, EXPAND_NORMAL);
-
-  expand_end_catch_block ();
-  expand_end_all_catch ();
+  emit_move_insn (flag, const0_rtx);
+  emit_label (cont);
+  emit_indirect_jump (ret);
+  emit_label (end);
+  
+  do_pending_stack_adjust ();
+  RTL_EXPR_SEQUENCE (expr) = get_insns ();
+  end_sequence ();
+  
+  expand_eh_region_end (expr);
 }
 
 /* This is called to expand all the toplevel exception handling
index 28071183c0f59180a61deb09e3d2147b4a66b12d..2d1ae08124703757a482771064643e3bad199cee 100644 (file)
@@ -47,8 +47,7 @@ __default_unexpected ()
   terminate ();
 }
 
-static unexpected_handler __unexpected_func __attribute__((__noreturn__))
-  = __default_unexpected;
+static unexpected_handler __unexpected_func = __default_unexpected;
 
 terminate_handler
 set_terminate (terminate_handler func)
@@ -160,54 +159,6 @@ __uncatch_exception (void)
   /* otherwise __throw will call terminate(); don't crash here.  */
 }
 
-/* As per [except.unexpected]:
-   If an exception is thrown, we check it against the spec.  If it doesn't
-   match, we call unexpected ().  If unexpected () throws, we check that
-   exception against the spec.  If it doesn't match, if the spec allows
-   bad_exception we throw that; otherwise we call terminate ().
-
-   The compiler treats an exception spec as a try block with a generic
-   handler that just calls this function with a list of the allowed
-   exception types, so we have an active exception that can be rethrown.
-
-   This function does not return.  */   
-
-extern "C" void
-__check_eh_spec (int n, const void **spec)
-{
-  cp_eh_info *p = __cp_exception_info ();
-
-  for (int i = 0; i < n; ++i)
-    {
-      if (__throw_type_match_rtti (spec[i], p->type, p->value))
-       throw;
-    }
-
-  try
-    {
-      unexpected ();
-    }
-  catch (...)
-    {
-      // __exception_info is an artificial var pushed into each catch block.
-      p = __exception_info;
-      for (int i = 0; i < n; ++i)
-       {
-         if (__throw_type_match_rtti (spec[i], p->type, p->value))
-           throw;
-       }
-
-      const type_info &bad_exc = typeid (bad_exception);
-      for (int i = 0; i < n; ++i)
-       {
-         if (__throw_type_match_rtti (spec[i], &bad_exc, p->value))
-           throw bad_exception ();
-       }
-
-      terminate ();
-    }
-}
-
 extern "C" void
 __throw_bad_cast (void)
 {
index 33cf190108cb9ec3c5bd9f4cb648dff08c0c003d..0db3497f1fa2b6681a8a5b40ba076984cac9144a 100644 (file)
 #include "new"
 
 const nothrow_t nothrow = { };
-
-new_handler __new_handler;
-
-new_handler
-set_new_handler (new_handler handler)
-{
-  new_handler prev_handler = __new_handler;
-  __new_handler = handler;
-  return prev_handler;
-}
index 98c2a4a955e200f07fc6bbd21a5c46c9c7658fc0..0ee111d293953f397a6071f964a209bd9923cfb8 100644 (file)
@@ -1,4 +1,4 @@
-// Support routines for the -*- C++ -*- dynamic memory management.
+// Support routine for the -*- C++ -*- dynamic memory management.
 // Copyright (C) 1997 Free Software Foundation
 
 // This file is part of GNU CC.
 #include "new"
 
 extern "C" void *malloc (size_t);
-extern new_handler __new_handler;
 
-#define WEAK(x) \
-  x __attribute__ ((weak)); \
-  x
+typedef void (*vfp)(void);
+extern vfp __new_handler;
+extern void __default_new_handler (void);
 
-#ifdef L_op_newnt
-WEAK (void * operator new (size_t sz, const nothrow_t&) throw())
+void *operator new (size_t sz, const nothrow_t&) throw()
 {
   void *p;
+  vfp handler = __new_handler;
 
   /* malloc (0) is unpredictable; avoid it.  */
   if (sz == 0)
@@ -45,43 +44,11 @@ WEAK (void * operator new (size_t sz, const nothrow_t&) throw())
   p = (void *) malloc (sz);
   while (p == 0)
     {
-      new_handler handler = __new_handler;
       if (! handler)
        return 0;
-      try
-       {
-         handler ();
-       }
-      catch (bad_alloc &)
-       {
-         return 0;
-       }
-
-      p = (void *) malloc (sz);
-    }
-
-  return p;
-}
-#endif
-
-#ifdef L_op_new
-WEAK (void * operator new (size_t sz) throw (std::bad_alloc))
-{
-  void *p;
-
-  /* malloc (0) is unpredictable; avoid it.  */
-  if (sz == 0)
-    sz = 1;
-  p = (void *) malloc (sz);
-  while (p == 0)
-    {
-      new_handler handler = __new_handler;
-      if (! handler)
-       throw bad_alloc ();
-      handler ();
+      (*handler) ();
       p = (void *) malloc (sz);
     }
-
+  
   return p;
 }
-#endif
index d5320f99502c5b1b4d08bb9a7f5fe9298d55c392..5aca49d21d1160c16808faf531eafff683299bd5 100644 (file)
@@ -1,4 +1,4 @@
-// Boilerplate support routines for -*- C++ -*- dynamic memory management.
+// Support routine for the -*- C++ -*- dynamic memory management.
 // Copyright (C) 1997 Free Software Foundation
 
 // This file is part of GNU CC.
 
 #include "new"
 
-extern "C" void free (void *);
-
-#define WEAK(x) \
-  x __attribute__ ((weak)); \
-  x
-
-#ifdef L_op_vnew
-WEAK(void * operator new[] (size_t sz) throw (std::bad_alloc))
-{
-  return ::operator new(sz);
-}
-#endif
-
-#ifdef L_op_vnewnt
-WEAK(void *operator new[] (size_t sz, const nothrow_t& nothrow) throw())
+void *operator new[] (size_t sz, const nothrow_t& nothrow) throw()
 {
   return ::operator new(sz, nothrow);
 }
-#endif
-
-#ifdef L_op_delete
-WEAK (void operator delete (void *ptr) throw ())
-{
-  if (ptr)
-    free (ptr);
-}
-#endif
-
-#ifdef L_op_vdel
-WEAK (void operator delete[] (void *ptr) throw ())
-{
-  if (ptr)
-    free (ptr);
-}
-#endif
-
-#ifdef L_op_delnt
-WEAK (void operator delete (void *ptr, const std::nothrow_t&) throw ())
-{
-  if (ptr)
-    free (ptr);
-}
-#endif
-
-#ifdef L_op_vdelnt
-WEAK (void operator delete[] (void *ptr, const std::nothrow_t&) throw ())
-{
-  if (ptr)
-    free (ptr);
-}
-#endif
index 531348895271dcf9049ea0db8830eb14fd375001..128661c1cd2e69f46ae51f296441549faad2e494 100644 (file)
@@ -119,8 +119,7 @@ struct __array_type_info : public type_info {
    variables and thrown objects.  */
 
 extern "C" void*
-__throw_type_match_rtti (const void *catch_type_r, const void *throw_type_r,
-                        void *objptr)
+__throw_type_match_rtti (void *catch_type_r, void *throw_type_r, void *objptr)
 {
   const type_info &catch_type = *(const type_info *)catch_type_r;
   const type_info &throw_type = *(const type_info *)throw_type_r;
index 7fec5cdd45edd924d3d718f056d1f8cd9b2891b9..6c34da7acf5284c6ef086edf83b204e93dec2514 100644 (file)
@@ -42,6 +42,10 @@ Boston, MA 02111-1307, USA.  */
 #undef abort
 #endif
 
+#if (SUPPORTS_WEAK == 1) && (defined (ASM_OUTPUT_DEF) || defined (ASM_OUTPUT_WEAK_ALIAS))
+#define WEAK_ALIAS
+#endif
+
 /* Permit the tm.h file to select the endianness to use just for this
    file.  This is used when the endianness is determined when the
    compiler is run.  */
@@ -2432,6 +2436,157 @@ stack_overflow:;
 #endif /* not BLOCK_PROFILER_CODE */
 #endif /* L_bb */
 \f
+/* Default free-store management functions for C++, per sections 12.5 and
+   17.3.3 of the Working Paper.  */
+
+#ifdef L_op_new
+/* operator new (size_t), described in 17.3.3.5.  This function is used by
+   C++ programs to allocate a block of memory to hold a single object.  */
+
+typedef void (*vfp)(void);
+extern vfp __new_handler;
+extern void __default_new_handler (void);
+
+#ifdef WEAK_ALIAS
+void * __builtin_new (size_t sz)
+     __attribute__ ((weak, alias ("___builtin_new")));
+void *
+___builtin_new (size_t sz)
+#else
+void *
+__builtin_new (size_t sz)
+#endif
+{
+  void *p;
+  vfp handler = (__new_handler) ? __new_handler : __default_new_handler;
+
+  /* malloc (0) is unpredictable; avoid it.  */
+  if (sz == 0)
+    sz = 1;
+  p = (void *) malloc (sz);
+  while (p == 0)
+    {
+      (*handler) ();
+      p = (void *) malloc (sz);
+    }
+  
+  return p;
+}
+#endif /* L_op_new */
+
+#ifdef L_op_vnew
+/* void * operator new [] (size_t), described in 17.3.3.6.  This function
+   is used by C++ programs to allocate a block of memory for an array.  */
+
+extern void * __builtin_new (size_t);
+
+#ifdef WEAK_ALIAS
+void * __builtin_vec_new (size_t sz)
+     __attribute__ ((weak, alias ("___builtin_vec_new")));
+void *
+___builtin_vec_new (size_t sz)
+#else
+void *
+__builtin_vec_new (size_t sz)
+#endif
+{
+  return __builtin_new (sz);
+}
+#endif /* L_op_vnew */
+
+#ifdef L_new_handler
+/* set_new_handler (fvoid_t *) and the default new handler, described in
+   17.3.3.2 and 17.3.3.5.  These functions define the result of a failure
+   to allocate the amount of memory requested from operator new or new [].  */
+
+#ifndef inhibit_libc
+/* This gets us __GNU_LIBRARY__.  */
+#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
+#include <stdio.h>
+
+#ifdef __GNU_LIBRARY__
+  /* Avoid forcing the library's meaning of `write' on the user program
+     by using the "internal" name (for use within the library)  */
+#define write(fd, buf, n)      __write((fd), (buf), (n))
+#endif
+#endif /* inhibit_libc */
+
+typedef void (*vfp)(void);
+void __default_new_handler (void);
+
+vfp __new_handler = (vfp) 0;
+
+vfp
+set_new_handler (vfp handler)
+{
+  vfp prev_handler;
+
+  prev_handler = __new_handler;
+  if (handler == 0) handler = __default_new_handler;
+  __new_handler = handler;
+  return prev_handler;
+}
+
+#define MESSAGE "Virtual memory exceeded in `new'\n"
+
+void
+__default_new_handler ()
+{
+#ifndef inhibit_libc
+  /* don't use fprintf (stderr, ...) because it may need to call malloc.  */
+  /* This should really print the name of the program, but that is hard to
+     do.  We need a standard, clean way to get at the name.  */
+  write (2, MESSAGE, sizeof (MESSAGE));
+#endif
+  /* don't call exit () because that may call global destructors which
+     may cause a loop.  */
+  _exit (-1);
+}
+#endif
+
+#ifdef L_op_delete
+/* operator delete (void *), described in 17.3.3.3.  This function is used
+   by C++ programs to return to the free store a block of memory allocated
+   as a single object.  */
+
+#ifdef WEAK_ALIAS
+void __builtin_delete (void *ptr)
+     __attribute__ ((weak, alias ("___builtin_delete")));
+void
+___builtin_delete (void *ptr)
+#else
+void
+__builtin_delete (void *ptr)
+#endif
+{
+  if (ptr)
+    free (ptr);
+}
+#endif
+
+#ifdef L_op_vdel
+/* operator delete [] (void *), described in 17.3.3.4.  This function is
+   used by C++ programs to return to the free store a block of memory
+   allocated as an array.  */
+
+extern void __builtin_delete (void *);
+
+#ifdef WEAK_ALIAS
+void __builtin_vec_delete (void *ptr)
+     __attribute__ ((weak, alias ("___builtin_vec_delete")));
+void
+___builtin_vec_delete (void *ptr)
+#else
+void
+__builtin_vec_delete (void *ptr)
+#endif
+{
+  __builtin_delete (ptr);
+}
+#endif
+
+/* End of C++ free-store management functions */
+\f
 #ifdef L_shtab
 unsigned int __shtab[] = {
     0x00000001, 0x00000002, 0x00000004, 0x00000008,