<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 - non-template friend does not find function template"
   href="https://bugs.llvm.org/show_bug.cgi?id=34329">34329</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>non-template friend does not find function template
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>new-bugs
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>4.0
          </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>new bugs
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>aschepler@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>clang rejects this well-formed code:

template <typename T>
int f(T& obj) { return obj.m; }

class X {
private:
    int m;
    friend int ::f(X&);
};

int main() {
    X x;
    f(x);
}

The error message is:
7 : <source>:7:18: error: out-of-line declaration of 'f' does not match any
declaration in the global namespace
    friend int ::f(X&);
                 ^

This situation is described in Standard section [temp.friend].  (The wording
was clarified some in C++11, but has the same meaning as in C++03, and has not
changed since.)

Quote:

For a friend function declaration that is not a template declaration:

- if the name of the friend is a qualified or unqualified template-id, the
friend declaration refers to a specialization of a function template,
otherwise,

- if the name of the friend is a qualified-id and a matching non-template
function is found in the specified class or namespace, the friend declaration
refers to that function, otherwise,

- if the name of the friend is a qualified-id and a matching function template
is found in the specified class or namespace, the friend declaration refers to
the deduced specialization of that function template ([]), otherwise,

- the name shall be an unqualified-id that declares (or redeclares) a
non-template function.

End Quote.

In this code, the first bullet does not apply because ::f is not a template-id
(there are no <> tokens).  ::f is a qualfied-id, so the second bullet should be
checked, but there is no matching non-template function named ::f.  The third
bullet is what makes the code well-formed: the compiler should deduce a
specialization of the function template ::f.  Since deduction should succeed,
the friend names a specialization of ::f.

(gcc 7.2, icc 17, and MSVC 19.00.23506 all accept the above code.)</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>