Skip to content

Commit d2ebbe0

Browse files
authored
Merge pull request #7469 from hvitved/csharp/promote-adhoc-consistency-checks
C#: Promote existing ad-hoc consistency checks to consistency queries
2 parents 533fc7a + a1bbe58 commit d2ebbe0

File tree

24 files changed

+156
-157
lines changed

24 files changed

+156
-157
lines changed

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImplCommon.qll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,4 +659,15 @@ module Consistency {
659659
not phiHasInputFromBlock(_, def, _) and
660660
not uncertainWriteDefinitionInput(_, def)
661661
}
662+
663+
query predicate notDominatedByDef(RelevantDefinition def, SourceVariable v, BasicBlock bb, int i) {
664+
exists(BasicBlock bbDef, int iDef | def.definesAt(v, bbDef, iDef) |
665+
ssaDefReachesReadWithinBlock(v, def, bb, i) and
666+
(bb != bbDef or i < iDef)
667+
or
668+
ssaDefReachesRead(v, def, bb, i) and
669+
not ssaDefReachesReadWithinBlock(v, def, bb, i) and
670+
not def.definesAt(v, getImmediateBasicBlockDominator*(bb), _)
671+
)
672+
}
662673
}

csharp/extractor/Semmle.Extraction.CSharp/Entities/Constructor.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,7 @@ protected override void ExtractInitializers(TextWriter trapFile)
113113

114114
trapFile.expr_call(init, target);
115115

116-
var child = 0;
117-
foreach (var arg in initializer.ArgumentList.Arguments)
118-
{
119-
Expression.Create(Context, arg.Expression, init, child++);
120-
}
116+
init.PopulateArguments(trapFile, initializer.ArgumentList, 0);
121117
}
122118

123119
private ConstructorDeclarationSyntax? Syntax

csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using Semmle.Extraction.CSharp.Entities.Expressions;
55
using Semmle.Extraction.Kinds;
66
using System;
7+
using System.Collections.Generic;
78
using System.IO;
89
using System.Linq;
910

@@ -324,7 +325,12 @@ public void MakeConditional(TextWriter trapFile)
324325

325326
public void PopulateArguments(TextWriter trapFile, BaseArgumentListSyntax args, int child)
326327
{
327-
foreach (var arg in args.Arguments)
328+
PopulateArguments(trapFile, args.Arguments, child);
329+
}
330+
331+
public void PopulateArguments(TextWriter trapFile, IEnumerable<ArgumentSyntax> args, int child)
332+
{
333+
foreach (var arg in args)
328334
PopulateArgument(trapFile, arg, child++);
329335
}
330336

csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Initializer.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,7 @@ protected override void PopulateExpression(TextWriter trapFile)
105105
if (assignment.Left is ImplicitElementAccessSyntax iea)
106106
{
107107
// An array/indexer initializer of the form `[...] = ...`
108-
109-
var indexChild = 0;
110-
foreach (var arg in iea.ArgumentList.Arguments)
111-
{
112-
Expression.Create(Context, arg.Expression, access, indexChild++);
113-
}
108+
access.PopulateArguments(trapFile, iea.ArgumentList.Arguments, 0);
114109
}
115110
}
116111
else

csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Tuple.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,7 @@ private Tuple(ExpressionNodeInfo info) : base(info.SetKind(ExprKind.TUPLE))
1515

1616
protected override void PopulateExpression(TextWriter trapFile)
1717
{
18-
var child = 0;
19-
foreach (var argument in Syntax.Arguments.Select(a => a.Expression))
20-
{
21-
Expression.Create(Context, argument, this, child++);
22-
}
18+
PopulateArguments(trapFile, Syntax.Arguments, 0);
2319
}
2420
}
2521
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import csharp
2+
3+
query predicate missingLocation(Element e) {
4+
(
5+
e instanceof Declaration or
6+
e instanceof Expr or
7+
e instanceof Stmt
8+
) and
9+
not e instanceof ImplicitAccessorParameter and
10+
not e instanceof NullType and
11+
not e instanceof Parameter and // Bug in Roslyn - params occasionally lack locations
12+
not e.(Operator).getDeclaringType() instanceof IntType and // Roslyn quirk
13+
not e instanceof Constructor and
14+
not e instanceof ArrayType and
15+
not e instanceof UnknownType and
16+
not e instanceof ArglistType and
17+
not exists(TupleType t | e = t or e = t.getAField()) and
18+
not exists(e.getLocation())
19+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import csharp
2+
3+
query predicate missingUnbound(ConstructedGeneric g) { not exists(g.getUnboundGeneric()) }
4+
5+
query predicate missingArgs(ConstructedGeneric g) { g.getNumberOfTypeArguments() = 0 }
6+
7+
query predicate inconsistentArgCount(ConstructedGeneric g) {
8+
g.getUnboundGeneric().getNumberOfTypeParameters() != g.getNumberOfTypeArguments()
9+
}

csharp/ql/consistency-queries/SsaConsistency.ql

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import csharp
22
import semmle.code.csharp.dataflow.internal.SsaImplCommon::Consistency
3+
import Ssa
34

45
class MyRelevantDefinition extends RelevantDefinition, Ssa::Definition {
56
override predicate hasLocationInfo(
@@ -8,3 +9,18 @@ class MyRelevantDefinition extends RelevantDefinition, Ssa::Definition {
89
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
910
}
1011
}
12+
13+
query predicate localDeclWithSsaDef(LocalVariableDeclExpr d) {
14+
// Local variables in C# must be initialized before every use, so uninitialized
15+
// local variables should not have an SSA definition, as that would imply that
16+
// the declaration is live (can reach a use without passing through a definition)
17+
exists(ExplicitDefinition def |
18+
d = def.getADefinition().(AssignableDefinitions::LocalVariableDefinition).getDeclaration()
19+
|
20+
not d = any(ForeachStmt fs).getVariableDeclExpr() and
21+
not d = any(SpecificCatchClause scc).getVariableDeclExpr() and
22+
not d.getVariable().getType() instanceof Struct and
23+
not d instanceof PatternExpr and
24+
not d.getVariable().isCaptured()
25+
)
26+
}

csharp/ql/lib/semmle/code/cil/internal/SsaImplCommon.qll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,4 +659,15 @@ module Consistency {
659659
not phiHasInputFromBlock(_, def, _) and
660660
not uncertainWriteDefinitionInput(_, def)
661661
}
662+
663+
query predicate notDominatedByDef(RelevantDefinition def, SourceVariable v, BasicBlock bb, int i) {
664+
exists(BasicBlock bbDef, int iDef | def.definesAt(v, bbDef, iDef) |
665+
ssaDefReachesReadWithinBlock(v, def, bb, i) and
666+
(bb != bbDef or i < iDef)
667+
or
668+
ssaDefReachesRead(v, def, bb, i) and
669+
not ssaDefReachesReadWithinBlock(v, def, bb, i) and
670+
not def.definesAt(v, getImmediateBasicBlockDominator*(bb), _)
671+
)
672+
}
662673
}

csharp/ql/lib/semmle/code/csharp/commons/ConsistencyChecks.qll

Lines changed: 0 additions & 102 deletions
This file was deleted.

0 commit comments

Comments
 (0)