Skip to content

Commit 464857c

Browse files
authored
Merge remote-tracking branch 'origin/copilot/vscode-mndb17m3-9fpv' into copilot/update-switch-stmt-usage
2 parents 316b414 + cae623d commit 464857c

67 files changed

Lines changed: 7563 additions & 5131 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import go
2+
private import semmle.go.controlflow.ControlFlowGraphShared
3+
import GoCfg::ControlFlow::Consistency
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: fix
3+
---
4+
* The Go control flow graph implementation has been migrated to use the shared CFG library. This is an internal change with no user-visible API changes.

go/ql/lib/printCfg.ql

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* @name Print CFG
3+
* @description Produces a representation of a file's Control Flow Graph.
4+
* This query is used by the VS Code extension.
5+
* @id go/print-cfg
6+
* @kind graph
7+
* @tags ide-contextual-queries/print-cfg
8+
*/
9+
10+
import go
11+
import semmle.go.controlflow.ControlFlowGraph
12+
private import semmle.go.controlflow.ControlFlowGraphShared
13+
14+
external string selectedSourceFile();
15+
16+
private predicate selectedSourceFileAlias = selectedSourceFile/0;
17+
18+
external int selectedSourceLine();
19+
20+
private predicate selectedSourceLineAlias = selectedSourceLine/0;
21+
22+
external int selectedSourceColumn();
23+
24+
private predicate selectedSourceColumnAlias = selectedSourceColumn/0;
25+
26+
module ViewCfgQueryInput implements GoCfg::ControlFlow::ViewCfgQueryInputSig<File> {
27+
predicate selectedSourceFile = selectedSourceFileAlias/0;
28+
29+
predicate selectedSourceLine = selectedSourceLineAlias/0;
30+
31+
predicate selectedSourceColumn = selectedSourceColumnAlias/0;
32+
33+
predicate cfgScopeSpan(
34+
CfgScope scope, File file, int startLine, int startColumn, int endLine, int endColumn
35+
) {
36+
file = scope.getFile() and
37+
scope.getLocation().getStartLine() = startLine and
38+
scope.getLocation().getStartColumn() = startColumn and
39+
exists(Location loc |
40+
loc.getEndLine() = endLine and
41+
loc.getEndColumn() = endColumn and
42+
loc = scope.(FuncDef).getBody().getLocation()
43+
)
44+
or
45+
file = scope.(File) and
46+
startLine = 1 and
47+
startColumn = 1 and
48+
endLine = file.getNumberOfLines() and
49+
endColumn = 999999
50+
}
51+
}
52+
53+
import GoCfg::ControlFlow::ViewCfgQuery<File, ViewCfgQueryInput>

go/ql/lib/semmle/go/Concepts.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ private class HeuristicLoggerFunction extends Method {
431431
)
432432
}
433433

434-
override predicate mayReturnNormally() { logFunctionPrefix != "Fatal" }
434+
override predicate mustNotReturnNormally() { logFunctionPrefix = "Fatal" }
435435

436436
override predicate mustPanic() { logFunctionPrefix = "Panic" }
437437
}

go/ql/lib/semmle/go/PrintAst.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* Provides queries to pretty-print a Go AST as a graph.
33
*/
4-
overlay[local]
4+
overlay[local?]
55
module;
66

77
import go

go/ql/lib/semmle/go/Scopes.qll

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -437,11 +437,12 @@ class Function extends ValueEntity, @functionobject {
437437
* This predicate is an over-approximation: it may hold for functions that can never
438438
* return normally, but it never fails to hold for functions that can.
439439
*
440-
* Note this is declared here and not in `DeclaredFunction` so that library models can override this
441-
* by extending `Function` rather than having to remember to extend `DeclaredFunction`.
440+
* Library models should not override this predicate; override `mustNotReturnNormally`
441+
* instead, so that the control-flow graph construction can take the model into account.
442442
*/
443443
predicate mayReturnNormally() {
444444
not this.mustPanic() and
445+
not this.mustNotReturnNormally() and
445446
(ControlFlow::mayReturnNormally(this.getFuncDecl()) or not exists(this.getBody()))
446447
}
447448

@@ -461,6 +462,16 @@ class Function extends ValueEntity, @functionobject {
461462
*/
462463
predicate mustPanic() { none() }
463464

465+
/**
466+
* Holds if calling this function never returns normally (for example because it
467+
* always panics, exits the process, or loops forever).
468+
*
469+
* Unlike `mayReturnNormally`, this predicate must be defined without reference to
470+
* the control-flow graph, so that it can be used during CFG construction to
471+
* suppress normal-flow successors of calls to this function.
472+
*/
473+
predicate mustNotReturnNormally() { none() }
474+
464475
/** Gets the number of parameters of this function. */
465476
int getNumParameter() { result = this.getType().(SignatureType).getNumParameter() }
466477

go/ql/lib/semmle/go/Stmt.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -761,7 +761,7 @@ class CaseClause extends @caseclause, Stmt, ScopeNode {
761761
*
762762
* Note that the default clause does not have any expressions.
763763
*/
764-
Expr getAnExpr() { result = this.getAChildExpr() }
764+
Expr getAnExpr() { result = this.getExpr(_) }
765765

766766
/**
767767
* Gets the number of expressions of this `case` clause.

go/ql/lib/semmle/go/controlflow/BasicBlocks.qll

Lines changed: 10 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -5,66 +5,27 @@ overlay[local]
55
module;
66

77
import go
8-
private import ControlFlowGraphImpl
9-
private import codeql.controlflow.BasicBlock as BB
10-
private import codeql.controlflow.SuccessorType
8+
private import ControlFlowGraphShared
119

12-
private module Input implements BB::InputSig<Location> {
13-
/** A delineated part of the AST with its own CFG. */
14-
class CfgScope = ControlFlow::Root;
10+
/** A basic block in the control-flow graph. */
11+
class BasicBlock = GoCfg::Cfg::BasicBlock;
1512

16-
/** The class of control flow nodes. */
17-
class Node = ControlFlowNode;
18-
19-
/** Gets the CFG scope in which this node occurs. */
20-
CfgScope nodeGetCfgScope(Node node) { node.getRoot() = result }
21-
22-
/** Gets an immediate successor of this node. */
23-
Node nodeGetASuccessor(Node node, SuccessorType t) {
24-
result = node.getASuccessor() and
25-
(
26-
not result instanceof ControlFlow::ConditionGuardNode and t instanceof DirectSuccessor
27-
or
28-
t.(BooleanSuccessor).getValue() = result.(ControlFlow::ConditionGuardNode).getOutcome()
29-
)
30-
}
31-
32-
/**
33-
* Holds if `node` represents an entry node to be used when calculating
34-
* dominance.
35-
*/
36-
predicate nodeIsDominanceEntry(Node node) { node instanceof EntryNode }
37-
38-
/**
39-
* Holds if `node` represents an exit node to be used when calculating
40-
* post dominance.
41-
*/
42-
predicate nodeIsPostDominanceExit(Node node) { node instanceof ExitNode }
43-
}
44-
45-
module Cfg = BB::Make<Location, Input>;
46-
47-
class BasicBlock = Cfg::BasicBlock;
48-
49-
class EntryBasicBlock = Cfg::EntryBasicBlock;
50-
51-
cached
52-
private predicate reachableBB(BasicBlock bb) {
53-
bb instanceof EntryBasicBlock
54-
or
55-
exists(BasicBlock predBB | predBB.getASuccessor(_) = bb | reachableBB(predBB))
56-
}
13+
/** An entry basic block. */
14+
class EntryBasicBlock = GoCfg::Cfg::EntryBasicBlock;
5715

5816
/**
5917
* A basic block that is reachable from an entry basic block.
18+
*
19+
* Since the shared CFG library only creates nodes for reachable code,
20+
* all basic blocks are reachable by construction.
6021
*/
6122
class ReachableBasicBlock extends BasicBlock {
62-
ReachableBasicBlock() { reachableBB(this) }
23+
ReachableBasicBlock() { any() }
6324
}
6425

6526
/**
6627
* A reachable basic block with more than one predecessor.
6728
*/
6829
class ReachableJoinBlock extends ReachableBasicBlock {
69-
ReachableJoinBlock() { this.getFirstNode().isJoin() }
30+
ReachableJoinBlock() { this.getFirstNode().(ControlFlow::Node).isJoin() }
7031
}

0 commit comments

Comments
 (0)