Determine addition of ACC_SUPER at write time.
Change-Id: I8c897b48b684e764adcaff4a5aef30bb619078c5
diff --git a/src/main/java/com/android/tools/r8/graph/ClassAccessFlags.java b/src/main/java/com/android/tools/r8/graph/ClassAccessFlags.java
index 4dcc108..36f43ba 100644
--- a/src/main/java/com/android/tools/r8/graph/ClassAccessFlags.java
+++ b/src/main/java/com/android/tools/r8/graph/ClassAccessFlags.java
@@ -64,8 +64,7 @@
}
public static ClassAccessFlags fromDexAccessFlags(int access) {
- // Assume that the SUPER flag should be set (behaviour for Java versions > 1.1).
- return new ClassAccessFlags((access & DEX_FLAGS) | Constants.ACC_SUPER);
+ return new ClassAccessFlags(access & DEX_FLAGS);
}
public static ClassAccessFlags fromCfAccessFlags(int access) {
@@ -84,6 +83,10 @@
@Override
public int getAsCfAccessFlags() {
+ assert !isInterface() || isAbstract();
+ assert !isInterface() || !isSuper();
+ assert !isInterface() || !isFinal();
+ assert !isInterface() || !isEnum();
return materialize();
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/JStyleLambdaGroupIdFactory.java b/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/JStyleLambdaGroupIdFactory.java
index e9ab954..349f3d7 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/JStyleLambdaGroupIdFactory.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/JStyleLambdaGroupIdFactory.java
@@ -5,6 +5,7 @@
package com.android.tools.r8.ir.optimize.lambda.kotlin;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.ClassAccessFlags;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexType;
@@ -27,8 +28,9 @@
assert lambda.getKotlinInfo().isSyntheticClass();
assert lambda.getKotlinInfo().asSyntheticClass().isJavaStyleLambda();
- checkAccessFlags("class access flags", lambda.accessFlags,
- PUBLIC_LAMBDA_CLASS_FLAGS, LAMBDA_CLASS_FLAGS);
+ ClassAccessFlags copy = lambda.accessFlags.copy();
+ copy.unsetSuper();
+ checkAccessFlags("class access flags", copy, PUBLIC_LAMBDA_CLASS_FLAGS, LAMBDA_CLASS_FLAGS);
// Class and interface.
validateSuperclass(kotlin, lambda);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KStyleLambdaGroupIdFactory.java b/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KStyleLambdaGroupIdFactory.java
index 495ab0b..6f7650b 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KStyleLambdaGroupIdFactory.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KStyleLambdaGroupIdFactory.java
@@ -5,6 +5,7 @@
package com.android.tools.r8.ir.optimize.lambda.kotlin;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.ClassAccessFlags;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexType;
@@ -27,8 +28,10 @@
assert lambda.getKotlinInfo().isSyntheticClass();
assert lambda.getKotlinInfo().asSyntheticClass().isKotlinStyleLambda();
- checkAccessFlags("class access flags", lambda.accessFlags,
- PUBLIC_LAMBDA_CLASS_FLAGS, LAMBDA_CLASS_FLAGS);
+ // Ignore ACC_SUPER.
+ ClassAccessFlags copy = lambda.accessFlags.copy();
+ copy.unsetSuper();
+ checkAccessFlags("class access flags", copy, PUBLIC_LAMBDA_CLASS_FLAGS, LAMBDA_CLASS_FLAGS);
// Class and interface.
validateSuperclass(kotlin, lambda);
diff --git a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
index e13331f..9ccc19c 100644
--- a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
@@ -163,6 +163,15 @@
String sourceDebug = getSourceDebugExtension(clazz.annotations());
writer.visitSource(clazz.sourceFile != null ? clazz.sourceFile.toString() : null, sourceDebug);
int version = getClassFileVersion(clazz);
+ if (version >= V1_8) {
+ // JDK8 and after ignore ACC_SUPER so unset it.
+ clazz.accessFlags.unsetSuper();
+ } else {
+ // In all other cases set the super bit as D8/R8 do not support targeting pre 1.0.2 JDKs.
+ if (!clazz.accessFlags.isInterface()) {
+ clazz.accessFlags.setSuper();
+ }
+ }
int access = clazz.accessFlags.getAsCfAccessFlags();
String desc = namingLens.lookupDescriptor(clazz.type).toString();
String name = namingLens.lookupInternalName(clazz.type);
diff --git a/src/test/java/com/android/tools/r8/jasmin/JasminBuilder.java b/src/test/java/com/android/tools/r8/jasmin/JasminBuilder.java
index 74d62e0..f06d96d 100644
--- a/src/test/java/com/android/tools/r8/jasmin/JasminBuilder.java
+++ b/src/test/java/com/android/tools/r8/jasmin/JasminBuilder.java
@@ -8,12 +8,14 @@
import com.android.tools.r8.ByteDataView;
import com.android.tools.r8.ClassFileConsumer;
import com.android.tools.r8.DiagnosticsHandler;
+import com.android.tools.r8.TestBase;
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.naming.MemberNaming.FieldSignature;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.origin.PathOrigin;
+import com.android.tools.r8.references.Reference;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.InternalOptions;
@@ -453,7 +455,15 @@
file.readJasmin(new StringReader(builder.toString()), builder.name, false);
ByteArrayOutputStream out = new ByteArrayOutputStream();
file.write(out);
- return out.toByteArray();
+ // Jasmin incorrectly sets super on interfaces: https://sourceforge.net/p/jasmin/bugs/5/
+ return TestBase.transformer(out.toByteArray(), Reference.classFromTypeName(file.getClassName()))
+ .setAccessFlags(
+ flags -> {
+ if (flags.isInterface()) {
+ flags.unsetSuper();
+ }
+ })
+ .transform();
}
public ImmutableList.Builder<byte[]> buildClasses(ImmutableList.Builder<byte[]> builder)