diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index be7497a..ba3eca3 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,8 @@
 2011-01-11  Jason Merrill  <jason@redhat.com>
 
+	PR c++/46658
+	* init.c (build_new_1): Handle value-init in templates differently.
+
 	PR c++/45520
 	* tree.c (maybe_dummy_object): Check current_class_ref against
 	context, not current_class_type.
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 9c3dd32..1546bf8 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -2294,7 +2294,22 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
 	  explicit_value_init_p = true;
 	}
 
-      if (array_p)
+      if (processing_template_decl && explicit_value_init_p)
+	{
+	  /* build_value_init doesn't work in templates, and we don't need
+	     the initializer anyway since we're going to throw it away and
+	     rebuild it at instantiation time, so just build up a single
+	     constructor call to get any appropriate diagnostics.  */
+	  init_expr = cp_build_indirect_ref (data_addr, RO_NULL, complain);
+	  if (TYPE_NEEDS_CONSTRUCTING (elt_type))
+	    init_expr = build_special_member_call (init_expr,
+						   complete_ctor_identifier,
+						   init, elt_type,
+						   LOOKUP_NORMAL,
+						   complain);
+	  stable = stabilize_init (init_expr, &init_preeval_expr);
+	}
+      else if (array_p)
 	{
 	  tree vecinit = NULL_TREE;
 	  if (*init && VEC_length (tree, *init) == 1
@@ -2343,8 +2358,7 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
 	{
 	  init_expr = cp_build_indirect_ref (data_addr, RO_NULL, complain);
 
-	  if (TYPE_NEEDS_CONSTRUCTING (type)
-	      && (!explicit_value_init_p || processing_template_decl))
+	  if (TYPE_NEEDS_CONSTRUCTING (type) && !explicit_value_init_p)
 	    {
 	      init_expr = build_special_member_call (init_expr,
 						     complete_ctor_identifier,
@@ -2354,17 +2368,11 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
 	    }
 	  else if (explicit_value_init_p)
 	    {
-	      if (processing_template_decl)
-		/* Don't worry about it, we'll handle this properly at
-		   instantiation time.  */;
-	      else
-		{
-		  /* Something like `new int()'.  */
-		  tree val = build_value_init (type, complain);
-		  if (val == error_mark_node)
-		    return error_mark_node;
-		  init_expr = build2 (INIT_EXPR, type, init_expr, val);
-		}
+	      /* Something like `new int()'.  */
+	      tree val = build_value_init (type, complain);
+	      if (val == error_mark_node)
+		return error_mark_node;
+	      init_expr = build2 (INIT_EXPR, type, init_expr, val);
 	    }
 	  else
 	    {
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 999a713..64f7ad0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
 2011-01-11  Jason Merrill  <jason@redhat.com>
 
+	PR c++/46658
+	* g++.dg/template/new10.C: New.
+
 	PR c++/45520
 	* g++.dg/cpp0x/lambda/lambda-this3.C: New.
 
diff --git a/gcc/testsuite/g++.dg/template/new10.C b/gcc/testsuite/g++.dg/template/new10.C
new file mode 100644
index 0000000..98293ba
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/new10.C
@@ -0,0 +1,23 @@
+// PR c++/46658
+
+typedef unsigned short int uint16_t;
+typedef unsigned int uint32_t;
+template<class T> class scoped_array {
+    void reset(T * p = 0)     { }
+};
+typedef uint16_t SequenceIndex;
+typedef uint32_t SequenceMapIndex;
+class Analyzer  {
+    template <typename READER>
+        bool ReadDictionary( READER& reader );
+    scoped_array<SequenceIndex> map_from_2_hints_to_composite_sequence;
+    SequenceMapIndex number_of_composite_sequences;
+};
+template <typename READER>
+bool Analyzer::ReadDictionary( READER &reader )
+{
+  const SequenceMapIndex ntt
+    = ( number_of_composite_sequences + SequenceMapIndex( 1 ) )
+    * ( number_of_composite_sequences + 1 );
+  map_from_2_hints_to_composite_sequence.reset(new SequenceIndex[ntt]());
+}