c++: ICE with late parsing of noexcept in nested class [PR98899]
authorMarek Polacek <polacek@redhat.com>
Tue, 2 Feb 2021 04:30:05 +0000 (23:30 -0500)
committerMarek Polacek <polacek@redhat.com>
Wed, 3 Feb 2021 14:44:18 +0000 (09:44 -0500)
commit25fdd0d6df44044a8b505e6fcd07270e2e279b06
tree511091a93cedd89ec505cbc85a5ec6213e00eec8
parent3535402e20118655b2ad4085a6e1d4f1b9c46e92
c++: ICE with late parsing of noexcept in nested class [PR98899]

Here we crash with a noexcept-specifier in a nested template class,
because my handling of such deferred-parse noexcept-specifiers was
gronked when we need to instantiate a DEFERRED_PARSE before it was
actually parsed at the end of the outermost class.

In

  struct S {
    template<class> struct B {
      B() noexcept(noexcept(x));
      int x;
    };
    struct A : B<int> {
      A() : B() {}
    };
  };

we call complete_type for B<int> which triggers tsubsting S::B<int>::B()
whose noexcept-specifier still contains a DEFERRED_PARSE.  The trick is
to stash such noexcept-specifiers into DEFPARSE_INSTANTIATIONS so that
we can replace it later when we've finally parsed all deferred
noexcept-specifiers.

In passing, fix missing usage of UNPARSED_NOEXCEPT_SPEC_P.

gcc/cp/ChangeLog:

PR c++/98899
* parser.c (cp_parser_class_specifier_1): Use any possible
DEFPARSE_INSTANTIATIONS to update DEFERRED_NOEXCEPT_PATTERN.
(cp_parser_save_noexcept): Initialize DEFPARSE_INSTANTIATIONS.
* pt.c (tsubst_exception_specification): Stash new_specs into
DEFPARSE_INSTANTIATIONS.
* tree.c (fixup_deferred_exception_variants): Use
UNPARSED_NOEXCEPT_SPEC_P.

gcc/testsuite/ChangeLog:

PR c++/98899
* g++.dg/cpp0x/noexcept65.C: New test.
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/tree.c
gcc/testsuite/g++.dg/cpp0x/noexcept65.C [new file with mode: 0644]