diff options
-rw-r--r-- | gcc/cp/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/cp/init.c | 36 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/new10.C | 23 |
4 files changed, 51 insertions, 14 deletions
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]()); +} |