/* { dg-require-effective-target alloca } */ /* { dg-additional-options "-fno-ipa-modref" } */ #include #include #include #include "analyzer-decls.h" struct foo { int i; }; /* Fields of a local. */ void test_1 (void) { struct foo f; f.i = 1; __analyzer_eval (f.i == 1); /* { dg-warning "TRUE" } */ } /* Fields of a param. */ void test_2 (struct foo f) { __analyzer_eval (f.i == 2); /* { dg-warning "UNKNOWN" } */ f.i = 2; __analyzer_eval (f.i == 2); /* { dg-warning "TRUE" } */ } /* Fields of a param ptr. */ void test_3 (struct foo *f) { __analyzer_eval (f->i == 3); /* { dg-warning "UNKNOWN" } */ f->i = 3; __analyzer_eval (f->i == 3); /* { dg-warning "TRUE" } */ } /* Fields of a global ptr. */ struct foo *global_foo_ptr; void test_3a (void) { struct foo *tmp = global_foo_ptr; __analyzer_eval (global_foo_ptr->i == 3); /* { dg-warning "UNKNOWN" } */ global_foo_ptr->i = 3; __analyzer_eval (global_foo_ptr->i == 3); /* { dg-warning "TRUE" } */ } /* Pointer to a local. */ void test_4 (void) { int i; int *p = &i; i = 1; *p = 2; __analyzer_eval (i == 2); /* { dg-warning "TRUE" } */ } /* Local array. */ void test_5 (void) { int a[10]; a[3] = 5; /* ARRAY_REF. */ __analyzer_eval (a[3] == 5); /* { dg-warning "TRUE" } */ } /* Local array, but using an unknown index. */ void test_5a (int idx) { int a[10]; a[idx] = 5; /* ARRAY_REF. */ __analyzer_eval (a[idx] == 5); /* { dg-warning "TRUE" } */ } /* Array passed in as a param. */ void test_6 (int a[10]) { /* POINTER_PLUS_EXPR then a MEM_REF. */ __analyzer_eval (a[3] == 42); /* { dg-warning "UNKNOWN" } */ a[3] = 42; __analyzer_eval (a[3] == 42); /* { dg-warning "TRUE" } */ } /* Array passed in as a param ptr. */ void test_7 (int *a) { __analyzer_eval (a[3] == 42); /* { dg-warning "UNKNOWN" } */ a[3] = 42; __analyzer_eval (a[3] == 42); /* { dg-warning "TRUE" } */ } /* Globals. */ int glob_a; void test_10 (void) { __analyzer_eval (glob_a == 42); /* { dg-warning "UNKNOWN" } */ glob_a = 42; __analyzer_eval (glob_a == 42); /* { dg-warning "TRUE" } */ } /* malloc. */ void test_11 (void) { void *p = malloc (256); void *q = malloc (256); /* malloc results should be unique. */ __analyzer_eval (p == q); /* { dg-warning "FALSE" } */ __analyzer_eval (p != q); /* { dg-warning "TRUE" } */ __analyzer_eval (p <= q); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (p >= q); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (p < q); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (p > q); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (p == p); /* { dg-warning "TRUE" } */ __analyzer_eval (p != p); /* { dg-warning "FALSE" } */ __analyzer_eval (p <= p); /* { dg-warning "TRUE" } */ __analyzer_eval (p >= p); /* { dg-warning "TRUE" } */ __analyzer_eval (p < p); /* { dg-warning "FALSE" } */ __analyzer_eval (p > p); /* { dg-warning "FALSE" } */ free (p); free (q); // TODO: mark freed memory as freed //__analyzer_break (); } /* alloca. */ int test_12 (void) { void *p = __builtin_alloca (256); void *q = __builtin_alloca (256); /* alloca results should be unique. */ __analyzer_eval (p == q); /* { dg-warning "FALSE" } */ return *(int *)p; /* { dg-warning "use of uninitialized value '\\*\\(int \\*\\)p" } */ } /* Use of uninit value. */ int test_12a (void) { int i; /* { dg-message "region created on stack here" } */ return i; /* { dg-warning "use of uninitialized value 'i'" } */ } void test_12b (void *p, void *q) { __analyzer_eval (p == q); /* { dg-warning "UNKNOWN" } */ } int test_12c (void) { int i; /* { dg-message "region created on stack here" } */ int j; j = i; /* { dg-warning "use of uninitialized value 'i'" } */ /* We should not emit followup warnings after the first warning about an uninitialized value. */ return j; /* { dg-bogus "use of uninitialized value" } */ } struct coord { long x; long y; }; int test_12d (struct coord c) { struct coord d; d = c; __analyzer_eval (d.x == c.x); /* { dg-warning "TRUE" } */ __analyzer_eval (d.y == c.y); /* { dg-warning "TRUE" } */ __analyzer_eval (d.x == d.y); /* { dg-warning "UNKNOWN" } */ /* d and c share an unknown value of type "struct coord". But d.x and d.y should be different unknown values (although they inherit from d's region). */ } /* Nested structs. */ struct outer { struct middle { struct inner { float f; } in; } mid; }; void test_13 (struct outer *o) { __analyzer_eval (o->mid.in.f == 0.f); /* { dg-warning "UNKNOWN" } */ o->mid.in.f = 0.f; __analyzer_eval (o->mid.in.f == 0.f); /* { dg-warning "TRUE" } */ } void test_14 (struct outer o) { __analyzer_eval (o.mid.in.f == 0.f); /* { dg-warning "UNKNOWN" } */ o.mid.in.f = 0.f; __analyzer_eval (o.mid.in.f == 0.f); /* { dg-warning "TRUE" } */ } void test_15 (const char *str) { char ch = str[0]; __analyzer_eval (ch == 'a'); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (ch == str[0]); /* { dg-warning "TRUE" } */ ch = 'a'; __analyzer_eval (ch == 'a'); /* { dg-warning "TRUE" } */ __analyzer_eval (str[0] == 'a'); /* { dg-warning "UNKNOWN" } */ } void test_16 (void) { const char *msg = "hello world"; __analyzer_eval (msg != NULL); /* { dg-warning "TRUE" } */ __analyzer_eval (msg[0] == 'h'); /* { dg-warning "TRUE" } */ __analyzer_eval (msg[1] == 'e'); /* { dg-warning "TRUE" } */ __analyzer_eval (strlen (msg) == 11); /* { dg-warning "TRUE" } */ /* Out-of-bounds. */ __analyzer_eval (msg[100] == 'e'); /* { dg-warning "UNKNOWN" "eval result" } */ /* { dg-warning "buffer over-read" "out-of-bounds" { target *-*-* } .-1 } */ } static const char *__attribute__((noinline)) get_hello_world (void) { return "hello world"; } void test_16_alt (void) { const char *msg = get_hello_world (); __analyzer_eval (msg != NULL); /* { dg-warning "TRUE" } */ __analyzer_eval (msg[0] == 'h'); /* { dg-warning "TRUE" } */ __analyzer_eval (msg[1] == 'e'); /* { dg-warning "TRUE" } */ __analyzer_eval (strlen (msg) == 11); /* { dg-warning "TRUE" } */ } void test_16a (const char *msg) { __analyzer_eval (strlen (msg) == 11); /* { dg-warning "UNKNOWN" } */ } void test_16b (const char *msg) { __analyzer_eval (strlen (msg) == strlen (msg)); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */ /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */ // TODO(xfail) } extern int unknown_result (void); void test_16c (int i) { int j; j = i; __analyzer_eval (j == i); /* { dg-warning "TRUE" } */ j = unknown_result (); __analyzer_eval (j == i); /* { dg-warning "UNKNOWN" } */ } void test_16c_a (void) { int i, j; i = unknown_result (); j = unknown_result (); __analyzer_eval (i == j); /* { dg-warning "UNKNOWN" } */ } int global_int_16d; void test_16d (int i) { global_int_16d = i; __analyzer_eval (global_int_16d == i); /* { dg-warning "TRUE" } */ global_int_16d = unknown_result (); __analyzer_eval (global_int_16d == i); /* { dg-warning "UNKNOWN" } */ } extern void might_write_to (int *); void test_16e (int i) { int j; j = i; __analyzer_eval (j == i); /* { dg-warning "TRUE" } */ might_write_to (&j); __analyzer_eval (j == i); /* { dg-warning "UNKNOWN" } */ } void test_17 (int i) { int j = 42; __analyzer_eval (j == 42); /* { dg-warning "TRUE" } */ __analyzer_eval (i == j); /* { dg-warning "UNKNOWN" } */ i = j; __analyzer_eval (i == j); /* { dg-warning "TRUE" } */ } void test_18 (int i) { int j; __analyzer_eval (i == 42); /* { dg-warning "UNKNOWN" } */ j = i; __analyzer_eval (i == j); /* { dg-warning "TRUE" } */ __analyzer_eval (i >= j); /* { dg-warning "TRUE" } */ __analyzer_eval (i <= j); /* { dg-warning "TRUE" } */ __analyzer_eval (i != j); /* { dg-warning "FALSE" } */ __analyzer_eval (i > j); /* { dg-warning "FALSE" } */ __analyzer_eval (i < j); /* { dg-warning "FALSE" } */ } void test_19 (void) { int i, j; /* { dg-message "region created on stack here" } */ /* Compare two uninitialized locals. */ __analyzer_eval (i == j); /* { dg-warning "use of uninitialized value 'i'" "uninit i" } */ /* { dg-warning "use of uninitialized value 'j'" "uninit j" { target *-*-* } .-1 } */ } void test_20 (int i, int j) { __analyzer_eval (i + 1); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i + j); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i - 1); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i - j); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i * 2); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i * j); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i / 2); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i / j); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i % 2); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i % j); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i & 1); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i & j); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i | 1); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i | j); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i ^ 1); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i ^ j); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i >> 1); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i >> j); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i << 1); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i << j); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i && 0); /* { dg-warning "FALSE" } */ __analyzer_eval (i && 1); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i && j); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i || 0); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i || 1); /* { dg-warning "TRUE" } */ __analyzer_eval (i || j); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (~i); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (-i); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (+i); /* { dg-warning "UNKNOWN" } */ /* Anything added above should be added to the next function also. */ } /* As above, but where the values are known due to the region model, but not known to GCC's regular optimizations (folding and SSA). */ void test_21 (void) { int i, j, zero; int *pi = &i; int *pj = &j; int *pzero = &zero; *pi = 5; *pj = 3; *pzero = 0; __analyzer_eval (i + j == 8); /* { dg-warning "TRUE" } */ __analyzer_eval (i - j == 2); /* { dg-warning "TRUE" } */ __analyzer_eval (i * j == 15); /* { dg-warning "TRUE" } */ __analyzer_eval (i / j == 1); /* { dg-warning "TRUE" } */ __analyzer_eval (i % j == 2); /* { dg-warning "TRUE" } */ /* Division by zero. */ // TODO: should we warn for this? __analyzer_eval (i / zero); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i % zero); /* { dg-warning "UNKNOWN" } */ __analyzer_eval ((i & 1) == (5 & 1)); /* { dg-warning "TRUE" } */ __analyzer_eval ((i & j) == (5 & 3)); /* { dg-warning "TRUE" } */ __analyzer_eval ((i | 1) == (5 | 1)); /* { dg-warning "TRUE" } */ __analyzer_eval ((i | j) == (5 | 3)); /* { dg-warning "TRUE" } */ __analyzer_eval ((i ^ 1) == (5 ^ 1)); /* { dg-warning "TRUE" } */ __analyzer_eval ((i ^ j) == (5 ^ 3)); /* { dg-warning "TRUE" } */ __analyzer_eval ((i >> 1) == (5 >> 1)); /* { dg-warning "TRUE" } */ __analyzer_eval ((i >> j) == (5 >> 3)); /* { dg-warning "TRUE" } */ __analyzer_eval ((i << 1) == (5 << 1)); /* { dg-warning "TRUE" } */ __analyzer_eval ((i << j) == (5 << 3)); /* { dg-warning "TRUE" } */ __analyzer_eval (i && 0); /* { dg-warning "FALSE" } */ __analyzer_eval (i && 1); /* { dg-warning "TRUE" } */ __analyzer_eval (i && j); /* { dg-warning "TRUE" } */ __analyzer_eval (i || 0); /* { dg-warning "TRUE" } */ __analyzer_eval (i || 1); /* { dg-warning "TRUE" } */ __analyzer_eval (i || j); /* { dg-warning "TRUE" } */ __analyzer_eval (~i == ~5); /* { dg-warning "TRUE" } */ __analyzer_eval (-i == -5); /* { dg-warning "TRUE" } */ __analyzer_eval (+i == +5); /* { dg-warning "TRUE" } */ } void test_22 (int i, int j) { __analyzer_eval (i + j == i + j); /* { dg-warning "TRUE" } */ // FIXME: this is getting folded; can we build a non-folded equivalent? } void test_23 (struct foo *f, struct foo *g) { int i, j, k; i = f->i + g->i; j = f->i + g->i; k = f->i * g->i; __analyzer_eval (i == j); /* { dg-warning "TRUE" } */ __analyzer_eval (i == k); /* { dg-warning "UNKNOWN" } */ } void test_24 (struct foo *f) { struct foo g; g.i = 42; __analyzer_eval (g.i == 42); /* { dg-warning "TRUE" } */ /* Overwriting a whole struct should invalidate our knowledge about fields within it. */ g = *f; __analyzer_eval (g.i == 42); /* { dg-warning "UNKNOWN" } */ } void test_25 (struct foo *f) { struct foo g; g.i = 42; f->i = 43; __analyzer_eval (f->i == 43); /* { dg-warning "TRUE" } */ __analyzer_eval (g.i == 42); /* { dg-warning "TRUE" } */ /* Overwriting a whole struct where we know things about the source value should update our knowledge about fields within the dest value. */ g = *f; __analyzer_eval (g.i == 43); /* { dg-warning "TRUE" } */ } void test_26 (struct coord *p, struct coord *q) { p->x = 42; q->y = 17; /* could clobber p->x. */ __analyzer_eval (p->x == 42); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (p->y); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (q->x); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (q->y == 17); /* { dg-warning "TRUE" } */ /* Overwriting a whole struct where we know some things about the source value should update our knowledge about fields within the dest value. */ *p = *q; __analyzer_eval (p->x); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (p->y == 17); /* { dg-warning "TRUE" } */ __analyzer_eval (q->x); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (q->y == 17); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */ /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */ } void test_27 (struct coord *p) { memset (p, 0, sizeof (struct coord)); __analyzer_eval (p->x == 0); /* { dg-warning "TRUE" } */ __analyzer_eval (p->y == 0); /* { dg-warning "TRUE" } */ } void test_28 (struct coord *p) { memset (p, 0, sizeof (struct coord) * 10); __analyzer_eval (p[0].x == 0); /* { dg-warning "TRUE" } */ __analyzer_eval (p[0].y == 0); /* { dg-warning "TRUE" } */ __analyzer_eval (p[9].x == 0); /* { dg-warning "TRUE" } */ __analyzer_eval (p[9].y == 0); /* { dg-warning "TRUE" } */ __analyzer_eval (p[10].x == 0); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (p[10].y == 0); /* { dg-warning "UNKNOWN" } */ } void test_29 (struct coord *p) { struct coord *q; p[0].x = 100024; p[0].y = 100025; p[7].x = 107024; p[7].y = 107025; p[9].x = 109024; p[9].y = 109025; __analyzer_eval (p[0].x == 100024); /* { dg-warning "TRUE" } */ __analyzer_eval (p[0].y == 100025); /* { dg-warning "TRUE" } */ __analyzer_eval (p[7].x == 107024); /* { dg-warning "TRUE" } */ __analyzer_eval (p[7].y == 107025); /* { dg-warning "TRUE" } */ __analyzer_eval (p[9].x == 109024); /* { dg-warning "TRUE" } */ __analyzer_eval (p[9].y == 109025); /* { dg-warning "TRUE" } */ __analyzer_eval (p[10].x == 0); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (p[10].y == 0); /* { dg-warning "UNKNOWN" } */ q = &p[7]; __analyzer_eval (q->x == 107024); /* { dg-warning "TRUE" } */ __analyzer_eval (q->y == 107025); /* { dg-warning "TRUE" } */ __analyzer_eval (q[2].x == 109024); /* { dg-warning "TRUE" } */ __analyzer_eval (q[2].y == 109025); /* { dg-warning "TRUE" } */ q += 2; __analyzer_eval (q->x == 109024); /* { dg-warning "TRUE" } */ __analyzer_eval (q->y == 109025); /* { dg-warning "TRUE" } */ __analyzer_eval (q[-2].x == 107024); /* { dg-warning "TRUE" } */ __analyzer_eval (q[-2].y == 107025); /* { dg-warning "TRUE" } */ q -= 2; __analyzer_eval (q->x == 107024); /* { dg-warning "TRUE" } */ __analyzer_eval (q->y == 107025); /* { dg-warning "TRUE" } */ } void test_29a (struct coord p[]) { struct coord *q; p[0].x = 100024; p[0].y = 100025; p[7].x = 107024; p[7].y = 107025; p[9].x = 109024; p[9].y = 109025; __analyzer_eval (p[0].x == 100024); /* { dg-warning "TRUE" } */ __analyzer_eval (p[0].y == 100025); /* { dg-warning "TRUE" } */ __analyzer_eval (p[7].x == 107024); /* { dg-warning "TRUE" } */ __analyzer_eval (p[7].y == 107025); /* { dg-warning "TRUE" } */ __analyzer_eval (p[9].x == 109024); /* { dg-warning "TRUE" } */ __analyzer_eval (p[9].y == 109025); /* { dg-warning "TRUE" } */ __analyzer_eval (p[10].x == 0); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (p[10].y == 0); /* { dg-warning "UNKNOWN" } */ q = &p[7]; __analyzer_eval (q->x == 107024); /* { dg-warning "TRUE" } */ __analyzer_eval (q->y == 107025); /* { dg-warning "TRUE" } */ __analyzer_eval (q[2].x == 109024); /* { dg-warning "TRUE" } */ __analyzer_eval (q[2].y == 109025); /* { dg-warning "TRUE" } */ q += 2; __analyzer_eval (q->x == 109024); /* { dg-warning "TRUE" } */ __analyzer_eval (q->y == 109025); /* { dg-warning "TRUE" } */ __analyzer_eval (q[-2].x == 107024); /* { dg-warning "TRUE" } */ __analyzer_eval (q[-2].y == 107025); /* { dg-warning "TRUE" } */ q -= 2; __analyzer_eval (q == &p[7]); /* { dg-warning "TRUE" } */ __analyzer_eval (q->x == 107024); /* { dg-warning "TRUE" } */ __analyzer_eval (q->y == 107025); /* { dg-warning "TRUE" } */ } void test_29b (void) { struct coord p[11]; /* { dg-message "region created on stack here" } */ struct coord *q; p[0].x = 100024; p[0].y = 100025; p[7].x = 107024; p[7].y = 107025; p[9].x = 109024; p[9].y = 109025; __analyzer_eval (p[0].x == 100024); /* { dg-warning "TRUE" } */ __analyzer_eval (p[0].y == 100025); /* { dg-warning "TRUE" } */ __analyzer_eval (p[7].x == 107024); /* { dg-warning "TRUE" } */ __analyzer_eval (p[7].y == 107025); /* { dg-warning "TRUE" } */ __analyzer_eval (p[9].x == 109024); /* { dg-warning "TRUE" } */ __analyzer_eval (p[9].y == 109025); /* { dg-warning "TRUE" } */ q = &p[7]; __analyzer_eval (q->x == 107024); /* { dg-warning "TRUE" } */ __analyzer_eval (q->y == 107025); /* { dg-warning "TRUE" } */ __analyzer_eval (q[2].x == 109024); /* { dg-warning "TRUE" } */ __analyzer_eval (q[2].y == 109025); /* { dg-warning "TRUE" } */ q += 2; __analyzer_eval (q->x == 109024); /* { dg-warning "TRUE" } */ __analyzer_eval (q->y == 109025); /* { dg-warning "TRUE" } */ __analyzer_eval (q[-2].x == 107024); /* { dg-warning "TRUE" } */ __analyzer_eval (q[-2].y == 107025); /* { dg-warning "TRUE" } */ q -= 2; __analyzer_eval (q == &p[7]); /* { dg-warning "TRUE" } */ __analyzer_eval (q->x == 107024); /* { dg-warning "TRUE" } */ __analyzer_eval (q->y == 107025); /* { dg-warning "TRUE" } */ __analyzer_eval (p[10].x == 0); /* { dg-warning "use of uninitialized value 'p\\\[10\\\].x'" } */ } void test_29c (int len) { struct coord p[len]; struct coord *q; p[0].x = 100024; p[0].y = 100025; p[7].x = 107024; p[7].y = 107025; p[9].x = 109024; p[9].y = 109025; __analyzer_eval (p[0].x == 100024); /* { dg-warning "TRUE" } */ __analyzer_eval (p[0].y == 100025); /* { dg-warning "TRUE" } */ __analyzer_eval (p[7].x == 107024); /* { dg-warning "TRUE" } */ __analyzer_eval (p[7].y == 107025); /* { dg-warning "TRUE" } */ __analyzer_eval (p[9].x == 109024); /* { dg-warning "TRUE" } */ __analyzer_eval (p[9].y == 109025); /* { dg-warning "TRUE" } */ q = &p[7]; __analyzer_eval (q->x == 107024); /* { dg-warning "TRUE" } */ __analyzer_eval (q->y == 107025); /* { dg-warning "TRUE" } */ __analyzer_eval (q[2].x == 109024); /* { dg-warning "TRUE" } */ __analyzer_eval (q[2].y == 109025); /* { dg-warning "TRUE" } */ q += 2; __analyzer_eval (q->x == 109024); /* { dg-warning "TRUE" } */ __analyzer_eval (q->y == 109025); /* { dg-warning "TRUE" } */ __analyzer_eval (q[-2].x == 107024); /* { dg-warning "TRUE" } */ __analyzer_eval (q[-2].y == 107025); /* { dg-warning "TRUE" } */ q -= 2; __analyzer_eval (q == &p[7]); /* { dg-warning "TRUE" } */ __analyzer_eval (q->x == 107024); /* { dg-warning "TRUE" } */ __analyzer_eval (q->y == 107025); /* { dg-warning "TRUE" } */ __analyzer_eval (p[10].x == 0); /* { dg-warning "use of uninitialized value '\\*p\\\[10\\\].x'" } */ } void test_30 (void *ptr) { struct coord *p = (struct coord *)ptr; struct coord *q = (struct coord *)ptr; p->x = 42; __analyzer_eval (p->x == 42); /* { dg-warning "TRUE" } */ __analyzer_eval (q->x == 42); /* { dg-warning "TRUE" } */ } void test_31 (unsigned i) { int j, k; j = i < 100 ? i : 100; /* MIN_EXPR. */ k = i < 100 ? 100 : i; /* MAX_EXPR. */ } enum color { RED, GREEN, BLUE }; void test_32 (enum color c) { __analyzer_eval (c == GREEN); /* { dg-warning "UNKNOWN" } */ c = RED; __analyzer_eval (c == RED); /* { dg-warning "TRUE" } */ __analyzer_eval (c == GREEN); /* { dg-warning "FALSE" } */ } void test_33 (void) { static int s; __analyzer_eval (s == 42); /* { dg-warning "UNKNOWN" } */ s = 42; __analyzer_eval (s == 42); /* { dg-warning "TRUE" } */ } static int __attribute__((noinline)) __analyzer_only_called_by_test_34 (int parm) { __analyzer_eval (parm == 42); /* { dg-warning "TRUE" } */ return parm * 2; } void test_34 (void) { int result = __analyzer_only_called_by_test_34 (42); __analyzer_eval (result == 84); /* { dg-warning "TRUE" } */ } void test_35 (int i, int j) { __analyzer_eval (&i == &i); /* { dg-warning "TRUE" } */ __analyzer_eval (&i != &j); /* { dg-warning "TRUE" } */ } static void __attribute__((noinline)) write_through_ptr (int *dst, int val) { *dst = val; } void test_36 (int i) { __analyzer_eval (i == 42); /* { dg-warning "UNKNOWN" } */ write_through_ptr (&i, 42); __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */ } /* Read through uninitialized pointer. */ int test_37 (void) { int *ptr; /* { dg-message "region created on stack here" } */ return *ptr; /* { dg-warning "use of uninitialized value 'ptr'" } */ } /* Write through uninitialized pointer. */ void test_37a (int i) { int *ptr; /* { dg-message "region created on stack here" } */ *ptr = i; /* { dg-warning "use of uninitialized value 'ptr'" } */ } // TODO: the various other ptr deref poisonings /* Read through NULL pointer. */ int test_38 (void) { int *ptr = NULL; return *ptr; /* { dg-warning "dereference of NULL 'ptr'" } */ } /* Write through NULL pointer. */ int test_38a (int i) { int *ptr = NULL; *ptr = i; /* { dg-warning "dereference of NULL 'ptr'" } */ } /* Read through non-NULL constant pointer. */ int test_39 (void) { int *ptr = (int *)0x1000; return *ptr; } int test_40 (int flag) { int i; if (flag) i = 43; else i = 17; /* With state-merging, we lose the relationship between 'flag' and 'i'. */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ if (flag) __analyzer_eval (i == 43); /* { dg-warning "UNKNOWN" } */ else __analyzer_eval (i == 17); /* { dg-warning "UNKNOWN" } */ } struct link { struct link *next; int f; }; /* Traversing a singly-linked list. */ void foo (struct link *in) { struct link a; struct link b; struct link c; a.next = &b; b.next = &c; in->next = &a; c.f = 42; __analyzer_eval (in->next->next->next->f == 42); /* { dg-warning "TRUE" } */ } union u { int i; int *ptr; }; void test_41 (void) { union u u; u.i = 42; __analyzer_eval (u.i == 42); /* { dg-warning "TRUE" } */ __analyzer_eval (u.ptr == NULL); /* { dg-warning "UNKNOWN|FALSE" } */ /* Writes to a union member should invalidate knowledge about other members. */ u.ptr = NULL; __analyzer_eval (u.ptr == NULL); /* { dg-warning "TRUE" } */ __analyzer_eval (u.i == 42); /* { dg-warning "UNKNOWN|FALSE" } */ } void test_42 (void) { int i; float f; i = 42; f = i; __analyzer_eval (f == 42.0); /* { dg-warning "TRUE" } */ } void test_43 (void) { int i; float f; f = 42.0f; i = f; __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */ } struct sbits { signed int b0 : 1; signed int b123 : 3; signed int b456 : 3; signed int b7 : 1; }; void test_44 (void) { struct sbits bits; bits.b0 = -1; __analyzer_eval (bits.b0 == -1); /* { dg-warning "TRUE" } */ bits.b456 = -4; __analyzer_eval (bits.b456 == -4); /* { dg-warning "TRUE" } */ }; struct ubits { unsigned int b0 : 1; unsigned int b123 : 3; unsigned int b456 : 3; unsigned int b7 : 1; }; void test_45 (void) { struct ubits bits; bits.b0 = 1; __analyzer_eval (bits.b0 == 1); /* { dg-warning "TRUE" } */ bits.b456 = 5; __analyzer_eval (bits.b456 == 5); /* { dg-warning "TRUE" } */ }; extern const char *char_ptr; int test_46 (void) { if (strcmp("literal", char_ptr)) return 1; return 0; } char test_47 (void) { static const char* my_version = "1.1.3"; return my_version[0]; } unsigned test_48 (unsigned char *p, unsigned char *q) { return (unsigned int)(p - q); } typedef struct { const char *filename; short lineno; } loc; static loc loc_last; void test_49 (void) { loc_last = __extension__(loc) { "", 328 }; loc_last = __extension__(loc) { "", 333 }; } void test_50 (void *p, void *q) { __analyzer_eval (p == q); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (p == p); /* { dg-warning "TRUE" } */ __analyzer_eval (q == q); /* { dg-warning "TRUE" } */ __analyzer_eval (p == (struct coord *)p); /* { dg-warning "TRUE" } */ __analyzer_eval (p == (const struct coord *)p); /* { dg-warning "TRUE" } */ struct coord *cp = (struct coord *)p; __analyzer_eval (p == cp); /* { dg-warning "TRUE" } */ struct coord *cq = (struct coord *)q; __analyzer_eval (q == cq); /* { dg-warning "TRUE" } */ __analyzer_eval (cp == cq); /* { dg-warning "UNKNOWN" } */ } void test_51 (struct coord c) { struct coord d; memcpy (&d, &c, sizeof (struct coord)); __analyzer_eval (c.x == d.x); /* { dg-warning "TRUE" } */ __analyzer_eval (c.y == d.y); /* { dg-warning "TRUE" } */ } struct big { int ia[1024]; }; void test_52 (struct big b) { struct big d; memcpy (&d, &b, sizeof (struct big)); __analyzer_eval (b.ia[0] == d.ia[0]); /* { dg-warning "TRUE" } */ __analyzer_eval (b.ia[1023] == d.ia[1023]); /* { dg-warning "TRUE" } */ } void test_53 (const char *msg) { (void)fprintf(stderr, "LOG: %s", msg); }