Skip to content

Commit 6e4414a

Browse files
committed
Additional tests
1 parent 9b38fc9 commit 6e4414a

File tree

3 files changed

+77
-2
lines changed

3 files changed

+77
-2
lines changed

usvm-ts/src/main/kotlin/org/usvm/machine/interpreter/TsInterpreter.kt

+25
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,33 @@ class TsInterpreter(
162162
is TsMethodResult.Success -> observer?.onAssignStatement(exprResolver.simpleValueResolver, stmt, scope)
163163
is TsMethodResult.TsException -> error("Exceptions must be processed earlier")
164164
}
165+
166+
if (!tsOptions.interproceduralAnalysis && methodResult == TsMethodResult.NoCall) {
167+
scope.doWithState {
168+
with(ctx) {
169+
val resultSort = typeToSort(it.method.returnType)
170+
val resultValue = when (resultSort) {
171+
is UAddressSort -> makeSymbolicRefUntyped()
172+
is TsUnresolvedSort -> {
173+
mkFakeValue(
174+
scope,
175+
makeSymbolicPrimitive(ctx.boolSort),
176+
makeSymbolicPrimitive(ctx.fp64Sort),
177+
makeSymbolicRefUntyped()
178+
)
179+
}
180+
181+
else -> makeSymbolicPrimitive(resultSort)
182+
}
183+
this@doWithState.methodResult = TsMethodResult.Success.MockedCall(it.method, resultValue)
184+
}
185+
}
186+
return
187+
}
188+
165189
} ?: observer?.onAssignStatement(exprResolver.simpleValueResolver, stmt, scope)
166190

191+
167192
val expr = exprResolver.resolve(stmt.rhv) ?: return
168193

169194
check(expr.sort != unresolvedSort) {

usvm-ts/src/test/kotlin/org/usvm/samples/checkers/UnreachableCodeDetector.kt

+39-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.usvm.samples.checkers
22

3+
import org.jacodb.ets.base.EtsAssignStmt
4+
import org.jacodb.ets.base.EtsIfStmt
35
import org.jacodb.ets.model.EtsScene
46
import org.jacodb.ets.utils.loadEtsFileAutoConvert
57
import org.jacodb.ets.utils.loadEtsProjectFromIR
@@ -20,11 +22,11 @@ class UnreachableCodeDetectorTest {
2022
)
2123
EtsScene(listOf(file))
2224
}
25+
val options = UMachineOptions()
26+
val tsOptions = TsOptions(interproceduralAnalysis = false)
2327

2428
@Test
2529
fun testUnreachableCode() {
26-
val options = UMachineOptions()
27-
val tsOptions = TsOptions(interproceduralAnalysis = false)
2830
val observer = UnreachableCodeDetector()
2931
val machine = TsMachine(scene, options, tsOptions, observer, observer)
3032
val methods = scene.projectClasses
@@ -38,4 +40,39 @@ class UnreachableCodeDetectorTest {
3840

3941
check(uncoveredStatements != null) { "Uncovered statements are incorrect, results are $uncoveredStatements" }
4042
}
43+
44+
@Test
45+
fun testUnreachableCodeWithMockedCallsInside() {
46+
val observer = UnreachableCodeDetector()
47+
val tsOptions = TsOptions(interproceduralAnalysis = false)
48+
val machine = TsMachine(scene, options, tsOptions, observer, observer)
49+
val methods = scene.projectClasses
50+
.flatMap { it.methods }
51+
.filter { it.name == "unreachableCodeWithCallsInside" }
52+
machine.analyze(methods)
53+
54+
val results = observer.result.values.singleOrNull() ?: error("No results found")
55+
check(results.single().second.single() is EtsAssignStmt)
56+
}
57+
58+
@Test
59+
fun testUnreachableCodeCallsInside() {
60+
val observer = UnreachableCodeDetector()
61+
val tsOptions = TsOptions(interproceduralAnalysis = true)
62+
val machine = TsMachine(scene, options, tsOptions, observer, observer)
63+
val methodName = "unreachableCodeWithCallsInside"
64+
val methods = scene.projectClasses
65+
.flatMap { it.methods }
66+
.filter { it.name == methodName }
67+
68+
machine.analyze(methods)
69+
70+
val results = observer.result.entries
71+
72+
check(results.size == 2)
73+
74+
val relatedBranch = results.single { it.key.name == methodName }
75+
val stmts = relatedBranch.value.single()
76+
check(stmts.second.single() is EtsIfStmt)
77+
}
4178
}

usvm-ts/src/test/resources/samples/checkers/UnreachableCode.ts

+13
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,17 @@ class UnreachableCode {
1010
return 2
1111
}
1212
}
13+
14+
unreachableCodeWithCallsInside(value: number): number {
15+
anotherValue = this.simpleUnreachableBranch(value)
16+
if (anotherValue > 2) {
17+
if (anotherValue < 1) {
18+
return -1 // Unreachable code
19+
} else {
20+
return 1 // Unreachable if we execute simpleUnreachableBranch call and reachable otherwise
21+
}
22+
}
23+
24+
return
25+
}
1326
}

0 commit comments

Comments
 (0)