summaryrefslogtreecommitdiff
path: root/test/674-hiddenapi/src-ex/ChildClass.java
diff options
context:
space:
mode:
author David Brazdil <dbrazdil@google.com> 2018-03-14 13:57:27 +0000
committer David Brazdil <dbrazdil@google.com> 2018-03-15 12:54:42 +0000
commitfc66129b478d49f493b8262f81f8813a5f41459e (patch)
tree305594db27eaf39336175f958ee447536d9bf5d9 /test/674-hiddenapi/src-ex/ChildClass.java
parent8ce3bfaf1da2139a70b67e6b53c0110489801d40 (diff)
Warn on overriding of hidden methods
We could prevent apps from overriding hidden methods in the same manner they cannot override a package-private method - by creating a separate vtable entry for the child method. For now, start by printing a warning when a hidden method is being overridden but do not change the semantics. Bug: 64382372 Test: art/test.py -r -t 674-hiddenapi Change-Id: I9d5bfa6b833a4c0f5aaffa5f82dbe9b1e1f03f1f
Diffstat (limited to 'test/674-hiddenapi/src-ex/ChildClass.java')
-rw-r--r--test/674-hiddenapi/src-ex/ChildClass.java34
1 files changed, 34 insertions, 0 deletions
diff --git a/test/674-hiddenapi/src-ex/ChildClass.java b/test/674-hiddenapi/src-ex/ChildClass.java
index 582e907ca3..8cd237ab6f 100644
--- a/test/674-hiddenapi/src-ex/ChildClass.java
+++ b/test/674-hiddenapi/src-ex/ChildClass.java
@@ -123,6 +123,9 @@ public class ChildClass {
// Check whether one can use an interface default method.
String name = "method" + visibility.name() + "Default" + hiddenness.name();
checkMethod(ParentInterface.class, name, /*isStatic*/ false, visibility, expected);
+
+ // Check whether one can override this method.
+ checkOverriding(suffix, isStatic, visibility, expected);
}
// Test whether static linking succeeds.
@@ -403,6 +406,37 @@ public class ChildClass {
}
}
+ private static void checkOverriding(String suffix,
+ boolean isStatic,
+ Visibility visibility,
+ Behaviour behaviour) throws Exception {
+ if (isStatic || visibility == Visibility.Private) {
+ // Does not make sense to override a static or private method.
+ return;
+ }
+
+ // The classes are in the same package, but will be able to access each
+ // other only if loaded with the same class loader, here the boot class loader.
+ boolean canAccess = (visibility != Visibility.Package) || (isParentInBoot && isChildInBoot);
+ boolean setsWarning = false; // warnings may be set during vtable linking
+
+ String methodName = "callMethod" + visibility.name() + suffix;
+
+ // Force the test class to link its vtable, which may cause warnings, before
+ // the actual test.
+ new OverrideClass().methodPublicWhitelist();
+
+ clearWarning();
+ if (Linking.canOverride(methodName) != canAccess) {
+ throw new RuntimeException("Expected to " + (canAccess ? "" : "not ") +
+ "be able to override " + methodName + "." +
+ "isParentInBoot = " + isParentInBoot + ", " + "isChildInBoot = " + isChildInBoot);
+ }
+ if (canAccess && hasPendingWarning() != setsWarning) {
+ throwWarningException(ParentClass.class, methodName, false, "static linking", setsWarning);
+ }
+ }
+
private static void throwDiscoveryException(Class<?> klass, String name, boolean isField,
String fn, boolean canAccess) {
throw new RuntimeException("Expected " + (isField ? "field " : "method ") + klass.getName() +