Skip to content

Commit 62d71aa

Browse files
committed
Handle reading from fake array
1 parent 97dea5f commit 62d71aa

1 file changed

Lines changed: 26 additions & 9 deletions

File tree

usvm-ts/src/main/kotlin/org/usvm/machine/expr/ReadArray.kt

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.usvm.machine.expr
22

33
import io.ksmt.utils.asExpr
4+
import mu.KotlinLogging
45
import org.jacodb.ets.model.EtsArrayAccess
56
import org.jacodb.ets.model.EtsArrayType
67
import org.jacodb.ets.model.EtsBooleanType
@@ -20,18 +21,30 @@ import org.usvm.types.first
2021
import org.usvm.util.mkArrayIndexLValue
2122
import org.usvm.util.mkArrayLengthLValue
2223

24+
private val logger = KotlinLogging.logger {}
25+
2326
internal fun TsExprResolver.handleArrayAccess(
2427
value: EtsArrayAccess,
2528
): UExpr<*>? = with(ctx) {
2629
// Resolve the array.
27-
val array = resolve(value.array) ?: return null
28-
check(array.sort == addressSort) {
29-
"Expected address sort for array, got: ${array.sort}"
30+
val array = run {
31+
val resolved = resolve(value.array) ?: return null
32+
if (resolved.isFakeObject()) {
33+
scope.assert(resolved.getFakeType(scope).refTypeExpr) ?: run {
34+
logger.warn { "UNSAT after ensuring fake object is ref-typed" }
35+
return null
36+
}
37+
resolved.extractRef(scope)
38+
} else {
39+
check(resolved.sort == addressSort) {
40+
"Expected address sort for array, got: ${resolved.sort}"
41+
}
42+
resolved.asExpr(addressSort)
43+
}
3044
}
31-
val arrayRef = array.asExpr(addressSort)
3245

3346
// Check for undefined or null array access.
34-
checkUndefinedOrNullPropertyRead(scope, arrayRef, propertyName = "[]") ?: return null
47+
checkUndefinedOrNullPropertyRead(scope, array, propertyName = "[]") ?: return null
3548

3649
// Resolve the index.
3750
val resolvedIndex = resolve(value.index) ?: return null
@@ -49,8 +62,8 @@ internal fun TsExprResolver.handleArrayAccess(
4962
).asExpr(sizeSort)
5063

5164
// Determine the array type.
52-
val arrayType = if (isAllocatedConcreteHeapRef(arrayRef)) {
53-
scope.calcOnState { memory.typeStreamOf(arrayRef).first() }
65+
val arrayType = if (isAllocatedConcreteHeapRef(array)) {
66+
scope.calcOnState { memory.typeStreamOf(array).first() }
5467
} else {
5568
value.array.type
5669
}
@@ -59,7 +72,7 @@ internal fun TsExprResolver.handleArrayAccess(
5972
}
6073

6174
// Read the array element.
62-
readArray(scope, arrayRef, bvIndex, arrayType)
75+
readArray(scope, array, bvIndex, arrayType)
6376
}
6477

6578
fun TsContext.readArray(
@@ -103,7 +116,11 @@ fun TsContext.readArray(
103116
index = index,
104117
type = arrayType,
105118
)
106-
return scope.calcOnState { memory.read(lValue) }
119+
val fake = scope.calcOnState { memory.read(lValue) }
120+
check(fake.isFakeObject()) {
121+
"Expected fake object in concrete array with unresolved element type, got: $fake"
122+
}
123+
return fake
107124
}
108125

109126
// If the element type is unresolved, we need to create a fake object

0 commit comments

Comments
 (0)