blob: c9095fa3b94a8ee4c91ecf3be7bc9ba42a76343b [file] [log] [blame]
#include "analyzer-decls.h"
#define NULL ((void *)0)
typedef __SIZE_TYPE__ size_t;
void test_terminated (void)
{
__analyzer_eval (__analyzer_get_strlen ("abc") == 3); /* { dg-warning "TRUE" } */
}
void test_unterminated (void)
{
char buf[3] = "abc";
__analyzer_get_strlen (buf); /* { dg-warning "stack-based buffer over-read" } */
/* { dg-message "out-of-bounds read at byte 3 but 'buf' ends at byte 3" "bad read event" { target *-*-* } .-1 } */
/* { dg-message "while looking for null terminator for argument 1 \\('&buf'\\) of '__analyzer_get_strlen'..." "null terminator event" { target *-*-* } .-2 } */
}
void test_embedded_nuls (void)
{
/* 0123 456 78. */
char buf[9] = "abc\0pq\0xy"; /* unterminated. */
__analyzer_eval (__analyzer_get_strlen (buf) == 3); /* { dg-warning "TRUE" } */
__analyzer_eval (__analyzer_get_strlen (buf + 1) == 2); /* { dg-warning "TRUE" } */
__analyzer_eval (__analyzer_get_strlen (buf + 2) == 1); /* { dg-warning "TRUE" } */
__analyzer_eval (__analyzer_get_strlen (buf + 3) == 0); /* { dg-warning "TRUE" } */
__analyzer_eval (__analyzer_get_strlen (buf + 4) == 2); /* { dg-warning "TRUE" } */
__analyzer_eval (__analyzer_get_strlen (buf + 5) == 1); /* { dg-warning "TRUE" } */
__analyzer_eval (__analyzer_get_strlen (buf + 6) == 0); /* { dg-warning "TRUE" } */
__analyzer_get_strlen (buf + 7); /* { dg-warning "stack-based buffer over-read" } */
/* { dg-message "while looking for null terminator for argument 1 \\('<unknown>'\\) of '__analyzer_get_strlen'..." "event" { target *-*-* } .-1 } */
// TODO: fix the "<unknown>" here?
}
void test_before_start_of_buffer (void)
{
const char *buf = "abc";
__analyzer_get_strlen (buf - 1); /* { dg-warning "buffer under-read" } */
/* { dg-message "while looking for null terminator for argument 1 \\('<unknown>'\\) of '__analyzer_get_strlen'..." "event" { target *-*-* } .-1 } */
// TODO: fix the "<unknown>" here?
}
void test_after_end_of_buffer (void)
{
const char *buf = "abc";
__analyzer_get_strlen (buf + 4); /* { dg-warning "buffer over-read" } */
/* { dg-message "while looking for null terminator for argument 1 \\('<unknown>'\\) of '__analyzer_get_strlen'..." "event" { target *-*-* } .-1 } */
// TODO: fix the "<unknown>" here?
}
void test_fully_initialized_but_unterminated (void)
{
char buf[3];
buf[0] = 'a';
buf[1] = 'b';
buf[2] = 'c';
__analyzer_get_strlen (buf); /* { dg-warning "stack-based buffer over-read" } */
/* { dg-message "while looking for null terminator for argument 1 \\('&buf'\\) of '__analyzer_get_strlen'..." "event" { target *-*-* } .-1 } */
}
void test_uninitialized (void)
{
char buf[16];
__analyzer_get_strlen (buf); /* { dg-warning "use of uninitialized value 'buf\\\[0\\\]'" } */
/* { dg-message "while looking for null terminator for argument 1 \\('&buf'\\) of '__analyzer_get_strlen'..." "event" { target *-*-* } .-1 } */
}
void test_partially_initialized (void)
{
char buf[16];
buf[0] = 'a';
__analyzer_get_strlen (buf); /* { dg-warning "use of uninitialized value 'buf\\\[1\\\]'" } */
/* { dg-message "while looking for null terminator for argument 1 \\('&buf'\\) of '__analyzer_get_strlen'..." "event" { target *-*-* } .-1 } */
}
char *test_dynamic_1 (void)
{
const char *kvstr = "NAME=value";
size_t len = __builtin_strlen (kvstr);
char *ptr = __builtin_malloc (len + 1);
if (!ptr)
return NULL;
__builtin_memcpy (ptr, kvstr, len);
ptr[len] = '\0';
__analyzer_eval (__analyzer_get_strlen (ptr) == 10); /* { dg-warning "UNKNOWN" } */
// TODO: should be TRUE
return ptr;
}
char *test_dynamic_2 (void)
{
const char *kvstr = "NAME=value";
size_t len = __builtin_strlen (kvstr);
char *ptr = __builtin_malloc (len + 1);
if (!ptr)
return NULL;
__builtin_memcpy (ptr, kvstr, len);
/* Missing termination. */
__analyzer_get_strlen (ptr); /* { dg-warning "use of uninitialized value '&buf'" "" { xfail *-*-* } } */
// TODO (xfail)
return ptr;
}
char *test_dynamic_3 (const char *src)
{
size_t len = __builtin_strlen (src);
char *ptr = __builtin_malloc (len + 1);
if (!ptr)
return NULL;
__builtin_memcpy (ptr, src, len);
ptr[len] = '\0';
__analyzer_eval (__analyzer_get_strlen (ptr) == len); /* { dg-warning "UNKNOWN" } */
// TODO: should get TRUE for this
return ptr;
}
char *test_dynamic_4 (const char *src)
{
size_t len = __builtin_strlen (src);
char *ptr = __builtin_malloc (len + 1);
if (!ptr)
return NULL;
__builtin_memcpy (ptr, src, len);
/* Missing termination. */
__analyzer_get_strlen (ptr); /* { dg-warning "use of uninitialized value 'buf\\\[len\\\]'" "" { xfail *-*-* } } */
// TODO (xfail)
return ptr;
}
void test_symbolic_ptr (const char *ptr)
{
__analyzer_describe (0, __analyzer_get_strlen (ptr)); /* { dg-warning "CONJURED" } */
}
void test_symbolic_offset (size_t idx)
{
__analyzer_describe (0, __analyzer_get_strlen ("abc" + idx)); /* { dg-warning "CONJURED" } */
}
void test_casts (void)
{
int i = 42;
const char *p = (const char *)&i;
__analyzer_eval (__analyzer_get_strlen (p) == 0); /* { dg-warning "UNKNOWN" } */
__analyzer_eval (__analyzer_get_strlen (p + 1) == 0); /* { dg-warning "UNKNOWN" } */
}
void test_filled_nonzero (void)
{
char buf[10];
__builtin_memset (buf, 'a', 10);
__analyzer_get_strlen (buf); /* { dg-warning "stack-based buffer over-read" "" { xfail *-*-* } } */
}
void test_filled_zero (void)
{
char buf[10];
__builtin_memset (buf, 0, 10);
__analyzer_eval (__analyzer_get_strlen (buf) == 0); /* { dg-warning "TRUE" "correct" { xfail *-*-* } } */
/* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */
__analyzer_eval (__analyzer_get_strlen (buf + 1) == 0); /* { dg-warning "TRUE" "correct" { xfail *-*-* } } */
/* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */
}
void test_filled_symbolic (int c)
{
char buf[10];
__builtin_memset (buf, c, 10);
__analyzer_eval (__analyzer_get_strlen (buf) == 0); /* { dg-warning "UNKNOWN" } */
}