Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4462bab

Browse files
Andrei DiaconuAndreiDiaconu1
authored andcommitted
Added support for switch stmt (CS 6.0 style)
1 parent de6f547 commit 4462bab

3 files changed

Lines changed: 84 additions & 58 deletions

File tree

csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/TranslatedStmt.qll

Lines changed: 73 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ private import TranslatedExpr
99
private import TranslatedFunction
1010
private import TranslatedInitialization
1111
private import IRInternal
12+
private import semmle.code.csharp.ir.internal.IRUtilities
1213

1314
TranslatedStmt getTranslatedStmt(Stmt stmt) {
1415
result.getAST() = stmt
@@ -663,63 +664,82 @@ class TranslatedJumpStmt extends TranslatedStmt {
663664
EdgeKind kind) {
664665
tag = OnlyInstructionTag() and
665666
kind instanceof GotoEdge and
666-
// TODO: FIX THE SUCCESSOR INSTRUCTION
667-
result = getTranslatedStmt(stmt).getInstructionSuccessor(tag, kind)
667+
// Get the target of the jump
668+
// TODO: Make sure this is the best way to do it.
669+
// TODO: Does not work if the switch is the last instruction in a void function.
670+
// Maybe insert a dummy label after the switch like in C++?
671+
result = getTranslatedStmt(stmt.getAControlFlowNode().getASuccessor().getElement()).getFirstInstruction()
668672
}
669673

670674
override Instruction getChildSuccessor(TranslatedElement child) {
671675
none()
672676
}
673677
}
674678

675-
// TODO: Fix Switch stmts
676-
//class TranslatedSwitchStmt extends TranslatedStmt {
677-
// override SwitchStmt stmt;
678-
//
679-
// private TranslatedExpr getExpr() {
680-
// result = getTranslatedExpr(stmt.getExpr())
681-
// }
682-
//
683-
// private TranslatedStmt getBody() {
684-
// result = getTranslatedStmt(stmt.getBody())
685-
// }
686-
//
687-
// override Instruction getFirstInstruction() {
688-
// result = getExpr().getFirstInstruction()
689-
// }
690-
//
691-
// override TranslatedElement getChild(int id) {
692-
// id = 0 and result = getExpr() or
693-
// id = 1 and result = getBody()
694-
// }
695-
//
696-
// override predicate hasInstruction(Opcode opcode, InstructionTag tag,
697-
// Type resultType, boolean isLValue) {
698-
// tag = SwitchBranchTag() and
699-
// opcode instanceof Opcode::Switch and
700-
// resultType instanceof VoidType and
701-
// isLValue = false
702-
// }
703-
//
704-
// override Instruction getInstructionOperand(InstructionTag tag,
705-
// OperandTag operandTag) {
706-
// tag = SwitchBranchTag() and
707-
// operandTag instanceof ConditionOperandTag and
708-
// result = getExpr().getResult()
709-
// }
710-
//
711-
// override Instruction getInstructionSuccessor(InstructionTag tag,
712-
// EdgeKind kind) {
713-
// tag = SwitchBranchTag() and
714-
// exists(CaseStmt caseStmt |
715-
// caseStmt = stmt.getACase() and
716-
// kind = getCaseEdge(caseStmt) and
717-
// result = getTranslatedStmt(caseStmt).getFirstInstruction()
718-
// )
719-
// }
720-
//
721-
// override Instruction getChildSuccessor(TranslatedElement child) {
722-
// child = getExpr() and result = getInstruction(SwitchBranchTag()) or
723-
// child = getBody() and result = getParent().getChildSuccessor(this)
724-
// }
725-
//}
679+
class TranslatedSwitchStmt extends TranslatedStmt {
680+
override SwitchStmt stmt;
681+
682+
private TranslatedExpr getSwitchExpr() {
683+
result = getTranslatedExpr(stmt.getExpr())
684+
}
685+
686+
override Instruction getFirstInstruction() {
687+
result = getSwitchExpr().getFirstInstruction()
688+
}
689+
690+
override TranslatedElement getChild(int id) {
691+
if (id = -1) then
692+
result = getTranslatedExpr(stmt.getChild(0))
693+
else if (id = 0) then
694+
result = getTranslatedStmt(stmt.getChild(0))
695+
else
696+
result = getTranslatedStmt(stmt.getChild(id))
697+
}
698+
699+
override predicate hasInstruction(Opcode opcode, InstructionTag tag,
700+
Type resultType, boolean isLValue) {
701+
tag = SwitchBranchTag() and
702+
opcode instanceof Opcode::Switch and
703+
resultType instanceof VoidType and
704+
isLValue = false
705+
}
706+
707+
override Instruction getInstructionOperand(InstructionTag tag,
708+
OperandTag operandTag) {
709+
tag = SwitchBranchTag() and
710+
operandTag instanceof ConditionOperandTag and
711+
result = getSwitchExpr().getResult()
712+
}
713+
714+
private EdgeKind getCaseEdge(CaseStmt caseStmt) {
715+
if caseStmt instanceof DefaultCase then
716+
result instanceof DefaultEdge
717+
else
718+
exists(CaseEdge edge |
719+
result = edge and
720+
hasCaseEdge(caseStmt, edge.getMinValue(), edge.getMinValue())
721+
)
722+
}
723+
724+
override Instruction getInstructionSuccessor(InstructionTag tag,
725+
EdgeKind kind) {
726+
tag = SwitchBranchTag() and
727+
exists(CaseStmt caseStmt |
728+
caseStmt = stmt.getACase() and
729+
kind = getCaseEdge(caseStmt) and
730+
result = getTranslatedStmt(caseStmt).getFirstInstruction()
731+
)
732+
}
733+
734+
override Instruction getChildSuccessor(TranslatedElement child) {
735+
child = getSwitchExpr() and result = getInstruction(SwitchBranchTag()) or
736+
exists(int index, int numStmts |
737+
numStmts = count(stmt.getAChild()) and
738+
child = getTranslatedStmt(stmt.getChild(index)) and
739+
if index = (numStmts - 1) then
740+
result = getParent().getChildSuccessor(this)
741+
else
742+
result = getTranslatedStmt(stmt.getChild(index + 1)).getFirstInstruction()
743+
)
744+
}
745+
}

csharp/ql/src/semmle/code/csharp/ir/internal/IRCSharpLanguage.qll

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
private import csharp as CSharp
2+
private import IRUtilities
23

34
class Function = CSharp::Callable;
45
class Location = CSharp::Location;
@@ -62,8 +63,10 @@ string getIdentityString(Function func) {
6263
}
6364

6465
predicate hasCaseEdge(string minValue, string maxValue) {
65-
// TODO: Need to handle `switch` statements that switch on an integer.
66-
none()
66+
// TODO: Need to handle pattern matching
67+
exists(CSharp :: CaseStmt cst |
68+
hasCaseEdge(cst, minValue, maxValue)
69+
)
6770
}
6871

6972
predicate hasPositionalArgIndex(int argIndex) {

csharp/ql/src/semmle/code/csharp/ir/internal/IRUtilities.qll

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import csharp
2-
3-
// TODO: CHECK IF TALKING ABOUT POINTERS HERE MAKES SENSE
1+
private import csharp
42

53
/**
64
* Given a type, get the type that would result by applying "pointer decay".
@@ -36,3 +34,8 @@ Type getVariableType(Variable v) {
3634
)
3735
)
3836
}
37+
38+
predicate hasCaseEdge(CaseStmt caseStmt, string minValue, string maxValue) {
39+
minValue = caseStmt.getPattern().getValue() and
40+
maxValue = minValue
41+
}

0 commit comments

Comments
 (0)