[C++ PATCH for 3.1, committed] Fix PR6944

Kriang Lerdsuwanakij lerdsuwa@users.sourceforge.net
Wed Jul 3 08:49:00 GMT 2002


Hi

Here is the final version of the patch fixing PR6944, 6803.
Committed to 3.1 branch and trunk.

--Kriang


2002-07-03  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

        PR c++/6944
        * init.c (build_aggr_init): Remove qualifiers of init before calling
        build_vec_init.
        (build_vec_init): Flatten multi-dimensional array during cleanup.
        (build_vec_delete_1): Abort if the type of each element is array.

2002-07-03  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

        PR c++/6944
        * g++.dg/init/array4.C: New test.
        * g++.dg/init/array5.C: New test.


diff -cprN gcc-31-save/gcc/cp/init.c gcc-31-new/gcc/cp/init.c
*** gcc-31-save/gcc/cp/init.c   Sun May 19 17:07:27 2002
--- gcc-31-new/gcc/cp/init.c    Wed Jul  3 20:37:15 2002
*************** build_aggr_init (exp, init, flags)
*** 1183,1193 ****
          return error_mark_node;
        }
        if (cp_type_quals (type) != TYPE_UNQUALIFIED)
!       {
!         TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);
!         if (init)
!           TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype);
!       }
        stmt_expr = build_vec_init (exp, init,
                                  init && same_type_p (TREE_TYPE (init),
                                                       TREE_TYPE (exp)));
--- 1183,1191 ----
          return error_mark_node;
        }
        if (cp_type_quals (type) != TYPE_UNQUALIFIED)
!       TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);
!       if (itype && cp_type_quals (itype) != TYPE_UNQUALIFIED)
!       TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype);
        stmt_expr = build_vec_init (exp, init,
                                  init && same_type_p (TREE_TYPE (init),
                                                       TREE_TYPE (exp)));
*************** build_vec_delete_1 (base, maxindex, type
*** 2593,2598 ****
--- 2591,2600 ----
       This is also the containing expression returned by this function.  */
    tree controller = NULL_TREE;
  
+   /* We should only have 1-D arrays here.  */
+   if (TREE_CODE (type) == ARRAY_TYPE)
+     abort ();
+ 
    if (! IS_AGGR_TYPE (type) || TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
      {
        loop = integer_zero_node;
*************** build_vec_init (base, init, from_array)
*** 3006,3017 ****
        && from_array != 2)
      {
        tree e;
  
        finish_compound_stmt (/*has_no_scope=*/1, try_body);
        finish_cleanup_try_block (try_block);
!       e = build_vec_delete_1 (rval,
!                             cp_build_binary_op (MINUS_EXPR, maxindex, 
!                                                 iterator),
                              type,
                              sfk_base_destructor,
                              /*use_global_delete=*/0);
--- 3008,3027 ----
        && from_array != 2)
      {
        tree e;
+       tree m = cp_build_binary_op (MINUS_EXPR, maxindex, iterator);
+ 
+       /* 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);
+       }
  
        finish_compound_stmt (/*has_no_scope=*/1, try_body);
        finish_cleanup_try_block (try_block);
!       e = build_vec_delete_1 (rval, m,
                              type,
                              sfk_base_destructor,
                              /*use_global_delete=*/0);
diff -cprN gcc-31-save/gcc/testsuite/g++.dg/init/array4.C gcc-31-new/gcc/testsuite/g++.dg/init/array4.C
*** gcc-31-save/gcc/testsuite/g++.dg/init/array4.C      Thu Jan  1 07:00:00 1970
--- gcc-31-new/gcc/testsuite/g++.dg/init/array4.C       Wed Jul  3 20:32:30 2002
***************
*** 0 ****
--- 1,27 ----
+ // { dg-do compile }
+ // Origin: Markus Breuer <markus.breuer@materna.de>
+ 
+ // PR c++/6944
+ // Fail to synthesize copy constructor of multi-dimensional
+ // array of class.
+ 
+ #include <string>
+ 
+ class Array
+ {
+ public:
+    std::string m_array[10][20][30];
+ };
+ 
+ Array func()
+ {
+    Array result;
+    return result; // sorry, not implemented: cannot initialize multi-dimensional array with initializer
+ }
+ 
+ 
+ int main()
+ {
+    Array arr = func();
+ }
+ 
diff -cprN gcc-31-save/gcc/testsuite/g++.dg/init/array5.C gcc-31-new/gcc/testsuite/g++.dg/init/array5.C
*** gcc-31-save/gcc/testsuite/g++.dg/init/array5.C      Thu Jan  1 07:00:00 1970
--- gcc-31-new/gcc/testsuite/g++.dg/init/array5.C       Wed Jul  3 20:32:30 2002
***************
*** 0 ****
--- 1,52 ----
+ // { dg-do run }
+ // Copyright (C) 2002 Free Software Foundation
+ // Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+ 
+ // Incorrect construction and destruction of multi-dimensional
+ // array of class.
+ 
+ extern "C" void abort();
+ extern "C" int printf(const char *, ...);
+ 
+ int count;
+ int num;
+ 
+ struct A
+ {
+       A()
+       {
+               if (count == num)
+                       throw "";
+               count++;
+ #ifdef PRINT
+               printf("ctor %p\n", static_cast<void *>(this));
+ #endif
+       }
+ 
+       ~A()
+       {
+               count--;
+ #ifdef PRINT
+               printf("dtor %p\n", static_cast<void *>(this));
+ #endif
+       }
+ };
+ 
+ struct Array
+ {
+       A array[2][2][2];
+ };
+ 
+ int main()
+ {
+       for (num = 0; num <= 8; ++num) {
+               count = 0;
+               try {
+                       Array A;
+               }
+               catch (...) {
+               }
+               if (count != 0)
+                       abort();
+       }
+ }



More information about the Gcc-patches mailing list