jdoerfert created this revision.
jdoerfert added reviewers: aaron.ballman, faisalv.
Herald added subscribers: guansong, bollu, yaxunl.
Herald added a project: All.
jdoerfert requested review of this revision.
Herald added a subscriber: sstefan1.
Herald added a project: clang.

There is no reason (obvious to me) that would prevent us from ignoring
the "simd" part during constexpr eval, assuming there are no clauses.
The potentially controversial part is the change from Equal to Encloses
when we do the context lookup.

Fixes https://github.com/llvm/llvm-project/issues/58092


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D135199

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/AST/ExprConstant.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/constexpr-openmp-simd.cpp

Index: clang/test/SemaCXX/constexpr-openmp-simd.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/constexpr-openmp-simd.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -verify -std=c++2a -fsyntax-only -fopenmp -triple x86_64-apple-macosx10.14.0 %s
+// RUN: %clang_cc1 -verify -std=c++2a -fsyntax-only -fopenmp -triple x86_64-apple-macosx10.14.0 %s -fno-signed-char
+// RUN: %clang_cc1 -verify -std=c++2a -fsyntax-only -fopenmp -triple aarch64_be-linux-gnu %s
+// RUN: %clang_cc1 -emit-llvm -std=c++2a -fopenmp -triple aarch64_be-linux-gnu %s -DEMIT_IR -o - | FileCheck %s
+
+constexpr int good(int r) {
+
+  #pragma omp simd
+  for (int i = 0; i != 10; ++i)
+    r += 1;
+
+  return r;
+}
+
+int test1() {
+  if (good(10) == 20)
+    return 42;
+  return good(7);
+// Make sure this is folded to 42 and not 17.
+// CHECK: ret i32 42
+}
+
+#ifndef EMIT_IR
+constexpr int bad(int r) {
+  #pragma omp simd private(r) // expected-error {{OpenMP simd statement with clauses not allowed in constexpr function}}
+  for (int i = 0; i != 10; ++i)
+    r += 1;
+
+  return r;
+}
+
+int test2() {
+  return bad(10);
+}
+#endif
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -2169,6 +2169,23 @@
       return false;
     return true;
 
+  case Stmt::OMPSimdDirectiveClass: {
+    if (!cast<OMPSimdDirective>(S)->clauses().empty()) {
+      if (Kind == Sema::CheckConstexprKind::Diagnose) {
+        SemaRef.Diag(
+            S->getBeginLoc(),
+            diag::err_constexpr_body_invalid_omp_simd_stmt_with_clauses)
+            << isa<CXXConstructorDecl>(Dcl) << Dcl->isConsteval();
+      }
+      return false;
+    }
+    Stmt *LoopStmt = cast<OMPSimdDirective>(S)->getAssociatedStmt();
+    if (auto *CS = dyn_cast<CapturedStmt>(LoopStmt))
+      LoopStmt = CS->getCapturedStmt();
+    return CheckConstexprFunctionStmt(SemaRef, Dcl, LoopStmt, ReturnStmts,
+                                      Cxx1yLoc, Cxx2aLoc, Cxx2bLoc, Kind);
+  }
+
   default:
     if (!isa<Expr>(S))
       break;
Index: clang/lib/AST/ExprConstant.cpp
===================================================================
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -5489,6 +5489,13 @@
   case Stmt::CXXTryStmtClass:
     // Evaluate try blocks by evaluating all sub statements.
     return EvaluateStmt(Result, Info, cast<CXXTryStmt>(S)->getTryBlock(), Case);
+
+  case Stmt::OMPSimdDirectiveClass: {
+    const Stmt *LoopStmt = cast<OMPSimdDirective>(S)->getAssociatedStmt();
+    if (auto *CS = dyn_cast<CapturedStmt>(LoopStmt))
+      LoopStmt = CS->getCapturedStmt();
+    return EvaluateStmt(Result, Info, LoopStmt, Case);
+  }
   }
 }
 
@@ -8271,7 +8278,8 @@
     // variable) or be ill-formed (and trigger an appropriate evaluation
     // diagnostic)).
     CallStackFrame *CurrFrame = Info.CurrentCall;
-    if (CurrFrame->Callee && CurrFrame->Callee->Equals(VD->getDeclContext())) {
+    if (CurrFrame->Callee &&
+        CurrFrame->Callee->Encloses(VD->getDeclContext())) {
       // Function parameters are stored in some caller's frame. (Usually the
       // immediate caller, but for an inherited constructor they may be more
       // distant.)
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2719,6 +2719,8 @@
   "use of this statement in a constexpr %select{function|constructor}0 "
   "is incompatible with C++ standards before C++2b">,
   InGroup<CXXPre2bCompat>, DefaultIgnore;
+def err_constexpr_body_invalid_omp_simd_stmt_with_clauses : Error<
+  "OpenMP simd statement with clauses not allowed in %select{constexpr|consteval}1 %select{function|constructor}0">;
 def ext_constexpr_type_definition : ExtWarn<
   "type definition in a constexpr %select{function|constructor}0 "
   "is a C++14 extension">, InGroup<CXX14>;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to