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.
180 lines
4.1 KiB
180 lines
4.1 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.
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
|
|
struct delicious {
|
|
int yum;
|
|
int* ptr;
|
|
};
|
|
|
|
struct delicious* bake(struct delicious** cake) {
|
|
int* zero = NULL;
|
|
*zero = 3;
|
|
return NULL;
|
|
}
|
|
|
|
struct delicious* skip_function_with_no_spec(void) {
|
|
struct delicious* cake = NULL;
|
|
int i;
|
|
|
|
if (bake(&cake) == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
i = cake->yum;
|
|
return cake;
|
|
}
|
|
|
|
extern struct delicious* bakery(struct delicious** cake);
|
|
extern struct delicious* bakery2(struct delicious** cake,
|
|
struct delicious** pie);
|
|
extern struct delicious* returnPassByRef();
|
|
extern void skip(struct delicious* s);
|
|
|
|
struct delicious* skip_external_function(void) {
|
|
struct delicious* cake = NULL;
|
|
int i;
|
|
|
|
if (bakery(&cake) == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
i = cake->yum;
|
|
return cake;
|
|
}
|
|
|
|
void by_ref_actual_already_in_footprint(struct delicious* param) {
|
|
int i;
|
|
struct delicious* ret = bakery(¶m);
|
|
i = param->yum;
|
|
}
|
|
|
|
void call_by_ref_actual_already_in_footprint_ok() {
|
|
by_ref_actual_already_in_footprint(NULL); // should not report a warning
|
|
}
|
|
|
|
void by_ref_actual_already_in_footprint2(struct delicious* param) {
|
|
int i;
|
|
i = param->yum; // should not report a warning
|
|
struct delicious* ret = bakery(¶m);
|
|
i = param->yum; // should not report a warning
|
|
}
|
|
|
|
void call_by_ref_actual_already_in_footprint_bad() {
|
|
by_ref_actual_already_in_footprint2(NULL); // should report a warning
|
|
}
|
|
|
|
void passByRefTwice() {
|
|
struct delicious* param;
|
|
bakery2(¶m, ¶m); // should not report a warning
|
|
int i = param->yum;
|
|
}
|
|
|
|
struct delicious* returnPassByRef2() {
|
|
struct delicious* param = NULL;
|
|
bakery(¶m);
|
|
int i = param->yum; // should not report a warning
|
|
return param;
|
|
}
|
|
|
|
void returnPassByRefDeref() {
|
|
struct delicious* ret = returnPassByRef();
|
|
ret->yum = 2; // should not report a warning
|
|
free(ret);
|
|
}
|
|
|
|
extern void struct_ptr_skip(struct delicious* s);
|
|
|
|
extern void struct_val_skip(struct delicious s);
|
|
|
|
int passStructByRefDeref() {
|
|
struct delicious d;
|
|
d.yum = 7;
|
|
struct_ptr_skip(&d);
|
|
return 1 / d.yum; // should not report divide by zero warning
|
|
}
|
|
|
|
int struct_value_by_ref_pure() {
|
|
struct delicious x;
|
|
struct_ptr_skip(&x);
|
|
return 1 / x.yum; // should not report divide by zero warning
|
|
}
|
|
|
|
int struct_value_by_ref_ptr() {
|
|
struct delicious x;
|
|
struct_ptr_skip(&x);
|
|
return *x.ptr; // should not report null deref warning
|
|
}
|
|
|
|
int struct_value_by_ref_abduce() {
|
|
struct delicious x;
|
|
struct_ptr_skip(&x);
|
|
return 1 / *x.ptr; // shoult not report divide by zero warning
|
|
}
|
|
|
|
int struct_value_by_ref_ptr_write_before() {
|
|
struct delicious x;
|
|
x.ptr = NULL;
|
|
struct_ptr_skip(&x);
|
|
return *x.ptr; // should not report null deref warning
|
|
}
|
|
|
|
int struct_value_by_ref_ptr_write() {
|
|
struct delicious x;
|
|
struct_ptr_skip(&x);
|
|
x.ptr = NULL;
|
|
return *x.ptr; // should report null deref warning
|
|
}
|
|
|
|
void setF(struct delicious* x, int val) { x->ptr = val; }
|
|
|
|
int struct_value_by_ref_callee_write_no_skip() {
|
|
struct delicious x;
|
|
setF(&x, NULL);
|
|
return *x.ptr; // should report null deref warning
|
|
}
|
|
|
|
int struct_value_by_ref_callee_write_skip() {
|
|
struct delicious x;
|
|
struct_ptr_skip(&x);
|
|
setF(&x, NULL);
|
|
return *x.ptr; // should report null deref warning
|
|
}
|
|
|
|
int struct_value_by_ref_write_then_skip() {
|
|
struct delicious x;
|
|
x.ptr = NULL;
|
|
struct_ptr_skip(&x);
|
|
return *x.ptr; // should not report null deref warning
|
|
}
|
|
|
|
int struct_value_skip_null_deref() {
|
|
struct delicious x;
|
|
x.ptr = NULL;
|
|
struct_val_skip(x);
|
|
return *x.ptr; // should report null deref warning
|
|
}
|
|
|
|
int struct_value_skip_ok() {
|
|
struct delicious x;
|
|
x.yum = 7;
|
|
struct_val_skip(x);
|
|
return 1 / x.yum; // should not report div by zero warning
|
|
}
|
|
|
|
int struct_value_from_pointer_skip_ok(struct delicious* x) {
|
|
struct_val_skip(*x);
|
|
return 1 / x->yum; // should not report div by zero warning
|
|
}
|
|
|
|
int struct_value_from_pointer_skip_bad(struct delicious* x) {
|
|
x->ptr = NULL;
|
|
struct_val_skip(*x);
|
|
return 1 / *x->ptr; // should report null deref warning
|
|
}
|