aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/init.c3
-rw-r--r--gcc/cp/pt.c43
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/variadic-new.C19
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/variadic-new2.C24
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();
+}