diff options
| author | 2020-08-07 17:38:51 +0100 | |
|---|---|---|
| committer | 2020-08-18 08:00:18 +0000 | |
| commit | 50fe6dc170402600936d72a5fd729b5ebda0294b (patch) | |
| tree | a26c3d7ec656537f32ebff7125c77b3b9dc766c8 | |
| parent | 2ea5d0408fd09bd95a97a796270d6b0c31acab2e (diff) | |
Optimizing: Fix weak field access check.
Test: New test 727-checker-unresolved-class
Test: testrunner.py --host --optimizing --interpreter --jvm -t 727
Test: testrunner.py --host --optimizing
Bug: 161898207
Change-Id: Iaab9e3fef4775144d533086ec3797ce7d06c50b7
11 files changed, 171 insertions, 5 deletions
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index c96ea5d945..62932c989f 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -1936,7 +1936,9 @@ ArtField* HInstructionBuilder::ResolveField(uint16_t field_idx, bool is_static, // Check access. Handle<mirror::Class> compiling_class = dex_compilation_unit_->GetCompilingClass(); if (compiling_class == nullptr) { - if (!resolved_field->IsPublic()) { + // For unresolved compiling class, handle only the simple case of a public field + // in a public class and use a slow runtime call for all other cases. + if (!resolved_field->IsPublic() || !resolved_field->GetDeclaringClass()->IsPublic()) { return nullptr; } } else if (!compiling_class->CanAccessResolvedField(resolved_field->GetDeclaringClass(), diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 09f22a46e6..dd6194fdc6 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -2895,13 +2895,13 @@ class Dex2Oat final { template <typename T> static std::unique_ptr<T> ReadCommentedInputFromFile( const char* input_filename, std::function<std::string(const char*)>* process) { - std::unique_ptr<std::ifstream> input_file(new std::ifstream(input_filename, std::ifstream::in)); - if (input_file.get() == nullptr) { + std::ifstream input_file(input_filename, std::ifstream::in); + if (!input_file.good()) { LOG(ERROR) << "Failed to open input file " << input_filename; return nullptr; } - std::unique_ptr<T> result = ReadCommentedInputStream<T>(*input_file, process); - input_file->close(); + std::unique_ptr<T> result = ReadCommentedInputStream<T>(input_file, process); + input_file.close(); return result; } diff --git a/test/727-checker-unresolved-class/expected.txt b/test/727-checker-unresolved-class/expected.txt new file mode 100644 index 0000000000..b0aad4deb5 --- /dev/null +++ b/test/727-checker-unresolved-class/expected.txt @@ -0,0 +1 @@ +passed diff --git a/test/727-checker-unresolved-class/info.txt b/test/727-checker-unresolved-class/info.txt new file mode 100644 index 0000000000..cc60c0fb91 --- /dev/null +++ b/test/727-checker-unresolved-class/info.txt @@ -0,0 +1,2 @@ +Tests for compiling with unresolved classes, including unresolved +class of the method being compiled. diff --git a/test/727-checker-unresolved-class/run b/test/727-checker-unresolved-class/run new file mode 100644 index 0000000000..04b3e17600 --- /dev/null +++ b/test/727-checker-unresolved-class/run @@ -0,0 +1,21 @@ +#!/bin/bash +# +# Copyright (C) 2020 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. + +if [[ "$TEST_RUNTIME" == "jvm" ]]; then + exec ${RUN} $@ +else + exec ${RUN} $@ -Xcompiler-option --updatable-bcp-packages-file="$PWD/updateable.txt" +fi diff --git a/test/727-checker-unresolved-class/src/Main.java b/test/727-checker-unresolved-class/src/Main.java new file mode 100644 index 0000000000..04b403bc2e --- /dev/null +++ b/test/727-checker-unresolved-class/src/Main.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2020 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. + */ + +import unresolved.UnresolvedClass; + +public class Main { + public static void main(String[] args) { + UnresolvedClass.$noinline$main(); + System.out.println("passed"); + } +} diff --git a/test/727-checker-unresolved-class/src/resolved/ResolvedPackagePrivateClass.java b/test/727-checker-unresolved-class/src/resolved/ResolvedPackagePrivateClass.java new file mode 100644 index 0000000000..983eea9d41 --- /dev/null +++ b/test/727-checker-unresolved-class/src/resolved/ResolvedPackagePrivateClass.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2020 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 resolved; + +// This class is used for compiling code that accesses its fields but it is +// replaced by a package-private class from src2/ to make that access illegal. +public class ResolvedPackagePrivateClass { + public static int publicIntField; + static int intField; +} diff --git a/test/727-checker-unresolved-class/src/resolved/ResolvedPublicSubclassOfPackagePrivateClass.java b/test/727-checker-unresolved-class/src/resolved/ResolvedPublicSubclassOfPackagePrivateClass.java new file mode 100644 index 0000000000..1ca6060995 --- /dev/null +++ b/test/727-checker-unresolved-class/src/resolved/ResolvedPublicSubclassOfPackagePrivateClass.java @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2020 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 resolved; + +public class ResolvedPublicSubclassOfPackagePrivateClass extends ResolvedPackagePrivateClass { +} diff --git a/test/727-checker-unresolved-class/src/unresolved/UnresolvedClass.java b/test/727-checker-unresolved-class/src/unresolved/UnresolvedClass.java new file mode 100644 index 0000000000..65e072de72 --- /dev/null +++ b/test/727-checker-unresolved-class/src/unresolved/UnresolvedClass.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 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 unresolved; + +import resolved.ResolvedPackagePrivateClass; +import resolved.ResolvedPublicSubclassOfPackagePrivateClass; + +public class UnresolvedClass { + public static void $noinline$main() { + $noinline$testPublicFieldInResolvedPackagePrivateClass(); + $noinline$testPublicFieldInPackagePrivateClassReferencedViaResolvedPublicSubclass(); + } + + /// CHECK-START: void unresolved.UnresolvedClass.$noinline$testPublicFieldInResolvedPackagePrivateClass() builder (after) + /// CHECK: UnresolvedStaticFieldSet + + /// CHECK-START: void unresolved.UnresolvedClass.$noinline$testPublicFieldInResolvedPackagePrivateClass() builder (after) + /// CHECK-NOT: StaticFieldSet + static void $noinline$testPublicFieldInResolvedPackagePrivateClass() { + try { + ResolvedPackagePrivateClass.publicIntField = 42; + throw new Error("Unreachable"); + } catch (IllegalAccessError expected) {} + } + + /// CHECK-START: void unresolved.UnresolvedClass.$noinline$testPublicFieldInPackagePrivateClassReferencedViaResolvedPublicSubclass() builder (after) + /// CHECK: UnresolvedStaticFieldSet + + /// CHECK-START: void unresolved.UnresolvedClass.$noinline$testPublicFieldInPackagePrivateClassReferencedViaResolvedPublicSubclass() builder (after) + /// CHECK-NOT: StaticFieldSet + static void $noinline$testPublicFieldInPackagePrivateClassReferencedViaResolvedPublicSubclass() { + // TODO: Use StaticFieldSet when the referenced class is public. + ResolvedPublicSubclassOfPackagePrivateClass.publicIntField = 42; + } +} diff --git a/test/727-checker-unresolved-class/src2/resolved/ResolvedPackagePrivateClass.java b/test/727-checker-unresolved-class/src2/resolved/ResolvedPackagePrivateClass.java new file mode 100644 index 0000000000..cf67135980 --- /dev/null +++ b/test/727-checker-unresolved-class/src2/resolved/ResolvedPackagePrivateClass.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2020 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 resolved; + +class ResolvedPackagePrivateClass { + public static int publicIntField; + static int intField; +} diff --git a/test/727-checker-unresolved-class/updateable.txt b/test/727-checker-unresolved-class/updateable.txt new file mode 100644 index 0000000000..7938381e0d --- /dev/null +++ b/test/727-checker-unresolved-class/updateable.txt @@ -0,0 +1 @@ +unresolved |