[clang] [OpenMP][Clang] Handle unsupported inscan modifier for generic types (PR #79431)

Animesh Kumar via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 25 02:01:35 PST 2024


https://github.com/animeshk-amd created https://github.com/llvm/llvm-project/pull/79431

The https://reviews.llvm.org/D79948 patch had implemented the `omp scan` directive. The scan computation happens when the `reduction` clause with the `inscan` modifier is used. The present implementation doesn't support the reduction variable and the input list item to be of generic type. This patch handles this edge case by throwing a diagnostic error message when the `inscan` modifier is used on template type variables.

This fixes #67002:
=> [OpenMP][Clang] Scan Directive not supported for Generic types

>From 259a0da5b208d5f23d29c76f8ad24214780181e5 Mon Sep 17 00:00:00 2001
From: Animesh Kumar <animesh.kumar at amd.com>
Date: Mon, 22 Jan 2024 05:28:07 -0600
Subject: [PATCH] [OpenMP][Clang] Handle unsupported inscan modifier for
 generic types

The https://reviews.llvm.org/D79948 patch had implemented the
'omp scan' directive. The scan computation happens when the
'reduction' clause with the 'inscan' modifier is used. The
present implementation doesn't support the reduction variable and
the input list item to be of generic type. This patch handles
this edge case by throwing a diagnostic error message when the
'inscan' modifier is used on template type variables.

This fixes #67002:
=> [OpenMP][Clang] Scan Directive not supported for Generic types
---
 .../clang/Basic/DiagnosticSemaKinds.td        |  2 ++
 clang/lib/Sema/SemaOpenMP.cpp                 |  7 +++++
 clang/test/OpenMP/scan_ast_print.cpp          | 24 +----------------
 clang/test/OpenMP/scan_messages.cpp           | 26 +++++++++++--------
 4 files changed, 25 insertions(+), 34 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index a1c32abb4dcd880..34efa9107a81ab8 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11254,6 +11254,8 @@ def err_omp_reduction_not_inclusive_exclusive : Error<
 def err_omp_wrong_inscan_reduction : Error<
   "'inscan' modifier can be used only in 'omp for', 'omp simd', 'omp for simd',"
   " 'omp parallel for', or 'omp parallel for simd' directive">;
+def err_omp_inscan_reduction_on_template_type: Error <
+  "'inscan' modifier currently does not support generic data types">;
 def err_omp_inscan_reduction_expected : Error<
   "expected 'reduction' clause with the 'inscan' modifier">;
 def note_omp_previous_inscan_reduction : Note<
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 217fcb979deea20..b0353bf9b287789 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -19520,6 +19520,13 @@ static bool actOnOMPReductionKindClause(
   bool FirstIter = true;
   for (Expr *RefExpr : VarList) {
     assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
+    if (ClauseKind == OMPC_reduction &&
+        RD.RedModifier == OMPC_REDUCTION_inscan && RefExpr->isTypeDependent()) {
+      S.Diag(RefExpr->getExprLoc(),
+             diag::err_omp_inscan_reduction_on_template_type);
+      continue;
+    }
+
     // OpenMP [2.1, C/C++]
     //  A list item is a variable or array section, subject to the restrictions
     //  specified in Section 2.4 on page 42 and in each of the sections
diff --git a/clang/test/OpenMP/scan_ast_print.cpp b/clang/test/OpenMP/scan_ast_print.cpp
index 3bbd3b60c3e8c4e..090f7d2cafc34f1 100644
--- a/clang/test/OpenMP/scan_ast_print.cpp
+++ b/clang/test/OpenMP/scan_ast_print.cpp
@@ -12,28 +12,6 @@
 
 void foo() {}
 
-template <class T>
-T tmain(T argc) {
-  static T a;
-#pragma omp for reduction(inscan, +: a)
-  for (int i = 0; i < 10; ++i) {
-#pragma omp scan inclusive(a)
-  }
-  return a + argc;
-}
-// CHECK:      static T a;
-// CHECK-NEXT: #pragma omp for reduction(inscan, +: a)
-// CHECK-NEXT: for (int i = 0; i < 10; ++i) {
-// CHECK-NEXT: #pragma omp scan inclusive(a){{$}}
-// CHECK:      static int a;
-// CHECK-NEXT: #pragma omp for reduction(inscan, +: a)
-// CHECK-NEXT: for (int i = 0; i < 10; ++i) {
-// CHECK-NEXT: #pragma omp scan inclusive(a)
-// CHECK:      static char a;
-// CHECK-NEXT: #pragma omp for reduction(inscan, +: a)
-// CHECK-NEXT: for (int i = 0; i < 10; ++i) {
-// CHECK-NEXT: #pragma omp scan inclusive(a)
-
 int main(int argc, char **argv) {
   static int a;
 // CHECK: static int a;
@@ -46,7 +24,7 @@ int main(int argc, char **argv) {
 // CHECK-NEXT: #pragma omp for simd reduction(inscan, ^: a,argc)
 // CHECK-NEXT: for (int i = 0; i < 10; ++i) {
 // CHECK-NEXT: #pragma omp scan exclusive(a,argc){{$}}
-  return tmain(argc) + tmain(argv[0][0]) + a;
+  return 0;
 }
 
 #endif
diff --git a/clang/test/OpenMP/scan_messages.cpp b/clang/test/OpenMP/scan_messages.cpp
index 0de94898c65712f..3e889072bebf79b 100644
--- a/clang/test/OpenMP/scan_messages.cpp
+++ b/clang/test/OpenMP/scan_messages.cpp
@@ -16,32 +16,32 @@ T tmain() {
 #pragma omp scan untied  // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp scan'}} expected-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}}
 #pragma omp scan unknown // expected-warning {{extra tokens at the end of '#pragma omp scan' are ignored}} expected-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}}
   }
-#pragma omp for simd reduction(inscan, +: argc)
+#pragma omp for simd reduction(inscan, +: argc) // expected-error {{'inscan' modifier currently does not support generic data types}}
   for (int i = 0; i < 10; ++i)
     if (argc)
 #pragma omp scan inclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
     if (argc) {
 #pragma omp scan inclusive(argc) // expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
     }
-#pragma omp simd reduction(inscan, +: argc)
+#pragma omp simd reduction(inscan, +: argc) // expected-error {{'inscan' modifier currently does not support generic data types}}
   for (int i = 0; i < 10; ++i)
   while (argc)
 #pragma omp scan inclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
     while (argc) {
 #pragma omp scan inclusive(argc) // expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
     }
-#pragma omp simd reduction(inscan, +: argc)
+#pragma omp simd reduction(inscan, +: argc) // expected-error {{'inscan' modifier currently does not support generic data types}}
   for (int i = 0; i < 10; ++i)
   do
 #pragma omp scan inclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
     while (argc)
       ;
-#pragma omp simd reduction(inscan, +: argc) // expected-error {{the inscan reduction list item must appear as a list item in an 'inclusive' or 'exclusive' clause on an inner 'omp scan' directive}}
+#pragma omp simd reduction(inscan, +: argc) // expected-error {{'inscan' modifier currently does not support generic data types}}
   for (int i = 0; i < 10; ++i)
   do {
 #pragma omp scan inclusive(argc) // expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
   } while (argc);
-#pragma omp simd reduction(inscan, +: argc)
+#pragma omp simd reduction(inscan, +: argc) // expected-error {{'inscan' modifier currently does not support generic data types}}
   for (int i = 0; i < 10; ++i)
   switch (argc)
 #pragma omp scan inclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
@@ -52,7 +52,7 @@ T tmain() {
   case 1: {
 #pragma omp scan inclusive(argc) // expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
   }
-#pragma omp simd reduction(inscan, +: argc) // expected-error {{the inscan reduction list item must appear as a list item in an 'inclusive' or 'exclusive' clause on an inner 'omp scan' directive}}
+#pragma omp simd reduction(inscan, +: argc) // expected-error {{'inscan' modifier currently does not support generic data types}}
   for (int i = 0; i < 10; ++i)
   switch (argc) {
 #pragma omp scan exclusive(argc) // expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
@@ -64,26 +64,30 @@ T tmain() {
 #pragma omp scan exclusive(argc) // expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
   } break;
   }
-#pragma omp simd reduction(inscan, +: argc)
+#pragma omp simd reduction(inscan, +: argc) // expected-error {{'inscan' modifier currently does not support generic data types}}
   for (int i = 0; i < 10; ++i)
   for (;;)
 #pragma omp scan exclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
     for (;;) {
 #pragma omp scan exclusive(argc) // expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
     }
-#pragma omp simd reduction(inscan, +: argc)
+#pragma omp simd reduction(inscan, +: argc) // expected-error {{'inscan' modifier currently does not support generic data types}}
   for (int i = 0; i < 10; ++i) {
 label:
-#pragma omp scan exclusive(argc) // expected-error{{'#pragma omp scan' cannot be an immediate substatement}}
+#pragma omp scan exclusive(argc) // expected-error{{'#pragma omp scan' cannot be an immediate substatement}} expected-error {{the list item must appear in 'reduction' clause with the 'inscan' modifier of the parent directive}}
   }
-#pragma omp simd reduction(inscan, +: argc)
+#pragma omp simd reduction(inscan, +: argc) // expected-error {{'inscan' modifier currently does not support generic data types}}
   for (int i = 0; i < 10; ++i) {
-#pragma omp scan inclusive(argc) // expected-note {{previous 'scan' directive used here}}
+#pragma omp scan inclusive(argc) // expected-note {{previous 'scan' directive used here}} expected-error {{the list item must appear in 'reduction' clause with the 'inscan' modifier of the parent directive}}
 #pragma omp scan inclusive(argc) // expected-error {{exactly one 'scan' directive must appear in the loop body of an enclosing directive}}
 label1 : {
 #pragma omp scan inclusive(argc) // expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
 }}
 
+#pragma omp for reduction(inscan, +: argc) // expected-error {{'inscan' modifier currently does not support generic data types}}
+  for (int i = 0; i < 10; ++i) {
+#pragma omp scan inclusive(argc) // expected-error {{the list item must appear in 'reduction' clause with the 'inscan' modifier of the parent directive}}
+  }
   return T();
 }
 



More information about the cfe-commits mailing list