This is an archive of the discontinued LLVM Phabricator instance.

Add an AST matcher for null pointers
ClosedPublic

Authored by aaron.ballman on Feb 9 2016, 10:11 AM.

Details

Reviewers
klimek
sbenza
Summary

There are several ways to specify a null pointer constant. C++11 has nullptr, GNU has the __null extension, and there's always NULL/0. This AST matcher will match on anything that generates a null pointer value, without requiring the user to figure out how to spell that with existing matchers.

Diff Detail

Event Timeline

aaron.ballman retitled this revision from to Add an AST matcher for null pointers.
aaron.ballman updated this object.
aaron.ballman added reviewers: klimek, sbenza.
aaron.ballman added a subscriber: cfe-commits.
sbenza added inline comments.Feb 9 2016, 11:30 AM
include/clang/ASTMatchers/ASTMatchers.h
4821

Use AST_MATCHER_FUNCTION instead, where the return value is the matcher (instead of the application of the matcher).
It is simpler to write and since it has no arguments it will memoize the matcher and construct it only once.

4821

Maybe use Expr::isNullPointerConstant?

aaron.ballman added inline comments.Feb 9 2016, 11:38 AM
include/clang/ASTMatchers/ASTMatchers.h
4821

Ah, interesting! I hadn't known about that macro. Thank you.

4821

Oh, hey, that's easier still! Would I still use AST_MATCHER_FUNCTION in that case though, or should that remain a simple AST_MATCHER?

sbenza added inline comments.Feb 9 2016, 11:42 AM
include/clang/ASTMatchers/ASTMatchers.h
4821

One or the other.
The _FUNCTION macro is for when the matcher itself is just a matcher expression. Saves typing and CPU.
Generating the temporary matchers on each match is expensive as they do memory allocation.
If you use Expr::isNullPointerConstant you won't be making any matchers.

aaron.ballman added inline comments.Feb 15 2016, 11:40 AM
include/clang/ASTMatchers/ASTMatchers.h
4821

One interesting problem I ran into with using Expr::isNullPointerConstant is that it makes the matcher overly aggressive with nullptr. Given:

AST_MATCHER(Expr, nullPointerConstant) {
  QualType QT = Node.getType();
  if (QT->isNullPtrType())
    return true;

  return QT->isPointerType() &&
         Node.isNullPointerConstant(Finder->getASTContext(),
                                    Expr::NPC_NeverValueDependent);
}

If you attempt to match somePtr = nullptr; with expr(nullPointerConstant()), you will get two matches. One for the initializer expression of the declaration, and one for the implicit cast expression. However, with somePtr = __null or somePtr = 0, you only get a single match (for the initializer expression). This seems like surprising behavior, but I'm not quite certain of the best way to address it, if it should be addressed at all.

Using the AST_MATCHER_FUNCTION macro instead.

Using Expr::isNullPointerConstant() turns out to have strange behavior with implicit casts and nullptr, and also requires further restrictions (for instance, it claims the initializer for int i = 0 is a null pointer constant, which is strictly true, but practically useless).

sbenza added inline comments.Feb 16 2016, 9:21 AM
include/clang/ASTMatchers/ASTMatchers.h
4838

is this expr() necessary?

aaron.ballman marked an inline comment as done.Feb 16 2016, 11:41 AM
aaron.ballman added inline comments.
include/clang/ASTMatchers/ASTMatchers.h
4838

Yes, without it I get errors about not having a matching overload for hasParent().

sbenza added inline comments.Feb 16 2016, 11:47 AM
include/clang/ASTMatchers/ASTMatchers.h
4838

Sorry, I meant the one around integerLiteral().

aaron.ballman marked an inline comment as done.

Removed an unnecessary expr() matcher.

aaron.ballman marked 2 inline comments as done.Feb 16 2016, 11:59 AM
aaron.ballman added inline comments.
include/clang/ASTMatchers/ASTMatchers.h
4838

Ah, good catch! No, that one was not required, I've removed it.

sbenza accepted this revision.Feb 16 2016, 1:03 PM
sbenza edited edge metadata.
This revision is now accepted and ready to land.Feb 16 2016, 1:03 PM
aaron.ballman closed this revision.Feb 16 2016, 1:07 PM
aaron.ballman marked an inline comment as done.

Thanks for the review and suggestions! I've commit in r261008.