const svalue *base_sval,
const svalue *iter_sval)
{
+ gcc_assert (base_sval->get_kind () != SK_WIDENING);
+ gcc_assert (iter_sval->get_kind () != SK_WIDENING);
widening_svalue::key_t key (type, point, base_sval, iter_sval);
if (widening_svalue **slot = m_widening_values_map.get (key))
return *slot;
/* The initial value of a pointer can't point to a local. */
return tristate::TS_FALSE;
}
+ if (sval_a->get_kind () == SK_INITIAL
+ && base_reg_b->get_kind () == RK_HEAP_ALLOCATED)
+ {
+ /* The initial value of a pointer can't point to a
+ region that was allocated on the heap after the beginning of the
+ path. */
+ return tristate::TS_FALSE;
+ }
+ if (const widening_svalue *widening_sval_a
+ = sval_a->dyn_cast_widening_svalue ())
+ {
+ const svalue *base = widening_sval_a->get_base_svalue ();
+ if (const region_svalue *region_sval
+ = base->dyn_cast_region_svalue ())
+ {
+ const region *pointee = region_sval->get_pointee ();
+ /* If we have sval_a is WIDENING(®ION, OP), and
+ B can't alias REGION, then B can't alias A either.
+ For example, A might arise from
+ for (ptr = ®ION; ...; ptr++)
+ where sval_a is ptr in the 2nd iteration of the loop.
+ We want to ensure that "*ptr" can only clobber things
+ within REGION's base region. */
+ tristate ts = eval_alias (pointee->get_base_region (),
+ base_reg_b);
+ if (ts.is_false ())
+ return tristate::TS_FALSE;
+ }
+ }
}
return tristate::TS_UNKNOWN;
}
other, this);
}
+ /* Merger of:
+ this: BINOP (X, OP, CST)
+ other: X, where X is non-widening
+ to: WIDENING (other, this). */
+ if (const binop_svalue *binop_sval = dyn_cast_binop_svalue ())
+ if (binop_sval->get_arg0 () == other
+ && binop_sval->get_arg1 ()->get_kind () == SK_CONSTANT
+ && other->get_kind () != SK_WIDENING)
+ return mgr->get_or_create_widening_svalue (other->get_type (),
+ merger->m_point,
+ other, this);
+
/* Merge: (Widen(existing_val, V), existing_val) -> Widen (existing_val, V)
and thus get a fixed point. */
if (const widening_svalue *widen_sval = dyn_cast_widening_svalue ())
{
return widen_arg0;
}
+
+ /* Merger of:
+ this: BINOP(WIDENING(BASE, BINOP(BASE, X)), X)
+ other: BINOP(BASE, X)
+ to: WIDENING(BASE, BINOP(BASE, X)). */
+ if (widen_arg0->get_iter_svalue () == other)
+ if (const binop_svalue *other_binop_sval
+ = other->dyn_cast_binop_svalue ())
+ if (other_binop_sval->get_arg0 () == widen_arg0->get_base_svalue ()
+ && other_binop_sval->get_arg1 () == binop_sval->get_arg1 ())
+ return widen_arg0;
}
return mgr->get_or_create_unknown_svalue (get_type ());
for (i = start; i < end; i++) {
__analyzer_eval (i < end); /* { dg-warning "TRUE" "true" } */
- /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
- /* TODO(xfail^^^): should report TRUE twice. */
__analyzer_eval (i == start); /* { dg-warning "TRUE" "1st" } */
/* { dg-warning "FALSE" "2nd" { xfail *-*-* } .-1 } */
--- /dev/null
+#include <stdlib.h>
+
+typedef short hashNx;
+
+typedef struct hashSt {
+ hashNx *hs_index;
+ int hs_used;
+ int hs_slots;
+} hashSt;
+
+void hashEmpty(hashSt *td);
+
+int hashAlloc(hashSt *td, int slots) {
+ hashNx *index;
+
+ if (slots > td->hs_slots) {
+ if (td->hs_index != NULL)
+ index = realloc(td->hs_index, (size_t)slots * sizeof(hashNx));
+ else
+ index = malloc((size_t)slots * sizeof(hashNx));
+
+ if (index == NULL)
+ return 0;
+
+ td->hs_index = index;
+ td->hs_slots = slots;
+ }
+
+ hashEmpty(td);
+
+ return 1;
+}
+
+void hashEmpty(hashSt *td) {
+ hashNx *index;
+ int slots;
+
+ for (slots = td->hs_slots, index = td->hs_index; --slots >= 0;)
+ *index++ = -1;
+
+ td->hs_used = 0;
+}
--- /dev/null
+#include <stdlib.h>
+
+typedef short hashNx;
+
+typedef struct hashSt {
+ hashNx *hs_index;
+ int hs_used;
+ int hs_slots;
+} hashSt;
+
+int test (hashSt *td, int slots)
+{
+ hashNx *index;
+
+ index = malloc((size_t)slots * sizeof(hashNx));
+ if (index == NULL)
+ return 0;
+ td->hs_index = index;
+ td->hs_slots = slots;
+
+ for (slots = td->hs_slots, index = td->hs_index; --slots >= 0;)
+ *index++ = -1;
+
+ return 1;
+}
while (n--)
{
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enode" } */
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
*p++ = val;
}
while (n--)
{
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enode" } */
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2|3 processed enodes" } */
*p++ = a;
*p++ = b;
}