OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / cp / init.c
index 5535033..61c78e1 100644 (file)
@@ -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);
@@ -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
@@ -2169,13 +2181,14 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
          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,
@@ -2241,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.  */;
@@ -2300,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);
@@ -2308,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, 
@@ -2362,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)
@@ -2383,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;
         }
@@ -2567,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,
@@ -2921,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);
 
@@ -3031,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;
            }
        }
@@ -3153,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)