@@ -17508,6 +17508,9 @@ cp_parser_decltype (cp_parser *parser)
/* Parse to the closing `)'. */
if (expr == error_mark_node || !parens.require_close (parser))
{
+ /* Commit to the tentative_firewall so we actually skip to the closing
+ parenthesis. */
+ cp_parser_commit_to_tentative_parse (parser);
cp_parser_skip_to_closing_parenthesis (parser, true, false,
/*consume_paren=*/true);
expr = error_mark_node;
@@ -7,3 +7,5 @@ template<int> struct A
};
template<int N> int A<N>::i(decltype (A::i; // { dg-error "expected" }
+
+// { dg-excess-errors "" }
new file mode 100644
@@ -0,0 +1,25 @@
+// PR c++/114858
+// { dg-do compile { target c++20 } }
+// { dg-timeout 2 }
+
+template <class F> void g(F);
+template <class... A>
+auto h(A &&... a) -> decltype(
+ decltype(g< // { dg-error "expected primary-expression" }
+ decltype(g<decltype(g<decltype(g<decltype(g<decltype(g<
+ decltype(g<decltype(g<decltype(g<decltype(g<decltype(g<decltype(g<
+ decltype(g<decltype(g<decltype(g<decltype(g<decltype(g<decltype(g<
+ decltype(g<decltype(g<decltype(g<decltype(g<decltype(g<decltype(g<
+ decltype(g<decltype(g<decltype(g<decltype(g<decltype(g<decltype(g<
+ decltype(g<decltype(g<
+ decltype()>)(a)...)
+{
+ h([] {});
+}
+
+int main() {
+ h();
+ return 0;
+}
+
+// { dg-excess-errors "" }