diff options
| author | 2022-07-04 16:24:06 +0000 | |
|---|---|---|
| committer | 2022-07-13 14:44:05 +0000 | |
| commit | ef0b9c465a24f1ff1c3442c9ae45ae0e0456e09e (patch) | |
| tree | 230a0ec53d7f0cb29ee3d1a5f556d65401053f74 | |
| parent | 26aef1213dbdd7ab03688d898cf802c8c8d7e610 (diff) | |
Reland "Adjust how we assign vtable indexes during class loading."
This reverts commit 07c2fec6b025d5cc104ab4f210c3941528f56fd6.
Bug: 211854716
Bug: 233545487
Bug: 181943478
Reason for revert: addressed comments
Change-Id: Id45c8e826b81f00190920a2b3270937614700f5f
| -rw-r--r-- | runtime/class_linker.cc | 253 | ||||
| -rw-r--r-- | runtime/mirror/array-inl.h | 2 | ||||
| -rw-r--r-- | test/838-override/expected-stderr.txt | 0 | ||||
| -rw-r--r-- | test/838-override/expected-stdout.txt | 0 | ||||
| -rw-r--r-- | test/838-override/info.txt | 1 | ||||
| -rw-r--r-- | test/838-override/src/Main.java | 99 | ||||
| -rw-r--r-- | test/838-override/src/pkg1/InterfaceFoo.java | 21 | ||||
| -rw-r--r-- | test/838-override/src/pkg1/LowerIndexImplementsFoo.java | 20 | ||||
| -rw-r--r-- | test/838-override/src/pkg1/LowerIndexPublicFoo.java | 23 | ||||
| -rw-r--r-- | test/838-override/src/pkg1/Pkg1Foo.java | 28 | ||||
| -rw-r--r-- | test/838-override/src/pkg1/PublicFoo.java | 23 | ||||
| -rw-r--r-- | test/838-override/src/pkg1/PublicFooInheritsPkg2.java | 23 | ||||
| -rw-r--r-- | test/838-override/src/pkg2/Pkg2Foo.java | 27 | ||||
| -rw-r--r-- | test/838-override/src/pkg2/PublicFoo.java | 23 | ||||
| -rw-r--r-- | test/838-override/src/pkg2/PublicFooInheritsPkg3.java | 23 | ||||
| -rw-r--r-- | test/838-override/src/pkg3/Pkg3Foo.java | 27 | ||||
| -rw-r--r-- | test/838-override/src/pkg3/PublicFoo.java | 23 |
17 files changed, 488 insertions, 128 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index c2ce3e2eb8..fd721cd732 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -37,6 +37,7 @@ #include "art_method-inl.h" #include "barrier.h" #include "base/arena_allocator.h" +#include "base/arena_bit_vector.h" #include "base/casts.h" #include "base/file_utils.h" #include "base/hash_map.h" @@ -7945,55 +7946,17 @@ size_t ClassLinker::LinkMethodsHelper<kPointerSize>::AssignVTableIndexes( static constexpr double kMinLoadFactor = 0.3; static constexpr double kMaxLoadFactor = 0.5; static constexpr size_t kMaxStackBuferSize = 256; - const size_t super_vtable_buffer_size = super_vtable_length * 3; const size_t declared_virtuals_buffer_size = num_virtual_methods * 3; - const size_t total_buffer_size = super_vtable_buffer_size + declared_virtuals_buffer_size; - uint32_t* super_vtable_buffer_ptr = (total_buffer_size <= kMaxStackBuferSize) - ? reinterpret_cast<uint32_t*>(alloca(total_buffer_size * sizeof(uint32_t))) - : allocator_.AllocArray<uint32_t>(total_buffer_size); - uint32_t* declared_virtuals_buffer_ptr = super_vtable_buffer_ptr + super_vtable_buffer_size; - VTableSignatureSet super_vtable_signatures( - kMinLoadFactor, - kMaxLoadFactor, - VTableSignatureHash(super_vtable_accessor), - VTableSignatureEqual(super_vtable_accessor), - super_vtable_buffer_ptr, - super_vtable_buffer_size, - allocator_.Adapter()); - ArrayRef<uint32_t> same_signature_vtable_lists; - // Insert the first `mirror::Object::kVTableLength` indexes with pre-calculated hashes. - DCHECK_GE(super_vtable_length, mirror::Object::kVTableLength); - for (uint32_t i = 0; i != mirror::Object::kVTableLength; ++i) { - size_t hash = class_linker_->object_virtual_method_hashes_[i]; - // There are no duplicate signatures in `java.lang.Object`, so use `HashSet<>::PutWithHash()`. - // This avoids equality comparison for the three `java.lang.Object.wait()` overloads. - super_vtable_signatures.PutWithHash(i, hash); - } - // Insert the remaining indexes, check for duplicate signatures. - if (super_vtable_length > mirror::Object::kVTableLength) { - for (size_t i = mirror::Object::kVTableLength; i < super_vtable_length; ++i) { - // Use `super_vtable_accessor` for getting the method for hash calculation. - // Letting `HashSet<>::insert()` use the internal accessor copy in the hash - // function prevents the compiler from optimizing this properly because the - // compiler cannot prove that the accessor copy is immutable. - size_t hash = ComputeMethodHash(super_vtable_accessor.GetVTableEntry(i)); - auto [it, inserted] = super_vtable_signatures.InsertWithHash(i, hash); - if (UNLIKELY(!inserted)) { - if (same_signature_vtable_lists.empty()) { - same_signature_vtable_lists = ArrayRef<uint32_t>( - allocator_.AllocArray<uint32_t>(super_vtable_length), super_vtable_length); - std::fill_n(same_signature_vtable_lists.data(), super_vtable_length, dex::kDexNoIndex); - same_signature_vtable_lists_ = same_signature_vtable_lists; - } - DCHECK_LT(*it, i); - same_signature_vtable_lists[i] = *it; - *it = i; - } - } - } + const size_t super_vtable_buffer_size = super_vtable_length * 3; + const size_t bit_vector_size = BitVector::BitsToWords(num_virtual_methods); + const size_t total_size = + declared_virtuals_buffer_size + super_vtable_buffer_size + bit_vector_size; + + uint32_t* declared_virtuals_buffer_ptr = (total_size <= kMaxStackBuferSize) + ? reinterpret_cast<uint32_t*>(alloca(total_size * sizeof(uint32_t))) + : allocator_.AllocArray<uint32_t>(total_size); + uint32_t* bit_vector_buffer_ptr = declared_virtuals_buffer_ptr + declared_virtuals_buffer_size; - // For each declared virtual method, look for a superclass virtual method - // to override and assign a new vtable index if no method was overridden. DeclaredVirtualSignatureSet declared_virtual_signatures( kMinLoadFactor, kMaxLoadFactor, @@ -8002,8 +7965,24 @@ size_t ClassLinker::LinkMethodsHelper<kPointerSize>::AssignVTableIndexes( declared_virtuals_buffer_ptr, declared_virtuals_buffer_size, allocator_.Adapter()); + + ArrayRef<uint32_t> same_signature_vtable_lists; const bool is_proxy_class = klass->IsProxyClass(); size_t vtable_length = super_vtable_length; + + // Record which declared methods are overriding a super method. + BitVector initialized_methods(/* expandable= */ false, + Allocator::GetNoopAllocator(), + bit_vector_size, + bit_vector_buffer_ptr); + + // Note: our sets hash on the method name, and therefore we pay a high + // performance price when a class has many overloads. + // + // We populate a set of declared signatures instead of signatures from the + // super vtable (which is only lazy populated in case of interface overriding, + // see below). This makes sure that we pay the performance price only on that + // class, and not on its subclasses (except in the case of interface overriding, see below). for (size_t i = 0; i != num_virtual_methods; ++i) { ArtMethod* virtual_method = klass->GetVirtualMethodDuringLinking(i, kPointerSize); DCHECK(!virtual_method->IsStatic()) << virtual_method->PrettyMethod(); @@ -8012,59 +7991,79 @@ size_t ClassLinker::LinkMethodsHelper<kPointerSize>::AssignVTableIndexes( : virtual_method; size_t hash = ComputeMethodHash(signature_method); declared_virtual_signatures.PutWithHash(i, hash); - auto it = super_vtable_signatures.FindWithHash(signature_method, hash); - if (it != super_vtable_signatures.end()) { - size_t super_index = *it; - DCHECK_LT(super_index, super_vtable_length); - ArtMethod* super_method = super_vtable_accessor.GetVTableEntry(super_index); - // Historical note: Before Android 4.1, an inaccessible package-private - // superclass method would have been incorrectly overridden. - bool overrides = klass->CanAccessMember(super_method->GetDeclaringClass(), - super_method->GetAccessFlags()); - if (overrides && super_method->IsFinal()) { - sants.reset(); - ThrowLinkageError(klass, "Method %s overrides final method in class %s", - virtual_method->PrettyMethod().c_str(), - super_method->GetDeclaringClassDescriptor()); - return 0u; - } - if (UNLIKELY(!same_signature_vtable_lists.empty())) { - // We may override more than one method according to JLS, see b/211854716 . - // We record the highest overridden vtable index here so that we can walk - // the list to find other overridden methods when constructing the vtable. - // However, we walk all the methods to check for final method overriding. - size_t current_index = super_index; - while (same_signature_vtable_lists[current_index] != dex::kDexNoIndex) { - DCHECK_LT(same_signature_vtable_lists[current_index], current_index); - current_index = same_signature_vtable_lists[current_index]; - ArtMethod* current_method = super_vtable_accessor.GetVTableEntry(current_index); - if (klass->CanAccessMember(current_method->GetDeclaringClass(), - current_method->GetAccessFlags())) { - if (current_method->IsFinal()) { - sants.reset(); - ThrowLinkageError(klass, "Method %s overrides final method in class %s", - virtual_method->PrettyMethod().c_str(), - current_method->GetDeclaringClassDescriptor()); - return 0u; - } - if (!overrides) { - overrides = true; - super_index = current_index; - super_method = current_method; - } - } - } - } - if (overrides) { - virtual_method->SetMethodIndex(super_index); - continue; - } + } + + // Loop through each super vtable method and see if they are overridden by a method we added to + // the hash table. + for (size_t j = 0; j < super_vtable_length; ++j) { + // Search the hash table to see if we are overridden by any method. + ArtMethod* super_method = super_vtable_accessor.GetVTableEntry(j); + if (!klass->CanAccessMember(super_method->GetDeclaringClass(), + super_method->GetAccessFlags())) { + // Continue on to the next method since this one is package private and cannot be overridden. + // Before Android 4.1, the package-private method super_method might have been incorrectly + // overridden. + continue; + } + size_t hash = (j < mirror::Object::kVTableLength) + ? class_linker_->object_virtual_method_hashes_[j] + : ComputeMethodHash(super_method); + auto it = declared_virtual_signatures.FindWithHash(super_method, hash); + if (it == declared_virtual_signatures.end()) { + continue; + } + ArtMethod* virtual_method = klass->GetVirtualMethodDuringLinking(*it, kPointerSize); + if (super_method->IsFinal()) { + sants.reset(); + ThrowLinkageError(klass, "Method %s overrides final method in class %s", + virtual_method->PrettyMethod().c_str(), + super_method->GetDeclaringClassDescriptor()); + return 0u; + } + if (initialized_methods.IsBitSet(*it)) { + // The method is overriding more than one method. + // We record that information in a linked list to later set the method in the vtable + // locations that are not the method index. + if (same_signature_vtable_lists.empty()) { + same_signature_vtable_lists = ArrayRef<uint32_t>( + allocator_.AllocArray<uint32_t>(super_vtable_length), super_vtable_length); + std::fill_n(same_signature_vtable_lists.data(), super_vtable_length, dex::kDexNoIndex); + same_signature_vtable_lists_ = same_signature_vtable_lists; + } + same_signature_vtable_lists[j] = virtual_method->GetMethodIndexDuringLinking(); + } else { + initialized_methods.SetBit(*it); } - // The method does not override any method from superclass, so it needs a new vtable index. - virtual_method->SetMethodIndex(vtable_length); - ++vtable_length; + + // We arbitrarily set to the largest index. This is also expected when + // iterating over the `same_signature_vtable_lists_`. + virtual_method->SetMethodIndex(j); } + // Add the non-overridden methods at the end. + for (size_t i = 0; i < num_virtual_methods; ++i) { + if (!initialized_methods.IsBitSet(i)) { + ArtMethod* local_method = klass->GetVirtualMethodDuringLinking(i, kPointerSize); + local_method->SetMethodIndex(vtable_length); + vtable_length++; + } + } + + // A lazily constructed super vtable set, which we only populate in the less + // common sittuation of a superclass implementing a method declared in an + // interface this class inherits. + // We still try to allocate the set on the stack as using the arena will have + // a larger cost. + uint32_t* super_vtable_buffer_ptr = bit_vector_buffer_ptr + bit_vector_size; + VTableSignatureSet super_vtable_signatures( + kMinLoadFactor, + kMaxLoadFactor, + VTableSignatureHash(super_vtable_accessor), + VTableSignatureEqual(super_vtable_accessor), + super_vtable_buffer_ptr, + super_vtable_buffer_size, + allocator_.Adapter()); + // Assign vtable indexes for interface methods in new interfaces and store them // in implementation method arrays. These shall be replaced by actual method // pointers later. We do not need to do this for superclass interfaces as we can @@ -8083,38 +8082,39 @@ size_t ClassLinker::LinkMethodsHelper<kPointerSize>::AssignVTableIndexes( ArtMethod* interface_method = iface->GetVirtualMethod(j, kPointerSize); size_t hash = ComputeMethodHash(interface_method); ArtMethod* vtable_method = nullptr; - bool found = false; auto it1 = declared_virtual_signatures.FindWithHash(interface_method, hash); if (it1 != declared_virtual_signatures.end()) { - vtable_method = klass->GetVirtualMethodDuringLinking(*it1, kPointerSize); - found = true; + ArtMethod* found_method = klass->GetVirtualMethodDuringLinking(*it1, kPointerSize); + // For interface overriding, we only look at public methods. + if (found_method->IsPublic()) { + vtable_method = found_method; + } } else { + // This situation should be rare (a superclass implements a method + // declared in an interface this class is inheriting). Only in this case + // do we lazily populate the super_vtable_signatures. + if (super_vtable_signatures.empty()) { + for (size_t k = 0; k < super_vtable_length; ++k) { + ArtMethod* super_method = super_vtable_accessor.GetVTableEntry(k); + if (!super_method->IsPublic()) { + // For interface overriding, we only look at public methods. + continue; + } + size_t super_hash = (k < mirror::Object::kVTableLength) + ? class_linker_->object_virtual_method_hashes_[k] + : ComputeMethodHash(super_method); + auto [it, inserted] = super_vtable_signatures.InsertWithHash(k, super_hash); + DCHECK(inserted || super_vtable_accessor.GetVTableEntry(*it) == super_method); + } + } auto it2 = super_vtable_signatures.FindWithHash(interface_method, hash); if (it2 != super_vtable_signatures.end()) { - // If there are multiple vtable methods with the same signature, the one with - // the highest vtable index is not nessarily the one in most-derived class. - // Find the most-derived method. See b/211854716 . vtable_method = super_vtable_accessor.GetVTableEntry(*it2); - if (UNLIKELY(!same_signature_vtable_lists.empty())) { - size_t current_index = *it2; - while (same_signature_vtable_lists[current_index] != dex::kDexNoIndex) { - DCHECK_LT(same_signature_vtable_lists[current_index], current_index); - current_index = same_signature_vtable_lists[current_index]; - ArtMethod* current_method = super_vtable_accessor.GetVTableEntry(current_index); - ObjPtr<mirror::Class> current_class = current_method->GetDeclaringClass(); - if (current_class->IsSubClass(vtable_method->GetDeclaringClass())) { - vtable_method = current_method; - } - } - } - found = true; } } - found = found && vtable_method->IsPublic(); uint32_t vtable_index = vtable_length; - if (found) { - DCHECK(vtable_method != nullptr); + if (vtable_method != nullptr) { vtable_index = vtable_method->GetMethodIndexDuringLinking(); if (!vtable_method->IsOverridableByDefaultMethod()) { method_array->SetElementPtrSize(j, vtable_index, kPointerSize); @@ -8124,7 +8124,7 @@ size_t ClassLinker::LinkMethodsHelper<kPointerSize>::AssignVTableIndexes( auto [it, inserted] = copied_method_records_.InsertWithHash( CopiedMethodRecord(interface_method, vtable_index), hash); - if (found) { + if (vtable_method != nullptr) { DCHECK_EQ(vtable_index, it->GetMethodIndex()); } else if (inserted) { DCHECK_EQ(vtable_index, it->GetMethodIndex()); @@ -8464,17 +8464,16 @@ bool ClassLinker::LinkMethodsHelper<kPointerSize>::LinkMethods( uint32_t vtable_index = virtual_method.GetMethodIndexDuringLinking(); vtable->SetElementPtrSize(vtable_index, &virtual_method, kPointerSize); if (UNLIKELY(vtable_index < same_signature_vtable_lists.size())) { - // We may override more than one method according to JLS, see b/211854716 . - // If we do, arbitrarily update the method index to the lowest overridden vtable index. + // We may override more than one method according to JLS, see b/211854716. while (same_signature_vtable_lists[vtable_index] != dex::kDexNoIndex) { DCHECK_LT(same_signature_vtable_lists[vtable_index], vtable_index); vtable_index = same_signature_vtable_lists[vtable_index]; - ArtMethod* current_method = super_class->GetVTableEntry(vtable_index, kPointerSize); - if (klass->CanAccessMember(current_method->GetDeclaringClass(), - current_method->GetAccessFlags())) { + vtable->SetElementPtrSize(vtable_index, &virtual_method, kPointerSize); + if (kIsDebugBuild) { + ArtMethod* current_method = super_class->GetVTableEntry(vtable_index, kPointerSize); + DCHECK(klass->CanAccessMember(current_method->GetDeclaringClass(), + current_method->GetAccessFlags())); DCHECK(!current_method->IsFinal()); - vtable->SetElementPtrSize(vtable_index, &virtual_method, kPointerSize); - virtual_method.SetMethodIndex(vtable_index); } } } diff --git a/runtime/mirror/array-inl.h b/runtime/mirror/array-inl.h index b0e77b45a6..b7a8a8ce49 100644 --- a/runtime/mirror/array-inl.h +++ b/runtime/mirror/array-inl.h @@ -98,7 +98,7 @@ inline void PrimitiveArray<T>::SetWithoutChecks(int32_t i, T value) { if (kTransactionActive) { Runtime::Current()->RecordWriteArray(this, i, GetWithoutChecks(i)); } - DCHECK(CheckIsValidIndex<kVerifyFlags>(i)); + DCHECK(CheckIsValidIndex<kVerifyFlags>(i)) << i << " " << GetLength<kVerifyFlags>(); GetData()[i] = value; } // Backward copy where elements are of aligned appropriately for T. Count is in T sized units. diff --git a/test/838-override/expected-stderr.txt b/test/838-override/expected-stderr.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/838-override/expected-stderr.txt diff --git a/test/838-override/expected-stdout.txt b/test/838-override/expected-stdout.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/838-override/expected-stdout.txt diff --git a/test/838-override/info.txt b/test/838-override/info.txt new file mode 100644 index 0000000000..a33ddb2eca --- /dev/null +++ b/test/838-override/info.txt @@ -0,0 +1 @@ +Tests for method overriding in the presence of package private methods. diff --git a/test/838-override/src/Main.java b/test/838-override/src/Main.java new file mode 100644 index 0000000000..1e6aa498aa --- /dev/null +++ b/test/838-override/src/Main.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class Main { + + public static void assertEquals(Object expected, Object actual) { + if (expected != actual) { + throw new Error("Expected " + expected + ", got " + actual); + } + } + + public static void main(String[] args) { + // Tescase 1: a class with: + // - a package-private pkg1 'foo' + // - a public pkg2 'foo'. + { + pkg2.PublicFoo obj = new pkg2.PublicFoo(); + assertEquals(pkg1.Pkg1Foo.class, pkg1.Pkg1Foo.callFoo(obj)); + assertEquals(pkg2.PublicFoo.class, pkg2.Pkg2Foo.callFoo(obj)); + assertEquals(pkg2.PublicFoo.class, pkg3.Pkg3Foo.callFoo(obj)); + assertEquals(pkg2.PublicFoo.class, obj.foo()); + } + // Tescase 2: a class with: + // - a package-private pkg1 'foo' + // - a public pkg2 'foo' + // - a public pkg1 'foo. + { + pkg1.PublicFoo obj = new pkg1.PublicFoo(); + assertEquals(pkg1.PublicFoo.class, pkg1.Pkg1Foo.callFoo(obj)); + assertEquals(pkg1.PublicFoo.class, pkg2.Pkg2Foo.callFoo(obj)); + assertEquals(pkg1.PublicFoo.class, pkg3.Pkg3Foo.callFoo(obj)); + assertEquals(pkg1.PublicFoo.class, obj.foo()); + } + + // Tescase 3: a class with: + // - a package-private pkg1 'foo' + // - a package-private pkg2 'foo' + // - a public pkg3 'foo. + { + pkg3.PublicFoo obj = new pkg3.PublicFoo(); + assertEquals(pkg1.Pkg1Foo.class, pkg1.Pkg1Foo.callFoo(obj)); + assertEquals(pkg2.Pkg2Foo.class, pkg2.Pkg2Foo.callFoo(obj)); + assertEquals(pkg3.PublicFoo.class, pkg3.Pkg3Foo.callFoo(obj)); + assertEquals(pkg3.PublicFoo.class, obj.foo()); + } + + // Tescase 4: a class with: + // - a package-private pkg1 'foo' + // - a package-private pkg2 'foo' + // - a public pkg3 'foo. + // - a public pkg2 'foo' + { + pkg2.PublicFooInheritsPkg3 obj = new pkg2.PublicFooInheritsPkg3(); + assertEquals(pkg1.Pkg1Foo.class, pkg1.Pkg1Foo.callFoo(obj)); + assertEquals(pkg2.PublicFooInheritsPkg3.class, pkg2.Pkg2Foo.callFoo(obj)); + assertEquals(pkg2.PublicFooInheritsPkg3.class, pkg3.Pkg3Foo.callFoo(obj)); + assertEquals(pkg2.PublicFooInheritsPkg3.class, obj.foo()); + } + + // Tescase 5: a class with: + // - a package-private pkg1 'foo' + // - a package-private pkg2 'foo' + // - a public pkg3 'foo. + // - a public pkg2 'foo' + // - a public pkg1 'foo' + { + pkg1.PublicFooInheritsPkg2 obj = new pkg1.PublicFooInheritsPkg2(); + assertEquals(pkg1.PublicFooInheritsPkg2.class, pkg1.Pkg1Foo.callFoo(obj)); + assertEquals(pkg1.PublicFooInheritsPkg2.class, pkg2.Pkg2Foo.callFoo(obj)); + assertEquals(pkg1.PublicFooInheritsPkg2.class, pkg3.Pkg3Foo.callFoo(obj)); + assertEquals(pkg1.PublicFooInheritsPkg2.class, obj.foo()); + } + + // Tescase 6: a class with: + // - a package-private pkg1 'foo' + // - a package-private pkg2 'foo' + // - a public pkg1 'foo. + { + pkg1.LowerIndexImplementsFoo obj = new pkg1.LowerIndexImplementsFoo(); + assertEquals(pkg1.LowerIndexPublicFoo.class, pkg1.Pkg1Foo.callFoo(obj)); + assertEquals(pkg2.Pkg2Foo.class, pkg2.Pkg2Foo.callFoo(obj)); + assertEquals(pkg2.Pkg2Foo.class, pkg3.Pkg3Foo.callFoo(obj)); + assertEquals(pkg1.LowerIndexPublicFoo.class, obj.foo()); + } + } +} diff --git a/test/838-override/src/pkg1/InterfaceFoo.java b/test/838-override/src/pkg1/InterfaceFoo.java new file mode 100644 index 0000000000..cd9e44bd07 --- /dev/null +++ b/test/838-override/src/pkg1/InterfaceFoo.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pkg1; + +public interface InterfaceFoo { + public Class<?> foo(); +} diff --git a/test/838-override/src/pkg1/LowerIndexImplementsFoo.java b/test/838-override/src/pkg1/LowerIndexImplementsFoo.java new file mode 100644 index 0000000000..290f07bd53 --- /dev/null +++ b/test/838-override/src/pkg1/LowerIndexImplementsFoo.java @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pkg1; + +public class LowerIndexImplementsFoo extends LowerIndexPublicFoo implements InterfaceFoo { +} diff --git a/test/838-override/src/pkg1/LowerIndexPublicFoo.java b/test/838-override/src/pkg1/LowerIndexPublicFoo.java new file mode 100644 index 0000000000..87c0c72c1a --- /dev/null +++ b/test/838-override/src/pkg1/LowerIndexPublicFoo.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pkg1; + +public class LowerIndexPublicFoo extends pkg2.Pkg2Foo { + public Class<?> foo() { + return LowerIndexPublicFoo.class; + } +} diff --git a/test/838-override/src/pkg1/Pkg1Foo.java b/test/838-override/src/pkg1/Pkg1Foo.java new file mode 100644 index 0000000000..0ffbc27ba6 --- /dev/null +++ b/test/838-override/src/pkg1/Pkg1Foo.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pkg1; + +public class Pkg1Foo { + + Class<?> foo() { + return Pkg1Foo.class; + } + + public static Class<?> callFoo(Pkg1Foo obj) { + return obj.foo(); + } +} diff --git a/test/838-override/src/pkg1/PublicFoo.java b/test/838-override/src/pkg1/PublicFoo.java new file mode 100644 index 0000000000..c43b2829bd --- /dev/null +++ b/test/838-override/src/pkg1/PublicFoo.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pkg1; + +public class PublicFoo extends pkg2.PublicFoo { + public Class<?> foo() { + return PublicFoo.class; + } +} diff --git a/test/838-override/src/pkg1/PublicFooInheritsPkg2.java b/test/838-override/src/pkg1/PublicFooInheritsPkg2.java new file mode 100644 index 0000000000..a255f36cb0 --- /dev/null +++ b/test/838-override/src/pkg1/PublicFooInheritsPkg2.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pkg1; + +public class PublicFooInheritsPkg2 extends pkg2.PublicFooInheritsPkg3 { + public Class<?> foo() { + return PublicFooInheritsPkg2.class; + } +} diff --git a/test/838-override/src/pkg2/Pkg2Foo.java b/test/838-override/src/pkg2/Pkg2Foo.java new file mode 100644 index 0000000000..c52191452b --- /dev/null +++ b/test/838-override/src/pkg2/Pkg2Foo.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pkg2; + +public class Pkg2Foo extends pkg1.Pkg1Foo{ + Class<?> foo() { + return Pkg2Foo.class; + } + + public static Class<?> callFoo(Pkg2Foo obj) { + return obj.foo(); + } +} diff --git a/test/838-override/src/pkg2/PublicFoo.java b/test/838-override/src/pkg2/PublicFoo.java new file mode 100644 index 0000000000..5434234a6e --- /dev/null +++ b/test/838-override/src/pkg2/PublicFoo.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pkg2; + +public class PublicFoo extends Pkg2Foo { + public Class<?> foo() { + return PublicFoo.class; + } +} diff --git a/test/838-override/src/pkg2/PublicFooInheritsPkg3.java b/test/838-override/src/pkg2/PublicFooInheritsPkg3.java new file mode 100644 index 0000000000..1a983a1ce6 --- /dev/null +++ b/test/838-override/src/pkg2/PublicFooInheritsPkg3.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pkg2; + +public class PublicFooInheritsPkg3 extends pkg3.PublicFoo { + public Class<?> foo() { + return PublicFooInheritsPkg3.class; + } +} diff --git a/test/838-override/src/pkg3/Pkg3Foo.java b/test/838-override/src/pkg3/Pkg3Foo.java new file mode 100644 index 0000000000..72a16aae09 --- /dev/null +++ b/test/838-override/src/pkg3/Pkg3Foo.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pkg3; + +public class Pkg3Foo extends pkg2.Pkg2Foo { + Class<?> foo() { + return Pkg3Foo.class; + } + + public static Class<?> callFoo(Pkg3Foo obj) { + return obj.foo(); + } +} diff --git a/test/838-override/src/pkg3/PublicFoo.java b/test/838-override/src/pkg3/PublicFoo.java new file mode 100644 index 0000000000..9d37137591 --- /dev/null +++ b/test/838-override/src/pkg3/PublicFoo.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pkg3; + +public class PublicFoo extends Pkg3Foo { + public Class<?> foo() { + return PublicFoo.class; + } +} |