File tree Expand file tree Collapse file tree
go/ql/lib/semmle/go/controlflow Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -354,7 +354,15 @@ module GoCfg {
354354 )
355355 }
356356
357- predicate preOrderExpr ( Ast:: Expr e ) { none ( ) }
357+ predicate preOrderExpr ( Ast:: Expr e ) {
358+ // The call of a `defer` statement is not invoked at the statement
359+ // itself; its callee and arguments are evaluated in place, but the call
360+ // is only invoked later, at function exit (modelled by the `defer-invoke`
361+ // node and `deferExitStep`). Marking it as pre-order means no in-order
362+ // "invocation" node (and hence no inline exceptional-exit edge) is
363+ // created at the `defer` statement.
364+ e = any ( Go:: DeferStmt s ) .getCall ( )
365+ }
358366
359367 predicate propagatesValue ( Ast:: AstNode child , Ast:: AstNode parent ) {
360368 child = parent .( Go:: ParenExpr ) .getExpr ( )
Original file line number Diff line number Diff line change @@ -218,6 +218,11 @@ module IR {
218218 EvalInstruction ( ) {
219219 this .isIn ( e )
220220 or
221+ // The call of a `defer` statement is pre-order (it has no in-order
222+ // "invocation" node at the statement), so its value is produced by the
223+ // `defer-invoke` node that models the call at function exit.
224+ this .isAdditional ( e , "defer-invoke" )
225+ or
221226 // `NotExpr` and `LogicalBinaryExpr` are not in `postOrInOrder`, so they
222227 // don't have an `isIn` node. Only use the after-node when the
223228 // expression is not in a conditional context; otherwise the value is
You can’t perform that action at this time.
0 commit comments