[cfe-dev] Order in which matchers are invoked

Whisperity via cfe-dev cfe-dev at lists.llvm.org
Mon Nov 25 05:36:10 PST 2019


RecursiveASTVisitor has an overridable which enables post-order visitation
instead of pre-order. Another approach you could take is to match the
functions directly, and in the callback fire another matcher - you could
manually call clang::ast_matchers::match(MATCHER, Node); (several other
overloads exist) which is essentially "fetch me the matched nodes and give
me back a data structure on the subtree started by 'Node'." Creating custom
matchers local to your code, you can use the "static const auto M =
declarative(matcher(syntax()))", or the AST_MATCHER macro, in case your
matching requires manually investigating the node via directly calling C++
functions on the node, or calculating some result.

I don't know how much of this could reasonably be channeled from the
checker's code to Clang-Tidy and the execution, or more importantly, how
much it could mess up potential other checkers running on the same
invocation...

Another option you could go for is using your check() only as a "data
collection" callback and build some (reasonably small!) data structure, and
using "void onEndOfTranslationUnit()" at the end to read your data
structure, calculate some reasonable result from it, and emit your
diagnostics.

Billy O'Mahony via cfe-dev <cfe-dev at lists.llvm.org> ezt írta (időpont:
2019. nov. 25., H, 11:48):

> Hi,
>
> I've been writing a project specific clang-tidy check (thanks to Artem and
> Steve for their help). I've matchers written and working but was seeing
> some strange things about the order in which my matcher callbacks were
> being called.
>
> I noticed that in the documentation for MatchFinder it says " The order of
> matches is guaranteed to be equivalent to doing a pre-order traversal on
> the AST, and applying the matchers in the order in which they were added to
> the MatchFinder
> <https://clang.llvm.org/doxygen/classclang_1_1ast__matchers_1_1MatchFinder.html>
> ."
>
> As my checker is checking that certain functions follow certain steps in
> order (check the "device" arg ptr for NULL, lock the device, do NOT return
> while the device is locked, unlock the device) I was expecting (depending
> on) in AST-order of the match callbacks. Not all the device-ptr-check
> matches first, then all the return matches, then all the etc etc.matches.
>
>
> So two questions:
> * Can this call-back order be changed somehow? - worth a shot ;)
>
> * Failing this I can maintain information about the function and line
> number of all the steps in all the functions and figure out the AST-order
> from that. But I notice that using srcLocation often returns the same value
> for several statements (this is because in the code the Lock is actually
> done in a macro which locks the device but also returns if the lock fails -
> so I end up with a lock and a return both reporting the same srcLocation  -
> is there a way to determine which comes before which. (I think I came
> across a way of matching on macros too but I had already written working
> AST matchers at that point).
>
> Thanks for reading,
>
> Billy.
>
>
> --------------
>
>
> Here's an example of one of the type of function I want to check with some
> examples of errors in the code order:
>
> int api_foo(device_t *dev) {
>     int ret_val = 0;
>
>     bar();  // fn calls & decls before api_enter is ok- just don't access
> dev.
>     dev->bla = 1; // NO! device access before api_enter() called
>     api_enter(dev);   // error if this call is not present exactly once
>
>     if (dev->bla)
>         return; // NO! didn't call api_exit before rtn. Also two return
> points
>
>     if (dev->ma) {
>         ret_val = 1;
>         goto cleanup;
>     }
>     tweak(dev);
>
> cleanup:
>     api_exit(dev); // error if this is not present exactly once
>     dev->bla = 1; //NO! device access after api_exit()
>     return ret_val;
> }
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20191125/34cecaff/attachment.html>


More information about the cfe-dev mailing list