diff mbox

C++0x PATCH for a couple of variadic templates/value-initialization issues

Message ID 4C4F583A.4040703@redhat.com
State New
Headers show

Commit Message

Jason Merrill July 27, 2010, 10:05 p.m. UTC
Daniel pointed out a couple of bugs with our handling of 
value-initialization when a pack expansion expands to 0 elements.  In 
one, we were failing to give an error message for value-initializing an 
array of unknown bound; in the other we were passing an AGGR_INIT_EXPR 
into cp_finish_decl, which isn't prepared to handle it.

Tested x86_64-pc-linux-gnu, applied to trunk.
diff mbox

Patch

commit 8807d220e86960d8ede6faabd963307c5951c278
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Jul 27 11:03:35 2010 -0400

    	* pt.c (tsubst_expr) [DECL_EXPR]: Handle getting an AGGR_INIT_EXPR
    	from build_value_init.
    	* init.c (build_value_init_noctor): Give error for unknown array
    	bound.

diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index d796fd0..0edb800 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -379,7 +379,10 @@  build_value_init_noctor (tree 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;
+	{
+	  error ("cannot value-initialize array of unknown bound %qT", type);
+	  return error_mark_node;
+	}
       gcc_assert (TREE_CODE (max_index) == INTEGER_CST);
 
       /* A zero-sized array, which is accepted as an extension, will
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 7a33147..2777ab7 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -11697,14 +11697,18 @@  tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
 			tree t = RECUR (init);
 
 			if (init && !t)
-			  /* If we had an initializer but it
-			     instantiated to nothing,
-			     value-initialize the object.  This will
-			     only occur when the initializer was a
-			     pack expansion where the parameter packs
-			     used in that expansion were of length
-			     zero.  */
-			  init = build_value_init (TREE_TYPE (decl));
+			  {
+			    /* If we had an initializer but it
+			       instantiated to nothing,
+			       value-initialize the object.  This will
+			       only occur when the initializer was a
+			       pack expansion where the parameter packs
+			       used in that expansion were of length
+			       zero.  */
+			    init = build_value_init (TREE_TYPE (decl));
+			    if (TREE_CODE (init) == AGGR_INIT_EXPR)
+			      init = get_target_expr (init);
+			  }
 			else
 			  init = t;
 		      }
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic102.C b/gcc/testsuite/g++.dg/cpp0x/variadic102.C
new file mode 100644
index 0000000..dc9c4ae
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic102.C
@@ -0,0 +1,19 @@ 
+// { dg-options "-std=c++0x" }
+
+struct nAny {
+  template<class... T>
+  nAny(T&&...);
+};
+
+template<class T>
+T&& create();
+
+template<class T, class... Args>
+void test() {
+  T t(create<Args>()...);
+  (void) t;
+}
+
+int main() {
+  test<nAny>();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic103.C b/gcc/testsuite/g++.dg/cpp0x/variadic103.C
new file mode 100644
index 0000000..6d12331
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic103.C
@@ -0,0 +1,14 @@ 
+// { dg-options "-std=c++0x" }
+
+template<class T>
+T&& create();
+
+template<class T, class... Args>
+void test() {
+  T t(create<Args>()...);	// { dg-error "unknown bound" }
+  (void) t;
+}
+
+int main() {
+  test<int[]>();
+}