blob: 407e996a124d5abd260fa16d33e7728d68df5361 [file]
/* { dg-additional-options "-Wno-compare-distinct-pointer-types" { target c } } */
#include "analyzer-decls.h"
const void *
hide_from_optimizer (void *ptr) __attribute__((noinline));
const void *
hide_from_optimizer (void *ptr)
{
return ptr;
}
unsigned char global_buf[1024];
void
test_pointer_ge (unsigned *p, int i, int j)
{
unsigned char local_declared_before_local_buf;
unsigned char local_buf[16];
unsigned char local_declared_after_local_buf;
__analyzer_eval (p >= hide_from_optimizer (p)); // { dg-warning "TRUE" }
__analyzer_eval (local_buf >= &local_buf[0]); // { dg-warning "TRUE" }
/* Same concrete base region. */
{
// Same concrete offsets
__analyzer_eval (local_buf >= hide_from_optimizer (&local_buf[0])); // { dg-warning "TRUE" }
// Different concrete offsets
__analyzer_eval (&local_buf[0] >= hide_from_optimizer (&local_buf[1])); // { dg-warning "FALSE" }
__analyzer_eval (&local_buf[1] >= hide_from_optimizer (&local_buf[0])); // { dg-warning "TRUE" }
// Same symbolic offset
__analyzer_eval (&local_buf[i] >= hide_from_optimizer (&local_buf[i])); // { dg-warning "TRUE" }
// Possibly different symbolic offset
{
__analyzer_eval (&local_buf[i] >= hide_from_optimizer (&local_buf[j])); // { dg-warning "UNKNOWN" }
if (i == j)
{
__analyzer_eval (&local_buf[i] >= hide_from_optimizer (&local_buf[j])); // { dg-warning "TRUE" "ideal behavior" { xfail *-*-* } }
// { dg-message "UNKNOWN" "current behavior" { target *-*-* } .-1 }
}
else
{
__analyzer_eval (&local_buf[i] >= hide_from_optimizer (&local_buf[j])); // { dg-warning "UNKNOWN" }
}
}
}
/* Different concrete base regions. */
{
__analyzer_eval (local_buf >= hide_from_optimizer (global_buf)); // { dg-warning "UNKNOWN" }
// We can't compare the addresses of locals
__analyzer_eval (&local_buf[0] >= hide_from_optimizer (&local_declared_before_local_buf)); // { dg-warning "UNKNOWN" }
__analyzer_eval (&local_buf[15] >= hide_from_optimizer (&local_declared_after_local_buf)); // { dg-warning "UNKNOWN" }
}
/* Concrete vs symbolic where we know they're different
(buf is local, so param p can't point to it). */
__analyzer_eval (local_buf >= hide_from_optimizer (p)); // { dg-warning "UNKNOWN" "ideal behavior" { xfail *-*-* } }
// { dg-message "FALSE" "current behavior" { target *-*-* } .-1 }
/* Concrete vs symbolic where we don't know they're different
(glob is global, so param p could point to it). */
__analyzer_eval (global_buf >= hide_from_optimizer (p)); // { dg-warning "UNKNOWN" }
// What about symbolic, could different offsets be the same?
// TODO: what about overflow of locals, to try to alias (undefined behavior)
}