On 07/14/2015 07:29 PM, Paolo Carlini wrote:
I see. At the time I had this second try:https://gcc.gnu.org/ml/gcc-patches/2015-06/msg01232.html which has the action in cp_parser_unqualified_id but unfortunately is more complex. Certainly we can't just return inconditionally error_mark_node in that case, we have at least these regressions, a few accepts-invalid:
I think the problem here was that you can't just return error_mark_node without also forcing a parser error, or you get accepts-invalids. I played around with it and came up with the following:
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 25d5216505bfc4b922ce3e9627ed6ad223f348e1 Author: Jason Merrill <[email protected]> Date: Tue Jul 14 14:34:00 2015 -0400 PR c++/65091 * parser.c (cp_parser_unqualified_id): Don't accept ~x in a template if there is no type x in scope. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 574ffba..f1d5656 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -5162,8 +5162,15 @@ cp_parser_unqualified_id (cp_parser* parser, if (processing_template_decl && ! cp_parser_parse_definitely (parser)) { - /* We couldn't find a type with this name, so just accept - it and check for a match at instantiation time. */ + /* We couldn't find a type with this name. If we're parsing + tentatively, fail and try something else. */ + if (cp_parser_uncommitted_to_tentative_parse_p (parser)) + { + cp_parser_simulate_error (parser); + return error_mark_node; + } + /* Otherwise, accept it and check for a match at instantiation + time. */ type_decl = cp_parser_identifier (parser); if (type_decl != error_mark_node) type_decl = build_nt (BIT_NOT_EXPR, type_decl); diff --git a/gcc/testsuite/g++.dg/parse/dtor17.C b/gcc/testsuite/g++.dg/parse/dtor17.C new file mode 100644 index 0000000..1fca413 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/dtor17.C @@ -0,0 +1,11 @@ +// PR c++/65091 +// { dg-do compile { target c++11 } } + +template<typename T> +auto foo(T x) -> decltype(~x) { + return ~x; +} + +int bar() { + return foo(10); +}
