re PR c++/46348 ([C++0x] ICE with constexpr default constructor and array member)
authorJason Merrill <jason@redhat.com>
Thu, 9 Dec 2010 02:08:28 +0000 (21:08 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 9 Dec 2010 02:08:28 +0000 (21:08 -0500)
PR c++/46348
* semantics.c (cxx_eval_vec_init_1): Handle value-init.
(cxx_eval_vec_init): Pass value_init arg.

From-SVN: r167623

gcc/cp/ChangeLog
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/constexpr-array2.C [new file with mode: 0644]

index f5bddffa7aac933ef43351034848757e9b906eec..fb148620b4134f39c2e5f16523f07f41ca93ab89 100644 (file)
@@ -1,3 +1,9 @@
+2010-12-08  Jason Merrill  <jason@redhat.com>
+
+       PR c++/46348
+       * semantics.c (cxx_eval_vec_init_1): Handle value-init.
+       (cxx_eval_vec_init): Pass value_init arg.
+
 2010-12-08  Nathan Froyd  <froydnj@codesourcery.com>
 
        PR c++/45329
index 1ee0ccf934c69f2f25a193595ff62afcd53ad464..db0d0a19ba2148ceabedb67c7ba0e46060da87aa 100644 (file)
@@ -6391,15 +6391,16 @@ cxx_eval_bare_aggregate (const constexpr_call *call, tree t,
    initialization of a non-static data member of array type.  Reduce it to a
    CONSTRUCTOR.
 
-   Note that this is only intended to support the initializations done by
-   defaulted constructors for classes with non-static data members of array
-   type.  In this case, VEC_INIT_EXPR_INIT will either be NULL_TREE for the
-   default constructor, or a COMPONENT_REF for the copy/move
-   constructor.  */
+   Note that apart from value-initialization (when VALUE_INIT is true),
+   this is only intended to support value-initialization and the
+   initializations done by defaulted constructors for classes with
+   non-static data members of array type.  In this case, VEC_INIT_EXPR_INIT
+   will either be NULL_TREE for the default constructor, or a COMPONENT_REF
+   for the copy/move constructor.  */
 
 static tree
 cxx_eval_vec_init_1 (const constexpr_call *call, tree atype, tree init,
-                    bool allow_non_constant, bool addr,
+                    bool value_init, bool allow_non_constant, bool addr,
                     bool *non_constant_p)
 {
   tree elttype = TREE_TYPE (atype);
@@ -6412,7 +6413,9 @@ cxx_eval_vec_init_1 (const constexpr_call *call, tree atype, tree init,
      here, as for a constructor to be constexpr, all members must be
      initialized, which for a defaulted default constructor means they must
      be of a class type with a constexpr default constructor.  */
-  if (!init)
+  if (value_init)
+    gcc_assert (!init);
+  else if (!init)
     {
       VEC(tree,gc) *argvec = make_tree_vector ();
       init = build_special_member_call (NULL_TREE, complete_ctor_identifier,
@@ -6433,12 +6436,21 @@ cxx_eval_vec_init_1 (const constexpr_call *call, tree atype, tree init,
       if (TREE_CODE (elttype) == ARRAY_TYPE)
        {
          /* A multidimensional array; recurse.  */
-         eltinit = cp_build_array_ref (input_location, init, idx,
-                                       tf_warning_or_error);
-         eltinit = cxx_eval_vec_init_1 (call, elttype, eltinit,
+         if (value_init)
+           eltinit = NULL_TREE;
+         else
+           eltinit = cp_build_array_ref (input_location, init, idx,
+                                         tf_warning_or_error);
+         eltinit = cxx_eval_vec_init_1 (call, elttype, eltinit, value_init,
                                         allow_non_constant, addr,
                                         non_constant_p);
        }
+      else if (value_init)
+       {
+         eltinit = build_value_init (elttype, tf_warning_or_error);
+         eltinit = cxx_eval_constant_expression
+           (call, eltinit, allow_non_constant, addr, non_constant_p);
+       }
       else if (TREE_CODE (init) == CONSTRUCTOR)
        {
          /* Initializing an element using the call to the default
@@ -6488,8 +6500,9 @@ cxx_eval_vec_init (const constexpr_call *call, tree t,
 {
   tree atype = TREE_TYPE (t);
   tree init = VEC_INIT_EXPR_INIT (t);
-  tree r = cxx_eval_vec_init_1 (call, atype, init, allow_non_constant,
-                               addr, non_constant_p);
+  tree r = cxx_eval_vec_init_1 (call, atype, init,
+                               VEC_INIT_EXPR_VALUE_INIT (t),
+                               allow_non_constant, addr, non_constant_p);
   if (*non_constant_p)
     return t;
   else
index c62306dad7493488e35e3f7199e9547ed0a35c84..303d40bf14643ea59e9638f8ca389c1383271b7f 100644 (file)
@@ -1,3 +1,8 @@
+2010-12-08  Jason Merrill  <jason@redhat.com>
+
+       PR c++/46348
+       * g++.dg/cpp0x/constexpr-array2.C: New.
+
 2010-12-08  H.J. Lu  <hongjiu.lu@intel.com>
 
        * gcc.target/i386/sse2-init-v2di-2.c: Add "-dp" and update
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-array2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-array2.C
new file mode 100644 (file)
index 0000000..9577f75
--- /dev/null
@@ -0,0 +1,19 @@
+// PR c++/46348
+// { dg-options -std=c++0x }
+
+template<__SIZE_TYPE__ _Nw>
+  struct _Base
+  {
+    typedef unsigned long _WordT;
+
+    _WordT _M_w[_Nw];
+
+    constexpr
+    _Base()
+    : _M_w() { }
+  };
+
+int main()
+{
+  _Base<256> bs;
+}