|
8 | 8 |
|
9 | 9 | /// \file
|
10 | 10 | /// Remove Instance-of Operators
|
| 11 | +/// |
| 12 | +/// Java has an operator called `instanceof`, which is used to check if an |
| 13 | +/// instance of a class is of a particular type. For example given that `A` and |
| 14 | +/// `B` are the identifiers of classes, which directly extend Object. If the |
| 15 | +/// following example java code is executed - |
| 16 | +/// ```java |
| 17 | +/// Object a = new A(); |
| 18 | +/// boolean x = a instanceof A; // true |
| 19 | +/// boolean y = a instanceof B; // false |
| 20 | +/// ``` |
| 21 | +/// Then, `x` will be set to `true` and `y` will be set to `false`. |
| 22 | +/// |
| 23 | +/// `instanceof` also works with inheritance. Given classes `C` and `D`, where |
| 24 | +/// `C` extends from `Object` and `D` extends `C`. If the following example java |
| 25 | +/// code is executed - |
| 26 | +/// ```java |
| 27 | +/// Object c = new C(); |
| 28 | +/// Object d = new D(); |
| 29 | +/// boolean b1 = c instanceof C; // true |
| 30 | +/// boolean b2 = c instanceof D; // false |
| 31 | +/// boolean b3 = d instanceof C; // true |
| 32 | +/// boolean b4 = d instanceof D; // true |
| 33 | +/// ``` |
| 34 | +/// Then, `b1` will be `true`, `b2` will be `false`, `b3` will be `true` and |
| 35 | +/// `b4` will be `true`. |
| 36 | +/// |
| 37 | +/// `instanceof` has its own instruction type in the java bytecode. We need to |
| 38 | +/// rewrite it in terms of other, more fundamental operations in order to |
| 39 | +/// analyse it. This operation is referred to as "lowering" or in this |
| 40 | +/// specific case - `remove_instanceof`. |
| 41 | +/// |
| 42 | +/// For a simple example where class `A` extends `Object` and no classes extend |
| 43 | +/// `A`, the expression `e instanceof A` needs to be lowered to an expression |
| 44 | +/// equivalent to `e == null ? false : e->@class_identifier == "A"`. The null |
| 45 | +/// case needs to be taken into account first, as we can't lookup the value of |
| 46 | +/// a `@class_identifier` field in a null pointer. Note that according to the |
| 47 | +/// Java specification, `null` is not an instance of any type. |
| 48 | +/// |
| 49 | +/// For an example with inheritance where class `D` extends `C` and `C` extends |
| 50 | +/// `Object`, then `e instanceof C` needs to be lowered to an expression |
| 51 | +/// equivalent to `e == null ? false : (e->@class_identifier == "C" || |
| 52 | +/// e->@class_identifier == "D")`. To lower `e instanceof C` correctly, we need |
| 53 | +/// to take into account each of the classes extends from `C`. Working out what |
| 54 | +/// classes extend a given class type is performed using an instance of the |
| 55 | +/// `class_hierarchyt` class. |
| 56 | +/// |
| 57 | +/// In terms of the goto program, the `instanceof` operator is identified in the |
| 58 | +/// expression tree, based on the `exprt.id()` being `ID_java_instance_of`. The |
| 59 | +/// left hand side of the operator must be a pointer and the right hand side |
| 60 | +/// must be a type. |
| 61 | +/// |
| 62 | +/// The lowered form has a refinement to help with null pointer analysis later |
| 63 | +/// on. Instead of dereferencing the pointer to get `@class_identifier` in each |
| 64 | +/// comparision, it is dereferenced a single time and the result is reused. This |
| 65 | +/// is easier to analyse for null pointers, because there is only a single |
| 66 | +/// dereference to consider. So the constructed program takes the form - |
| 67 | +/// ```cpp |
| 68 | +/// if(expr == null) |
| 69 | +/// instanceof_result = false; |
| 70 | +/// else |
| 71 | +/// string class_identifier_tmpX = expr->@class_identifier; |
| 72 | +/// instanceof_result = |
| 73 | +/// class_identifier_tmpX == "C" || |
| 74 | +/// class_identifier_tmpX == "D"; |
| 75 | +/// ``` |
| 76 | +/// Where the `X` in `class_identifier_tmp` is a number which makes the |
| 77 | +/// identifier unique. |
11 | 78 |
|
12 | 79 | #ifndef CPROVER_JAVA_BYTECODE_REMOVE_INSTANCEOF_H
|
13 | 80 | #define CPROVER_JAVA_BYTECODE_REMOVE_INSTANCEOF_H
|
|
0 commit comments