Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parameterless constructor might be made private when another constructor has its parameters removed #18

Closed
netomi opened this issue Dec 12, 2019 · 2 comments
Labels
bug Potential bug in ProGuard.

Comments

@netomi
Copy link

netomi commented Dec 12, 2019

When a class has multiple constructors it can happen that for some of them, unused parameters are removed. When several constructors have the same descriptor afterwards, ProGuard has to fix that by introducing some synthetic parameters to distinguish them from another.

Now this can lead to situations where the constructor whose parameter has been removed will become the new parameterless constructor, and the original constructor has some additional parameter.

This can have multiple effects: the original parameterless constructor might be made private, and a different constructor might be called when the class is dynamically created.

A simple example to illustrate the problem is this kotlin class:

class MyService(
private val foo: String = "bar",
private val bar: Intent = Intent()
) : Service() {
override fun onBind(intent: Intent?): IBinder? = null
}

As there are default values, the kotlin compiler will create additional synthetic constructors whose parameters might get removed.

When using Proguard on the class with optimization enabled, the original parameterless constructor is made private.

@netomi netomi self-assigned this Dec 12, 2019
@netomi
Copy link
Author

netomi commented Dec 12, 2019

The problem lies in the DuplicateInitializerFixer that is run after parameters have been removed.
The fixer checks if there are multiple constructors with the same descriptor, and fixes it by adding an additional parameter to one of these constructors. Unfortunately there is no precedence which constructor gets modified (if none is kept), the one that has been modified in the step before should be used to avoid such problems.

@netomi netomi added the bug Potential bug in ProGuard. label Dec 18, 2019
@netomi netomi removed their assignment Dec 30, 2019
@mrjameshamilton
Copy link
Collaborator

mrjameshamilton commented Mar 24, 2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Potential bug in ProGuard.
Projects
None yet
Development

No branches or pull requests

2 participants