On 01/24/2017 11:36 AM, Jason Merrill wrote:
This is the wrong place for this; we don't know at this point whether we're in a new-expression or actually creating a temporary. I think we want to add this flag in the call to build_value_init from build_new_1. And look at other calls to build_value_init to see if they want it as well.
Oh yeah, need to set the flag further up the all chain. I couldn't see other build_value_init calls that needed it set.
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. * init.c (build_new_1): Pass tf_no_cleanup to build_value_init. * tree.c (build_target_expr): Check tf_no_cleanup. PR c++/78469 * g++.dg/cpp0x/pr78469.C: New. Index: cp/cp-tree.h =================================================================== --- cp/cp-tree.h (revision 244880) +++ 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/init.c =================================================================== --- cp/init.c (revision 244880) +++ cp/init.c (working copy) @@ -3262,8 +3262,10 @@ build_new_1 (vec<tree, va_gc> **placemen } else if (explicit_value_init_p) { - /* Something like `new int()'. */ - tree val = build_value_init (type, complain); + /* Something like `new int()'. NO_CLEANUP is needed so + we don't try and build a (possibly ill-formed) + destructor. */ + tree val = build_value_init (type, complain | tf_no_cleanup); if (val == error_mark_node) return error_mark_node; init_expr = build2 (INIT_EXPR, type, init_expr, val); Index: cp/tree.c =================================================================== --- cp/tree.c (revision 244880) +++ 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 (); +}