diff mbox series

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

Message ID 20200609235441.917678-1-polacek@redhat.com
State New
Headers show
Series c++: Fix ICE with delayed parsing of noexcept-specifier [PR95562] | expand

Commit Message

Marek Polacek June 9, 2020, 11:54 p.m. UTC
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.)

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/10?

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.
---
 gcc/cp/parser.c                         |  5 +++++
 gcc/testsuite/g++.dg/cpp0x/noexcept60.C | 13 +++++++++++++
 2 files changed, 18 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/noexcept60.C


base-commit: d7274dbf82001ae52e5c9a514129b49152498d40

Comments

Jason Merrill June 10, 2020, 4:49 a.m. UTC | #1
On 6/9/20 7:54 PM, Marek Polacek wrote:
> 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.)
> 
> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/10?

OK.

> 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.
> ---
>   gcc/cp/parser.c                         |  5 +++++
>   gcc/testsuite/g++.dg/cpp0x/noexcept60.C | 13 +++++++++++++
>   2 files changed, 18 insertions(+)
>   create mode 100644 gcc/testsuite/g++.dg/cpp0x/noexcept60.C
> 
> diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
> index b0b31d241f3..bc66e6e5c50 100644
> --- a/gcc/cp/parser.c
> +++ b/gcc/cp/parser.c
> @@ -21283,6 +21283,11 @@ cp_parser_direct_declarator (cp_parser* parser,
>   		    /* DR 1207: 'this' is in scope after the cv-quals.  */
>   		    inject_this_parameter (current_class_type, cv_quals);
>   
> +		  /* 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;
> +
>   		  /* Parse 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{};
> +}
> 
> base-commit: d7274dbf82001ae52e5c9a514129b49152498d40
>
diff mbox series

Patch

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index b0b31d241f3..bc66e6e5c50 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -21283,6 +21283,11 @@  cp_parser_direct_declarator (cp_parser* parser,
 		    /* DR 1207: 'this' is in scope after the cv-quals.  */
 		    inject_this_parameter (current_class_type, cv_quals);
 
+		  /* 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;
+
 		  /* Parse 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{};
+}