diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index 0aaf8f189a0ec..7dd25f75d9eb7 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -745,6 +745,9 @@ class ReductionProcessor { const Fortran::parser::ProcedureDesignator &pd) { const auto *name{Fortran::parser::Unwrap(pd)}; assert(name && "Invalid Reduction Intrinsic."); + if (!name->symbol->GetUltimate().attrs().test( + Fortran::semantics::Attr::INTRINSIC)) + return false; auto redType = llvm::StringSwitch>( getRealName(name).ToString()) .Case("max", IntrinsicProc::MAX) diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index c430375d5ed01..22e9d5d4dd799 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -2299,18 +2299,20 @@ bool OmpStructureChecker::CheckReductionOperators( }, [&](const parser::ProcedureDesignator &procD) { const parser::Name *name{std::get_if(&procD.u)}; - if (name) { - if (name->source == "max" || name->source == "min" || - name->source == "iand" || name->source == "ior" || - name->source == "ieor") { + if (name && name->symbol) { + const SourceName &realName{name->symbol->GetUltimate().name()}; + if (realName == "max" || realName == "min" || + realName == "iand" || realName == "ior" || + realName == "ieor") { ok = true; - } else { - context_.Say(GetContext().clauseSource, - "Invalid reduction identifier in REDUCTION " - "clause."_err_en_US, - ContextDirectiveAsFortran()); } } + if (!ok) { + context_.Say(GetContext().clauseSource, + "Invalid reduction identifier in REDUCTION " + "clause."_err_en_US, + ContextDirectiveAsFortran()); + } }, }, definedOp.u); diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index e31193f490f79..2c570bc3abeb2 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -481,21 +481,28 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor { bool Pre(const parser::OmpClause::Reduction &x) { const parser::OmpReductionOperator &opr{ std::get(x.v.t)}; + auto createDummyProcSymbol = [&](const parser::Name *name) { + // If name resolution failed, create a dummy symbol + const auto namePair{ + currScope().try_emplace(name->source, Attrs{}, ProcEntityDetails{})}; + auto &newSymbol{*namePair.first->second}; + name->symbol = &newSymbol; + }; if (const auto *procD{parser::Unwrap(opr.u)}) { if (const auto *name{parser::Unwrap(procD->u)}) { if (!name->symbol) { - const auto namePair{currScope().try_emplace( - name->source, Attrs{}, ProcEntityDetails{})}; - auto &symbol{*namePair.first->second}; - name->symbol = &symbol; - name->symbol->set(Symbol::Flag::OmpReduction); - AddToContextObjectWithDSA(*name->symbol, Symbol::Flag::OmpReduction); + if (!ResolveName(name)) { + createDummyProcSymbol(name); + } } } if (const auto *procRef{ parser::Unwrap(procD->u)}) { - ResolveOmp(*procRef->v.thing.component.symbol, - Symbol::Flag::OmpReduction, currScope()); + if (!procRef->v.thing.component.symbol) { + if (!ResolveName(&procRef->v.thing.component)) { + createDummyProcSymbol(&procRef->v.thing.component); + } + } } } const auto &objList{std::get(x.v.t)}; diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-max-2.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-max-2.f90 new file mode 100644 index 0000000000000..7e079470df847 --- /dev/null +++ b/flang/test/Lower/OpenMP/wsloop-reduction-max-2.f90 @@ -0,0 +1,19 @@ +! RUN: bbc -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s +! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s + +! CHECK: omp.wsloop reduction(@max_i_32 +! CHECK: omp.reduction + +module m1 + intrinsic max +end module m1 +program main + use m1, ren=>max + n=0 + !$omp parallel do reduction(ren:n) + do i=1,100 + n=max(n,i) + end do + if (n/=100) print *,101 + print *,'pass' +end program main