1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /** 18 * Tests for detecting throwing methods for code sinking. 19 */ 20 public class Main { 21 22 // 23 // Some "runtime library" methods. 24 // 25 doThrow(String par)26 public final void doThrow(String par) { 27 throw new Error("you are null: " + par); 28 } 29 checkNotNullDirect(Object obj, String par)30 public final void checkNotNullDirect(Object obj, String par) { 31 if (obj == null) 32 throw new Error("you are null: " + par); 33 } 34 checkNotNullSplit(Object obj, String par)35 public final void checkNotNullSplit(Object obj, String par) { 36 if (obj == null) 37 doThrow(par); 38 } 39 40 // 41 // Various ways of enforcing non-null parameter. 42 // In all cases, par should be subject to code sinking. 43 // 44 45 /// CHECK-START: void Main.doit1(int[]) code_sinking (before) 46 /// CHECK: begin_block 47 /// CHECK: <<Str:l\d+>> LoadString 48 /// CHECK: <<Tst:z\d+>> Equal 49 /// CHECK: If [<<Tst>>] 50 /// CHECK: end_block 51 /// CHECK: begin_block 52 /// CHECK: InvokeVirtual [{{l\d+}},<<Str>>] 53 /// CHECK: Throw 54 /// CHECK: end_block 55 // 56 /// CHECK-START: void Main.doit1(int[]) code_sinking (after) 57 /// CHECK: begin_block 58 /// CHECK: <<Tst:z\d+>> Equal 59 /// CHECK: If [<<Tst>>] 60 /// CHECK: end_block 61 /// CHECK: begin_block 62 /// CHECK: <<Str:l\d+>> LoadString 63 /// CHECK: InvokeVirtual [{{l\d+}},<<Str>>] 64 /// CHECK: Throw 65 /// CHECK: end_block doit1(int[] a)66 public void doit1(int[] a) { 67 String par = "a"; 68 if (a == null) 69 throw new Error("you are null: " + par); 70 for (int i = 0; i < a.length; i++) { 71 a[i] = 1; 72 } 73 } 74 75 /// CHECK-START: void Main.doit2(int[]) code_sinking (before) 76 /// CHECK: begin_block 77 /// CHECK: <<Str:l\d+>> LoadString 78 /// CHECK: <<Tst:z\d+>> NotEqual 79 /// CHECK: If [<<Tst>>] 80 /// CHECK: end_block 81 /// CHECK: begin_block 82 /// CHECK: InvokeVirtual [{{l\d+}},<<Str>>] method_name:Main.doThrow 83 /// CHECK: end_block 84 // 85 /// CHECK-START: void Main.doit2(int[]) code_sinking (after) 86 /// CHECK: begin_block 87 /// CHECK: <<Tst:z\d+>> NotEqual 88 /// CHECK: If [<<Tst>>] 89 /// CHECK: end_block 90 /// CHECK: begin_block 91 /// CHECK: <<Str:l\d+>> LoadString 92 /// CHECK: InvokeVirtual [{{l\d+}},<<Str>>] method_name:Main.doThrow 93 /// CHECK: end_block doit2(int[] a)94 public void doit2(int[] a) { 95 String par = "a"; 96 if (a == null) 97 doThrow(par); 98 for (int i = 0; i < a.length; i++) { 99 a[i] = 2; 100 } 101 } 102 103 /// CHECK-START: void Main.doit3(int[]) code_sinking (before) 104 /// CHECK: begin_block 105 /// CHECK: <<Str:l\d+>> LoadString 106 /// CHECK: <<Tst:z\d+>> Equal 107 /// CHECK: If [<<Tst>>] 108 /// CHECK: end_block 109 /// CHECK: begin_block 110 /// CHECK: InvokeVirtual [{{l\d+}},<<Str>>] 111 /// CHECK: Throw 112 /// CHECK: end_block 113 // 114 /// CHECK-START: void Main.doit3(int[]) code_sinking (after) 115 /// CHECK: begin_block 116 /// CHECK: <<Tst:z\d+>> Equal 117 /// CHECK: If [<<Tst>>] 118 /// CHECK: end_block 119 /// CHECK: begin_block 120 /// CHECK: <<Str:l\d+>> LoadString 121 /// CHECK: InvokeVirtual [{{l\d+}},<<Str>>] 122 /// CHECK: Throw 123 /// CHECK: end_block doit3(int[] a)124 public void doit3(int[] a) { 125 String par = "a"; 126 checkNotNullDirect(a, par); 127 for (int i = 0; i < a.length; i++) { 128 a[i] = 3; 129 } 130 } 131 132 /// CHECK-START: void Main.doit4(int[]) code_sinking (before) 133 /// CHECK: begin_block 134 /// CHECK: <<Str:l\d+>> LoadString 135 /// CHECK: <<Tst:z\d+>> NotEqual 136 /// CHECK: If [<<Tst>>] 137 /// CHECK: end_block 138 /// CHECK: begin_block 139 /// CHECK: InvokeVirtual [{{l\d+}},<<Str>>] method_name:Main.doThrow 140 /// CHECK: end_block 141 // 142 /// CHECK-START: void Main.doit4(int[]) code_sinking (after) 143 /// CHECK: begin_block 144 /// CHECK: <<Tst:z\d+>> NotEqual 145 /// CHECK: If [<<Tst>>] 146 /// CHECK: end_block 147 /// CHECK: begin_block 148 /// CHECK: <<Str:l\d+>> LoadString 149 /// CHECK: InvokeVirtual [{{l\d+}},<<Str>>] method_name:Main.doThrow 150 /// CHECK: end_block doit4(int[] a)151 public void doit4(int[] a) { 152 String par = "a"; 153 checkNotNullSplit(a, par); 154 for (int i = 0; i < a.length; i++) { 155 a[i] = 4; 156 } 157 } 158 159 // 160 // Test driver. 161 // 162 main(String[] args)163 static public void main(String[] args) { 164 int[] a = new int[100]; 165 for (int i = 0; i < 100; i++) { 166 a[i] = 0; 167 } 168 169 Main m = new Main(); 170 171 try { 172 m.doit1(null); 173 System.out.println("should not reach this!"); 174 } catch (Error e) { 175 m.doit1(a); 176 } 177 for (int i = 0; i < 100; i++) { 178 expectEquals(1, a[i]); 179 } 180 181 try { 182 m.doit2(null); 183 System.out.println("should not reach this!"); 184 } catch (Error e) { 185 m.doit2(a); 186 } 187 for (int i = 0; i < 100; i++) { 188 expectEquals(2, a[i]); 189 } 190 191 try { 192 m.doit3(null); 193 System.out.println("should not reach this!"); 194 } catch (Error e) { 195 m.doit3(a); 196 } 197 for (int i = 0; i < 100; i++) { 198 expectEquals(3, a[i]); 199 } 200 201 try { 202 m.doit4(null); 203 System.out.println("should not reach this!"); 204 } catch (Error e) { 205 m.doit4(a); 206 } 207 for (int i = 0; i < 100; i++) { 208 expectEquals(4, a[i]); 209 } 210 211 System.out.println("passed"); 212 } 213 expectEquals(int expected, int result)214 private static void expectEquals(int expected, int result) { 215 if (expected != result) { 216 throw new Error("Expected: " + expected + ", found: " + result); 217 } 218 } 219 } 220