Status Update
Comments
yb...@google.com <yb...@google.com>
da...@google.com <da...@google.com> #2
Could you look into it @christofferqa?
The issue is with this class:
class MySpi : Spi {
@Volatile
private var myApi: Api? = null
// Incorrectly rewritten to return null;
override fun createApi(): Api {
return myApi ?: synchronized(this) {
myApi ?: MyApi().also { myApi = it }
}
}
}
The error seems to be that the ArgumentPropagator believes that the fieldState of myApi is ExactDynamicType(@NotNull MyApi)
while it should be ExactDynamicType(@Nullable MyApi)
It then removes the first branch (assuming myApi is not null):
return myApi ?: synchronized(this) {
myApi ?: MyApi().also { myApi = it }
}
is rewritten into:
return myApi
And then it eventually concludes that myApi is always null, replacing the code by
return null
The ArgumentPropagatorCodeScanner analyzes the assignment myApi = it
and correctly set join the state to ExactDynamicType(@NotNull MyApi)
However the ArgumentPropagator fails to understand that myApi
can be read before being written in the method, relying on the default null value, so it fails to join null
to the dynamic type.
he...@gmail.com <he...@gmail.com> #3
Yes I can take a look. Would it be possible for you to add a regression test of this issue?
Description
Version used:1.1.1
Devices/Android versions reproduced on: All
File: FrameworkSQLiteOpenHelper
FrameworkSQLiteDatabase getWrappedDb(SQLiteDatabase sqLiteDatabase) {
FrameworkSQLiteDatabase dbRef = mDbRef[0];
if (dbRef == null) {
dbRef = new FrameworkSQLiteDatabase(sqLiteDatabase);
mDbRef[0] = dbRef;
}
return mDbRef[0];
}
Room always preserve The First Open db, even if it is closed.
Sometimes sqLiteDatabase != mDbRef[0].mDelegate, we get the wrong db from room.
This occurs when opening db, then something wrong and throws exception, but app caught it. The next time we use room, it throws re-open exception.
I thinks mDbRef[0].mDelegate should change when sqLiteDatabase is changed.
Like this:
FrameworkSQLiteDatabase getWrappedDb(SQLiteDatabase sqLiteDatabase) {
FrameworkSQLiteDatabase dbRef = mDbRef[0];
if (dbRef == null || dbRef.isDatabaseChanged(sqLiteDatabase)) {
dbRef = new FrameworkSQLiteDatabase(sqLiteDatabase);
mDbRef[0] = dbRef;
}
return mDbRef[0];
}
File: FrameworkSQLiteDatabase
public boolean isDatabaseChanged(SQLiteDatabase db) {
return mDelegate != db;
}