Fix shared Go CFG expression and return-edge regressions

Agent-Logs-Url: https://github.com/github/codeql/sessions/3f96ead2-cda4-479c-9e37-f38ace035870

Co-authored-by: owen-mc <62447351+owen-mc@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-04-24 15:37:20 +00:00
committed by Owen Mansel-Chan
parent 190a76125e
commit 081f24a3b9
2 changed files with 22 additions and 3 deletions

View File

@@ -340,7 +340,10 @@ module ControlFlow {
* cannot return normally, but never fails to hold of a function that can return normally.
*/
predicate mayReturnNormally(FuncDecl f) {
exists(GoCfg::ControlFlow::NormalExitNode exit | exit.getEnclosingCallable() = f)
exists(GoCfg::ControlFlow::NormalExitNode exit |
exit.getEnclosingCallable() = f and
exists(exit.getAPredecessor())
)
}
/**

View File

@@ -79,8 +79,7 @@ module GoCfg {
or
not node instanceof Callable and
not exists(node.getEnclosingFunction()) and
result = node.getFile() and
result instanceof Callable
result = node.getFile()
}
class Stmt = Go::Stmt;
@@ -292,6 +291,10 @@ module GoCfg {
predicate preOrderExpr(Ast::Expr e) { none() }
predicate postOrInOrder(Ast::AstNode n) {
n instanceof Go::ReferenceExpr
or
n instanceof Go::BasicLit
or
n instanceof Go::CallExpr and
not n = any(Go::DeferStmt defer).getCall() and
not n = any(Go::GoStmt go_).getCall()
@@ -633,6 +636,12 @@ module GoCfg {
c.hasLabel(TGoLabel(lbl.getLabel()))
)
or
exists(Go::FuncDef fd |
ast = fd.getBody() and
c.getSuccessorType() instanceof ReturnSuccessor and
n.isAfter(fd.getBody())
)
or
exists(Go::LabeledStmt lbl, Go::FuncDef fd |
ast = fd.getBody() and
n.isBefore(lbl) and
@@ -841,6 +850,13 @@ module GoCfg {
n1.isAfter(lastChild) and n2.isAdditional(ret, getFirstReturnEpilogueTag(ret))
)
or
exists(Ast::AstNode lastChild | lastChild = getLastRankedChild(ret) |
// After last expr → return node directly if there is no return epilogue
not exists(getFirstReturnEpilogueTag(ret)) and
n1.isAfter(lastChild) and
n2.isIn(ret)
)
or
// No expressions → before → return node directly
not exists(getRankedChild(ret, _)) and
n1.isBefore(ret) and