PR c++/89036 reports an ICE due to this assertion failing 1136 /* A class should never have more than one destructor. */ 1137 gcc_assert (!current_fns || via_using || !DECL_DESTRUCTOR_P (method));
on this template with a pair of dtors, with mutually exclusive "requires" clauses: template<typename T> struct Y { ~Y() requires(true) = default; ~Y() requires(false) {} }; (is this valid? my knowledge of this part of C++ is fairly hazy) Nathan introduced this assertion as part of: ca9219bf18c68a001d62ecb981bc9176b0feaf12 (aka r251340): 2017-08-24 Nathan Sidwell <nat...@acm.org> Conversion operators kept on single overload set which, amongst other changes to add_method had this: /* A class should never have more than one destructor. */ - if (current_fns && DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (method)) - return false; + gcc_assert (!current_fns || !DECL_DESTRUCTOR_P (method)); The following patch generalizes the assertion to allow for multiple dtors if they have "requires" clauses. (I already generalized the assertion in another way in r268041 to fix PR c++/88699; alternatively, is this too much like whack-a-mole, and would dropping the assertion altogether be better?) Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. OK for trunk? gcc/cp/ChangeLog: PR c++/89036 * class.c (add_method): Generalize assertion to allow for multiple dtors if they have "requires" clauses. gcc/testsuite/ChangeLog: PR c++/89036 * g++.dg/concepts/pr89036.C: New test. --- gcc/cp/class.c | 11 +++++++++-- gcc/testsuite/g++.dg/concepts/pr89036.C | 8 ++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/concepts/pr89036.C diff --git a/gcc/cp/class.c b/gcc/cp/class.c index e8773c2..fb46f92 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -1133,8 +1133,15 @@ add_method (tree type, tree method, bool via_using) } } - /* A class should never have more than one destructor. */ - gcc_assert (!current_fns || via_using || !DECL_DESTRUCTOR_P (method)); + /* A class should never have more than one destructor... */ + gcc_assert (!current_fns + || via_using + || !DECL_DESTRUCTOR_P (method) + /* ...unless the destructors are constrained by "requires" + clauses. */ + || (flag_concepts + && get_constraints (method) + && CI_DECLARATOR_REQS (get_constraints (method)))); current_fns = ovl_insert (method, current_fns, via_using); diff --git a/gcc/testsuite/g++.dg/concepts/pr89036.C b/gcc/testsuite/g++.dg/concepts/pr89036.C new file mode 100644 index 0000000..f83ef8b --- /dev/null +++ b/gcc/testsuite/g++.dg/concepts/pr89036.C @@ -0,0 +1,8 @@ +// { dg-do compile { target c++11 } } +// { dg-options "-fconcepts" } + +template<typename T> +struct Y { + ~Y() requires(true) = default; + ~Y() requires(false) {} +}; -- 1.8.5.3