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 |
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
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 --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" } +}