diff mbox series

[C++] PR c++/88368 - wrong 'use of deleted function'

Message ID 20190220020003.6375-1-jason@redhat.com
State New
Headers show
Series [C++] PR c++/88368 - wrong 'use of deleted function' | expand

Commit Message

Jason Merrill Feb. 20, 2019, 2 a.m. UTC
Since my patch for 81359 allowed us to signal failure on return from
maybe_instantiate_noexcept, we no longer need to turn an error into
noexcept(false).  We also need to handle NSDMI instantiation errors under
synthesized_method_walk.  This change caused some instantiation context
notes to be lost in the testsuite, so I added push_tinst_level to
get_defaulted_eh_spec to restore that context.

Tested x86_64-pc-linux-gnu, applying to trunk.

	* method.c (walk_field_subobs): Remember errors from get_nsdmi.
	(get_defaulted_eh_spec): Call push_tinst_level.
	* pt.c (maybe_instantiate_noexcept): Keep error_mark_node.
	* typeck2.c (merge_exception_specifiers): Handle error_mark_node.
---
 gcc/cp/method.c                              | 10 +++++++++-
 gcc/cp/pt.c                                  |  2 --
 gcc/cp/typeck2.c                             |  3 +++
 gcc/testsuite/g++.dg/cpp0x/nsdmi3.C          |  3 ++-
 gcc/testsuite/g++.dg/ext/is_constructible3.C | 17 +++++++++++++++++
 gcc/cp/ChangeLog                             |  8 ++++++++
 6 files changed, 39 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_constructible3.C


base-commit: cfa86c5ebc839435491f6ab8f541eb44f02d6849
diff mbox series

Patch

diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index a5f2304d49c..6e0df68273e 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1367,7 +1367,10 @@  walk_field_subobs (tree fields, special_function_kind sfk, tree fnname,
 	      if (spec_p)
 		{
 		  tree nsdmi = get_nsdmi (field, /*ctor*/false, complain);
-		  if (!expr_noexcept_p (nsdmi, complain))
+		  if (nsdmi == error_mark_node)
+		    *spec_p = error_mark_node;
+		  else if (*spec_p != error_mark_node
+			   && !expr_noexcept_p (nsdmi, complain))
 		    *spec_p = noexcept_false_spec;
 		}
 	      /* Don't do the normal processing.  */
@@ -1753,8 +1756,13 @@  get_defaulted_eh_spec (tree decl, tsubst_flags_t complain)
   if (SFK_DTOR_P (sfk) && DECL_VIRTUAL_P (decl))
     /* We have to examine virtual bases even if abstract.  */
     sfk = sfk_virtual_destructor;
+  bool pushed = false;
+  if (CLASSTYPE_TEMPLATE_INSTANTIATION (ctype))
+    pushed = push_tinst_level (decl);
   synthesized_method_walk (ctype, sfk, const_p, &spec, NULL, NULL,
 			   NULL, diag, &inh, parms);
+  if (pushed)
+    pop_tinst_level ();
   return spec;
 }
 
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index d8be92ddca4..a69a17ad3b2 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -24199,8 +24199,6 @@  maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain)
 	  pop_deferring_access_checks ();
 	  pop_access_scope (fn);
 	  pop_tinst_level ();
-	  if (spec == error_mark_node)
-	    spec = noexcept_false_spec;
 	}
       else
 	spec = noexcept_false_spec;
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index ac2c253196b..4e4b1f03b7c 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -2363,6 +2363,9 @@  merge_exception_specifiers (tree list, tree add)
 {
   tree noex, orig_list;
 
+  if (list == error_mark_node || add == error_mark_node)
+    return error_mark_node;
+
   /* No exception-specifier or noexcept(false) are less strict than
      anything else.  Prefer the newer variant (LIST).  */
   if (!list || list == noexcept_false_spec)
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi3.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi3.C
index d2e74392487..8276eab8f80 100644
--- a/gcc/testsuite/g++.dg/cpp0x/nsdmi3.C
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi3.C
@@ -13,6 +13,7 @@  struct B
   A a3 = { 3 };			// { dg-error "explicit" }
 };
 
-constexpr B b;			// { dg-error "B::B" }
+constexpr B b;
 
+// { dg-prune-output "B::B. is not usable" }
 // { dg-prune-output "B::a1" }
diff --git a/gcc/testsuite/g++.dg/ext/is_constructible3.C b/gcc/testsuite/g++.dg/ext/is_constructible3.C
new file mode 100644
index 00000000000..c7c58746cd0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_constructible3.C
@@ -0,0 +1,17 @@ 
+// PR c++/88368
+// { dg-do compile { target c++11 } }
+
+struct A {
+
+  struct B {
+    int I = 1;
+    B() = default;
+  };
+
+  static constexpr bool v = __is_constructible (B);
+
+};
+
+void print()  {
+  A::B BB;
+}
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 9c42190f04a..3fe0cedb0e3 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@ 
+2019-02-19  Jason Merrill  <jason@redhat.com>
+
+	PR c++/88368 - wrong 'use of deleted function'
+	* method.c (walk_field_subobs): Remember errors from get_nsdmi.
+	(get_defaulted_eh_spec): Call push_tinst_level.
+	* pt.c (maybe_instantiate_noexcept): Keep error_mark_node.
+	* typeck2.c (merge_exception_specifiers): Handle error_mark_node.
+
 2019-02-19  Chung-Lin Tang <cltang@codesourcery.com>
 
 	PR c/87924