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.
Tested x86_64-linux.
Thanks, Paolo.
////////////////////////
/cp
2019-02-25 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/89488
* method.c (process_subob_fn): When maybe_instantiate_noexcept returns
false don't call merge_exception_specifiers.
/testsuite
2019-02-25 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/89488
* g++.dg/cpp0x/nsdmi15.C: New.
Index: cp/method.c
===================================================================
--- cp/method.c (revision 269187)
+++ cp/method.c (working copy)
@@ -1254,9 +1254,8 @@ process_subob_fn (tree fn, tree *spec_p, bool *tri
return;
}
- if (spec_p)
+ if (spec_p && maybe_instantiate_noexcept (fn))
{
- maybe_instantiate_noexcept (fn);
tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
*spec_p = merge_exception_specifiers (*spec_p, raises);
}
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|cannot convert" }
+ } fx;
+};