Fix a bug where, in static synchronized methods that had no other uses
of registers (no locals, no parameters, no method calls with arguments),
v0 would be used both to hold the object being synchronized on and to hold
a caught exception.

The result was code that, if an exception was thrown through it, would
in turn throw an IllegalMonitorStateException, as the vm would be
asked to monitor-exit the exception object and not the monitor-entered
class.

Dx test 062 has a couple new cases to cover this case as well as the
parallel instance method case (not that the latter was problematic,
but I like the symmetry).
diff --git a/dx/src/com/android/dx/cf/code/Ropper.java b/dx/src/com/android/dx/cf/code/Ropper.java
index f2298e8..8217166 100644
--- a/dx/src/com/android/dx/cf/code/Ropper.java
+++ b/dx/src/com/android/dx/cf/code/Ropper.java
@@ -424,11 +424,14 @@
     private RegisterSpec getSynchReg() {
         /*
          * We use the register that is just past the deepest possible
-         * stack element. We don't need to do anything else special at
-         * this level, since later passes will merely notice the
-         * highest register used by explicit inspection.
+         * stack element, with a minimum of v1 since v0 is what's
+         * always used to hold the caught exception when unwinding. We
+         * don't need to do anything else special at this level, since
+         * later passes will merely notice the highest register used
+         * by explicit inspection.
          */
-        return RegisterSpec.make(getNormalRegCount(), Type.OBJECT);
+        int reg = getNormalRegCount();
+        return RegisterSpec.make((reg < 1) ? 1 : reg, Type.OBJECT);
     }
 
     /**
diff --git a/dx/tests/062-dex-synch-method/Blort.java b/dx/tests/062-dex-synch-method/Blort.java
index 643165d..823c2ca 100644
--- a/dx/tests/062-dex-synch-method/Blort.java
+++ b/dx/tests/062-dex-synch-method/Blort.java
@@ -40,6 +40,10 @@
         }
     }
 
+    public synchronized void testInstance5() {
+        testInstance5();
+    }
+
     public static synchronized void testStatic1() {
         // This space intentionally left blank.
     }
@@ -63,4 +67,8 @@
             return 2;
         }
     }
+
+    public static synchronized void testStatic5() {
+        testStatic5();
+    }
 }
diff --git a/dx/tests/062-dex-synch-method/expected.txt b/dx/tests/062-dex-synch-method/expected.txt
index 68bdebe..5585038 100644
--- a/dx/tests/062-dex-synch-method/expected.txt
+++ b/dx/tests/062-dex-synch-method/expected.txt
@@ -58,11 +58,27 @@
   0010: const-wide/16 v3, #long 2 // #0002
   0012: move-wide v0, v3
   0013: goto 000e // -0005
+Blort.testInstance5:()V:
+regs: 0004; ins: 0001; outs: 0001
+  0000: move-object v0, v3
+  0001: move-object v2, v3
+  0002: monitor-enter v2
+  0003: move-object v1, v0
+  0004: invoke-virtual {v1}, Blort.testInstance5:()V
+  0007: monitor-exit v2
+  0008: return-void
+  0009: move-exception v0
+  000a: monitor-exit v2
+  000b: throw v0
+  catches
+    tries:
+      try 0004..0007
+      catch <any> -> 0009
 Blort.testStatic1:()V:
-regs: 0001; ins: 0000; outs: 0000
-  0000: const-class v0, Blort
-  0002: monitor-enter v0
-  0003: monitor-exit v0
+regs: 0002; ins: 0000; outs: 0000
+  0000: const-class v1, Blort
+  0002: monitor-enter v1
+  0003: monitor-exit v1
   0004: return-void
 Blort.testStatic2:(Ljava/lang/Object;)V:
 regs: 0004; ins: 0001; outs: 0001
@@ -114,3 +130,17 @@
   0010: const-wide/16 v2, #long 2 // #0002
   0012: move-wide v0, v2
   0013: goto 000e // -0005
+Blort.testStatic5:()V:
+regs: 0002; ins: 0000; outs: 0000
+  0000: const-class v1, Blort
+  0002: monitor-enter v1
+  0003: invoke-static {}, Blort.testStatic5:()V
+  0006: monitor-exit v1
+  0007: return-void
+  0008: move-exception v0
+  0009: monitor-exit v1
+  000a: throw v0
+  catches
+    tries:
+      try 0003..0006
+      catch <any> -> 0008