Commit Graph

179 Commits

Author SHA1 Message Date
Michael Tautschnig 4d020ce447 Revert "Use std::forward_list instead of std::map in irept by default"
This reverts commit 2b9849af73.
2019-05-29 23:53:39 +00:00
Michael Tautschnig c4ffbeeb40
Merge pull request #4458 from tautschnig/forward-list
Use std::forward_list instead of std::map in irept by default [blocks: #3486]
2019-05-28 16:01:35 +01:00
Daniel Poetzl 37c3439cdb Return reference from methods that cannot return a nullpointer
Previously some methods returned a pointer but would never return nullptr. This
changes their return type to references instead.
2019-05-23 14:26:14 +01:00
Daniel Poetzl a2f32bffc8 Add new unit tests which check the shape of the map and adapt existing ones
The shape of a sharing map is now different than before, as now leafs can be
directly attached to internal nodes. This adapts the various unit tests that
check that the map has a certain shape.
2019-05-23 14:26:14 +01:00
Daniel Poetzl 8243434515 Unify leaf nodes with internal nodes and container nodes
Previously the leaf nodes were a separate type, and internal nodes and container
nodes were represented by the same type. This changes the representation such
that all nodes are represented by sharing_nodet. This will allow an internal
node to directly point to a leaf node (instead of having to point to a container
node which in turn points to a leaf node).
2019-05-23 12:23:57 +01:00
Michael Tautschnig 2b9849af73 Use std::forward_list instead of std::map in irept by default
This reduces the size of an irept by 5 pointers (i.e., 40 bytes on
64-bit systems). On SV-COMP's ReachSafety-ECA with this change we can
perform 3819.81 symex_step calls per second, compared to 2752.28 calls
per second with the std::map configuration. The performance improvements
are spread across various `irept`-related operations.
2019-05-19 17:03:01 +00:00
Daniel Poetzl 35b91f44e9 Move sharing map unit test sections into more appropriate test cases 2019-05-18 13:55:19 +01:00
Daniel Poetzl d70636d02b Add comment to explain sharing map shape unit tests 2019-05-16 18:34:55 +01:00
Daniel Poetzl f82e08e43d Use plain std::size_t as key in sharing map hash collision unit tests 2019-05-16 16:41:59 +01:00
Daniel Poetzl 13f792e276 Fix bug where an item was not added to the delta view of the sharing map
The bug could appear when there are hash collisions between the keys stored in
the sharing map.
2019-05-16 16:28:20 +01:00
Daniel Poetzl 86c5a3fab6 Sharing map variable height trees
Previously the sharing map was a fixed-height tree (with height 6 by default).
This changes the sharing map to a variable-height tree.
2019-05-15 14:00:51 +01:00
Daniel Poetzl 922adf0576 Small shared n-way pointer
This replaces small_shared_two_way_ptrt with small_shared_n_way_ptrt. The new
shared pointer type allows more than two types for the managed objects. This can
be useful e.g. for implementing graph data structures with sharing where there
are more than two different node types.
2019-05-15 11:14:15 +01:00
Michael Tautschnig 359a063ca2 Fix simplification of pointer-object comparison
1) pointer_object((T1 *)NULL) equals pointer_object((T2 *)NULL) for any
types T1, T2. Previously, this would return false, unless T1==T2.
2) Do not restrict the above to NULL, but instead let the existing logic
in simplify_inequality fully simplify this.
3) Add a unit test of this code, which highlighted further bugs and
limitations: the unit test previously did not set the instance of the
desired dynamic object, and address-of inequalities over dynamic objects
can also be simplified.
2019-05-12 17:45:26 +00:00
Michael Tautschnig 8affad0554 Enable HASH_CODE by default to avoid repeated hash computation
On some SV-COMP benchmark categories, hashing accounts for >20% of CPU
time (with profiling enabled) - top five:

* ReachSafety-BitVectors: 29.29% (470.54 seconds, which reduces to 4.39
  seconds; for benchmarks not timing out we save 170 seconds (25%) in
  non-profiling mode)
* Systems_BusyBox_NoOverflows: 27.98% (284.15 seconds, which reduces to
  1.74 seconds; for the 1 benchmark not timing out we save 23 seconds
  (6%) in non-profiling mode)
* Systems_BusyBox_MemSafety: 24.24% (194.74 seconds, which reduces to
  0.93 seconds; no measurable difference on the 2 benchmarks not
  failing/timing out)
* NoOverflows-Other: 18.84% (1127.61 seconds, which reduces to
  23.57 seconds; for benchmarks not timing out we save 5 seconds (7%) in
  non-profiling mode)
* ReachSafety-ControlFlow: 17.75% (1194.04 seconds, which reduces to
  29.17 seconds; for benchmarks not timing out we save 200 seconds (25%)
  in non-profiling mode)

For ReachSafety-ECA it's only 4.7%, which still amounts to 3006.7
seconds. With this change this reduces to 323.07 seconds. On
ReachSafety-ECA, this enables 3055.35 symex_step calls per second over
2752.28 calls per second without this change.
2019-05-08 15:23:59 +00:00
Chris Smowton ea4ec407f9 Sharing map: don't require a default constructor for mapped_type
Replace the dummy element in its delta views with a pointer + accessor method.
2019-05-03 16:26:12 +01:00
Michael Tautschnig c1baa03b2e Remove redundant string initialisation
Both std::string and dstringt are default-initialised to an empty string.
2019-04-30 22:30:57 +00:00
Daniel Poetzl 4d3cb8c9f5 Add unit test to test iteration over empty sharing map 2019-04-29 11:41:38 +01:00
Daniel Poetzl 2b4f0aed2d Use REQUIRE_THROWS_AS() in sharing map unit tests 2019-04-18 14:37:40 +01:00
Daniel Poetzl 2d29291123 Refactor existing tests of error cases to use cbmc_invariants_should_throwt
This adds sharing map unit tests to check that operations fail as expected. For
example, calling map.replace(key, value) when the key does not exist in the map
should fail.
2019-04-18 14:37:40 +01:00
Daniel Poetzl 94bc97ff31 Add unit tests to check that sharing map modifications do not invalidate views
This adds unit tests to check that the references into the sharing map in the
views and delta views remain valid after operations erase(), insert(), and
replace(). The references should remain valid to those elements that are not
changed by the respective operations.
2019-04-18 14:37:40 +01:00
Daniel Poetzl 2e7f41473d Use existing type sharing_map_error_checkt in sharing map unit test 2019-04-18 14:37:40 +01:00
Daniel Poetzl 9e348b735c Fix sharing map unit tests bug that assumed that irep_idts are lexicographically ordered 2019-04-18 14:37:39 +01:00
Chris Smowton aa9dbefd14 Add sharing_mapt::iterate
This gives a simple const iterator without copying the whole dataset.
2019-04-16 22:20:06 +01:00
Chris Smowton 4b8e92737d Add sharing_mapt::update
This permits an in-place update, avoiding needless copy-out / mutate / move-in cycles for
expensive-to-copy value types without leaking a non-const reference to a value.
2019-04-16 22:20:06 +01:00
Chris Smowton f0de6395e8 Add convenience method sharing_mapt::erase_if_exists
Just saves repeating the if-has-key-then-erase pattern
2019-04-16 21:58:38 +01:00
Chris Smowton 90145061e6 Restore recognition of dynamic objects
These were accidentally disabled when distinguishing ID_is_dynamic_object (a predicate that tests
whether an object is dynamic) from ID_dynamic_object (a reference to the object itself, similar to
symbol_exprt). I also take the opportunity to restore pretty-printing of dynamic object expressions
(while also keeping pretty-printing of the predicate).
2019-04-15 18:03:45 +01:00
Daniel Poetzl b2a548c6a7 Change erase() method of the sharing map to require that the given key exists
Previously when sharing_map.erase(key) was called, two traversals of the path to
the leaf to erase were done. One to check whether the key was in the map, and if
it was, a second one to copy and detach the nodes on the path to the leaf to
erase. This commit changes erase() to require that the given key exists in the
map. This simplifies the implementation and avoids two traversals of the path to
the leaf to erase when it is known that the key exists. If it is not known
whether the key exists, sharing_map.has_key(key) should be explicitely called
first.
2019-04-04 15:41:15 +01:00
Daniel Kroening f43e786cf1 fix compilation with cygwin
The variant of std::ifstream with a wide character file name is only
available when using Visual Studio but not when using Cygwin.
2019-03-31 17:07:53 +01:00
Daniel Poetzl 3872df2941 Disable sharing stats when using msvc to avert msvc crash 2019-03-26 16:51:07 +00:00
Daniel Poetzl a1d7024441 Update unit tests for new sharing map interface 2019-03-26 16:51:07 +00:00
Daniel Poetzl 19d3c5c88e Refactor sharing_node_leaft
Add move constructors and remove unnecessary methods.
2019-03-26 10:28:19 +00:00
Daniel Poetzl 468717f39e Make the shared pointers and write_* methods of the sharing nodes protected
The data member and the write_* methods of sharing_node_innert and
sharing_node_leaft are made protected and existing external callers are
refactored to not use write_* directly.
2019-03-21 11:15:12 +00:00
Daniel Poetzl 2614c5bac9 Add reset() method to small_shared_two_way_ptrt
This adds a reset() method which clears the contents of the shared pointer.
Furthermore, the code to remove a reference to the pointed-to object is factored
out into a method destruct(). The method is used both by the destructor and by
reset().
2019-03-21 10:59:59 +00:00
Michael Tautschnig 4fa790bdc2
Merge pull request #4385 from smowton/smowton/fix/expr-iterator-mutated
Expr-depth-iterator: support iterating over mutated expressions
2019-03-14 20:37:18 +00:00
Chris Smowton 17bee52504 Add unit tests for expr_iterator 2019-03-14 18:09:17 +00:00
Michael Tautschnig 027760b479 Pass irept by value in modifying irept::add/set operations
This should enable use (with performance benefit) of rvalue references in
higher-level APIs.
2019-03-14 15:03:12 +00:00
Romain Brenguier e80340d31a Unit test for ranget drop
This tests that these operations behave as expected and gives examples
on how to use them.
2019-03-08 14:13:53 +00:00
Michael Tautschnig 0a73e03b24 std_expr.h: add/enable missing can_cast, validate_expr
Some were unnecessarily missing, others were wrongly commented out.
2019-03-06 23:25:22 +00:00
Daniel Kroening d285eb8e90 pointer_offset_size functions now use optional
This reminds the user of these functionst that they might return an error.
2019-02-27 11:55:09 +00:00
Daniel Kroening a5944a75a9 numeric_cast_v(expr) now requires constant_expr
This is follow-up from a discussion on PR #3998, and a comment by
@tautschnig.

This function always fails, with an exception, when given anything but a
constant_exprt.

This change means that the caller must do the type conversion.  The benefit
is to make the caller more aware of the requirement that this must be a
constant, and to make the caller handle the error appropriately (with an
user-friendly error message) in case this is not possible.

The disadvantage is additional code at the call site.
2019-02-17 16:27:44 +00:00
Daniel Kroening 93d5278b21 simplify_exprt::bits2expr now returns optionalt<exprt>
This prevents accidental modifications of a nil_exprt.
2019-02-16 19:34:52 +00:00
Hannes Steffenhagen e9ccc27f97 Add string2optional conversion functions
These are intended as helpers for when you want to convert a string to
and integer, but don't want to assert the result (e.g. when dealing with
user input there's usually something better you can do than outright
crashing if the conversion fails), but also don't want to deal with
exceptions (which involve more code to write and read and it's easy to
handle the wrong set of exceptions, whether it is too many or too few).
2019-02-15 12:24:04 +00:00
Michael Tautschnig 2df457856f Avoid deprecated symbol_exprt default construction in unit test
We don't care about either the type or the name in this test, so just use
symbol_exprt::typeless(irep_idt()).
2019-02-05 19:37:34 +00:00
Thomas Spriggs 52e95a6920 Add try_dynamic_cast from rvalue to optional
This commit adds templates for `expr_try_dynamic_cast` and
`type_try_dynamic_cast` where the parameter is an rvalue and the return
type is an `optionalt`. This is implemented by moving the parameter into
the `optionalt`.

Included are unit tests of the new templates, which show that they
return the types and values expected. As well as tests and a static
assert for the existing overloads which show that they still return a
pointer.

These new templates are useful in the case where we are using the
result of a function, which returns by value but only in the case where
the value can be cast to a given type. For example with the new
overloads the following code can be written -
```
exprt enig();
void handle_struct_case(const struct_exprt &struct_expr);

void myFunction()
{
  if(const auto my_struct = expr_try_dynamic_cast<struct_exprt>(enig()))
    handle_struct_case(*my_struct);
}
```
However without the new templates and because the old ones do not bind
to rvalues, an additional temporary variable otherwise would have to be
declared -
```
void myFunction2()
{
  const exprt enigma = enig();
  if(const auto my_struct = expr_try_dynamic_cast<struct_exprt>(enigma))
    handle_struct_case(*my_struct);
}
```
2019-02-05 12:29:03 +00:00
Michael Tautschnig 4cb4bc9653 Cleanup use of messaget in unit tests
Constructing a messaget without a message handler is deprecated. Don't
unnecessarily include iostream, use a (null) message handler instead.
2019-02-03 20:47:19 +00:00
Fotis Koutoulakis f98cbed9e7 Add new join_strings function that applies a function to the elements of the container it flattens
and add tests for it.
2019-02-01 11:28:50 +00:00
Fotis Koutoulakis 14cfc086bd Copy constructor parameter instead of storing reference
Previously we stored a reference to the name_prefix parameter in
allocate objects that led to segfaults if it was constructed with
a temporary. Now we store a copy instead, which prevents that from
happening.
2019-01-31 11:02:49 +00:00
Michael Tautschnig 267094c7eb Replace all uses of deprecated symbol_exprt constructors
This helps type safety has it avoids constructing symbol_exprts that never get a
proper type (or identifier).
2019-01-29 18:23:23 +00:00
Michael Tautschnig d1875dba52
Merge pull request #3965 from tautschnig/vs2013-cleanup
Remove Visual Studio 2013-specific code
2019-01-29 07:06:11 +00:00
Thomas Spriggs 773603cf35 Add support for range to construct json_arrayt and json_objectt
The end result of this commit is that code like the following example
can be used to construct `json_arrayt` / `json_objectt` -
```
const std::vector<std::string> input{"foo", "bar"};
const auto json_array =
make_range(input)
.map(constructor_of<json_stringt>())
.collect<json_arrayt>();
```
This commit includes -
* Constructors from iterators for json_arrayt and json_objectt, so
that the iterators from a range can be used to construct these classes.
* A `collect` member function for `ranget`, so that a chain of range
operations can finish with the construction of a resulting container
containing a collection of the results.
* A `constructor_of` template function, which provides syntactic sugar
when using `map` to call a constructor, compared to writing a new lambda
function each time such an operation is carried out.
* Unit tests covering all of the above functionality.
2019-01-28 17:39:02 +00:00