On 01/23/2017 05:01 PM, Jason Merrill wrote:
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.
Not too ugly, I guess. Looking at the other calls that end up at build_target_expr, the only one I found that looked like it might need it is also in call.c:
if (is_dummy_object (fa)) { if (TREE_CODE (arg) == TARGET_EXPR) return arg; else if (trivial) return force_target_expr (DECL_CONTEXT (fn), arg, complain); but I convinced myself it didn't. ok? nathan -- Nathan Sidwell
2017-01-24 Nathan Sidwell <nat...@acm.org> PR c++/78469 - defaulted ctor and inaccessible dtor * cp-tree.h (tsubst_flags): Add tf_no_cleanup. * call.c (build-over_call): Pass tf_no_cleanup for ctor in new-expr. * tree.c (build_target_expr): Check tf_no_cleanup. PR c++/78469 * g++.dg/cpp0x/pr78469.C: New. Index: cp/call.c =================================================================== --- cp/call.c (revision 244869) +++ cp/call.c (working copy) @@ -8055,7 +8055,8 @@ build_over_call (struct z_candidate *can else if (default_ctor_p (fn)) { if (is_dummy_object (argarray[0])) - return force_target_expr (DECL_CONTEXT (fn), void_node, complain); + return force_target_expr (DECL_CONTEXT (fn), void_node, + complain | tf_no_cleanup); else return cp_build_indirect_ref (argarray[0], RO_NULL, complain); } Index: cp/cp-tree.h =================================================================== --- cp/cp-tree.h (revision 244869) +++ cp/cp-tree.h (working copy) @@ -4786,6 +4786,8 @@ enum tsubst_flags { substitution in fn_type_unification. */ tf_fndecl_type = 1 << 9, /* Substituting the type of a function declaration. */ + tf_no_cleanup = 1 << 10, /* Do not build a cleanup + (build_target_expr and friends) */ /* Convenient substitution flags combinations. */ tf_warning_or_error = tf_warning | tf_error }; Index: cp/tree.c =================================================================== --- cp/tree.c (revision 244869) +++ cp/tree.c (working copy) @@ -404,9 +404,15 @@ build_target_expr (tree decl, tree value || useless_type_conversion_p (TREE_TYPE (decl), TREE_TYPE (value))); - t = cxx_maybe_build_cleanup (decl, complain); - if (t == error_mark_node) - return error_mark_node; + if (complain & tf_no_cleanup) + /* The caller is building a new-expr and does not need a cleanup. */ + t = NULL_TREE; + else + { + t = cxx_maybe_build_cleanup (decl, complain); + if (t == error_mark_node) + return error_mark_node; + } t = build4 (TARGET_EXPR, type, decl, value, t, NULL_TREE); if (EXPR_HAS_LOCATION (value)) SET_EXPR_LOCATION (t, EXPR_LOCATION (value)); Index: testsuite/g++.dg/cpp0x/pr78469.C =================================================================== --- testsuite/g++.dg/cpp0x/pr78469.C (revision 0) +++ testsuite/g++.dg/cpp0x/pr78469.C (working copy) @@ -0,0 +1,14 @@ +// { dg-do compile { target c++11 } } +// PR78469, bogus error about inaccessible dtor. + +struct no_destr { + no_destr() = default; + +protected: + ~no_destr() = default; +}; + +void *Foo () +{ + return new no_destr (); +}