[cfe-dev] clang checker is not called back on goto statements

Artem Dergachev via cfe-dev cfe-dev at lists.llvm.org
Mon Aug 28 02:22:04 PDT 2017


Hello,

In the analyzer (which is a very specific part of clang you're digging 
into, quite isolated from the rest of the clang, just in case) we only 
provide checkPreStmt/checkPostStmt callbacks for statements that are 
also CFGElements within CFGBlocks, i.e. statements that are executed 
sequentially and don't change control flow. Goto is different because it 
jumps between two blocks. We also provide the checkBranchCondition 
callback to check CFGTerminators (last statements in the block, which 
determine which block is executed next) - i'm not sure if it's called on 
goto statements (though they are terminators).

In any case, i've never seen anybody need to handle goto statements in a 
special manner; most of the time you don't care how exactly the control 
flows, you only care what actions are performed along the path.

Note that the analyzer displays path diagnostics. In your particular 
project, if you simply throw a warning (CheckerContext::emitReport()) on 
the ReturnStmt, you'd automatically get a pretty path explanation 
printed out as console text (-analyzer-output=text), fancy HTML with 
syntax highlighting (-analyzer-output=html) or machine-readable plist 
xml for use in IDEs (-analyzer-output=plist).

I also doubt it'd be helpful to try to draw the path through debug 
prints from the callbacks, because callbacks aren't called sequentially 
as the program executes, but instead they may jump randomly from one 
execution branch to another. You need to add information to the program 
state if you want to track what happens along the current path.

On 8/28/17 1:13 AM, Sheng Chen via cfe-dev wrote:
> Hi everyone,
>
> I have just got started with clang development. My first project would 
> extract the return value from each path. I can get the return value 
> quite easily, but have some problem with path representation. For 
> example, given the following very simple function,
>
> 1:   int jump(int x){
> 2: int result = x;
>
> 4: if (x < 5) {
> result = -1;
> 6: goto out;
> }
>
> 9: result = 0;
>
> out:
> 12: return result;
> }
>
> I would like to return two paths and their corresponding return 
> values. I use line numbers to represent each path.
>
> Path                      Return value
> ----------                 --------------------
> L6, L12                 -1
> L12                       0
>
> The problem I am having now is that I am not able to get line numbers 
> of goto statements, although my checker writes callback functions for 
> goto statements. My code is as follows. I have tried to add callback 
> functions for PreStmt on both GotoStmt and IndirectGotoStmt and also 
> PostStmt on them, but never got line numbers for goto statements. I 
> can get line numbers for return statements with the following code.
>
> Does anybody have any idea about why this happens?
>
> Thank you for your help.
> Sheng
>
> namespace {
> class CheckReturnValue : public Checker< check::PreStmt<ReturnStmt>,
> check::PreStmt<IndirectGotoStmt>,
> check::PostStmt<GotoStmt>> {
>
> public:
>   void checkPreStmt(const ReturnStmt *DS, CheckerContext &C) const;
>   void checkPreStmt(const IndirectGotoStmt *DS, CheckerContext &C) const;
>   void checkPostStmt(const GotoStmt *DS, CheckerContext &C) const;
> private:
>   static bool isNegative(CheckerContext &C, const Expr *E);
> };
> } // end anonymous namespace
>
> void CheckReturnValue::checkPostStmt(const GotoStmt *DS, 
> CheckerContext &C) const{
>
>   llvm :: outs() << "Goto statement\t";
>   DS -> getLocStart().print(llvm::outs(),C.getSourceManager()) ;
>
> }
>
> void CheckReturnValue::checkPreStmt(const IndirectGotoStmt *DS, 
> CheckerContext &C) const {
>   llvm :: outs() << "Indirect goto statement\t";
>   DS -> getLocStart().print(llvm::outs(),C.getSourceManager()) ;
>
> }
>
> void CheckReturnValue::checkPreStmt(const ReturnStmt *DS, 
> CheckerContext &C) const {
>   const Expr* retExp = DS -> getRetValue() ;
>   retExp -> printPretty(llvm::outs(), NULL, 
> PrintingPolicy(LangOptions())) ;
>
>   llvm :: outs() << "\tLocation\t";
>   DS -> getLocStart().print(llvm::outs(),C.getSourceManager()) ;
> }
>
>
>
> Dr. Sheng Chen
> Assistant Professor
> The Center for Advanced Computer Studies
> UL Lafayette
> http://www.ucs.louisiana.edu/~sxc2311/ 
> <http://www.ucs.louisiana.edu/%7Esxc2311/>
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev




More information about the cfe-dev mailing list