Matching Code Patterns

For the syntax highlighting example, we have used the RecursiveASTVisitor in order to obtain information about the AST. We will now use the Clang AST Matchers to identify certain code patterns. As before, we will use a project based on LibTooling - therefore, you will notice a lot of similarity in the setup code: both projects use CommonOptionsParser and ClangTool. The difference is that, instead of providing a custom FrontendAction, we will use a FrontendActionFactory that receives a MatchFinder object. We can add any number of Matchers and MatchCallbacks to the MatchFinder - the Matchers define the patterns we are interested in, whereas the MatchCallbacks define the action that we wish to take whenever we find a match.

When writing AST matchers, the matchers reference is essential. This describes all the existing matchers, what kind of parameters they expect and what they return. This is crucial for figuring out how matchers can be chained in a way that makes sense.

To dip our toes in the water, we'll try to match a code pattern that can cause a world of problems in C programs: returning the address of a local variable.

Download this project and follow the comments.

Task 0

Build and run the project on a simple file. You can use the one below or write your own. You should notice two things: one is that Clang is helpfully throwing a warning when it identifies this code pattern (you can use -Wno-return-stack-address to silence it if it bothers you); the other is that our code considers any return statement as fishy. We need to fix the latter.

fishy.c
int *fishy() {
  int x = 0;
  return &x;
}
 
int y = 0;
int *notfishy() {
  return &y;
}
 
int *alsonotfishy() {
  static int z = 0;
  return &z;
}
 
int *evenlessfishy() {
  return (int *)0;
}

Task 1

Try to narrow the matcher in order to remove bogus diagnostics - we only want it to trigger when there really is a problem. Try to match only return statements that return the address of a local variable. Make sure to take a good look at the AST snippet that you're trying to match before starting to write the matcher.

Task 2 (bonus)

Returning the address of a local variable isn't the only way in which we can return a stack address - we can conceive all sorts of expressions that may lead to the return of a stack address. Try to find some examples. How many of them does Clang warn for?

sesiuni/llvm/patterns.txt · Last modified: 2015/09/08 13:23 by freescale