tianshilei1992 created this revision.
tianshilei1992 added reviewers: jdoerfert, ABataev.
tianshilei1992 requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

In 'cond-update-stmt', `else` statement is not expected. This patch adds
the check in Sema.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D120225

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaOpenMP.cpp
  clang/test/OpenMP/atomic_messages.c


Index: clang/test/OpenMP/atomic_messages.c
===================================================================
--- clang/test/OpenMP/atomic_messages.c
+++ clang/test/OpenMP/atomic_messages.c
@@ -473,6 +473,15 @@
       x = e;
     d = e;
   }
+// omp51-error@+7 {{the statement for 'atomic compare' must be a compound 
statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : 
x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x 
= expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) 
{x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 
'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}}
+// omp51-note@+6 {{unexpected 'else' statement}}
+#pragma omp atomic compare
+  {
+    if (x > e)
+      x = e;
+    else
+      d = e;
+  }
   float fx = 0.0f;
   float fd = 0.0f;
   float fe = 0.0f;
Index: clang/lib/Sema/SemaOpenMP.cpp
===================================================================
--- clang/lib/Sema/SemaOpenMP.cpp
+++ clang/lib/Sema/SemaOpenMP.cpp
@@ -10974,6 +10974,8 @@
     NotScalar,
     /// Not an integer.
     NotInteger,
+    /// 'else' statement is not expected.
+    UnexpectedElse,
     /// No error.
     NoError,
   };
@@ -11111,6 +11113,13 @@
     return false;
   }
 
+  if (S->getElse()) {
+    ErrorInfo.Error = ErrorTy::UnexpectedElse;
+    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getElse()->getBeginLoc();
+    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 
S->getElse()->getSourceRange();
+    return false;
+  }
+
   return true;
 }
 
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10526,7 +10526,7 @@
 def note_omp_atomic_compare: Note<
   "%select{expected compound statement|expected exactly one expression 
statement|expected assignment statement|expected conditional operator|expect 
result value to be at false expression|"
   "expect binary operator in conditional expression|expect '<', '>' or '==' as 
order operator|expect comparison in a form of 'x == e', 'e == x', 'x ordop 
expr', or 'expr ordop x'|"
-  "expect lvalue for result value|expect scalar value|expect integer value}0">;
+  "expect lvalue for result value|expect scalar value|expect integer 
value|unexpected 'else' statement}0">;
 def err_omp_atomic_several_clauses : Error<
   "directive '#pragma omp atomic' cannot contain more than one 'read', 
'write', 'update', 'capture', or 'compare' clause">;
 def err_omp_several_mem_order_clauses : Error<


Index: clang/test/OpenMP/atomic_messages.c
===================================================================
--- clang/test/OpenMP/atomic_messages.c
+++ clang/test/OpenMP/atomic_messages.c
@@ -473,6 +473,15 @@
       x = e;
     d = e;
   }
+// omp51-error@+7 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}}
+// omp51-note@+6 {{unexpected 'else' statement}}
+#pragma omp atomic compare
+  {
+    if (x > e)
+      x = e;
+    else
+      d = e;
+  }
   float fx = 0.0f;
   float fd = 0.0f;
   float fe = 0.0f;
Index: clang/lib/Sema/SemaOpenMP.cpp
===================================================================
--- clang/lib/Sema/SemaOpenMP.cpp
+++ clang/lib/Sema/SemaOpenMP.cpp
@@ -10974,6 +10974,8 @@
     NotScalar,
     /// Not an integer.
     NotInteger,
+    /// 'else' statement is not expected.
+    UnexpectedElse,
     /// No error.
     NoError,
   };
@@ -11111,6 +11113,13 @@
     return false;
   }
 
+  if (S->getElse()) {
+    ErrorInfo.Error = ErrorTy::UnexpectedElse;
+    ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getElse()->getBeginLoc();
+    ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getElse()->getSourceRange();
+    return false;
+  }
+
   return true;
 }
 
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10526,7 +10526,7 @@
 def note_omp_atomic_compare: Note<
   "%select{expected compound statement|expected exactly one expression statement|expected assignment statement|expected conditional operator|expect result value to be at false expression|"
   "expect binary operator in conditional expression|expect '<', '>' or '==' as order operator|expect comparison in a form of 'x == e', 'e == x', 'x ordop expr', or 'expr ordop x'|"
-  "expect lvalue for result value|expect scalar value|expect integer value}0">;
+  "expect lvalue for result value|expect scalar value|expect integer value|unexpected 'else' statement}0">;
 def err_omp_atomic_several_clauses : Error<
   "directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update', 'capture', or 'compare' clause">;
 def err_omp_several_mem_order_clauses : Error<
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to