diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/init.c | 3 | ||||
-rw-r--r-- | gcc/cp/pt.c | 43 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/variadic-new.C | 19 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/variadic-new2.C | 24 |
7 files changed, 99 insertions, 9 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index cc5e063..558aa06 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2007-08-31 Douglas Gregor <doug.gregor@gmail.com> + + PR c++/32597 + * init.c (build_default_init): Make extern. + * cp-tree.h (build_default_init): Declare here. + * pt.c (tsubst_expr): When the instantiation of the initializer of + a variable results in an empty list, default-initialize the + variable. + (tsubst_copy_and_build): When the instantiation of the initializer + in a new expression results in an empty initializer list, + default-initialize it. + 2007-08-31 Douglas Gregor <doug.gregor@gmail.com> * mangle.c (write_type): Change mangling of rvalue reference from diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index e07c0bd..71f401f 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4345,6 +4345,7 @@ extern tree build_zero_init (tree, tree, bool); extern tree build_offset_ref (tree, tree, bool); extern tree build_new (tree, tree, tree, tree, int); extern tree build_vec_init (tree, tree, tree, bool, int); +extern tree build_default_init (tree, tree); extern tree build_delete (tree, tree, special_function_kind, int, int); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index ce33e42..b46d687 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -51,7 +51,6 @@ static tree initializing_context (tree); static void expand_cleanup_for_base (tree, tree); static tree get_temp_regvar (tree, tree); static tree dfs_initialize_vtbl_ptrs (tree, void *); -static tree build_default_init (tree, tree); static tree build_dtor_call (tree, special_function_kind, int); static tree build_field_list (tree, tree, int *); static tree build_vtbl_address (tree); @@ -275,7 +274,7 @@ build_zero_init (tree type, tree nelts, bool static_storage_p) returns NULL_TREE; the caller is responsible for arranging for the constructors to be called. */ -static tree +tree build_default_init (tree type, tree nelts) { /* [dcl.init]: diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index e1eda24..68716f1 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -9885,7 +9885,23 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, init = cp_fname_init (name, &TREE_TYPE (decl)); } else - init = RECUR (init); + { + 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_default_init (TREE_TYPE (decl), + NULL_TREE); + else + init = t; + } + finish_decl (decl, init, NULL_TREE); } } @@ -10489,12 +10505,25 @@ tsubst_copy_and_build (tree t, return build_x_arrow (op1); case NEW_EXPR: - return build_new - (RECUR (TREE_OPERAND (t, 0)), - RECUR (TREE_OPERAND (t, 1)), - RECUR (TREE_OPERAND (t, 2)), - RECUR (TREE_OPERAND (t, 3)), - NEW_EXPR_USE_GLOBAL (t)); + { + tree init = RECUR (TREE_OPERAND (t, 3)); + + if (TREE_OPERAND (t, 3) && !init) + /* If there was an initializer in the the original tree, but + it instantiated to an empty list, then we should pass on + VOID_ZERO_NODE to tell build_new that it was an empty + initializer () rather than no initializer. This can only + happen when the initializer is a pack expansion whose + parameter packs are of length zero. */ + init = void_zero_node; + + return build_new + (RECUR (TREE_OPERAND (t, 0)), + RECUR (TREE_OPERAND (t, 1)), + RECUR (TREE_OPERAND (t, 2)), + init, + NEW_EXPR_USE_GLOBAL (t)); + } case DELETE_EXPR: return delete_sanity diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ea3bd82..95c522f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2007-08-31 Douglas Gregor <doug.gregor@gmail.com> + + PR c++/32597 + * gcc/testsuite/g++.dg/cpp0x/variadic-new2.C: New. + * gcc/testsuite/g++.dg/cpp0x/variadic-new.C: New. + 2007-08-31 Tobias Burnus <burnus@net-b.de> PR fortran/33232 diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-new.C b/gcc/testsuite/g++.dg/cpp0x/variadic-new.C new file mode 100644 index 0000000..8690527 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-new.C @@ -0,0 +1,19 @@ +// { dg-do "run" } +// { dg-options "-std=c++0x" } +// Contributed by Peter Dimov +// PR c++/32597 +#include <assert.h> +#include <new> + +int k = 5; + +template< class... Args > void f( Args... args ) +{ + new( &k ) int( args... ); +} + +int main() +{ + f(); + assert( k == 0 ); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-new2.C b/gcc/testsuite/g++.dg/cpp0x/variadic-new2.C new file mode 100644 index 0000000..a40f96e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-new2.C @@ -0,0 +1,24 @@ +// { dg-do "run" } +// { dg-options "-std=c++0x" } +// PR c++/32597 +#include <assert.h> +#include <new> + +template< class... Args > void f( Args... args ) +{ + { + int x = 17; + (void)x; + } + + { + int y(args...); + assert(y == 0); + } + +} + +int main() +{ + f(); +} |