On Wed, Jan 18, 2017 at 1:25 PM, Nathan Sidwell <nat...@acm.org> wrote:
> I've figured out what's happening here.  Just not sure of the most prudent
> way to fix it.
>
> struct no_destr {
>   no_destr() = default;
>
> protected:
>   ~no_destr() = default;
> };
>
> void *Foo ()
> {
>   return new no_destr ();
> }
>
> no_destr is a type for which the default ctor is not DECL_ARTIFICIAL, but
> is_trivial is true.  type_build_ctor_call returns true because of that.
>
> After parsing 'no_destr ()' part of the new expr, we're inside build_new_1,
> which because it's an explicit_value_init, we end up doing:
>               /* Something like `new int()'.  */
>               tree val = build_value_init (type, complain);
>
> build_value_init ends up in build_over_call at:
>  else if (!DECL_DELETED_FN (fn)
>            && trivial_fn_p (fn))
>     {
>       ...
>       else if (default_ctor_p (fn))
>         {
>           if (is_dummy_object (argarray[0]))
>             return force_target_expr (DECL_CONTEXT (fn), void_node,
> complain);
>
> and force_target_expr ends up (via build_target_expr) with trying to build a
> clean up for the object.  Poof!
>
> We need to tell that force_target_expr to not create a cleanup. Choices are
> 1) augment tf_subst flags to add such a flag. (somewhat icky, but simple)
> 2) a new force_target_expr_nocleanup routine, wrapping things appropriately.
>
> thoughts?

Ugh.

I suppose adding a tsubst flag isn't too horrible.  But then we also
need to audit other uses of build_value_init to decide whether they
should build a cleanup or not.

Jason

Reply via email to