Skip to content

Go: migrate control flow graph to shared CFG library #2#22182

Open
owen-mc wants to merge 29 commits into
github:mainfrom
owen-mc:go/shared-cfg
Open

Go: migrate control flow graph to shared CFG library #2#22182
owen-mc wants to merge 29 commits into
github:mainfrom
owen-mc:go/shared-cfg

Conversation

@owen-mc

@owen-mc owen-mc commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

No description provided.

owen-mc added 23 commits July 13, 2026 12:31
The test shouldn't have an alert because the panic happens before the
deferred call to recover.
We now do a simple syntactic check for whether a function may return,
without taking into account whether other functions called inside it may
return. This is an acceptable loss of precision.
This result should not be here because the panic is recovered. We now
correctly spot this.
We expect a missing in node for any ParenExpr.

Defer statements in conditionals legitimately lead to multiple
successors because we may or may not have visited the defer statement.

A single defer statement in a loop legitimately leads to a self loop,
because we may have visited that defer statement multiple times.

Select statements legitimately lead to multiple successors.

An empty select statement legitimately leads to a dead end.
Increment/decrement statements previously produced three control-flow
nodes: an 'implicit-one' node for the constant 1, an 'incdec-rhs' node
for the 'operand + 1' value, and the write node. The implicit-one node
existed only to serve as the right operand of the increment's binary
operation model.

Remove the implicit-one node, modelling the implicit constant 1 directly
on the incdec-rhs instruction. This saves one CFG node per inc/dec. The
inc/dec disjunct of BinaryOperationNode is dropped as well; it only fed
string-concatenation taint (impossible for ++/--) and GVN of a synthetic
node, so no data-flow results are lost.
A compound assignment (`x += y`) previously produced two sequential
control-flow nodes: a 'compound-rhs' node computing the binary operation
`x + y`, followed by an 'assign:0' write node storing the result.

Make the compound-rhs instruction itself perform the write (it becomes a
WriteInstruction whose right-hand side is its own value), and stop
emitting the separate assign:0 node for compound assignments. This saves
one CFG node per compound assignment while preserving the BinaryOperationNode
model (so string-concatenation taint through `s += ...` still holds) and
SSA semantics (the def value is the binary operation).
A slice expression with omitted bounds (e.g. `s[:]`, `s[a:]`, `s[:b]`)
previously created up to three synthetic control-flow nodes: implicit-low
(constant 0), implicit-high (length) and implicit-max (capacity). These
carried no data-flow value beyond the implicit lower bound of 0.

Stop emitting these nodes: control flow now skips directly to the next
present bound (or the slice evaluation). SliceInstruction.getLow/getHigh/
getMax return only explicit bounds. The one consumer of the implicit
lower bound, StringOps' HasPrefix_Substring, now treats an absent lower
bound as 0. No data-flow or StringOps results change.
Each parameter previously created two additional nodes: an 'arg:i'
node (ReadArgumentInstruction) holding the incoming argument value, and
a 'param-init:i' node (InitParameterInstruction) writing it to the
parameter's SSA variable. The 'arg' node existed only to be the RHS of
the param-init write; the ParameterNode and inter-procedural flow are
already anchored on param-init.

Make InitParameterInstruction its own RHS and drop the 'arg:i' node,
halving the per-parameter node count. DeadStoreOfLocal now excludes
InitParameterInstruction (instead of ReadArgumentInstruction). The
data-flow changes are pure relabelings (arg -> param-init) with no flow
loss.
A named result variable previously created two additional nodes:
'result-zero-init:i' computing the zero value, and 'result-init:i'
writing that value into the result variable. The result-init node
existed only to write the value already computed by result-zero-init.

Make the result-zero-init instruction perform the write itself
(InitResultInstruction is now keyed on result-zero-init with its own
value as RHS) and drop the separate result-init node. All zero-value
constant semantics stay on the same node, so GVN and constant analysis
are unchanged; the only data-flow change is the SSA def relabeling
(result-init -> result-zero-init) with no flow loss.
A positional element of an array or slice literal (e.g. the elements of
[]T{a, b}) previously created a 'lit-index' node holding its implicit
index constant (0, 1, ...), in addition to the 'lit-init' write node.

Array and slice content flow is index-insensitive (the store step
ignores the element index), map literals always use explicit keys, and
literal bases are not tracked by VariableWithFields, so the implicit
index value is never actually consumed. Drop the 'lit-index' node and
let the lit-init instruction act as its own opaque index. All 100
data-flow library tests pass unchanged, confirming no content-flow loss.
Copilot AI review requested due to automatic review settings July 13, 2026 16:39
@owen-mc owen-mc requested review from a team as code owners July 13, 2026 16:39
@github-actions github-actions Bot added the Go label Jul 13, 2026

@github-advanced-security github-advanced-security AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CodeQL found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Migrates Go control-flow, SSA, and data-flow modeling to the shared CFG framework, including schema support and updated test baselines.

Changes:

  • Integrates shared CFG/basic-block infrastructure and no-return modeling.
  • Adds synthesized range-element nodes with upgrade/downgrade support.
  • Updates framework models, inline annotations, and generated expectations.
Show a summary per file
File Description
go/ql/test/query-tests/Security/CWE-918/RequestForgery.expected Updates data-flow node labels.
go/ql/test/query-tests/Security/CWE-918/CONSISTENCY/DataFlowConsistency.expected Updates consistency output.
go/ql/test/query-tests/Security/CWE-770/UncontrolledAllocationSize.expected Updates extraction-node labels.
go/ql/test/query-tests/Security/CWE-770/CONSISTENCY/DataFlowConsistency.expected Updates consistency output.
go/ql/test/query-tests/Security/CWE-643/CONSISTENCY/DataFlowConsistency.expected Updates dereference labels.
go/ql/test/query-tests/Security/CWE-640/CONSISTENCY/DataFlowConsistency.expected Updates dereference labels.
go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/CONSISTENCY/DataFlowConsistency.expected Updates consistency output.
go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/main.go Relocates source annotations.
go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/cves.go Relocates source annotation.
go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/CONSISTENCY/DataFlowConsistency.expected Updates dereference labels.
go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/BadRedirectCheck.go Relocates source annotation.
go/ql/test/query-tests/Security/CWE-347/MissingJwtSignatureCheck.expected Updates SSA locations and labels.
go/ql/test/query-tests/Security/CWE-347/CONSISTENCY/DataFlowConsistency.expected Updates dereference labels.
go/ql/test/query-tests/Security/CWE-327/CONSISTENCY/DataFlowConsistency.expected Updates dereference labels.
go/ql/test/query-tests/Security/CWE-326/InsufficientKeySize.expected Updates result ordering and SSA locations.
go/ql/test/query-tests/Security/CWE-322/InsecureHostKeyCallback.expected Updates SSA and extraction nodes.
go/ql/test/query-tests/Security/CWE-312/CONSISTENCY/DataFlowConsistency.expected Updates consistency output.
go/ql/test/query-tests/Security/CWE-295/DisabledCertificateCheck/DisabledCertificateCheck.expected Updates assignment and literal labels.
go/ql/test/query-tests/Security/CWE-190/CONSISTENCY/DataFlowConsistency.expected Updates dereference labels.
go/ql/test/query-tests/Security/CWE-117/CONSISTENCY/DataFlowConsistency.expected Updates dereference labels.
go/ql/test/query-tests/Security/CWE-089/StringBreak.expected Updates extraction-node labels.
go/ql/test/query-tests/Security/CWE-089/CONSISTENCY/DataFlowConsistency.expected Updates consistency output.
go/ql/test/query-tests/Security/CWE-089/CONSISTENCY/CfgConsistency.expected Adds CFG consistency baseline.
go/ql/test/query-tests/Security/CWE-079/StoredXss.expected Updates extraction and SSA nodes.
go/ql/test/query-tests/Security/CWE-079/stored.go Relocates source annotation.
go/ql/test/query-tests/Security/CWE-079/CONSISTENCY/DataFlowConsistency.expected Updates consistency output.
go/ql/test/query-tests/Security/CWE-078/StoredCommand.expected Updates extraction-node labels.
go/ql/test/query-tests/Security/CWE-078/CONSISTENCY/DataFlowConsistency.expected Updates dereference labels.
go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected Updates SSA source ranges.
go/ql/test/query-tests/Security/CWE-022/UnsafeUnzipSymlink.expected Updates SSA locations.
go/ql/test/query-tests/Security/CWE-022/CONSISTENCY/DataFlowConsistency.expected Updates dereference labels.
go/ql/test/query-tests/Security/CWE-020/MissingRegexpAnchor/CONSISTENCY/DataFlowConsistency.expected Updates dereference labels.
go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/CONSISTENCY/DataFlowConsistency.expected Updates dereference labels.
go/ql/test/query-tests/RedundantCode/UnreachableStatement/CONSISTENCY/CfgConsistency.expected Adds CFG consistency baseline.
go/ql/test/query-tests/RedundantCode/RedundantRecover/tst.go Removes an obsolete alert annotation.
go/ql/test/query-tests/RedundantCode/RedundantRecover/RedundantRecover.expected Updates recover-call results.
go/ql/test/query-tests/RedundantCode/DeadStoreOfLocal/DeadStoreOfLocal.expected Updates assignment instruction labels.
go/ql/test/query-tests/RedundantCode/DeadStoreOfLocal/CONSISTENCY/CfgConsistency.expected Adds CFG consistency baseline.
go/ql/test/query-tests/RedundantCode/DeadStoreOfField/DeadStoreOfField.expected Updates assignment label.
go/ql/test/query-tests/InconsistentCode/UnhandledCloseWritableHandle/CONSISTENCY/CfgConsistency.expected Adds defer CFG baseline.
go/ql/test/query-tests/InconsistentCode/MissingErrorCheck/MissingErrorCheck.expected Updates SSA locations.
go/ql/test/library-tests/semmle/go/Types/notype.ql Excludes synthesized valid types.
go/ql/test/library-tests/semmle/go/security/SafeUrlFlow/SafeUrlFlow.expected Updates dereference labels.
go/ql/test/library-tests/semmle/go/Scopes/EntityWrite.expected Updates parameter-init nodes.
go/ql/test/library-tests/semmle/go/PrintAst/PrintAstExcludeComments.expected Adds range-element AST nodes.
go/ql/test/library-tests/semmle/go/PrintAst/PrintAst.expected Adds range-element AST nodes.
go/ql/test/library-tests/semmle/go/PrintAst/CONSISTENCY/CfgConsistency.expected Adds CFG consistency baseline.
go/ql/test/library-tests/semmle/go/IR/test.expected Updates extraction instruction labels.
go/ql/test/library-tests/semmle/go/frameworks/Yaml/yaml.go Updates inline model expectations.
go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/SqlInjection.expected Updates extraction-node labels.
go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/CONSISTENCY/DataFlowConsistency.expected Updates consistency output.
go/ql/test/library-tests/semmle/go/frameworks/WebSocket/RemoteFlowSources.expected Updates extraction-node labels.
go/ql/test/library-tests/semmle/go/frameworks/WebSocket/Read.expected Updates extraction-node labels.
go/ql/test/library-tests/semmle/go/frameworks/WebSocket/CONSISTENCY/DataFlowConsistency.expected Updates dereference label.
go/ql/test/library-tests/semmle/go/frameworks/Twirp/server/main.go Relocates handler/source annotations.
go/ql/test/library-tests/semmle/go/frameworks/TaintSteps/CONSISTENCY/DataFlowConsistency.expected Updates dereference labels.
go/ql/test/library-tests/semmle/go/frameworks/SystemCommandExecutors/CONSISTENCY/DataFlowConsistency.expected Updates dereference label.
go/ql/test/library-tests/semmle/go/frameworks/Revel/test.expected Records inline expectation mismatch.
go/ql/test/library-tests/semmle/go/frameworks/Revel/Revel.go Relocates response-body annotation.
go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected Updates dereference labels.
go/ql/test/library-tests/semmle/go/frameworks/Protobuf/CONSISTENCY/DataFlowConsistency.expected Updates consistency output.
go/ql/test/library-tests/semmle/go/frameworks/Protobuf/CONSISTENCY/CfgConsistency.expected Adds CFG consistency baseline.
go/ql/test/library-tests/semmle/go/frameworks/gqlgen/graph/schema.resolvers.go Relocates resolver annotation.
go/ql/test/library-tests/semmle/go/frameworks/GoMicro/main.go Relocates request annotation.
go/ql/test/library-tests/semmle/go/frameworks/GoMicro/LogInjection.expected Updates parameter SSA location.
go/ql/test/library-tests/semmle/go/frameworks/GoMicro/CONSISTENCY/DataFlowConsistency.expected Updates consistency output.
go/ql/test/library-tests/semmle/go/frameworks/GoKit/main.go Relocates endpoint annotations.
go/ql/test/library-tests/semmle/go/frameworks/Gin/Gin.expected Updates extraction-node labels.
go/ql/test/library-tests/semmle/go/frameworks/Gin/CONSISTENCY/DataFlowConsistency.expected Updates dereference labels.
go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/fasthttp.go Updates inline source expectations.
go/ql/test/library-tests/semmle/go/frameworks/Fasthttp/CONSISTENCY/DataFlowConsistency.expected Updates consistency output.
go/ql/test/library-tests/semmle/go/frameworks/Echo/CONSISTENCY/DataFlowConsistency.expected Updates dereference label.
go/ql/test/library-tests/semmle/go/frameworks/Chi/CONSISTENCY/DataFlowConsistency.expected Updates dereference label.
go/ql/test/library-tests/semmle/go/frameworks/Beego/test.go Relocates source annotation.
go/ql/test/library-tests/semmle/go/frameworks/Beego/CONSISTENCY/DataFlowConsistency.expected Updates consistency output.
go/ql/test/library-tests/semmle/go/frameworks/Afero/CONSISTENCY/DataFlowConsistency.expected Updates dereference label.
go/ql/test/library-tests/semmle/go/dataflow/VarArgs/CONSISTENCY/DataFlowConsistency.expected Removes resolved consistency failure.
go/ql/test/library-tests/semmle/go/dataflow/ThreatModels/CONSISTENCY/DataFlowConsistency.expected Updates dereference label.
go/ql/test/library-tests/semmle/go/dataflow/SSA/VarUses.expected Updates result-read nodes.
go/ql/test/library-tests/semmle/go/dataflow/SliceExpressions/CONSISTENCY/CfgConsistency.expected Adds CFG consistency baseline.
go/ql/test/library-tests/semmle/go/dataflow/ReadsAndWrites/writesField.expected Updates field-write instructions.
go/ql/test/library-tests/semmle/go/dataflow/ReadsAndWrites/writesElement.expected Updates element-write instructions.
go/ql/test/library-tests/semmle/go/dataflow/ReadsAndWrites/readsMethod.expected Updates implicit dereference label.
go/ql/test/library-tests/semmle/go/dataflow/ReadsAndWrites/readsField.expected Updates implicit dereference label.
go/ql/test/library-tests/semmle/go/dataflow/ReadsAndWrites/readsElement.expected Updates implicit dereference label.
go/ql/test/library-tests/semmle/go/dataflow/PostUpdateNodes/test.expected Updates post-update dereference labels.
go/ql/test/library-tests/semmle/go/dataflow/Nodes/resultParameters.go Relocates result-node annotations.
go/ql/test/library-tests/semmle/go/dataflow/Nodes/ResultNode.expected Updates result-read nodes.
go/ql/test/library-tests/semmle/go/dataflow/Nodes/CallNode_getResult_int.expected Updates extraction-node labels.
go/ql/test/library-tests/semmle/go/dataflow/Nodes/BinaryOperationNodes.expected Updates compound-assignment label.
go/ql/test/library-tests/semmle/go/dataflow/HiddenNodes/test.expected Updates extraction-node labels.
go/ql/test/library-tests/semmle/go/dataflow/GlobalValueNumbering/GlobalValueNumber.expected Updates CFG instruction locations.
go/ql/test/library-tests/semmle/go/dataflow/FunctionInputsAndOutputs/FunctionOutput_isResult_int.expected Updates result extraction labels.
go/ql/test/library-tests/semmle/go/dataflow/FunctionInputsAndOutputs/FunctionOutput_getExitNode.expected Updates output exit nodes.
go/ql/test/library-tests/semmle/go/dataflow/FunctionInputsAndOutputs/FunctionOutput_getEntryNode.expected Updates zero-init nodes.
go/ql/test/library-tests/semmle/go/dataflow/FunctionInputsAndOutputs/FunctionInput_getExitNode.expected Updates parameter-init nodes.
go/ql/test/library-tests/semmle/go/dataflow/FunctionInputsAndOutputs/FunctionInput_getEntryNode.expected Updates SSA source ranges.
go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/steps.expected Updates extraction-node labels.
go/ql/test/library-tests/semmle/go/dataflow/ExternalValueFlow/srcs.expected Updates source-node locations.
go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/steps.expected Updates extraction-node labels.
go/ql/test/library-tests/semmle/go/dataflow/ExternalTaintFlow/srcs.expected Updates source-node locations.
go/ql/test/library-tests/semmle/go/dataflow/DefaultTaintSanitizer/CONSISTENCY/DataFlowConsistency.expected Updates dereference labels.
go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph/NoretFunctions.expected Updates normal-return classification.
go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph/CONSISTENCY/CfgConsistency.expected Adds CFG consistency baseline.
go/ql/test/library-tests/semmle/go/concepts/Regexp/RegexpPattern.expected Updates extraction and SSA nodes.
go/ql/test/library-tests/semmle/go/concepts/HTTP/CONSISTENCY/DataFlowConsistency.expected Updates consistency output.
go/ql/test/experimental/Unsafe/WrongUsageOfUnsafe.expected Updates SSA location.
go/ql/test/experimental/Unsafe/CONSISTENCY/CfgConsistency.expected Adds CFG consistency baseline.
go/ql/test/experimental/InconsistentCode/CONSISTENCY/CfgConsistency.expected Adds defer-loop CFG baseline.
go/ql/test/experimental/frameworks/CleverGo/CONSISTENCY/DataFlowConsistency.expected Updates dereference label.
go/ql/test/experimental/CWE-942/CONSISTENCY/DataFlowConsistency.expected Updates dereference labels.
go/ql/test/experimental/CWE-918/SSRF.expected Updates dereference and extraction labels.
go/ql/test/experimental/CWE-918/CONSISTENCY/DataFlowConsistency.expected Updates consistency output.
go/ql/test/experimental/CWE-840/CONSISTENCY/DataFlowConsistency.expected Updates dereference labels.
go/ql/test/experimental/CWE-807/CONSISTENCY/DataFlowConsistency.expected Updates dereference labels.
go/ql/test/experimental/CWE-74/DsnInjectionLocal.expected Updates dereference labels.
go/ql/test/experimental/CWE-369/CONSISTENCY/DataFlowConsistency.expected Updates dereference labels.
go/ql/test/experimental/CWE-321-V2/CONSISTENCY/DataFlowConsistency.expected Updates dereference labels.
go/ql/test/experimental/CWE-287/CONSISTENCY/DataFlowConsistency.expected Updates dereference labels.
go/ql/test/experimental/CWE-285/PamAuthBypass.expected Updates extraction-node label.
go/ql/test/experimental/CWE-203/CONSISTENCY/DataFlowConsistency.expected Updates dereference labels.
go/ql/test/example-tests/snippets/varwrite.expected Updates assignment label.
go/ql/test/example-tests/snippets/typeinfo.expected Updates parameter-init nodes.
go/ql/test/example-tests/snippets/fieldwrite.expected Updates assignment label.
go/ql/src/RedundantCode/UnreachableStatement.ql Reworks unreachable-statement detection.
go/ql/src/RedundantCode/DeadStoreOfLocal.ql Uses shared parameter initialization.
go/ql/src/experimental/IntegerOverflow/RangeAnalysis.qll Adapts increment/decrement analysis.
go/ql/lib/upgrades/b1341734d6870b105e5c9d168ce7dec25d7f72d0/upgrade.properties Declares range-element schema upgrade.
go/ql/lib/semmle/go/StringOps.qll Handles omitted slice lower bounds.
go/ql/lib/semmle/go/Stmt.qll Adds the range-element AST API.
go/ql/lib/semmle/go/Scopes.qll Adds no-normal-return modeling hook.
go/ql/lib/semmle/go/PrintAst.qll Makes the local overlay optional.
go/ql/lib/semmle/go/frameworks/Zap.qll Migrates no-return model.
go/ql/lib/semmle/go/frameworks/stdlib/Os.qll Migrates os.Exit model.
go/ql/lib/semmle/go/frameworks/stdlib/Log.qll Migrates fatal-log model.
go/ql/lib/semmle/go/frameworks/Revel.qll Adapts implicit field-read traversal.
go/ql/lib/semmle/go/frameworks/Logrus.qll Migrates fatal/panic models.
go/ql/lib/semmle/go/frameworks/Glog.qll Migrates fatal/exit models.
go/ql/lib/semmle/go/Expr.qll Synthesizes key-value expression types.
go/ql/lib/semmle/go/dataflow/SsaImpl.qll Connects SSA to the shared CFG.
go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll Refines switch-edge filtering.
go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll Adapts reachable and compound nodes.
go/ql/lib/semmle/go/dataflow/GlobalValueNumbering.qll Anchors side-effect lookup to CFG entry.
go/ql/lib/semmle/go/controlflow/BasicBlocks.qll Replaces bespoke basic blocks.
go/ql/lib/semmle/go/Concepts.qll Migrates heuristic fatal logging model.
go/ql/lib/printCfg.ql Adds the Go CFG viewer query.
go/ql/lib/go.dbscheme Adds @rangeelementexpr.
go/ql/consistency-queries/CfgConsistency.ql Enables shared CFG consistency checks.
go/extractor/extractor.go Extracts synthesized range-element nodes.
go/extractor/dbscheme/tables.go Registers the new expression kind.
go/downgrades/23f2f56b5d3a846b4f73e3fa62510e36f934fb46/upgrade.properties Configures downgrade transforms.
go/downgrades/23f2f56b5d3a846b4f73e3fa62510e36f934fb46/has_location.ql Removes synthesized-node locations.
go/downgrades/23f2f56b5d3a846b4f73e3fa62510e36f934fb46/exprs.ql Reparents range variables on downgrade.

Review details

  • Files reviewed: 191/192 changed files
  • Comments generated: 3
  • Review effort level: Medium

c.ViewArgs["Foo"] = c.Params.Query // $ responsebody='selection of Query' Alert[go/reflected-xss]
c.Render()
}
} // $ responsebody='arg:-1 block statement'
r = 0
return
}
} // $ Alert[result-node] // implicit reads of result parameters are located at the result parameter declaration
}
return
}
} // $ Alert[result-node] // implicit reads of result parameters are located at the result parameter declaration
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants