summaryrefslogtreecommitdiff
path: root/test/670-bitstring-type-check/build
blob: 38307f2c0ffe6d746e65305d866428d9110fe2a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
#!/bin/bash
#
# Copyright (C) 2018 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.

# Stop if something fails.
set -e

# Write out the source file.

mkdir src
cat >src/Main.java <<EOF
/*
 * Copyright (C) 2018 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.
 */

EOF

for i in {0..8192}; do echo "class Level1Class$i { }" >>src/Main.java; done
for i in {0..1024}; do echo "class Level2Class$i extends Level1Class0 { }" >>src/Main.java; done

cat >>src/Main.java <<EOF
class Level3Class0 extends Level2Class0 { }
class Level4Class0 extends Level3Class0 { }
class Level5Class0 extends Level4Class0 { }
class Level6Class0 extends Level5Class0 { }
class Level7Class0 extends Level6Class0 { }
class Level8Class0 extends Level7Class0 { }
class Level9Class0 extends Level8Class0 { }

public class Main {
  public static void main(String[] args) throws Exception {
    // 8193 classes at level 1 make sure we shall have an overflow if there are 13 or
    // less bits for the level 1 character. 1025 classes at level 2 similarly guarantees
    // an overflow if the number of bits for level 2 character is 10 or less. To test
    // type checks also for the depth overflow, we provide a hierarchy 9 levels deep.

    // Make sure the bitstrings are initialized.
    for (int i = 0; i <= 8192; ++i) {
      Class.forName("Level1Class" + i).newInstance();
    }
    for (int i = 0; i <= 1024; ++i) {
      Class.forName("Level2Class" + i).newInstance();
    }

    // Note: Using a different class for tests so that verification of Main.main() does
    // not try to resolve classes used by the tests. This guarantees uninitialized type
    // check bitstrings when we enter Main.main() and start initializing them above.
    Helper.testInstanceOf();
    Helper.testCheckCast();
  }
}

class Helper {
  public static void testInstanceOf() throws Exception {
    for (int i = 1; i <= 9; ++i) {
      Object o = createInstance("Level" + i + "Class0");
      assertTrue(o instanceof Level1Class0);
      if (o instanceof Level2Class0) {
        assertFalse(i < 2);
      } else {
        assertTrue(i < 2);
      }
      if (o instanceof Level3Class0) {
        assertFalse(i < 3);
      } else {
        assertTrue(i < 3);
      }
      if (o instanceof Level4Class0) {
        assertFalse(i < 4);
      } else {
        assertTrue(i < 4);
      }
      if (o instanceof Level5Class0) {
        assertFalse(i < 5);
      } else {
        assertTrue(i < 5);
      }
      if (o instanceof Level6Class0) {
        assertFalse(i < 6);
      } else {
        assertTrue(i < 6);
      }
      if (o instanceof Level7Class0) {
        assertFalse(i < 7);
      } else {
        assertTrue(i < 7);
      }
      if (o instanceof Level8Class0) {
        assertFalse(i < 8);
      } else {
        assertTrue(i < 8);
      }
      if (o instanceof Level9Class0) {
        assertFalse(i < 9);
      } else {
        assertTrue(i < 9);
      }
    }

    assertTrue(createInstance("Level1Class8192") instanceof Level1Class8192);
    assertFalse(createInstance("Level1Class8192") instanceof Level1Class0);
    assertTrue(createInstance("Level2Class1024") instanceof Level2Class1024);
    assertTrue(createInstance("Level2Class1024") instanceof Level1Class0);
    assertFalse(createInstance("Level2Class1024") instanceof Level2Class0);
  }

  public static void testCheckCast() throws Exception {
    for (int i = 1; i <= 9; ++i) {
      Object o = createInstance("Level" + i + "Class0");
      Level1Class0 l1c0 = (Level1Class0) o;
      try {
        Level2Class0 l2c0 = (Level2Class0) o;
        assertFalse(i < 2);
      } catch (ClassCastException cce) {
        assertTrue(i < 2);
      }
      try {
        Level3Class0 l3c0 = (Level3Class0) o;
        assertFalse(i < 3);
      } catch (ClassCastException cce) {
        assertTrue(i < 3);
      }
      try {
        Level4Class0 l4c0 = (Level4Class0) o;
        assertFalse(i < 4);
      } catch (ClassCastException cce) {
        assertTrue(i < 4);
      }
      try {
        Level5Class0 l5c0 = (Level5Class0) o;
        assertFalse(i < 5);
      } catch (ClassCastException cce) {
        assertTrue(i < 5);
      }
      try {
        Level6Class0 l6c0 = (Level6Class0) o;
        assertFalse(i < 6);
      } catch (ClassCastException cce) {
        assertTrue(i < 6);
      }
      try {
        Level7Class0 l7c0 = (Level7Class0) o;
        assertFalse(i < 7);
      } catch (ClassCastException cce) {
        assertTrue(i < 7);
      }
      try {
        Level8Class0 l8c0 = (Level8Class0) o;
        assertFalse(i < 8);
      } catch (ClassCastException cce) {
        assertTrue(i < 8);
      }
      try {
        Level9Class0 l9c0 = (Level9Class0) o;
        assertFalse(i < 9);
      } catch (ClassCastException cce) {
        assertTrue(i < 9);
      }
    }

    Level1Class8192 l1c8192 = (Level1Class8192) createInstance("Level1Class8192");
    try {
      Level1Class0 l1c0 = (Level1Class0) createInstance("Level1Class8192");
      throw new AssertionError("Unexpected");
    } catch (ClassCastException expected) {}
    Level2Class1024 l2c1024 = (Level2Class1024) createInstance("Level2Class1024");
    Level1Class0 l1c0 = (Level1Class0) createInstance("Level2Class1024");
    try {
      Level2Class0 l2c0 = (Level2Class0) createInstance("Level2Class1024");
      throw new AssertionError("Unexpected");
    } catch (ClassCastException expected) {}
  }

  public static Object createInstance(String className) throws Exception {
    return Class.forName(className).newInstance();
  }

  public static void assertTrue(boolean value) throws Exception {
    if (!value) {
      throw new AssertionError();
    }
  }

  public static void assertFalse(boolean value) throws Exception {
    if (value) {
      throw new AssertionError();
    }
  }
}
EOF

./default-build "$@"