re PR c++/15172 (Copy constructor optimization in aggregate initialization)
PR c++/15172 * typeck2.c (store_init_value): Use split_nonconstant_init even for types that require construction. PR c++/15172 * g++.dg/init/aggr2.C: New test. From-SVN: r89922
This commit is contained in:
parent
8d511b9097
commit
80439563c5
4 changed files with 66 additions and 17 deletions
|
@ -1,3 +1,9 @@
|
|||
2004-10-31 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/15172
|
||||
* typeck2.c (store_init_value): Use split_nonconstant_init even
|
||||
for types that require construction.
|
||||
|
||||
1004-10-28 Matt Austern <austern@apple.com>
|
||||
|
||||
PR c++/17542
|
||||
|
|
|
@ -604,24 +604,16 @@ store_init_value (tree decl, tree init)
|
|||
|
||||
/* Digest the specified initializer into an expression. */
|
||||
value = digest_init (type, init, (tree *) 0);
|
||||
|
||||
/* Store the expression if valid; else report error. */
|
||||
|
||||
if (TREE_CODE (value) == ERROR_MARK)
|
||||
;
|
||||
/* Other code expects that initializers for objects of types that need
|
||||
constructing never make it into DECL_INITIAL, and passes 'init' to
|
||||
build_aggr_init without checking DECL_INITIAL. So just return. */
|
||||
else if (TYPE_NEEDS_CONSTRUCTING (type))
|
||||
return build2 (INIT_EXPR, type, decl, value);
|
||||
else if (TREE_STATIC (decl)
|
||||
&& (TREE_SIDE_EFFECTS (value)
|
||||
|| ! initializer_constant_valid_p (value, TREE_TYPE (value))))
|
||||
/* If the initializer is not a constant, fill in DECL_INITIAL with
|
||||
the bits that are constant, and then return an expression that
|
||||
will perform the dynamic initialization. */
|
||||
if (value != error_mark_node
|
||||
&& (TREE_SIDE_EFFECTS (value)
|
||||
|| ! initializer_constant_valid_p (value, TREE_TYPE (value))))
|
||||
return split_nonconstant_init (decl, value);
|
||||
|
||||
/* Store the VALUE in DECL_INITIAL. If we're building a
|
||||
statement-tree we will actually expand the initialization later
|
||||
when we output this function. */
|
||||
/* If the value is a constant, just put it in DECL_INITIAL. If DECL
|
||||
is an automatic variable, the middle end will turn this into a
|
||||
dynamic initialization later. */
|
||||
DECL_INITIAL (decl) = value;
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2004-10-31 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/15172
|
||||
* g++.dg/init/aggr2.C: New test.
|
||||
|
||||
2004-10-30 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
* objc.dg/local-decl-1.m: New test.
|
||||
|
|
46
gcc/testsuite/g++.dg/init/aggr2.C
Normal file
46
gcc/testsuite/g++.dg/init/aggr2.C
Normal file
|
@ -0,0 +1,46 @@
|
|||
// PR c++/15172
|
||||
// { dg-do run }
|
||||
|
||||
extern "C" int printf (const char *, ...);
|
||||
extern "C" void abort ();
|
||||
|
||||
struct A {
|
||||
static A* p;
|
||||
|
||||
A() { p = this; }
|
||||
A(const A&);
|
||||
~A() { if (this != p) abort (); }
|
||||
void print () { }
|
||||
};
|
||||
|
||||
A* A::p;
|
||||
|
||||
struct B {
|
||||
A a;
|
||||
};
|
||||
|
||||
B b = { A () };
|
||||
|
||||
struct A2 {
|
||||
static A2* p;
|
||||
|
||||
A2() { p = this; }
|
||||
A2(const A2&);
|
||||
~A2() { if (this != p) abort (); }
|
||||
void print () { }
|
||||
};
|
||||
|
||||
A2* A2::p;
|
||||
|
||||
struct B2 {
|
||||
A2 a2;
|
||||
};
|
||||
|
||||
int main () {
|
||||
b.a.print ();
|
||||
{
|
||||
B2 b2 = { A2() };
|
||||
b2.a2.print ();
|
||||
}
|
||||
}
|
||||
|
Loading…
Add table
Reference in a new issue