Hi,
yesterday I didn't notice that we have a separate bug for a similar
issue affecting cp_parser_compound_requirement. Tested x86_64-linux.
Thanks, Paolo.
PS: while working on these issues, I noticed that somewhere else in the
concepts parsing bits we check the return value of cp_parser_require
and, in case, immediately return error_mark_node. That doesn't seem a
good idea - and isn't what we do for all the other cp_parser_require
semicolon calls - because it normally degrades error recovery when the
only bug in the code is the missing semicolon. I mean to further look
into that...
///////////////////////
/cp
2018-10-04 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/71140
* parser.c (cp_parser_compound_requirement): Require a terminating
semicolon, per 7.5.7.3.
/testsuite
2018-10-04 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/71140
* g++.dg/concepts/pr71139.C: New.
* g++.dg/concepts/pr67595.C: Adjust.
* g++.dg/concepts/diagnostic1.C: Likewise.
* g++.dg/concepts/disjunction1.C: Likewise.
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 264837)
+++ cp/parser.c (working copy)
@@ -26108,6 +26112,8 @@ cp_parser_compound_requirement (cp_parser *parser)
return error_mark_node;
}
+ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
+
return finish_compound_requirement (expr, type, noexcept_p);
}
Index: testsuite/g++.dg/concepts/diagnostic1.C
===================================================================
--- testsuite/g++.dg/concepts/diagnostic1.C (revision 264837)
+++ testsuite/g++.dg/concepts/diagnostic1.C (working copy)
@@ -6,7 +6,7 @@ concept bool SameAs = __is_same_as(T, U);
template <class T>
concept bool R1 = requires (T& t) {
- { t.begin() } -> T
+ { t.begin() } -> T;
{ t.end() } -> SameAs<T*>;
};
Index: testsuite/g++.dg/concepts/disjunction1.C
===================================================================
--- testsuite/g++.dg/concepts/disjunction1.C (revision 264837)
+++ testsuite/g++.dg/concepts/disjunction1.C (working copy)
@@ -29,7 +29,7 @@ template <class T> concept bool Movable() {
}
template <class, class> int Swappable_ = requires { 0; };
template <class T, class U> int Swappable();
-template <class T> concept bool Dereferencable = requires{{0}};
+template <class T> concept bool Dereferencable = requires{{0};};
template <Dereferencable R> using RvalueReferenceType = decltype(0);
template <class T> int IsValueType;
template <class> struct value_type;
@@ -39,7 +39,7 @@ requires IsValueType<
_t<value_type<remove_cv_t<T>>>;
template <class I> concept bool Readable() {
return Movable<I>() && DefaultConstructible<I>() &&
- Dereferencable<const I> && requires{{0}};
+ Dereferencable<const I> && requires{{0};};
}
template <class Out, class T> concept bool MoveWritable() {
return Movable<Out>() && DefaultConstructible<Out>() &&
Index: testsuite/g++.dg/concepts/pr67595.C
===================================================================
--- testsuite/g++.dg/concepts/pr67595.C (revision 264837)
+++ testsuite/g++.dg/concepts/pr67595.C (working copy)
@@ -1,9 +1,9 @@
// { dg-options "-std=c++17 -fconcepts" }
-template <class X> concept bool allocatable = requires{{new X}->X * };
+template <class X> concept bool allocatable = requires{{new X}->X *;};
template <class X> concept bool semiregular = allocatable<X>;
template <class X> concept bool readable = requires{requires semiregular<X>};
-template <class> int weak_input_iterator = requires{{0}->readable};
+template <class> int weak_input_iterator = requires{{0}->readable;};
template <class X> bool input_iterator{weak_input_iterator<X>}; // {
dg-warning "narrowing conversion" }
template <class X> bool forward_iterator{input_iterator<X>};
template <class X> bool bidirectional_iterator{forward_iterator<X>};
Index: testsuite/g++.dg/concepts/pr71139.C
===================================================================
--- testsuite/g++.dg/concepts/pr71139.C (nonexistent)
+++ testsuite/g++.dg/concepts/pr71139.C (working copy)
@@ -0,0 +1,8 @@
+// { dg-do compile { target c++14 } }
+// { dg-additional-options "-fconcepts" }
+
+template<typename T>
+concept bool C = requires(T t) {
+ { +t } // { dg-error "expected .\;. before .\}. token" }
+};
+static_assert(C<int>, "");