re PR c++/29291 (ICE on invalid use of new)
[gcc.git] / gcc / cp / init.c
index 8a338faa5496f7c2492389330aa1cc83e7616d13..0c85c0fe8fddfd1efdc2663a45353d7b6306711c 100644 (file)
@@ -178,7 +178,8 @@ build_zero_init (tree type, tree nelts, bool static_storage_p)
        items with static storage duration that are not otherwise
        initialized are initialized to zero.  */
     ;
-  else if (SCALAR_TYPE_P (type))
+  else if (SCALAR_TYPE_P (type)
+          || TREE_CODE (type) == COMPLEX_TYPE)
     init = convert (type, integer_zero_node);
   else if (CLASS_TYPE_P (type))
     {
@@ -222,6 +223,11 @@ build_zero_init (tree type, tree nelts, bool static_storage_p)
                                 nelts, integer_one_node);
       else
        max_index = array_type_nelts (type);
+
+      /* If we have an error_mark here, we should just return error mark
+        as we don't know the size of the array yet.  */
+      if (max_index == error_mark_node)
+       return error_mark_node;
       gcc_assert (TREE_CODE (max_index) == INTEGER_CST);
 
       /* A zero-sized array, which is accepted as an extension, will
@@ -248,6 +254,8 @@ build_zero_init (tree type, tree nelts, bool static_storage_p)
       /* Build a constructor to contain the initializations.  */
       init = build_constructor (type, v);
     }
+  else if (TREE_CODE (type) == VECTOR_TYPE)
+    init = fold_convert (type, integer_zero_node);
   else
     gcc_assert (TREE_CODE (type) == REFERENCE_TYPE);
 
@@ -1320,7 +1328,7 @@ build_offset_ref (tree type, tree member, bool address_p)
     return member;
 
   if (dependent_type_p (type) || type_dependent_expression_p (member))
-    return build_qualified_name (NULL_TREE, type, member, 
+    return build_qualified_name (NULL_TREE, type, member,
                                 /*template_p=*/false);
 
   gcc_assert (TYPE_P (type));
@@ -1339,7 +1347,7 @@ build_offset_ref (tree type, tree member, bool address_p)
     }
 
   /* Entities other than non-static members need no further
-     processing.  */ 
+     processing.  */
   if (TREE_CODE (member) == TYPE_DECL)
     return member;
   if (TREE_CODE (member) == VAR_DECL || TREE_CODE (member) == CONST_DECL)
@@ -1451,7 +1459,7 @@ static tree
 constant_value_1 (tree decl, bool integral_p)
 {
   while (TREE_CODE (decl) == CONST_DECL
-        || (integral_p 
+        || (integral_p
             ? DECL_INTEGRAL_CONSTANT_VAR_P (decl)
             : (TREE_CODE (decl) == VAR_DECL
                && CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl)))))
@@ -1466,7 +1474,7 @@ constant_value_1 (tree decl, bool integral_p)
         instantiation time.  */
       if (DECL_CLASS_SCOPE_P (decl)
          && CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (decl))
-         && uses_template_parms (CLASSTYPE_TI_ARGS 
+         && uses_template_parms (CLASSTYPE_TI_ARGS
                                  (DECL_CONTEXT (decl))))
        {
          ++processing_template_decl;
@@ -1520,7 +1528,7 @@ integral_constant_value (tree decl)
 tree
 decl_constant_value (tree decl)
 {
-  return constant_value_1 (decl, 
+  return constant_value_1 (decl,
                           /*integral_p=*/processing_template_decl);
 }
 \f
@@ -1548,9 +1556,9 @@ build_raw_new_expr (tree placement, tree type, tree nelts, tree init,
                    int use_global_new)
 {
   tree new_expr;
-  
-  new_expr = build4 (NEW_EXPR, build_pointer_type (type), placement, type, 
-                    nelts, init); 
+
+  new_expr = build4 (NEW_EXPR, build_pointer_type (type), placement, type,
+                    nelts, init);
   NEW_EXPR_USE_GLOBAL (new_expr) = use_global_new;
   TREE_SIDE_EFFECTS (new_expr) = 1;
 
@@ -1565,7 +1573,6 @@ build_raw_new_expr (tree placement, tree type, tree nelts, tree init,
 static tree
 build_new_1 (tree placement, tree type, tree nelts, tree init,
             bool globally_qualified_p)
-            
 {
   tree size, rval;
   /* True iff this is a call to "operator new[]" instead of just
@@ -1626,10 +1633,14 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
         function context.  Methinks that's not it's purvey.  So we'll do
         our own VLA layout later.  */
       vla_p = true;
-      full_type = build_cplus_array_type (type, NULL_TREE);
       index = convert (sizetype, nelts);
       index = size_binop (MINUS_EXPR, index, size_one_node);
-      TYPE_DOMAIN (full_type) = build_index_type (index);
+      index = build_index_type (index);
+      full_type = build_cplus_array_type (type, NULL_TREE);
+      /* We need a copy of the type as build_array_type will return a shared copy
+         of the incomplete array type.  */
+      full_type = build_distinct_type_copy (full_type);
+      TYPE_DOMAIN (full_type) = index;
     }
   else
     {
@@ -1697,6 +1708,9 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
       tree class_decl = build_java_class_ref (elt_type);
       static const char alloc_name[] = "_Jv_AllocObject";
 
+      if (class_decl == error_mark_node)
+       return error_mark_node;
+
       use_java_new = 1;
       if (!get_global_value_if_present (get_identifier (alloc_name),
                                        &alloc_fn))
@@ -1894,8 +1908,8 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
            = build_vec_init (init_expr,
                              cp_build_binary_op (MINUS_EXPR, outer_nelts,
                                                  integer_one_node),
-                             init, 
-                             explicit_default_init_p,
+                             init,
+                             explicit_default_init_p,
                              /*from_array=*/0);
 
          /* An array initialization is stable because the initialization
@@ -1920,14 +1934,14 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
            {
              /* We are processing something like `new int (10)', which
                 means allocate an int, and initialize it with 10.  */
-             
+
              if (TREE_CODE (init) == TREE_LIST)
-               init = build_x_compound_expr_from_list (init, 
+               init = build_x_compound_expr_from_list (init,
                                                        "new initializer");
              else
                gcc_assert (TREE_CODE (init) != CONSTRUCTOR
                            || TREE_TYPE (init) != NULL_TREE);
-             
+
              init_expr = build_modify_expr (init_expr, INIT_EXPR, init);
              stable = stabilize_init (init_expr, &init_preeval_expr);
            }
@@ -2061,7 +2075,8 @@ build_new (tree placement, tree type, tree nelts, tree init,
   tree orig_nelts;
   tree orig_init;
 
-  if (type == error_mark_node)
+  if (placement == error_mark_node || type == error_mark_node
+      || init == error_mark_node)
     return error_mark_node;
 
   orig_placement = placement;
@@ -2098,7 +2113,7 @@ build_new (tree placement, tree type, tree nelts, tree init,
           array with no elements.  The pointer returned by the
           new-expression is non-null.  [Note: If the library allocation
           function is called, the pointer returned is distinct from the
-          pointer to any other object.]  
+          pointer to any other object.]
 
         However, that is not generally useful, so we issue a
         warning.  */
@@ -2149,8 +2164,10 @@ build_java_class_ref (tree type)
     {
       jclass_node = IDENTIFIER_GLOBAL_VALUE (get_identifier ("jclass"));
       if (jclass_node == NULL_TREE)
-       fatal_error ("call to Java constructor, while %<jclass%> undefined");
-
+       {
+         error ("call to Java constructor, while %<jclass%> undefined");
+         return error_mark_node;
+       }
       jclass_node = TREE_TYPE (jclass_node);
     }
 
@@ -2165,8 +2182,11 @@ build_java_class_ref (tree type)
          break;
        }
     if (!field)
-      internal_error ("can't find class$");
-    }
+      {
+       error ("can't find %<class$%> in %qT", type);
+       return error_mark_node;
+      }
+  }
 
   class_decl = IDENTIFIER_GLOBAL_VALUE (name);
   if (class_decl == NULL_TREE)
@@ -2276,7 +2296,7 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
        deallocate_expr = build_op_delete_call (VEC_DELETE_EXPR,
                                                base_tbd, virtual_size,
                                                use_global_delete & 1,
-                                               /*placement=*/NULL_TREE, 
+                                               /*placement=*/NULL_TREE,
                                                /*alloc_fn=*/NULL_TREE);
     }
 
@@ -2370,7 +2390,7 @@ get_temp_regvar (tree type, tree init)
    but use assignment instead of initialization.  */
 
 tree
-build_vec_init (tree base, tree maxindex, tree init, 
+build_vec_init (tree base, tree maxindex, tree init,
                bool explicit_default_init_p,
                int from_array)
 {
@@ -2579,12 +2599,12 @@ build_vec_init (tree base, tree maxindex, tree init,
            sorry
              ("cannot initialize multi-dimensional array with initializer");
          elt_init = build_vec_init (build1 (INDIRECT_REF, type, base),
-                                    0, 0, 
+                                    0, 0,
                                     /*explicit_default_init_p=*/false,
                                     0);
        }
       else if (!TYPE_NEEDS_CONSTRUCTING (type))
-       elt_init = (build_modify_expr 
+       elt_init = (build_modify_expr
                    (to, INIT_EXPR,
                     build_zero_init (type, size_one_node,
                                      /*static_storage_p=*/false)));
@@ -2763,8 +2783,8 @@ build_delete (tree type, tree addr, special_function_kind auto_delete,
       if (auto_delete != sfk_deleting_destructor)
        return void_zero_node;
 
-      return build_op_delete_call (DELETE_EXPR, addr, 
-                                  cxx_sizeof_nowarn (type), 
+      return build_op_delete_call (DELETE_EXPR, addr,
+                                  cxx_sizeof_nowarn (type),
                                   use_global_delete,
                                   /*placement=*/NULL_TREE,
                                   /*alloc_fn=*/NULL_TREE);
@@ -2814,7 +2834,7 @@ build_delete (tree type, tree addr, special_function_kind auto_delete,
          /* Make sure we have access to the member op delete, even though
             we'll actually be calling it from the destructor.  */
          build_op_delete_call (DELETE_EXPR, addr, cxx_sizeof_nowarn (type),
-                               /*global_p=*/false, 
+                               /*global_p=*/false,
                                /*placement=*/NULL_TREE,
                                /*alloc_fn=*/NULL_TREE);
        }
@@ -2899,7 +2919,9 @@ push_base_cleanups (void)
   for (member = TYPE_FIELDS (current_class_type); member;
        member = TREE_CHAIN (member))
     {
-      if (TREE_CODE (member) != FIELD_DECL || DECL_ARTIFICIAL (member))
+      if (TREE_TYPE (member) == error_mark_node
+         || TREE_CODE (member) != FIELD_DECL
+         || DECL_ARTIFICIAL (member))
        continue;
       if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (member)))
        {