diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index a1c32abb4dcd8..34efa9107a81a 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 217fcb979deea..b0353bf9b2877 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 3bbd3b60c3e8c..090f7d2cafc34 100644 --- a/clang/test/OpenMP/scan_ast_print.cpp +++ b/clang/test/OpenMP/scan_ast_print.cpp @@ -12,28 +12,6 @@ void foo() {} -template -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 0de94898c6571..3e889072bebf7 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(); }