diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 29 | ||||
-rw-r--r-- | clang/test/OpenMP/for_misc_messages.c | 6 |
3 files changed, 35 insertions, 3 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 7db98d59923..cb81078880d 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -7238,6 +7238,9 @@ def err_omp_loop_cannot_use_stmt : Error< "'%0' statement cannot be used in OpenMP for loop">; def err_omp_simd_region_cannot_use_stmt : Error< "'%0' statement cannot be used in OpenMP simd region">; +def warn_omp_loop_64_bit_var : Warning< + "OpenMP loop iteration variable cannot have more than 64 bits size and will be narrowed">, + InGroup<OpenMPLoopForm>; def err_omp_unknown_reduction_identifier : Error< "incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'">; def err_omp_reduction_type_array : Error< diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index e70090d930e..ff2b2826092 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -1851,7 +1851,7 @@ public: /// \brief True if the step should be subtracted. bool ShouldSubtractStep() const { return SubtractStep; } /// \brief Build the expression to calculate the number of iterations. - Expr *BuildNumIterations(Scope *S) const; + Expr *BuildNumIterations(Scope *S, const bool LimitedType) const; /// \brief Build reference expression to the counter be used for codegen. Expr *BuildCounterVar() const; /// \brief Build initization of the counter be used for codegen. @@ -2183,7 +2183,9 @@ bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) { } /// \brief Build the expression to calculate the number of iterations. -Expr *OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S) const { +Expr * +OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S, + const bool LimitedType) const { ExprResult Diff; if (Var->getType()->isIntegerType() || Var->getType()->isPointerType() || SemaRef.getLangOpts().CPlusPlus) { @@ -2230,6 +2232,26 @@ Expr *OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S) const { if (!Diff.isUsable()) return nullptr; + // OpenMP runtime requires 32-bit or 64-bit loop variables. + if (LimitedType) { + auto &C = SemaRef.Context; + QualType Type = Diff.get()->getType(); + unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; + if (NewSize != C.getTypeSize(Type)) { + if (NewSize < C.getTypeSize(Type)) { + assert(NewSize == 64 && "incorrect loop var size"); + SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) + << InitSrcRange << ConditionSrcRange; + } + QualType NewType = C.getIntTypeForBitwidth( + NewSize, Type->hasSignedIntegerRepresentation()); + Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, + Sema::AA_Converting, true); + if (!Diff.isUsable()) + return nullptr; + } + } + return Diff.get(); } @@ -2418,7 +2440,8 @@ static bool CheckOpenMPIterationSpace( return HasErrors; // Build the loop's iteration space representation. - ResultIterSpace.NumIterations = ISC.BuildNumIterations(DSA.getCurScope()); + ResultIterSpace.NumIterations = ISC.BuildNumIterations( + DSA.getCurScope(), /* LimitedType */ isOpenMPWorksharingDirective(DKind)); ResultIterSpace.CounterVar = ISC.BuildCounterVar(); ResultIterSpace.CounterInit = ISC.BuildCounterInit(); ResultIterSpace.CounterStep = ISC.BuildCounterStep(); diff --git a/clang/test/OpenMP/for_misc_messages.c b/clang/test/OpenMP/for_misc_messages.c index 99e6a2b7d5f..ab40570e3ea 100644 --- a/clang/test/OpenMP/for_misc_messages.c +++ b/clang/test/OpenMP/for_misc_messages.c @@ -369,5 +369,11 @@ void test_loop_messages() { for (double fi = 0; fi < 10.0; fi++) { c[(int)fi] = a[(int)fi] + b[(int)fi]; } + + // expected-warning@+2 {{OpenMP loop iteration variable cannot have more than 64 bits size and will be narrowed}} + #pragma omp for + for (__int128 ii = 0; ii < 10; ii++) { + c[ii] = a[ii] + b[ii]; + } } |