pp_newline (&pp);
}
+/* Assert that this object is valid. */
+
+void
+binding_map::validate () const
+{
+ const size_t num_concrete = m_concrete.size ();
+ const size_t num_symbolic = m_symbolic.size ();
+
+ /* We shouldn't have more than one symbolic key per cluster
+ (or one would have clobbered the other). */
+ gcc_assert (num_symbolic < 2);
+ /* We can't have both concrete and symbolic keys. */
+ gcc_assert (num_concrete == 0 || num_symbolic == 0);
+
+ /* Check for overlapping concrete bindings. */
+ for (auto iter = m_concrete.begin (); iter != m_concrete.end (); ++iter)
+ {
+ auto next (iter);
+ ++next;
+ if (next != m_concrete.end ())
+ {
+ /* Verify they are in order, and do not overlap. */
+ const bit_range &iter_bits = iter->first;
+ const bit_range &next_bits = next->first;
+ gcc_assert (iter_bits.get_start_bit_offset ()
+ < next_bits.get_start_bit_offset ());
+ gcc_assert (iter_bits.get_last_bit_offset ()
+ < next_bits.get_start_bit_offset ());
+ gcc_assert (iter_bits.get_next_bit_offset ()
+ <= next_bits.get_start_bit_offset ());
+ }
+ }
+}
+
/* Return a new json::object of the form
{KEY_DESC : SVALUE_DESC,
...for the various key/value pairs in this binding_map}. */
void
binding_cluster::validate () const
{
- int num_symbolic = 0;
- int num_concrete = 0;
- for (auto iter : m_map)
- {
- if (iter.m_key->symbolic_p ())
- num_symbolic++;
- else
- num_concrete++;
- }
- /* We shouldn't have more than one symbolic key per cluster
- (or one would have clobbered the other). */
- gcc_assert (num_symbolic < 2);
- /* We can't have both concrete and symbolic keys. */
- gcc_assert (num_concrete == 0 || num_symbolic == 0);
+ m_map.validate ();
}
/* Return a new json::object of the form
out_cluster->m_map.put (key, unknown_sval);
}
+ /* We might now have overlapping concrete clusters in OUT_CLUSTER.
+ Reject such cases. */
+ if (num_concrete_keys > 0)
+ {
+ /* Check for overlapping concrete bindings. */
+ const auto &concrete_bindings
+ = out_cluster->get_map ().get_concrete_bindings ();
+ for (auto iter = concrete_bindings.begin ();
+ iter != concrete_bindings.end (); ++iter)
+ {
+ auto next (iter);
+ ++next;
+ if (next != concrete_bindings.end ())
+ {
+ const bit_range &iter_bits = iter->first;
+ const bit_range &next_bits = next->first;
+ if (iter_bits.intersects_p (next_bits))
+ return false;
+ }
+ }
+ }
+
/* We can only have at most one symbolic key per cluster,
and if we do, we can't have any concrete keys.
If this happens, mark the cluster as touched, with no keys. */
void dump_to_pp (pretty_printer *pp, bool simple, bool multiline) const;
void dump (bool simple) const;
+ void validate () const;
+
std::unique_ptr<json::object> to_json () const;
void add_to_tree_widget (text_art::tree_widget &parent_widget,
svalue_set *maybe_live_values,
bool always_overlap);
+ const concrete_bindings_t &
+ get_concrete_bindings () const { return m_concrete; }
+
private:
void get_overlapping_bindings (const binding_key *key,
auto_vec<const binding_key *> *out);
/* { dg-additional-options "-D_POSIX_SOURCE" } */
/* { dg-skip-if "requires hosted libstdc++ for stdlib malloc" { ! hostedlib } } */
-
+/* { dg-skip-if "C++98 builds hit different limits exploring egraph" { c++98_only } } */
/* A lexical scanner generated by flex */
b->yy_buf_size *= 2;
b->yy_ch_buf = (char *) /* { dg-warning "leak of '\\*b.yy_ch_buf'" "" { xfail *-*-* } } */
- /* { dg-warning "leak of '\\*b.yy_buffer_state::yy_ch_buf'" "" { xfail *-*-* } .-1 } */
+ /* { dg-warning "leak of '\\*b.yy_buffer_state::yy_ch_buf'" "" { target c++ } .-1 } */
/* Include room in for 2 EOB chars. */
yyrealloc( (void *) b->yy_ch_buf,
(yy_size_t) (b->yy_buf_size + 2) );
}
else
/* Can't grow it, we don't own it. */
- b->yy_ch_buf = NULL; /* { dg-bogus "leak" "PR analyzer/103546" } */
+ b->yy_ch_buf = NULL; /* { dg-bogus "leak" "PR analyzer/103546" { xfail c++ } } */
if ( ! b->yy_ch_buf )
YY_FATAL_ERROR(