mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-17 05:26:47 +00:00
145 lines
3.2 KiB
C
145 lines
3.2 KiB
C
// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -verify %s
|
|
|
|
extern void __assert_fail (__const char *__assertion, __const char *__file,
|
|
unsigned int __line, __const char *__function)
|
|
__attribute__ ((__noreturn__));
|
|
|
|
#define assert(expr) \
|
|
((expr) ? (void)(0) : __assert_fail (#expr, __FILE__, __LINE__, __func__))
|
|
|
|
typedef unsigned long long uintptr_t;
|
|
|
|
void f0(void) {
|
|
int *p = (int*) 0x10000; // Should not crash here.
|
|
*p = 3; // expected-warning{{Dereference of a fixed address}}
|
|
}
|
|
|
|
void f1(int *p) {
|
|
if (p != (int *)-1)
|
|
*p = 1;
|
|
else
|
|
*p = 0; // expected-warning{{Dereference of a fixed address}}
|
|
}
|
|
|
|
struct f2_struct {
|
|
int x;
|
|
};
|
|
|
|
int f2(struct f2_struct* p) {
|
|
|
|
if (p != (struct f2_struct *)1)
|
|
p->x = 1;
|
|
|
|
return p->x++; // expected-warning{{Access to field 'x' results in a dereference of a fixed address (loaded from variable 'p')}}
|
|
}
|
|
|
|
int f3_1(char* x) {
|
|
int i = 2;
|
|
|
|
if (x != (char *)1)
|
|
return x[i - 1];
|
|
|
|
return x[i+1]; // expected-warning{{Array access (from variable 'x') results in a dereference of a fixed address}}
|
|
}
|
|
|
|
int f3_2(char* x) {
|
|
int i = 2;
|
|
|
|
if (x != (char *)1)
|
|
return x[i - 1];
|
|
|
|
return x[i+1]++; // expected-warning{{Array access (from variable 'x') results in a dereference of a fixed address}}
|
|
}
|
|
|
|
int f4_1(int *p) {
|
|
uintptr_t x = (uintptr_t) p;
|
|
|
|
if (x != (uintptr_t)1)
|
|
return 1;
|
|
|
|
int *q = (int*) x;
|
|
return *q; // expected-warning{{Dereference of a fixed address (loaded from variable 'q')}}
|
|
}
|
|
|
|
int f4_2(void) {
|
|
short array[2];
|
|
uintptr_t x = (uintptr_t)array;
|
|
short *p = (short *)x;
|
|
|
|
// The following branch should be infeasible.
|
|
if (!(p == &array[0])) {
|
|
p = (short *)1;
|
|
*p = 1; // no-warning
|
|
}
|
|
|
|
if (p != (short *)1) {
|
|
*p = 5; // no-warning
|
|
p = (short *)1; // expected-warning {{Using a fixed address is not portable}}
|
|
}
|
|
else return 1;
|
|
|
|
*p += 10; // expected-warning{{Dereference of a fixed}}
|
|
return 0;
|
|
}
|
|
|
|
int f5(void) {
|
|
char *s = "hello world";
|
|
return s[0]; // no-warning
|
|
}
|
|
|
|
void f6(int *p, int *q) {
|
|
if (p != (int *)1)
|
|
if (p == (int *)1)
|
|
*p = 1; // no-warning
|
|
|
|
if (q == (int *)1)
|
|
if (q != (int *)1)
|
|
*q = 1; // no-warning
|
|
}
|
|
|
|
int* qux(int);
|
|
|
|
int f7_1(unsigned len) {
|
|
assert (len != 0);
|
|
int *p = (int *)1;
|
|
unsigned i;
|
|
|
|
for (i = 0; i < len; ++i)
|
|
p = qux(i);
|
|
|
|
return *p++; // no-warning
|
|
}
|
|
|
|
int f7_2(unsigned len) {
|
|
assert (len > 0); // note use of '>'
|
|
int *p = (int *)1;
|
|
unsigned i;
|
|
|
|
for (i = 0; i < len; ++i)
|
|
p = qux(i);
|
|
|
|
return *p++; // no-warning
|
|
}
|
|
|
|
struct f8_s {
|
|
int x;
|
|
int y[2];
|
|
};
|
|
|
|
void f8(struct f8_s *s, int coin) {
|
|
if (s != (struct f8_s *)7)
|
|
return;
|
|
|
|
if (coin)
|
|
s->x = 5; // expected-warning{{Access to field 'x' results in a dereference of a fixed address (loaded from variable 's')}}
|
|
else
|
|
s->y[1] = 6; // expected-warning{{Array access (via field 'y') results in a dereference of a fixed address}}
|
|
}
|
|
|
|
void f9() {
|
|
int (*p_function) (char, char) = (int (*)(char, char))0x04040; // FIXME: warn at this initialization
|
|
p_function = (int (*)(char, char))0x04080; // expected-warning {{Using a fixed address is not portable}}
|
|
// FIXME: there should be a warning from calling the function pointer with fixed address
|
|
int x = (*p_function) ('x', 'y');
|
|
}
|