mirror of
https://github.com/Guardsquare/proguard.git
synced 2026-03-13 09:50:34 +08:00
Do not inline methods from interfaces
This commit is contained in:
committed by
Dimitrios Anyfantakis
parent
9a7a97d1ca
commit
8bb7cc0c4b
@@ -652,6 +652,14 @@ implements AttributeVisitor,
|
||||
AccessConstants.STATIC |
|
||||
AccessConstants.FINAL)) != 0 &&
|
||||
|
||||
DEBUG("Interface?") &&
|
||||
|
||||
// Methods in interfaces should not be inlined since this can potentially
|
||||
// lead to other methods in the interface needing broadened visibility,
|
||||
// which can lead to either compilation errors during output writing
|
||||
// or various issues at runtime.
|
||||
(programClass.getAccessFlags() & AccessConstants.INTERFACE) == 0 &&
|
||||
|
||||
DEBUG("Synchronized?") &&
|
||||
|
||||
// Only inline the method if it is not synchronized, etc.
|
||||
|
||||
@@ -282,6 +282,60 @@ class MethodInlinerTest : FreeSpec({
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"Given a method calling another method in an interface" - {
|
||||
val (programClassPool, _) = ClassPoolBuilder.fromSource(
|
||||
JavaSource(
|
||||
"Foo.java",
|
||||
"""interface Foo {
|
||||
default void f1() {
|
||||
f2();
|
||||
}
|
||||
|
||||
static void f2() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(System.currentTimeMillis());
|
||||
System.out.println(sb.toString());
|
||||
}
|
||||
}"""
|
||||
)
|
||||
)
|
||||
|
||||
val clazz = programClassPool.getClass("Foo") as ProgramClass
|
||||
val method = clazz.findMethod("f1", "()V") as ProgramMethod
|
||||
val codeAttr = method.attributes.filterIsInstance<CodeAttribute>()[0]
|
||||
|
||||
val lengthBefore = codeAttr.u4codeLength
|
||||
|
||||
// Initialize optimization info (used when inlining).
|
||||
val optimizationInfoInitializer: ClassVisitor = MultiClassVisitor(
|
||||
ProgramClassOptimizationInfoSetter(),
|
||||
AllMethodVisitor(
|
||||
ProgramMemberOptimizationInfoSetter()
|
||||
)
|
||||
)
|
||||
|
||||
programClassPool.classesAccept(optimizationInfoInitializer)
|
||||
|
||||
// Create a mock method inliner which always returns true.
|
||||
val methodInliner = object : MethodInliner(false, true, true) {
|
||||
override fun shouldInline(clazz: Clazz?, method: Method?, codeAttribute: CodeAttribute?): Boolean = true
|
||||
}
|
||||
|
||||
"Then the interface method is not inlined" {
|
||||
programClassPool.classesAccept(
|
||||
AllMethodVisitor(
|
||||
AllAttributeVisitor(
|
||||
methodInliner
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
val lengthAfter = codeAttr.u4codeLength
|
||||
|
||||
lengthAfter shouldBeExactly lengthBefore
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
private fun printProgramMethodInstructions(
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
- Fix "NoClassDefFoundError: Failed resolution of: Lorg/apache/logging/log4j/LogManager" when using GSON optimization or `-addconfigurationdebugging`. (#326)
|
||||
- Don't drop Record attribute for records with no components. (proguard-core#118)
|
||||
- Fix potential duplication class when name obfuscating Kotlin multi-file facades.
|
||||
- Do not inline interface methods to avoid compilation errors during output writing due to an interface method being made package visible.
|
||||
|
||||
## Version 7.3.2
|
||||
|
||||
|
||||
Reference in New Issue
Block a user