Skip to content

Commit a473fdb

Browse files
authored
Merge pull request #21759 from hvitved/csharp/cfg-params
C#: Include parameters and their defaults in the CFG
2 parents fed42d6 + e14b654 commit a473fdb

51 files changed

Lines changed: 8707 additions & 1163 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

csharp/downgrades/3cabc77473cbbda95edebafea345c2e3fdfa12d9/old.dbscheme

Lines changed: 1505 additions & 0 deletions
Large diffs are not rendered by default.

csharp/downgrades/3cabc77473cbbda95edebafea345c2e3fdfa12d9/semmlecode.csharp.dbscheme

Lines changed: 1505 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
description: Remove `@parameter` from `@control_flow_element`
2+
compatibility: full

csharp/ql/lib/printCfg.ql

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99

1010
import csharp
11+
import semmle.code.csharp.controlflow.internal.ControlFlowGraph
1112

1213
external string selectedSourceFile();
1314

@@ -22,14 +23,16 @@ external int selectedSourceColumn();
2223
private predicate selectedSourceColumnAlias = selectedSourceColumn/0;
2324

2425
module ViewCfgQueryInput implements ControlFlow::ViewCfgQueryInputSig<File> {
26+
private import semmle.code.csharp.controlflow.ControlFlowGraph
27+
2528
predicate selectedSourceFile = selectedSourceFileAlias/0;
2629

2730
predicate selectedSourceLine = selectedSourceLineAlias/0;
2831

2932
predicate selectedSourceColumn = selectedSourceColumnAlias/0;
3033

3134
predicate cfgScopeSpan(
32-
Callable scope, File file, int startLine, int startColumn, int endLine, int endColumn
35+
Ast::Callable scope, File file, int startLine, int startColumn, int endLine, int endColumn
3336
) {
3437
file = scope.getFile() and
3538
scope.getLocation().getStartLine() = startLine and

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

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,8 @@ module AssignableInternal {
271271
def = TPatternDefinition(result)
272272
or
273273
def = TAssignOperationDefinition(result)
274+
or
275+
def = TParameterDefaultDefinition(_, result)
274276
}
275277

276278
/** A local variable declaration at the top-level of a pattern. */
@@ -308,10 +310,17 @@ module AssignableInternal {
308310
exists(Callable c | p = c.getAParameter() |
309311
c.hasBody()
310312
or
311-
// Same as `c.(Constructor).hasInitializer()`, but avoids negative recursion warning
312-
c.getAChildExpr() instanceof @constructor_init_expr
313+
c.(Constructor).hasInitializer()
313314
)
314315
} or
316+
TParameterDefaultDefinition(Parameter p, Expr default) {
317+
exists(Callable c | p = c.getAParameter() |
318+
c.hasBody()
319+
or
320+
c.(Constructor).hasInitializer()
321+
) and
322+
default = p.getDefaultValue()
323+
} or
315324
TAddressOfDefinition(AddressOfExpr aoe) or
316325
TPatternDefinition(TopLevelPatternDecl tlpd) or
317326
TAssignOperationDefinition(AssignOperation ao) {
@@ -350,6 +359,8 @@ module AssignableInternal {
350359
any(AssignableDefinitions::PatternDefinition pd | result = pd.getDeclaration().getVariable())
351360
or
352361
def = any(AssignableDefinitions::InitializerDefinition init | result = init.getAssignable())
362+
or
363+
def = TParameterDefaultDefinition(result, _)
353364
}
354365

355366
// Not defined by dispatch in order to avoid too conservative negative recursion error
@@ -493,11 +504,6 @@ class AssignableDefinition extends TAssignableDefinition {
493504
exists(Ssa::ExplicitDefinition def | result = def.getAFirstReadAtNode(cfn) |
494505
this = def.getADefinition()
495506
)
496-
or
497-
exists(Ssa::ImplicitParameterDefinition def | result = def.getAFirstReadAtNode(cfn) |
498-
this.(AssignableDefinitions::ImplicitParameterDefinition).getParameter() =
499-
def.getParameter()
500-
)
501507
)
502508
}
503509

@@ -689,7 +695,33 @@ module AssignableDefinitions {
689695

690696
override string toString() { result = p.toString() }
691697

692-
override Location getLocation() { result = this.getTarget().getLocation() }
698+
override Location getLocation() { result = p.getLocation() }
699+
}
700+
701+
/**
702+
* A default value assigned to a parameter.
703+
*/
704+
class ParameterDefaultDefinition extends AssignableDefinition, TParameterDefaultDefinition {
705+
Parameter p;
706+
Expr default;
707+
708+
ParameterDefaultDefinition() { this = TParameterDefaultDefinition(p, default) }
709+
710+
/** Gets the underlying parameter. */
711+
Parameter getParameter() { result = p }
712+
713+
/** Gets the default value expression for the parameter. */
714+
Expr getDefaultValue() { result = default }
715+
716+
override Expr getSource() { result = default }
717+
718+
override Expr getElement() { result = default }
719+
720+
override Callable getEnclosingCallable() { result = p.getCallable() }
721+
722+
override string toString() { result = p.toString() + " = ..." }
723+
724+
override Location getLocation() { result = default.getLocation() }
693725
}
694726

695727
/**

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

0 commit comments

Comments
 (0)