init.c (build_new): Handle freeing allocated memory when the constructor throws.
authorJason Merrill <jason@yorick.cygnus.com>
Wed, 12 Nov 1997 09:18:40 +0000 (09:18 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 12 Nov 1997 09:18:40 +0000 (04:18 -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: r16436

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

index 0eb150a1f332a0ef7163c582768197b901c0be0c..fdfb3061574ec896e9d81bdbc30e0ff2c3f8283b 100644 (file)
@@ -4,6 +4,20 @@ Sun Nov  9 01:29:55 1997  Jim Wilson  (wilson@cygnus.com)
        * init.c (build_vec_delete_1): Delete build_block and
        add_block_current_level calls.
 
+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 da1d50ca692b7550e7b029f52b9511cde9616838..0efcf4aa971d8b05056b41cf779ac5c6dd55b2ae 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))
@@ -5580,8 +5580,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 5d94797e299472eb465f1ba158ff65348c881a5f..dfe31c29923f60bc9799db242e9be8a413e478e6 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 8e05af3b613fd349bf858ebba38bd2f2c785e6c3..b02ff634bb38040d6a7f65bd4c76ebcce6d5af9f 100644 (file)
@@ -3988,6 +3988,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);
@@ -4397,7 +4399,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);