Don't crash when compiling java.lang.Object
MOE_MIGRATED_REVID=137196464
diff --git a/java/com/google/turbine/binder/HierarchyBinder.java b/java/com/google/turbine/binder/HierarchyBinder.java
index 91f10ab..386b051 100644
--- a/java/com/google/turbine/binder/HierarchyBinder.java
+++ b/java/com/google/turbine/binder/HierarchyBinder.java
@@ -115,8 +115,7 @@
case INTERFACE:
case ANNOTATION:
case CLASS:
- // TODO(b/31185757): this doesn't handle compiling Object
- superclass = ClassSymbol.OBJECT;
+ superclass = !owner.equals(ClassSymbol.OBJECT) ? ClassSymbol.OBJECT : null;
break;
default:
throw new AssertionError(decl.tykind());
diff --git a/java/com/google/turbine/bytecode/ClassWriter.java b/java/com/google/turbine/bytecode/ClassWriter.java
index ce2a16f..24b505c 100644
--- a/java/com/google/turbine/bytecode/ClassWriter.java
+++ b/java/com/google/turbine/bytecode/ClassWriter.java
@@ -41,7 +41,7 @@
ByteArrayDataOutput output = ByteStreams.newDataOutput();
output.writeShort(classfile.access());
output.writeShort(pool.classInfo(classfile.name()));
- output.writeShort(pool.classInfo(classfile.superName()));
+ output.writeShort(classfile.superName() != null ? pool.classInfo(classfile.superName()) : 0);
output.writeShort(classfile.interfaces().size());
for (String i : classfile.interfaces()) {
output.writeShort(pool.classInfo(i));
diff --git a/java/com/google/turbine/bytecode/ConstantPool.java b/java/com/google/turbine/bytecode/ConstantPool.java
index e46cd70..cbe5a03 100644
--- a/java/com/google/turbine/bytecode/ConstantPool.java
+++ b/java/com/google/turbine/bytecode/ConstantPool.java
@@ -25,6 +25,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
/** A constant pool builder, used when writing class files. */
public class ConstantPool {
@@ -89,6 +90,7 @@
/** Adds a CONSTANT_Class_info entry to the pool. */
short classInfo(String value) {
+ Objects.requireNonNull(value);
short utf8 = utf8(value);
if (classInfoPool.containsKey(utf8)) {
return classInfoPool.get(utf8);
@@ -100,6 +102,7 @@
/** Adds a CONSTANT_Utf8_info entry to the pool. */
short utf8(String value) {
+ Objects.requireNonNull(value);
if (utf8Pool.containsKey(value)) {
return utf8Pool.get(value);
}
@@ -145,6 +148,7 @@
}
short string(String value) {
+ Objects.requireNonNull(value);
short utf8 = utf8(value);
if (stringPool.containsKey(utf8)) {
return stringPool.get(utf8);
diff --git a/java/com/google/turbine/lower/Lower.java b/java/com/google/turbine/lower/Lower.java
index d157b57..194484f 100644
--- a/java/com/google/turbine/lower/Lower.java
+++ b/java/com/google/turbine/lower/Lower.java
@@ -108,7 +108,7 @@
int access = classAccess(info);
String name = sig.descriptor(sym);
String signature = sig.classSignature(info);
- String superName = sig.descriptor(info.superclass());
+ String superName = info.superclass() != null ? sig.descriptor(info.superclass()) : null;
List<String> interfaces = new ArrayList<>();
for (ClassSymbol i : info.interfaces()) {
interfaces.add(sig.descriptor(i));
diff --git a/javatests/com/google/turbine/lower/LowerIntegrationTest.java b/javatests/com/google/turbine/lower/LowerIntegrationTest.java
index 7f07318..fd1acb8 100644
--- a/javatests/com/google/turbine/lower/LowerIntegrationTest.java
+++ b/javatests/com/google/turbine/lower/LowerIntegrationTest.java
@@ -233,6 +233,7 @@
// TODO(cushon): crashes ASM, see:
// http://forge.ow2.org/tracker/?func=detail&aid=317776&group_id=23&atid=100023
// "canon_array.test",
+ "java_lang_object.test",
};
List<Object[]> tests =
ImmutableList.copyOf(testCases).stream().map(x -> new Object[] {x}).collect(toList());
diff --git a/javatests/com/google/turbine/lower/testdata/java_lang_object.test b/javatests/com/google/turbine/lower/testdata/java_lang_object.test
new file mode 100644
index 0000000..27d7d81
--- /dev/null
+++ b/javatests/com/google/turbine/lower/testdata/java_lang_object.test
@@ -0,0 +1,36 @@
+=== Object.java ===
+package java.lang;
+public class Object {
+public Object() {}
+ public final Class<?> getClass() {
+ return null;
+ }
+
+ public int hashCode() {
+ return -1;
+ }
+
+ public boolean equals(Object o) {
+ return false;
+ }
+
+ protected Object clone() throws CloneNotSupportedException {
+ return null;
+ }
+
+ public String toString() {
+ return "";
+ }
+
+ protected void finalize() throws Throwable {}
+
+ public final void notify() {}
+
+ public final void notifyAll() {}
+
+ public final void wait(long timeout) throws InterruptedException {}
+
+ public final void wait(long timeout, int nanos) throws InterruptedException {}
+
+ public final void wait() throws InterruptedException {}
+}