Skip to content

Commit

Permalink
Another bunch of locals var fixes (#189)
Browse files Browse the repository at this point in the history
Java function argument assignment ignored #187

Co-authored-by: DaniilStepanov <[email protected]>
  • Loading branch information
lehvolk and DaniilStepanov authored Oct 10, 2023
1 parent 7eb353d commit d0363b2
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,17 @@ class MethodNodeBuilder(
mn.tryCatchBlocks = tryCatchNodeList
mn.maxLocals = localIndex
mn.maxStack = maxStack + 1
//At this moment, we're just copying annotations from original method without any modifications
// with(method.asmNode()) {
// mn.visibleAnnotations = visibleAnnotations
// mn.visibleTypeAnnotations = visibleTypeAnnotations
// mn.visibleLocalVariableAnnotations = visibleLocalVariableAnnotations
// mn.visibleParameterAnnotations = visibleParameterAnnotations
// mn.invisibleAnnotations = invisibleAnnotations
// mn.invisibleTypeAnnotations = invisibleTypeAnnotations
// mn.invisibleLocalVariableAnnotations = invisibleLocalVariableAnnotations
// mn.invisibleParameterAnnotations = invisibleParameterAnnotations
// }
return mn
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -413,9 +413,14 @@ class RawInstListBuilder(
expr: JcRawValue,
insn: AbstractInsnNode,
override: Boolean = false
): JcRawAssignInst? {
): JcRawAssignInst {
val oldVar = currentFrame.locals[variable]?.let {
if (expr.typeName.isPrimitive.xor(it.typeName.isPrimitive) && it.typeName.typeName != PredefinedPrimitives.Null) {
val infoFromLocalVars = methodNode.localVariables.find { it.index == variable && insn.isBetween(it.start, it.end) }
val isArg = variable < argCounter && infoFromLocalVars != null && infoFromLocalVars.start == methodNode.instructions.firstOrNull { it is LabelNode }
if (expr.typeName.isPrimitive.xor(it.typeName.isPrimitive)
&& it.typeName.typeName != PredefinedPrimitives.Null
&& !isArg
) {
null
} else {
it
Expand All @@ -438,7 +443,18 @@ class RawInstListBuilder(
JcRawAssignInst(method, assignment, expr)
}
} else {
val newLocal = nextRegisterDeclaredVariable(expr.typeName, variable, insn)
//We have to get type if rhv expression is NULL
val typeOfNewAssigment =
if (expr.typeName.typeName == PredefinedPrimitives.Null) {
methodNode.localVariables
.find { it.index == variable && insn.isBetween(it.start, it.end) }
?.desc?.typeName()
?: currentFrame.locals[variable]?.typeName
?: "java.lang.Object".typeName()
} else {
expr.typeName
}
val newLocal = nextRegisterDeclaredVariable(typeOfNewAssigment, variable, insn)
val result = JcRawAssignInst(method, newLocal, expr)
currentFrame = currentFrame.put(variable, newLocal)
result
Expand Down Expand Up @@ -922,8 +938,7 @@ class RawInstListBuilder(
val isArg =
if (actualLocalFromDebugInfo == null) {
variable < argCounter
}
else {
} else {
actualLocalFromDebugInfo.start == methodNode.instructions.firstOrNull { it is LabelNode }
}

Expand Down Expand Up @@ -1094,9 +1109,13 @@ class RawInstListBuilder(
val variable = insnNode.`var`
val local = local(variable)
val nextInst = insnNode.next
val prevInst = insnNode.previous
val incrementedVariable = when {
nextInst != null && nextInst.isBranchingInst -> local
nextInst != null && nextInst is VarInsnNode && nextInst.`var` == variable -> local
//Workaround for if (x++) if x is function argument
prevInst != null && local is JcRawArgument && prevInst is VarInsnNode && prevInst.`var` == variable -> nextRegister(local.typeName)
local is JcRawArgument -> local
else -> nextRegister(local.typeName)
}
val add = JcRawAddExpr(local.typeName, local, JcRawInt(insnNode.incr))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ import org.jacodb.testing.hierarchies.Inheritance
import org.jacodb.testing.primitives.Primitives
import org.jacodb.testing.structure.FieldsAndMethods
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.condition.DisabledOnJre
import org.junit.jupiter.api.condition.EnabledOnJre
Expand Down Expand Up @@ -314,6 +313,11 @@ class InstructionsTest : BaseInstructionsTest() {
assertNull(res)
}

@Test
fun `arg assignment`() {
runTest(ArgAssignmentExample::class.java.name)
}

}

fun JcMethod.dumpInstructions(): String {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2022 UnitTestBot contributors (utbot.org)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.jacodb.testing.cfg;

public class ArgAssignmentExample {
private static class X {
public final int a = 0;
}

private static X sample(X arg) {
if (arg.a == 0) {
arg = null;
}
return arg;
}

public String box() {
X result = sample(new X());
return result == null ? "OK" : "BAD";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ val guavaLib: File

val asmLib: File
get() {
val asmUrl = classpath.first { it.contains("/asm/") }
val asmUrl = classpath.first { it.contains("${File.separator}asm${File.separator}") }
return File(asmUrl).also {
Assertions.assertTrue(it.isFile && it.exists())
}
Expand All @@ -51,7 +51,7 @@ val kotlinxCoroutines: File

val kotlinStdLib: File
get() {
val kotlinStdLib = classpath.first { it.contains("/kotlin-stdlib/") }
val kotlinStdLib = classpath.first { it.contains("${File.separator}kotlin-stdlib${File.separator}") }
return File(kotlinStdLib).also {
Assertions.assertTrue(it.isFile && it.exists())
}
Expand Down

0 comments on commit d0363b2

Please sign in to comment.