]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
init.c (build_new): Handle freeing allocated memory when the constructor throws.
authorJason Merrill <jason@yorick.cygnus.com>
Wed, 12 Nov 1997 09:19:26 +0000 (09:19 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 12 Nov 1997 09:19:26 +0000 (04:19 -0500)
* init.c (build_new): Handle freeing allocated memory when the
constructor throws.

* call.c (build_new_method_call): Fix flags arg.

* pt.c (do_type_instantiation): Don't try to instantiate
member templates.
(mark_decl_instantiated): If we support one_only but not
weak symbols, mark this one_only.
* decl2.c (import_export_vtable): Don't defer handling of vtables
if MULTIPLE_SYMBOL_SPACES.

From-SVN: r16437

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/decl2.c
gcc/cp/init.c
gcc/cp/pt.c

index 6a56778d92c81039a26ef75bdb79ff803a36b1a9..6971e935aaa7e610978c59ad854698dd33459174 100644 (file)
@@ -1,3 +1,17 @@
+Wed Nov 12 00:48:16 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * init.c (build_new): Handle freeing allocated memory when the
+       constructor throws.
+
+       * call.c (build_new_method_call): Fix flags arg.
+
+       * pt.c (do_type_instantiation): Don't try to instantiate
+       member templates.
+       (mark_decl_instantiated): If we support one_only but not
+       weak symbols, mark this one_only.
+       * decl2.c (import_export_vtable): Don't defer handling of vtables
+       if MULTIPLE_SYMBOL_SPACES.
+
 Tue Nov 11 12:02:12 1997  Jason Merrill  <jason@yorick.cygnus.com>
 
        * except.c (expand_end_catch_block): Lose call to __sjpopnthrow.
index eaa39c69e720fc3a74d3cc370eebad5e29a47410..d4cf780f277bf86b9aa7d913cf50e90bddfbecf0 100644 (file)
@@ -4810,9 +4810,6 @@ build_new_op (code, flags, arg1, arg2, arg3)
   if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
     arg2 = integer_zero_node;
 
-  fns = lookup_name_nonclass (fnname);
-  /* + Koenig lookup */
-
   if (arg2 && arg3)
     arglist = scratch_tree_cons (NULL_TREE, arg1, scratch_tree_cons
                      (NULL_TREE, arg2, build_scratch_list (NULL_TREE, arg3)));
@@ -4821,6 +4818,9 @@ build_new_op (code, flags, arg1, arg2, arg3)
   else
     arglist = build_scratch_list (NULL_TREE, arg1);
 
+  fns = lookup_name_nonclass (fnname);
+  /* + Koenig lookup */
+
   if (fns && TREE_CODE (fns) == TREE_LIST)
     fns = TREE_VALUE (fns);
   for (; fns; fns = DECL_CHAIN (fns))
@@ -5575,8 +5575,7 @@ build_new_method_call (instance, name, args, basetype_path, flags)
              candidates = 
                add_template_candidate (candidates, t, explicit_targs,
                                        this_arglist,
-                                       TREE_TYPE (name), 
-                                       LOOKUP_NORMAL); 
+                                       TREE_TYPE (name), flags); 
            }
          else if (! template_only)
            candidates = add_function_candidate (candidates, t,
index c9c7f7c0fb2b5e8521c5cb879c7b9af6975381fe..583b7d403ad5418f9bce97596efab5d6948a60d1 100644 (file)
@@ -2528,6 +2528,7 @@ import_export_vtable (decl, type, final)
 
       int found = CLASSTYPE_TEMPLATE_INSTANTIATION (type);
 
+#ifndef MULTIPLE_SYMBOL_SPACES
       if (! found && ! final)
        {
          tree method;
@@ -2541,6 +2542,7 @@ import_export_vtable (decl, type, final)
                break;
              }
        }
+#endif
 
       if (final || ! found)
        {
index 09a3de18c14e4fae4bc984f784c5a5aec4b6d1df..5c02d053bdd46ccfdd05283406d531ce6f54b53e 100644 (file)
@@ -2522,7 +2522,7 @@ build_new (placement, decl, init, use_global_new)
       TREE_CALLS_NEW (rval) = 1;
     }
 
-  if (check_new && rval)
+  if ((flag_exceptions || check_new) && rval)
     alloc_expr = rval = save_expr (rval);
   else
     alloc_expr = NULL_TREE;
@@ -2705,13 +2705,34 @@ build_new (placement, decl, init, use_global_new)
          rval = xval;
        }
 #endif
+
+      /* If any part of the object initialization terminates by throwing
+        an exception and the new-expression does not contain a
+        new-placement, then the deallocation function is called to free
+        the memory in which the object was being constructed.  */
+      /* FIXME: handle placement delete.  */
+      if (flag_exceptions && ! placement)
+       {
+         tree cleanup;
+
+         if (! use_global_new && TYPE_LANG_SPECIFIC (true_type)
+             && (TYPE_GETS_DELETE (true_type) & (1 << has_array)))
+           cleanup = build_opfncall (DELETE_EXPR, LOOKUP_NORMAL,
+                                     alloc_expr, size, NULL_TREE);
+         else
+           cleanup = build_builtin_call
+             (void_type_node, BID, build_expr_list (NULL_TREE, alloc_expr));
+                                        
+         rval = build (TRY_CATCH_EXPR, TREE_TYPE (rval), rval, cleanup);
+         rval = build (COMPOUND_EXPR, TREE_TYPE (rval), alloc_expr, rval);
+       }
     }
   else if (TYPE_READONLY (true_type))
     cp_error ("uninitialized const in `new' of `%#T'", true_type);
 
  done:
 
-  if (alloc_expr && rval != alloc_expr)
+  if (check_new && alloc_expr && rval != alloc_expr)
     {
       /* Did we modify the storage?  */
       tree ifexp = build_binary_op (NE_EXPR, alloc_expr,
index 1d16bb2de0ef801bc6d9f7223fd811a370e653b8..96b21aae03b4ef20c219ce03f89d5f831f363176 100644 (file)
@@ -3962,6 +3962,8 @@ mark_decl_instantiated (result, extern_p)
     {
       DECL_INTERFACE_KNOWN (result) = 1;
       DECL_NOT_REALLY_EXTERN (result) = 1;
+      if (supports_one_only () && ! SUPPORTS_WEAK)
+       comdat_linkage (result);
     }
   else if (TREE_CODE (result) == FUNCTION_DECL)
     mark_inline_for_output (result);
@@ -4371,7 +4373,8 @@ do_type_instantiation (t, storage)
 
     if (! static_p)
       for (tmp = TYPE_METHODS (t); tmp; tmp = TREE_CHAIN (tmp))
-       if (DECL_TEMPLATE_INSTANTIATION (tmp))
+       if (TREE_CODE (t) == FUNCTION_DECL
+           && DECL_TEMPLATE_INSTANTIATION (tmp))
          {
            mark_decl_instantiated (tmp, extern_p);
            repo_template_instantiated (tmp, extern_p);