[llvm-branch-commits] [flang] [flang][OpenMP] Improve diagnosing invalid operators in DECLARE_REDUCTION (PR #232353)
Krzysztof Parzyszek via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Oct 15 07:48:24 PDT 2026
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/232353
Move the check out of the common MakeNameFromOperator function and
into OmpStructureChecker. Remove the no longer needed SemanticsContext
parameter in MakeNameFromOperator.
This will allow reusing at least some parts of the the name-mangling
code in DECLARE_INDUCTION.
---
<sub>Stack created with <a href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>
>From bb11efb630cffde3dbe561d63d4e5b490ea1e63a Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Thu, 15 Oct 2026 08:14:08 -0500
Subject: [PATCH] [flang][OpenMP] Improve diagnosing invalid operators in
DECLARE_REDUCTION
Move the check out of the common MakeNameFromOperator function and
into OmpStructureChecker. Remove the no longer needed SemanticsContext
parameter in MakeNameFromOperator.
This will allow reusing at least some parts of the the name-mangling
code in DECLARE_INDUCTION.
---
flang/include/flang/Semantics/tools.h | 3 +-
flang/lib/Lower/OpenMP/OpenMP.cpp | 3 +-
.../lib/Lower/Support/ReductionProcessor.cpp | 2 +-
flang/lib/Semantics/check-omp-structure.cpp | 63 +++++++++++++------
flang/lib/Semantics/check-omp-structure.h | 2 +
flang/lib/Semantics/resolve-names.cpp | 3 +-
flang/lib/Semantics/tools.cpp | 8 +--
.../OpenMP/declare-reduction-bad-operator.f90 | 4 +-
flang/test/Semantics/OpenMP/in-reduction.f90 | 2 +-
.../Semantics/OpenMP/reduction-subtract.f90 | 3 +-
flang/test/Semantics/OpenMP/reduction01.f90 | 2 +-
flang/test/Semantics/OpenMP/reduction14.f90 | 3 +-
.../test/Semantics/OpenMP/task-reduction.f90 | 2 +-
13 files changed, 62 insertions(+), 38 deletions(-)
diff --git a/flang/include/flang/Semantics/tools.h b/flang/include/flang/Semantics/tools.h
index bd2cb0780de9bd..eb8bc762aa1a06 100644
--- a/flang/include/flang/Semantics/tools.h
+++ b/flang/include/flang/Semantics/tools.h
@@ -791,8 +791,7 @@ bool HadUseError(SemanticsContext &, SourceName at, const Symbol *);
bool AreSameModuleSymbol(const Symbol &, const Symbol &);
parser::CharBlock MakeNameFromOperator(
- const parser::DefinedOperator::IntrinsicOperator &op,
- SemanticsContext &context);
+ const parser::DefinedOperator::IntrinsicOperator &op);
parser::CharBlock MangleSpecialFunctions(parser::CharBlock name);
std::string MangleDefinedOperator(parser::CharBlock name);
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 7aa11e3bc776ad..4769b098a064da 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -6678,8 +6678,7 @@ static void genOpenMPDeclareReductionImpl(
parser::CharBlock mangledOpName =
semantics::MakeNameFromOperator(
ReductionProcessor::toParserIntrinsicOperator(
- intrOp),
- semaCtx);
+ intrOp));
redSymPtr = semantics::omp::FindUserReductionSymbol(
converter.getCurrentScope(), mangledOpName);
}
diff --git a/flang/lib/Lower/Support/ReductionProcessor.cpp b/flang/lib/Lower/Support/ReductionProcessor.cpp
index 55f24c937d8b5f..0655bff1e76042 100644
--- a/flang/lib/Lower/Support/ReductionProcessor.cpp
+++ b/flang/lib/Lower/Support/ReductionProcessor.cpp
@@ -1206,7 +1206,7 @@ bool ReductionProcessor::processReductionArguments(
const semantics::DeclTypeSpec *opVarType =
reductionSymbols[idx]->GetUltimate().GetType();
parser::CharBlock mangledOpName = semantics::MakeNameFromOperator(
- toParserIntrinsicOperator(intrinsicOp), *semaCtx);
+ toParserIntrinsicOperator(intrinsicOp));
if (const semantics::Symbol *userSym =
semantics::omp::FindUserReductionSymbol(
converter.getCurrentScope(), mangledOpName, opVarType)) {
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 7376a05d5c2ae9..1041ab778192c7 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -2756,17 +2756,32 @@ void OmpStructureChecker::Enter(const parser::OmpDeclareMapperDirective &x) {
}
void OmpStructureChecker::Enter(const parser::OmpDeclareReductionDirective &x) {
+ llvm::omp::Version version{context_.langOptions().getOpenMPVersion()};
+ std::string dirName{
+ GetUpperName(llvm::omp::Directive::OMPD_declare_reduction, version)};
+
const parser::OmpArgumentList &args{x.v.Arguments()};
if (args.v.size() != 1) {
context_.Say(args.source,
- "DECLARE_REDUCTION directive should have a single argument"_err_en_US);
+ "%s directive should have a single argument"_err_en_US, dirName);
return;
}
const parser::OmpArgument &arg{args.v.front()};
- if (!std::holds_alternative<parser::OmpReductionSpecifier>(arg.u)) {
+ if (auto *spec{std::get_if<parser::OmpReductionSpecifier>(&arg.u)}) {
+ auto &ident{std::get<parser::OmpReductionIdentifier>(spec->t)};
+ using IntrinsicOperator = parser::DefinedOperator::IntrinsicOperator;
+ if (auto *intOp{parser::Unwrap<IntrinsicOperator>(ident)}) {
+ if (!CheckReductionIntrinsicOperator(*intOp, arg.source)) {
+ context_.Say(arg.source,
+ "Invalid reduction intrinsic operator in %s directive"_err_en_US,
+ dirName);
+ }
+ }
+ } else {
context_.Say(arg.source,
- "The argument to the DECLARE_REDUCTION directive should be a reduction-specifier"_err_en_US);
+ "The argument to the %s directive should be a reduction-specifier"_err_en_US,
+ dirName);
}
}
@@ -4161,6 +4176,25 @@ void OmpStructureChecker::Enter(const parser::OmpClause::TaskReduction &x) {
CheckReductionObjects(objects, llvm::omp::Clause::OMPC_task_reduction);
}
+bool OmpStructureChecker::CheckReductionIntrinsicOperator(
+ parser::DefinedOperator::IntrinsicOperator op, parser::CharBlock source) {
+ switch (op) {
+ case parser::DefinedOperator::IntrinsicOperator::Add:
+ case parser::DefinedOperator::IntrinsicOperator::Multiply:
+ case parser::DefinedOperator::IntrinsicOperator::AND:
+ case parser::DefinedOperator::IntrinsicOperator::OR:
+ case parser::DefinedOperator::IntrinsicOperator::EQV:
+ case parser::DefinedOperator::IntrinsicOperator::NEQV:
+ return true;
+ case parser::DefinedOperator::IntrinsicOperator::Subtract:
+ context_.Say(source,
+ "The minus reduction operator is deprecated since OpenMP 5.2"_err_en_US);
+ return false;
+ default:
+ return false;
+ }
+}
+
bool OmpStructureChecker::CheckReductionOperator(
const parser::OmpReductionIdentifier &ident, parser::CharBlock source,
llvm::omp::Clause clauseId) {
@@ -4169,22 +4203,13 @@ bool OmpStructureChecker::CheckReductionOperator(
auto visitOperator{[&](const parser::DefinedOperator &dOpr) {
if (const auto *intrinsicOp{
std::get_if<parser::DefinedOperator::IntrinsicOperator>(&dOpr.u)}) {
- switch (*intrinsicOp) {
- case parser::DefinedOperator::IntrinsicOperator::Add:
- case parser::DefinedOperator::IntrinsicOperator::Multiply:
- case parser::DefinedOperator::IntrinsicOperator::AND:
- case parser::DefinedOperator::IntrinsicOperator::OR:
- case parser::DefinedOperator::IntrinsicOperator::EQV:
- case parser::DefinedOperator::IntrinsicOperator::NEQV:
- return true;
- case parser::DefinedOperator::IntrinsicOperator::Subtract:
- context_.Say(GetContext().clauseSource,
- "The minus reduction operator is deprecated since OpenMP 5.2 and is not supported in the REDUCTION clause."_err_en_US,
- ContextDirectiveAsFortran());
+ if (!CheckReductionIntrinsicOperator(*intrinsicOp, source)) {
+ context_.Say(source,
+ "Invalid reduction operator in %s clause"_err_en_US,
+ GetUpperName(clauseId, version));
return false;
- default:
- break;
}
+ return true;
}
// User-defined operators are OK if there has been a declared reduction
// for that. We mangle those names to store the user details.
@@ -4304,7 +4329,7 @@ static std::optional<parser::CharBlock> MangledReductionIdentifier(
if (const auto *intrinsicOp{
std::get_if<parser::DefinedOperator::IntrinsicOperator>(
&dOpr.u)}) {
- return MakeNameFromOperator(*intrinsicOp, context);
+ return MakeNameFromOperator(*intrinsicOp);
}
if (const auto *definedOp{
std::get_if<parser::DefinedOpName>(&dOpr.u)};
@@ -4389,7 +4414,7 @@ static bool IsReductionAllowedForType(
DIE("This should have been caught in CheckIntrinsicOperator");
return false;
}
- parser::CharBlock name{MakeNameFromOperator(*intrinsicOp, context)};
+ parser::CharBlock name{MakeNameFromOperator(*intrinsicOp)};
return CheckSymbolSupportsType(scope, name, type);
} else if (const auto *definedOp{
std::get_if<parser::DefinedOpName>(&dOpr.u)}) {
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index 530ad90abcefc6..39652012714191 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -487,6 +487,8 @@ class OmpStructureChecker : public OmpStructureCheckerBase {
const parser::CharBlock &source, llvm::omp::Directive type);
void CheckReductionObjects(
const parser::OmpObjectList &objects, llvm::omp::Clause clauseId);
+ bool CheckReductionIntrinsicOperator(
+ parser::DefinedOperator::IntrinsicOperator op, parser::CharBlock source);
bool CheckReductionOperator(const parser::OmpReductionIdentifier &ident,
parser::CharBlock source, llvm::omp::Clause clauseId);
void CheckReductionObjectTypes(const parser::OmpObjectList &objects,
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index f67f567578e906..562d290240b77f 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -2181,8 +2181,7 @@ void OmpVisitor::ProcessReductionSpecifier(
mangledName = context().SaveTempName(MangleDefinedOperator(name->source));
} else {
mangledName = MakeNameFromOperator(
- std::get<parser::DefinedOperator::IntrinsicOperator>(defOp.u),
- context());
+ std::get<parser::DefinedOperator::IntrinsicOperator>(defOp.u));
}
}
diff --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp
index ce5c72a481c78b..32aa55c5bd73ab 100644
--- a/flang/lib/Semantics/tools.cpp
+++ b/flang/lib/Semantics/tools.cpp
@@ -1995,8 +1995,7 @@ bool AreSameModuleSymbol(const Symbol &symbol, const Symbol &other) {
}
parser::CharBlock MakeNameFromOperator(
- const parser::DefinedOperator::IntrinsicOperator &op,
- SemanticsContext &context) {
+ const parser::DefinedOperator::IntrinsicOperator &op) {
switch (op) {
case parser::DefinedOperator::IntrinsicOperator::Multiply:
return parser::CharBlock{"op.*", 4};
@@ -2015,7 +2014,6 @@ parser::CharBlock MakeNameFromOperator(
return parser::CharBlock{"op.NEQV", 7};
default:
- context.Say("Unsupported operator in DECLARE REDUCTION"_err_en_US);
return parser::CharBlock{"op.?", 4};
}
}
@@ -2031,8 +2029,8 @@ parser::CharBlock MangleSpecialFunctions(parser::CharBlock name) {
}
std::string MangleDefinedOperator(parser::CharBlock name) {
- CHECK(name[0] == '.' && name[name.size() - 1] == '.');
- return "op" + name.ToString();
+ CHECK(name.starts_with('.') && name.ends_with('.'));
+ return "op" + name.str();
}
std::string GetReductionFortranId(parser::CharBlock mangledName) {
diff --git a/flang/test/Semantics/OpenMP/declare-reduction-bad-operator.f90 b/flang/test/Semantics/OpenMP/declare-reduction-bad-operator.f90
index 1d1d2903a2780c..ce93b640f237bf 100644
--- a/flang/test/Semantics/OpenMP/declare-reduction-bad-operator.f90
+++ b/flang/test/Semantics/OpenMP/declare-reduction-bad-operator.f90
@@ -1,6 +1,6 @@
-! RUN: not %flang_fc1 -fdebug-dump-symbols -fopenmp -fopenmp-version=50 %s 2>&1 | FileCheck %s
+!RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=50
function func(n)
+!ERROR: Invalid reduction intrinsic operator in DECLARE REDUCTION directive
!$omp declare reduction(/:integer:omp_out=omp_out+omp_in)
-!CHECK: error: Unsupported operator in DECLARE REDUCTION
end function func
diff --git a/flang/test/Semantics/OpenMP/in-reduction.f90 b/flang/test/Semantics/OpenMP/in-reduction.f90
index 0472774704334c..54d11028f8e45e 100644
--- a/flang/test/Semantics/OpenMP/in-reduction.f90
+++ b/flang/test/Semantics/OpenMP/in-reduction.f90
@@ -9,7 +9,7 @@ subroutine f00
subroutine f01
real :: x
-!ERROR: Invalid reduction operator in IN_REDUCTION clause.
+!ERROR: Invalid reduction operator in IN_REDUCTION clause
!$omp target in_reduction(.not.: x)
!$omp end target
end
diff --git a/flang/test/Semantics/OpenMP/reduction-subtract.f90 b/flang/test/Semantics/OpenMP/reduction-subtract.f90
index d4034743a14dc7..fc0dd98da32d9d 100644
--- a/flang/test/Semantics/OpenMP/reduction-subtract.f90
+++ b/flang/test/Semantics/OpenMP/reduction-subtract.f90
@@ -4,7 +4,8 @@
subroutine reduction_subtract
integer :: x
- !ERROR: The minus reduction operator is deprecated since OpenMP 5.2 and is not supported in the REDUCTION clause.
+ !ERROR: Invalid reduction operator in REDUCTION clause
+ !ERROR: The minus reduction operator is deprecated since OpenMP 5.2
!$omp do reduction(-:x)
do i=1, 100
x = x - i
diff --git a/flang/test/Semantics/OpenMP/reduction01.f90 b/flang/test/Semantics/OpenMP/reduction01.f90
index 0e1a8a571c5847..d08b55c4b92141 100644
--- a/flang/test/Semantics/OpenMP/reduction01.f90
+++ b/flang/test/Semantics/OpenMP/reduction01.f90
@@ -5,7 +5,7 @@ program omp_reduction
integer :: i
integer :: k = 10
- !ERROR: Invalid reduction operator in REDUCTION clause.
+ !ERROR: Invalid reduction operator in REDUCTION clause
!$omp parallel do reduction(**:k)
do i = 1, 10
k = k ** 1
diff --git a/flang/test/Semantics/OpenMP/reduction14.f90 b/flang/test/Semantics/OpenMP/reduction14.f90
index 7d3f8d468f7652..966c0610c8e924 100644
--- a/flang/test/Semantics/OpenMP/reduction14.f90
+++ b/flang/test/Semantics/OpenMP/reduction14.f90
@@ -23,7 +23,8 @@ program omp_reduction
!$omp end parallel
! - is deprecated for all types
- ! ERROR: The minus reduction operator is deprecated since OpenMP 5.2 and is not supported in the REDUCTION clause.
+ ! ERROR: Invalid reduction operator in REDUCTION clause
+ ! ERROR: The minus reduction operator is deprecated since OpenMP 5.2
!$omp parallel reduction(-:i,r,c,z,l)
!$omp end parallel
diff --git a/flang/test/Semantics/OpenMP/task-reduction.f90 b/flang/test/Semantics/OpenMP/task-reduction.f90
index 7e43332d53fe1e..efbfa6ba199f5f 100644
--- a/flang/test/Semantics/OpenMP/task-reduction.f90
+++ b/flang/test/Semantics/OpenMP/task-reduction.f90
@@ -9,7 +9,7 @@ subroutine f00
subroutine f01
real :: x
-!ERROR: Invalid reduction operator in TASK_REDUCTION clause.
+!ERROR: Invalid reduction operator in TASK_REDUCTION clause
!$omp taskgroup task_reduction(.not.: x)
!$omp end taskgroup
end
More information about the llvm-branch-commits
mailing list