-Wunused-template already exists in Clang, but it's DefaultIgnore and commented out of the Unused diagnostic group in clang/include/clang/Basic/DiagnosticGroups.td, so it isn't part of -Wall. This issue tracks cleaning up the remaining in-tree occurrences and then enabling the warning.
Why it helps
A static (or anonymous-namespace) function template defined in a header has internal linkage, so every translation unit that includes the header gets its own copy. When such a template is referenced from another inline function or template in a header, the definitions across TUs refer to different entities, which is a latent ODR violation (ill-formed, no diagnostic required). -Wunused-template surfaces these, and enabling it keeps the pattern from coming back.
Status
Building LLVM + Clang with the flag enabled:
- Started at 652 raw warnings (46 unique sites) across ~24 files.
- After the cleanup below, the tree builds completely clean (0 warnings).
- libc++/libc++abi/libunwind already build clean (handled in D144667), so the historical "clean up libc++ first" note is stale. The remaining work is in LLVM core and Clang.
Approach
Three kinds of warning, each with its own fix:
static or anonymous-namespace function template in a header: remove the internal linkage (drop static, or move it out of the anonymous namespace into a named one). Templates are implicitly inline, so nothing is added. This is the ODR fix.
- Template in a
.cpp that's never instantiated: dead code, delete it.
- Template used only inside
assert() or LLVM_DEBUG() (compiled out in release): mark [[maybe_unused]].
Cleanup PRs (per area, all NFC)
Final step
Prior art
- D29877: original implementation of
-Wunused-template (2017).
- D144667:
[libc++] Enable -Wunused-template (landed).
- D143524: earlier attempt to enable it by default (didn't land, bandwidth).
-Wunused-templatealready exists in Clang, but it'sDefaultIgnoreand commented out of theUnuseddiagnostic group inclang/include/clang/Basic/DiagnosticGroups.td, so it isn't part of-Wall. This issue tracks cleaning up the remaining in-tree occurrences and then enabling the warning.Why it helps
A
static(or anonymous-namespace) function template defined in a header has internal linkage, so every translation unit that includes the header gets its own copy. When such a template is referenced from another inline function or template in a header, the definitions across TUs refer to different entities, which is a latent ODR violation (ill-formed, no diagnostic required).-Wunused-templatesurfaces these, and enabling it keeps the pattern from coming back.Status
Building LLVM + Clang with the flag enabled:
Approach
Three kinds of warning, each with its own fix:
staticor anonymous-namespace function template in a header: remove the internal linkage (dropstatic, or move it out of the anonymous namespace into a named one). Templates are implicitly inline, so nothing is added. This is the ODR fix..cppthat's never instantiated: dead code, delete it.assert()orLLVM_DEBUG()(compiled out in release): mark[[maybe_unused]].Cleanup PRs (per area, all NFC)
[Object][ELF]Remove internal linkage from header function templates (NFC) / Approved, Wait for past contributor to acknowledge the change[Mips]Remove unused function templates (NFC) / Approved[JITLink][ORC]Clean up unused and assert-only function templates (NFC) / Approved[VPlan]Remove internal linkage fromfindUserOftemplates (NFC) / Approved need to merge[IR]Remove unused and mark debug-only verifier templates (NFC)[clang]Fix-Wunused-templatein AST/analysis helpers (NFC)[clang]Clean up unused/assert-only frontend helpers (NFC)[FunctionAttrs]Remove unused legacy-PMrunImpltemplate (NFC)[OpenMP]Remove unusedisStrictSubsettemplate (NFC)Final step
[Clang]Enable-Wunused-templateunder-Wall-- uncommentUnusedTemplateinDiagnosticGroups.tdand update testsPrior art
-Wunused-template(2017).[libc++] Enable -Wunused-template(landed).