blob: 908d99981a62b99cc4d1fe76d65b6c85b315842f [file] [log] [blame]
/* { dg-require-effective-target alloca } */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#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;
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;
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" } */
// TODO: some kind of warning for the out-of-bounds access
}
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;
/* Compare two uninitialized locals. */
__analyzer_eval (i == j); /* { dg-warning "UNKNOWN" "unknown " } */
/* { dg-warning "use of uninitialized value 'i'" "uninit i" { target *-*-* } .-1 } */
/* { dg-warning "use of uninitialized value 'j'" "uninit j" { target *-*-* } .-2 } */
}
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 "UNKNOWN" } */
// TODO: make this be 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];
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" "unknown" } */
/* { dg-warning "use of uninitialized value 'p\\\[10\\\].x'" "uninit" { target *-*-* } .-1 } */
__analyzer_eval (p[10].y == 0); /* { dg-warning "UNKNOWN" "unknown" } */
/* { dg-warning "use of uninitialized value 'p\\\[10\\\].y'" "uninit" { target *-*-* } .-1 } */
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_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" } */
__analyzer_eval (p[10].x == 0); /* { dg-warning "UNKNOWN" "unknown" } */
/* { dg-warning "use of uninitialized value '\\*p\\\[10\\\].x'" "uninit" { target *-*-* } .-1 } */
__analyzer_eval (p[10].y == 0); /* { dg-warning "UNKNOWN" "unknown" } */
/* { dg-warning "use of uninitialized value '\\*p\\\[10\\\].y'" "uninit" { target *-*-* } .-1 } */
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_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;
return *ptr; /* { dg-warning "use of uninitialized value 'ptr'" } */
}
/* Write through uninitialized pointer. */
void test_37a (int i)
{
int *ptr;
*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);
}