This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
RFH: TARGET_EXPRs and value-initialization
- From: Mark Mitchell <mark at codesourcery dot com>
- To: jason at redhat dot com
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Tue, 8 Jan 2008 14:30:52 -0800
- Subject: RFH: TARGET_EXPRs and value-initialization
- Reply-to: mark at codesourcery dot com
Jason --
I'm trying to fix PR c++/33916. This is essentially a request that we
implement TC1 value-initialization, which means, in particular, that
we zero-initialize classes before calling their default constructor,
if that default constructor is not user-declared.
I've tried;
ctor_call
= build_special_member_call (NULL_TREE,
complete_ctor_identifier,
NULL_TREE,
type, LOOKUP_NORMAL);
exp = build_cplus_new (type, ctor_call);
var = TARGET_EXPR_SLOT (exp);
/* Perform the zero-initialization. */
zero_init = build_zero_init (type,
/*nelts=*/NULL_TREE,
/*static_storage_p=*/false);
zero_init = build2 (INIT_EXPR, type, var, zero_init);
TARGET_EXPR_INITIAL (exp)
= build2 (COMPOUND_EXPR, void_type_node, zero_init,
TARGET_EXPR_INITIAL (exp));
return exp;
and:
/* Allocate the object. */
exp = force_target_expr (type, NULL_TREE);
var = TARGET_EXPR_SLOT (exp);
/* Perform the zero-initialization. */
zero_init = build_zero_init (type,
/*nelts=*/NULL_TREE,
/*static_storage_p=*/false);
zero_init = build2 (INIT_EXPR, type, var, zero_init);
/* Call the constructor. */
ctor_call
= build_special_member_call (TARGET_EXPR_SLOT (exp),
complete_ctor_identifier,
NULL_TREE,
type, LOOKUP_NORMAL);
TARGET_EXPR_INITIAL (exp)
= build2 (COMPOUND_EXPR, void_type_node, zero_init, ctor_call);
TARGET_EXPR_IMPLICIT_P (exp) = 1;
return exp;
But, in both cases, I get ICEs. In the first case, I get ICEs from
gimplification; something seems to eliminate the TARGET_EXPR, but not
then the zero-initialization is referring to a variable that doesn't
exist.
In the second case, the gimplifier ends up trying to copy classes that
have constructors when we have code like:
throw S();
It looks like the gimplifier doesn't want to smash the TARGET_EXPR
into the destination object and instead tries to do a copy.
We seem to be falling afoul of:
case TARGET_EXPR:
{
/* If we are initializing something from a TARGET_EXPR, strip the
TARGET_EXPR and initialize it directly, if possible. This can't
be done if the initializer is void, since that implies that the
temporary is set in some non-trivial way.
??? What about code that pulls out the temp and uses it
elsewhere? I think that such code never uses the TARGET_EXPR as
an initializer. If I'm wrong, we'll die because the temp won't
have any RTL. In that case, I guess we'll need to replace
references somehow. */
tree init = TARGET_EXPR_INITIAL (*from_p);
if (!VOID_TYPE_P (TREE_TYPE (init)))
{
*from_p = init;
ret = GS_OK;
}
in that in the first case we're pulling out the temporary variable,
and that in the second we have a VOID_TYPE_P initializer.
Do you have any good ideas about how to implement this code? Is it
representable in our current representation? The combination of
TARGET_EXPR, AGGR_INIT_EXPR, and gimplification is really making my
head hurt.
Thanks,
--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713