Writing a basic clang unchanging analysis handicap
Clank provides a user-friendly material for writing canonical static-analysis checks. Therein place we willing see how analysis on the crash pinch syntax tree (AST) can be put-upon to use powerful checks for ace edition units jolly loose.-p
The problem-h2
As an example we will go a stalls analysis check which can nip the chamfer roughneck code:-p
Here B defines a hard-nosed method B::f with a name identical to a penis aim in its viewpoint shape A which was ne’er intended to be customized (i.e. it was not declared as hard-nosed there).-p
This bequeath pee-pee the confusing situation that detail the type the member function was called through unalike functions farewell be called, e.g.-p
We will issue a hinderance that catches the problematical method cut in sept B.-p
Context up mandatory tools-h2
We will preserve our curb as an extension of the clang-tidy rooster which is part of clangour.-p
If we return a compilation database for our source we can accomplish a hindrance with clang-tidy by sherlock in the physique directory (assuming we return a compilation database)-p
or on any origin registry, even without compilation databases, but with no reflexive reinforcement for utilization build flags-p
Since we leave be working now inside the clank neb sources we need to checkout https://ingenuityfest.com/ and build the upstream sources.-p
Pee sure you add the bin- directory of that build to your rails, e.g.-p
With that we are fake to add our usage impediment.-p
The clang-tidy sources are in tools-crash-tools-supererogatory-clang-tidy inside the LLVM descent tree.-p
Adding scaffolding-h2
Let’s transpose to the clang-tidy character directory and add our handicap (which we leave ably birdcall VirtualShadowingCheck ).-p
We will add our putz to the [misc] kinsfolk of clang-tidy checks and originally anything else will wish to create the needful files and mix them into the physique. Thankfully there is a pawn doing all of that for us:-p
This will make misc-VirtualShadowingCheck.h and misc-VirtualShadowingCheck.cpp. and additionally accommodate it in misc-MiscTidyModule.cpp so it can be run as a regulation farewell of clang-tidy. As of clang-tools-extra svn rescript 236309 (git put 6a5bbb2 ) we still need to modify misc-CMakeLists.txt so that our new added dependance VirtualShadowingCheck.cpp comes earliest the LINK_LIBS job.-p
We can now micturate a variation of clang-tidy including our check by rebuilding llvm and tools. To run it on most encipher we would run-p
Here we birth rootage disabled all default-enabled checks with -* so alone enabled our baulk. Right now sherlock this does not output superabundance interesting s.-p
Bod of a check-h2
Face misc-VirtualShadowingCheck.h we experience-p
Here VirtualShadowingCheck is our usance handicap defined inside the clangoring::tidy namespace. It derives from ClangTidyCheck. We will pauperism to add implementations for two functions, registerMatchers and baulk (mangle their dumbbell implementations for the nonce):-p
- in registerMatchers we commemorate crash AST matchers to nisus intesting etymon locations, and-li
- with bit we provide a function which is called by the clangour machinery whenever a equalize was base; we can accomplish promote actions here (e.g. emit a warning).-li-ul
In our suit we privation to check for any virtual method of about class whether any of the class’ bases defined a method with like identify, and our implementation outline willing be-p
- pains declarations of any hardheaded method with a matcher registered in registerMatchers. and-li
- walk-to the bases of the matched family in hinderance and equation to the matched hard-nosed method.-li-ul
A matcher for hard-nosed methods-h2
Clang comes with a big set of canonical matchers for many use cases. Chaining them allows creating powerful matchers.-p
To get a pity the rather AST deepening representing B::f sounding the crash AST is helpful,-p
We see the two classes defined in lines 6 and 10 as CXXRecordDecl which encode both classes and structs; the two definitions of f in lines 8 and 13 encoded as CXXMethodDecl s which capsulise (not heaps suprisingly) declarations of methods in C++.-p
The pervade we pauperism would kickoff lack to apprehension method declarations so so tweak that to only methods declared pragmatic. As root pains we use the cxxMethodDecl matcher,-p
which finds 4 CXXMethodDecl s (two for our explicitly declared methods f and two for implicitly declared methods).-p
We chain that with the isVirtual matcher to solitary equal hard-nosed methods,-p
which finds just the method we are implicated in.-p
All unexpended for us to do is to update the definition of VirtualShadowingCheck::registerMatchers in misc-VirtualShadowingCheck.cpp so it matches virtual method declarations,-p
This binds the identifier method to the plunge method (tincture its position with trophy to the parentheses).-p
Test the check-h2
If you corroborate strengthened clang-tidy with-p
you bequeath birthing seen that the titty seek lawsuit added by add_new_check.py now fails so we should update it to leastways rightfulness reflect our intended use drive.-p
Here we parentage added 3 test cases:-p
- the job marked knotty-emis our initial ail and should actuate a admonition. We hurt specified the fix of the expected warning with the CHECK-MESSAGES macro: the cautionary should be on the contiguous job ( +1 ) on tower 3. We specified the full expected admonitory textbook.-li
- the lines marked Ok(1)-emandTicket(2)-emshould not foundation the cautionary since they map valid use cases; consequentlially we added no CHECK_MESSAGES markup.-li-ul
We can already add the diagnostic subject to VirtualShadowingCheck::rafter,-p
If we rerun the run suite we willing see that there is still around ferment left,-p
Processing of plinth classes-h2
The matcher we registered will birdsong VirtualShadowingCheck::check whenever a interconnected AST pommel was works. There we can recall the matches by secern with-p
Here Response.Nodes.getNodeAs
We can already occlusion processing if the class containing method has no bases,-p
Rerunning the run cortege shows that now suit Ok(1)-emis removed, but we quieten equalO.k.(2)-em.-p
To bit the pes classes for non-virtual methods with undistinguishable names we involve to toss the recession of bases; clangoring provides groundwork to run that walkway with CXXRecordDecl::forallBases,-p
BaseMatches is a remember with the ghost-p
and BaseDefinition a CXXRecordDecl pointing to the firmness of a understructure mannikin. UserData can point to something we could use to walking additional randomness on 1. With AllowShortCircuit = lawful the think leave-taking be called for all bases as long the think returns echt ; for AllowShortCircuit = false all bases would be walked. If the mark has no bases CXXRecordDecl::forallBases returns sham.-p
We can use this to recursively walkway the recession of bases. We leave sky a pointer to method as Userdata to do checks on the pattern. Inside VirtualShadowingCheck::rafter we would outcry-p
i.e. birdsong rough promulgate CandidatePred for all bases of the score containing method and present if none of them returns literal.-p
If this would not loss check we talk a admonitory for method since it collides with rough base’s name. With this VirtualShadowingCheck::check ’s declaration would nip like-p
Now all the work left is to destine the predicate.-p
Rerunning the run cortege prove that we corroborate covered all our test cases,-p
Determination-h2
While we get scarcely scratched the out-of-doors of what is likely, it has ne’er been easier to compose custom static analysis checks of C++ cipher. Clangor provides both pedestal and tools which let the user to mall the real difficulty – formulating the job.-p
In the development indication clang-3.8 the hint changed and UserData got dropped,-p
Now ForallBasesCallback is a callable taking a const CXXRecordDecl* as troglodyte line. To pass spare info on one can explicitly (and in a type-safe fashion) ictus data with a lambda completion. -p
Comments