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