Skip to content

Commit af98779

Browse files
committed
C#: Include parameters and their defaults in the CFG
1 parent f5f6189 commit af98779

19 files changed

Lines changed: 1968 additions & 1014 deletions

csharp/ql/lib/semmle/code/csharp/ExprOrStmtParent.qll

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ private import internal.Location
1313
* An element that can have a child statement or expression.
1414
*/
1515
class ExprOrStmtParent extends Element, @exprorstmt_parent {
16-
final override ControlFlowElement getChild(int i) {
16+
override ControlFlowElement getChild(int i) {
1717
result = this.getChildExpr(i) or
1818
result = this.getChildStmt(i)
1919
}
@@ -42,14 +42,8 @@ class ExprOrStmtParent extends Element, @exprorstmt_parent {
4242
*
4343
* An element that can have a child top-level expression.
4444
*/
45-
class TopLevelExprParent extends Element, @top_level_expr_parent {
45+
class TopLevelExprParent extends ExprOrStmtParent, @top_level_expr_parent {
4646
final override Expr getChild(int i) { result = this.getChildExpr(i) }
47-
48-
/** Gets the `i`th child expression of this element (zero-based). */
49-
final Expr getChildExpr(int i) { expr_parent_top_level_adjusted(result, i, this) }
50-
51-
/** Gets a child expression of this element, if any. */
52-
final Expr getAChildExpr() { result = this.getChildExpr(_) }
5347
}
5448

5549
/** INTERNAL: Do not use. */

csharp/ql/lib/semmle/code/csharp/PrintAst.qll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,9 @@ class ControlFlowElementNode extends ElementNode {
299299
not isNotNeeded(element.getParent+()) and
300300
// LambdaExpr is both a Callable and a ControlFlowElement,
301301
// print it with the more specific CallableNode
302-
not element instanceof Callable
302+
not element instanceof Callable and
303+
// Handled in `ParameterNode`
304+
not element instanceof Parameter
303305
}
304306

305307
override PrintAstNode getChild(int childIndex) {

csharp/ql/lib/semmle/code/csharp/Variable.qll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,9 @@ class LocalScopeVariable extends Variable, @local_scope_variable {
8787
* }
8888
* ```
8989
*/
90-
class Parameter extends LocalScopeVariable, Attributable, TopLevelExprParent, @parameter {
90+
class Parameter extends LocalScopeVariable, Attributable, TopLevelExprParent, ControlFlowElement,
91+
@parameter
92+
{
9193
/** Gets the raw position of this parameter, including the `this` parameter at index 0. */
9294
final int getRawPosition() { this = this.getDeclaringElement().getRawParameter(result) }
9395

csharp/ql/lib/semmle/code/csharp/controlflow/ControlFlowGraph.qll

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,16 @@ private module Ast implements AstSig<Location> {
7373
private AstNode getParent(AstNode n) { n = getChild(result, _) }
7474

7575
Callable getEnclosingCallable(AstNode node) {
76-
result = node.(ControlFlowElement).getEnclosingCallable() or
77-
result.(ObjectInitMethod).initializes(getParent*(node)) or
76+
result = node.(ControlFlowElement).getEnclosingCallable()
77+
or
78+
result.(ObjectInitMethod).initializes(getParent*(node))
79+
or
7880
Initializers::staticMemberInitializer(result, getParent*(node))
81+
or
82+
result = node.(Parameter).getCallable()
83+
or
84+
not skipControlFlow(node) and
85+
getParent*(node) = any(Parameter p | result = p.getCallable()).getDefaultValue()
7986
}
8087

8188
class Callable = CS::Callable;
@@ -85,6 +92,17 @@ private module Ast implements AstSig<Location> {
8592
result = c.getBody()
8693
}
8794

95+
final private class ParameterFinal = CS::Parameter;
96+
97+
class Parameter extends ParameterFinal {
98+
Expr getDefaultValue() {
99+
result = super.getDefaultValue() and
100+
getCompilation(result.getFile()) = getCompilation(this.getFile())
101+
}
102+
}
103+
104+
Parameter callableGetParameter(Callable c, int i) { result = c.getParameter(i) }
105+
88106
class Stmt = CS::Stmt;
89107

90108
class Expr = CS::Expr;
@@ -415,10 +433,10 @@ private module Input implements InputSig1, InputSig2 {
415433
l = TLblGoto(n.(LabelStmt).getLabel())
416434
}
417435

418-
class CallableBodyPartContext = CompilationExt;
436+
class CallableContext = CompilationExt;
419437

420438
pragma[nomagic]
421-
Ast::AstNode callableGetBodyPart(Callable c, CallableBodyPartContext ctx, int index) {
439+
Ast::AstNode callableGetBodyPart(Callable c, CallableContext ctx, int index) {
422440
not Ast::skipControlFlow(result) and
423441
ctx = getCompilation(result.getFile()) and
424442
(
@@ -437,9 +455,19 @@ private module Input implements InputSig1, InputSig2 {
437455
or
438456
i = 2 and result = ctor.getBody()
439457
)
458+
or
459+
not c instanceof Constructor and
460+
result = c.getBody() and
461+
index = 0
440462
)
441463
}
442464

465+
pragma[nomagic]
466+
Ast::Parameter callableGetParameter(Callable c, CallableContext ctx, int index) {
467+
result = Ast::callableGetParameter(c, index) and
468+
ctx = getCompilation(result.getFile())
469+
}
470+
443471
private Expr getQualifier(QualifiableExpr qe) {
444472
result = qe.getQualifier() or
445473
result = qe.(ExtensionMethodCall).getArgument(0)

csharp/ql/lib/semmlecode.csharp.dbscheme

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1362,7 +1362,7 @@ compiler_generated(unique int id: @element ref);
13621362

13631363
/** CONTROL/DATA FLOW **/
13641364

1365-
@control_flow_element = @stmt | @expr;
1365+
@control_flow_element = @stmt | @expr | @parameter;
13661366

13671367
/* XML Files */
13681368

0 commit comments

Comments
 (0)