I want to record all the global variables' SymbolRef for analysis. Try
the following ways, but failed.
1) void check::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const;
only contains the local variables of the analysed function
2) void check::checkASTDecl(const VarDecl *TU, AnalysisManager& mgr,
BugReporter &BR) const
contains the global variables, but no CheckerContext info. so can not
convert it to SVal as usual:
ProgramStateRef state = C.getState();
SVal sv = state->getSVal(...);
SymbolRef Sym = sv.getAsSymbol();
3) depends on "state", how to get the "state" corresponding to the global
Environment env = state->getEnvironment();
for(Environment::iterator it = env.begin(); it != env.end(); ++it)
SVal sv = it->second;
is there correct way?
The first thing is that there are a couple of things wrong with your plan: global variables have regions, not symbols, and the state of memory is modeled by the Store, not the Environment. checkASTDecl is for syntactic checks, not path-sensitive ones, so of course the globals have no value.
What you actually need depends a lot on what sort of analysis you’re doing. If you’re trying to verify the initial values of global variables, you can use checkASTDecl and the normal constant-evaluation functions in the AST library. If you’re trying to check the state of all global variables at a particular time…that’s a bit harder, but I’m almost sure you don’t need it. (Why does your checker care about errno, for example?) So, what check are you trying to implement?
I also recommend you read through the Checker Developer Manual at http://clang-analyzer.llvm.org/checker_dev_manual.html, or watch the talk linked from there, for a firm grounding in the design of the analyzer and component classes.
Thank you for your advice very much.
At last the problem is solved by this way:
1) record the "VarDecl* p" of global variable in the checkASTDecl
2) get the SymbolRef by recorded "VarDecl* p" in the evalCall
SVal sv = state->getLValue(p, C.getLocationContext());
const SymbolRef symRef = sv.getAsSymbol();
Do this to get the unique id of global variables and local variables.
VarDecls are never symbolic, so symRef will always be null. Unless I’m forgetting something? The contents will be symbolic, but you only asked for the lvalue (the location).