Commit 844ae01d by Jason Merrill Committed by Jason Merrill

re PR c++/11309 (Testsuite failures in g++.dg/expr/anew1.C (and anew2.C anew3.C anew4.c))

        PR c++/11309
        * tree.c (build_aggr_init_expr): Split out...
        (build_cplus_new): ...from here.
        (stabilize_init): Don't mess with AGGR_INIT_EXPR either.
        * init.c (build_new_1): new T() means value-initialization,
        not default-initialization.
        (build_vec_init): Likewise.
        (build_value_init_1): Use build_aggr_init_expr.

From-SVN: r138355
parent 636b71b9
2008-07-31 Jason Merrill <jason@redhat.com>
PR c++/11309
* tree.c (build_aggr_init_expr): Split out...
(build_cplus_new): ...from here.
(stabilize_init): Don't mess with AGGR_INIT_EXPR either.
* init.c (build_new_1): new T() means value-initialization,
not default-initialization.
(build_vec_init): Likewise.
(build_value_init_1): Use build_aggr_init_expr.
2008-07-30 Dodji Seketeli <dseketel@redhat.com>
PR c++/36767
......
......@@ -4742,6 +4742,7 @@ extern tree build_min_nt (enum tree_code, ...);
extern tree build_min_non_dep (enum tree_code, tree, ...);
extern tree build_min_non_dep_call_list (tree, tree, tree);
extern tree build_cplus_new (tree, tree);
extern tree build_aggr_init_expr (tree, tree);
extern tree get_target_expr (tree);
extern tree build_cplus_array_type (tree, tree);
extern tree build_array_of_n_type (tree, int);
......
......@@ -347,7 +347,7 @@ build_value_init_1 (tree type, bool have_ctor)
if (CLASS_TYPE_P (type))
{
if (type_has_user_provided_constructor (type) && !have_ctor)
return build_cplus_new
return build_aggr_init_expr
(type,
build_special_member_call (NULL_TREE, complete_ctor_identifier,
NULL_TREE, type, LOOKUP_NORMAL,
......@@ -511,7 +511,7 @@ perform_member_init (tree member, tree init)
{
/* Initialization of one array from another. */
finish_expr_stmt (build_vec_init (decl, NULL_TREE, TREE_VALUE (init),
/*explicit_default_init_p=*/false,
/*explicit_value_init_p=*/false,
/* from_array=*/1,
tf_warning_or_error));
}
......@@ -1286,7 +1286,7 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain)
if (itype && cp_type_quals (itype) != TYPE_UNQUALIFIED)
itype = TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype);
stmt_expr = build_vec_init (exp, NULL_TREE, init,
/*explicit_default_init_p=*/false,
/*explicit_value_init_p=*/false,
itype && same_type_p (itype,
TREE_TYPE (exp)),
complain);
......@@ -2154,19 +2154,19 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
if (is_initialized)
{
bool stable;
bool explicit_value_init_p = false;
init_expr = cp_build_indirect_ref (data_addr, NULL, complain);
if (array_p)
if (init == void_zero_node)
{
bool explicit_default_init_p = false;
init = NULL_TREE;
explicit_value_init_p = true;
}
if (init == void_zero_node)
{
init = NULL_TREE;
explicit_default_init_p = true;
}
else if (init)
if (array_p)
{
if (init)
{
if (complain & tf_error)
permerror ("ISO C++ forbids initialization in array new");
......@@ -2179,7 +2179,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
integer_one_node,
complain),
init,
explicit_default_init_p,
explicit_value_init_p,
/*from_array=*/0,
complain);
......@@ -2190,17 +2190,19 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
}
else
{
if (init == void_zero_node)
init = build_default_init (full_type, nelts);
if (TYPE_NEEDS_CONSTRUCTING (type))
if (TYPE_NEEDS_CONSTRUCTING (type) && !explicit_value_init_p)
{
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 (explicit_value_init_p)
{
/* Something like `new int()'. */
init_expr = build2 (INIT_EXPR, full_type,
init_expr, build_value_init (full_type));
}
else
{
......@@ -2216,8 +2218,8 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
init_expr = cp_build_modify_expr (init_expr, INIT_EXPR, init,
complain);
stable = stabilize_init (init_expr, &init_preeval_expr);
}
stable = stabilize_init (init_expr, &init_preeval_expr);
}
if (init_expr == error_mark_node)
......@@ -2662,8 +2664,8 @@ get_temp_regvar (tree type, tree init)
INIT is the (possibly NULL) initializer.
If EXPLICIT_DEFAULT_INIT_P is true, then INIT must be NULL. All
elements in the array are default-initialized.
If EXPLICIT_VALUE_INIT_P is true, then INIT must be NULL. All
elements in the array are value-initialized.
FROM_ARRAY is 0 if we should init everything with INIT
(i.e., every element initialized from INIT).
......@@ -2674,7 +2676,7 @@ get_temp_regvar (tree type, tree init)
tree
build_vec_init (tree base, tree maxindex, tree init,
bool explicit_default_init_p,
bool explicit_value_init_p,
int from_array, tsubst_flags_t complain)
{
tree rval;
......@@ -2704,7 +2706,7 @@ build_vec_init (tree base, tree maxindex, tree init,
if (maxindex == NULL_TREE || maxindex == error_mark_node)
return error_mark_node;
if (explicit_default_init_p)
if (explicit_value_init_p)
gcc_assert (!init);
inner_elt_type = strip_array_types (atype);
......@@ -2840,7 +2842,7 @@ build_vec_init (tree base, tree maxindex, tree init,
We do need to keep going if we're copying an array. */
if (from_array
|| ((TYPE_NEEDS_CONSTRUCTING (type) || explicit_default_init_p)
|| ((TYPE_NEEDS_CONSTRUCTING (type) || explicit_value_init_p)
&& ! (host_integerp (maxindex, 0)
&& (num_initialized_elts
== tree_low_cst (maxindex, 0) + 1))))
......@@ -2889,17 +2891,17 @@ build_vec_init (tree base, tree maxindex, tree init,
("cannot initialize multi-dimensional array with initializer");
elt_init = build_vec_init (build1 (INDIRECT_REF, type, base),
0, 0,
/*explicit_default_init_p=*/false,
explicit_value_init_p,
0, complain);
}
else if (!TYPE_NEEDS_CONSTRUCTING (type))
elt_init = (cp_build_modify_expr
(to, INIT_EXPR,
build_zero_init (type, size_one_node,
/*static_storage_p=*/false),
complain));
else if (explicit_value_init_p)
elt_init = build2 (INIT_EXPR, type, to,
build_value_init (type));
else
elt_init = build_aggr_init (to, init, 0, complain);
{
gcc_assert (TYPE_NEEDS_CONSTRUCTING (type));
elt_init = build_aggr_init (to, init, 0, complain);
}
current_stmt_tree ()->stmts_are_full_exprs_p = 1;
finish_expr_stmt (elt_init);
......
......@@ -339,15 +339,17 @@ build_aggr_init_array (tree return_type, tree fn, tree slot, int nargs,
}
/* INIT is a CALL_EXPR or AGGR_INIT_EXPR which needs info about its
target. TYPE is the type that this initialization should appear to
have.
target. TYPE is the type to be initialized.
Build an encapsulation of the initialization to perform
and return it so that it can be processed by language-independent
and language-specific expression expanders. */
Build an AGGR_INIT_EXPR to represent the initialization. This function
differs from build_cplus_new in that an AGGR_INIT_EXPR can only be used
to initialize another object, whereas a TARGET_EXPR can either
initialize another object or create its own temporary object, and as a
result building up a TARGET_EXPR requires that the type's destructor be
callable. */
tree
build_cplus_new (tree type, tree init)
build_aggr_init_expr (tree type, tree init)
{
tree fn;
tree slot;
......@@ -369,8 +371,6 @@ build_cplus_new (tree type, tree init)
&& TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
&& DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0)));
slot = build_local_temp (type);
/* We split the CALL_EXPR into its function and its arguments here.
Then, in expand_expr, we put them back together. The reason for
this is that this expression might be a default argument
......@@ -384,6 +384,8 @@ build_cplus_new (tree type, tree init)
type, don't mess with AGGR_INIT_EXPR. */
if (is_ctor || TREE_ADDRESSABLE (type))
{
slot = build_local_temp (type);
if (TREE_CODE(init) == CALL_EXPR)
rval = build_aggr_init_array (void_type_node, fn, slot,
call_expr_nargs (init),
......@@ -398,6 +400,30 @@ build_cplus_new (tree type, tree init)
else
rval = init;
return rval;
}
/* INIT is a CALL_EXPR or AGGR_INIT_EXPR which needs info about its
target. TYPE is the type that this initialization should appear to
have.
Build an encapsulation of the initialization to perform
and return it so that it can be processed by language-independent
and language-specific expression expanders. */
tree
build_cplus_new (tree type, tree init)
{
tree rval = build_aggr_init_expr (type, init);
tree slot;
if (TREE_CODE (rval) == AGGR_INIT_EXPR)
slot = AGGR_INIT_EXPR_SLOT (rval);
else if (TREE_CODE (rval) == CALL_EXPR)
slot = build_local_temp (type);
else
return rval;
rval = build_target_expr (slot, rval);
TARGET_EXPR_IMPLICIT_P (rval) = 1;
......@@ -2687,7 +2713,8 @@ stabilize_init (tree init, tree *initp)
return true;
if (TREE_CODE (t) == INIT_EXPR
&& TREE_CODE (TREE_OPERAND (t, 1)) != TARGET_EXPR)
&& TREE_CODE (TREE_OPERAND (t, 1)) != TARGET_EXPR
&& TREE_CODE (TREE_OPERAND (t, 1)) != AGGR_INIT_EXPR)
{
TREE_OPERAND (t, 1) = stabilize_expr (TREE_OPERAND (t, 1), initp);
return true;
......
......@@ -6114,7 +6114,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
from_array = TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE
? 1 + (modifycode != INIT_EXPR): 0;
return build_vec_init (lhs, NULL_TREE, newrhs,
/*explicit_default_init_p=*/false,
/*explicit_value_init_p=*/false,
from_array, complain);
}
......
// { dg-do run { xfail *-*-* } }
// XFAILed until PR2123 is fixed
// { dg-do run }
// PR 11228: array operator new, with zero-initialization and a variable sized array.
// Regression test for PR
// Author: Matt Austern <austern@apple.com>
......
// Testcase for value-initialization in new-expressions.
// { dg-do run }
#include <stdlib.h>
#include <string.h>
// Make sure that we return memory that isn't already set to 0.
void *operator new(size_t s)
{
void *p = malloc (s);
memset (p, 42, s);
return p;
}
struct A { A() {} ~A() {} };
struct B { A a; int i; };
int main()
{
B *p = new B();
if (p->i != 0)
abort();
p = new B[2]();
if (p[0].i != 0 || p[1].i != 0)
abort();
B(*p2)[2] = new B[2][2]();
if (p2[0][0].i != 0 || p2[0][1].i != 0)
abort();
}
......@@ -4,10 +4,10 @@
int main() {
int i;
void* operator new(unsigned s, int* p);
void* operator new(__SIZE_TYPE__ s, int* p);
int* e = new(&i) int; // { dg-error "no matching function" }
int* f = new int;
return 0;
}
// { dg-excess-errors "operator new" }
// { dg-error "candidate" "" { target *-*-* } 0 }
......@@ -20,5 +20,5 @@ double foo (void)
return v.a[2];
}
/* { dg-final { scan-tree-dump "Replaced .*iftmp.* != 0B. with .1" "forwprop1" } } */
/* { dg-final { scan-tree-dump "Replaced .* != 0B. with .1" "forwprop1" } } */
/* { dg-final { cleanup-tree-dump "forwprop1" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment