[flang-commits] [flang] [Flang][#212316] Fix -Wunused-template errors under -Werror (PR #218985)
via flang-commits
flang-commits at lists.llvm.org
Wed Sep 2 05:19:18 PDT 2026
https://github.com/laoshd updated https://github.com/llvm/llvm-project/pull/218985
>From f63def66285bb16c811d4d5c4e33005d762bee6f Mon Sep 17 00:00:00 2001
From: Shandong Lao <shandong.lao at hpe.com>
Date: Wed, 26 Aug 2026 11:46:48 -0500
Subject: [PATCH 1/3] [Flang][#212316] Fix -Wunused-template errors under
-Werror
Some function templates with internal linkage are never instantiated in
their translation unit, which triggers -Wunused-template. With clang
builds that enable this warning by default and -DFLANG_ENABLE_WERROR=ON,
these become fatal errors.
Fix each case with the minimal change that preserves semantics:
- Drop 'static' (give external linkage) for free function templates at
namespace/file scope: DirectivesCommon.h, PFTBuilder.h, RTBuilder.h,
fold-reduction.h, formatting.cpp, check-cuda.cpp, resolve-directives.cpp.
- Add [[maybe_unused]] where dropping 'static' would change linkage/ODR
semantics (member, anonymous-namespace, or global generic-named
templates): ConvertType.cpp, IO.cpp, CUFAllocationConversion.cpp,
openmp-utils.cpp.
No functional change. With AI assistance.
---
flang/include/flang/Lower/DirectivesCommon.h | 4 ++--
flang/include/flang/Lower/PFTBuilder.h | 2 +-
.../flang/Optimizer/Builder/Runtime/RTBuilder.h | 4 ++--
flang/lib/Evaluate/fold-reduction.h | 12 ++++++------
flang/lib/Evaluate/formatting.cpp | 4 ++--
flang/lib/Lower/ConvertType.cpp | 3 ++-
flang/lib/Lower/IO.cpp | 5 +++--
.../Transforms/CUDA/CUFAllocationConversion.cpp | 2 +-
flang/lib/Semantics/check-cuda.cpp | 2 +-
flang/lib/Semantics/openmp-utils.cpp | 6 ++++--
flang/lib/Semantics/resolve-directives.cpp | 2 +-
11 files changed, 25 insertions(+), 21 deletions(-)
diff --git a/flang/include/flang/Lower/DirectivesCommon.h b/flang/include/flang/Lower/DirectivesCommon.h
index 6f6089a4ffb6c..ac129ef18d7e0 100644
--- a/flang/include/flang/Lower/DirectivesCommon.h
+++ b/flang/include/flang/Lower/DirectivesCommon.h
@@ -75,11 +75,11 @@ getDataOperandBaseAddr(Fortran::lower::AbstractConverter &converter,
namespace detail {
template <typename T> //
-static T &&AsRvalueRef(T &&t) {
+T &&AsRvalueRef(T &&t) {
return std::move(t);
}
template <typename T> //
-static T AsRvalueRef(T &t) {
+T AsRvalueRef(T &t) {
return t;
}
template <typename T> //
diff --git a/flang/include/flang/Lower/PFTBuilder.h b/flang/include/flang/Lower/PFTBuilder.h
index 8a59dd6638b71..f34024a5ed903 100644
--- a/flang/include/flang/Lower/PFTBuilder.h
+++ b/flang/include/flang/Lower/PFTBuilder.h
@@ -849,7 +849,7 @@ struct Program {
/// Helper to get location from FunctionLikeUnit/ModuleLikeUnit begin/end
/// statements.
template <typename T>
-static parser::CharBlock stmtSourceLoc(const T &stmt) {
+parser::CharBlock stmtSourceLoc(const T &stmt) {
return stmt.visit(common::visitors{[](const auto &x) { return x.source; }});
}
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h b/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h
index e2131aa7708a3..f18b09fb3fd93 100644
--- a/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h
+++ b/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h
@@ -843,7 +843,7 @@ struct RuntimeTableEntry<RuntimeTableKey<KT>, RuntimeIdentifier<Cs...>> {
/// Get (or generate) the MLIR FuncOp for a given runtime function. Its template
/// argument is intended to be of the form: <mkRTKey(runtime function name)>.
template <typename RuntimeEntry>
-static mlir::func::FuncOp getRuntimeFunc(mlir::Location loc,
+mlir::func::FuncOp getRuntimeFunc(mlir::Location loc,
fir::FirOpBuilder &builder,
bool isIO = false) {
using namespace Fortran::runtime;
@@ -857,7 +857,7 @@ static mlir::func::FuncOp getRuntimeFunc(mlir::Location loc,
/// Get (or generate) the MLIR FuncOp for a given IO runtime function.
template <typename E>
-static mlir::func::FuncOp getIORuntimeFunc(mlir::Location loc,
+mlir::func::FuncOp getIORuntimeFunc(mlir::Location loc,
fir::FirOpBuilder &builder) {
return getRuntimeFunc<E>(loc, builder, /*isIO=*/true);
}
diff --git a/flang/lib/Evaluate/fold-reduction.h b/flang/lib/Evaluate/fold-reduction.h
index a068364135295..566e04ed772bf 100644
--- a/flang/lib/Evaluate/fold-reduction.h
+++ b/flang/lib/Evaluate/fold-reduction.h
@@ -15,7 +15,7 @@ namespace Fortran::evaluate {
// DOT_PRODUCT
template <typename T>
-static Expr<T> FoldDotProduct(
+Expr<T> FoldDotProduct(
FoldingContext &context, FunctionRef<T> &&funcRef) {
using Element = typename Constant<T>::Element;
auto args{funcRef.arguments()};
@@ -132,7 +132,7 @@ template <typename T> struct ArrayAndMask {
Constant<LogicalResult> mask;
};
template <typename T>
-static std::optional<ArrayAndMask<T>> ProcessReductionArgs(
+std::optional<ArrayAndMask<T>> ProcessReductionArgs(
FoldingContext &context, ActualArguments &arg, std::optional<int> &dim,
int arrayIndex, std::optional<int> dimIndex = std::nullopt,
std::optional<int> maskIndex = std::nullopt) {
@@ -174,7 +174,7 @@ static std::optional<ArrayAndMask<T>> ProcessReductionArgs(
// operator()(Scalar<T> &, const ConstantSubscripts &, bool first)
// and Done(Scalar<T> &).
template <typename T, typename ACCUMULATOR, typename ARRAY>
-static Constant<T> DoReduction(const Constant<ARRAY> &array,
+Constant<T> DoReduction(const Constant<ARRAY> &array,
const Constant<LogicalResult> &mask, std::optional<int> &dim,
const Scalar<T> &identity, ACCUMULATOR &accumulator) {
ConstantSubscripts at{array.lbounds()};
@@ -265,7 +265,7 @@ template <typename T, bool ABS = false> class MaxvalMinvalAccumulator {
};
template <typename T>
-static Expr<T> FoldMaxvalMinval(FoldingContext &context, FunctionRef<T> &&ref,
+Expr<T> FoldMaxvalMinval(FoldingContext &context, FunctionRef<T> &&ref,
RelationalOperator opr, const Scalar<T> &identity) {
static_assert(T::category == TypeCategory::Integer ||
T::category == TypeCategory::Unsigned ||
@@ -309,7 +309,7 @@ template <typename T> class ProductAccumulator {
};
template <typename T>
-static Expr<T> FoldProduct(
+Expr<T> FoldProduct(
FoldingContext &context, FunctionRef<T> &&ref, Scalar<T> identity) {
static_assert(T::category == TypeCategory::Integer ||
T::category == TypeCategory::Unsigned ||
@@ -371,7 +371,7 @@ template <typename T> class SumAccumulator {
};
template <typename T>
-static Expr<T> FoldSum(FoldingContext &context, FunctionRef<T> &&ref) {
+Expr<T> FoldSum(FoldingContext &context, FunctionRef<T> &&ref) {
static_assert(T::category == TypeCategory::Integer ||
T::category == TypeCategory::Unsigned ||
T::category == TypeCategory::Real ||
diff --git a/flang/lib/Evaluate/formatting.cpp b/flang/lib/Evaluate/formatting.cpp
index fcedd15ee1791..1187daa5620cc 100644
--- a/flang/lib/Evaluate/formatting.cpp
+++ b/flang/lib/Evaluate/formatting.cpp
@@ -414,7 +414,7 @@ template <typename T> static Precedence ToPrecedence(const Expr<T> &expr) {
return common::visit([](const auto &x) { return ToPrecedence(x); }, expr.u);
}
-template <typename T> static bool IsNegatedScalarConstant(const Expr<T> &expr) {
+template <typename T> bool IsNegatedScalarConstant(const Expr<T> &expr) {
static constexpr TypeCategory cat{T::category};
if constexpr (cat == TypeCategory::Integer || cat == TypeCategory::Real) {
if (auto n{GetScalarConstantValue<T>(expr)}) {
@@ -425,7 +425,7 @@ template <typename T> static bool IsNegatedScalarConstant(const Expr<T> &expr) {
}
template <TypeCategory CAT>
-static bool IsNegatedScalarConstant(const Expr<SomeKind<CAT>> &expr) {
+bool IsNegatedScalarConstant(const Expr<SomeKind<CAT>> &expr) {
return common::visit(
[](const auto &x) { return IsNegatedScalarConstant(x); }, expr.u);
}
diff --git a/flang/lib/Lower/ConvertType.cpp b/flang/lib/Lower/ConvertType.cpp
index 0fdbdfcc74424..ca4f19c6fcb92 100644
--- a/flang/lib/Lower/ConvertType.cpp
+++ b/flang/lib/Lower/ConvertType.cpp
@@ -536,7 +536,8 @@ struct TypeBuilderImpl {
}
template <typename A>
- Fortran::lower::LenParameterTy getCharacterLength(const A &expr) {
+ [[maybe_unused]] Fortran::lower::LenParameterTy getCharacterLength(
+ const A &expr) {
return fir::SequenceType::getUnknownExtent();
}
diff --git a/flang/lib/Lower/IO.cpp b/flang/lib/Lower/IO.cpp
index 490db8cc1d1ba..8b44fe27ce9a8 100644
--- a/flang/lib/Lower/IO.cpp
+++ b/flang/lib/Lower/IO.cpp
@@ -126,14 +126,15 @@ static void genIoLoop(Fortran::lower::AbstractConverter &converter,
/// Helper function to retrieve the name of the IO function given the key `A`
template <typename A>
-static constexpr const char *getName() {
+[[maybe_unused]] static constexpr const char *getName() {
return std::get<A>(Fortran::lower::newIOTable).name;
}
/// Helper function to retrieve the type model signature builder of the IO
/// function as defined by the key `A`
template <typename A>
-static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
+[[maybe_unused]] static constexpr fir::runtime::FuncTypeBuilderFunc
+getTypeModel() {
return std::get<A>(Fortran::lower::newIOTable).getTypeModel();
}
diff --git a/flang/lib/Optimizer/Transforms/CUDA/CUFAllocationConversion.cpp b/flang/lib/Optimizer/Transforms/CUDA/CUFAllocationConversion.cpp
index b75d289faca7a..c8fb7b0797188 100644
--- a/flang/lib/Optimizer/Transforms/CUDA/CUFAllocationConversion.cpp
+++ b/flang/lib/Optimizer/Transforms/CUDA/CUFAllocationConversion.cpp
@@ -43,7 +43,7 @@ using namespace Fortran::runtime::cuda;
namespace {
template <typename OpTy>
-static bool isPinned(OpTy op) {
+[[maybe_unused]] bool isPinned(OpTy op) {
if (op.getDataAttr() && *op.getDataAttr() == cuf::DataAttribute::Pinned)
return true;
return false;
diff --git a/flang/lib/Semantics/check-cuda.cpp b/flang/lib/Semantics/check-cuda.cpp
index 8922e0eb559e8..5d432fd1f3db3 100644
--- a/flang/lib/Semantics/check-cuda.cpp
+++ b/flang/lib/Semantics/check-cuda.cpp
@@ -208,7 +208,7 @@ struct FindHostArray
};
template <typename A>
-static MaybeMsg CheckUnwrappedExpr(
+MaybeMsg CheckUnwrappedExpr(
SemanticsContext &context, const A &x, bool allowHostCallees = false) {
if (const auto *expr{parser::Unwrap<parser::Expr>(x)}) {
return DeviceExprChecker{context, allowHostCallees}(expr->typedExpr);
diff --git a/flang/lib/Semantics/openmp-utils.cpp b/flang/lib/Semantics/openmp-utils.cpp
index dc3d5a302e841..4050d95fd1ea3 100644
--- a/flang/lib/Semantics/openmp-utils.cpp
+++ b/flang/lib/Semantics/openmp-utils.cpp
@@ -462,11 +462,13 @@ struct ContiguousHelper {
: fctx_(context.foldingContext()) {}
template <typename Contained>
- std::optional<bool> Visit(const common::Indirection<Contained> &x) {
+ [[maybe_unused]] std::optional<bool> Visit(
+ const common::Indirection<Contained> &x) {
return Visit(x.value());
}
template <typename Contained>
- std::optional<bool> Visit(const common::Reference<Contained> &x) {
+ [[maybe_unused]] std::optional<bool> Visit(
+ const common::Reference<Contained> &x) {
return Visit(x.get());
}
template <typename T> std::optional<bool> Visit(const evaluate::Expr<T> &x) {
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 532f1f821b8f2..67678cdd68a0b 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -36,7 +36,7 @@
namespace Fortran::semantics {
template <typename T>
-static Scope *GetScope(SemanticsContext &context, const T &x) {
+Scope *GetScope(SemanticsContext &context, const T &x) {
if (auto source{GetLastSource(x)}) {
return &context.FindScope(*source);
} else {
>From f621113b4b915cd4147906d9daf57ff36785e5d8 Mon Sep 17 00:00:00 2001
From: Shandong Lao <shandong.lao at hpe.com>
Date: Wed, 26 Aug 2026 13:13:08 -0500
Subject: [PATCH 2/3] [Flang][#212316] Corrects code formats.
---
.../include/flang/Optimizer/Builder/Runtime/RTBuilder.h | 6 +++---
flang/lib/Evaluate/fold-reduction.h | 9 ++++-----
flang/lib/Lower/ConvertType.cpp | 4 ++--
flang/lib/Semantics/resolve-directives.cpp | 3 +--
4 files changed, 10 insertions(+), 12 deletions(-)
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h b/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h
index f18b09fb3fd93..67bdf6867251a 100644
--- a/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h
+++ b/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h
@@ -844,8 +844,8 @@ struct RuntimeTableEntry<RuntimeTableKey<KT>, RuntimeIdentifier<Cs...>> {
/// argument is intended to be of the form: <mkRTKey(runtime function name)>.
template <typename RuntimeEntry>
mlir::func::FuncOp getRuntimeFunc(mlir::Location loc,
- fir::FirOpBuilder &builder,
- bool isIO = false) {
+ fir::FirOpBuilder &builder,
+ bool isIO = false) {
using namespace Fortran::runtime;
auto name = RuntimeEntry::name;
auto func = builder.getNamedFunction(name);
@@ -858,7 +858,7 @@ mlir::func::FuncOp getRuntimeFunc(mlir::Location loc,
/// Get (or generate) the MLIR FuncOp for a given IO runtime function.
template <typename E>
mlir::func::FuncOp getIORuntimeFunc(mlir::Location loc,
- fir::FirOpBuilder &builder) {
+ fir::FirOpBuilder &builder) {
return getRuntimeFunc<E>(loc, builder, /*isIO=*/true);
}
diff --git a/flang/lib/Evaluate/fold-reduction.h b/flang/lib/Evaluate/fold-reduction.h
index 566e04ed772bf..aef5e93287297 100644
--- a/flang/lib/Evaluate/fold-reduction.h
+++ b/flang/lib/Evaluate/fold-reduction.h
@@ -15,8 +15,7 @@ namespace Fortran::evaluate {
// DOT_PRODUCT
template <typename T>
-Expr<T> FoldDotProduct(
- FoldingContext &context, FunctionRef<T> &&funcRef) {
+Expr<T> FoldDotProduct(FoldingContext &context, FunctionRef<T> &&funcRef) {
using Element = typename Constant<T>::Element;
auto args{funcRef.arguments()};
CHECK(args.size() == 2);
@@ -132,9 +131,9 @@ template <typename T> struct ArrayAndMask {
Constant<LogicalResult> mask;
};
template <typename T>
-std::optional<ArrayAndMask<T>> ProcessReductionArgs(
- FoldingContext &context, ActualArguments &arg, std::optional<int> &dim,
- int arrayIndex, std::optional<int> dimIndex = std::nullopt,
+std::optional<ArrayAndMask<T>> ProcessReductionArgs(FoldingContext &context,
+ ActualArguments &arg, std::optional<int> &dim, int arrayIndex,
+ std::optional<int> dimIndex = std::nullopt,
std::optional<int> maskIndex = std::nullopt) {
if (arg.empty()) {
return std::nullopt;
diff --git a/flang/lib/Lower/ConvertType.cpp b/flang/lib/Lower/ConvertType.cpp
index ca4f19c6fcb92..8bb8f359b2e79 100644
--- a/flang/lib/Lower/ConvertType.cpp
+++ b/flang/lib/Lower/ConvertType.cpp
@@ -536,8 +536,8 @@ struct TypeBuilderImpl {
}
template <typename A>
- [[maybe_unused]] Fortran::lower::LenParameterTy getCharacterLength(
- const A &expr) {
+ [[maybe_unused]] Fortran::lower::LenParameterTy
+ getCharacterLength(const A &expr) {
return fir::SequenceType::getUnknownExtent();
}
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 67678cdd68a0b..af6640eb40dac 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -35,8 +35,7 @@
namespace Fortran::semantics {
-template <typename T>
-Scope *GetScope(SemanticsContext &context, const T &x) {
+template <typename T> Scope *GetScope(SemanticsContext &context, const T &x) {
if (auto source{GetLastSource(x)}) {
return &context.FindScope(*source);
} else {
>From 27ef1525cf12bbb7844cb1d17a2b7436f07aceae Mon Sep 17 00:00:00 2001
From: Shandong Lao <shandong.lao at hpe.com>
Date: Wed, 2 Sep 2026 07:18:33 -0500
Subject: [PATCH 3/3] [FLANG][OMP] #219234: Add error message for invalid
dependence type in taskwait construct.
---
flang/lib/Semantics/check-omp-structure.cpp | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 274efa64d03d0..762c9bf8a9be7 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -5116,6 +5116,14 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Depend &x) {
context_.Say(GetContext().clauseSource,
"The SINK and SOURCE dependence types can only be used with the ORDERED directive, used here in the %s construct"_err_en_US,
parser::omp::GetUpperName(dir, version));
+ } else if (dir == llvm::omp::OMPD_taskwait &&
+ taskDep->GetTaskDepType() ==
+ parser::OmpTaskDependenceType::Value::Mutexinoutset) {
+ // A depend clause on a taskwait construct must not have
+ // mutexinoutset as dependence-type.
+ context_.Say(GetContext().clauseSource,
+ "A DEPEND clause on a TASKWAIT construct must not have %s as dependence type"_err_en_US,
+ "MUTEXINOUTSET");
}
}
if (taskDep) {
More information about the flang-commits
mailing list