Commits

Anonymous committed c7f2d5e

Fix inner class access flags and array modifiers.

Inner class access flags should come from the InnerClass attribute.

Array classes should all have the ACC_ABSTRACT modifier set.

Bug: https://code.google.com/p/android/issues/detail?id=56267
Change-Id: If4793ee6c7a6b24bf4d32ef05167d81b58011188

Comments (0)

Files changed (3)

tests/031-class-attributes/expected.txt

+public abstract final int
+public abstract final [I
+public java.lang.Object
+public abstract final [Ljava.lang.Object;
+public ClassAttrs$PublicInnerClass
+public abstract final [LClassAttrs$PublicInnerClass;
+protected ClassAttrs$ProtectedInnerClass
+protected abstract final [LClassAttrs$ProtectedInnerClass;
+private ClassAttrs$PrivateInnerClass
+private abstract final [LClassAttrs$PrivateInnerClass;
+ ClassAttrs$PackagePrivateInnerClass
+abstract final [LClassAttrs$PackagePrivateInnerClass;
 ***** class ClassAttrs:
   name: ClassAttrs
   canonical: ClassAttrs
   enclosingMeth: null
   modifiers: 1
   package: null
-  declaredClasses: [2] class ClassAttrs$PublicMemberClass, class ClassAttrs$MemberClass
-  member classes: [1] class ClassAttrs$PublicMemberClass
+  declaredClasses: [6] class ClassAttrs$PublicMemberClass, class ClassAttrs$MemberClass, class ClassAttrs$PackagePrivateInnerClass, class ClassAttrs$PrivateInnerClass, class ClassAttrs$ProtectedInnerClass, class ClassAttrs$PublicInnerClass
+  member classes: [3] class ClassAttrs$PublicMemberClass, class ClassAttrs$ProtectedInnerClass, class ClassAttrs$PublicInnerClass
   isAnnotation: false
   isAnonymous: false
   isArray: false

tests/031-class-attributes/src/ClassAttrs.java

 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
 import java.lang.reflect.Type;
 import java.lang.reflect.TypeVariable;
 
         cinner.showMe();
     }
 
+    public class PublicInnerClass {
+    }
+
+    protected class ProtectedInnerClass {
+    }
+
+    private class PrivateInnerClass {
+    }
+
+    class PackagePrivateInnerClass {
+    }
+
+    private static void showModifiers(Class<?> c) {
+        System.out.println(Modifier.toString(c.getModifiers()) + " " + c.getName());
+    }
+
+    // https://code.google.com/p/android/issues/detail?id=56267
+    private static void test56267() {
+        // Primitive classes.
+        showModifiers(int.class);
+        showModifiers(int[].class);
+
+        // Regular classes.
+        showModifiers(Object.class);
+        showModifiers(Object[].class);
+
+        // Inner classes.
+        showModifiers(PublicInnerClass.class);
+        showModifiers(PublicInnerClass[].class);
+        showModifiers(ProtectedInnerClass.class);
+        showModifiers(ProtectedInnerClass[].class);
+        showModifiers(PrivateInnerClass.class);
+        showModifiers(PrivateInnerClass[].class);
+        showModifiers(PackagePrivateInnerClass.class);
+        showModifiers(PackagePrivateInnerClass[].class);
+    }
+
     public static void main() {
+        test56267();
+
         printClassAttrs(ClassAttrs.class);
         printClassAttrs(OtherClass.class);
         printClassAttrs(OtherPackageClass.class);
 
     /*
      * Inherit access flags from the element.  Arrays can't be used as a
-     * superclass or interface, so we want to add "final" and remove
+     * superclass or interface, so we want to add "abstract final" and remove
      * "interface".
-     *
-     * Don't inherit any non-standard flags (e.g., CLASS_FINALIZABLE)
-     * from elementClass.  We assume that the array class does not
-     * override finalize().
      */
-    newClass->accessFlags = ((newClass->elementClass->accessFlags &
-                             ~ACC_INTERFACE) | ACC_FINAL) & JAVA_FLAGS_MASK;
+    int accessFlags = elementClass->accessFlags;
+    if (!gDvm.optimizing) {
+        // If the element class is an inner class, make sure we get the correct access flags.
+        StringObject* className = NULL;
+        dvmGetInnerClass(elementClass, &className, &accessFlags);
+        dvmReleaseTrackedAlloc((Object*) className, NULL);
+    }
+    accessFlags &= JAVA_FLAGS_MASK;
+    accessFlags &= ~ACC_INTERFACE;
+    accessFlags |= ACC_ABSTRACT | ACC_FINAL;
 
-    /* Set the flags we determined above.
-     * This must happen after accessFlags is set.
-     */
-    SET_CLASS_FLAG(newClass, extraFlags);
+    // Set the flags we determined above.
+    SET_CLASS_FLAG(newClass, accessFlags | extraFlags);
 
     if (!dvmAddClassToHash(newClass)) {
         /*
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.