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 <ja...@redhat.com>
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);
+}