================
@@ -908,10 +908,17 @@ static bool ShouldRemoveFromUnused(Sema *SemaRef, const 
DeclaratorDecl *D) {
 
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     // If this is a function template and none of its specializations is used,
-    // we should warn.
+    // we should warn. A specialization that was implicitly instantiated only
+    // because it was named in an unevaluated operand (decltype, sizeof,
+    // noexcept, a requires-expression) is referenced but never odr-used and
+    // never gets a body; the template still determined the meaning of that
+    // expression, so treat it as a use.
     if (FunctionTemplateDecl *Template = FD->getDescribedFunctionTemplate())
       for (const auto *Spec : Template->specializations())
-        if (ShouldRemoveFromUnused(SemaRef, Spec))
+        if (ShouldRemoveFromUnused(SemaRef, Spec) ||
+            (Spec->getTemplateSpecializationKind() ==
+                 TSK_ImplicitInstantiation &&
+             Spec->isReferenced()))
----------------
zyn0217 wrote:

Why aren't those instantiations covered by ShouldRemoveFromUnused? We do have 
the following things

```cpp
  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
    // If this is a function template and none of its specializations is used,
    // we should warn.
    if (FunctionTemplateDecl *Template = FD->getDescribedFunctionTemplate())
      for (const auto *Spec : Template->specializations())
        if (ShouldRemoveFromUnused(SemaRef, Spec))
          return true;
```


https://github.com/llvm/llvm-project/pull/234168
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to