diff mbox series

[pushed] c++: parse error with -std=c++14 -fconcepts [PR116071]

Message ID 20240724213509.3270629-1-jason@redhat.com
State New
Headers show
Series [pushed] c++: parse error with -std=c++14 -fconcepts [PR116071] | expand

Commit Message

Jason Merrill July 24, 2024, 9:34 p.m. UTC
Tested x86_64-pc-linux-gnu, applying to trunk.

-- 8< --

cp_parser_simple_type_specifier tries a variety of different things that
might qualify as a user-defined type: an actual type-name, a constrained
auto, a CTAD placeholder.  In a context where a type-specifier is optional,
this is all tentative.  With -std=c++14 -fconcepts, we try type-name and
constrained auto in sub-tentative parses, and when we run out of things to
try we haven't found anything but also haven't failed the outer tentative
parse, so parse_definitely succeeds, discarding the nested-name-specifier.

Fixed by failing if we didn't find anything.

I said in r14-3203 that we should disable this combination of flags if
further problems arise, but this seems like a more general problem that only
happened to occur with just this combination of flags.  So it lives on.

	PR c++/116071

gcc/cp/ChangeLog:

	* parser.cc (cp_parser_simple_type_specifier): Call
	cp_parser_simulate_error if nothing worked.

gcc/testsuite/ChangeLog:

	* g++.dg/parse/pr116071.C: New test.
---
 gcc/cp/parser.cc                      | 10 +++++++---
 gcc/testsuite/g++.dg/parse/pr116071.C | 18 ++++++++++++++++++
 2 files changed, 25 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/parse/pr116071.C


base-commit: d2fc64c85788c135419cc3dcf5b4fa64558af547
diff mbox series

Patch

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 1fa0780944b..f79736c17ac 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -20786,9 +20786,13 @@  cp_parser_simple_type_specifier (cp_parser* parser,
 	}
 
       /* If it didn't work out, we don't have a TYPE.  */
-      if ((flags & CP_PARSER_FLAGS_OPTIONAL)
-	  && !cp_parser_parse_definitely (parser))
-	type = NULL_TREE;
+      if (flags & CP_PARSER_FLAGS_OPTIONAL)
+	{
+	  if (!type)
+	    cp_parser_simulate_error (parser);
+	  if (!cp_parser_parse_definitely (parser))
+	    type = NULL_TREE;
+	}
 
       /* Keep track of all name-lookups performed in class scopes.  */
       if (type
diff --git a/gcc/testsuite/g++.dg/parse/pr116071.C b/gcc/testsuite/g++.dg/parse/pr116071.C
new file mode 100644
index 00000000000..7590782d5ee
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/pr116071.C
@@ -0,0 +1,18 @@ 
+// PR c++/116071
+// { dg-options "-std=c++14 -fconcepts" }
+
+template<class T> struct S { ~S(); };
+template<class T> S<T>::~S() { }
+
+template<typename MemPtr>
+struct result_of;
+
+template<typename Res, typename Class>
+struct result_of<Res Class::*>
+{
+  using type = void;
+};
+
+struct thread {
+  void join() { };
+};