[cfe-dev] CallEvent::isCalled() alternative if a function is called by pointer

Artem Razin via cfe-dev cfe-dev at lists.llvm.org
Thu May 3 08:35:14 PDT 2018


Hi Artem,

It seems I was wrong, the situation is not so simple as I thought initially.

First of all, here the checkPreCall() call, it checks a call against
CloseHandle and outputs result along with passed function information:

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();
}

The first sample uses usual CloseHandle call, without function pointer:
CloseHandle(NULL);

So it works.

My original code that didn't work has used template class. The simplified
code:

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;
}

The output:

It's NOT CloseHandle: &CloseHandle(this->_h)
It's NOT CloseHandle: 0
It's NOT CloseHandle: Call to ~AutoCloseHandle<&CloseHandle>() noexcept {
    &CloseHandle(this->_h);
}
It's NOT CloseHandle: &CloseHandle(this->_h)

> Could you see if you can get Call.getOriginExpr()->dump() and/or
Call.getDecl()->dump()? These should be more informative.

Sure, I've added it. 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

Call.dump()'s result:

&CloseHandle(this->_h)

Thank you!

2018-05-02 23:32 GMT+03:00 Artem Dergachev <noqnoqneo at gmail.com>:

> On 5/2/18 3:58 AM, Artem Razin via cfe-dev wrote:
>
> Hi All,
>
> I hope this is right place to ask such a newbie question like the
> following.
>
> I am trying to write a checker to catch potential handle leaks (it's on
> Windows: a handle is closed by CloseHandle).
>
> So I took SimpleStreamChecker as a base, now my checkPreCall() checks if
> "CloseHandle" is called. Call.isCalled() works great except one case when
> CloseHandle is called by pointer. It happens because of using a template
> class that took a pointer to closing function as template parameter (useful
> to close different types of handles by appropriate functions: FindClose,
> CloseHandle etc.).
>
> Call.dump() prints "&CloseHandle(this->m_h)" in this case, so it
> understands that this a pointer and that this is a pointer of
> CloseHandle.But how to "extract" the the identifier of CloseHandle?
>
>
> I'm not quite understanding that dump, it looks a bit weird. What is the
> actual code under analysis? Could you see if you can get
> Call.getOriginExpr()->dump() and/or Call.getDecl()->dump()? These should be
> more informative.
>
> In general the analyzer does indeed understand calls through function
> pointers, as long as it can at all be tracked by looking at the current
> execution path.
>
> And when it is tracked, CallEvent::isCalled() should "just work" because
> it only looks at Call.getDecl() which should be the path-specific decl.
>
>
> Thank you in advance!
>
> --
> Best regards,
> Artem A. Razin
>
> _______________________________________________
> cfe-dev mailing listcfe-dev at lists.llvm.orghttp://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
>
>


-- 
Best regards,
Artem A. Razin
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20180503/ba54586d/attachment.html>


More information about the cfe-dev mailing list