From 52f205a38bda70d5c63907ef354a1475b4237b21 Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Fri, 1 Dec 2017 12:16:07 -0800 Subject: ART: Remove old aget on null workaround Use null for an aget-object of null. Ensure that other aget types on null cannot be converted to or used as a reference type. Let the verifier continue scanning after an aget on a null register, to ensure that the dead code is type-safe. Add test coverage for the new behavior. Partially reverts commit 4824c27988c8eeb302791624bb3ce1d557b0db6c Partially reverts commit 857f058d4b7bd07c5c99eda416ad91516a10b4da Bug: 22059710 Bug: 64683522 Bug: 69669661 Test: m test-art-host Change-Id: Ie0b554e8f880251d8e73ab6dfb6b41a5e63defc6 --- test/518-null-array-get/expected.txt | 6 ++++ test/518-null-array-get/info.txt | 12 ++++++-- test/518-null-array-get/smali/NullArray.smali | 26 ---------------- .../smali/NullArrayFailInt2Object.smali | 28 +++++++++++++++++ .../smali/NullArrayFailObject2Int.smali | 28 +++++++++++++++++ .../smali/NullArraySuccessInt.smali | 33 ++++++++++++++++++++ .../smali/NullArraySuccessInt2Float.smali | 33 ++++++++++++++++++++ .../smali/NullArraySuccessRef.smali | 33 ++++++++++++++++++++ .../smali/NullArraySuccessShort.smali | 33 ++++++++++++++++++++ test/518-null-array-get/src/Main.java | 36 +++++++++++++++++----- 10 files changed, 231 insertions(+), 37 deletions(-) delete mode 100644 test/518-null-array-get/smali/NullArray.smali create mode 100644 test/518-null-array-get/smali/NullArrayFailInt2Object.smali create mode 100644 test/518-null-array-get/smali/NullArrayFailObject2Int.smali create mode 100644 test/518-null-array-get/smali/NullArraySuccessInt.smali create mode 100644 test/518-null-array-get/smali/NullArraySuccessInt2Float.smali create mode 100644 test/518-null-array-get/smali/NullArraySuccessRef.smali create mode 100644 test/518-null-array-get/smali/NullArraySuccessShort.smali (limited to 'test/518-null-array-get') diff --git a/test/518-null-array-get/expected.txt b/test/518-null-array-get/expected.txt index e69de29bb2..ae5318e53d 100644 --- a/test/518-null-array-get/expected.txt +++ b/test/518-null-array-get/expected.txt @@ -0,0 +1,6 @@ +NullArrayFailInt2Object +NullArrayFailObject2Int +NullArraySuccessInt +NullArraySuccessInt2Float +NullArraySuccessShort +NullArraySuccessRef diff --git a/test/518-null-array-get/info.txt b/test/518-null-array-get/info.txt index 407f590b2b..71e0332e62 100644 --- a/test/518-null-array-get/info.txt +++ b/test/518-null-array-get/info.txt @@ -1,3 +1,9 @@ -Regression test for Quick and Optimizing that used -to crash on an aget-object + int-to-byte sequence -(accepted by the verifier in the case the array was null). +Codifies that the verifier should reject type-unsafe +instructions in dead code after aget on null, but pass +type-safe dead code. + +Previously verification stopped after aget on null and +punted the method to the interpreter in an effort to avoid +compiler crashes. As broken code appears very uncommon, +ensure verifier strictness and help the compilers see more +code. diff --git a/test/518-null-array-get/smali/NullArray.smali b/test/518-null-array-get/smali/NullArray.smali deleted file mode 100644 index 52abc38473..0000000000 --- a/test/518-null-array-get/smali/NullArray.smali +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (C) 2015 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. - -.class public LNullArray; - -.super Ljava/lang/Object; - -.method public static method()B - .registers 2 - const/4 v0, 0 - const/4 v1, 0 - aget-object v0, v0, v1 - int-to-byte v0, v0 - return v0 -.end method diff --git a/test/518-null-array-get/smali/NullArrayFailInt2Object.smali b/test/518-null-array-get/smali/NullArrayFailInt2Object.smali new file mode 100644 index 0000000000..ca4ed10660 --- /dev/null +++ b/test/518-null-array-get/smali/NullArrayFailInt2Object.smali @@ -0,0 +1,28 @@ +# Copyright (C) 2015 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. + +# Check that the result of aget on null cannot be used as a reference. + +.class public LNullArrayFailInt2Object; + +.super Ljava/lang/Object; + +.method public static method()V + .registers 2 + const/4 v0, 0 + const/4 v1, 0 + aget v0, v0, v1 + invoke-virtual { v0 }, Ljava/lang/Object;->toString()Ljava/lang/String; + return-void +.end method diff --git a/test/518-null-array-get/smali/NullArrayFailObject2Int.smali b/test/518-null-array-get/smali/NullArrayFailObject2Int.smali new file mode 100644 index 0000000000..83823a24e5 --- /dev/null +++ b/test/518-null-array-get/smali/NullArrayFailObject2Int.smali @@ -0,0 +1,28 @@ +# Copyright (C) 2015 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. + +# Check that the result of aget-object on null cannot be used as an integral. + +.class public LNullArrayFailObject2Int; + +.super Ljava/lang/Object; + +.method public static method()B + .registers 2 + const/4 v0, 0 + const/4 v1, 0 + aget-object v0, v0, v1 + int-to-byte v0, v0 + return v0 +.end method diff --git a/test/518-null-array-get/smali/NullArraySuccessInt.smali b/test/518-null-array-get/smali/NullArraySuccessInt.smali new file mode 100644 index 0000000000..01cf1c92ab --- /dev/null +++ b/test/518-null-array-get/smali/NullArraySuccessInt.smali @@ -0,0 +1,33 @@ +# Copyright (C) 2015 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. + +# Check that the result of aget on null can be used as an int. + +.class public LNullArraySuccessInt; + +.super Ljava/lang/Object; + +.method public static intMethod(I)V + .registers 1 + return-void +.end method + +.method public static method()V + .registers 2 + const/4 v0, 0 + const/4 v1, 0 + aget v0, v0, v1 + invoke-static { v0 }, LNullArraySuccessInt;->intMethod(I)V + return-void +.end method diff --git a/test/518-null-array-get/smali/NullArraySuccessInt2Float.smali b/test/518-null-array-get/smali/NullArraySuccessInt2Float.smali new file mode 100644 index 0000000000..bd59d5f68e --- /dev/null +++ b/test/518-null-array-get/smali/NullArraySuccessInt2Float.smali @@ -0,0 +1,33 @@ +# Copyright (C) 2015 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. + +# Check that the result of aget on null can be used as a float. + +.class public LNullArraySuccessInt2Float; + +.super Ljava/lang/Object; + +.method public static floatMethod(F)V + .registers 1 + return-void +.end method + +.method public static method()V + .registers 2 + const/4 v0, 0 + const/4 v1, 0 + aget v0, v0, v1 + invoke-static { v0 }, LNullArraySuccessInt2Float;->floatMethod(F)V + return-void +.end method diff --git a/test/518-null-array-get/smali/NullArraySuccessRef.smali b/test/518-null-array-get/smali/NullArraySuccessRef.smali new file mode 100644 index 0000000000..2f512d4089 --- /dev/null +++ b/test/518-null-array-get/smali/NullArraySuccessRef.smali @@ -0,0 +1,33 @@ +# Copyright (C) 2015 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. + +# Check that the result of aget-object on null can be used as a reference. + +.class public LNullArraySuccessRef; + +.super Ljava/lang/Object; + +.method public voidMethod()V + .registers 1 + return-void +.end method + +.method public static method()V + .registers 2 + const/4 v0, 0 + const/4 v1, 0 + aget-object v0, v0, v1 + invoke-virtual { v0 }, LNullArraySuccessRef;->voidMethod()V + return-void +.end method diff --git a/test/518-null-array-get/smali/NullArraySuccessShort.smali b/test/518-null-array-get/smali/NullArraySuccessShort.smali new file mode 100644 index 0000000000..d332e51f52 --- /dev/null +++ b/test/518-null-array-get/smali/NullArraySuccessShort.smali @@ -0,0 +1,33 @@ +# Copyright (C) 2015 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. + +# Check that the result of aget-short on null can be used as a short. + +.class public LNullArraySuccessShort; + +.super Ljava/lang/Object; + +.method public static shortMethod(S)V + .registers 1 + return-void +.end method + +.method public static method()V + .registers 2 + const/4 v0, 0 + const/4 v1, 0 + aget-short v0, v0, v1 + invoke-static { v0 }, LNullArraySuccessShort;->shortMethod(S)V + return-void +.end method diff --git a/test/518-null-array-get/src/Main.java b/test/518-null-array-get/src/Main.java index 66e50aacd7..678aef1f43 100644 --- a/test/518-null-array-get/src/Main.java +++ b/test/518-null-array-get/src/Main.java @@ -22,16 +22,36 @@ public class Main { class InnerClass {} public static void main(String[] args) throws Exception { - Class c = Class.forName("NullArray"); - Method m = c.getMethod("method"); - Object[] arguments = { }; + checkLoad("NullArrayFailInt2Object", true); + checkLoad("NullArrayFailObject2Int", true); + checkLoad("NullArraySuccessInt", false); + checkLoad("NullArraySuccessInt2Float", false); + checkLoad("NullArraySuccessShort", false); + checkLoad("NullArraySuccessRef", false); + } + + private static void checkLoad(String className, boolean expectError) throws Exception { + Class c; try { - m.invoke(null, arguments); - throw new Error("Expected an InvocationTargetException"); - } catch (InvocationTargetException e) { - if (!(e.getCause() instanceof NullPointerException)) { - throw new Error("Expected a NullPointerException"); + c = Class.forName(className); + if (expectError) { + throw new RuntimeException("Expected error for " + className); + } + Method m = c.getMethod("method"); + try { + m.invoke(null); + throw new RuntimeException("Expected an InvocationTargetException"); + } catch (InvocationTargetException e) { + if (!(e.getCause() instanceof NullPointerException)) { + throw new RuntimeException("Expected a NullPointerException"); + } + System.out.println(className); + } + } catch (VerifyError e) { + if (!expectError) { + throw new RuntimeException(e); } + System.out.println(className); } } } -- cgit v1.2.3-59-g8ed1b