aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-04-07 00:22:55 -0400
committerJason Merrill <jason@redhat.com>2020-04-07 16:49:29 -0400
commit31449cf8e119bbe172a68689068591827472da5c (patch)
tree95d85f2965934a6c8f971f4f2d4fe43aa5af4cbf /gcc
parentc23c899aedf11069e992eed7358802b262d62f98 (diff)
downloadgcc-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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/parser.c12
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-placeholder2.C9
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 "" }
+}