Version 1.6.36

Cherry-pick: Ensure GenericSignatureRewriter is not modifying annotation sets
CL: https://r8-review.googlesource.com/c/r8/+/43909

Cherry-pick: Add assertion that ensures no hash change for CachedHashValueDexItem
CL: https://r8-review.googlesource.com/c/r8/+/43906

Cherry-pick: Fix AssertionRewriter to split the block and use precise types
CL: https://r8-review.googlesource.com/c/r8/+/43921

Bug: 139991218
Bug: 142064862
Change-Id: I0af24abc18066dce4d18ccee3335ee157d3c80c2
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index 455fad2..9cf1550 100644
--- a/src/main/java/com/android/tools/r8/Version.java
+++ b/src/main/java/com/android/tools/r8/Version.java
@@ -11,7 +11,7 @@
 
   // This field is accessed from release scripts using simple pattern matching.
   // Therefore, changing this field could break our release scripts.
-  public static final String LABEL = "1.6.35";
+  public static final String LABEL = "1.6.36";
 
   private Version() {
   }
diff --git a/src/main/java/com/android/tools/r8/graph/CachedHashValueDexItem.java b/src/main/java/com/android/tools/r8/graph/CachedHashValueDexItem.java
index 8f110d5..749ce04 100644
--- a/src/main/java/com/android/tools/r8/graph/CachedHashValueDexItem.java
+++ b/src/main/java/com/android/tools/r8/graph/CachedHashValueDexItem.java
@@ -26,6 +26,8 @@
       }
       hash = cache;
     }
+    assert cache == computeHashCode()
+        : "Hash code for " + this + " has changed from " + hash + " to " + computeHashCode();
     return cache;
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index fba5ae7..63540a2 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -3747,31 +3747,43 @@
       return;
     }
 
-    InstructionListIterator iterator = code.instructionListIterator();
-    while (iterator.hasNext()) {
-      Instruction current = iterator.next();
-      if (current.isInvokeMethod()) {
-        DexMethod invokedMethod = current.asInvokeMethod().getInvokedMethod();
-        if (invokedMethod == dexItemFactory.assertionErrorMethods.initMessageAndCause) {
-          // Rewrite calls to new AssertionError(message, cause) to new AssertionError(message)
-          // and then initCause(cause).
-          List<Value> inValues = current.inValues();
-          assert inValues.size() == 3; // receiver, message, cause
+    ListIterator<BasicBlock> blockIterator = code.listIterator();
+    while (blockIterator.hasNext()) {
+      BasicBlock block = blockIterator.next();
+      InstructionListIterator insnIterator = block.listIterator(code);
+      while (insnIterator.hasNext()) {
+        Instruction current = insnIterator.next();
+        if (current.isInvokeMethod()) {
+          DexMethod invokedMethod = current.asInvokeMethod().getInvokedMethod();
+          if (invokedMethod == dexItemFactory.assertionErrorMethods.initMessageAndCause) {
+            // Rewrite calls to new AssertionError(message, cause) to new AssertionError(message)
+            // and then initCause(cause).
+            List<Value> inValues = current.inValues();
+            assert inValues.size() == 3; // receiver, message, cause
 
-          // Remove cause from the constructor call
-          List<Value> newInitInValues = inValues.subList(0, 2);
-          iterator.replaceCurrentInstruction(
-              new InvokeDirect(dexItemFactory.assertionErrorMethods.initMessage, null,
-                  newInitInValues));
+            // Remove cause from the constructor call
+            List<Value> newInitInValues = inValues.subList(0, 2);
+            insnIterator.replaceCurrentInstruction(
+                new InvokeDirect(
+                    dexItemFactory.assertionErrorMethods.initMessage, null, newInitInValues));
 
-          // On API 15 and older we cannot use initCause because of a bug in AssertionError.
-          if (options.canInitCauseAfterAssertionErrorObjectConstructor()) {
-            // Add a call to Throwable.initCause(cause)
-            List<Value> initCauseArguments = Arrays.asList(inValues.get(0), inValues.get(2));
-            InvokeVirtual initCause = new InvokeVirtual(dexItemFactory.throwableMethods.initCause,
-                code.createValue(TypeLatticeElement.SINGLE), initCauseArguments);
-            initCause.setPosition(current.getPosition());
-            iterator.add(initCause);
+            // On API 15 and older we cannot use initCause because of a bug in AssertionError.
+            if (options.canInitCauseAfterAssertionErrorObjectConstructor()) {
+              // Add a call to Throwable.initCause(cause)
+              if (block.hasCatchHandlers()) {
+                insnIterator = insnIterator.split(code, blockIterator).listIterator(code);
+              }
+              List<Value> initCauseArguments = Arrays.asList(inValues.get(0), inValues.get(2));
+              InvokeVirtual initCause =
+                  new InvokeVirtual(
+                      dexItemFactory.throwableMethods.initCause,
+                      code.createValue(
+                          TypeLatticeElement.fromDexType(
+                              dexItemFactory.throwableType, Nullability.maybeNull(), appView)),
+                      initCauseArguments);
+              initCause.setPosition(current.getPosition());
+              insnIterator.add(initCause);
+            }
           }
         }
       }
diff --git a/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureRewriter.java b/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureRewriter.java
index 7b3caa7..c3b7188 100644
--- a/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureRewriter.java
+++ b/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureRewriter.java
@@ -85,24 +85,34 @@
     // There can be no more than one signature annotation in an annotation set.
     final int VALID = -1;
     int invalid = VALID;
+    DexAnnotation[] rewrittenAnnotations = null;
     for (int i = 0; i < annotations.annotations.length && invalid == VALID; i++) {
       DexAnnotation annotation = annotations.annotations[i];
       if (DexAnnotation.isSignatureAnnotation(annotation, appView.dexItemFactory())) {
+        if (rewrittenAnnotations == null) {
+          rewrittenAnnotations = new DexAnnotation[annotations.annotations.length];
+          System.arraycopy(annotations.annotations, 0, rewrittenAnnotations, 0, i);
+        }
         String signature = DexAnnotation.getSignature(annotation);
         try {
           parser.accept(signature);
-          annotations.annotations[i] =
+          DexAnnotation signatureAnnotation =
               DexAnnotation.createSignatureAnnotation(collector.get(), appView.dexItemFactory());
+          rewrittenAnnotations[i] = signatureAnnotation;
         } catch (GenericSignatureFormatError e) {
           parseError.accept(signature, e);
           invalid = i;
         }
+      } else if (rewrittenAnnotations != null) {
+        rewrittenAnnotations[i] = annotation;
       }
     }
 
     // Return the rewritten signatures if it was valid and could be rewritten.
     if (invalid == VALID) {
-      return annotations;
+      return rewrittenAnnotations != null
+          ? new DexAnnotationSet(rewrittenAnnotations)
+          : annotations;
     }
     // Remove invalid signature if found.
     DexAnnotation[] prunedAnnotations =