Skip to content

Commit 11f7688

Browse files
committed
C#: Include parameters and their defaults in the CFG
1 parent 935c833 commit 11f7688

18 files changed

Lines changed: 1965 additions & 1013 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/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

csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected

Lines changed: 157 additions & 169 deletions
Large diffs are not rendered by default.

csharp/ql/test/library-tests/controlflow/graph/Condition.expected

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,10 @@ conditionBlock
260260
| Conditions.cs:143:10:143:12 | Entry | Conditions.cs:145:17:145:17 | After access to parameter b [true] | true |
261261
| Conditions.cs:145:17:145:29 | After ... ? ... : ... | Conditions.cs:146:13:146:13 | After access to parameter b [false] | false |
262262
| Conditions.cs:145:17:145:29 | After ... ? ... : ... | Conditions.cs:146:13:146:13 | After access to parameter b [true] | true |
263+
| DefaultParam.cs:3:12:3:13 | Entry | DefaultParam.cs:3:30:3:30 | After s [match] | true |
264+
| DefaultParam.cs:3:12:3:13 | Entry | DefaultParam.cs:3:30:3:30 | After s [no-match] | false |
265+
| DefaultParam.cs:3:42:3:42 | i | DefaultParam.cs:3:42:3:42 | After i [match] | true |
266+
| DefaultParam.cs:3:42:3:42 | i | DefaultParam.cs:3:42:3:42 | After i [no-match] | false |
263267
| ExitMethods.cs:38:10:38:11 | Entry | ExitMethods.cs:44:9:47:9 | After catch (...) {...} [match] | true |
264268
| ExitMethods.cs:38:10:38:11 | Entry | ExitMethods.cs:44:9:47:9 | After catch (...) {...} [no-match] | false |
265269
| ExitMethods.cs:38:10:38:11 | Entry | ExitMethods.cs:48:9:51:9 | After catch (...) {...} [match] | false |
@@ -485,6 +489,8 @@ conditionBlock
485489
| LoopUnrolling.cs:94:10:94:12 | Entry | LoopUnrolling.cs:97:22:97:22 | String x | false |
486490
| LoopUnrolling.cs:94:10:94:12 | Entry | LoopUnrolling.cs:97:27:97:28 | After access to local variable xs [empty] | true |
487491
| LoopUnrolling.cs:94:10:94:12 | Entry | LoopUnrolling.cs:97:27:97:28 | After access to local variable xs [non-empty] | false |
492+
| MultiImplementationA.cs:16:17:16:18 | Entry | MultiImplementationA.cs:16:24:16:24 | After i [match] | true |
493+
| MultiImplementationA.cs:16:17:16:18 | Entry | MultiImplementationA.cs:16:24:16:24 | After i [no-match] | false |
488494
| NullCoalescing.cs:3:9:3:10 | Entry | NullCoalescing.cs:3:23:3:23 | After access to parameter i [non-null] | false |
489495
| NullCoalescing.cs:3:9:3:10 | Entry | NullCoalescing.cs:3:23:3:23 | After access to parameter i [null] | true |
490496
| NullCoalescing.cs:5:9:5:10 | Entry | NullCoalescing.cs:5:25:5:25 | After access to parameter b [non-null] | false |

0 commit comments

Comments
 (0)