diff mbox series

c++: Make *_cast<*> parsing more robust to errors [PR108438]

Message ID 0102018ff29db4bf-c0839f10-7b1e-4d82-bcf1-a26f114611d5-000000@eu-west-1.amazonses.com
State New
Headers show
Series c++: Make *_cast<*> parsing more robust to errors [PR108438] | expand

Commit Message

Simon Martin June 7, 2024, 12:12 p.m. UTC
We ICE upon the following when trying to emit a -Wlogical-not-parentheses
warning:

=== cut here ===
template <typename T> T foo (T arg, T& ref, T* ptr) {
  int a = 1;
  return static_cast<T!>(a);
}
=== cut here ===

This patch makes *_cast<*> parsing more robust by skipping to the closing '>'
upon error in the target type.

Successfully tested on x86_64-pc-linux-gnu.

(Note that I have a patch pending review that also adds g++.dg/parse/crash74.C;
I will obviously handle the name conflict at commit time)

	PR c++/108438

gcc/cp/ChangeLog:

	* parser.cc (cp_parser_postfix_expression): Skip to the closing '>'
	upon error parsing the target type of *_cast<*> expressions.

gcc/testsuite/ChangeLog:

	* g++.dg/parse/crash74.C: New test.

---
 gcc/cp/parser.cc                     | 3 ++-
 gcc/testsuite/g++.dg/parse/crash74.C | 9 +++++++++
 2 files changed, 11 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/parse/crash74.C

Comments

Jason Merrill June 7, 2024, 5:30 p.m. UTC | #1
On 6/7/24 08:12, Simon Martin wrote:
> We ICE upon the following when trying to emit a -Wlogical-not-parentheses
> warning:
> 
> === cut here ===
> template <typename T> T foo (T arg, T& ref, T* ptr) {
>    int a = 1;
>    return static_cast<T!>(a);
> }
> === cut here ===
> 
> This patch makes *_cast<*> parsing more robust by skipping to the closing '>'
> upon error in the target type.
> 
> Successfully tested on x86_64-pc-linux-gnu.
> 
> (Note that I have a patch pending review that also adds g++.dg/parse/crash74.C;
> I will obviously handle the name conflict at commit time)
> 
> 	PR c++/108438
> 
> gcc/cp/ChangeLog:
> 
> 	* parser.cc (cp_parser_postfix_expression): Skip to the closing '>'
> 	upon error parsing the target type of *_cast<*> expressions.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/parse/crash74.C: New test.
> 
> ---
>   gcc/cp/parser.cc                     | 3 ++-
>   gcc/testsuite/g++.dg/parse/crash74.C | 9 +++++++++
>   2 files changed, 11 insertions(+), 1 deletion(-)
>   create mode 100644 gcc/testsuite/g++.dg/parse/crash74.C
> 
> diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
> index bc4a2359153..3516c2aa38b 100644
> --- a/gcc/cp/parser.cc
> +++ b/gcc/cp/parser.cc
> @@ -7569,7 +7569,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
>   				  NULL);
>   	parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
>   	/* Look for the closing `>'.  */
> -	cp_parser_require (parser, CPP_GREATER, RT_GREATER);
> +	if (!cp_parser_require (parser, CPP_GREATER, RT_GREATER))
> +	  cp_parser_skip_to_end_of_template_parameter_list (parser);

Looks like this could use cp_parser_require_end_of_template_parameter_list.

OK with that change.

Jason
Simon Martin June 8, 2024, 11:18 a.m. UTC | #2
Hi Jason,

On 7 Jun 2024, at 19:30, Jason Merrill wrote:

> On 6/7/24 08:12, Simon Martin wrote:
>> We ICE upon the following when trying to emit a 
>> -Wlogical-not-parentheses
>> warning:
>>
>> === cut here ===
>> template <typename T> T foo (T arg, T& ref, T* ptr) {
>>    int a = 1;
>>    return static_cast<T!>(a);
>> }
>> === cut here ===
>>
>> This patch makes *_cast<*> parsing more robust by skipping to the 
>> closing '>'
>> upon error in the target type.
>>
>> Successfully tested on x86_64-pc-linux-gnu.
>>
>> (Note that I have a patch pending review that also adds 
>> g++.dg/parse/crash74.C;
>> I will obviously handle the name conflict at commit time)
>>
>> 	PR c++/108438
>>
>> gcc/cp/ChangeLog:
>>
>> 	* parser.cc (cp_parser_postfix_expression): Skip to the closing '>'
>> 	upon error parsing the target type of *_cast<*> expressions.
>>
>> gcc/testsuite/ChangeLog:
>>
>> 	* g++.dg/parse/crash74.C: New test.
>>
>> ---
>>   gcc/cp/parser.cc                     | 3 ++-
>>   gcc/testsuite/g++.dg/parse/crash74.C | 9 +++++++++
>>   2 files changed, 11 insertions(+), 1 deletion(-)
>>   create mode 100644 gcc/testsuite/g++.dg/parse/crash74.C
>>
>> diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
>> index bc4a2359153..3516c2aa38b 100644
>> --- a/gcc/cp/parser.cc
>> +++ b/gcc/cp/parser.cc
>> @@ -7569,7 +7569,8 @@ cp_parser_postfix_expression (cp_parser 
>> *parser, bool address_p, bool cast_p,
>>   				  NULL);
>>   	parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
>>   	/* Look for the closing `>'.  */
>> -	cp_parser_require (parser, CPP_GREATER, RT_GREATER);
>> +	if (!cp_parser_require (parser, CPP_GREATER, RT_GREATER))
>> +	  cp_parser_skip_to_end_of_template_parameter_list (parser);
>
> Looks like this could use 
> cp_parser_require_end_of_template_parameter_list.
Indeed, thanks for pointing me to this function.
>
> OK with that change.
Merged with the change made via 
https://gcc.gnu.org/g:2c9643c27ecddb7f597d34009d89e932b4aca58e

-- Simon
>
> Jason
diff mbox series

Patch

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index bc4a2359153..3516c2aa38b 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -7569,7 +7569,8 @@  cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
 				  NULL);
 	parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
 	/* Look for the closing `>'.  */
-	cp_parser_require (parser, CPP_GREATER, RT_GREATER);
+	if (!cp_parser_require (parser, CPP_GREATER, RT_GREATER))
+	  cp_parser_skip_to_end_of_template_parameter_list (parser);
 	/* Restore the old message.  */
 	parser->type_definition_forbidden_message = saved_message;
 
diff --git a/gcc/testsuite/g++.dg/parse/crash74.C b/gcc/testsuite/g++.dg/parse/crash74.C
new file mode 100644
index 00000000000..81a16e35b14
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/crash74.C
@@ -0,0 +1,9 @@ 
+// PR c++/108438
+// { dg-options "-Wlogical-not-parentheses" }
+
+template <typename T>
+T foo (T arg, T& ref, T* ptr)
+{
+  int a = 1;
+  return static_cast<T!>(a); // { dg-error "expected" }
+}