This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR c++/65154 (ICE on braced initializer)


The following patch is supposed to fix the problem related to
initializing an array of aggregates with members, which have
user-defined default constructors.

Bootstrapped and regtested on x86_64-unknown-linux-gnu.

diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 0274663..0f53146 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -3716,11 +3716,9 @@ build_vec_init (tree base, tree maxindex, tree
init, {
 	  if (cxx_dialect >= cxx11 && AGGREGATE_TYPE_P (type))
 	    {
-	      if (BRACE_ENCLOSED_INITIALIZER_P (init)
-		  && CONSTRUCTOR_NELTS (init) == 0)
-		/* Reuse it.  */;
-	      else
-		init = build_constructor (init_list_type_node, NULL);
+	      /* We cannot reuse INIT here, because it must not be shared
+		 with member initializers.  */
+	      init = build_constructor (init_list_type_node, NULL);
 	      CONSTRUCTOR_IS_DIRECT_INIT (init) = true;
 	    }
 	  else
diff --git a/gcc/testsuite/g++.dg/init/array39.C
b/gcc/testsuite/g++.dg/init/array39.C new file mode 100644
index 0000000..2fd8937
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/array39.C
@@ -0,0 +1,46 @@
+// PR c++/65154
+// { dg-do run { target c++11 } }
+
+int cnt1 = 0,
+    cnt2 = 0;
+
+struct S_empty
+{
+    S_empty () {
+	cnt1++;
+    };
+};
+
+struct C1
+{
+  S_empty s;
+};
+
+struct S_init
+{
+  S_init () : i(42)
+  {
+    cnt2++;
+  };
+  int i;
+};
+
+struct C2
+{
+  S_init a, b;
+};
+
+int
+main ()
+{
+  C1 c1[5]{};
+  C2 c2[1]{};
+
+  if (c2[0].a.i != 42 || c2[0].b.i != 42)
+    return 1;
+
+  if (cnt1 != 5 || cnt2 != 2)
+    return 1;
+
+  return 0;
+}


Changelog record:

2015-03-02  Mikhail Maltsev  <maltsevm@gmail.com>

    	PR c++/65154
        * gcc/cp/init.c (build_vec_init): Fixed initializing aggregates
          with empty init list.
        * gcc/testsuite/g++.dg/init/array39.C: New test.


N.B.:
Consider the test case. The constructors of S_init and S_empty are
called from main (this can be seen in GIMPLE dump, right after
gimplification), while clang, for example, generates an explicit call to
constructors of C1 and C2. GCC does the same, if direct initializers
are removed. I don't know, if such behavior is OK or not.

-- 
Regards,
    Mikhail Maltsev


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]