Index: lib/Sema/SemaOpenMP.cpp =================================================================== --- lib/Sema/SemaOpenMP.cpp +++ lib/Sema/SemaOpenMP.cpp @@ -5426,26 +5426,44 @@ return nullptr; } -static bool checkSimdlenSafelenValues(Sema &S, const Expr *Simdlen, - const Expr *Safelen) { - llvm::APSInt SimdlenRes, SafelenRes; - if (Simdlen->isValueDependent() || Simdlen->isTypeDependent() || - Simdlen->isInstantiationDependent() || - Simdlen->containsUnexpandedParameterPack()) - return false; - if (Safelen->isValueDependent() || Safelen->isTypeDependent() || - Safelen->isInstantiationDependent() || - Safelen->containsUnexpandedParameterPack()) - return false; - Simdlen->EvaluateAsInt(SimdlenRes, S.Context); - Safelen->EvaluateAsInt(SafelenRes, S.Context); - // OpenMP 4.1 [2.8.1, simd Construct, Restrictions] - // If both simdlen and safelen clauses are specified, the value of the simdlen - // parameter must be less than or equal to the value of the safelen parameter. - if (SimdlenRes > SafelenRes) { - S.Diag(Simdlen->getExprLoc(), diag::err_omp_wrong_simdlen_safelen_values) - << Simdlen->getSourceRange() << Safelen->getSourceRange(); - return true; +static bool checkSimdlenSafelenSpecified(Sema &S, + const ArrayRef Clauses) { + OMPSafelenClause *Safelen = nullptr; + OMPSimdlenClause *Simdlen = nullptr; + + for (auto *Clause : Clauses) { + if (Clause->getClauseKind() == OMPC_safelen) + Safelen = cast(Clause); + else if (Clause->getClauseKind() == OMPC_simdlen) + Simdlen = cast(Clause); + if (Safelen && Simdlen) + break; + } + + if (Simdlen && Safelen) { + llvm::APSInt SimdlenRes, SafelenRes; + auto SimdlenLength = Simdlen->getSimdlen(); + auto SafelenLength = Safelen->getSafelen(); + if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || + SimdlenLength->isInstantiationDependent() || + SimdlenLength->containsUnexpandedParameterPack()) + return false; + if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || + SafelenLength->isInstantiationDependent() || + SafelenLength->containsUnexpandedParameterPack()) + return false; + SimdlenLength->EvaluateAsInt(SimdlenRes, S.Context); + SafelenLength->EvaluateAsInt(SafelenRes, S.Context); + // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] + // If both simdlen and safelen clauses are specified, the value of the + // simdlen parameter must be less than or equal to the value of the safelen + // parameter. + if (SimdlenRes > SafelenRes) { + S.Diag(SimdlenLength->getExprLoc(), + diag::err_omp_wrong_simdlen_safelen_values) + << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); + return true; + } } return false; } @@ -5481,22 +5499,7 @@ } } - // OpenMP 4.1 [2.8.1, simd Construct, Restrictions] - // If both simdlen and safelen clauses are specified, the value of the simdlen - // parameter must be less than or equal to the value of the safelen parameter. - OMPSafelenClause *Safelen = nullptr; - OMPSimdlenClause *Simdlen = nullptr; - for (auto *Clause : Clauses) { - if (Clause->getClauseKind() == OMPC_safelen) - Safelen = cast(Clause); - else if (Clause->getClauseKind() == OMPC_simdlen) - Simdlen = cast(Clause); - if (Safelen && Simdlen) - break; - } - if (Simdlen && Safelen && - checkSimdlenSafelenValues(*this, Simdlen->getSimdlen(), - Safelen->getSafelen())) + if (checkSimdlenSafelenSpecified(*this, Clauses)) return StmtError(); getCurFunction()->setHasBranchProtectedScope(); @@ -5572,22 +5575,7 @@ } } - // OpenMP 4.1 [2.8.1, simd Construct, Restrictions] - // If both simdlen and safelen clauses are specified, the value of the simdlen - // parameter must be less than or equal to the value of the safelen parameter. - OMPSafelenClause *Safelen = nullptr; - OMPSimdlenClause *Simdlen = nullptr; - for (auto *Clause : Clauses) { - if (Clause->getClauseKind() == OMPC_safelen) - Safelen = cast(Clause); - else if (Clause->getClauseKind() == OMPC_simdlen) - Simdlen = cast(Clause); - if (Safelen && Simdlen) - break; - } - if (Simdlen && Safelen && - checkSimdlenSafelenValues(*this, Simdlen->getSimdlen(), - Safelen->getSafelen())) + if (checkSimdlenSafelenSpecified(*this, Clauses)) return StmtError(); getCurFunction()->setHasBranchProtectedScope(); @@ -5831,22 +5819,7 @@ } } - // OpenMP 4.1 [2.8.1, simd Construct, Restrictions] - // If both simdlen and safelen clauses are specified, the value of the simdlen - // parameter must be less than or equal to the value of the safelen parameter. - OMPSafelenClause *Safelen = nullptr; - OMPSimdlenClause *Simdlen = nullptr; - for (auto *Clause : Clauses) { - if (Clause->getClauseKind() == OMPC_safelen) - Safelen = cast(Clause); - else if (Clause->getClauseKind() == OMPC_simdlen) - Simdlen = cast(Clause); - if (Safelen && Simdlen) - break; - } - if (Simdlen && Safelen && - checkSimdlenSafelenValues(*this, Simdlen->getSimdlen(), - Safelen->getSafelen())) + if (checkSimdlenSafelenSpecified(*this, Clauses)) return StmtError(); getCurFunction()->setHasBranchProtectedScope(); @@ -7144,6 +7117,9 @@ assert((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built"); + if (checkSimdlenSafelenSpecified(*this, Clauses)) + return StmtError(); + getCurFunction()->setHasBranchProtectedScope(); return OMPDistributeParallelForSimdDirective::Create( Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); @@ -7177,6 +7153,9 @@ assert((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built"); + if (checkSimdlenSafelenSpecified(*this, Clauses)) + return StmtError(); + getCurFunction()->setHasBranchProtectedScope(); return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); @@ -7220,23 +7199,7 @@ return StmtError(); } } - - // OpenMP 4.1 [2.8.1, simd Construct, Restrictions] - // If both simdlen and safelen clauses are specified, the value of the simdlen - // parameter must be less than or equal to the value of the safelen parameter. - OMPSafelenClause *Safelen = nullptr; - OMPSimdlenClause *Simdlen = nullptr; - for (auto *Clause : Clauses) { - if (Clause->getClauseKind() == OMPC_safelen) - Safelen = cast(Clause); - else if (Clause->getClauseKind() == OMPC_simdlen) - Simdlen = cast(Clause); - if (Safelen && Simdlen) - break; - } - if (Simdlen && Safelen && - checkSimdlenSafelenValues(*this, Simdlen->getSimdlen(), - Safelen->getSafelen())) + if (checkSimdlenSafelenSpecified(*this, Clauses)) return StmtError(); getCurFunction()->setHasBranchProtectedScope(); Index: test/OpenMP/distribute_parallel_for_simd_misc_messages.c =================================================================== --- test/OpenMP/distribute_parallel_for_simd_misc_messages.c +++ test/OpenMP/distribute_parallel_for_simd_misc_messages.c @@ -334,6 +334,23 @@ ; } +void test_safelen_simdlen() { + int i; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}} +#pragma omp distribute parallel for simd simdlen(6) safelen(5) + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}} +#pragma omp distribute parallel for simd safelen(5) simdlen(6) + for (i = 0; i < 16; ++i) + ; +} + void test_collapse() { int i; #pragma omp target Index: test/OpenMP/distribute_simd_misc_messages.c =================================================================== --- test/OpenMP/distribute_simd_misc_messages.c +++ test/OpenMP/distribute_simd_misc_messages.c @@ -336,6 +336,23 @@ ; } +void test_safelen_simdlen() { + int i; +#pragma omp target +#pragma omp teams +// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}} +#pragma omp distribute simd simdlen(6) safelen(5) + for (i = 0; i < 16; ++i) + ; + +#pragma omp target +#pragma omp teams +// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}} +#pragma omp distribute simd safelen(5) simdlen(6) + for (i = 0; i < 16; ++i) + ; +} + void test_collapse() { int i; #pragma omp target Index: test/OpenMP/target_parallel_for_simd_misc_messages.c =================================================================== --- test/OpenMP/target_parallel_for_simd_misc_messages.c +++ test/OpenMP/target_parallel_for_simd_misc_messages.c @@ -312,3 +312,184 @@ } } +void test_safelen() { + int i; +// expected-error@+1 {{expected '('}} +#pragma omp target parallel for simd safelen + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd safelen( + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp target parallel for simd safelen() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd safelen(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd safelen(, ) + for (i = 0; i < 16; ++i) + ; +// expected-warning@+2 {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp target parallel for simd safelen 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd safelen(4 + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd safelen(4, + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd safelen(4, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target parallel for simd safelen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd safelen(4 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd safelen(4, , 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target parallel for simd safelen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd safelen(4, 8) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp target parallel for simd safelen(2.5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp target parallel for simd safelen(foo()) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}} +#pragma omp target parallel for simd safelen(-5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}} +#pragma omp target parallel for simd safelen(0) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}} +#pragma omp target parallel for simd safelen(5 - 5) + for (i = 0; i < 16; ++i) + ; +} + +void test_simdlen() { + int i; +// expected-error@+1 {{expected '('}} +#pragma omp target parallel for simd simdlen + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd simdlen( + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} +#pragma omp target parallel for simd simdlen() + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd simdlen(, + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd simdlen(, ) + for (i = 0; i < 16; ++i) + ; +// expected-warning@+2 {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} +// expected-error@+1 {{expected '('}} +#pragma omp target parallel for simd simdlen 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd simdlen(4 + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd simdlen(4, + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd simdlen(4, ) + for (i = 0; i < 16; ++i) + ; +#pragma omp target parallel for simd simdlen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd simdlen(4 4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd simdlen(4, , 4) + for (i = 0; i < 16; ++i) + ; +#pragma omp target parallel for simd simdlen(4) + for (i = 0; i < 16; ++i) + ; +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} +#pragma omp target parallel for simd simdlen(4, 8) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp target parallel for simd simdlen(2.5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{expression is not an integer constant expression}} +#pragma omp target parallel for simd simdlen(foo()) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}} +#pragma omp target parallel for simd simdlen(-5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}} +#pragma omp target parallel for simd simdlen(0) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}} +#pragma omp target parallel for simd simdlen(5 - 5) + for (i = 0; i < 16; ++i) + ; +} + +void test_safelen_simdlen() { + int i; +// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}} +#pragma omp target parallel for simd simdlen(6) safelen(5) + for (i = 0; i < 16; ++i) + ; +// expected-error@+1 {{the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter}} +#pragma omp target parallel for simd safelen(5) simdlen(6) + for (i = 0; i < 16; ++i) + ; +}