Author: Krzysztof Parzyszek Date: 2025-07-28T09:37:49+02:00 New Revision: 9554152c8a9ce8af926cc31e1cef56a7a2181d9d
URL: https://github.com/llvm/llvm-project/commit/9554152c8a9ce8af926cc31e1cef56a7a2181d9d DIFF: https://github.com/llvm/llvm-project/commit/9554152c8a9ce8af926cc31e1cef56a7a2181d9d.diff LOG: [flang][OpenMP] Avoid analyzing assumed-size array bases (#150324) A check for character substrings masquerading as array sections was using expression analyzer on the array base. When this array happened to be an assumed-size array, the analyzer emitted a semantic error that did not correspond to any issue with the source code. To avoid that, check whether the object is an assumed-size array before using the expression analyzer on it. While at it, replace the call to GetShape with a simple check for rank, since that's the only information needed. Fixes https://github.com/llvm/llvm-project/issues/150297 (cherry picked from commit 8fcbd06b25fd0c1b4bc4a4c8775129f7dab1affd) Added: flang/test/Semantics/OpenMP/assumed-size-array.f90 Modified: flang/lib/Semantics/check-omp-structure.cpp Removed: ################################################################################ diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 2425265e196c6..783aef18fb894 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -16,7 +16,6 @@ #include "flang/Common/idioms.h" #include "flang/Common/indirection.h" #include "flang/Common/visit.h" -#include "flang/Evaluate/shape.h" #include "flang/Evaluate/tools.h" #include "flang/Evaluate/type.h" #include "flang/Parser/char-block.h" @@ -4117,21 +4116,26 @@ void OmpStructureChecker::CheckArraySection( // Detect this by looking for array accesses on character variables which are // not arrays. bool isSubstring{false}; - evaluate::ExpressionAnalyzer ea{context_}; - if (MaybeExpr expr = ea.Analyze(arrayElement.base)) { - std::optional<evaluate::Shape> shape = evaluate::GetShape(expr); - // Not an array: rank 0 - if (shape && shape->size() == 0) { - if (std::optional<evaluate::DynamicType> type = expr->GetType()) { - if (type->category() == evaluate::TypeCategory::Character) { - // Substrings are explicitly denied by the standard [6.0:163:9-11]. - // This is supported as an extension. This restriction was added in - // OpenMP 5.2. - isSubstring = true; - context_.Say(GetContext().clauseSource, - "The use of substrings in OpenMP argument lists has been disallowed since OpenMP 5.2."_port_en_US); - } else { - llvm_unreachable("Array indexing on a variable that isn't an array"); + // Cannot analyze a base of an assumed-size array on its own. If we know + // this is an array (assumed-size or not) we can ignore it, since we're + // looking for strings. + if (!IsAssumedSizeArray(*name.symbol)) { + evaluate::ExpressionAnalyzer ea{context_}; + if (MaybeExpr expr = ea.Analyze(arrayElement.base)) { + if (expr->Rank() == 0) { + // Not an array: rank 0 + if (std::optional<evaluate::DynamicType> type = expr->GetType()) { + if (type->category() == evaluate::TypeCategory::Character) { + // Substrings are explicitly denied by the standard [6.0:163:9-11]. + // This is supported as an extension. This restriction was added in + // OpenMP 5.2. + isSubstring = true; + context_.Say(GetContext().clauseSource, + "The use of substrings in OpenMP argument lists has been disallowed since OpenMP 5.2."_port_en_US); + } else { + llvm_unreachable( + "Array indexing on a variable that isn't an array"); + } } } } diff --git a/flang/test/Semantics/OpenMP/assumed-size-array.f90 b/flang/test/Semantics/OpenMP/assumed-size-array.f90 new file mode 100644 index 0000000000000..6e36db178dc8e --- /dev/null +++ b/flang/test/Semantics/OpenMP/assumed-size-array.f90 @@ -0,0 +1,25 @@ +!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s + +! This should compile without errors. Check for a symptom of a reasonable +! output. + +!CHECK: omp.task depend + +subroutine omp_task_depend_reproducer(work, myid, shift) + implicit none + integer, intent(in) :: myid, shift + real, intent(inout) :: work(*) + +!$omp parallel shared(work, myid, shift) + !$omp single + !$omp task depend(in:work(myid+shift-1)) depend(in:work(myid-1)) depend(out:work(myid)) + call dummy_kernel(work(myid)) + !$omp end task + !$omp end single +!$omp end parallel +contains + subroutine dummy_kernel(x) + real :: x + x = x + 1.0 + end subroutine dummy_kernel +end subroutine omp_task_depend_reproducer _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits