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