[cfe-dev] Order in which matchers are invoked

Billy O'Mahony via cfe-dev cfe-dev at lists.llvm.org
Mon Nov 25 02:48:23 PST 2019


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;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20191125/fa013f9b/attachment.html>


More information about the cfe-dev mailing list