[cfe-dev] Static analyzer question on how to tell if a Decl is a particular c++ function, or a particular class

Artem Dergachev via cfe-dev cfe-dev at lists.llvm.org
Thu Feb 15 10:26:35 PST 2018


Yeah, the traditional way to see if this is a certain method of a 
certain class is to compare the name of the method 
(CXXMethodDecl->getName()) and the class 
(CXXMethodDecl->getParent()->getName()), as strings, to the desired 
strings. getQualifiedNameAsString() works fine, but it's considered slow 
for whatever reason (i've never observed it personally). ASTMatchers 
would also work, even if a bit of an overkill. Don't forget to check the 
method's argument number and types as well. We have an effort to make 
this whole common idiom more simple via CallDescription, but it doesn't 
work for C++ methods yet.

With C++, you'll need to be aware of the bug we're currently having with 
object lifetime extension. If you're identifying the object by its 
memory region (which is correct), you'd occasionally notice that the 
region for a C++ temporary object may change along the analysis even if 
no copy-construction occurs. It has been making our new C++ checkers 
(most noticeably, the iterator checker) more difficult to write than 
they needed to be. More details in 
http://lists.llvm.org/pipermail/cfe-dev/2018-February/056898.html - i'm 
hoping to do something about it soon.

On 15/02/2018 1:35 AM, Aleksei Sidorin via cfe-dev wrote:
> Hello Li,
>
> What you're doing is mostly fine. I can only add some potentially 
> useful info inline.
>
> 14.02.2018 23:04, Li Kan via cfe-dev пишет:
>> Hi folks,
>>
>> If this is not the correct mailing list for this question, please let 
>> me know.
> You're in the right place. Welcome :)
>
>> I am trying to write a static analyzer for code base of my current 
>> job. The particular static analyzer I am writing involves a 
>> particular class of my company's code base. Let's say it is T. I want 
>> to write a checker to ensure T.ok() is called before T.value() is called.
>>
>> Static analyzer is perfect for this type of check as it requires path 
>> sensitive checks. When I trying to write the checker, I basically 
>> checks for pre-call and post-call. I want to tell if a CallEvent is 
>> T.ok() and T.value(). Currently what I am doing is:
>> 1. From CallEvent, I cast to CXXMemberCall, and getOriginExpr(), then 
>> call getMethodDecl().
> You can also try to do the following chain: 
> dyn_cast_or_null<CXXMethodDecl>(CallEvent.getDecl()) to obtain 
> CXXMethodDecl.
>
>> 2. From CXXMethodDecl, I first call getThisType(), then call 
>> getAsCXXRecordDecl(), then getQualifiedNameAsString(), and compare 
>> with qualified name of T, to make sure it is member of T.
> To obtain parent class declaration from CXXMethodDecl, you can use 
> getParent() method. So, the pseudocode will look like 
> "MethodDecl->getParent()->getQualifiedNameAsString()".
>
>> 3. From CXXMethodDecl, I call getNameAsString() to get the method 
>> name, and compare them with "ok" and "value".
> This looks OK. But it can be useful to know that 
> getQualifiedNameAsString() for CXXMethodDecl will also include parent 
> name. So, you can just check if MethodDecl->getQualifiedNameAsString() 
> is equal to "T::value" or "T::ok".
>
>> It works, but it looks complicated, and involves string comparison, 
>> which I assume is slow. Is there a easier way, blessed by clang 
>> static analyzer official teams, that tell if a MethodDecl, or 
>> CXXRecordDecl, is the function or class I am interested in?
>>
>> The ideal way is, there is one-time call to lookup the MethodDecl for 
>> T::ok() and T::value(), and CXXRecordDecl for T. Then ever since 
>> then, I just need to compare the pointers.
> This is possible. You can just launch a simple matcher against AST:
> cxxMethodDecl(hasName("::T::value"))
> and get CXXMethodDecl you need and compare with it later.
>
>> Another way is, the first time I found it is T, T::ok() or 
>> T::value(), I save the pointer of CXXRecordDecl or MethodDecl, and 
>> use the pointers later. Is this the reliable (assume I use the 
>> pointer canonical decl will not change) and blessed way to do it? If 
>> it is, is my steps above the correct and simplest way to determine it 
>> is T::ok or T::value? Is there some better and more reliable way?
> I think it is reliable enough: pointers to canonical declarations 
> don't change in AST.
>>
>> Thanks.
>>
>>
>> _______________________________________________
>> cfe-dev mailing list
>> cfe-dev at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
>
> -- 
> Best regards,
> Aleksei Sidorin,
> SRR, Samsung Electronics
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev




More information about the cfe-dev mailing list