41st Cygnus<->FSF merge
[platform/upstream/gcc.git] / gcc / cp / init.c
index 8a81db9..5e5d580 100644 (file)
@@ -217,12 +217,8 @@ perform_member_init (member, name, init, explicit)
          expand_expr_stmt (build_modify_expr (decl, INIT_EXPR, init));
        }
     }
-
-  if (flag_handle_exceptions == 2 && TYPE_NEEDS_DESTRUCTOR (type))
-    {
-      cplus_expand_start_try (1);
-      push_exception_cleanup (build_unary_op (ADDR_EXPR, decl, 0));
-    }
+  if (flag_handle_exceptions && TYPE_NEEDS_DESTRUCTOR (type))
+    cp_warning ("caution, member `%D' may not be destroyed in the presense of an exception during construction", member);
 }
 
 /* Subroutine of emit_member_init.  */
@@ -390,20 +386,6 @@ emit_base_init (t, immediately)
     emit_line_note_force (DECL_SOURCE_FILE (current_function_decl),
                          DECL_SOURCE_LINE (current_function_decl));
 
-  /* In this case, we always need IN_CHARGE_NODE, because we have
-     to know whether to deallocate or not before exiting.  */
-  if (flag_handle_exceptions == 2
-      && lookup_name (in_charge_identifier, 0) == NULL_TREE)
-    {
-      tree in_charge_node = pushdecl (build_decl (VAR_DECL, in_charge_identifier,
-                                                 integer_type_node));
-      store_init_value (in_charge_node, build (EQ_EXPR, integer_type_node,
-                                              current_class_decl,
-                                              integer_zero_node));
-      expand_decl (in_charge_node);
-      expand_decl_init (in_charge_node);
-    }
-
   start = ! TYPE_USES_VIRTUAL_BASECLASSES (t);
   for (pass = start; pass < 2; pass++)
     {
@@ -521,11 +503,6 @@ emit_base_init (t, immediately)
          expand_aggr_init_1 (t_binfo, 0,
                              build_indirect_ref (member, NULL_PTR), init,
                              BINFO_OFFSET_ZEROP (binfo), LOOKUP_COMPLAIN);
-         if (flag_handle_exceptions == 2 && TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (binfo)))
-           {
-             cplus_expand_start_try (1);
-             push_exception_cleanup (member);
-           }
        }
 
       if (pass == 0)
@@ -594,12 +571,6 @@ emit_base_init (t, immediately)
              expand_aggr_init_1 (t_binfo, 0, ref, NULL_TREE,
                                  BINFO_OFFSET_ZEROP (base_binfo),
                                  LOOKUP_COMPLAIN);
-             if (flag_handle_exceptions == 2
-                 && TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo)))
-               {
-                 cplus_expand_start_try (1);
-                 push_exception_cleanup (base);
-               }
            }
        }
       CLEAR_BINFO_BASEINIT_MARKED (base_binfo);
@@ -672,7 +643,7 @@ emit_base_init (t, immediately)
          /* member could be, for example, a CONST_DECL for an enumerated
             tag; we don't want to try to initialize that, since it already
             has a value.  */
-         if (TREE_CODE (member) != FIELD_DECL)
+         if (TREE_CODE (member) != FIELD_DECL || !DECL_NAME (member))
            continue;
 
          name = DECL_NAME (member);
@@ -1146,13 +1117,7 @@ expand_aggr_init (exp, init, alias_this)
       int was_const_elts = TYPE_READONLY (TREE_TYPE (type));
       tree itype = init ? TREE_TYPE (init) : NULL_TREE;
       if (was_const_elts)
-       {
-         tree atype = build_cplus_array_type (TYPE_MAIN_VARIANT (TREE_TYPE (type)),
-                                              TYPE_DOMAIN (type));
-         if (init && (TREE_TYPE (exp) == TREE_TYPE (init)))
-           TREE_TYPE (init) = atype;
-         TREE_TYPE (exp) = atype;
-       }
+       TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);
       if (init && TREE_TYPE (init) == NULL_TREE)
        {
          /* Handle bad initializers like:
@@ -1895,7 +1860,7 @@ build_member_call (cname, name, parmlist)
        {
          tree newtype = build_type_variant (type, TYPE_READONLY (oldtype),
                                             TYPE_VOLATILE (oldtype));
-         decl = convert_force (TYPE_POINTER_TO (newtype), olddecl);
+         decl = convert_force (build_pointer_type (newtype), olddecl);
        }
       else
        decl = olddecl;
@@ -2116,8 +2081,7 @@ build_offset_ref (cname, name)
 
   if (t == NULL_TREE)
     {
-      cp_error ("`%D' is not a member of type `%T'", name,
-               IDENTIFIER_TYPE_VALUE (cname));
+      cp_error ("`%D' is not a member of type `%T'", name, type);
       return error_mark_node;
     }
 
@@ -2643,40 +2607,9 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
      enum overload_flags flags;
      tree quals;
 {
-  /* first, lets find out if what we are making a friend needs overloading */
-  tree previous_decl;
-  int was_c_linkage = 0;
-
   /* Every decl that gets here is a friend of something.  */
   DECL_FRIEND_P (decl) = 1;
 
-  /* If we find something in scope, let see if it has extern "C" linkage.  */
-  /* This code is pretty general and should be ripped out and reused
-     as a separate function. */
-  if (DECL_NAME (decl))
-    {
-      previous_decl = lookup_name (DECL_NAME (decl), 0);
-      if (previous_decl && TREE_CODE (previous_decl) == TREE_LIST)
-       {
-         do
-           {
-             if (TREE_TYPE (TREE_VALUE (previous_decl)) == TREE_TYPE (decl))
-               {
-                 previous_decl = TREE_VALUE (previous_decl);
-                 break;
-               }
-             previous_decl = TREE_CHAIN (previous_decl);
-           }
-         while (previous_decl);
-       }
-
-      /* It had extern "C" linkage, so don't overload this.  */
-      if (previous_decl && TREE_CODE (previous_decl) == FUNCTION_DECL
-         && TREE_TYPE (decl) == TREE_TYPE (previous_decl)
-         && DECL_LANGUAGE (previous_decl) == lang_c)
-       was_c_linkage = 1;
-    }
-         
   if (ctype)
     {
       tree cname = TYPE_NAME (ctype);
@@ -2741,7 +2674,6 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
          decl = void_type_node;
        }
     }
-  /* never overload C functions */
   else if (TREE_CODE (decl) == FUNCTION_DECL
           && ((IDENTIFIER_LENGTH (declarator) == 4
                && IDENTIFIER_POINTER (declarator)[0] == 'm'
@@ -2750,8 +2682,7 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
                   && IDENTIFIER_POINTER (declarator)[0] == '_'
                   && IDENTIFIER_POINTER (declarator)[1] == '_'
                   && strncmp (IDENTIFIER_POINTER (declarator)+2,
-                              "builtin_", 8) == 0)
-              || was_c_linkage))
+                              "builtin_", 8) == 0)))
     {
       /* raw "main", and builtin functions never gets overloaded,
         but they can become friends.  */
@@ -2777,7 +2708,7 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
 
       /* We can call pushdecl here, because the TREE_CHAIN of this
         FUNCTION_DECL is not needed for other purposes.  */
-      decl = pushdecl_top_level (decl);
+      decl = pushdecl (decl);
 
       make_decl_rtl (decl, NULL_PTR, 1);
       add_friend (current_class_type, decl);
@@ -3596,7 +3527,7 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
 
   if (TREE_CODE (type) == POINTER_TYPE)
     {
-      type = TREE_TYPE (type);
+      type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
       if (TYPE_SIZE (type) == 0)
        {
          incomplete_type_error (0, type);
@@ -3612,6 +3543,9 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
        }
       if (TREE_SIDE_EFFECTS (addr))
        addr = save_expr (addr);
+
+      /* throw away const and volatile on target type of addr */
+      addr = convert_force (build_pointer_type (type), addr);
       ref = build_indirect_ref (addr, NULL_PTR);
       ptr = 1;
     }