cor3ntin created this revision.
cor3ntin requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Simple requierements in requierement body shall not start with
requires.
A warning was already in place so we just turn this warning into
an error.

In addition we add tests to make sure typename is optional
in requierement-parameter-list as per the same paper.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D106252

Files:
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/lib/Parse/ParseExprCXX.cpp
  clang/test/Parser/cxx2a-concepts-requires-expr.cpp
  clang/www/cxx_status.html


Index: clang/www/cxx_status.html
===================================================================
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -934,7 +934,7 @@
       </tr>
       <tr> <!-- from Belfast -->
         <td><a href="https://wg21.link/p1972r0";>P1972R0</a></td>
-        <td rowspan="5" class="none" align="center">No</td>
+        <td rowspan="3" class="none" align="center">No</td>
       </tr>
       <tr>
         <td><a href="https://wg21.link/p1980r0";>P1980R0</a></td>
@@ -944,9 +944,11 @@
       </tr>
       <tr>
         <td><a href="https://wg21.link/p2092r0";>P2092R0</a></td>
+        <td rowspan="1" class="full" align="center">Clang 13</td>
       </tr>
       <tr>
         <td><a href="https://wg21.link/p2113r0";>P2113R0</a></td>
+        <td rowspan="1" class="none" align="center">No</td>
       </tr>
     <!-- Albuquerque papers -->
     <tr>
Index: clang/test/Parser/cxx2a-concepts-requires-expr.cpp
===================================================================
--- clang/test/Parser/cxx2a-concepts-requires-expr.cpp
+++ clang/test/Parser/cxx2a-concepts-requires-expr.cpp
@@ -134,13 +134,21 @@
 // expected-error@-1 {{expected ';' at end of requirement}}
 
 bool r38 = requires { requires { 1; }; };
-// expected-warning@-1 {{this requires expression will only be checked for 
syntactic validity; did you intend to place it in a nested requirement? (add 
another 'requires' before the expression)}}
+// expected-error@-1 {{requires expression in requierement body; did you 
intend to place it in a nested requirement? (add another 'requires' before the 
expression)}}
 
 bool r39 = requires { requires () { 1; }; };
-// expected-warning@-1 {{this requires expression will only be checked for 
syntactic validity; did you intend to place it in a nested requirement? (add 
another 'requires' before the expression)}}
+// expected-error@-1 {{requires expression in requierement body; did you 
intend to place it in a nested requirement? (add another 'requires' before the 
expression)}}
 
 bool r40 = requires { requires (int i) { i; }; };
-// expected-warning@-1 {{this requires expression will only be checked for 
syntactic validity; did you intend to place it in a nested requirement? (add 
another 'requires' before the expression)}}
+// expected-error@-1 {{requires expression in requierement body; did you 
intend to place it in a nested requirement? (add another 'requires' before the 
expression)}}
 
 bool r41 = requires { requires (); };
 // expected-error@-1 {{expected expression}}
+
+template <typename T>
+struct S {
+    using type = T;
+};
+bool r42 = requires (typename S<int>::type i) { requires requires (typename 
S<int>::type i) { requires true; };};
+
+bool r43 = requires (S<int>::type i) { requires requires (S<int>::type i) { 
requires true; }; };
Index: clang/lib/Parse/ParseExprCXX.cpp
===================================================================
--- clang/lib/Parse/ParseExprCXX.cpp
+++ clang/lib/Parse/ParseExprCXX.cpp
@@ -3602,7 +3602,7 @@
           break;
         }
         if (!Expression.isInvalid() && PossibleRequiresExprInSimpleRequirement)
-          Diag(StartLoc, diag::warn_requires_expr_in_simple_requirement)
+          Diag(StartLoc, diag::err_requires_expr_in_simple_requirement)
               << FixItHint::CreateInsertion(StartLoc, "requires");
         if (auto *Req = Actions.ActOnSimpleRequirement(Expression.get()))
           Requirements.push_back(Req);
Index: clang/include/clang/Basic/DiagnosticParseKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticParseKinds.td
+++ clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -806,10 +806,10 @@
 def err_requires_expr_simple_requirement_noexcept : Error<
   "'noexcept' can only be used in a compound requirement (with '{' '}' around "
   "the expression)">;
-def warn_requires_expr_in_simple_requirement : Warning<
-  "this requires expression will only be checked for syntactic validity; did "
+def err_requires_expr_in_simple_requirement : Error<
+  "requires expression in requierement body; did "
   "you intend to place it in a nested requirement? (add another 'requires' "
-  "before the expression)">, InGroup<DiagGroup<"requires-expression">>;
+  "before the expression)">;
 
 def err_missing_dependent_template_keyword : Error<
   "use 'template' keyword to treat '%0' as a dependent template name">;


Index: clang/www/cxx_status.html
===================================================================
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -934,7 +934,7 @@
       </tr>
       <tr> <!-- from Belfast -->
         <td><a href="https://wg21.link/p1972r0";>P1972R0</a></td>
-        <td rowspan="5" class="none" align="center">No</td>
+        <td rowspan="3" class="none" align="center">No</td>
       </tr>
       <tr>
         <td><a href="https://wg21.link/p1980r0";>P1980R0</a></td>
@@ -944,9 +944,11 @@
       </tr>
       <tr>
         <td><a href="https://wg21.link/p2092r0";>P2092R0</a></td>
+        <td rowspan="1" class="full" align="center">Clang 13</td>
       </tr>
       <tr>
         <td><a href="https://wg21.link/p2113r0";>P2113R0</a></td>
+        <td rowspan="1" class="none" align="center">No</td>
       </tr>
     <!-- Albuquerque papers -->
     <tr>
Index: clang/test/Parser/cxx2a-concepts-requires-expr.cpp
===================================================================
--- clang/test/Parser/cxx2a-concepts-requires-expr.cpp
+++ clang/test/Parser/cxx2a-concepts-requires-expr.cpp
@@ -134,13 +134,21 @@
 // expected-error@-1 {{expected ';' at end of requirement}}
 
 bool r38 = requires { requires { 1; }; };
-// expected-warning@-1 {{this requires expression will only be checked for syntactic validity; did you intend to place it in a nested requirement? (add another 'requires' before the expression)}}
+// expected-error@-1 {{requires expression in requierement body; did you intend to place it in a nested requirement? (add another 'requires' before the expression)}}
 
 bool r39 = requires { requires () { 1; }; };
-// expected-warning@-1 {{this requires expression will only be checked for syntactic validity; did you intend to place it in a nested requirement? (add another 'requires' before the expression)}}
+// expected-error@-1 {{requires expression in requierement body; did you intend to place it in a nested requirement? (add another 'requires' before the expression)}}
 
 bool r40 = requires { requires (int i) { i; }; };
-// expected-warning@-1 {{this requires expression will only be checked for syntactic validity; did you intend to place it in a nested requirement? (add another 'requires' before the expression)}}
+// expected-error@-1 {{requires expression in requierement body; did you intend to place it in a nested requirement? (add another 'requires' before the expression)}}
 
 bool r41 = requires { requires (); };
 // expected-error@-1 {{expected expression}}
+
+template <typename T>
+struct S {
+    using type = T;
+};
+bool r42 = requires (typename S<int>::type i) { requires requires (typename S<int>::type i) { requires true; };};
+
+bool r43 = requires (S<int>::type i) { requires requires (S<int>::type i) { requires true; }; };
Index: clang/lib/Parse/ParseExprCXX.cpp
===================================================================
--- clang/lib/Parse/ParseExprCXX.cpp
+++ clang/lib/Parse/ParseExprCXX.cpp
@@ -3602,7 +3602,7 @@
           break;
         }
         if (!Expression.isInvalid() && PossibleRequiresExprInSimpleRequirement)
-          Diag(StartLoc, diag::warn_requires_expr_in_simple_requirement)
+          Diag(StartLoc, diag::err_requires_expr_in_simple_requirement)
               << FixItHint::CreateInsertion(StartLoc, "requires");
         if (auto *Req = Actions.ActOnSimpleRequirement(Expression.get()))
           Requirements.push_back(Req);
Index: clang/include/clang/Basic/DiagnosticParseKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticParseKinds.td
+++ clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -806,10 +806,10 @@
 def err_requires_expr_simple_requirement_noexcept : Error<
   "'noexcept' can only be used in a compound requirement (with '{' '}' around "
   "the expression)">;
-def warn_requires_expr_in_simple_requirement : Warning<
-  "this requires expression will only be checked for syntactic validity; did "
+def err_requires_expr_in_simple_requirement : Error<
+  "requires expression in requierement body; did "
   "you intend to place it in a nested requirement? (add another 'requires' "
-  "before the expression)">, InGroup<DiagGroup<"requires-expression">>;
+  "before the expression)">;
 
 def err_missing_dependent_template_keyword : Error<
   "use 'template' keyword to treat '%0' as a dependent template name">;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to