Reviewed By: mbouaziz Differential Revision: D14437821 fbshipit-source-id: 4b5f761b2master
parent
67b42bf021
commit
b537685fc2
@ -0,0 +1,13 @@
|
|||||||
|
# Copyright (c) 2019-present, Facebook, Inc.
|
||||||
|
#
|
||||||
|
# This source code is licensed under the MIT license found in the
|
||||||
|
# LICENSE file in the root directory of this source tree.
|
||||||
|
TESTS_DIR = ../../..
|
||||||
|
|
||||||
|
CLANG_OPTIONS = -c
|
||||||
|
INFER_OPTIONS = -F --project-root $(TESTS_DIR) --purity-only --function-pointer-specialization
|
||||||
|
INFERPRINT_OPTIONS = --issues-tests
|
||||||
|
|
||||||
|
SOURCES = $(wildcard *.c)
|
||||||
|
|
||||||
|
include $(TESTS_DIR)/clang.make
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-present, Facebook, Inc.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
void swap_bad(int* array, int i, int j) {
|
||||||
|
int tmp = array[i];
|
||||||
|
array[i] = array[j];
|
||||||
|
array[j] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void alias_mod_bad(int array[], int i, int j) {
|
||||||
|
int* a = array;
|
||||||
|
a[j] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fresh_arr_ok(int size) {
|
||||||
|
int arr[size];
|
||||||
|
for (int i = 0; i < size - 1; i++) {
|
||||||
|
arr[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void call_impure_with_local_ok(int size) {
|
||||||
|
int arr[size];
|
||||||
|
alias_mod_bad(arr, 0, 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
void time_bad() {
|
||||||
|
time_t rawtime;
|
||||||
|
struct tm* timeinfo;
|
||||||
|
|
||||||
|
time(&rawtime);
|
||||||
|
timeinfo = localtime(&rawtime);
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-present, Facebook, Inc.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int global;
|
||||||
|
|
||||||
|
static int s;
|
||||||
|
|
||||||
|
void static_incr_bad() { s += 1; }
|
||||||
|
|
||||||
|
void global_write_bad(int x, int y) { global += x + y; }
|
||||||
|
|
||||||
|
void call_impure_bad(int size) {
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
global_write_bad(i, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int local_write_ok(int x, int y) {
|
||||||
|
int k = x + y;
|
||||||
|
k++;
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calls foo which modifies global var
|
||||||
|
void call_set_bad() { static_incr_bad(); }
|
@ -0,0 +1,6 @@
|
|||||||
|
codetoanalyze/c/purity/array.c, call_impure_with_local_ok, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function call_impure_with_local_ok]
|
||||||
|
codetoanalyze/c/purity/array.c, fresh_arr_ok, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function fresh_arr_ok]
|
||||||
|
codetoanalyze/c/purity/global_test.c, local_write_ok, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function local_write_ok]
|
||||||
|
codetoanalyze/c/purity/struct.c, set_fresh_ok, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function set_fresh_ok]
|
||||||
|
codetoanalyze/c/purity/struct.c, set_fresh_primitive_ok, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function set_fresh_primitive_ok]
|
||||||
|
codetoanalyze/c/purity/struct.c, variable_init_ok, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function variable_init_ok]
|
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-present, Facebook, Inc.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
int i;
|
||||||
|
} Foo;
|
||||||
|
|
||||||
|
static int variable_init_ok(const int* x) {
|
||||||
|
const Foo* foo = (const Foo*)x;
|
||||||
|
return foo->i;
|
||||||
|
}
|
||||||
|
|
||||||
|
Foo* variable_init_bad(const int* x) {
|
||||||
|
Foo* foo = (const Foo*)x; // aliasing to x
|
||||||
|
foo->i = 0;
|
||||||
|
return foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_fresh_ok() {
|
||||||
|
Foo* foo = {0};
|
||||||
|
foo->i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_fresh_primitive_ok(int x) {
|
||||||
|
Foo* foo = {x};
|
||||||
|
foo->i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_alias_primitive_bad(int* x) {
|
||||||
|
Foo* foo = {x};
|
||||||
|
foo->i = 0;
|
||||||
|
}
|
Loading…
Reference in new issue