11package org.usvm.machine.expr
22
33import io.ksmt.utils.asExpr
4+ import mu.KotlinLogging
45import org.jacodb.ets.model.EtsArrayAccess
56import org.jacodb.ets.model.EtsArrayType
67import org.jacodb.ets.model.EtsBooleanType
@@ -20,18 +21,30 @@ import org.usvm.types.first
2021import org.usvm.util.mkArrayIndexLValue
2122import org.usvm.util.mkArrayLengthLValue
2223
24+ private val logger = KotlinLogging .logger {}
25+
2326internal 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
6578fun 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