OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / cp / init.c
index 3deb85d..61c78e1 100644 (file)
@@ -347,7 +347,7 @@ build_value_init_1 (tree type, bool have_ctor)
   if (CLASS_TYPE_P (type))
     {
       if (type_has_user_provided_constructor (type) && !have_ctor)
-       return build_cplus_new
+       return build_aggr_init_expr
          (type,
           build_special_member_call (NULL_TREE, complete_ctor_identifier,
                                      NULL_TREE, type, LOOKUP_NORMAL,
@@ -511,7 +511,7 @@ perform_member_init (tree member, tree init)
        {
          /* Initialization of one array from another.  */
          finish_expr_stmt (build_vec_init (decl, NULL_TREE, TREE_VALUE (init),
-                                           /*explicit_default_init_p=*/false,
+                                           /*explicit_value_init_p=*/false,
                                            /* from_array=*/1,
                                             tf_warning_or_error));
        }
@@ -522,7 +522,7 @@ perform_member_init (tree member, tree init)
              && !type_has_user_provided_default_constructor (type))
            /* TYPE_NEEDS_CONSTRUCTING can be set just because we have a
               vtable; still give this diagnostic.  */
-           permerror ("%Juninitialized member %qD with %<const%> type %qT",
+           permerror (input_location, "%Juninitialized member %qD with %<const%> type %qT",
                       current_function_decl, member, type);
          finish_expr_stmt (build_aggr_init (decl, init, 0, 
                                             tf_warning_or_error));
@@ -542,10 +542,10 @@ perform_member_init (tree member, tree init)
            }
          /* member traversal: note it leaves init NULL */
          else if (TREE_CODE (type) == REFERENCE_TYPE)
-           permerror ("%Juninitialized reference member %qD",
+           permerror (input_location, "%Juninitialized reference member %qD",
                       current_function_decl, member);
          else if (CP_TYPE_CONST_P (type))
-           permerror ("%Juninitialized member %qD with %<const%> type %qT",
+           permerror (input_location, "%Juninitialized member %qD with %<const%> type %qT",
                       current_function_decl, member, type);
        }
       else if (TREE_CODE (init) == TREE_LIST)
@@ -1001,7 +1001,7 @@ expand_cleanup_for_base (tree binfo, tree flag)
                                     tf_warning_or_error);
   if (flag)
     expr = fold_build3 (COND_EXPR, void_type_node,
-                       c_common_truthvalue_conversion (flag),
+                       c_common_truthvalue_conversion (input_location, flag),
                        expr, integer_zero_node);
 
   finish_eh_cleanup (expr);
@@ -1286,7 +1286,7 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain)
       if (itype && cp_type_quals (itype) != TYPE_UNQUALIFIED)
        itype = TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype);
       stmt_expr = build_vec_init (exp, NULL_TREE, init,
-                                 /*explicit_default_init_p=*/false,
+                                 /*explicit_value_init_p=*/false,
                                  itype && same_type_p (itype,
                                                        TREE_TYPE (exp)),
                                   complain);
@@ -1659,6 +1659,15 @@ constant_value_1 (tree decl, bool integral_p)
        }
       if (init == error_mark_node)
        return decl;
+      /* Initializers in templates are generally expanded during
+        instantiation, so before that for const int i(2)
+        INIT is a TREE_LIST with the actual initializer as
+        TREE_VALUE.  */
+      if (processing_template_decl
+         && init
+         && TREE_CODE (init) == TREE_LIST
+         && TREE_CHAIN (init) == NULL_TREE)
+       init = TREE_VALUE (init);
       if (!init
          || !TREE_TYPE (init)
          || (integral_p
@@ -1877,7 +1886,8 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
   for (elt_type = type;
        TREE_CODE (elt_type) == ARRAY_TYPE;
        elt_type = TREE_TYPE (elt_type))
-    nelts = cp_build_binary_op (MULT_EXPR, nelts,
+    nelts = cp_build_binary_op (input_location,
+                               MULT_EXPR, nelts,
                                array_type_nelts_top (elt_type),
                                complain);
 
@@ -2055,11 +2065,9 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
       return rval;
     }
 
-  /* While we're working, use a pointer to the type we've actually
-     allocated. Store the result of the call in a variable so that we
-     can use it more than once.  */
-  full_pointer_type = build_pointer_type (full_type);
-  alloc_expr = get_target_expr (build_nop (full_pointer_type, alloc_call));
+  /* Store the result of the allocation call in a variable so that we can
+     use it more than once.  */
+  alloc_expr = get_target_expr (alloc_call);
   alloc_node = TARGET_EXPR_SLOT (alloc_expr);
 
   /* Strip any COMPOUND_EXPRs from ALLOC_CALL.  */
@@ -2111,16 +2119,17 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
       tree size_ptr_type;
 
       /* Adjust so we're pointing to the start of the object.  */
-      data_addr = get_target_expr (build2 (POINTER_PLUS_EXPR, full_pointer_type,
-                                          alloc_node, cookie_size));
+      data_addr = build2 (POINTER_PLUS_EXPR, TREE_TYPE (alloc_node),
+                         alloc_node, cookie_size);
 
       /* Store the number of bytes allocated so that we can know how
         many elements to destroy later.  We use the last sizeof
         (size_t) bytes to store the number of elements.  */
-      cookie_ptr = fold_build1 (NEGATE_EXPR, sizetype, size_in_bytes (sizetype));
+      cookie_ptr = size_binop (MINUS_EXPR, cookie_size, size_in_bytes (sizetype));
+      cookie_ptr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (alloc_node),
+                               alloc_node, cookie_ptr);
       size_ptr_type = build_pointer_type (sizetype);
-      cookie_ptr = build2 (POINTER_PLUS_EXPR, size_ptr_type,
-                          fold_convert (size_ptr_type, data_addr), cookie_ptr);
+      cookie_ptr = fold_convert (size_ptr_type, cookie_ptr);
       cookie = cp_build_indirect_ref (cookie_ptr, NULL, complain);
 
       cookie_expr = build2 (MODIFY_EXPR, sizetype, cookie, nelts);
@@ -2134,11 +2143,10 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
 
          cookie = cp_build_indirect_ref (cookie_ptr, NULL, complain);
          cookie = build2 (MODIFY_EXPR, sizetype, cookie,
-                          size_in_bytes(elt_type));
+                          size_in_bytes (elt_type));
          cookie_expr = build2 (COMPOUND_EXPR, TREE_TYPE (cookie_expr),
                                cookie, cookie_expr);
        }
-      data_addr = TARGET_EXPR_SLOT (data_addr);
     }
   else
     {
@@ -2146,6 +2154,10 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
       data_addr = alloc_node;
     }
 
+  /* Now use a pointer to the type we've actually allocated.  */
+  full_pointer_type = build_pointer_type (full_type);
+  data_addr = fold_convert (full_pointer_type, data_addr);
+
   /* Now initialize the allocated object.  Note that we preevaluate the
      initialization expression, apart from the actual constructor call or
      assignment--we do this because we want to delay the allocation as long
@@ -2154,32 +2166,33 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
   if (is_initialized)
     {
       bool stable;
+      bool explicit_value_init_p = false;
 
       init_expr = cp_build_indirect_ref (data_addr, NULL, complain);
 
-      if (array_p)
+      if (init == void_zero_node)
        {
-         bool explicit_default_init_p = false;
+         init = NULL_TREE;
+         explicit_value_init_p = true;
+       }
 
-         if (init == void_zero_node)
-           {
-             init = NULL_TREE;
-             explicit_default_init_p = true;
-           }
-         else if (init)
+      if (array_p)
+       {
+         if (init)
             {
               if (complain & tf_error)
-                permerror ("ISO C++ forbids initialization in array new");
+                permerror (input_location, "ISO C++ forbids initialization in array new");
               else
                 return error_mark_node;
             }
          init_expr
            = build_vec_init (init_expr,
-                             cp_build_binary_op (MINUS_EXPR, outer_nelts,
+                             cp_build_binary_op (input_location,
+                                                 MINUS_EXPR, outer_nelts,
                                                  integer_one_node,
                                                  complain),
                              init,
-                             explicit_default_init_p,
+                             explicit_value_init_p,
                              /*from_array=*/0,
                               complain);
 
@@ -2190,17 +2203,19 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
        }
       else
        {
-         if (init == void_zero_node)
-           init = build_default_init (full_type, nelts);
-
-         if (TYPE_NEEDS_CONSTRUCTING (type))
+         if (TYPE_NEEDS_CONSTRUCTING (type) && !explicit_value_init_p)
            {
              init_expr = build_special_member_call (init_expr,
                                                     complete_ctor_identifier,
                                                     init, elt_type,
                                                     LOOKUP_NORMAL,
                                                      complain);
-             stable = stabilize_init (init_expr, &init_preeval_expr);
+           }
+         else if (explicit_value_init_p)
+           {
+             /* Something like `new int()'.  */
+             init_expr = build2 (INIT_EXPR, full_type,
+                                 init_expr, build_value_init (full_type));
            }
          else
            {
@@ -2216,8 +2231,8 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
 
              init_expr = cp_build_modify_expr (init_expr, INIT_EXPR, init,
                                                complain);
-             stable = stabilize_init (init_expr, &init_preeval_expr);
            }
+         stable = stabilize_init (init_expr, &init_preeval_expr);
        }
 
       if (init_expr == error_mark_node)
@@ -2239,11 +2254,13 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
          /* The Standard is unclear here, but the right thing to do
             is to use the same method for finding deallocation
             functions that we use for finding allocation functions.  */
-         cleanup = build_op_delete_call (dcode, alloc_node, size,
-                                         globally_qualified_p,
-                                         (placement_allocation_fn_p
-                                          ? alloc_call : NULL_TREE),
-                                         alloc_fn);
+         cleanup = (build_op_delete_call
+                    (dcode,
+                     fold_convert (full_pointer_type, alloc_node),
+                     size,
+                     globally_qualified_p,
+                     placement_allocation_fn_p ? alloc_call : NULL_TREE,
+                     alloc_fn));
 
          if (!cleanup)
            /* We're done.  */;
@@ -2298,7 +2315,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
   if (cookie_expr)
     rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), cookie_expr, rval);
 
-  if (rval == alloc_node)
+  if (rval == data_addr)
     /* If we don't have an initializer or a cookie, strip the TARGET_EXPR
        and return the call (which doesn't need to be adjusted).  */
     rval = TARGET_EXPR_INITIAL (alloc_expr);
@@ -2306,7 +2323,8 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
     {
       if (check_new)
        {
-         tree ifexp = cp_build_binary_op (NE_EXPR, alloc_node,
+         tree ifexp = cp_build_binary_op (input_location,
+                                          NE_EXPR, alloc_node,
                                           integer_zero_node,
                                           complain);
          rval = build_conditional_expr (ifexp, rval, alloc_node, 
@@ -2360,6 +2378,14 @@ build_new (tree placement, tree type, tree nelts, tree init,
   orig_nelts = nelts;
   orig_init = init;
 
+  if (nelts == NULL_TREE && init != void_zero_node && list_length (init) == 1
+      && !any_type_dependent_arguments_p (init))
+    {
+      tree auto_node = type_uses_auto (type);
+      if (auto_node)
+       type = do_auto_deduction (type, TREE_VALUE (init), auto_node);
+    }
+
   if (processing_template_decl)
     {
       if (dependent_type_p (type)
@@ -2381,7 +2407,7 @@ build_new (tree placement, tree type, tree nelts, tree init,
       if (!build_expr_type_conversion (WANT_INT | WANT_ENUM, nelts, false))
         {
           if (complain & tf_error)
-            permerror ("size in array new must have integral type");
+            permerror (input_location, "size in array new must have integral type");
           else
             return error_mark_node;
         }
@@ -2565,7 +2591,8 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
          cookie_size = targetm.cxx.get_cookie_size (type);
          base_tbd
            = cp_convert (ptype,
-                         cp_build_binary_op (MINUS_EXPR,
+                         cp_build_binary_op (input_location,
+                                             MINUS_EXPR,
                                              cp_convert (string_type_node,
                                                          base),
                                              cookie_size,
@@ -2662,8 +2689,8 @@ get_temp_regvar (tree type, tree init)
 
    INIT is the (possibly NULL) initializer.
 
-   If EXPLICIT_DEFAULT_INIT_P is true, then INIT must be NULL.  All
-   elements in the array are default-initialized.
+   If EXPLICIT_VALUE_INIT_P is true, then INIT must be NULL.  All
+   elements in the array are value-initialized.
 
    FROM_ARRAY is 0 if we should init everything with INIT
    (i.e., every element initialized from INIT).
@@ -2674,7 +2701,7 @@ get_temp_regvar (tree type, tree init)
 
 tree
 build_vec_init (tree base, tree maxindex, tree init,
-               bool explicit_default_init_p,
+               bool explicit_value_init_p,
                int from_array, tsubst_flags_t complain)
 {
   tree rval;
@@ -2704,7 +2731,7 @@ build_vec_init (tree base, tree maxindex, tree init,
   if (maxindex == NULL_TREE || maxindex == error_mark_node)
     return error_mark_node;
 
-  if (explicit_default_init_p)
+  if (explicit_value_init_p)
     gcc_assert (!init);
 
   inner_elt_type = strip_array_types (atype);
@@ -2840,7 +2867,7 @@ build_vec_init (tree base, tree maxindex, tree init,
      We do need to keep going if we're copying an array.  */
 
   if (from_array
-      || ((TYPE_NEEDS_CONSTRUCTING (type) || explicit_default_init_p)
+      || ((TYPE_NEEDS_CONSTRUCTING (type) || explicit_value_init_p)
          && ! (host_integerp (maxindex, 0)
                && (num_initialized_elts
                    == tree_low_cst (maxindex, 0) + 1))))
@@ -2889,17 +2916,17 @@ build_vec_init (tree base, tree maxindex, tree init,
              ("cannot initialize multi-dimensional array with initializer");
          elt_init = build_vec_init (build1 (INDIRECT_REF, type, base),
                                     0, 0,
-                                    /*explicit_default_init_p=*/false,
+                                    explicit_value_init_p,
                                     0, complain);
        }
-      else if (!TYPE_NEEDS_CONSTRUCTING (type))
-       elt_init = (cp_build_modify_expr
-                   (to, INIT_EXPR,
-                    build_zero_init (type, size_one_node,
-                                     /*static_storage_p=*/false),
-                    complain));
+      else if (explicit_value_init_p)
+       elt_init = build2 (INIT_EXPR, type, to,
+                          build_value_init (type));
       else
-       elt_init = build_aggr_init (to, init, 0, complain);
+       {
+         gcc_assert (TYPE_NEEDS_CONSTRUCTING (type));
+         elt_init = build_aggr_init (to, init, 0, complain);
+       }
 
       current_stmt_tree ()->stmts_are_full_exprs_p = 1;
       finish_expr_stmt (elt_init);
@@ -2919,13 +2946,15 @@ build_vec_init (tree base, tree maxindex, tree init,
       && from_array != 2)
     {
       tree e;
-      tree m = cp_build_binary_op (MINUS_EXPR, maxindex, iterator,
+      tree m = cp_build_binary_op (input_location,
+                                  MINUS_EXPR, maxindex, iterator,
                                   complain);
 
       /* Flatten multi-dimensional array since build_vec_delete only
         expects one-dimensional array.  */
       if (TREE_CODE (type) == ARRAY_TYPE)
-       m = cp_build_binary_op (MULT_EXPR, m,
+       m = cp_build_binary_op (input_location,
+                               MULT_EXPR, m,
                                array_type_nelts_total (type),
                                complain);
 
@@ -3029,12 +3058,14 @@ build_delete (tree type, tree addr, special_function_kind auto_delete,
          complete_type (type);
          if (!COMPLETE_TYPE_P (type))
            {
-             warning (0, "possible problem detected in invocation of "
-                      "delete operator:");
-             cxx_incomplete_type_diagnostic (addr, type, 1);
-             inform ("neither the destructor nor the class-specific "
-                     "operator delete will be called, even if they are "
-                     "declared when the class is defined.");
+             if (warning (0, "possible problem detected in invocation of "
+                          "delete operator:"))
+               {
+                 cxx_incomplete_type_diagnostic (addr, type, DK_WARNING);
+                 inform (input_location, "neither the destructor nor the class-specific "
+                         "operator delete will be called, even if they are "
+                         "declared when the class is defined.");
+               }
              complete_p = false;
            }
        }
@@ -3151,7 +3182,8 @@ build_delete (tree type, tree addr, special_function_kind auto_delete,
        ifexp = integer_one_node;
       else
        /* Handle deleting a null pointer.  */
-       ifexp = fold (cp_build_binary_op (NE_EXPR, addr, integer_zero_node,
+       ifexp = fold (cp_build_binary_op (input_location,
+                                         NE_EXPR, addr, integer_zero_node,
                                          tf_warning_or_error));
 
       if (ifexp != integer_one_node)