[gcc r10-8268] c++: Fix ICE with delayed parsing of noexcept-specifier [PR95562]

Marek Polacek mpolacek@gcc.gnu.org
Wed Jun 10 15:33:56 GMT 2020


https://gcc.gnu.org/g:977a173c196dc5ba5ac2e1b890083beb0451cf60

commit r10-8268-g977a173c196dc5ba5ac2e1b890083beb0451cf60
Author: Marek Polacek <polacek@redhat.com>
Date:   Wed Jun 10 10:49:08 2020 -0400

    c++: Fix ICE with delayed parsing of noexcept-specifier [PR95562]
    
    Here we ICE because a DEFERRED_PARSE expression leaked to tsubst_copy.
    We create these expressions for deferred noexcept-specifiers in
    cp_parser_save_noexcept; they are supposed to be re-parsed in
    cp_parser_late_noexcept_specifier.  In this case we never got around
    to re-parsing it because the noexcept-specifier was attached to a
    pointer to a function, not to a function declaration.  But we should
    not have delayed the parsing here in the first place; we already
    avoid delaying the parsing for alias-decls, typedefs, and friend
    function declarations.  (Clang++ also doesn't delay the parsing
    for pointers to function.)
    
    gcc/cp/ChangeLog:
    
            PR c++/95562
            * parser.c (cp_parser_direct_declarator): Clear
            CP_PARSER_FLAGS_DELAY_NOEXCEPT if the declarator kind is not
            cdk_id.
    
    gcc/testsuite/ChangeLog:
    
            PR c++/95562
            * g++.dg/cpp0x/noexcept60.C: New test.

Diff:
---
 gcc/cp/parser.c                         |  6 ++++++
 gcc/testsuite/g++.dg/cpp0x/noexcept60.C | 13 +++++++++++++
 2 files changed, 19 insertions(+)

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 4daec18a2e9..42d7b1c0336 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -21225,6 +21225,12 @@ cp_parser_direct_declarator (cp_parser* parser,
 		  ref_qual = cp_parser_ref_qualifier_opt (parser);
 		  /* Parse the tx-qualifier.  */
 		  tree tx_qual = cp_parser_tx_qualifier_opt (parser);
+
+		  /* If it turned out that this is e.g. a pointer to a
+		     function, we don't want to delay noexcept parsing.  */
+		  if (declarator == NULL || declarator->kind != cdk_id)
+		    flags &= ~CP_PARSER_FLAGS_DELAY_NOEXCEPT;
+
 		  /* And the exception-specification.  */
 		  exception_specification
 		    = cp_parser_exception_specification_opt (parser,
diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept60.C b/gcc/testsuite/g++.dg/cpp0x/noexcept60.C
new file mode 100644
index 00000000000..d8efe1a24cb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/noexcept60.C
@@ -0,0 +1,13 @@
+// PR c++/95562
+// { dg-do compile { target c++11 } }
+
+template <bool Nothrow>
+struct Functions
+{
+  void (*func)(void*) noexcept(Nothrow);
+};
+
+void test()
+{
+  Functions<true> f{};
+}


More information about the Gcc-cvs mailing list