Account for moved instance initializers when building CfFrames
Change-Id: I8c76044ab0f736da8c6a89d7908145bd40d00b45
diff --git a/src/main/java/com/android/tools/r8/cf/TypeVerificationHelper.java b/src/main/java/com/android/tools/r8/cf/TypeVerificationHelper.java
index 90fc9ee..db785cc 100644
--- a/src/main/java/com/android/tools/r8/cf/TypeVerificationHelper.java
+++ b/src/main/java/com/android/tools/r8/cf/TypeVerificationHelper.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeElement;
@@ -234,16 +235,15 @@
if (!instruction.isArgument()) {
break;
}
+ DexMethod reference = code.context().getReference();
TypeInfo argumentType;
if (argumentIndex < 0) {
argumentType =
- code.method().isInstanceInitializer()
- ? new ThisInstanceInfo(instruction.asArgument(), code.method().getHolderType())
- : createInitializedType(code.method().getHolderType());
+ reference.isInstanceInitializerInlineIntoOrMerged(appView)
+ ? new ThisInstanceInfo(instruction.asArgument(), reference.getHolderType())
+ : createInitializedType(reference.getHolderType());
} else {
- argumentType =
- createInitializedType(
- code.method().getReference().proto.parameters.values[argumentIndex]);
+ argumentType = createInitializedType(reference.proto.parameters.values[argumentIndex]);
}
Value outValue = instruction.outValue();
if (outValue.outType().isObject()) {
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfFrameVerifier.java b/src/main/java/com/android/tools/r8/cf/code/CfFrameVerifier.java
index 09cabd8..44f3fde 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfFrameVerifier.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfFrameVerifier.java
@@ -293,9 +293,7 @@
state =
state.storeLocal(
localIndex,
- context.isInstanceInitializer(dexItemFactory)
- || context.mustBeInlinedIntoInstanceInitializer(appView)
- || context.isHorizontallyMergedInstanceInitializer(dexItemFactory)
+ context.isInstanceInitializerInlineIntoOrMerged(appView)
? FrameType.uninitializedThis()
: FrameType.initializedNonNullReference(context.getHolderType()),
config);
diff --git a/src/main/java/com/android/tools/r8/graph/DexMethod.java b/src/main/java/com/android/tools/r8/graph/DexMethod.java
index 2fbdbdc..fe2f81d 100644
--- a/src/main/java/com/android/tools/r8/graph/DexMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexMethod.java
@@ -317,6 +317,12 @@
return getName().startsWith(dexItemFactory.syntheticConstructorMethodPrefix);
}
+ public boolean isInstanceInitializerInlineIntoOrMerged(AppView<?> appView) {
+ return isInstanceInitializer(appView.dexItemFactory())
+ || mustBeInlinedIntoInstanceInitializer(appView)
+ || isHorizontallyMergedInstanceInitializer(appView.dexItemFactory());
+ }
+
public DexMethod withExtraArgumentPrepended(DexType type, DexItemFactory dexItemFactory) {
return dexItemFactory.createMethod(
holder, dexItemFactory.prependTypeToProto(type, proto), name);
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
index a62fd2f..23e1ab3 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
@@ -199,7 +199,7 @@
}
private Set<UninitializedThisLocalRead> insertUninitializedThisLocalReads() {
- if (!method.getDefinition().isInstanceInitializer()) {
+ if (!method.getReference().isInstanceInitializerInlineIntoOrMerged(appView)) {
return Collections.emptySet();
}
// Find all non-normal exit blocks.
@@ -246,11 +246,13 @@
assert initializers == null;
assert thisInitializers == null;
initializers = new HashMap<>();
+ boolean isInstanceInitializer =
+ method.getReference().isInstanceInitializerInlineIntoOrMerged(appView);
for (BasicBlock block : code.blocks) {
for (Instruction insn : block.getInstructions()) {
if (insn.isNewInstance()) {
initializers.put(insn.asNewInstance(), computeInitializers(insn.outValue()));
- } else if (insn.isArgument() && method.getDefinition().isInstanceInitializer()) {
+ } else if (insn.isArgument() && isInstanceInitializer) {
if (insn.outValue().isThis()) {
// By JVM8 §4.10.1.9 (invokespecial), a this() or super() call in a constructor
// changes the type of `this` from uninitializedThis
@@ -260,7 +262,7 @@
}
}
}
- assert !(method.getDefinition().isInstanceInitializer() && thisInitializers == null);
+ assert !(isInstanceInitializer && thisInitializers == null);
}
private List<InvokeDirect> computeInitializers(Value value) {