https://github.com/flash1729 created https://github.com/llvm/llvm-project/pull/207942
None >From ba7b242aeb71a7c1ae0361b48046f023e4711e05 Mon Sep 17 00:00:00 2001 From: flash1729 <[email protected]> Date: Tue, 7 Jul 2026 14:40:57 +0530 Subject: [PATCH 1/2] [flang-rt] Fix -Wunused-template in time intrinsics and test helpers (NFC) time-intrinsic.cpp implements the timing intrinsics as SFINAE overload sets (preferred/fallback per platform), so on any given platform some overloads are intentionally never instantiated and trip -Wunused-template. Mark all variants [[maybe_unused]]. StoreElement and MakeArray in unittests/Runtime/tools.h are static function templates in a header, so any test TU that includes it without using all of them trips the warning. Drop static. Part of #202945. --- flang-rt/lib/runtime/time-intrinsic.cpp | 32 ++++++++++++++++--------- flang-rt/unittests/Runtime/tools.h | 6 ++--- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/flang-rt/lib/runtime/time-intrinsic.cpp b/flang-rt/lib/runtime/time-intrinsic.cpp index e72b12663ec4c..89e199a1bc79d 100644 --- a/flang-rt/lib/runtime/time-intrinsic.cpp +++ b/flang-rt/lib/runtime/time-intrinsic.cpp @@ -54,7 +54,8 @@ using fallback_implementation = double; using preferred_implementation = int; // This is the fallback implementation, which should work everywhere. -template <typename Unused = void> double GetCpuTime(fallback_implementation) { +template <typename Unused = void> +[[maybe_unused]] double GetCpuTime(fallback_implementation) { std::clock_t timestamp{std::clock()}; if (timestamp != static_cast<std::clock_t>(-1)) { return static_cast<double>(timestamp) / CLOCKS_PER_SEC; @@ -106,7 +107,7 @@ template <typename Unused = void> double GetCpuTime(fallback_implementation) { // POSIX implementation using clock_gettime. This is only enabled where // clock_gettime is available. template <typename T = int, typename U = struct timespec> -double GetCpuTime(preferred_implementation, +[[maybe_unused]] double GetCpuTime(preferred_implementation, // We need some dummy parameters to pass to decltype(clock_gettime). T ClockId = 0, U *Timespec = nullptr, decltype(clock_gettime(ClockId, Timespec)) *Enabled = nullptr) { @@ -165,7 +166,8 @@ static count_t ConvertTimevalToCount(int kind, const struct timeval &tval) { } template <typename Unused = void> -static count_t GetSystemClockCount(int kind, fallback_implementation) { +[[maybe_unused]] static count_t GetSystemClockCount( + int kind, fallback_implementation) { struct timeval tval; if (gettimeofday(&tval, /*timezone=*/nullptr) != 0) { @@ -192,7 +194,8 @@ count_t ConvertTimeSpecToCount(int kind, const struct timespec &tspec) { #ifndef _AIX // More accurate version with nanosecond accuracy template <typename Unused = void> -static count_t GetSystemClockCount(int kind, fallback_implementation) { +[[maybe_unused]] static count_t GetSystemClockCount( + int kind, fallback_implementation) { struct timespec tspec; if (timespec_get(&tspec, TIME_UTC) < 0) { @@ -208,12 +211,14 @@ static count_t GetSystemClockCount(int kind, fallback_implementation) { #endif // !NO_TIMESPEC template <typename Unused = void> -static count_t GetSystemClockCountRate(int kind, fallback_implementation) { +[[maybe_unused]] static count_t GetSystemClockCountRate( + int kind, fallback_implementation) { return kind >= 8 ? NS_PER_SEC : kind >= 2 ? MS_PER_SEC : DS_PER_SEC; } template <typename Unused = void> -static count_t GetSystemClockCountMax(int kind, fallback_implementation) { +[[maybe_unused]] static count_t GetSystemClockCountMax( + int kind, fallback_implementation) { unsigned_count_t maxCount{GetHUGE(kind)}; return maxCount; } @@ -221,7 +226,8 @@ static count_t GetSystemClockCountMax(int kind, fallback_implementation) { #ifndef NO_TIMESPEC #ifdef CLOCKID_ELAPSED_TIME template <typename T = int, typename U = struct timespec> -static count_t GetSystemClockCount(int kind, preferred_implementation, +[[maybe_unused]] static count_t GetSystemClockCount(int kind, + preferred_implementation, // We need some dummy parameters to pass to decltype(clock_gettime). T ClockId = 0, U *Timespec = nullptr, decltype(clock_gettime(ClockId, Timespec)) *Enabled = nullptr) { @@ -238,7 +244,8 @@ static count_t GetSystemClockCount(int kind, preferred_implementation, #endif // CLOCKID_ELAPSED_TIME template <typename T = int, typename U = struct timespec> -static count_t GetSystemClockCountRate(int kind, preferred_implementation, +[[maybe_unused]] static count_t GetSystemClockCountRate(int kind, + preferred_implementation, // We need some dummy parameters to pass to decltype(clock_gettime). T ClockId = 0, U *Timespec = nullptr, decltype(clock_gettime(ClockId, Timespec)) *Enabled = nullptr) { @@ -246,7 +253,8 @@ static count_t GetSystemClockCountRate(int kind, preferred_implementation, } template <typename T = int, typename U = struct timespec> -static count_t GetSystemClockCountMax(int kind, preferred_implementation, +[[maybe_unused]] static count_t GetSystemClockCountMax(int kind, + preferred_implementation, // We need some dummy parameters to pass to decltype(clock_gettime). T ClockId = 0, U *Timespec = nullptr, decltype(clock_gettime(ClockId, Timespec)) *Enabled = nullptr) { @@ -361,14 +369,16 @@ static std::size_t getUTCOffsetToBuffer( // SFINAE helper to return the struct tm.tm_gmtoff which is not a POSIX standard // field. template <int KIND, typename TM = struct tm> -Fortran::runtime::CppTypeFor<Fortran::common::TypeCategory::Integer, KIND> +[[maybe_unused]] Fortran::runtime::CppTypeFor< + Fortran::common::TypeCategory::Integer, KIND> GetGmtOffset(const TM &tm, preferred_implementation, decltype(tm.tm_gmtoff) *Enabled = nullptr) { // Returns the GMT offset in minutes. return tm.tm_gmtoff / 60; } template <int KIND, typename TM = struct tm> -Fortran::runtime::CppTypeFor<Fortran::common::TypeCategory::Integer, KIND> +[[maybe_unused]] Fortran::runtime::CppTypeFor< + Fortran::common::TypeCategory::Integer, KIND> GetGmtOffset(const TM &tm, fallback_implementation) { // tm.tm_gmtoff is not available, there may be platform dependent alternatives // (such as using timezone from <time.h> when available), but so far just diff --git a/flang-rt/unittests/Runtime/tools.h b/flang-rt/unittests/Runtime/tools.h index 4ada862df110b..a20b21f4ea760 100644 --- a/flang-rt/unittests/Runtime/tools.h +++ b/flang-rt/unittests/Runtime/tools.h @@ -21,19 +21,19 @@ namespace Fortran::runtime { template <typename A> -static void StoreElement(void *p, const A &x, std::size_t bytes) { +void StoreElement(void *p, const A &x, std::size_t bytes) { std::memcpy(p, &x, bytes); } template <typename CHAR> -static void StoreElement( +void StoreElement( void *p, const std::basic_string<CHAR> &str, std::size_t bytes) { ASSERT_LE(bytes, sizeof(CHAR) * str.size()); std::memcpy(p, str.data(), bytes); } template <TypeCategory CAT, int KIND, typename A> -static OwningPtr<Descriptor> MakeArray(const std::vector<int> &shape, +OwningPtr<Descriptor> MakeArray(const std::vector<int> &shape, const std::vector<A> &data, std::size_t elemLen = CAT == TypeCategory::Complex ? 2 * KIND : KIND) { auto rank{static_cast<int>(shape.size())}; >From 6b33038502139b072c413b3ccbe678efbcba0686 Mon Sep 17 00:00:00 2001 From: flash1729 <[email protected]> Date: Fri, 26 Jun 2026 21:40:49 +0530 Subject: [PATCH 2/2] [Clang] Enable -Wunused-template under -Wall Uncomment UnusedTemplate in the Unused diagnostic group so -Wunused-template is part of -Wall. It diagnoses unused function and variable templates with internal linkage; in a header, such a template gives every translation unit its own internal-linkage copy, which is a latent ODR violation. Also update the affected tests (Misc/warning-wall.c and the warn-func-not-needed.cpp / warn-variable-not-needed.cpp -verify tests) and add a release note. Closes #202945. --- clang/docs/ReleaseNotes.md | 5 +++++ clang/include/clang/Basic/DiagnosticGroups.td | 2 +- clang/test/Misc/warning-wall.c | 2 ++ clang/test/SemaCXX/warn-func-not-needed.cpp | 2 +- clang/test/SemaCXX/warn-variable-not-needed.cpp | 2 +- 5 files changed, 10 insertions(+), 3 deletions(-) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index cc85604343da9..e81670acb0452 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -563,6 +563,11 @@ latest release, please see the [Clang Web Site](https://clang.llvm.org) or the allowing it to be disabled independently with `-Wno-unused-but-set-global`. (#GH148361) +- `-Wunused-template` is now part of `-Wunused` (which is enabled by `-Wall`). + It diagnoses unused function and variable templates with internal linkage, + which in a header is a latent ODR hazard. It can be disabled with + `-Wno-unused-template`. (#GH202945) + - Added `-Wlifetime-safety` to enable lifetime safety analysis, a CFG-based intra-procedural analysis that detects use-after-free and related temporal safety bugs. See the diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 73fb97aeeb302..79583534b9bbd 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -1369,7 +1369,7 @@ def Conversion def Unused : DiagGroup<"unused", [UnusedArgument, UnusedFunction, UnusedLabel, // UnusedParameter, (matches GCC's behavior) - // UnusedTemplate, (clean-up libc++ before enabling) + UnusedTemplate, // UnusedMemberFunction, (clean-up llvm before enabling) UnusedPrivateField, UnusedLambdaCapture, UnusedLocalTypedef, UnusedValue, UnusedVariable, diff --git a/clang/test/Misc/warning-wall.c b/clang/test/Misc/warning-wall.c index 6d6c4e562400f..ade9cbaace77e 100644 --- a/clang/test/Misc/warning-wall.c +++ b/clang/test/Misc/warning-wall.c @@ -73,6 +73,8 @@ CHECK-NEXT: -Wunused-argument CHECK-NEXT: -Wunused-function CHECK-NEXT: -Wunneeded-internal-declaration CHECK-NEXT: -Wunused-label +CHECK-NEXT: -Wunused-template +CHECK-NEXT: -Wunneeded-internal-declaration CHECK-NEXT: -Wunused-private-field CHECK-NEXT: -Wunused-lambda-capture CHECK-NEXT: -Wunused-local-typedef diff --git a/clang/test/SemaCXX/warn-func-not-needed.cpp b/clang/test/SemaCXX/warn-func-not-needed.cpp index cb3cae4cd6c76..74438543c43b7 100644 --- a/clang/test/SemaCXX/warn-func-not-needed.cpp +++ b/clang/test/SemaCXX/warn-func-not-needed.cpp @@ -10,7 +10,7 @@ void foo() { } namespace test1_template { -template <typename T> static void f() {} +template <typename T> static void f() {} // expected-warning {{unused function template}} template <> void f<int>() {} // expected-warning {{function 'f<int>' is not needed and will not be emitted}} template <typename T> void foo() { diff --git a/clang/test/SemaCXX/warn-variable-not-needed.cpp b/clang/test/SemaCXX/warn-variable-not-needed.cpp index 272c8998d15c0..d234e9140e3fd 100644 --- a/clang/test/SemaCXX/warn-variable-not-needed.cpp +++ b/clang/test/SemaCXX/warn-variable-not-needed.cpp @@ -4,7 +4,7 @@ namespace test1 { static int abc = 42; // expected-warning {{variable 'abc' is not needed and will not be emitted}} namespace { - template <typename T> int abc_template = 0; + template <typename T> int abc_template = 0; // expected-warning {{unused variable template}} template <> int abc_template<int> = 0; // expected-warning {{variable 'abc_template<int>' is not needed and will not be emitted}} } // namespace template <typename T> _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
