Message ID | 1548434902-64282-1-git-send-email-dmalcolm@redhat.com |
---|---|
State | New |
Headers | show |
Series | C++ concepts: fix ICE with requires on dtors (PR c++/89036) | expand |
On 1/25/19 8:48 AM, David Malcolm wrote: > 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) Yes. A more sensible example would have 'true' and 'false' replaced by something determined from the template parms. > > Nathan introduced this assertion as part of: > > ca9219bf18c68a001d62ecb981bc9176b0feaf12 (aka r251340): > 2017-08-24 Nathan Sidwell <nathan@acm.org> > Conversion operators kept on single overload set I'd just drop the assert at this point. nathan
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) {} +};