This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFH: TARGET_EXPRs and value-initialization


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]