<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 - CallEvent::isCalled() failed for a call made by template parameter that is a function pointer"
   href="https://bugs.llvm.org/show_bug.cgi?id=37370">37370</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>CallEvent::isCalled() failed for a call made by template parameter that is a function pointer
          </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>Windows NT
          </td>
        </tr>

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

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>Static Analyzer
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>dcoughlin@apple.com
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>artem.razin@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org, noqnoqneo@gmail.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>While trying create a handle leak detection checker found the following issue.

Here the checkPreCall() call, it checks a call against CloseHandle (used in
Windows API to close handles):

void HandleChecker::checkPreCall(
        const CallEvent &Call,
        CheckerContext &C) const
{
        if (Call.isCalled(_closeHandleFn))
                fprintf(stderr, "It's CloseHandle: ");
        else
                fprintf(stderr, "It's NOT CloseHandle: ");
        Call.dump();
}

It works as expected when a code calls CloseHandle by usual call, or by
pointer, but when CloseHandle address is used as template parameter
Call.isCalled() fails.

The code that was checked to reproduce the behavior is the following:

typedef BOOL (WINAPI *P_CloseHandle)(HANDLE);

template <P_CloseHandle pCloseHandle> struct AutoCloseHandle
{
  AutoCloseHandle(HANDLE h) : _h(h) {}
  ~AutoCloseHandle() { pCloseHandle(_h); };
  HANDLE _h;
};

int main()
{
  AutoCloseHandle<&CloseHandle> autoCloseHandle(NULL);
  return 1;
}

Additionally I've checked Call.getDecl() and Call.getOriginExpr().

Call.getDecl() is NULL for that call. Call.getOriginExpr() is the following:

CallExpr 0x64ecb10 'BOOL':'int'
|-SubstNonTypeTemplateParmExpr 0x64ecac0 'BOOL (*)(HANDLE)
__attribute__((stdcall))'
| `-UnaryOperator 0x64ecaa8 'BOOL (*)(HANDLE) __attribute__((stdcall))' prefix
'&' cannot overflow
|   `-DeclRefExpr 0x64eca90 'BOOL (HANDLE) __attribute__((stdcall))':'BOOL
(HANDLE) __attribute__((stdcall))' lvalue Function 0x57b8890 'CloseHandle'
'BOOL (HANDLE) __attribute__((stdcall))':'BOOL (HANDLE)
__attribute__((stdcall))'
`-ImplicitCastExpr 0x64ecb30 'HANDLE':'void *' <LValueToRValue>
  `-MemberExpr 0x64ecae8 'HANDLE':'void *' lvalue ->_h 0x64dc710
    `-CXXThisExpr 0x64ecad8 'struct AutoCloseHandle<&CloseHandle> *' this</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>