re PR c++/20142 (implicit assignment operator with multi-dimensional array is broken)
authorMark Mitchell <mark@codesourcery.com>
Wed, 9 Mar 2005 07:28:10 +0000 (07:28 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Wed, 9 Mar 2005 07:28:10 +0000 (07:28 +0000)
PR c++/20142
* cp-tree.h (target_type): Remove.
* decl.c (layout_var_decl): Remove #if 0'd code.
(cp_finish_decl): Remove dead code.
* init.c (build_vec_init): When determining whether or not the
element type has an asignment operator, look through all array
dimensions.
* typeck.c (target_type): Remove.

PR c++/20142
* g++.dg/init/array18.C: New test.

From-SVN: r96170

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/init.c
gcc/cp/name-lookup.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/init/array18.C [new file with mode: 0644]

index 3048511f23b084797165b7dc1863b474c8c53b5a..a5dba31ddefca121b2afd9992bb2361b66fa9200 100644 (file)
@@ -1,3 +1,14 @@
+2005-03-08  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/20142
+       * cp-tree.h (target_type): Remove.
+       * decl.c (layout_var_decl): Remove #if 0'd code.
+       (cp_finish_decl): Remove dead code.
+       * init.c (build_vec_init): When determining whether or not the
+       element type has an asignment operator, look through all array
+       dimensions. 
+       * typeck.c (target_type): Remove.
+
 2005-03-07  Mark Mitchell  <mark@codesourcery.com>
 
        * class.c (finish_struct_1): Do not warn about non-virtual
index d7144242d6d91a3183e60aab0b6aa30e1ddfa4fa..22d5f17a0cdcdb4212f2973f3ff630815a40b882 100644 (file)
@@ -4267,7 +4267,6 @@ extern tree fold_if_not_in_template             (tree);
 extern int string_conv_p                       (tree, tree, int);
 extern tree cp_truthvalue_conversion           (tree);
 extern tree condition_conversion               (tree);
-extern tree target_type                                (tree);
 extern tree require_complete_type              (tree);
 extern tree complete_type                      (tree);
 extern tree complete_type_or_else              (tree, tree);
index dfc1790a175ad6fe842c62b36b691a5901ffb65d..fbb264e96406fb15565afcaef7c68f344f6bd385 100644 (file)
@@ -3940,9 +3940,6 @@ static void
 layout_var_decl (tree decl)
 {
   tree type = TREE_TYPE (decl);
-#if 0
-  tree ttype = target_type (type);
-#endif
 
   /* If we haven't already layed out this declaration, do so now.
      Note that we must not call complete type for an external object
@@ -4710,7 +4707,6 @@ void
 cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
 {
   tree type;
-  tree ttype = NULL_TREE;
   tree cleanup;
   const char *asmspec = NULL;
   int was_readonly = 0;
@@ -4795,10 +4791,6 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
       goto finish_end;
     }
 
-  if (TREE_CODE (decl) != FUNCTION_DECL)
-    ttype = target_type (type);
-
-
   /* A reference will be modified here, as it is initialized.  */
   if (! DECL_EXTERNAL (decl) 
       && TREE_READONLY (decl)
index d572bca344e92bbedb59d7d4bfd09cec283f4dff..c526bb14511be9ca4a0db4b43a7f32d8c25172d8 100644 (file)
@@ -2388,6 +2388,9 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array)
   tree atype = TREE_TYPE (base);
   /* The type of an element in the array.  */
   tree type = TREE_TYPE (atype);
+  /* The element type reached after removing all outer array 
+     types.  */
+  tree inner_elt_type;
   /* The type of a pointer to an element in the array.  */
   tree ptype;
   tree stmt_expr;
@@ -2403,15 +2406,17 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array)
   if (maxindex == NULL_TREE || maxindex == error_mark_node)
     return error_mark_node;
 
+  inner_elt_type = strip_array_types (atype);
   if (init
       && (from_array == 2
-         ? (!CLASS_TYPE_P (type) || !TYPE_HAS_COMPLEX_ASSIGN_REF (type))
+         ? (!CLASS_TYPE_P (inner_elt_type) 
+            || !TYPE_HAS_COMPLEX_ASSIGN_REF (inner_elt_type))
          : !TYPE_NEEDS_CONSTRUCTING (type))
       && ((TREE_CODE (init) == CONSTRUCTOR
           /* Don't do this if the CONSTRUCTOR might contain something
              that might throw and require us to clean up.  */
           && (CONSTRUCTOR_ELTS (init) == NULL_TREE
-              || ! TYPE_HAS_NONTRIVIAL_DESTRUCTOR (target_type (type))))
+              || ! TYPE_HAS_NONTRIVIAL_DESTRUCTOR (inner_elt_type)))
          || from_array))
     {
       /* Do non-default initialization of POD arrays resulting from
@@ -2602,14 +2607,12 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array)
       /* 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,
-                                 array_type_nelts_total (type));
-         type = strip_array_types (type);
-       }
+       m = cp_build_binary_op (MULT_EXPR, m,
+                               array_type_nelts_total (type));
 
       finish_cleanup_try_block (try_block);
-      e = build_vec_delete_1 (rval, m, type, sfk_base_destructor,
+      e = build_vec_delete_1 (rval, m, 
+                             inner_elt_type, sfk_base_destructor,
                              /*use_global_delete=*/0);
       finish_cleanup (e, try_block);
     }
index accd35210ec556a995178167f8edbf4caf7b1e0f..e861a660393ff56dd8213cd678631242f9e6bc9e 100644 (file)
@@ -4644,6 +4644,9 @@ pushtag (tree name, tree type, int globalize)
          else
            d = pushdecl_with_scope (d, b);
 
+         if (d == error_mark_node)
+           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+
          /* FIXME what if it gets a name from typedef?  */
          if (ANON_AGGRNAME_P (name))
            DECL_IGNORED_P (d) = 1;
index 9de7b24d0a2112dffc7564e0e56b74b04540ce29..1639b54532ba3415c4dcb32899bd3fa318e0113c 100644 (file)
@@ -59,22 +59,6 @@ static void maybe_warn_about_returning_address_of_local (tree);
 static tree lookup_destructor (tree, tree, tree);
 static tree convert_arguments (tree, tree, tree, int);
 
-/* Return the target type of TYPE, which means return T for:
-   T*, T&, T[], T (...), and otherwise, just T.  */
-
-tree
-target_type (tree type)
-{
-  type = non_reference (type);
-  while (TREE_CODE (type) == POINTER_TYPE
-        || TREE_CODE (type) == ARRAY_TYPE
-        || TREE_CODE (type) == FUNCTION_TYPE
-        || TREE_CODE (type) == METHOD_TYPE
-        || TYPE_PTRMEM_P (type))
-    type = TREE_TYPE (type);
-  return type;
-}
-
 /* Do `exp = require_complete_type (exp);' to make sure exp
    does not have an incomplete type.  (That includes void types.)
    Returns the error_mark_node if the VALUE does not have
index 6c1ac228a1f6a23f998ae90e5e0f2ff914f2c24e..c7bdbe1f81e2c74cfc17fd8dcde93eb068e47547 100644 (file)
@@ -1,3 +1,8 @@
+2005-03-08  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/20142
+       * g++.dg/init/array18.C: New test.
+       
 2005-03-09  Ben Elliston  <bje@au.ibm.com>
 
        * consistency.vlad/vlad.exp: Remove trailing semicolons.
diff --git a/gcc/testsuite/g++.dg/init/array18.C b/gcc/testsuite/g++.dg/init/array18.C
new file mode 100644 (file)
index 0000000..1cb5dba
--- /dev/null
@@ -0,0 +1,21 @@
+// PR c++/20142
+
+int n=4;
+
+struct A
+{
+  A() {}
+  A& operator= (const A&) { --n; return *this; }
+};
+
+struct B
+{
+  A x[2][2];
+};
+
+int main()
+{
+  B b;
+  b = b;
+  return n;
+}