You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 lines
2.3 KiB

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import java.util.ArrayList;
class Test {
private int a = 0;
static Integer[] global_arr;
void Test(int size) {
global_arr = new Integer[size];
}
void set_impure(int x, int y) {
a = x + y;
}
void global_array_set_impure(int x, int y) {
global_arr[0] = x + y;
}
int local_write_pure(int x, int y) {
int k = x + y;
k++;
return k;
}
void call_pure_pure(int size) {
for (int i = 0; i < size; i++) {
local_write_pure(i, size);
}
}
void call_impure_impure(int size) {
int d = 0;
for (int i = 0; i < size; i++) {
set_impure(i, size);
}
}
// no change to outside state, the local allocation is ok.
int local_alloc_pure(int x, int y) {
ArrayList<Integer> list = new ArrayList<Integer>(x + y);
for (Integer el : list) {
call_pure_pure(el);
}
return list.size();
}
void parameter_field_write_impure(Test test, boolean b) {
int c = b ? 0 : 1;
test.a = c;
}
int parameter_field_access_pure(Test test) {
return test.a;
}
// expected to be impure since y points to x
void local_field_write_impure(Test x) {
Test y = x;
y.a = 0;
}
void swap_impure(int[] array, int i, int j) {
int tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
void alias_impure(int[] array, int i, int j) {
int[] a = array;
a[j] = i;
}
// Currently, we can't distinguish between returning new Objects or
// creating new Objects locally. Ideally, the latter should be fine
// as long as it doesn't leak to the result.
public ArrayList<Integer> emptyList_impure_FN() {
return new ArrayList<Integer>();
}
// All unmodeled calls should be considered impure
static long systemNanoTime_impure() {
return System.nanoTime();
}
[pulse] Distinguish exit state at top level Summary: This diff lifts the `PulseAbductiveDomain.t` in `PulseExecutionState` by tracking whether the program continues the analysis normally or exits unusually (e.g. by calling `exit` or `throw`): ``` type exec_state = | ContinueProgram of PulseAbductiveDomain.t (** represents the state at the program point *) | ExitProgram of PulseAbductiveDomain.t (** represents the state originating at exit/divergence. *) ``` Now, Pulse's actual domain is tracked by `PulseExecutionState` and as soon as we try to analyze an instruction at `ExitProgram`, we simply return its state. The aim is to recover the state at the time of the exit, rather than simply ignoring them (i.e. returning empty disjuncts). This allows us to get rid of some FNs that we were not able to detect before. Moreover, it also allows the impurity analysis to be more precise since we will know how the state changed up to exit. TODO: - Impurity analysis needs to be improved to consider functions that simply exit as impure. - The next goal is to handle error state similarly so that when pulse finds an error, we recover the state at the error location (and potentially continue to analyze?). Disclaimer: currently, we handle throw statements like exit (as was the case before). However, this is not correct. Ideally, control flow from throw nodes follows catch nodes rather than exiting the program entirely. Reviewed By: jvillard Differential Revision: D20791747 fbshipit-source-id: df9e5445a
5 years ago
// In pulse, we get Exited summary where pre=post
// TODO: change impurity to track exit as impure
void exit_impure_FN() {
System.exit(1);
}
// In pulse, we get Exited summary where pre=post
void modify_exit_impure(int[] a) {
a[0] = 0;
System.exit(1);
}
// We get no pulse summary, hence consider this as impure
void while_true_impure() {
while (true) {}
}
}