Hi,

On 26/02/19 15:28, Jason Merrill wrote:
On 2/25/19 10:27 AM, Paolo Carlini wrote:
Hi,

this error recovery regression has to do with the recent changes committed by Jason for c++/88368. What happens is that maybe_instantiate_noexcept fails the hard way, thus, toward the end of the function, doesn't update TREE_TYPE (fn) and just returns false. process_subob_fn doesn't notice and proceeds to call merge_exception_specifiers anyway where of course the gcc_assert (!DEFERRED_NOEXCEPT_SPEC_P (add)) triggers, because maybe_instantiate_noexcept has not done its normal job. To improve error-recovery I think we can simply leave *spec_p alone in such cases, because we would merge the *spec_p with a TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)) where TREE_TYPE (fn) has not been normally computed. I tried a few other things which prima facie looked sensible but nothing else worked - eg, returning false from maybe_instantiate_noexcept and also updating TREE_TYPE (fn) to a noexcept_false_spec variant causes regressions exactly for the testcases of c++/88368.

If maybe_instantiate_noexcept returns false, I think we should set *spec_p to error_mark_node.

Sure, that certainly works, I tested it a couple of days ago and I'm finishing testing the below now. The only difference is that during error-recovery 'zl ()' is seen as seriously broken and we don't give the second,  "cannot convert", error message, which we used to give.

Thanks, Paolo.

/////////////////////

Index: cp/method.c
===================================================================
--- cp/method.c (revision 269187)
+++ cp/method.c (working copy)
@@ -1256,9 +1256,13 @@ process_subob_fn (tree fn, tree *spec_p, bool *tri
 
   if (spec_p)
     {
-      maybe_instantiate_noexcept (fn);
-      tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
-      *spec_p = merge_exception_specifiers (*spec_p, raises);
+      if (!maybe_instantiate_noexcept (fn))
+       *spec_p = error_mark_node;
+      else
+       {
+         tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
+         *spec_p = merge_exception_specifiers (*spec_p, raises);
+       }
     }
 
   if (!trivial_fn_p (fn) && !dtor_from_ctor)
Index: testsuite/g++.dg/cpp0x/nsdmi15.C
===================================================================
--- testsuite/g++.dg/cpp0x/nsdmi15.C    (nonexistent)
+++ testsuite/g++.dg/cpp0x/nsdmi15.C    (working copy)
@@ -0,0 +1,8 @@
+// PR c++/89488
+// { dg-do compile { target c++11 } }
+
+struct zl {
+  struct {
+    int x2 = zl ();  // { dg-error "default member" }
+  } fx;
+};

Reply via email to