On Wed, Nov 14, 2018 at 10:03:50AM -0500, Jason Merrill wrote: > On Wed, Nov 14, 2018 at 9:55 AM Marek Polacek <pola...@redhat.com> wrote: > > > > In elaborated-type-specifier, the typename keyword can only follow a > > nested-name-specifier: > > > > class-key nested-name-specifier template[opt] simple-template-id > > > > but we weren't detecting it. > > > > Bootstrapped/regtested on x86_64-linux, ok for trunk? > > > > 2018-11-14 Marek Polacek <pola...@redhat.com> > > > > PR c++/87781 - detect invalid elaborated-type-specifier. > > * parser.c (cp_parser_elaborated_type_specifier): Ensure that > > typename follows a nested-name-specifier. > > > > * g++.dg/parse/elab3.C: New test. > > > > diff --git gcc/cp/parser.c gcc/cp/parser.c > > index e9e49b15702..0ab44ab93e3 100644 > > --- gcc/cp/parser.c > > +++ gcc/cp/parser.c > > @@ -17986,6 +17986,10 @@ cp_parser_elaborated_type_specifier (cp_parser* > > parser, > > template-id or not. */ > > if (!template_p) > > cp_parser_parse_tentatively (parser); > > + /* The `template' keyword must follow a nested-name-specifier. */ > > + else if (!nested_name_specifier) > > + return error_mark_node; > > Don't we want a diagnostic here?
We'd get "invalid declarator" even without a diagnostic there but I guess it'd be nicer so say what the actual problem is. Unsure which diagnostic to go with, this patch uses cp_parser_error though. Bootstrapped/regtested on x86_64-linux, ok for trunk? 2018-11-14 Marek Polacek <pola...@redhat.com> PR c++/87781 - detect invalid elaborated-type-specifier. * parser.c (cp_parser_elaborated_type_specifier): Ensure that typename follows a nested-name-specifier. * g++.dg/parse/elab3.C: New test. * g++.dg/template/crash115.C: Adjust dg-error. diff --git gcc/cp/parser.c gcc/cp/parser.c index e9e49b15702..bfcf42b0f39 100644 --- gcc/cp/parser.c +++ gcc/cp/parser.c @@ -17986,6 +17986,14 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, template-id or not. */ if (!template_p) cp_parser_parse_tentatively (parser); + /* The `template' keyword must follow a nested-name-specifier. */ + else if (!nested_name_specifier) + { + cp_parser_error (parser, "%<template%> must follow a nested-" + "name-specifier"); + return error_mark_node; + } + /* Parse the template-id. */ token = cp_lexer_peek_token (parser->lexer); decl = cp_parser_template_id (parser, template_p, diff --git gcc/testsuite/g++.dg/parse/elab3.C gcc/testsuite/g++.dg/parse/elab3.C new file mode 100644 index 00000000000..61338fb7ac4 --- /dev/null +++ gcc/testsuite/g++.dg/parse/elab3.C @@ -0,0 +1,6 @@ +// PR c++/87781 +// { dg-do compile } +// { dg-options "" } + +template<class> class A; +class template A<int> *p; // { dg-error ".template. must follow|invalid" } diff --git gcc/testsuite/g++.dg/template/crash115.C gcc/testsuite/g++.dg/template/crash115.C index 5c9f525cd64..80f8683a136 100644 --- gcc/testsuite/g++.dg/template/crash115.C +++ gcc/testsuite/g++.dg/template/crash115.C @@ -1,3 +1,3 @@ // PR c++/56534 -template < struct template rebind < > // { dg-error "expected" } +template < struct template rebind < > // { dg-error "expected|must follow" }