diff options
author | 2013-06-14 15:04:14 -0700 | |
---|---|---|
committer | 2013-06-14 16:42:20 -0700 | |
commit | 00626c2e50ba085b95f860e941d0f41eb84d4ac9 (patch) | |
tree | a3643f7de76053f678565a78e2727cafb81b1564 | |
parent | d457d8a5542aacfb497790a0c648c7e34f1e4f69 (diff) |
Fix Class.getModifiers for array classes.
A separate libcore change is needed to fix Class.getModifiers for
arrays of inner classes.
Bug: https://code.google.com/p/android/issues/detail?id=56267
Change-Id: I3d95b266bb14a72b766921fe09e53fdef2f6d01b
-rw-r--r-- | src/class_linker.cc | 17 | ||||
-rw-r--r-- | src/class_linker_test.cc | 2 | ||||
-rw-r--r-- | test/031-class-attributes/expected.txt | 26 | ||||
-rw-r--r-- | test/031-class-attributes/src/ClassAttrs.java | 67 |
4 files changed, 102 insertions, 10 deletions
diff --git a/src/class_linker.cc b/src/class_linker.cc index 6e320656f8..93de3f5b1b 100644 --- a/src/class_linker.cc +++ b/src/class_linker.cc @@ -2021,15 +2021,16 @@ mirror::Class* ClassLinker::CreateArrayClass(const std::string& descriptor, CHECK(array_iftable_ != NULL); new_class->SetIfTable(array_iftable_); - // Inherit access flags from the component type. Arrays can't be - // used as a superclass or interface, so we want to add "final" + // Inherit access flags from the component type. + int access_flags = new_class->GetComponentType()->GetAccessFlags(); + // Lose any implementation detail flags; in particular, arrays aren't finalizable. + access_flags &= kAccJavaFlagsMask; + // Arrays can't be used as a superclass or interface, so we want to add "abstract final" // and remove "interface". - // - // Don't inherit any non-standard flags (e.g., kAccFinal) - // from component_type. We assume that the array class does not - // override finalize(). - new_class->SetAccessFlags(((new_class->GetComponentType()->GetAccessFlags() & - ~kAccInterface) | kAccFinal) & kAccJavaFlagsMask); + access_flags |= kAccAbstract | kAccFinal; + access_flags &= ~kAccInterface; + + new_class->SetAccessFlags(access_flags); mirror::Class* existing = InsertClass(descriptor, new_class.get(), false); if (existing == NULL) { diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc index 73bdc613ab..4540c01375 100644 --- a/src/class_linker_test.cc +++ b/src/class_linker_test.cc @@ -90,6 +90,7 @@ class ClassLinkerTest : public CommonTest { EXPECT_TRUE(primitive->GetVTable() == NULL); EXPECT_EQ(0, primitive->GetIfTableCount()); EXPECT_TRUE(primitive->GetIfTable() == NULL); + EXPECT_EQ(kAccPublic | kAccFinal | kAccAbstract, primitive->GetAccessFlags()); } void AssertArrayClass(const std::string& array_descriptor, @@ -100,6 +101,7 @@ class ClassLinkerTest : public CommonTest { ClassHelper array_component_ch(array->GetComponentType()); EXPECT_STREQ(component_type.c_str(), array_component_ch.GetDescriptor()); EXPECT_EQ(class_loader, array->GetClassLoader()); + EXPECT_EQ(kAccFinal | kAccAbstract, (array->GetAccessFlags() & (kAccFinal | kAccAbstract))); AssertArrayClass(array_descriptor, array); } diff --git a/test/031-class-attributes/expected.txt b/test/031-class-attributes/expected.txt index afa3416e21..4ae1eeda96 100644 --- a/test/031-class-attributes/expected.txt +++ b/test/031-class-attributes/expected.txt @@ -1,3 +1,25 @@ +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; +public abstract interface java.io.Serializable +public abstract final [Ljava.io.Serializable; +public abstract static interface ClassAttrs$PublicInnerInterface +public abstract final [LClassAttrs$PublicInnerInterface; +protected abstract static interface ClassAttrs$ProtectedInnerInterface +protected abstract final [LClassAttrs$ProtectedInnerInterface; +private abstract static interface ClassAttrs$PrivateInnerInterface +private abstract final [LClassAttrs$PrivateInnerInterface; +abstract static interface ClassAttrs$PackagePrivateInnerInterface +abstract final [LClassAttrs$PackagePrivateInnerInterface; ***** class ClassAttrs: name: ClassAttrs canonical: ClassAttrs @@ -11,8 +33,8 @@ enclosingMeth: null modifiers: 1 package: null - declaredClasses: [2] class ClassAttrs$PublicMemberClass, class ClassAttrs$MemberClass - member classes: [1] class ClassAttrs$PublicMemberClass + declaredClasses: [10] class ClassAttrs$PublicMemberClass, class ClassAttrs$MemberClass, interface ClassAttrs$PackagePrivateInnerInterface, interface ClassAttrs$PrivateInnerInterface, interface ClassAttrs$ProtectedInnerInterface, interface ClassAttrs$PublicInnerInterface, class ClassAttrs$PackagePrivateInnerClass, class ClassAttrs$PrivateInnerClass, class ClassAttrs$ProtectedInnerClass, class ClassAttrs$PublicInnerClass + member classes: [3] class ClassAttrs$PublicMemberClass, interface ClassAttrs$PublicInnerInterface, class ClassAttrs$PublicInnerClass isAnnotation: false isAnonymous: false isArray: false diff --git a/test/031-class-attributes/src/ClassAttrs.java b/test/031-class-attributes/src/ClassAttrs.java index 8719e3bd06..ae8b2f56da 100644 --- a/test/031-class-attributes/src/ClassAttrs.java +++ b/test/031-class-attributes/src/ClassAttrs.java @@ -1,10 +1,12 @@ import otherpackage.OtherPackageClass; +import java.io.Serializable; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Constructor; 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; @@ -21,7 +23,72 @@ public class ClassAttrs { cinner.showMe(); } + public class PublicInnerClass { + } + + protected class ProtectedInnerClass { + } + + private class PrivateInnerClass { + } + + class PackagePrivateInnerClass { + } + + public interface PublicInnerInterface { + } + + protected interface ProtectedInnerInterface { + } + + private interface PrivateInnerInterface { + } + + interface PackagePrivateInnerInterface { + } + + 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); + + // Regular interfaces. + showModifiers(Serializable.class); + showModifiers(Serializable[].class); + + // Inner interfaces. + showModifiers(PublicInnerInterface.class); + showModifiers(PublicInnerInterface[].class); + showModifiers(ProtectedInnerInterface.class); + showModifiers(ProtectedInnerInterface[].class); + showModifiers(PrivateInnerInterface.class); + showModifiers(PrivateInnerInterface[].class); + showModifiers(PackagePrivateInnerInterface.class); + showModifiers(PackagePrivateInnerInterface[].class); + } + public static void main() { + test56267(); + printClassAttrs(ClassAttrs.class); printClassAttrs(OtherClass.class); printClassAttrs(OtherPackageClass.class); |