aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2017-01-24 19:29:44 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2017-01-24 19:29:44 +0000
commit1d7bc790d78f6913a72061e526a4a89e083826a4 (patch)
tree278e354fb8fcdc27cfba50fc6e4e58fb037f44d1
parent3e4b91f275a6fb8f6466f1ab8c9f24e3d2abf13f (diff)
downloadgcc-1d7bc790d78f6913a72061e526a4a89e083826a4.zip
gcc-1d7bc790d78f6913a72061e526a4a89e083826a4.tar.gz
gcc-1d7bc790d78f6913a72061e526a4a89e083826a4.tar.bz2
PR c++/78469 - defaulted ctor and inaccessible dtor
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. From-SVN: r244882
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/init.c6
-rw-r--r--gcc/cp/tree.c12
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr78469.C14
6 files changed, 37 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5b86344..5010aeb 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,10 @@
2017-01-24 Nathan Sidwell <nathan@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++/79118 - anon-members and constexpr
* constexpr.c (cx_check_missing_mem_inits): Caller passes type not
ctor decl. Recursively check anonymous members.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index b4c4dfa..57833c5 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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
};
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 15388b1..de43d81 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -3262,8 +3262,10 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
}
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);
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 25927ae..6fbc99e 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -404,9 +404,15 @@ build_target_expr (tree decl, tree value, tsubst_flags_t complain)
|| 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));
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index cdd4e1b..01df86d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2017-01-24 Nathan Sidwell <nathan@acm.org>
+ PR c++/78469
+ * g++.dg/cpp0x/pr78469.C: New.
+
PR c++/79118
* g++.dg/cpp0x/pr79118.C: New.
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr78469.C b/gcc/testsuite/g++.dg/cpp0x/pr78469.C
new file mode 100644
index 0000000..dd5ff84
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr78469.C
@@ -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 ();
+}