diff options
author | Jason Merrill <jason@redhat.com> | 2020-04-07 00:22:55 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2020-04-07 16:49:29 -0400 |
commit | 31449cf8e119bbe172a68689068591827472da5c (patch) | |
tree | 95d85f2965934a6c8f971f4f2d4fe43aa5af4cbf | |
parent | c23c899aedf11069e992eed7358802b262d62f98 (diff) | |
download | gcc-31449cf8e119bbe172a68689068591827472da5c.zip gcc-31449cf8e119bbe172a68689068591827472da5c.tar.gz gcc-31449cf8e119bbe172a68689068591827472da5c.tar.bz2 |
c++: ICE on invalid concept placeholder [PR94481].
Here the 'decltype' is missing '(auto)', so open_paren was NULL, and trying
to get its location is a SEGV. Using matching_parens avoids that problem.
gcc/cp/ChangeLog
2020-04-07 Jason Merrill <jason@redhat.com>
PR c++/94481
* parser.c (cp_parser_placeholder_type_specifier): Use
matching_parens.
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/parser.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/concepts-placeholder2.C | 9 |
3 files changed, 20 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 60d9279..8227f28 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2020-04-07 Jason Merrill <jason@redhat.com> + + PR c++/94481 + * parser.c (cp_parser_placeholder_type_specifier): Use + matching_parens. + 2020-04-07 Iain Sandoe <iain@sandoe.co.uk> * coroutines.cc (maybe_promote_captured_temps): Ensure that diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index fbcdc9b..2c33ca4 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -18367,7 +18367,7 @@ cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc, /* As per the standard, require auto or decltype(auto), except in some cases (template parameter lists, -fconcepts-ts enabled). */ - cp_token *placeholder = NULL, *open_paren = NULL, *close_paren = NULL; + cp_token *placeholder = NULL, *close_paren = NULL; if (cxx_dialect >= cxx2a) { if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AUTO)) @@ -18375,12 +18375,10 @@ cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc, else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DECLTYPE)) { placeholder = cp_lexer_consume_token (parser->lexer); - open_paren = cp_parser_require (parser, CPP_OPEN_PAREN, - RT_OPEN_PAREN); + matching_parens parens; + parens.require_open (parser); cp_parser_require_keyword (parser, RID_AUTO, RT_AUTO); - close_paren = cp_parser_require (parser, CPP_CLOSE_PAREN, - RT_CLOSE_PAREN, - open_paren->location); + close_paren = parens.require_close (parser); } } @@ -18429,7 +18427,7 @@ cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc, results in an invented template parameter. */ if (parser->auto_is_implicit_function_template_parm_p) { - if (placeholder && token_is_decltype (placeholder)) + if (close_paren) { location_t loc = make_location (placeholder->location, placeholder->location, diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder2.C new file mode 100644 index 0000000..b04354c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder2.C @@ -0,0 +1,9 @@ +// PR c++/94481 +// { dg-do compile { target c++2a } } + +template<typename T> +concept C = true; + +void foo() { + C decltype c = 1; // { dg-error "" } +} |