From patchwork Thu Aug 19 16:54:21 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: C++ PATCH for c++/45315 (ICE on new T()) Date: Thu, 19 Aug 2010 06:54:21 -0000 From: Jason Merrill X-Patchwork-Id: 62202 Message-Id: <4C6D61BD.9030006@redhat.com> To: gcc-patches List The hoops that we jump through to implement value-initialization of aggregates don't work in templates, so we shouldn't try to do it at all; we're just going to throw away the result of build_new_1 anyway. Tested x86_64-pc-linux-gnu, applied to trunk. commit 2bec61b98748c07fe7e985d787cf92b9a7faa4e5 Author: Jason Merrill Date: Wed Aug 18 16:00:41 2010 -0400 PR c++/45315 * init.c (build_new_1): Don't use build_value_init in a template. (build_value_init): Make sure we don't. diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 8555fad..189bcbe 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -295,6 +295,9 @@ build_value_init (tree type, tsubst_flags_t complain) zero-initializing the object and then calling the default constructor. */ + /* The AGGR_INIT_EXPR tweaking below breaks in templates. */ + gcc_assert (!processing_template_decl); + if (CLASS_TYPE_P (type)) { if (type_has_user_provided_constructor (type)) @@ -2310,7 +2313,8 @@ 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) + if (TYPE_NEEDS_CONSTRUCTING (type) + && (!explicit_value_init_p || processing_template_decl)) { init_expr = build_special_member_call (init_expr, complete_ctor_identifier, @@ -2320,11 +2324,17 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, } else if (explicit_value_init_p) { - /* 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); + 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); + } } else { diff --git a/gcc/testsuite/g++.dg/init/value8.C b/gcc/testsuite/g++.dg/init/value8.C new file mode 100644 index 0000000..0a9b90b --- /dev/null +++ b/gcc/testsuite/g++.dg/init/value8.C @@ -0,0 +1,19 @@ +// PR c++/45315 + +struct A +{ + A (); +}; + +template < int > struct B : A +{ + void foo () + { + new B < 0 > (); + } +}; + +int main() +{ + B<1>().foo(); +}