Skip to content

Commit 16c13fb

Browse files
authored
Initiate concrete execution if a wrapper method is missing (#392)
If a JVM class is overridden but a method is missing from the wrapper, the engine will discard the path and fall back to concrete execution instead of analysing the real JVM code graph. This approach fixes the problem with methods that have been introduced in newer JDKs. Now wrappers are mostly limited to Java 1.8 interfaces and fail to analyze methods like `String::isBlank` or `String::lines` when the code runs under JDK 11. Building graphs from the real JDK code fails because the wrapper does not have private fields that the original code uses. TODO: to allow symbolic analysis of the code, missing methods should be actually implemented in corresponding wrappers.
1 parent d4f95c1 commit 16c13fb

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

utbot-framework/src/main/kotlin/org/utbot/engine/CollectionWrappers.kt

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import org.utbot.engine.overrides.collections.UtHashSet
1010
import org.utbot.engine.overrides.collections.UtLinkedList
1111
import org.utbot.engine.pc.UtAddrExpression
1212
import org.utbot.engine.pc.UtExpression
13+
import org.utbot.engine.pc.UtFalse
1314
import org.utbot.engine.pc.select
1415
import org.utbot.engine.symbolic.asHardConstraint
1516
import org.utbot.engine.z3.intValue
@@ -84,10 +85,15 @@ abstract class BaseOverriddenWrapper(protected val overriddenClassName: String)
8485

8586
val overriddenMethod = overriddenClass.findMethodOrNull(method.subSignature)
8687

87-
val jimpleBody = overriddenMethod?.jimpleBody() ?: method.jimpleBody()
88-
val graphResult = GraphResult(jimpleBody.graph())
89-
90-
return listOf(graphResult)
88+
if (overriddenMethod == null) {
89+
// No overridden method has been found, switch to concrete execution
90+
pathLogger.warn("Method ${overriddenClass.name}::${method.subSignature} not found, executing concretely")
91+
return emptyList()
92+
} else {
93+
val jimpleBody = overriddenMethod.jimpleBody()
94+
val graphResult = GraphResult(jimpleBody.graph())
95+
return listOf(graphResult)
96+
}
9197
}
9298
}
9399

utbot-framework/src/main/kotlin/org/utbot/engine/UtBotSymbolicEngine.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3079,6 +3079,11 @@ class UtBotSymbolicEngine(
30793079

30803080
instanceAsWrapperOrNull?.run {
30813081
val results = invoke(instance as ObjectValue, invocation.method, invocation.parameters)
3082+
if (results.isEmpty()) {
3083+
// Drop the branch and switch to concrete execution
3084+
statesForConcreteExecution += environment.state
3085+
queuedSymbolicStateUpdates += UtFalse.asHardConstraint()
3086+
}
30823087
return OverrideResult(success = true, results)
30833088
}
30843089

0 commit comments

Comments
 (0)