A Block represents a basic block: a list of statements and expressions that are always evaluated sequentially.
A block may have 0-2 successors: zero for a return block or a block that calls a function such as panic that never returns; one for a normal (jump) block; and two for a conditional (if) block.
type Block struct {
Nodes []ast.Node // statements, expressions, and ValueSpecs
Succs []*Block // successor nodes in the graph
Index int32 // index within CFG.Blocks
Live bool // block is reachable from entry
Kind BlockKind // block kind
Stmt ast.Stmt // statement that gave rise to this block (see BlockKind for details)
// contains filtered or unexported fields
}
func (b *Block) Return() (ret *ast.ReturnStmt)
Return returns the return statement at the end of this block if present, nil otherwise.
When control falls off the end of the function, the ReturnStmt is synthetic and its ast.Node.End position may be beyond the end of the file.
func (b *Block) String() string
A BlockKind identifies the purpose of a block. It also determines the possible types of its Stmt field.
type BlockKind uint8
const (
KindInvalid BlockKind = iota // Stmt=nil
KindUnreachable // unreachable block after {Branch,Return}Stmt / no-return call ExprStmt
KindBody // function body BlockStmt
KindForBody // body of ForStmt
KindForDone // block after ForStmt
KindForLoop // head of ForStmt
KindForPost // post condition of ForStmt
KindIfDone // block after IfStmt
KindIfElse // else block of IfStmt
KindIfThen // then block of IfStmt
KindLabel // labeled block of BranchStmt (Stmt may be nil for dangling label)
KindRangeBody // body of RangeStmt
KindRangeDone // block after RangeStmt
KindRangeLoop // head of RangeStmt
KindSelectCaseBody // body of SelectStmt
KindSelectDone // block after SelectStmt
KindSelectAfterCase // block after a CommClause
KindSwitchCaseBody // body of CaseClause
KindSwitchDone // block after {Type.}SwitchStmt
KindSwitchNextCase // secondary expression of a multi-expression CaseClause
)
func (kind BlockKind) String() string
A CFG represents the control-flow graph of a single function.
The entry point is Blocks[0]; there may be multiple return blocks.
type CFG struct {
Blocks []*Block // block[0] is entry; order otherwise undefined
// contains filtered or unexported fields
}
func New(body *ast.BlockStmt, mayReturn func(*ast.CallExpr) bool) *CFG
New returns a new control-flow graph for the specified function body, which must be non-nil.
The CFG builder calls mayReturn to determine whether a given function call may return. For example, calls to panic, os.Exit, and log.Fatal do not return, so the builder can remove infeasible graph edges following such calls. The builder calls mayReturn only for a CallExpr beneath an ExprStmt.
func (g *CFG) Dot(fset *token.FileSet) string
Dot returns the control-flow graph in the [Dot graph description language]. Use a command such as 'dot -Tsvg' to render it in a form viewable in a browser. This method is provided as a debugging aid; the details of the output are unspecified and may change.
[Dot graph description language]: https://en.wikipedia.org/wiki/DOT_(graph_description_language)
func (g *CFG) Format(fset *token.FileSet) string
Format formats the control-flow graph for ease of debugging.