@@ -9,6 +9,7 @@ private import TranslatedExpr
99private import TranslatedFunction
1010private import TranslatedInitialization
1111private import IRInternal
12+ private import semmle.code.csharp.ir.internal.IRUtilities
1213
1314TranslatedStmt 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+ }
0 commit comments