<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - -Wunneeded-internal-declaration warned on needed function"
   href="https://bugs.llvm.org/show_bug.cgi?id=43598">43598</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>-Wunneeded-internal-declaration warned on needed function
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Frontend
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>leonardchan@google.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org, neeilans@live.com, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>For this code:

```
  1 #include <type_traits>
  2 
  3 namespace {
  4 
  5 // Check if Op is convertible to bool.
  6 template <typename Op>
  7 using enable_relop_t = std::enable_if_t<(std::is_convertible<Op,
bool>::value), bool>;
  8 
  9 // Chek if can do == with T and U.
 10 template <typename T, typename U,
 11          enable_relop_t<decltype(std::declval<T>() == std::declval<U>())> =
true>
 12 constexpr bool is_comparable(T&&, U&&) {
 13   return true;
 14 }
 15 
 16 struct comparable_a {};
 17 
 18 constexpr bool operator==(const comparable_a&, const comparable_a&) {
return true; }
 19 
 20 static_assert(is_comparable(comparable_a{}, comparable_a{}));
 21 
 22 }
```

We get this warning on line 18: warning: function 'operator==' is not needed
and will not be emitted [-Wunneeded-internal-declaration]. If the function were
truly unneeded, I would assume I should just be able to comment out line 18 and
everything should still compile, but I would get an `error no matching function
for call to 'is_comparable'` meaning it was used.

Compiled with `bin/clang++ ~/misc/test.cpp -c -std=c++17 -Wall` from ToT clang.

I'm noticing that this compiles without warnings also if I don't wrap
everything in an unnamed namespace or mark operator== with
__attrubute__((used)).</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>