Report the correct instruction index in stack-map errors.
Fixes: b/282992444
Change-Id: I72892a3b3b5cc80e2923fe6204bdf0d6464d0b56
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 d56f09a..110e7ca 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
@@ -104,6 +104,7 @@
// Linear scan over instructions.
CfFrameState state = initialState.asContinue().getValue();
+ int actualInstructionIndexForReporting = 0;
for (int i = 0; i < code.getInstructions().size(); i++) {
CfInstruction instruction = code.getInstruction(i);
assert !state.isError();
@@ -120,7 +121,11 @@
if (state.isError()) {
return fail(
CfCodeStackMapValidatingException.invalidStackMapForInstruction(
- method, i, instruction, state.asError().getMessage(), appView));
+ method,
+ actualInstructionIndexForReporting,
+ instruction,
+ state.asError().getMessage(),
+ appView));
}
}
}
@@ -143,7 +148,8 @@
state = traversalContinuation.asContinue().getValue();
}
TraversalContinuation<CfCodeDiagnostics, CfFrameState> traversalContinuation =
- computeStateForNextInstruction(instruction, i, state, labelToFrameMap);
+ computeStateForNextInstruction(
+ instruction, i, actualInstructionIndexForReporting, state, labelToFrameMap);
if (traversalContinuation.isContinue()) {
state = traversalContinuation.asContinue().getValue();
} else {
@@ -152,12 +158,23 @@
if (state.isError()) {
return fail(
CfCodeStackMapValidatingException.invalidStackMapForInstruction(
- method, i, instruction, state.asError().getMessage(), appView));
+ method,
+ actualInstructionIndexForReporting,
+ instruction,
+ state.asError().getMessage(),
+ appView));
+ }
+ if (isActualCfInstruction(instruction)) {
+ ++actualInstructionIndexForReporting;
}
}
return StackMapStatus.VALID;
}
+ private static boolean isActualCfInstruction(CfInstruction instruction) {
+ return !instruction.isLabel() && !instruction.isFrame() && !instruction.isPosition();
+ }
+
private TraversalContinuation<CfCodeDiagnostics, Map<CfLabel, CfFrame>> buildLabelToFrameMap() {
Map<CfLabel, CfFrame> labelToFrameMap = new IdentityHashMap<>();
List<CfLabel> labels = new ArrayList<>();
@@ -319,6 +336,7 @@
private TraversalContinuation<CfCodeDiagnostics, CfFrameState> computeStateForNextInstruction(
CfInstruction instruction,
int instructionIndex,
+ int actualInstructionIndexForReporting,
CfFrameState state,
Map<CfLabel, CfFrame> labelToFrameMap) {
if (!instruction.isJump()) {
@@ -334,8 +352,7 @@
if (instruction.asJump().hasFallthrough()) {
return TraversalContinuation.doContinue(state);
}
- int nextInstructionIndex = instructionIndex + 1;
- CfInstruction nextInstruction = code.getInstruction(nextInstructionIndex);
+ CfInstruction nextInstruction = code.getInstruction(instructionIndex + 1);
CfFrame nextFrame = null;
if (nextInstruction.isFrame()) {
nextFrame = nextInstruction.asFrame();
@@ -352,7 +369,11 @@
}
return TraversalContinuation.doBreak(
CfCodeStackMapValidatingException.invalidStackMapForInstruction(
- method, nextInstructionIndex, nextInstruction, "Expected frame instruction", appView));
+ method,
+ actualInstructionIndexForReporting + 1,
+ nextInstruction,
+ "Expected frame instruction",
+ appView));
}
private boolean isFinalAndExitInstruction(CfInstruction instruction) {
diff --git a/src/main/java/com/android/tools/r8/graph/CfCodeStackMapValidatingException.java b/src/main/java/com/android/tools/r8/graph/CfCodeStackMapValidatingException.java
index cc3f47c..59788bc 100644
--- a/src/main/java/com/android/tools/r8/graph/CfCodeStackMapValidatingException.java
+++ b/src/main/java/com/android/tools/r8/graph/CfCodeStackMapValidatingException.java
@@ -70,7 +70,7 @@
String detailMessage,
AppView<?> appView) {
StringBuilder sb =
- new StringBuilder("Invalid stack map table at instruction ")
+ new StringBuilder("Invalid stack map table at instruction index ")
.append(instructionIndex)
.append(": ")
.append(instruction)