Traverse AST and save Stmt* pointers for later use

Hello everyone!

I am writing a tool that traverses ASTs of my project files, stores several Stmt* pointers, and then compares them as present here https://clang.llvm.org/doxygen/IdenticalExprChecker_8cpp_source.html#l00307 .

I tried inheriting from ast_matchers::MatchFinder::MatchCallback and overriding its void run(const MatchResult &match) / inheriting RecursiveASTVisitor and implementing VisitFunctionDecl to store pointers of interest into a container. However it seems that at some point during/after traversing those pointers invalidate - e.g. if I check body->getStmtClass() during run, it correctly shows CompoundStmt , but afterwards it turns into some other clearly wrong class like If or For.

What are my options to solve this problem? I am aware that AST Matchers or Visitors might be a wrong tool in this case, so please don't hesitate to advise other means if those will suit me better.

Best regards,
Igor Ivanov

Hello Igor,

There is too few information to say definitely what happens in your case. Could you share the code?
My wild guess is that you are trying to check the whole result after ASTContext storing all Stmts dies causing use-after-free.

11.05.2018 10:55, Иванов Игорь via cfe-dev пишет:

Sure!

https://github.com/Artalus/odrey/blob/feature/ast-equal/odrey/odr_decl_traverser.h Here is traversing boilerplate and saving pointers to OdrMap container passed from outside
https://github.com/Artalus/odrey/blob/feature/ast-equal/odrey/odr_decl_traverser.cpp

https://github.com/Artalus/odrey/blob/feature/ast-equal/odrey/odr_tool.cpp#L23 Here I initiate the traversing. ClangTool, OdrMap and OdrActionFactory are members of the class, so they stay alive when at L43 I begin comparing saved pointers. How can I ensure that ASTContext stays alive too (and who actually owns it)?

Naming is rather unintuitive currently and stuff is overengineered, but I am working on it ^^"

Best regards,
Igor Ivanov

You can check who owns ASTContext you actually use (it is the CompilerInstance, most probably). And then, check if the owner is destroyed before you use your data. Another option is to put a breakpoint into ASTContext dtor (or add a debug print) and check if it is called before the use.

11.05.2018 13:17, Иванов Игорь пишет: