Skip to content
Merged
Prev Previous commit
Next Next commit
Fixed a substitution static fields with unbounded variables
  • Loading branch information
Damtev committed Jan 3, 2023
commit fe0c3e6b4bb37824cb2a242ebddccc6b450f69a4
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.utbot.examples.annotations
import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test
import org.utbot.testcheckers.eq
import org.utbot.testing.AtLeast
import org.utbot.testing.UtValueTestCaseChecker

internal class NotNullAnnotationTest : UtValueTestCaseChecker(testClass = NotNullAnnotation::class) {
Expand Down Expand Up @@ -68,7 +69,8 @@ internal class NotNullAnnotationTest : UtValueTestCaseChecker(testClass = NotNul
checkStatics(
NotNullAnnotation::notNullStaticField,
eq(1),
{ statics, result -> result == statics.values.single().value }
{ statics, result -> result == statics.values.single().value },
coverage = AtLeast(66)
)
}

Expand Down
11 changes: 9 additions & 2 deletions utbot-framework/src/main/kotlin/org/utbot/engine/Memory.kt
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ data class Memory( // TODO: split purely symbolic memory and information about s
.mapValues { (_, values) -> values.first().value to values.last().value }

val previousMemoryStates = staticFieldsStates.toMutableMap()
val previousFieldValues = fieldValues.toMutableMap()


/**
Expand All @@ -212,6 +213,11 @@ data class Memory( // TODO: split purely symbolic memory and information about s
update.classIdToClearStatics?.let { classId ->
Scene.v().getSootClass(classId.name).fields.forEach { sootField ->
previousMemoryStates.remove(sootField.fieldId)

if (sootField.isStatic) {
// Only statics should be cleared here
previousFieldValues.remove(sootField)
Comment thread
Damtev marked this conversation as resolved.
}
}
}

Expand Down Expand Up @@ -254,7 +260,7 @@ data class Memory( // TODO: split purely symbolic memory and information about s
initializedStaticFields = initializedStaticFields.addAll(update.initializedStaticFields),
staticFieldsStates = previousMemoryStates.toPersistentMap().putAll(updatedStaticFields),
meaningfulStaticFields = meaningfulStaticFields.addAll(update.meaningfulStaticFields),
fieldValues = fieldValues.putAll(update.fieldValues),
fieldValues = previousFieldValues.toPersistentMap().putAll(update.fieldValues),
addrToArrayType = addrToArrayType.putAll(update.addrToArrayType),
addrToMockInfo = addrToMockInfo.putAll(update.addrToMockInfo),
updates = updates + update,
Expand All @@ -278,7 +284,8 @@ data class Memory( // TODO: split purely symbolic memory and information about s
*/
fun queuedStaticMemoryUpdates(): MemoryUpdate = MemoryUpdate(
staticInstanceStorage = updates.staticInstanceStorage,
staticFieldsUpdates = updates.staticFieldsUpdates
staticFieldsUpdates = updates.staticFieldsUpdates,
fieldValues = updates.fieldValues.filter { it.key.isStatic }.toPersistentMap()
)

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import kotlinx.collections.immutable.persistentHashSetOf
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.persistentSetOf
import kotlinx.collections.immutable.toPersistentList
import kotlinx.collections.immutable.toPersistentMap
import kotlinx.collections.immutable.toPersistentSet
import org.utbot.common.WorkaroundReason.HACK
import org.utbot.framework.UtSettings.ignoreStaticsFromTrustedLibraries
Expand Down Expand Up @@ -1936,7 +1937,6 @@ class Traverser(
val touchedStaticFields = persistentListOf(staticFieldMemoryUpdate)
queuedSymbolicStateUpdates += MemoryUpdate(staticFieldsUpdates = touchedStaticFields)

// TODO filter enum constant static fields JIRA:1681
if (!environment.method.isStaticInitializer && isStaticFieldMeaningful(field)) {
queuedSymbolicStateUpdates += MemoryUpdate(meaningfulStaticFields = persistentSetOf(fieldId))
}
Expand Down Expand Up @@ -3579,6 +3579,7 @@ class Traverser(
val declaringClassId = declaringClass.id

val staticFieldsUpdates = updates.staticFieldsUpdates.toMutableList()
val fieldValuesUpdates = updates.fieldValues.toMutableMap()
val updatedFields = staticFieldsUpdates.mapTo(mutableSetOf()) { it.fieldId }
val objectUpdates = mutableListOf<UtNamedStore>()

Expand All @@ -3591,6 +3592,7 @@ class Traverser(
// remove updates from clinit, because we'll replace those values
// with new unbounded symbolic variable
staticFieldsUpdates.removeAll { update -> update.fieldId == it.fieldId }
fieldValuesUpdates.keys.removeAll { key -> key.fieldId == it.fieldId }

val value = createConst(it.type, it.name)
val valueToStore = if (value is ReferenceValue) {
Expand All @@ -3610,6 +3612,7 @@ class Traverser(
return updates.copy(
stores = updates.stores.addAll(objectUpdates),
staticFieldsUpdates = staticFieldsUpdates.toPersistentList(),
fieldValues = fieldValuesUpdates.toPersistentMap(),
classIdToClearStatics = declaringClassId
)
}
Expand Down