diff --git a/go/ql/lib/semmle/go/controlflow/ControlFlowGraphShared.qll b/go/ql/lib/semmle/go/controlflow/ControlFlowGraphShared.qll index 9db6fa28838..30b2b3409a2 100644 --- a/go/ql/lib/semmle/go/controlflow/ControlFlowGraphShared.qll +++ b/go/ql/lib/semmle/go/controlflow/ControlFlowGraphShared.qll @@ -9,6 +9,7 @@ module; private import codeql.controlflow.ControlFlowGraph as CfgLib private import codeql.controlflow.SuccessorType +private import codeql.util.Void /** Contains the shared CFG library instantiation for Go. */ module GoCfg { @@ -72,6 +73,14 @@ module GoCfg { AstNode callableGetBody(Callable c) { result = c } + class Parameter extends AstNode { + Parameter() { none() } + + Expr getDefaultValue() { none() } + } + + Parameter callableGetParameter(Callable c, int index) { none() } + Callable getEnclosingCallable(AstNode node) { result = node and node instanceof Callable or @@ -152,12 +161,14 @@ module GoCfg { class ContinueStmt = Go::ContinueStmt; + class GotoStmt = Go::GotoStmt; + class ReturnStmt extends Go::ReturnStmt { override Expr getExpr() { result = Go::ReturnStmt.super.getExpr() } } - class ThrowStmt extends Stmt { - ThrowStmt() { none() } + class Throw extends AstNode { + Throw() { none() } Expr getExpr() { none() } } @@ -241,12 +252,46 @@ module GoCfg { boolean getValue() { result = val } } + + class Assignment extends BinaryExpr { + Assignment() { none() } + } + + class AssignExpr extends Assignment { + AssignExpr() { none() } + } + + class CompoundAssignment extends Assignment { + CompoundAssignment() { none() } + } + + class AssignLogicalAndExpr extends CompoundAssignment { + AssignLogicalAndExpr() { none() } + } + + class AssignLogicalOrExpr extends CompoundAssignment { + AssignLogicalOrExpr() { none() } + } + + class AssignNullCoalescingExpr extends CompoundAssignment { + AssignNullCoalescingExpr() { none() } + } + + class PatternMatchExpr extends Expr { + PatternMatchExpr() { none() } + + Expr getExpr() { none() } + + AstNode getPattern() { none() } + } } /** The Input module implementing InputSig1 and InputSig2 for Go. */ private module Input implements Cfg0::InputSig1, Cfg1::InputSig2 { predicate cfgCachedStageRef() { CfgCachedStage::ref() } + class CallableContext = Void; + private newtype TLabel = TGoLabel(string l) { exists(Go::LabeledStmt ls | l = ls.getLabel()) } or TFallthrough() diff --git a/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll b/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll index 7a6b6318ed1..3b824ac0a4f 100644 --- a/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll +++ b/shared/controlflow/codeql/controlflow/ControlFlowGraph.qll @@ -1506,6 +1506,26 @@ module Make0 Ast> { n2.isAfterValue(pme, any(BooleanSuccessor s | s.getValue() = true)) ) or + exists(PatternMatchExpr pme | + n1.isBefore(pme) and + n2.isBefore(pme.getExpr()) + or + n1.isAfter(pme.getExpr()) and + n2.isIn(pme) + or + n1.isIn(pme) and + n2.isAfterValue(pme, any(BooleanSuccessor s | s.getValue() = false)) + or + n1.isIn(pme) and + n2.isAdditional(pme, patternMatchTrueTag()) + or + n1.isAdditional(pme, patternMatchTrueTag()) and + n2.isBefore(pme.getPattern()) + or + n1.isAfter(pme.getPattern()) and + n2.isAfterValue(pme, any(BooleanSuccessor s | s.getValue() = true)) + ) + or exists(IfStmt ifstmt | n1.isBefore(ifstmt) and n2.isBefore(ifstmt.getCondition())