PR c++/78469 - defaulted ctor and inaccessible dtor
authorNathan Sidwell <nathan@acm.org>
Tue, 24 Jan 2017 19:29:44 +0000 (19:29 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Tue, 24 Jan 2017 19:29:44 +0000 (19:29 +0000)
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

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/init.c
gcc/cp/tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/pr78469.C [new file with mode: 0644]

index 5b863446b8973ff950f8852bbabafd37fdb6fc0b..5010aeb1303053e4e050befdd5f16488bbf91929 100644 (file)
@@ -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.
index b4c4dfa2f6b58a1078282ee4942ed2c45b0bcffe..57833c5884cf9eb8fff39b63711a66a7f4c6735d 100644 (file)
@@ -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 15388b1426440a6b3093e0b238a26093fede28ce..de43d81ce30264bd0f119999072efde2c065a790 100644 (file)
@@ -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);
index 25927ae3b375bfdcee53f6b44536af5893c1aae9..6fbc99ee56b9088035a380ce645b6f7a98c44159 100644 (file)
@@ -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));
index cdd4e1b8a0482e113936bed3ac20b8bb4b8e405e..01df86dffd2d5fb0a9203fd62407a845b624c98a 100644 (file)
@@ -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 (file)
index 0000000..dd5ff84
--- /dev/null
@@ -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 ();
+}