diff --git a/.gitignore b/.gitignore index edac3d3e326..560bd432c77 100644 --- a/.gitignore +++ b/.gitignore @@ -28,9 +28,16 @@ src/ansi-c/gcc_builtin_headers_alpha.inc src/ansi-c/gcc_builtin_headers_arm.inc src/ansi-c/gcc_builtin_headers_generic.inc src/ansi-c/gcc_builtin_headers_ia32-2.inc +src/ansi-c/gcc_builtin_headers_ia32-3.inc +src/ansi-c/gcc_builtin_headers_ia32-4.inc src/ansi-c/gcc_builtin_headers_ia32.inc +src/ansi-c/gcc_builtin_headers_math.inc +src/ansi-c/gcc_builtin_headers_mem_string.inc +src/ansi-c/gcc_builtin_headers_omp.inc +src/ansi-c/gcc_builtin_headers_tm.inc src/ansi-c/gcc_builtin_headers_mips.inc src/ansi-c/gcc_builtin_headers_power.inc +src/ansi-c/gcc_builtin_headers_ubsan.inc # regression/test files *.out @@ -69,6 +76,10 @@ src/xmllang/xml_lex.yy.cpp src/xmllang/xml_y.output src/xmllang/xml_y.tab.cpp src/xmllang/xml_y.tab.h +src/memory-models/mm_lex.yy.cpp +src/memory-models/mm_y.output +src/memory-models/mm_y.tab.cpp +src/memory-models/mm_y.tab.h # binaries src/cbmc/cbmc @@ -100,3 +111,8 @@ src/ansi-c/library/converter src/ansi-c/library/converter.exe src/util/irep_ids_convert src/util/irep_ids_convert.exe + +*.pyc + +# auto generated documentation +doc/html/ diff --git a/.travis.yml b/.travis.yml index 7375549537b..4683eeba79d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -134,6 +134,15 @@ matrix: script: scripts/travis_lint.sh before_cache: + - env: NAME="DOXYGEN-CHECK" + addons: + apt: + packages: + - doxygen + install: + script: scripts/travis_doxygen.sh + before_cache: + allow_failures: - env: NAME="CPP-LINT" install: @@ -152,9 +161,9 @@ install: script: - if [ -e bin/gcc ] ; then export PATH=$PWD/bin:$PATH ; fi ; - COMMAND="env UBSAN_OPTIONS=print_stacktrace=1 make -C regression test" && + COMMAND="env UBSAN_OPTIONS=print_stacktrace=1 make -C regression test CXX=\"$COMPILER\" CXXFLAGS=\"-Wall -Werror -pedantic -O2 -g $EXTRA_CXXFLAGS\"" && eval ${PRE_COMMAND} ${COMMAND} - - COMMAND="make -C unit CXX=\"$COMPILER\" CXXFLAGS=\"$FLAGS $EXTRA_CXXFLAGS\" -j2" && + - COMMAND="make -C unit CXX=\"$COMPILER\" CXXFLAGS=\"-Wall -Werror -pedantic -O2 -g $EXTRA_CXXFLAGS\" -j2" && eval ${PRE_COMMAND} ${COMMAND} - COMMAND="make -C unit test" && eval ${PRE_COMMAND} ${COMMAND} diff --git a/CHANGELOG b/CHANGELOG index 1718d32243d..e497b1cadc2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -7,6 +7,9 @@ * GOTO-INSTRUMENT: New option --print-path-lenghts * GOTO-ANALYZER: New option --unreachable-functions, --reachable-functions * GOTO-INSTRUMENT: New option --undefined-function-is-assume-false +* GOTO-INSTRUMENT: New option --remove-function-body +* GOTO-INSTRUMENT: New option --use-all-headers, changed --use-system-headers to + --no-system-headers 5.7 diff --git a/CODING_STANDARD b/CODING_STANDARD deleted file mode 100644 index 0d8c44da54c..00000000000 --- a/CODING_STANDARD +++ /dev/null @@ -1,202 +0,0 @@ -Here a few minimalistic coding rules for the CPROVER source tree. - -Whitespaces: -- Use 2 spaces indent, no tabs. -- No lines wider than 80 chars. - - When line is wider, do the following: - - Subsequent lines should be indented two more than the initial line - - Break after = if it is part of an assignment - - For chained calls, prefer immediately before . - - For other operators (e.g. &&, +) prefer immediately after the operator - - For brackets, break after the bracket - - In the case of function calls, put each argument on a separate line if - they do not fit after one line break - - Nested function calls do not need to be broken up into separate lines even - if the outer function call does. -- If a method is bigger than 50 lines, break it into parts. -- Put matching { } into the same column. -- No spaces around operators (=, +, ==, ...) - Exceptions: Spaces around &&, || and << -- Space after comma (parameter lists, argument lists, ...) -- Space after colon inside 'for' -- For pointers and references, the */& should be attached to the variable name - as oppposed to the tyep. E.g. for a pointer to an int the syntax would be: - `int *x;` -- No whitespaces at end of line -- No whitespaces in blank lines -- Put argument lists on next line (and ident 2 spaces) if too long -- Put parameters on separate lines (and ident 2 spaces) if too long -- No whitespaces around colon for inheritance, - put inherited into separate lines in case of multiple inheritance -- The initializer list follows the constructor without a whitespace - around the colon. Break line after the colon if required and indent members. -- if(...), else, for(...), do, and while(...) are always in a separate line -- Break expressions in if, for, while if necessary and align them - with the first character following the opening parenthesis -- Use {} instead of ; for the empty statement -- Single line blocks without { } are allowed, - but put braces around multi-line blocks -- Use blank lines to visually separate logically cohesive code blocks - within a function -- Have a newline at the end of a file - -Comments: -- Do not use /* */ except for file and function comment blocks -- Each source and header file must start with a comment block - stating the Module name and Author [will be changed when we roll out doxygen] -- Each function in the source file (not the header) is preceded - by a function comment header consisting of a comment block stating - Name, Inputs, Outputs and Purpose [will be changed when we roll - out doxygen] - - It should look like this: - ``` - /*******************************************************************\ - - Function: class_namet::function_name - - Inputs: - arg_name - Description of its purpose - long_arg_name - Descriptions should be indented - to match the first line of the - description - - Outputs: A description of what the function returns - - Purpose: A description of what the function does. - Again, indentation with the line above - - \*******************************************************************/ - ``` -- An empty line should appear between the bottom of the function comment header - and the function. -- Put comments on a separate line -- Use comments to explain the non-obvious -- Use #if 0 for commenting out source code -- Use #ifdef DEBUG to guard debug code - -Naming: -- Identifiers may use the characters [a-z0-9_] and should start with a - lower-case letter (parameters in constructors may start with _). -- Use american spelling for identifiers. -- Separate basic words by _ -- Avoid abbreviations (e.g. prefer symbol_table to of st). -- User defined type identifiers have to be terminated by 't'. Moreover, - before 't' may not be '_'. -- Do not use 'm_' prefix nor '_' suffix for names of attributes of structured - types. -- Enum values may use the characters [A-Z0-9_] - -Header files: -- Avoid unnecessary #includes, especially in header files -- Prefer forward declaration to includes, but forward declare at the top - of the header file rather than in line -- Guard headers with #ifndef CPROVER_DIRECTORIES_FILE_H, etc - -Make files -- Each source file should appear on a separate line -- The final source file should still be followed by a trailing slash -- The last line should be a comment to not be deleted, i.e. should look like: -``` -SRC = source_file.cpp \ - source_file2.cpp \ - # Empty last line -``` -- This ensures the Makefiles can be easily merged. - -Program Command Line Options -- Each program contains a program_name_parse_optionst class which should - contain a define PROGRAM_NAME_PARSE_OPTIONS which is a string of all the - parse options in brackets (with a colon after the bracket if it takes a - parameter) -- Each parameter should be one per line to yield easy merging -- If parameters are shared between programs, they should be pulled out into - a common file and then included using a define -- The defines should be OPT_FLAG_NAMES which should go into the OPTIONS define -- The defines should include HELP_FLAG_NAMES which should contain the help - output of the format: - ``` - " --flag explanations\n" \ - " --another flag more explanation\n" \ - <-------30 chars------> -- The defines may include PARSE_OPTIONS_FLAG_NAMES which move the options - from the command line into the options - -C++ features: -- Do not use namespaces. -- Prefer use of 'typedef' insted of 'using'. -- Prefer use of 'class' instead of 'struct'. -- Write type modifiers before the type specifier. -- Make references const whenever possible -- Make functions const whenever possible -- Do not hide base class functions -- You are encouraged to use override -- Single argument constructors must be explicit -- Avoid implicit conversions -- Avoid friend declarations -- Avoid iterators, use ranged for instead -- Avoid allocation with new/delete, use unique_ptr -- Avoid pointers, use references -- Avoid char *, use std::string -- For numbers, use int, unsigned, long, unsigned long, double -- Use mp_integer, not BigInt -- Use the functions in util for conversions between numbers and strings -- Avoid C-style functions. Use classes with an operator() instead. -- Use irep_idt for identifiers (not std::string) -- Avoid destructive updates if possible. The irept has constant time copy. -- Use instances of std::size_t for comparison with return values of .size() of - STL containers and algorithms, and use them as indices to arrays or vectors. -- Do not use default values in public functions -- Use assertions to detect programming errors, e.g. whenever you make - assumptions on how your code is used -- Use exceptions only when the execution of the program has to abort - because of erroneous user input -- We allow to use 3rd-party libraries directly. - No wrapper matching the coding rules is required. - Allowed libraries are: STL. -- When throwing, omit the brackets, i.e. `throw "error"`. -- Error messages should start with a lower case letter. -- Use the auto keyword if and only if one of the following - - The type is explictly repeated on the RHS (e.g. a constructor call) - - Adding the type will increase confusion (e.g. iterators, function pointers) - -Architecture-specific code: -- Avoid if possible. -- Use __LINUX__, __MACH__, and _WIN32 to distinguish the architectures. -- Don't include architecture-specific header files without #ifdef ... - -Output: -- Do not output to cout or cerr directly (except in temporary debug code, - and then guard #include by #ifdef DEBUG) -- Derive from messaget if the class produces output and use the streams provided - (status(), error(), debug(), etc) -- Use '\n' instead of std::endl - -Unit tests: - - Unit tests are written using Catch: https://github.com/philsquared/Catch/ - - For large classes: - - Create a separate file that contains the tests for each method of each - class - - The file should be named according to - `unit/class/path/class_name/function_name.cpp` - - For small classes: - - Create a separate file that contains the tests for all methods of each - class - - The file should be named according to unit/class/path/class_name.cpp - - Catch supports tagging, tests should be tagged with all the following tags: - - [core] should be used for all tests unless the test takes more than 1 - second to run, then it should be tagged with [long] - - [folder_name] of the file being tested - - [class_name] of the class being tested - - [function_name] of the function being tested - -You are allowed to break rules if you have a good reason to do so. - -Pre-commit hook to run cpplint locally --------------------------------------- -To install the hook -cp .githooks/pre-commit .git/hooks/pre-commit -or use a symbolic link. -Then, when running git commit, you should get the linter output -(if any) before being prompted to enter a commit message. -To bypass the check (e.g. if there was a false positive), -add the option --no-verify. diff --git a/CODING_STANDARD.md b/CODING_STANDARD.md new file mode 100644 index 00000000000..06c6bf53666 --- /dev/null +++ b/CODING_STANDARD.md @@ -0,0 +1,231 @@ +Here a few minimalistic coding rules for the CPROVER source tree. + +# Whitespaces +- Use 2 spaces indent, no tabs. +- No lines wider than 80 chars. + - When line is wider, do the following: + - Subsequent lines should be indented two more than the initial line + - Break after `=` if it is part of an assignment + - For chained calls, prefer immediately before `.` + - For other operators (e.g. `&&`, `+`) prefer immediately after the + operator + - For brackets, break after the bracket + - In the case of function calls, put each argument on a separate line if + they do not fit after one line break + - Nested function calls do not need to be broken up into separate lines + even if the outer function call does. +- If a method is bigger than 50 lines, break it into parts. +- Put matching `{ }` into the same column. +- No spaces around operators (`=`, `+`, `==` ...) Exceptions: Spaces around + `&&`, `||` and `<<` +- Space after comma (parameter lists, argument lists, ...) +- Space after colon inside `for` +- For pointers and references, the `*`/`&` should be attached to the variable + name as opposed to the type. E.g. for a pointer to an int the syntax would + be: `int *x;` +- No whitespaces at end of line +- No whitespaces in blank lines +- Put argument lists on next line (and indent 2 spaces) if too long +- Put parameters on separate lines (and indent 2 spaces) if too long +- No whitespaces around colon for inheritance, put inherited into separate + lines in case of multiple inheritance +- The initializer list follows the constructor without a whitespace around the + colon. Break line after the colon if required and indent members. +- `if(...)`, `else`, `for(...)`, `do`, and `while(...)` are always in a + separate line +- Break expressions in `if`, `for`, `while` if necessary and align them with + the first character following the opening parenthesis +- Use `{}` instead of `;` for the empty statement +- Single line blocks without `{ }` are allowed, but put braces around + multi-line blocks +- Use blank lines to visually separate logically cohesive code blocks within a + function +- Have a newline at the end of a file + +# Comments +- Do not use `/* */` +- Each source and header file must start with a comment block stating the + author. See existing source for an example of the format of this block. This + should be followed by a Doxygen `\file` comment: + ```c++ + /// \file + /// + ``` + Note that the `\file` tag must be immediately followed by a newline in order + for Doxygen to relate the comment to the current file. +- Each function should be preceded by a Doxygen comment describing that + function. The format should match the [LLVM + guidelines](http://llvm.org/docs/CodingStandards.html#doxygen-use-in-documentation-comments), + with one extension: `\param` and `\return` comments longer than a single line + should have subsequent lines indented by two spaces, so that the tags stand + out. An example: + ```c++ + /// This sentence, until the first dot followed by whitespace, becomes + /// the brief description. More detailed text follows. Feel free to + /// break this into paragraphs to aid readability. + /// \param arg_name: This parameter doesn't need much description + /// \param [out] long_arg_name: This parameter is mutated by the function. + /// Extra info about the parameter gets indented an extra two columns, + /// like this. + /// \return The return value is literally the value returned by the + /// function. For out-parameters, use "\param [out]". + return_typet my_function(argt arg_name, argt &long_arg_name) + ``` +- The priority of documentation is readability. Therefore, feel free to use + Doxygen features, or to add whitespace for multi-paragraph comment blocks if + necessary. +- A comment block should immediately precede the definition of the entity it + documents, which will generally mean that it will live in the source file. + This allows us to take advantage of the one definition rule. If each entity + is defined only once, then it is also documented only once. +- The documentation block must *immediately* precede the entity it documents. + Don't insert empty lines between docs and functions, because this will + confuse Doxygen. +- Put comments on a separate line +- Use comments to explain the non-obvious +- Use #if 0 for commenting out source code +- Use #ifdef DEBUG to guard debug code + +# Naming +- Identifiers may use the characters `[a-z0-9_]` and should start with a + lower-case letter (parameters in constructors may start with `_`). +- Use American spelling for identifiers. +- Separate basic words by `_` +- Avoid abbreviations (e.g. prefer `symbol_table` to `st`). +- User defined type identifiers have to be terminated by `t`. Moreover, before + `t` may not be `_`. +- Do not use `m_` prefix nor `_` suffix for names of attributes of structured + types. +- Enum values may use the characters `[A-Z0-9_]` + +# Header files +- Avoid unnecessary `#include`s, especially in header files +- Prefer forward declaration to includes, but forward declare at the top of the + header file rather than in line +- Guard headers with `#ifndef CPROVER_DIRECTORIES_FILE_H`, etc +- The corresponding header for a given source file should always be the *first* + include in the source file. For example, given `foo.h` and `foo.cpp`, the + line `#include "foo.h"` should precede all other include statements in + `foo.cpp`. +- Use the C++ versions of C headers (e.g. `cmath` instead of `math.h`). + Some of the C headers use macros instead of functions which can have + unexpected consequences. + +# Makefiles +- Each source file should appear on a separate line +- The final source file should still be followed by a trailing slash +- The last line should be a comment to not be deleted, i.e. should look like: + ```makefile + SRC = source_file.cpp \ + source_file2.cpp \ + # Empty last line + ``` + This ensures the Makefiles can be easily merged. + +# Program Command Line Options +- Each program contains a `program_name_parse_optionst` class which should + contain a define `PROGRAM_NAME_PARSE_OPTIONS` which is a string of all the + parse options in brackets (with a colon after the bracket if it takes a + parameter) +- Each parameter should be one per line to yield easy merging +- If parameters are shared between programs, they should be pulled out into a + common file and then included using a define +- The defines should be `OPT_FLAG_NAMES` which should go into the `OPTIONS` + define +- The defines should include `HELP_FLAG_NAMES` which should contain the help + output in the format: + ``` + " --flag explanations\n" \ + " --another flag more explanation\n" \ + <-------30 chars------> + ``` +- The defines may include `PARSE_OPTIONS_FLAG_NAMES` which move the options + from the command line into the options + +# C++ features +- Do not use namespaces, except for anonymous namespaces. +- Prefer use of `typedef` instead of `using`. +- Prefer use of `class` instead of `struct`. +- Write type modifiers before the type specifier. +- Make references `const` whenever possible +- Make member functions `const` whenever possible +- Do not hide base class functions +- You are encouraged to use `override` +- Single argument constructors must be `explicit` +- Avoid implicit conversions +- Avoid `friend` declarations +- Avoid iterators, use ranged `for` instead +- Avoid allocation with `new`/`delete`, use `unique_ptr` +- Avoid pointers, use references +- Avoid `char *`, use `std::string` +- For numbers, use `int`, `unsigned`, `long`, `unsigned long`, `double` +- Use `mp_integer`, not `BigInt` +- Use the functions in util for conversions between numbers and strings +- Avoid C-style functions. Use classes with an `operator()` instead. +- Use `irep_idt` for identifiers (not `std::string`) +- Avoid destructive updates if possible. The `irept` has constant time copy. +- Use instances of `std::size_t` for comparison with return values of `.size()` + of STL containers and algorithms, and use them as indices to arrays or + vectors. +- Do not use default values in public functions +- Use assertions to detect programming errors, e.g. whenever you make + assumptions on how your code is used +- Use exceptions only when the execution of the program has to abort because of + erroneous user input +- We allow to use 3rd-party libraries directly. No wrapper matching the coding + rules is required. Allowed libraries are: STL. +- When throwing, omit the brackets, i.e. `throw "error"`. +- Error messages should start with a lower case letter. +- Use the `auto` keyword if and only if one of the following + - The type is explicitly repeated on the RHS (e.g. a constructor call) + - Adding the type will increase confusion (e.g. iterators, function pointers) +- Avoid `assert`. If the condition is an actual invariant, use INVARIANT, + PRECONDITION, POSTCONDITION, CHECK_RETURN, UNREACHABLE or DATA_INVARIANT. If + there are possible reasons why it might fail, throw an exception. + +# Architecture-specific code +- Avoid if possible. +- Use `__LINUX__`, `__MACH__`, and `_WIN32` to distinguish the architectures. +- Don't include architecture-specific header files without `#ifdef` ... + +# Output +- Do not output to `cout` or `cerr` directly (except in temporary debug code, + and then guard `#include ` by `#ifdef DEBUG`) +- Derive from `messaget` if the class produces output and use the streams + provided (`status()`, `error()`, `debug()`, etc) +- Use `\n` instead of `std::endl` + +# Unit tests +- Unit tests are written using [Catch](https://github.com/philsquared/Catch) +- For large classes: + - Create a separate file that contains the tests for each method of each + class + - The file should be named according to + `unit/class/path/class_name/function_name.cpp` +- For small classes: + - Create a separate file that contains the tests for all methods of each + class + - The file should be named according to `unit/class/path/class_name.cpp` +- Catch supports tagging, tests should be tagged with all the following tags: + - [core] should be used for all tests unless the test takes more than 1 + second to run, then it should be tagged with [long] + - [folder_name] of the file being tested + - [class_name] of the class being tested + - [function_name] of the function being tested + +--- + +You are allowed to break rules if you have a good reason to do so. + +--- + +# Pre-commit hook to run cpplint locally + +To install the hook +```sh +cp .githooks/pre-commit .git/hooks/pre-commit +``` +or use a symbolic link. Then, when running git commit, you should get the +linter output (if any) before being prompted to enter a commit message. To +bypass the check (e.g. if there was a false positive), add the option +`--no-verify`. diff --git a/COMPILING b/COMPILING index 4b47b38b790..3df46849022 100644 --- a/COMPILING +++ b/COMPILING @@ -32,7 +32,7 @@ We assume that you have a Debian/Ubuntu or Red Hat-like distribution. The GNU Make needs to be version 3.81 or higher. On Debian-like distributions, do - apt-get install g++-6 gcc flex bison make git libwww-perl patch + apt-get install g++ gcc flex bison make git libwww-perl patch On Red Hat/Fedora or derivates, do @@ -44,13 +44,7 @@ We assume that you have a Debian/Ubuntu or Red Hat-like distribution. git clone https://github.com/diffblue/cbmc cbmc-git -2) On Debian, do - - cd cbmc-git/src - make minisat2-download - make CXX=g++-6 - - On Ubuntu, or other distributions with recent g++, do +2) On Debian or Ubuntu, do cd cbmc-git/src make minisat2-download diff --git a/appveyor.yml b/appveyor.yml index f1f66142620..3a7c2d5c363 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -75,6 +75,10 @@ test_script: cat goto-instrument-typedef/chain.sh || true rem HACK disable failing tests + rmdir /s /q ansi-c\arch_flags_mcpu_bad + rmdir /s /q ansi-c\arch_flags_mcpu_good + rmdir /s /q ansi-c\arch_flags_mthumb_bad + rmdir /s /q ansi-c\arch_flags_mthumb_good rmdir /s /q ansi-c\Forward_Declaration2 rmdir /s /q ansi-c\Incomplete_Type1 rmdir /s /q ansi-c\Union_Padding1 diff --git a/doc/CPPLINT.cfg b/doc/CPPLINT.cfg new file mode 100644 index 00000000000..51ff339c184 --- /dev/null +++ b/doc/CPPLINT.cfg @@ -0,0 +1 @@ +exclude_files=.* diff --git a/doc/architectural/cbmc-guide.md b/doc/architectural/cbmc-guide.md new file mode 100644 index 00000000000..ccbf0068cea --- /dev/null +++ b/doc/architectural/cbmc-guide.md @@ -0,0 +1,601 @@ +\ingroup module_hidden +\page cbmc-guide CBMC Guide + +\author Martin Brain + +Background Information +====================== + +First off; read the \ref cprover-manual "CProver Manual". It describes +how to get, build and use CBMC and SATABS. This document covers the +internals of the system and how to get started on development. + +Documentation +------------- + +Apart from the (user-orientated) CPROVER manual and this document, most +of the rest of the documentation is inline in the code as `doxygen` and +some comments. A man page for CBMC, goto-cc and goto-instrument is +contained in the `doc/` directory and gives some options for these +tools. All of these could be improved and patches are very welcome. In +some cases the algorithms used are described in the relevant papers. + +Architecture +------------ + +CPROVER is structured in a similar fashion to a compiler. It has +language specific front-ends which perform limited syntactic analysis +and then convert to an intermediate format. The intermediate format can +be output to files (this is what `goto-cc` does) and are (informally) +referred to as “goto binaries” or “goto programs”. The back-end are +tools process this format, either directly from the front-end or from +it’s saved output. These include a wide range of analysis and +transformation tools (see Section \[section:other-apps\]). + +Coding Standards +---------------- + +CPROVER is written in a fairly minimalist subset of C++; templates and +meta-programming are avoided except where necessary. The standard +library is used but in many cases there are alternatives provided in +`util/` (see Section \[section:util\]) which are preferred. Boost is +not used. + +Patches should be formatted so that code is indented with two space +characters, not tab and wrapped to 75 or 72 columns. Headers for doxygen +should be given (and preferably filled!) and the author will be the +person who first created the file. + +Identifiers should be lower case with underscores to separate words. +Types (classes, structures and typedefs) names must[^1] end with a `t`. +Types that model types (i.e. C types in the program that is being +interpreted) are named with `_typet`. For example `ui_message_handlert` +rather than `UI_message_handlert` or `UIMessageHandler` and +`union_typet`. + +How to Contribute +----------------- + +Fixes, changes and enhancements to the CPROVER code base should be +developed against the `trunk` version and submitted to Daniel as patches +produced by `diff -Naur` or `svn diff`. Entire applications are best +developed independently (`git svn` is a popular choice for tracking the +main trunk but also having local development) until it is clear what +their utility, future and maintenance is likely to be. + +Other Useful Code {#section:other-apps} +----------------- + +The CPROVER subversion archive contains a number of separate programs. +Others are developed separately as patches or separate +branches.Interfaces are have been and are continuing to stablise but +older code may require work to compile and function correctly. + +In the main archive: + +* `CBMC`: A bounded model checking tool for C and C++. See Section + \[section:CBMC\]. + +* `goto-cc`: A drop-in, flag compatible replacement for GCC and other + compilers that produces goto-programs rather than executable binaries. + See Section \[section:goto-cc\]. + +* `goto-instrument`: A collection of functions for instrumenting and + modifying goto-programs. See Section \[section:goto-instrument\]. + +Model checkers and similar tools: + +* `SatABS`: A CEGAR model checker using predicate abstraction. Is + roughly 10,000 lines of code (on top of the CPROVER code base) and is + developed in its own subversion archive. It uses an external model + checker to find potentially feasible paths. Key limitations are + related to code with pointers and there is scope for significant + improvement. + +* `Scratch`: Alistair Donaldson’s k-induction based tool. The + front-end is in the old project CVS and some of the functionality is + in `goto-instrument`. + +* `Wolverine`: An implementation of Ken McMillan’s IMPACT algorithm + for sequential programs. In the old project CVS. + +* `C-Impact`: An implementation of Ken McMillan’s IMPACT algorithm for + parallel programs. In the old project CVS. + +* `LoopFrog`: A loop summarisation tool. + +* `???`: Christoph’s termination analyser. + +Test case generation: + +* `cover`: A basic test-input generation tool. In the old + project CVS. + +* `FShell`: A test-input generation tool that allows the user to + specify the desired coverage using a custom language (which includes + regular expressions over paths). It uses incremental SAT and is thus + faster than the naïve “add assertions one at a time and use the + counter-examples” approach. Is developed in its own subversion. + +Alternative front-ends and input translators: + +* `Scoot`: A System-C to C translator. Probably in the old + project CVS. + +* `???`: A Simulink to C translator. In the old project CVS. + +* `???`: A Verilog front-end. In the old project CVS. + +* `???`: A converter from Codewarrior project files to Makefiles. In + the old project CVS. + +Other tools: + +* `ai`: Leo’s hybrid abstract interpretation / CEGAR tool. + +* `DeltaCheck?`: Ajitha’s slicing tool, aimed at locating changes and + differential verification. In the old project CVS. + +There are tools based on the CPROVER framework from other research +groups which are not listed here. + +Source Walkthrough +================== + +This section walks through the code bases in a rough order of interest / +comprehensibility to the new developer. + +`doc` +----- + +At the moment just contains the CBMC man page. + +`regression/` +------------- + +The regression tests are currently being moved from CVS. The +`regression/` directory contains all of those that have +been moved. They are grouped into directories for each of the tools. +Each of these contains a directory per test case, containing a C or C++ +file that triggers the bug and a `.dsc` file that describes +the tests, expected output and so on. There is a Perl script, +`test.pl` that is used to invoke the tests as: + + ../test.pl -c PATH_TO_CBMC + +The `–help` option gives instructions for use and the +format of the description files. + +`src/` +------ + +The source code is divided into a number of sub-directories, each +containing the code for a different part of the system. In the top level +files there are only a few files: + +* `config.inc`: The user-editable configuration parameters for the + build process. The main use of this file is setting the paths for the + various external SAT solvers that are used. As such, anyone building + from source will likely need to edit this. + +* `Makefile`: The main systems Make file. Parallel builds are + supported and encouraged; please don’t break them! + +* `common`: System specific magic required to get the system to build. + This should only need to be edited if porting CBMC to a new platform / + build environment. + +* `doxygen.cfg`: The config file for doxygen.cfg + +### `util/` {#section:util} + +`util/` contains the low-level data structures and +manipulation functions that are used through-out the CPROVER code-base. +For almost any low-level task, the code required is probably in +`util/`. Key files include: + +* `irep.h`: This contains the definition of `irept`, the basis of many + of the data structures in the project. They should not be used + directly; one of the derived classes should be used. For more + information see Section \[section:irept\]. + +* `expr.h`: The parent class for all of the expressions. Provides a + number of generic functions, `exprt` can be used with these but when + creating data, subclasses of `exprt` should be used. + +* `std_expr.h`: Provides subclasses of `exprt` for common kinds of + expression for example `plus_exprt`, `minus_exprt`, + `dereference_exprt`. These are the intended interface for creating + expressions. + +* `std_types.h`: Provides subclasses of `typet` (a subclass of + `irept`) to model C and C++ types. This is one of the preferred + interfaces to `irept`. The front-ends handle type promotion and most + coercision so the type system and checking goto-programs is simpler + than C. + +* `dstring.h`: The CPROVER string class. This enables sharing between + strings which significantly reduces the amount of memory required and + speeds comparison. `dstring` should not be used directly, `irep_idt` + should be used instead, which (dependent on build options) is an alias + for `dstring`. + +* `mp_arith.h`: The wrapper class for multi-precision arithmetic + within CPROVER. Also see `arith_tools.h`. + +* `ieee_float.h`: The arbitrary precision float model used within + CPROVER. Based on `mp_integer`s. + +* `context.h`: A generic container for symbol table like constructs + such as namespaces. Lookup gives type, location of declaration, name, + ‘pretty name’, whether it is static or not. + +* `namespace.h`: The preferred interface for the context class. The + key function is `lookup` which converts a string (`irep_idt`) to a + symbol which gives the scope of declaration, type and so on. This + works for functions as well as variables. + +### `langapi/` + +This contains the basic interfaces and support classes for programming +language front ends. Developers only really need look at this if they +are adding support for a new language. It’s main users are the two (in +trunk) language front-ends; `ansi-c/` and +`cpp/`. + +### `ansi-c/` + +Contains the front-end for ANSI C, plus a variety of common extensions. +This parses the file, performs some basic sanity checks (this is one +area in which the UI could be improved; patches most welcome) and then +produces a goto-program (see below). The parser is a traditional Flex / +Bison system. + +`internal_addition.c` contains the implementation of various ‘magic’ +functions that are that allow control of the analysis from the source +code level. These include assertions, assumptions, atomic blocks, memory +fences and rounding modes. + +The `library/` subdirectory contains versions of some of the C standard +header files that make use of the CPROVER built-in functions. This +allows CPROVER programs to be ‘aware’ of the functionality and model it +correctly. Examples include `stdio.c`, `string.c`, `setjmp.c` and +various threading interfaces. + +### `cpp/` + +This directory contains the C++ front-end. It supports the subset of C++ +commonly found in embedded and system applications. Consequentially it +doesn’t have full support for templates and many of the more advanced +and obscure C++ features. The subset of the language that can be handled +is being extended over time so bug reports of programs that cannot be +parsed are useful. + +The functionality is very similar to the ANSI C front end; parsing the +code and converting to goto-programs. It makes use of code from +`langapi` and `ansi-c`. + +### `goto-programs/` + +Goto programs are the intermediate representation of the CPROVER tool +chain. They are language independent and similar to many of the compiler +intermediate languages. Section \[section:goto-programs\] describes the +`goto_programt` and `goto_functionst` data structures in detail. However +it useful to understand some of the basic concepts. Each function is a +list of instructions, each of which has a type (one of 18 kinds of +instruction), a code expression, a guard expression and potentially some +targets for the next instruction. They are not natively in static +single-assign (SSA) form. Transitions are nondeterministic (although in +practise the guards on the transitions normally cover form a disjoint +cover of all possibilities). Local variables have non-deterministic +values if they are not initialised. Variables and data within the +program is commonly one of three types (parameterised by width): +`unsignedbv_typet`, `signedbv_typet` and `floatbv_typet`, see +`util/std_types.h` for more information. Goto programs can be serialised +in a binary (wrapped in ELF headers) format or in XML (see the various +`_serialization` files). + +The `cbmc` option `–show-goto-programs` is often a good starting point +as it outputs goto-programs in a human readable form. However there are +a few things to be aware of. Functions have an internal name (for +example `c::f00`) and a ‘pretty name’ (for example `f00`) and which is +used depends on whether it is internal or being presented to the user. +The `main` method is the ‘logical’ main which is not necessarily the +main method from the code. In the output `NONDET` is use to represent a +nondeterministic assignment to a variable. Likewise `IF` as a beautified +`GOTO` instruction where the guard expression is used as the condition. +`RETURN` instructions may be dropped if they precede an `END_FUNCTION` +instruction. The comment lines are generated from the `locationt` field +of the `instructiont` structure. + +`goto-programs/` is one of the few places in the CPROVER codebase that +templates are used. The intention is to allow the general architecture +of program and functions to be used for other formalisms. At the moment +most of the templates have a single instantiation; for example +`goto_functionst` and `goto_function_templatet` and `goto_programt` and +`goto_program_templatet`. + +### `goto-symex/` + +This directory contains a symbolic evaluation system for goto-programs. +This takes a goto-program and translates it to an equation system by +traversing the program, branching and merging and unwinding loops as +needed. Each reverse goto has a separate counter (the actual counting is +handled by `cbmc`, see the `–unwind` and `–unwind-set` options). When a +counter limit is reach, an assertion can be added to explicitly show +when analysis is incomplete. The symbolic execution includes constant +folding so loops that have a constant number of iterations will be +handled completely (assuming the unwinding limit is sufficient). + +The output of the symbolic execution is a system of equations; an object +containing a list of `symex_target_elements`, each of which are +equalities between `expr` expressions. See `symex_target_equation.h`. +The output is in static, single assignment (SSA) form, which is *not* +the case for goto-programs. + +### `pointer-analysis/` + +To perform symbolic execution on programs with dereferencing of +arbitrary pointers, some alias analysis is needed. `pointer-analysis` +contains the three levels of analysis; flow and context insensitive, +context sensitive and flow and context sensitive. The code needed is +subtle and sophisticated and thus there may be bugs. + +### `solvers/` + +The `solvers/` directory contains interfaces to a number of +different decision procedures, roughly one per directory. + +* prop/: The basic and common functionality. The key file is + `prop_conv.h` which defines `prop_convt`. This is the base class that + is used to interface to the decision procedures. The key functions are + `convert` which takes an `exprt` and converts it to the appropriate, + solver specific, data structures and `dec_solve` (inherited from + `decision_proceduret`) which invokes the actual decision procedures. + Individual decision procedures (named `*_dect`) objects can be created + but `prop_convt` is the preferred interface for code that uses them. + +* flattening/: A library that converts operations to bit-vectors, + including calling the conversions in `floatbv` as necessary. Is + implemented as a simple conversion (with caching) and then a + post-processing function that adds extra constraints. This is not used + by the SMT or CVC back-ends. + +* dplib/: Provides the `dplib_dect` object which used the decision + procedure library from “Decision Procedures : An Algorithmic Point of + View”. + +* cvc/: Provides the `cvc_dect` type which interfaces to the old (pre + SMTLib) input format for the CVC family of solvers. This format is + still supported by depreciated in favour of SMTLib 2. + +* smt1/: Provides the `smt1_dect` type which converts the formulae to + SMTLib version 1 and then invokes one of Boolector, CVC3, OpenSMT, + Yices, MathSAT or Z3. Again, note that this format is depreciated. + +* smt2/: Provides the `smt2_dect` type which functions in a similar + way to `smt1_dect`, calling Boolector, CVC3, MathSAT, Yices or Z3. + Note that the interaction with the solver is batched and uses + temporary files rather than using the interactive command supported by + SMTLib 2. With the `–fpa` option, this output mode will not flatten + the floating point arithmetic and instead output the proposed SMTLib + floating point standard. + +* qbf/: Back-ends for a variety of QBF solvers. Appears to be no + longer used or maintained. + +* sat/: Back-ends for a variety of SAT solvers and DIMACS output. + +### `cbmc/` {#section:CBMC} + +This contains the first full application. CBMC is a bounded model +checker that uses the front ends (`ansi-c`, `cpp`, goto-program or +others) to create a goto-program, `goto-symex` to unwind the loops the +given number of times and to produce and equation system and finally +`solvers` to find a counter-example (technically, `goto-symex` is then +used to construct the counter-example trace). + +### `goto-cc/` {#section:goto-cc} + +`goto-cc` is a compiler replacement that just performs the first step of +the process; converting C or C++ programs to goto-binaries. It is +intended to be dropped in to an existing build procedure in place of the +compiler, thus it emulates flags that would affect the semantics of the +code produced. Which set of flags are emulated depends on the naming of +the `goto-cc/` binary. If it is called `goto-cc` then it emulates GCC +flags, `goto-armcc` emulates the ARM compiler, `goto-cl` emulates VCC +and `goto-cw` emulates the Code Warrior compiler. The output of this +tool can then be used with `cbmc` or `goto-instrument`. + +### `goto-instrument/` {#section:goto-instrument} + +The `goto-instrument/` directory contains a number of tools, one per +file, that are built into the `goto-instrument` program. All of them +take in a goto-program (produced by `goto-cc`) and either modify it or +perform some analysis. Examples include `nondet_static.cpp` which +initialises static variables to a non-deterministic value, +`nondet_volatile.cpp` which assigns a non-deterministic value to any +volatile variable before it is read and `weak_memory.h` which performs +the necessary transformations to reason about weak memory models. The +exception to the “one file for each piece of functionality” rule are the +program instrumentation options (mostly those given as “Safety checks” +in the `goto-instrument` help text) which are included in the +`goto-program/` directory. An example of this is +`goto-program/stack_depth.h` and the general rule seems to be that +transformations and instrumentation that `cbmc` uses should be in +`goto-program/`, others should be in `goto-instrument`. + +`goto-instrument` is a very good template for new analysis tools. New +developers are advised to copy the directory, remove all files apart +from `main.*`, `parseoptions.*` and the `Makefile` and use these as the +skeleton of their application. The `doit()` method in `parseoptions.cpp` +is the preferred location for the top level control for the program. + +### `linking/` + +Probably the code to emulate a linker. This allows multiple ‘object +files’ (goto-programs) to be linked into one ‘executable’ (another +goto-program), thus allowing existing build systems to be used to build +complete goto-program binaries. + +### `big-int/` + +CPROVER is distributed with its own multi-precision arithmetic library; +mainly for historical and portability reasons. The library is externally +developed and thus `big-int` contains the source as it is distributed. +This should not be used directly, see `util/mp_arith.h` for the CPROVER +interface. + +### `xmllang/` + +CPROVER has optional XML output for results and there is an XML format +for goto-programs. It is used to interface to various IDEs. The +`xmllang/` directory contains the parser and helper functions for +handling this format. + +### `floatbv/` + +This library contains the code that is used to convert floating point +variables (`floatbv`) to bit vectors (`bv`). This is referred to as +‘bit-blasting’ and is called in the `solver` code during conversion to +SAT or SMT. It also contains the abstraction code described in the +FMCAD09 paper. + +Data Structures +=============== + +This section discusses some of the key data-structures used in the +CPROVER codebase. + +`irept` {#section:irept} +------------------------ + +There are a large number of kind of tree structured or tree-like data in +CPROVER. `irept` provides a single, unified representation for all of +these, allowing structure sharing and reference counting of data. As +such `irept` is the basic unit of data in CPROVER. Each `irept` +contains[^2] a basic unit of data (of type `dt`) which contains four +things: + +* `data`: A string[^3], which is returned when the `id()` function is + used. + +* `named_sub`: A map from `irep_namet` (a string) to an `irept`. This + is used for named children, i.e. subexpressions, parameters, etc. + +* `comments`: Another map from `irep_namet` to `irept` which is used + for annotations and other ‘non-semantic’ information + +* `sub`: A vector of `irept` which is used to store ordered but + unnamed children. + +The `irept::pretty` function outputs the contents of an `irept` directly +and can be used to understand an debug problems with `irept`s. + +On their own `irept`s do not “mean” anything; they are effectively +generic tree nodes. Their interpretation depends on the contents of +result of the `id` function (the `data`) field. `util/irep_ids.txt` +contains the complete list of `id` values. During the build process it +is used to generate `util/irep_ids.h` which gives constants for each id +(named `ID_`). These can then be used to identify what kind of data +`irept` stores and thus what can be done with it. + +To simplify this process, there are a variety of classes that inherit +from `irept`, roughly corresponding to the ids listed (i.e. `ID_or` +(the string `"or”`) corresponds to the class `or_exprt`). These give +semantically relevant accessor functions for the data; effectively +different APIs for the same underlying data structure. None of these +classes add fields (only methods) and so static casting can be used. The +inheritance graph of the subclasses of `irept` is a useful starting +point for working out how to manipulate data. + +There are three main groups of classes (or APIs); those derived from +`typet`, `codet` and `exprt` respectively. Although all of these inherit +from `irept`, these are the most abstract level that code should handle +data. If code is manipulating plain `irept`s then something is wrong +with the architecture of the code. + +Many of the key descendent of `exprt` are declared in `std_expr.h`. All +expressions have a named subfield / annotation which gives the type of +the expression (slightly simplified from C/C++ as `unsignedbv_typet`, +`signedbv_typet`, `floatbv_typet`, etc.). All type conversions are +explicit with an expression with `id() == ID_typecast` and an ‘interface +class’ named `typecast_exprt`. One key descendent of `exprt` is +`symbol_exprt` which creates `irept` instances with the id of “symbol”. +These are used to represent variables; the name of which can be found +using the `get_identifier` accessor function. + +`codet` inherits from `exprt` and is defined in `std_code.h`. They +represent executable code; statements in C rather than expressions. In +the front-end there are versions of these that hold whole code blocks, +but in goto-programs these have been flattened so that each `irept` +represents one sequence point (almost one line of code / one +semi-colon). The most common descendents of `codet` are `code_assignt` +so a common pattern is to cast the `codet` to an assignment and then +recurse on the expression on either side. + +`goto-programs` {#section:goto-programs} +---------------------------------------- + +The common starting point for working with goto-programs is the +`read_goto_binary` function which populates an object of +`goto_functionst` type. This is defined in `goto_functions.h` and is an +instantiation of the template `goto_functions_templatet` which is +contained in `goto_functions_template.h`. They are wrappers around a map +from strings to `goto_programt`’s and iteration macros are provided. +Note that `goto_function_templatet` (no `s`) is defined in the same +header as `goto_functions_templatet` and is gives the C type for the +function and Boolean which indicates whether the body is available +(before linking this might not always be true). Also note the slightly +counter-intuitive naming; `goto_functionst` instances are the top level +structure representing the program and contain `goto_programt` instances +which represent the individual functions. At the time of writing +`goto_functionst` is the only instantiation of the template +`goto_functions_templatet` but other could be produced if a different +data-structures / kinds of models were needed for functions. + +`goto_programt` is also an instantiation of a template. In a similar +fashion it is `goto_program_templatet` and allows the types of the guard +and expression used in instructions to be parameterised. Again, this is +currently the only use of the template. As such there are only really +helper functions in `goto_program.h` and thus `goto_program_template.h` +is probably the key file that describes the representation of (C) +functions in the goto-program format. It is reasonably stable and +reasonably documented and thus is a good place to start looking at the +code. + +An instance of `goto_program_templatet` is effectively a list of +instructions (and inner template called `instructiont`). It is important +to use the copy and insertion functions that are provided as iterators +are used to link instructions to their predecessors and targets and +careless manipulation of the list could break these. Likewise there are +helper macros for iterating over the instructions in an instance of +`goto_program_templatet` and the use of these is good style and strongly +encouraged. + +Individual instructions are instances of type `instructiont`. They +represent one step in the function. Each has a type, an instance of +`goto_program_instruction_typet` which denotes what kind of instruction +it is. They can be computational (such as `ASSIGN` or `FUNCTION_CALL`), +logical (such as `ASSUME` and `ASSERT`) or informational (such as +`LOCATION` and `DEAD`). At the time of writing there are 18 possible +values for `goto_program_instruction_typet` / kinds of instruction. +Instructions also have a guard field (the condition under which it is +executed) and a code field (what the instruction does). These may be +empty depending on the kind of instruction. In the default +instantiations these are of type `exprt` and `codet` respectively and +thus covered by the previous discussion of `irept` and its descendents. +The next instructions (remembering that transitions are guarded by +non-deterministic) are given by the list `targets` (with the +corresponding list of labels `labels`) and the corresponding set of +previous instructions is get by `incoming_edges`. Finally `instructiont` +have informational `function` and `location` fields that indicate where +they are in the code. + +[^1]: There are a couple of exceptions, including the graph classes + +[^2]: Or references, if reference counted data sharing is enabled. It is + enabled by default; see the `SHARING` macro. + +[^3]: When `USE_DSTRING` is enabled (it is by default), this is actually +a `dstring` and thus an integer which is a reference into a string table diff --git a/doc/architectural/front-page.md b/doc/architectural/front-page.md new file mode 100644 index 00000000000..13e832074a8 --- /dev/null +++ b/doc/architectural/front-page.md @@ -0,0 +1,46 @@ +CProver Documentation +===================== + +\author Kareem Khazem + +These pages contain user tutorials, automatically-generated API +documentation, and higher-level architectural overviews for the +CProver codebase. Users can download CProver tools from the +CProver website; contributors +should use the repository +hosted on GitHub. + +### For users: + +* The \ref cprover-manual "CProver Manual" details the capabilities of + CBMC and SATABS and describes how to install and use these tools. It + also covers the underlying theory and prerequisite concepts behind how + these tools work. + +### For contributors: + +* If you already know exactly what you're looking for, the API reference + is generated from the codebase. You can search for classes and class + members in the search bar at top-right or use one of the links in the + sidebar. + +* For higher-level architectural information, each of the pages under + the "Modules" link in the sidebar gives an overview of a directory in + the CProver codebase. + +* The \ref module_cbmc "CBMC guided tour" is a good start for new + contributors to CBMC. It describes the stages through which CBMC + transforms source files into bug reports and counterexamples, linking + to the relevant documentation for each stage. + +* The \subpage cbmc-hacking "CBMC hacking HOWTO" helps new contributors + to CProver to get their feet wet through a series of programming + exercises---mostly modifying goto-instrument, and thus learning to + manipulate the main data structures used within CBMC. + +* The \subpage cbmc-guide "CBMC guide" is a single document describing + the layout of the codebase and many of the important data structures. + It probably contains more information than the module pages at the + moment, but may be somewhat out-of-date. + +\defgroup module_hidden _hidden diff --git a/doc/architectural/howto.md b/doc/architectural/howto.md new file mode 100644 index 00000000000..5eee0f0058f --- /dev/null +++ b/doc/architectural/howto.md @@ -0,0 +1,243 @@ +\ingroup module_hidden +\page cbmc-hacking CBMC Hacking HOWTO + +\author Kareem Khazem + +This is an introduction to hacking on the `cprover` codebase. It is not +intended as a user guide to `CBMC` or related tools. It is structured +as a series of programming exercises that aim to acclimatise the reader +to the basic data structures and workflow needed for contributing to +`CBMC`. + + +## Initial setup + +Clone the [CBMC repository][cbmc-repo] and build it: + + git clone https://github.com/diffblue/cbmc.git + cd cbmc/src + make minisat2-download + make + +Ensure that [graphviz][graphviz] is installed on your system (in +particular, you should be able to run a program called `dot`). Install +[Doxygen][doxygen] and generate doxygen documentation: + + # In the src directory + doxygen doxyfile + # View the documentation in a web browser + firefox doxy/html/index.html + +If you've never used doxygen documentation before, get familiar with the +layout. Open the generated HTML page in a web browser; search for the +class `goto_programt` in the search bar, and jump to the documentation +for that class; and read through the copious documentation. + +The build writes executable programs into several of the source +directories. In this tutorial, we'll be using binaries inside the +`cbmc`, `goto-instrument`, and `goto-cc` directories. Add these +directories to your `$PATH`: + + # Assuming you cloned CBMC into ~/code + export PATH=~/code/cbmc/src/goto-instrument:~/code/cbmc/src/goto-cc:~/code/cbmc/src/cbmc:$PATH + # Add to your shell's startup configuration file so that you don't have to run that command every time. + echo 'export PATH=~/code/cbmc/src/goto-instrument:~/code/cbmc/src/goto-cc:~/code/cbmc/src/cbmc:$PATH' >> .bashrc + +Optional: install an image viewer that can read images on stdin. +I use [feh][feh]. + +[cbmc-repo]: https://github.com/diffblue/cbmc/ +[doxygen]: http://www.stack.nl/~dimitri/doxygen/ +[graphviz]: http://www.graphviz.org/ +[feh]: https://feh.finalrewind.org/ + + + +## Whirlwind tour of the tools + +CBMC's code is located under the `cbmc` directory. Even if you plan to +contribute only to CBMC, it is important to be familiar with several +other of cprover's auxiliary tools. + + +### Compiling with `goto-cc` + +There should be an executable file called `goto-cc` in the `goto-cc` +directory; make a symbolic link to it called `goto-gcc`: + + cd cbmc/src/goto-cc + ln -s "$(pwd)/goto-cc" goto-gcc + +Find or write a moderately-interesting C program; we'll call it `main.c`. +Run the following commands: + + goto-gcc -o main.goto main.c + cc -o main.exe main.c + +Invoke `./main.goto` and `./main.exe` and observe that they run identically. +The version that was compiled with `goto-gcc` is larger, though: + + du -hs *.{goto,exe} + +Programs compiled with `goto-gcc` are mostly identical to their `clang`- +or `gcc`-compiled counterparts, but contain additional object code in +cprover's intermediate representation. The intermediate representation +is (informally) called a *goto-program*. + + +### Viewing goto-programs + +`goto-instrument` is a Swiss army knife for viewing goto-programs and +performing single program analyses on them. Run the following command: + + goto-instrument --show-goto-functions main.goto + +Many of the instructions in the goto-program intermediate representation +are similar to their C counterparts. `if` and `goto` statements replace +structured programming constructs. + +Find or write a small C program (2 or 3 functions, each containing a few +varied statements). Compile it using `goto-gcc` as above into an object +file called `main`. If you installed `feh`, try the following command +to dump a control-flow graph: + + goto-instrument --dot main | tail -n +2 | dot -Tpng | feh - + +If you didn't install `feh`, you can write the diagram to the file and +then view it: + + goto-instrument --dot main | tail -n +2 | dot -Tpng > main.png + Now open main.png with an image viewer + +(the invocation of `tail` is used to filter out the first line of +`goto-instrument` output. If `goto-instrument` writes more or less +debug output by the time you read this, read the output of +`goto-instrument --dot main` and change the invocation of `tail` +accordingly.) + +There are a few other views of goto-programs. Run `goto-instrument -h` +and try the various switches under the "Diagnosis" section. + + + +## Learning about goto-programs + +In this section, you will learn about the basic goto-program data +structures. Reading from and manipulating these data structures form +the core of writing an analysis for CBMC. + + +### First steps with `goto-instrument` + +
+**Task:** Write a simple C program with a few functions, each containing +a few statements. Compile the program with `goto-gcc` into a binary +called `main`. +
+ + +The entry point of `goto-instrument` is in `goto_instrument_main.cpp`. +Follow the control flow into `goto_instrument_parse_optionst::doit()`, located in `goto_instrument_parse_options.cpp`. +At some point in that function, there will be a long sequence of `if` statements. + +
+**Task:** Add a `--greet` switch to `goto-instrument`, taking an optional +argument, with the following behaviour: + + $ goto-instrument --greet main + hello, world! + $ goto-instrument --greet Leperina main + hello, Leperina! + +You will also need to add the `greet` option to the +`goto_instrument_parse_options.h` file in order for this to work. +Notice that in the `.h` file, options that take an argument are followed +by a colon (like `(property):`), while simple switches have no colon. +Make sure that you `return 0;` after printing the message. +
+ +The idea behind `goto-instrument` is that it parses a goto-program and +then performs one single analysis on that goto-program, and then +returns. Each of the switches in `doit` function of +`goto_instrument_parse_options` does something different with the +goto-program that was supplied on the command line. + + +### Goto-program basics + +At this point in `goto-instrument_parse_options` (where the `if` +statements are), the goto-program will have been loaded into the object +`goto_functions`, of type `goto_functionst`. This has a field called +`function_map`, a map from function names to functions. + + +
+**Task:** Add a `--print-function-names` switch to `goto-instrument` +that prints out the name of every function in the goto-binary. Are +there any functions that you didn't expect to see? +
+ +The following is quite difficult to follow from doxygen, but: the value +type of `function_map` is `goto_function_templatet`. + + +
+**Task:** Read the documentation for `goto_function_templatet` +and `goto_programt`. +
+ +Each goto_programt object contains a list of +\ref goto_program_templatet::instructiont called +`instructions`. Each instruction has a field called `code`, which has +type \ref codet. + +
+**Task:** Add a `--pretty-program` switch to `goto-instrument`. This +switch should use the `codet::pretty()` function to pretty-print every +\ref codet in the entire program. The strings that `pretty()` generates +for a codet look like this: + + index + * type: unsignedbv + * width: 8 + * #c_type: char + 0: symbol + * type: array + * size: nil + * type: + * #source_location: + * file: src/main.c + * line: 18 + * function: + * working_directory: /some/dir + 0: unsignedbv + * width: 8 + * #c_type: char + ... +
+ +The sub-nodes of a particular node in the pretty representation are +numbered, starting from 0. They can be accessed through the `op0()`, +`op1()` and `op2()` methods in the `exprt` class. + +Every node in the pretty representation has an identifier, accessed +through the `id()` function. The file `util/irep_ids.def` lists the +possible values of these identifiers; have a quick scan through that +file. In the pretty representation above, the following facts are true +of that particular node: + + - `node.id() == ID_index` + - `node.type().id() == ID_unsignedbv` + - `node.op0().id() == ID_symbol` + - `node.op0().type().id() == ID_array` + +The fact that the `op0()` child has a `symbol` ID menas that you could +cast it to a `symbol_exprt` (which is a subtype of `exprt`) using the +function `to_symbol_expr`. + +
+**Task:** Add flags to `goto-instrument` to print out the following information: +* the name of every function that is *called* in the program; +* the value of every constant in the program; +* the value of every symbol in the program. +
diff --git a/doc/html-manual/binsearch.c b/doc/assets/binsearch.c similarity index 100% rename from doc/html-manual/binsearch.c rename to doc/assets/binsearch.c diff --git a/doc/html-manual/c_to_ir.svg b/doc/assets/c_to_ir.svg similarity index 100% rename from doc/html-manual/c_to_ir.svg rename to doc/assets/c_to_ir.svg diff --git a/doc/html-manual/cegar-1.png b/doc/assets/cegar-1.png similarity index 100% rename from doc/html-manual/cegar-1.png rename to doc/assets/cegar-1.png diff --git a/doc/html-manual/counter.c b/doc/assets/counter.c similarity index 100% rename from doc/html-manual/counter.c rename to doc/assets/counter.c diff --git a/doc/html-manual/boop-example/driver.c b/doc/assets/driver.c similarity index 100% rename from doc/html-manual/boop-example/driver.c rename to doc/assets/driver.c diff --git a/doc/html-manual/boop-example/driver.h b/doc/assets/driver.h similarity index 100% rename from doc/html-manual/boop-example/driver.h rename to doc/assets/driver.h diff --git a/doc/html-manual/expr.c b/doc/assets/expr.c similarity index 100% rename from doc/html-manual/expr.c rename to doc/assets/expr.c diff --git a/doc/html-manual/expr.svg b/doc/assets/expr.svg similarity index 100% rename from doc/html-manual/expr.svg rename to doc/assets/expr.svg diff --git a/doc/html-manual/file1.c b/doc/assets/file1.c similarity index 100% rename from doc/html-manual/file1.c rename to doc/assets/file1.c diff --git a/doc/html-manual/file2.c b/doc/assets/file2.c similarity index 100% rename from doc/html-manual/file2.c rename to doc/assets/file2.c diff --git a/doc/html-manual/gcc-wrap.c b/doc/assets/gcc-wrap.c similarity index 100% rename from doc/html-manual/gcc-wrap.c rename to doc/assets/gcc-wrap.c diff --git a/doc/html-manual/goto_program.svg b/doc/assets/goto_program.svg similarity index 100% rename from doc/html-manual/goto_program.svg rename to doc/assets/goto_program.svg diff --git a/doc/html-manual/ireptree.svg b/doc/assets/ireptree.svg similarity index 100% rename from doc/html-manual/ireptree.svg rename to doc/assets/ireptree.svg diff --git a/doc/html-manual/boop-example/kdev_t.h b/doc/assets/kdev_t.h similarity index 100% rename from doc/html-manual/boop-example/kdev_t.h rename to doc/assets/kdev_t.h diff --git a/doc/html-manual/lock-example-fixed.c b/doc/assets/lock-example-fixed.c similarity index 100% rename from doc/html-manual/lock-example-fixed.c rename to doc/assets/lock-example-fixed.c diff --git a/doc/html-manual/lock-example.c b/doc/assets/lock-example.c similarity index 100% rename from doc/html-manual/lock-example.c rename to doc/assets/lock-example.c diff --git a/doc/html-manual/boop-example/modules.h b/doc/assets/modules.h similarity index 100% rename from doc/html-manual/boop-example/modules.h rename to doc/assets/modules.h diff --git a/doc/html-manual/pid.c b/doc/assets/pid.c similarity index 100% rename from doc/html-manual/pid.c rename to doc/assets/pid.c diff --git a/doc/html-manual/pid.png b/doc/assets/pid.png similarity index 100% rename from doc/html-manual/pid.png rename to doc/assets/pid.png diff --git a/doc/html-manual/refinement.png b/doc/assets/refinement.png similarity index 100% rename from doc/html-manual/refinement.png rename to doc/assets/refinement.png diff --git a/doc/html-manual/ring_buffer1.c b/doc/assets/ring_buffer1.c similarity index 100% rename from doc/html-manual/ring_buffer1.c rename to doc/assets/ring_buffer1.c diff --git a/doc/html-manual/ring_buffer2.c b/doc/assets/ring_buffer2.c similarity index 100% rename from doc/html-manual/ring_buffer2.c rename to doc/assets/ring_buffer2.c diff --git a/doc/html-manual/boop-example/spec.c b/doc/assets/spec.c similarity index 100% rename from doc/html-manual/boop-example/spec.c rename to doc/assets/spec.c diff --git a/doc/html-manual/states.png b/doc/assets/states.png similarity index 100% rename from doc/html-manual/states.png rename to doc/assets/states.png diff --git a/doc/cprover-manual.md b/doc/cprover-manual.md new file mode 100644 index 00000000000..90d609193d9 --- /dev/null +++ b/doc/cprover-manual.md @@ -0,0 +1,2982 @@ +\ingroup module_hidden +\page cprover-manual CProver User Manual + +\author Daniel Kroening + +This tutorial is intended for users of CProver (CBMC, SatAbs, and +associated tools). + +\tableofcontents + +\section man_introduction Introduction + +## Motivation + +Numerous tools to hunt down functional design flaws in silicon have been +available for many years, mainly due to the enormous cost of hardware +bugs. The use of such tools is wide-spread. In contrast, the market for +tools that address the need for quality software is still in its +infancy. + +Research in software quality has an enormous breadth. We focus the +presentation using two criteria: + +1. We believe that any form of quality requires a specific *guarantee*, + in theory and practice. +2. The sheer size of software designs requires techniques that are + highly *automated*. + +In practice, quality guarantees usually do not refer to "total +correctness" of a design, as ensuring the absence of all bugs is too +expensive for most applications. In contrast, a guarantee of the absence +of specific flaws is achievable, and is a good metric of quality. + +We document two programs that try to achieve formal guarantees of the +absence of specific problems: CBMC and SATABS. The algorithms +implemented by CBMC and SATABS are complementary, and often, one tool is +able to solve a problem that the other cannot solve. + +Both CBMC and SATABS are verification tools for ANSI-C/C++ programs. +They verify array bounds (buffer overflows), pointer safety, exceptions +and user-specified assertions. Both tools model integer arithmetic +accurately, and are able to reason about machine-level artifacts such as +integer overflow. CBMC and SATABS are therefore able to detect a class +of bugs that has so far gone unnoticed by many other verification tools. +This manual also covers some variants of CBMC, which includes HW-CBMC +for +\ref man_hard-soft-introduction "hardware/software co-verification". + +## Bounded Model Checking with CBMC + +CBMC implements a technique called *Bounded Model Checking* (BMC). In +BMC, the transition relation for a complex state machine and its +specification are jointly unwound to obtain a Boolean formula, which is +then checked for satisfiability by using an efficient SAT procedure. If +the formula is satisfiable, a counterexample is extracted from the +output of the SAT procedure. If the formula is not satisfiable, the +program can be unwound more to determine if a longer counterexample +exists. + +In many engineering domains, real-time guarantees are a strict +requirement. An example is software embedded in automotive controllers. +As a consequence, the loop constructs in these types of programs often +have a strict bound on the number of iterations. CBMC is able to +formally verify such bounds by means of *unwinding assertions*. Once +this bound is established, CBMC is able to prove the absence of errors. + +A more detailed description of how to apply CBMC to verify programs is +\ref man_cbmc-tutorial "here". + +## Automatic Program Verification with SATABS + +In many cases, lightweight properties such as array bounds do not rely +on the entire program. A large fraction of the program is *irrelevant* +to the property. SATABS exploits this observation and computes an +*abstraction* of the program in order to handle large amounts of code. + +In order to use SATABS it is not necessary to understand the abstraction +refinement process. For the interested reader, a high-level introduction +to abstraction refinement is provided +\ref man_satabs-overview "here". +We also provide +\ref man_satabs-tutorials "tutorials on how to use SATABS". + +Just as CBMC, SATABS attempts to build counterexamples that refute the +property. If such a counterexample is found, it is presented to the +engineer to facilitate localization and repair of the program. + +### Example: Buffer Overflows + +In order to give a brief overview of the capabilities of CBMC and SATABS +we start with a small example. The issue of *[buffer +overflows](http://en.wikipedia.org/wiki/Buffer_overflow)* has obtained +wide public attention. A buffer is a contiguously-allocated chunk of +memory, represented by an array or a pointer in C. Programs written in C +do not provide automatic bounds checking on the buffer, which means a +program can – accidentally or maliciously – write past a buffer. The +following example is a perfectly valid C program (in the sense that a +compiler compiles it without any errors): + +```{.c} +int main() +{ + int buffer[10]; + buffer[20] = 10; +} +``` + +However, the write access to an address outside the allocated memory +region can lead to unexpected behavior. In particular, such bugs can be +exploited to overwrite the return address of a function, thus enabling +the execution of arbitrary user-induced code. CBMC and SATABS are able +to detect this problem and reports that the "upper bound property" of +the buffer is violated. CBMC and SATABS are capable of checking these +lower and upper bounds, even for arrays with dynamic size. A detailed +discussion of the properties that CBMC and SATABS can check +automatically is \ref man_instrumentation-properties "here". + +## Hardware/Software Co-Verification + +Software programs often interact with hardware in a non-trivial manner, +and many properties of the overall design only arise from the interplay +of both components. CBMC and SATABS therefore support *Co-Verification*, +i.e., are able to reason about a C/C++ program together with a circuit +description given in Verilog. + +These co-verification capabilities can also be applied to perform +refinement proofs. Software programs are often used as high-level +descriptions of circuitry. While both describe the same functionality, +the hardware implementation usually contains more detail. It is highly +desirable to establish some form for equivalence between the two +descriptions. Hardware/Software co-verification and equivalence checking +with CBMC and SATABS are described +\ref man_hard-soft-introduction "here". + + +\section man_installation Installation + +\subsection man_install-cbmc Installing CBMC + +### Requirements + +CBMC is available for Windows, i86 Linux, and MacOS X. CBMC requires a +code pre-processing environment comprising of a suitable preprocessor +and an a set of header files. + +1. **Linux:** the preprocessor and the header files typically come with + a package called *gcc*, which must be installed prior to the + installation of CBMC. + +2. **Windows:** The Windows version of CBMC requires the preprocessor + `cl.exe`, which is part of Microsoft Visual Studio. We recommend the + free [Visual Studio Community + 2013](http://www.visualstudio.com/en-us/products/visual-studio-community-vs). + +3. **MacOS:** Install the [XCode Command Line + Utilities](http://developer.apple.com/technologies/xcode.html) prior + to installing CBMC. Just installing XCode alone is not enough. + +Important note for Windows users: Visual Studio's `cl.exe` relies on a +complex set of environment variables to identify the target architecture +and the directories that contain the header files. You must run CBMC +from within the *Visual Studio Command Prompt*. + +Note that the distribution files for the [Eclipse +plugin](installation-plugin.shtml) include the CBMC executable. +Therefore, if you intend to run CBMC exclusively within Eclipse, you can +skip the installation of the CBMC executable. However, you still have to +install the compiler environment as described above. + +### Installing the CBMC Binaries + +1. Download CBMC for your operating system. The binaries are available + from http://www.cprover.org/cbmc/. +2. Unzip/untar the archive into a directory of your choice. We + recommend to add this directory to your `PATH` environment variable. + +You are now ready to \ref man_cbmc-tutorial "use CBMC"! + +### Building CBMC from Source + +Alternatively, the CBMC source code is available [via +SVN](http://www.cprover.org/svn/cbmc/). To compile the source code, +follow [these +instructions](http://www.cprover.org/svn/cbmc/trunk/COMPILING). + +\subsection man_install-satabs Installing SATABS + +### Requirements + +SATABS is available for Windows, i86 Linux, and MacOS X. SATABS requires +a code pre-processing environment comprising of a suitable preprocessor +and an a set of header files. + +1. **Linux:** the preprocessor and the header files typically come with + a package called *gcc*, which must be installed prior to the + installation of SATABS. +2. **Windows:** The Windows version of SATABS requires the preprocessor + `cl.exe`, which is part of Visual Studio (including the free [Visual + Studio + Express](http://msdn.microsoft.com/vstudio/express/visualc/)). +3. **MacOS:** Install + [XCode](http://developer.apple.com/technologies/xcode.html) prior to + installing SATABS. + +Important note for Windows users: Visual Studio's `cl.exe` relies on a +complex set of environment variables to identify the target architecture +and the directories that contain the header files. You must run SATABS +from within the *Visual Studio Command Prompt*. + +Note that the distribution files for the [Eclipse +plugin](installation-plugin.shtml) include the command-line tools. +Therefore, if you intend to run SATABS exclusively within Eclipse, you +can skip the installation of the command-line tools. However, you still +have to install the compiler environment as described above. + +### Choosing and Installing a Model Checker + +You need to install a Model Checker in order to be able to run SATABS. +You can choose between following alternatives: + +- **Cadence SMV**. Available from http://www.kenmcmil.com/smv.html. + Cadence SMV is a commercial model checker. The free version that is + available on the homepage above must not be used for commercial + purposes (read the license agreement thoroughly before you download + the tool). The documentation for SMV can be found in the directory + where you unzip/untar SMV under ./smv/doc/smv/. Read the + installation instructions carefully. The Linux/MacOS versions + require setting environment variables. You must add add the + directory containing the `smv` binary (located in ./smv/bin/, + relative to the path where you unpacked it) to your `PATH` + environment variable. SATABS uses Cadence SMV by default. + +- **NuSMV**. Available from http://nusmv.irst.itc.it/. NuSMV is the + open source alternative to Cadence SMV. Installation instructions + and documentation can be found on the NuSMV homepage. The directory + containing the NuSMV binary should be added to your `PATH` + environment variable. Use the option + + --modelchecker nusmv + + to instruct SATABS to use NuSMV. + +- **BOPPO**. Available from http://www.cprover.org/boppo/. BOPPO is + a model checker that uses SAT-solving algorithms. BOPPO relies on a + built-in SAT solver and Quantor, a solver for quantified boolean + formulas that is currently bundled with BOPPO, but also available + separately from . We recommend to add + the directories containing both tools to your `PATH` environment + variable. Use the option + + --modelchecker boppo + + when you call SATABS and want it to use BOPPO instead of SMV. + +- **BOOM**. Available from http://www.cprover.org/boom/. Boom has a + number of unique features, including the verification of programs + with unbounded thread creation. + +### Installing SATABS + +1. Download SATABS for your operating system. The binaries are + available from . +2. Unzip/untar the archive into a directory of your choice. We + recommend to add this directory to your `PATH` environment variable. + +Now you can execute SATABS. Try running SATABS on the small examples +presented in the \ref man_satabs-tutorials "SATABS tutorial". If you use +the Cadence SMV model checker, the only command line arguments you have +to specify are the names of the files that contain your program. + + +\subsection man_install-eclipse Installing the Eclipse Plugin + +### Requirements + +We provide a graphical user interface to CBMC and SATABS, which is +realized as a plugin to the Eclipse framework. Eclipse is available at +http://www.eclipse.org. We do not provide installation instructions for +Eclipse (basically, you only have to download the current version and +extract the files to your hard-disk) and assume that you have already +installed the current version. + +CBMC and SATABS have their own requirements. As an example, both CBMC and SATABS require a suitable preprocessor and a set of header files. As +first step, you should therefore follow the installation instructions +for \ref man_install-cbmc "CBMC" and \ref man_install-satabs "SATABS". + +Important note for Windows users: Visual Studio's `cl.exe` relies on a +complex set of environment variables to identify the target architecture +and the directories that contain the header files. You must run Eclipse +from within the *Visual Studio Command Prompt*. + +### Installing the Eclipse Plugin + +The installation instructions for the Eclipse Plugin, including the link +to the download site, are available +[here](http://www.cprover.org/eclipse-plugin/). This includes a small +tutorial on how to use the Eclipse plugin. + + +\section man_cbmc CBMC: Bounded Model Checking for C, C++ and Java + +\subsection man_cbmc-tutorial A Short Tutorial + +### First Steps + +We assume you have already installed CBMC and the necessary support +files on your system. If not so, please follow the instructions +\ref man_install-cbmc "here". + +Like a compiler, CBMC takes the names of .c files as command line +arguments. CBMC then translates the program and merges the function +definitions from the various .c files, just like a linker. But instead +of producing a binary for execution, CBMC performs symbolic simulation +on the program. + +As an example, consider the following simple program, named file1.c: + + int puts(const char *s) { } + + int main(int argc, char **argv) { + puts(argv[2]); + } + +Of course, this program is faulty, as the `argv` array might have fewer +than three elements, and then the array access `argv[2]` is out of +bounds. Now, run CBMC as follows: + + cbmc file1.c --show-properties --bounds-check --pointer-check + +The two options `--bounds-check` and `--pointer-check` instruct CBMC to +look for errors related to pointers and array bounds. CBMC will print +the list of properties it checks. Note that it lists, among others, a +property labelled with "object bounds in argv" together with the location +of the faulty array access. As you can see, CBMC largely determines the +property it needs to check itself. This is realized by means of a +preliminary static analysis, which relies on computing a fixed point on +various [abstract +domains](http://en.wikipedia.org/wiki/Abstract_interpretation). More +detail on automatically generated properties is provided +\ref man_instrumentation-properties "here". + +Note that these automatically generated properties need not necessarily +correspond to bugs – these are just *potential* flaws, as abstract +interpretation might be imprecise. Whether these properties hold or +correspond to actual bugs needs to be determined by further analysis. + +CBMC performs this analysis using *symbolic simulation*, which +corresponds to a translation of the program into a formula. The formula +is then combined with the property. Let's look at the formula that is +generated by CBMC's symbolic simulation: + + cbmc file1.c --show-vcc --bounds-check --pointer-check + +With this option, CBMC performs the symbolic simulation and prints the +verification conditions on the screen. A verification condition needs to +be proven to be valid by a [decision +procedure](http://en.wikipedia.org/wiki/Decision_problem) in order to +assert that the corresponding property holds. Let's run the decision +procedure: + + cbmc file1.c --bounds-check --pointer-check + +CBMC transforms the equation you have seen before into CNF and passes it +to a SAT solver (more background on this step is in the book on +[Decision Procedures](http://www.decision-procedures.org/)). It then +determines which of the properties that it has generated for the program +hold and which do not. Using the SAT solver, CBMC detects that the +property for the object bounds of `argv` does not hold, and will thus +print a line as follows: + + [main.pointer_dereference.6] dereference failure: object bounds in argv[(signed long int)2]: FAILURE + +### Counterexample Traces + +Let us have a closer look at this property and why it fails. To aid the +understanding of the problem, CBMC can generate a *counterexample trace* +for failed properties. To obtain this trace, run + + cbmc file1.c --bounds-check --trace + +CBMC then prints a counterexample trace, i.e., a program trace that +begins with `main` and ends in a state which violates the property. In +our example, the program trace ends in the faulty array access. It also +gives the values the input variables must have for the bug to occur. In +this example, `argc` must be one to trigger the out-of-bounds array +access. If you add a branch to the example that requires that `argc>=3`, +the bug is fixed and CBMC will report that the proofs of all properties +have been successful. + +### Verifying Modules + +In the example above, we used a program that starts with a `main` +function. However, CBMC is aimed at embedded software, and these kinds +of programs usually have different entry points. Furthermore, CBMC is +also useful for verifying program modules. Consider the following +example, called file2.c: + + int array[10]; + int sum() { + unsigned i, sum; + + sum=0; + for(i=0; i<10; i++) + sum+=array[i]; + } + +In order to set the entry point to the `sum` function, run + + cbmc file2.c --function sum --bounds-check + +It is often necessary to build a suitable *harness* for the function in +order to set up the environment appropriately. + +### Loop Unwinding + +When running the previous example, you will have noted that CBMC unwinds +the `for` loop in the program. As CBMC performs Bounded Model Checking, +all loops have to have a finite upper run-time bound in order to +guarantee that all bugs are found. CBMC can optionally check that enough +unwinding is performed. As an example, consider the program binsearch.c: + + int binsearch(int x) { + int a[16]; + signed low=0, high=16; + + while(low>1); + + if(a[middle]x) + low=middle+1; + else // a[middle]==x + return middle; + } + + return -1; + } + +If you run CBMC on this function, you will notice that the unwinding +does not stop on its own. The built-in simplifier is not able to +determine a run time bound for this loop. The unwinding bound has to be +given as a command line argument: + + cbmc binsearch.c --function binsearch --unwind 6 --bounds-check --unwinding-assertions + +CBMC verifies that verifies the array accesses are within the bounds; +note that this actually depends on the result of the right shift. In +addition, as CBMC is given the option `--unwinding-assertions`, it also +checks that enough unwinding is done, i.e., it proves a run-time bound. +For any lower unwinding bound, there are traces that require more loop +iterations. Thus, CBMC will report that the unwinding assertion has +failed. As usual, a counterexample trace that documents this can be +obtained with the option `--property`. + +### Unbounded Loops + +CBMC can also be used for programs with unbounded loops. In this case, +CBMC is used for bug hunting only; CBMC does not attempt to find all +bugs. The following program (lock-example.c) is an example of a program +with a user-specified property: + + _Bool nondet_bool(); + _Bool LOCK = 0; + + _Bool lock() { + if(nondet_bool()) { + assert(!LOCK); + LOCK=1; + return 1; } + + return 0; + } + + void unlock() { + assert(LOCK); + LOCK=0; + } + + int main() { + unsigned got_lock = 0; + int times; + + while(times > 0) { + if(lock()) { + got_lock++; + /* critical section */ + } + + if(got_lock!=0) + unlock(); + + got_lock--; + times--; + } + } + +The `while` loop in the `main` function has no (useful) run-time bound. +Thus, a bound has to be set on the amount of unwinding that CBMC +performs. There are two ways to do so: + +1. The `--unwind` command-line parameter can to be used to limit the + number of times loops are unwound. +2. The `--depth` command-line parameter can be used to limit the number + of program steps to be processed. + +Given the option `--unwinding-assertions`, CBMC checks whether the +arugment to `--unwind` is large enough to cover all program paths. If +the argument is too small, CBMC will detect that not enough unwinding is +done reports that an unwinding assertion has failed. + +Reconsider the example. For a loop unwinding bound of one, no bug is +found. But already for a bound of two, CBMC detects a trace that +violates an assertion. Without unwinding assertions, or when using the +`--depth` command line switch, CBMC does not prove the program correct, +but it can be helpful to find program bugs. The various command line +options that CBMC offers for loop unwinding are described in the section +on \ref man_cbmc-loops "understanding loop unwinding". + +### A Note About Compilers and the ANSI-C Library + +Most C programs make use of functions provided by a library; instances +are functions from the standard ANSI-C library such as `malloc` or +`printf`. The verification of programs that use such functions has two +requirements: + +1. Appropriate header files have to be provided. These header files + contain *declarations* of the functions that are to be used. +2. Appropriate *definitions* have to be provided. + +Most C compilers come with header files for the ANSI-C library +functions. We briefly discuss how to obtain/install these library files. + +#### Linux + +Linux systems that are able to compile software are usually equipped +with the appropriate header files. Consult the documentation of your +distribution on how to install the compiler and the header files. First +try to compile some significant program before attempting to verify it. + +#### Windows + +On Microsoft Windows, CBMC is pre-configured to use the compiler that is +part of Microsoft's Visual Studio. Microsoft's [Visual Studio +Community](http://www.visualstudio.com/en-us/products/visual-studio-community-vs) +is fully featured and available for download for free from the Microsoft +webpage. Visual Studio installs the usual set of header files together +with the compiler. However, the Visual Studio compiler requires a large +set of environment variables to function correctly. It is therefore +required to run CBMC from the *Visual Studio Command Prompt*, which can +be found in the menu *Visual Studio Tools*. + +Note that in both cases, only header files are available. CBMC only +comes with a small set of definitions, which includes functions such as +`malloc`. Detailed information about the built-in definitions is +\ref man_instrumentation-libraries "here". + +### Command Line Interface + +This section describes the command line interface of CBMC. Like a C +compiler, CBMC takes the names of the .c source files as arguments. +Additional options allow to customize the behavior of CBMC. Use +`cbmc --help` to get a full list of the available options. + +Structured output can be obtained from CBMC using the option `--xml-ui`. +Any output from CBMC (e.g., counterexamples) will then use an XML +representation. + +### Further Reading + +- \ref man_cbmc-loops "Understanding Loop Unwinding" +- [Hardware Verification using ANSI-C Programs as a + Reference](http://www-2.cs.cmu.edu/~svc/papers/view-publications-ck03.html) +- [Behavioral Consistency of C and Verilog Programs Using Bounded + Model Checking](http://www-2.cs.cmu.edu/~svc/papers/view-publications-cky03.html) +- [A Tool for Checking ANSI-C + Programs](http://www-2.cs.cmu.edu/~svc/papers/view-publications-ckl2004.html) + +We also have a [list of interesting applications of +CBMC](http://www.cprover.org/cbmc/applications/). + + +\subsection man_cbmc-loops Understanding Loop Unwinding + +### Iteration-based Unwinding + +The basic idea of CBMC is to model the computation of the programs up to +a particular depth. Technically, this is achieved by a process that +essentially amounts to *unwinding loops*. This concept is best +illustrated with a generic example: + + int main(int argc, char **argv) { + while(cond) { + BODY CODE + } + } + +A BMC instance that will find bugs with up to five iterations of the +loop would contain five copies of the loop body, and essentially +corresponds to checking the following loop-free program: + + int main(int argc, char **argv) { + if(cond) { + BODY CODE COPY 1 + if(cond) { + BODY CODE COPY 2 + if(cond) { + BODY CODE COPY 3 + if(cond) { + BODY CODE COPY 4 + if(cond) { + BODY CODE COPY 5 + } + } + } + } + } + } + +Note the use of the `if` statement to prevent the execution of the loop +body in the case that the loop ends before five iterations are executed. +The construction above is meant to produce a program that is trace +equivalent with the original programs for those traces that contain up +to five iterations of the loop. + +In many cases, CBMC is able to automatically determine an upper bound on +the number of loop iterations. This may even work when the number of +loop unwindings is not constant. Consider the following example: + + _Bool f(); + + int main() { + for(int i=0; i<100; i++) { + if(f()) break; + } + assert(0); + } + +The loop in the program above has an obvious upper bound on the number +of iterations, but note that the loop may abort prematurely depending on +the value that is returned by `f()`. CBMC is nevertheless able to +automatically unwind the loop to completion. + +This automatic detection of the unwinding bound may fail if the number +of loop iterations is highly data-dependent. Furthermore, the number of +iterations that are executed by any given loop may be too large or may +simply be unbounded. For this case, CBMC offers the command-line option +`--unwind B`, where `B` denotes a number that corresponds to the maximal +number of loop unwindings CBMC performs on any loop. + +Note that the number of unwindings is measured by counting the number of +*backjumps*. In the example above, note that the condition `i<100` is in +fact evaluated 101 times before the loop terminates. Thus, the loop +requires a limit of 101, and not 100. + +### Setting Separate Unwinding Limits + +The setting given with `--unwind` is used globally, that is, for all +loops in the program. In order to set individual limits for the loops, +first use + + --show-loops + +to obtain a list of all loops in the program. Then identify the loops +you need to set a separate bound for, and note their loop ID. Then use + + --unwindset L:B,L:B,... + +where `L` denotes a loop ID and `B` denotes the bound for that loop. + +As an example, consider a program with two loops in the function main: + + --unwindset c::main.0:10,c::main.1:20 + +This sets a bound of 10 for the first loop, and a bound of 20 for the +second loop. + +What if the number of unwindings specified is too small? In this case, +bugs that require paths that are deeper may be missed. In order to +address this problem, CBMC can optionally insert checks that the given +unwinding bound is actually sufficiently large. These checks are called +*unwinding assertions*, and are enabled with the option +`--unwinding-assertions`. Continuing the generic example above, this +unwinding assertion for a bound of five corresponds to checking the +following loop-free program: + + int main(int argc, char **argv) { + if(cond) { + BODY CODE COPY 1 + if(cond) { + BODY CODE COPY 2 + if(cond) { + BODY CODE COPY 3 + if(cond) { + BODY CODE COPY 4 + if(cond) { + BODY CODE COPY 5 + assert(!cond); + } + } + } + } + } + } + +The unwinding assertions can be verified just like any other generated +assertion. If all of them are proven to hold, the given loop bounds are +sufficient for the program. This establishes a [high-level worst-case +execution time](http://en.wikipedia.org/wiki/Worst-case_execution_time) +(WCET). + +In some cases, it is desirable to cut off very deep loops in favor of +code that follows the loop. As an example, consider the following +program: + + int main() { + for(int i=0; i<10000; i++) { + BODY CODE + } + assert(0); + } + +In the example above, small values of `--unwind` will prevent that the +assertion is reached. If the code in the loop is considered irrelevant +to the later assertion, use the option + + --partial-loops + +This option will allow paths that execute loops only partially, enabling +a counterexample for the assertion above even for small unwinding +bounds. The disadvantage of using this option is that the resulting path +may be spurious, i.e., may not exist in the original program. + +### Depth-based Unwinding + +The loop-based unwinding bound is not always appropriate. In particular, +it is often difficult to control the size of the generated formula when +using the `--unwind` option. The option + + --depth nr + +specifies an unwinding bound in terms of the number of instructions that +are executed on a given path, irrespectively of the number of loop +iterations. Note that CBMC uses the number of instructions in the +control-flow graph as the criterion, not the number of instructions in +the source code. + +\subsection man_cbmc-cover COVER: Test Suite Generation with CBMC + + +### A Small Tutorial with A Case Study + +We assume that CBMC is installed on your system. If not so, follow +\ref man_install-cbmc "these instructions". + +CBMC can be used to automatically generate test cases that satisfy a +certain [code coverage](https://en.wikipedia.org/wiki/Code_coverage) +criteria. Common coverage criteria include branch coverage, condition +coverage and [Modified Condition/Decision Coverage +(MC/DC)](https://en.wikipedia.org/wiki/Modified_condition/decision_coverage). +Among others, MC/DC is required by several avionics software development +guidelines to ensure adequate testing of safety critical software. +Briefly, in order to satisfy MC/DC, for every conditional statement +containing boolean decisions, each Boolean variable should be evaluated +one time to "true" and one time to "false", in a way that affects the +outcome of the decision. + +In the following, we are going to demonstrate how to apply the test +suite generation functionality in CBMC, by means of a case study. The +following program is an excerpt from a real-time embedded benchmark +[PapaBench](https://www.irit.fr/recherches/ARCHI/MARCH/rubrique.php3?id_rubrique=97), +and implements part of a fly-by-wire autopilot for an Unmanned Aerial +Vehicle (UAV). It is adjusted mildly for our purposes. + +The aim of function `climb_pid_run` is to control the vertical climb of +the UAV. Details on the theory behind this operation are documented in +the [wiki](https://wiki.paparazziuav.org/wiki/Theory_of_Operation) for +the Paparazzi UAV project. The behaviour of this simple controller, +supposing that the desired speed is 0.5 meters per second, is plotted in +the Figure below. + +\image html pid.png "The pid controller" + + 01: // CONSTANTS: + 02: #define MAX_CLIMB_SUM_ERR 10 + 03: #define MAX_CLIMB 1 + 04: + 05: #define CLOCK 16 + 06: #define MAX_PPRZ (CLOCK*600) + 07: + 08: #define CLIMB_LEVEL_GAZ 0.31 + 09: #define CLIMB_GAZ_OF_CLIMB 0.75 + 10: #define CLIMB_PITCH_OF_VZ_PGAIN 0.05 + 11: #define CLIMB_PGAIN -0.03 + 12: #define CLIMB_IGAIN 0.1 + 13: + 14: const float pitch_of_vz_pgain=CLIMB_PITCH_OF_VZ_PGAIN; + 15: const float climb_pgain=CLIMB_PGAIN; + 16: const float climb_igain=CLIMB_IGAIN; + 17: const float nav_pitch=0; + 18: + 19: /** PID function INPUTS */ + 20: // The user input: target speed in vertical direction + 21: float desired_climb; + 22: // Vertical speed of the UAV detected by GPS sensor + 23: float estimator_z_dot; + 24: + 25: /** PID function OUTPUTS */ + 26: float desired_gaz; + 27: float desired_pitch; + 28: + 29: /** The state variable: accumulated error in the control */ + 30: float climb_sum_err=0; + 31: + 32: /** Computes desired_gaz and desired_pitch */ + 33: void climb_pid_run() + 34: { + 35: + 36: float err=estimator_z_dot-desired_climb; + 37: + 38: float fgaz=climb_pgain*(err+climb_igain*climb_sum_err)+CLIMB_LEVEL_GAZ+CLIMB_GAZ_OF_CLIMB*desired_climb; + 39: + 40: float pprz=fgaz*MAX_PPRZ; + 41: desired_gaz=((pprz>=0 && pprz<=MAX_PPRZ) ? pprz : (pprz>MAX_PPRZ ? MAX_PPRZ : 0)); + 42: + 43: /** pitch offset for climb */ + 44: float pitch_of_vz=(desired_climb>0) ? desired_climb*pitch_of_vz_pgain : 0; + 45: desired_pitch=nav_pitch+pitch_of_vz; + 46: + 47: climb_sum_err=err+climb_sum_err; + 48: if (climb_sum_err>MAX_CLIMB_SUM_ERR) climb_sum_err=MAX_CLIMB_SUM_ERR; + 49: if (climb_sum_err<-MAX_CLIMB_SUM_ERR) climb_sum_err=-MAX_CLIMB_SUM_ERR; + 50: + 51: } + 52: + 53: int main() + 54: { + 55: + 56: while(1) + 57: { + 58: /** Non-deterministic input values */ + 59: desired_climb=nondet_float(); + 60: estimator_z_dot=nondet_float(); + 61: + 62: /** Range of input values */ + 63: __CPROVER_assume(desired_climb>=-MAX_CLIMB && desired_climb<=MAX_CLIMB); + 64: __CPROVER_assume(estimator_z_dot>=-MAX_CLIMB && estimator_z_dot<=MAX_CLIMB); + 65: + 66: __CPROVER_input("desired_climb", desired_climb); + 67: __CPROVER_input("estimator_z_dot", estimator_z_dot); + 68: + 69: climb_pid_run(); + 70: + 71: __CPROVER_output("desired_gaz", desired_gaz); + 72: __CPROVER_output("desired_pitch", desired_pitch); + 73: + 74: } + 75: + 76: return 0; + 77: } + +In order to test the PID controller, we construct a main control loop, +which repeatedly invokes the function `climb_pid_run` (line 69). This +PID function has two input variables: the desired speed `desired_climb` +and the estimated speed `estimated_z_dot`. In the beginning of each loop +iteration, values of the inputs are assigned non-deterministically. +Subsequently, the `__CPROVER_assume` statement in lines 63 and 64 +guarantees that both values are bounded within a valid range. The +`__CPROVER_input` and `__CPROVER_output` will help clarify the inputs +and outputs of interest for generating test suites. + +To demonstrate the automatic test suite generation in CBMC, we call the +following command and we are going to explain the command line options +one by one. + + cbmc pid.c --cover mcdc --unwind 6 --xml-ui + +The option `--cover mcdc` specifies the code coverage criterion. There +are four conditional statements in the PID function: in line 41, line +44, line 48 and line 49. To satisfy MC/DC, the test suite has to meet +multiple requirements. For instance, each conditional statement needs to +evaluate to *true* and *false*. Consider the condition +`"pprz>=0 && pprz<=MAX_PPRZ"` in line 41. CBMC instruments three +coverage goals to control the respective evaluated results of +`"pprz>=0"` and `"pprz<=MAX_PPRZ"`. We list them in below and they +satisfy the MC/DC rules. Note that `MAX_PPRZ` is defined as 16 \* 600 in +line 06 of the program. + + !(pprz >= (float)0) && pprz <= (float)(16 * 600) id="climb_pid_run.coverage.1" + pprz >= (float)0 && !(pprz <= (float)(16 * 600)) id="climb_pid_run.coverage.2" + pprz >= (float)0 && pprz <= (float)(16 * 600) id="climb_pid_run.coverage.3" + +The "id" of each coverage goal is automatically assigned by CBMC. For +every coverage goal, a test suite (if there exists) that satisfies such +a goal is printed out in XML format, as the parameter `--xml-ui` is +given. Multiple coverage goals can share a test suite, when the +corresponding execution of the program satisfies all these goals at the +same time. + +In the end, the following test suites are automatically generated for +testing the PID controller. A test suite consists of a sequence of input +parameters that are passed to the PID function `climb_pid_run` at each +loop iteration. For example, Test 1 covers the MC/DC goal with +id="climb\_pid\_run.coverage.1". The complete output from CBMC is in +[pid\_test\_suites.xml](pid_test_suites.xml), where every test suite and +the coverage goals it is for are clearly described. + + Test suite: + Test 1. + (iteration 1) desired_climb=-1.000000f, estimator_z_dot=1.000000f + + Test 2. + (iteration 1) desired_climb=-1.000000f, estimator_z_dot=1.000000f + (iteration 2) desired_climb=1.000000f, estimator_z_dot=-1.000000f + + Test 3. + (iteration 1) desired_climb=0.000000f, estimator_z_dot=-1.000000f + (iteration 2) desired_climb=1.000000f, estimator_z_dot=-1.000000f + + Test 4. + (iteration 1) desired_climb=1.000000f, estimator_z_dot=-1.000000f + (iteration 2) desired_climb=1.000000f, estimator_z_dot=-1.000000f + (iteration 3) desired_climb=1.000000f, estimator_z_dot=-1.000000f + (iteration 4) desired_climb=1.000000f, estimator_z_dot=-1.000000f + (iteration 5) desired_climb=0.000000f, estimator_z_dot=-1.000000f + (iteration 6) desired_climb=1.000000f, estimator_z_dot=-1.000000f + + Test 5. + (iteration 1) desired_climb=-1.000000f, estimator_z_dot=1.000000f + (iteration 2) desired_climb=-1.000000f, estimator_z_dot=1.000000f + (iteration 3) desired_climb=-1.000000f, estimator_z_dot=1.000000f + (iteration 4) desired_climb=-1.000000f, estimator_z_dot=1.000000f + (iteration 5) desired_climb=-1.000000f, estimator_z_dot=1.000000f + (iteration 6) desired_climb=-1.000000f, estimator_z_dot=1.000000f + +The option `--unwind 6` unwinds the loop inside the main function body +six times. In order to achieve the complete coverage on all the +instrumented goals in the PID function `climb_pid_run`, the loop must be +unwound sufficient enough times. For example, `climb_pid_run` needs to +be called at least six times for evaluating the condition +`climb_sum_err>MAX_CLIMB_SUM_ERR` in line 48 to *true*. This corresponds +to the Test 5. An introduction to the use of loop unwinding can be found +in [Understanding Loop Unwinding](cbmc-loops.shtml). + +In this small tutorial, we present the automatic test suite generation +functionality of CBMC, by applying the MC/DC code coverage criterion to +a PID controller case study. In addition to `--cover mcdc`, other +coverage criteria like `branch`, `decision`, `path` etc. are also +available when calling CBMC. + +### Coverage Criteria + +The table below summarizes the coverage criteria that CBMC supports. + +Criterion |Definition +----------|---------- +assertion |For every assertion, generate a test that reaches it +location |For every location, generate a test that reaches it +branch |Generate a test for every branch outcome +decision |Generate a test for both outcomes of every Boolean expression that is not an operand of a propositional connective +condition |Generate a test for both outcomes of every Boolean expression +mcdc |Modified Condition/Decision Coverage (MC/DC) +path |Bounded path coverage +cover |Generate a test for every `__CPROVER_cover` statement + + +\section man_satabs SATABS---Predicate Abstraction with SAT + +\subsection man_satabs-overview Overview + +This section describes SATABS from the point of view of the user. To +learn about the technology implemented in SATABS, read +\ref man_satabs-background "this". + +We assume you have already installed SATABS and the necessary support +files on your system. If not so, please follow +\ref man_install-satabs "these instructions". + +While users of SATABS almost never have to be concerned about the +underlying refinement abstraction algorithms, understanding the classes +of properties that can be verified is crucial. Predicate abstraction is +most effective when applied to *control-flow dominated properties*. As +an example, reconsider the following program (lock-example-fixed.c): + + _Bool nondet_bool(); + _Bool LOCK = 0; + + _Bool lock() { + if(nondet_bool()) { + assert(!LOCK); + LOCK=1; + return 1; } + + return 0; + } + + void unlock() { + assert(LOCK); + LOCK=0; + } + + int main() { + unsigned got_lock = 0; + int times; + + while(times > 0) { + if(lock()) { + got_lock++; + /* critical section */ + } + + if(got_lock!=0) { + unlock(); + got_lock--; + } + + times--; + } + } + +The two assertions in the program model that the functions `lock()` and +`unlock()` are called in the right order. Note that the value of `times` +is chosen non-deterministically and is not bounded. The program has no +run-time bound, and thus, unwinding the code with CBMC will never +terminate. + +### Working with Claims + +The two assertions will give rise to two *properties*. Each property is +associated to a specific line of code, i.e., a property is violated when +some condition can become false at the corresponding program location. +SATABS will generate a list of all properties for the programs as +follows: + + satabs lock-example-fixed.c --show-properties + +SATABS will list two properties; each property corresponds to one of the +two assertions. We can use SATABS to verify both properties as follows: + + satabs lock-example-fixed.c + +SATABS will conclude the verification successfully, that is, both +assertions hold for execution traces of any length. + +By default, SATABS attempts to verify all properties at once. A single +property can be verified (or refuted) by using the `--property id` +option of SATABS, where `id` denotes the identifier of the property in +the list obtained by calling SATABS with the `--show-properties` flag. +Whenever a property is violated, SATABS reports a feasible path that +leads to a state in which the condition that corresponds to the violated +property evaluates to false. + +\subsection man_satabs-libraries Programs that use Libraries + +SATABS cannot check programs that use functions that are only available +in binary (compiled) form (this restriction is not imposed by the +verification algorithms that are used by SATABS – they also work on +assembly code). The reason is simply that so far no assembly language +frontend is available for SATABS. At the moment, (library) functions for +which no C source code is available have to be replaced by stubs. The +usage of stubs and harnesses (as known from unit testing) also allows to +check more complicated properties (like, for example, whether function +`fopen` is always called before `fclose`). This technique is explained +in detail in the \ref man_satabs-tutorials "SATABS tutorials". + +\subsection man_satabs-unit-test Unit Testing with SATABS + +The example presented \ref man_satabs-tutorial-driver "here" is +obviously a toy example and can hardly be used to convince your project +manager to use static verification in your next project. Even though we +recommend to use formal verification and specification already in the +early phases of your project, the sad truth is that in most projects +verification (of any kind) is still pushed to the very end of the +development cycle. Therefore, this section is dedicated to the +verification of legacy code. However, the techniques presented here can +also be used for *unit testing*. + +Unit testing is used in most software development projects, and static +verification with SATABS can be very well combined with this technique. +Unit testing relies on a number test cases that yield the desired code +coverage. Such test cases are implemented by a software testing engineer +in terms of a test harness (aka test driver) and a set of function +stubs. Typically, a slight modification to the test harness allows it to +be used with SATABS. Replacing the explicit input values with +non-deterministic inputs (as explained in +\ref man_satabs-tutorial-aeon "here" and +\ref man_satabs-tutorial-driver "here")) guarantees that SATABS will try +to achieve **full** path and state coverage (due to the fact that +predicate abstraction implicitly detects equivalence classes). However, +it is not guaranteed that SATABS terminates in all cases. Keep in mind +that you must not make any assumptions about the validity of the +properties if SATABS did not run to completion! + +### Further Reading + +- [Model Checking Concurrent Linux Device + Drivers](http://www.kroening.com/publications/view-publications-wbwk2007.html) +- [SATABS: SAT-based Predicate Abstraction for + ANSI-C](http://www-2.cs.cmu.edu/~svc/papers/view-publications-cksy2005.html) +- [Predicate Abstraction of ANSI-C Programs using + SAT](http://www-2.cs.cmu.edu/~svc/papers/view-publications-cksy2004.html) + +\subsection man_satabs-background Background + +### Sound Abstractions + +This section provides background information on how SATABS operates. +Even for very trivial C programs it is impossible to exhaustively +examine their state space (which is potentially unbounded). However, not +all details in a C program necessarily contribute to a bug, so it may be +sufficient to only examine those parts of the program that are somehow +related to a bug. + +In practice, many static verification tools (such as `lint`) try to +achieve this goal by applying heuristics. This approach comes at a cost: +bugs might be overlooked because the heuristics do not cover all +relevant aspects of the program. Therefore, the conclusion that a +program is correct whenever such a static verification tool is unable to +find an error is invalid. + +\image html cegar-1.png "CEGAR Loop" + +A more sophisticated approach that has been very successful recently is +to generate a *sound* abstraction of the original program. In this +context, *soundness* refers to the fact that the abstract program +contains (at least) all relevant behaviors (i.e., bugs) that are present +in the original program. In the Figure above, the first component strips +details from the original program. The number of possible behaviors +increases as the number of details in the abstract program decreases. +Intuitively, the reason is that whenever the model checking tool lacks +the information that is necessary to make an accurate decision on +whether a branch of an control flow statement can be taken or not, both +branches have to be considered. + +In the resulting *abstract program*, a set of concrete states is +subsumed by means of a single abstract state. Consider the following +figure: + +![](states.png) + +The concrete states *x*~1~ and *x*~2~ are mapped to an abstract state +*X*, and similarly *Y* subsumes *y*~1~ and *y*~2~. However, all +transitions that are possible in the concrete program are also possible +in the abstract model. The abstract transition *X* → *Y* summarizes the +concrete transitions *x*~1~ → *y*~1~ and *x*~1~ → *x*~1~, and *Y* → *X* +corresponds to *x*~1~ → *x*~2~. The behavior *X* → *Y* → *X* is feasible +in the original program, because it maps to *x*~1~ → *x*~1~ → *x*~2~. +However, *Y* → *X* → *Y* is feasible only in the abstract model. + +### Spurious Counterexamples + +The consequence is that the model checker (component number two in the +figure above) possibly reports a *spurious* counterexample. We call a +counterexample spurious whenever it is feasible in the current abstract +model but not in the original program. However, whenever the model +checker is unable to find an execution trace that violates the given +property, we can conclude that there is no such trace in the original +program, either. + +The feasibility of counterexamples is checked by *symbolic simulation* +(performed by component three in the figure above). If the +counterexample is indeed feasible, SATABS found a bug in the original +program and reports it to the user. + +### Automatic Refinement + +On the other hand, infeasible counterexamples (that originate from +abstract behaviors that result from the omission of details and are not +present in the original program) are never reported to the user. +Instead, the information is used in order to refine the abstraction such +that the spurious counterexample is not part of the refined model +anymore. For instance, the reason for the infeasibility of *Y* → *X* → +*Y* is that neither *y*~1~ nor *x*~1~ can be reached from *x*~2~. +Therefore, the abstraction can be refined by partitioning *X*. + +The refinement steps can be illustrated as follows: + +![Iterative refinement](refinement.png) + +The first step (1) is to generate a very coarse abstraction with a very +small state space. This abstraction is then successively refined (2, 3, +...) until either a feasible counterexample is found or the abstract +program is detailed enough to show that there is no path that leads to a +violation of the given property. The problem is that this point is not +necessarily reached for every input program, i.e., it is possible that +the the abstraction refinement loop never terminates. Therefore, SATABS +allows to specify an upper bound for the number of iterations. + +When this upper bound is reached and no counterexample was found, this +does not necessarily mean that there is none. In this case, you cannot +make any conclusions at all with respect to the correctness of the input +program. + +\subsection man_satabs-tutorials Tutorials + +We provide an introduction to model checking "real" C programs with +SATABS using two small examples. + +\subsubsection man_satabs-tutorial-driver Reference Counting in Linux Device Drivers + +Microsoft's [SLAM](http://research.microsoft.com/SLAM) toolkit has been +successfully used to find bugs in Windows device drivers. SLAM +automatically verifies device driver whether a device driver adheres to +a set of specifications. SLAM provides a test harness for device drivers +that calls the device driver dispatch routines in a non-deterministic +order. Therefore, the Model Checker examines all combinations of calls. +Motivated by the success this approach, we provide a toy example based +on Linux device drivers. For a more complete approach to the +verification of Linux device drivers, consider +[DDVerify](http://www.cprover.org/ddverify/). + +Dynamically loadable modules enable the Linux Kernel to load device +drivers on demand and to release them when they are not needed anymore. +When a device driver is registered, the kernel provides a major number +that is used to uniquely identify the device driver. The corresponding +device can be accessed through special files in the filesystem; by +convention, they are located in the `/dev` directory. If a process +accesses a device file the kernel calls the corresponding `open`, `read` +and `write` functions of the device driver. Since a driver must not be +released by the kernel as long as it is used by at least one process, +the device driver must maintain a usage counter (in more recent Linux +kernels, this is done automatically, however, drivers that must maintain +backward compatibility have to adjust this counter). + +We provide a skeleton of such a driver. Download the files +assets/spec.c, assets/driver.c, assets/driver.h, assets/kdev_t.h, and +assets/modules.h. + +The driver contains following functions: + +1. `register_chrdev`: (in assets/spec.c) Registers a character device. + In our implementation, the function sets the variable `usecount` to + zero and returns a major number for this device (a constant, if the + user provides 0 as argument for the major number, and the value + specified by the user otherwise). + + int usecount; + + int register_chrdev (unsigned int major, const char* name) + { + usecount = 0; + if (major == 0) + return MAJOR_NUMBER; + return major; + } + +2. `unregister_chrdev`: (in assets/spec.c) Unregisters a character + device. This function asserts that the device is not used by any + process anymore (we use the macro `MOD_IN_USE` to check this). + + int unregister_chrdev (unsigned int major, const char* name) + { + if (MOD_IN_USE) + { + ERROR: assert (0); + } + else + return 0; + } + +3. `dummy_open`: (in assets/driver.c) This function increases the + `usecount`. If the device is locked by some other process + `dummy_open` returns -1. Otherwise it locks the device for the + caller. + +4. `dummy_read`: (in assets/driver.c) This function "simulates" a read + access to the device. In fact it does nothing, since we are + currently not interested in the potential buffer overflow that may + result from a call to this function. Note the usage of the function + `nondet_int`: This is an internal SATABS-function that + non­determi­nistically returns an arbitrary integer value. The + function `__CPROVER_assume` tells SATABS to ignore all traces that + do not adhere to the given assumption. Therefore, whenever the lock + is held, `dummy_read` will return a value between 0 and `max`. If + the lock is not held, then `dummy_read` returns -1. + +5. `dummy_release`: (in assets/driver.c) If the lock is held, then + `dummy_release` decreases the `usecount`, releases the lock, and + returns 0. Otherwise, the function returns -1. + +We now want to check if any *valid* sequence of calls of the dispatch +functions (in driver.c) can lead to the violation of the assertion (in +assets/spec.c). Obviously, a call to `dummy_open` that is immediately +followed by a call to `unregister_chrdev` violates the assertion. + +The function `main` in spec.c gives an example of how these functions +are called. First, a character device "`dummy`" is registered. The major +number is stored in the `inode` structure of the device. The values for +the file structure are assigned non-deterministically. We rule out +invalid sequences of calls by ensuring that no device is unregistered +while it is still locked. We use the following model checking harness +for calling the dispatching functions: + + random = nondet_uchar (); + __CPROVER_assume (0 <= random && random <= 3); + + switch (random) + { + case 1: + rval = dummy_open (&inode, &my_file); + if (rval == 0) + lock_held = TRUE; + break; + case 2: + __CPROVER_assume (lock_held); + count = dummy_read (&my_file, buffer, BUF_SIZE); + break; + case 3: + dummy_release (&inode, &my_file); + lock_held = FALSE; + break; + default: + break; + } + +The variable `random` is assigned non-deterministically. Subsequently, +the value of `random` is restricted to be 0 &le `random` ≤ 3 by a call +to `__CPROVER_assume`. Whenever the value of `random` is not in this +interval, the corresponding execution trace is simply discarded by +SATABS. Depending on the value of `random`, the harness calls either +`dummy_open`, `dummy_read` or `dummy_close`. Therefore, if there is a +sequence of calls to these three functions that leads to a violation of +the assertion in `unregister_chrdev`, then SATABS will eventually +consider it. + +If we ask SATABS to show us the properties it verifies with + + satabs driver.c spec.c --show-properties + +for our example, we obtain + +1. Claim unregister\_chrdev.1:\ +     file spec.c line 18 function unregister\_chrdev\ +     MOD\_IN\_USE in unregister\_chrdev\ +     FALSE + +2. Claim dummy\_open.1:\ +     file driver.c line 15 function dummy\_open\ +     i\_rdev mismatch\ +     (unsigned int)inode->i\_rdev >> 8 == (unsigned + int)dummy\_major + +It seems obvious that the property dummy\_open.1 can never be violated. +SATABS confirms this assumption: We call + + satabs driver.c spec.c --property dummy_open.1 + +and SATABS reports `VERIFICATION SUCCESSFUL` after a few iterations. + +If we try to verify property unregister\_chrdev.1, SATABS reports that +the property in line 18 in file spec.c is violated (i.e., the assertion +does not hold, therefore the `VERIFICATION FAILED`). Furthermore, SATABS +provides a detailed description of the problem in the form of a +counterexample (i.e., an execution trace that violates the property). On +this trace, `dummy_open` is called **twice**, leading to a `usecount` of 2. +The second call of course fails with `rval=-1`, but the counter is +increased nevertheless: + + int dummy_open (struct inode *inode, struct file *filp) + { + __CPROVER_assert(MAJOR (inode->i_rdev) == dummy_major, + "i_rdev mismatch"); + MOD_INC_USE_COUNT; + + if (locked) + return -1; + locked = TRUE; + + return 0; /* success */ + } + +Then, `dummy_release` is called to release the lock on the device. +Finally, the loop is left and the call to `unregister_chrdev` results in +a violation of the assertion (since `usecount` is still 1, even though +`locked=0`). + +\subsubsection man_satabs-tutorial-aeon Buffer Overflow in a Mail Transfer Agent + +We explain how to model check Aeon version 0.2a, a small mail transfer +agent written by Piotr Benetkiewicz. The description advertises Aeon as +a "*good choice for **hardened** or minimalistic boxes*". The sources +are available +[here](http://www.cprover.org/satabs/examples/loop_detection/aeon-0.2a.tar.gz). + +Our first naive attempt to verify Aeon using + + satabs *.c + +produces a positive result, but also warns us that the property holds +trivially. It also reveals that a large number library functions are +missing: SATABS is unable to find the source code for library functions +like `send`, `write` and `close`. + +Now, do you have to provide a body for all missing library functions? +There is no easy answer to this question, but a viable answer would be +"most likely not". It is necessary to understand how SATABS handles +functions without bodies: It simply assumes that such a function returns +an arbitrary value, but that no other locations than the one on the left +hand side of the assignment are changed. Obviously, there are cases in +which this assumption is un­sound, since the function potentially +modifies all memory locations that it can somehow address. + +We now use static analysis to generate array bounds checks for Aeon: + + satabs *.c --pointer-check --bounds-check --show-properties + +SATABS will show about 300 properties in various functions (read +\ref man_instrumentation-properties "this" for more information on the +property instrumentation). Now consider the first few lines of the +`main` function of Aeon: + + int main(int argc, char **argv) + { + char settings[MAX_SETTINGS][MAX_LEN]; + ... + numSet = getConfig(settings); + if (numSet == -1) { + logEntry("Missing config file!"); + exit(1); + } + ... + +and the function `getConfig` in `lib_aeon.c`: + + int getConfig(char settings[MAX_SETTINGS][MAX_LEN]) + { + char home[MAX_LEN]; + FILE *fp; /* .rc file handler */ + int numSet = 0; /* number of settings */ + + strcpy(home, getenv("HOME")); /* get home path */ + strcat(home, "/.aeonrc"); /* full path to rc file */ + fp = fopen(home, "r"); + if (fp == NULL) return -1; /* no cfg - ERROR */ + while (fgets(settings[numSet], MAX_LEN-1, fp) + && (numSet < MAX_SETTINGS)) numSet++; + fclose(fp); + + return numSet; + } + +The function `getConfig` makes calls to `strcpy`, `strcat`, `getenv`, +`fopen`, `fgets`, and `fclose`. It is very easy to provide an +implementation for the functions from the string library (string.h), and +SATABS comes with meaningful definitions for most of them. The +definition of `getenv` is not so straight-forward. The man-page of +`getenv` (which we obtain by entering `man 3 getenv` in a Unix or cygwin +command prompt) tells us: + + `` `getenv' `` searches the list of en­vi­ron­ment variable names + and values (using the global pointer `char **environ`) for a + variable whose name matches the string at `NAME`. If a variable name + matches, `getenv` returns a pointer to the associated value. + +SATABS has no information whatsoever about the content of `environ`. +Even if SATABS could access the environment variables on your +computer, a successful verification of `Aeon` would then only guarantee +that the properties for this program hold on your computer with a +specific set of en­vi­ron­ment variables. We have to assume that +`environ` contains en­vi­ron­ment variables that have an arbitrary +content of arbitrary length. The content of en­vi­ron­ment variables is +not only arbitrary but could be malefic, since it can be modified by the +user. The approximation of the behavior of `getenv` that is shipped with +SATABS completely ignores the content of the string. + +Now let us have another look at the properties that SATABS generates for +the models of the the string library and for `getenv`. Most of these +properties require that we verify that the upper and lower bounds of +buffers or arrays are not violated. Let us look at one of the properties +that SATABS generates for the code in function `getConfig`: + + Claim getConfig.3:   file lib_aeon.c line 19 function getConfig   dereference failure: NULL plus offset pointer   !(SAME-OBJECT(src, NULL))` + +The model of the function `strcpy` dereferences the pointer returned by +`getenv`, which may return a NULL pointer. This possibility is detected +by the static analysis, and thus a corresponding property is generated. +Let us check this specific property: + + satabs *.c --pointer-check --bounds-check --property getConfig.3 + +SATABS immediately returns a counterexample path that demonstrates how +`getenv` returns a NULL, which is subsequently dereferenced. We have +identified the first bug in this program: it requires that the +environment variable HOME is set, and crashes otherwise. + +Let us examine one more property in the same function: + + Claim getConfig.7:   file lib_aeon.c line 19 function getConfig   dereference failure: array `home' upper bound   !(POINTER_OFFSET(dst) + (int)i >= 512) || !(SAME-OBJECT(dst, &home[0])) + +This property asserts that the upper bound of the array `home` is not +violated. The variable `home` looks familiar: We encountered it in the +function `getConfig` given above. The function `getenv` in combination +with functions `strcpy`, `strcat` or `sprintf` is indeed often the +source for buffer overflows. Therefore, we try to use SATABS to check +the upper bound of the array `home`: + + satabs *.c --pointer-check --bounds-check --property getConfig.7 + +SATABS runs for quite a while and will eventually give up, telling us +that its upper bound for abstraction refinement iterations has been +exceeded. This is not exactly the result we were hoping for, and we +could now increase the bound for iterations with help of the +`--iterations` command line switch of SATABS. + +Before we do this, let us investigate why SATABS has failed to provide a +useful result. The function `strcpy` contains a loop that counts from 1 +to the length of the input string. Predicate abstraction, the mechanism +SATABS is based on, is unable to detect such loops and will therefore +unroll the loop body as often as necessary. The array `home` has +`MAX_LEN` elements, and `MAX_LEN` is defined to be 512 in `aeon.h`. +Therefore, SATABS would have to run through at least 512 iterations, +only to verify (or reject) one of the more than 300 properties! Does +this fact defeat the purpose of static verification? + +We can make the job easier: after reducing the value of `MAX_LEN` in +`aeon.h` to a small value, say to 10, SATABS provides a counterexample +trace that demonstrates how the buffer overflow be reproduced. If you +use the Eclipse plugin (as described \ref man_install-eclipse "here"), +you can step through this counterexample. The trace contains the string +that is returned by `getenv`. + + +\section man_modelling Modelling + +\subsection man_modelling-nondet Nondeterminism + +### Rationale + +Programs typically read inputs from an environment. These inputs can +take the form of data read from a file, keyboard or network socket, or +arguments passed on the command line. It is usually desirable to analyze +the program for any choice of these inputs. In Model Checking, inputs +are therefore modeled by means of *nondeterminism*, which means that the +value of the input is not specified. The program may follow any +computation that results from any choice of inputs. + +### Sources of Nondeterminism + +The CPROVER tools support the following sources of nondeterminism: + +- functions that read inputs from the environments; +- the thread schedule in concurrent programs; +- initial values of local-scoped variables and memory allocated with + `malloc`; +- initial values of variables that are `extern` in all compilation + units; +- explicit functions for generating nondeterminism. + +The CPROVER tools are shipped with a number of stubs for the most +commonly used library functions. When executing a statement such as +`getchar()`, a nondeterministic value is chosen instead of reading a +character from the keyboard. + +When desired, nondeterminism can be introduced explicitly into the +program by means of functions that begin with the prefix `nondet_`. As +an example, the following function returns a nondeterministically chosen +unsigned short int: + + unsigned short int nondet_ushortint(); + +Note that the body of the function is not defined. The name of the +function itself is irrelevant (save for the prefix), but must be unique. +Also note that a nondeterministic choice is not to be confused with a +probabilistic (or random) choice. + +### Uninterpreted Functions + +It may be necessary to check parts of a program independently. +Nondeterminism can be used to over-approximate the behaviour of part of +the system which is not being checked. Rather than calling a complex or +unrelated function, a nondeterministic stub is used. However, separate +calls to the function can return different results, even for the same +inputs. If the function output only depends on its inputs then this can +introduce spurious errors. To avoid this problem, functions whose names +begin with the prefix `__CPROVER_uninterpreted_` are treated as +uninterpreted functions. Their value is non-deterministic but different +invocations will return the same value if their inputs are the same. +Note that uninterpreted functions are not supported by all back-end +solvers. + +\subsection man_modelling-assumptions Modeling with Assertions and Assumptions + +### Assertions + +[Assertions](http://en.wikipedia.org/wiki/Assertion_%28computing%29) are +statements within the program that attempt to capture the programmer's +intent. The ANSI-C standard defines a header file +[assert.h](http://en.wikipedia.org/wiki/Assert.h), which offers a macro +`assert(cond)`. When executing a statement such as + + assert(p!=NULL); + +the execution is aborted with an error message if the condition +evaluates to *false*, i.e., if `p` is NULL in the example above. The +CPROVER tools can check the validity of the programmer-annotated +assertions statically. Specifically, the CPROVER tools will check that +the assertions hold for *any* nondeterministic choice that the program +can make. The static assertion checks can be disabled using the +`--no-assertions` command line option. + +In addition, there is a CPROVER-specific way to specify assertions, +using the built-in function `__CPROVER_assert`: + + __CPROVER_assert(p!=NULL, "p is not NULL"); + +The (mandatory) string that is passed as the second argument provides an +informal description of the assertion. It is shown in the list of +properties together with the condition. + +The assertion language of the CPROVER tools is identical to the language +used for expressions. Note that \ref man_modelling-nondet +"nondeterminism" +can be exploited in order to check a range of choices. As an example, +the following code fragment asserts that **all** elements of the array +are zero: + + int a[100], i; + + ... + + i=nondet_uint(); + if(i>=0 && i<100) + assert(a[i]==0); + +The nondeterministic choice will guess the element of the array that is +nonzero. The code fragment above is therefore equivalent to + + int a[100], i; + + ... + + for(i=0; i<100; i++) + assert(a[i]==0); + +Future CPROVER releases will support explicit quantifiers with a syntax +that resembles Spec\#: + + __CPROVER_forall { *type identifier* ; *expression* } + __CPROVER_exists { *type identifier* ; *expression* } + +### Assumptions + +Assumptions are used to restrict nondeterministic choices made by the +program. As an example, suppose we wish to model a nondeterministic +choice that returns a number from 1 to 100. There is no integer type +with this range. We therefore use \_\_CPROVER\_assume to restrict the +range of a nondeterministically chosen integer: + + unsigned int nondet_uint(); + + unsigned int one_to_hundred() + { + unsigned int result=nondet_uint(); + __CPROVER_assume(result>=1 && result<=100); + return result; + } + +The function above returns the desired integer from 1 to 100. You must +ensure that the condition given as an assumption is actually satisfiable +by some nondeterministic choice, or otherwise the model checking step +will pass vacuously. + +Also note that assumptions are never retroactive: They only affect +assertions (or other properties) that follow them in program order. This +is best illustrated with an example. In the following fragment, the +assumption has no effect on the assertion, which means that the +assertion will fail: + + x=nondet_uint(); + assert(x==100); + __CPROVER_assume(x==100); + +Assumptions do restrict the search space, but only for assertions that +follow. As an example, the following program will pass: + + int main() { + int x; + + __CPROVER_assume(x>=1 && x<=100000); + + x*=-1; + + __CPROVER_assert(x<0, "x is negative"); + } + +Beware that nondeterminism cannot be used to obtain the effect of +universal quantification in assumptions. As an example, + + int main() { + int a[10], x, y; + + x=nondet_int(); + y=nondet_int(); + __CPROVER_assume(x>=0 && x<10 && y>=0 && y<10); + + __CPROVER_assume(a[x]>=0); + + assert(a[y]>=0); + } + +fails, as there is a choice of x and y which results in a counterexample +(any choice in which x and y are different). + +\subsection man_modelling-pointers Pointer Model + +### Pointers in C + +C programs (and sometimes C++ programs as well) make intensive use of +pointers in order to decouple program code from specific data. A pointer +variable does not store data such as numbers or letters, but instead +points to a location in memory that hold the relevant data. This section +describes the way the CPROVER tools model pointers. + +### Objects and Offsets + +The CPROVER tools represent pointers as a pair. The first member of the +pair is the *object* the pointer points to, and the second is the offset +within the object. + +In C, objects are simply continuous fragments of memory (this definition +of "object" is not to be confused with the use of the term in +object-oriented programming). Variables of any type are guaranteed to be +stored as one object, irrespectively of their type. As an example, all +members of a struct or array belong to the same object. CPROVER simply +assigns a number to each active object. The object number of a pointer +`p` can be extracted using the expression `__CPROVER_POINTER_OBJECT(p)`. +As a consequence, pointers to different objects are always different, +which is not sound. + +The offset (the second member of the pair that forms a pointer) is +relative to the beginning of the object; it uses byte granularity. As an +example, the code fragment + + unsigned array[10]; + char *p; + + p=(char *)(array+1); + p++; + +will result in a pointer with offset 5. The offset of a pointer `p` can +be extracted using the expression `__CPROVER_POINTER_OFFSET(p)`. + +### Dereferencing Pointers + +The CPROVER tools require that pointers that are dereferenced point to a +valid object. Assertions that check this requirement can be generated +using the option --pointer-check and, if desired, --bounds-check. These +options will ensure that NULL pointers are not dereferenced, and that +dynamically allocated objects have not yet been deallocated. + +Furthermore, the CPROVER tools check that dynamically allocated memory +is not deallocated twice. The goto-instrument tool is also able to add +checks for memory leaks, i.e., it detects dynamically allocated objects +that are not deallocated once the program terminates. + +The CPROVER tools support pointer typecasts. Most casts are supported, +with the following exceptions: + +1. One notable exception is that pointers can only be accessed using a + pointer type. The conversion of a pointer into an integer-type using + a pointer typecast is not supported. + +2. Casts from integers to pointers yield a pointer that is either NULL + (if the integer is zero) or that point into a special array for + modeling [memory-mapped + I/O](http://en.wikipedia.org/wiki/Memory-mapped_I/O). Such pointers + are assumed not to overlap with any other objects. This is, of + course, only sound if a corresponding range check is instrumented. + +3. Accesses to arrays via pointers that have the array subtype need to + be well-aligned. + +### Pointers in Open Programs + +It is frequently desired to validate an open program, i.e., a fragment +of a program. Some variables are left undefined. In case an undefined +pointer is dereferenced, CBMC assumes that the pointer points to a +separate object of appropriate type with unbounded size. The object is +assumed not to alias with any other object. This assumption may +obviously be wrong in specific extensions of the program. + +\subsection man_modelling-floating-point Floating Point + +The CPROVER tools support bit-accurate reasoning about IEEE-754 +floating-point and fixed-point arithmetic. The C standard contains a +number of areas of implementation-defined behaviour with regard to +floating-point arithmetic: + +- CPROVER supports C99 Appendix F, and thus, the `__STD_IEC_559__` + macro is defined. This means that the C `float` data type maps to + IEEE 754 `binary32` and `double` maps to `binary64` and operations + on them are as specified in IEEE 754. + +- `long double` can be configured to be `binary64`, `binary128` + (quad precision) or a 96 bit type with 15 exponent bits and 80 + significant bits. The last is an approximation of Intel's x87 + extended precision double data type. As the C standard allows a + implementations a fairly wide set of options for `long double`, it + is best avoided for both portable code and bit-precise analysis. The + default is to match the build architecture as closely as possible. + +- In CPROVER, floating-point expressions are evaluated at the 'natural + precision' (the greatest of the arguments) and not at a + higher precision. This corresponds to `FLT_EVAL_METHOD` set to `0`. + Note that this is a different policy to some platforms (see below). + +- Expression contraction (for example, converting `x * y + c` to + `fma(x,y,c)`) is not performed. In effect, the `FP_CONTRACT` pragma + is always off. + +- Constant expressions are evaluated at \`run' time wherever possible + and so will respect changes in the rounding mode. In effect, the + `FENV_ACCESS` pragma is always off. Note that floating point + constants are treated as doubles (unless they are followed by `f` + when they are float) as specified in the C standard. `goto-cc` + supports `-fsingle-precision-constant`, which allows + the (non-standard) treatment of constants as floats. + +- Casts from int to float and float to float make use of the current + rounding mode. Note that the standard requires that casts from float + to int use round-to-zero (i.e. truncation). + +### x86 and Other Platform-specific Issues + +Not all platforms have the same implementation-defined behaviour as +CPROVER. This can cause mismatches between the verification environment +and the execution environment. If this occurs, check the compiler manual +for the choices listed above. There are two common cases that can cause +these problems: 32-bit x86 code and the use of unsafe optimisations. + +Many compilers that target 32-bit x86 platforms employ a different +evaluation method. The extended precision format of the x87 unit is used +for all computations regardless of their native precision. Most of the +time, this results in more accurate results and avoids edge cases. +However, it can result in some obscure and difficult to debug behaviour. +Checking if the `FLT_EVAL_METHOD` macro is non-zero (for these platforms +it will typically be 2), should warn of these problems. Changing the +compiler flags to use the SSE registers will resolve many of them, give +a more standards-compliant platform and will likely perform better. Thus +it is *highly* recommended. Use `-msse2 -mfpmath=sse` to enable this +option for GCC. Visual C++ does not have an option to force the +exclusive use of SSE instructions, but `/arch:SSE2` will pick SSE +instructions "when it \[the compiler\] determines that it is faster to +use the SSE/SSE2 instructions" and is thus better than `/arch:IA32`, +which exclusively uses the x87 unit. + +The other common cause of discrepancy between CPROVER results and the +actual platform are the use of unsafe optimisations. Some higher +optimisation levels enable transformations that are unsound with respect +to the IEEE-754 standard. Consult the compiler manual and disable any +optimisations that are described as unsafe (for example, the GCC options +`-ffast-math`). The options `-ffp-contract=off` (which replaces +`-mno-fused-madd`), `-frounding-math` and `-fsignaling-nans` are needed +for GCC to be strictly compliant with IEEE-754. + +### Rounding Mode + +CPROVER supports the four rounding modes given by IEEE-754 1985; round +to nearest (ties to even), round up, round down and round towards zero. +By default, round to nearest is used. However, command line options +(`--round-to-zero`, etc.) can be used to over-ride this. If more control +is needed, CPROVER has models of `fesetround` (for POSIX systems) and +`_controlfp` (for Windows), which can be used to change the rounding +mode during program execution. Furthermore, the inline assembly commands +fstcw/fnstcw/fldcw (on x86) can be used. + +The rounding mode is stored in the (thread local) variable +`__CPROVER_rounding_mode`, but users are strongly advised not to use +this directly. + +### Math Library + +CPROVER implements some of `math.h`, including `fabs`, `fpclassify` and +`signbit`. It has very limited support for elementary functions. Care +must be taken when verifying properties that are dependent on these +functions as the accuracy of implementations can vary considerably. The +C compilers can (and many do) say that the accuracy of these functions +is unknown. + +### Fixed-point Arithmetic + +CPROVER also has support for fixed-point types. The `--fixedbv` flag +switches `float`, `double` and `long double` to fixed-point types. The +length of these types is platform specific. The upper half of each type +is the integer component and the lower half is the fractional part. + + +\section man_hard-soft Hardware and Software Equivalence and Co-Verification + +\subsection man_hard-soft-introduction Introduction + +A common hardware design approach employed by many companies is to first +write a quick prototype that behaves like the planned circuit in a +language like ANSI-C. This program is then used for extensive testing +and debugging, in particular of any embedded software that will later on +be shipped with the circuit. An example is the hardware of a cell phone +and its software. After testing and debugging of the program, the actual +hardware design is written using hardware description languages like +[VHDL](http://en.wikipedia.org/wiki/VHDL) or +[Verilog](http://en.wikipedia.org/wiki/Verilog). + +Thus, there are two implementations of the same design: one written in +ANSI-C, which is written for simulation, and one written in register +transfer level HDL, which is the actual product. The ANSI-C +implementation is usually thoroughly tested and debugged. + +Due to market constraints, companies aim to sell the chip as soon as +possible, i.e., shortly after the HDL implementation is designed. There +is usually little time for additional debugging and testing of the HDL +implementation. Thus, an automated, or nearly automated way of +establishing the consistency of the HDL implementation is highly +desirable. + +This motivates the verification problem: we want to verify the +consistency of the HDL implementation, i.e., the product, [using the +ANSI-C implementation as a +reference](http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=936243&userType=inst). +Es­ta­bli­shing the consistency does not re­quire a formal +specification. However, formal methods to verify either the hardware or +software design are still desirable. + +### Related Work + +There have been several attempts in the past to tackle the problem. +[Semeria et al.](http://portal.acm.org/citation.cfm?id=513951) describe +a tool for verifying the combinational equivalence of RTL-C and an HDL. +They translate the C code into HDL and use standard equivalence checkers +to establish the equivalence. The C code has to be very close to a +hardware description (RTL level), which implies that the source and +target have to be implemented in a very similar way. There are also +variants of C specifically for this purpose. The [SystemC +standard](http://en.wikipedia.org/wiki/SystemC) defines a subset of C++ +that can be used for synthesis. Further variants of ANSI-C for +specifying hardware are SpecC and Handel C, among others. + +The concept of verifying the equivalence of a software implementation +and a synchronous transition system was introduced by [Pnueli, Siegel, +and Shtrichman](http://www.springerlink.com/content/ah5lpxaagrjp8ax2/). +The C program is re­quired to be in a very specific form, since a +mechanical translation is assumed. + +In 2000, [Currie, Hu, and +Rajan](http://doi.acm.org/10.1145/337292.337339) transform DSP assembly +language into an equation for the Stanford Validity Checker. The +symbolic execution of programs for comparison with RTL is now common +practice. + +The previous work focuses on a small subset of ANSI-C that is +particularly close to register transfer language. Thus, the designer is +often re­quired to rewrite the C program manually in order to comply +with these constraints. We extend the methodology to handle the full set +of ANSI-C language features. This is a challenge in the presence of +complex, dynamic data structures and pointers that may dynamically point +to multiple objects. Furthermore, our methodology allows arbitrary loop +constructs. + +### Further Material + +We provide a small \ref man_hard-soft-tutorial "tutorial" and a +description on +\ref man_hard-soft-inputs "how to synchronize inputs between the C model and the Verilog model". +There is also a collection of +[benchmark problems](http://www.cprover.org/hardware/sequential-equivalence/) +available. + +Further Reading + +- [Hardware Verification using ANSI-C Programs as a + Reference](http://www-2.cs.cmu.edu/~svc/papers/view-publications-ck03.html) +- [Behavioral Consistency of C and Verilog Programs Using Bounded + Model Checking](http://www-2.cs.cmu.edu/~svc/papers/view-publications-cky03.html) +- [A Tool for Checking ANSI-C + Programs](http://www-2.cs.cmu.edu/~svc/papers/view-publications-ckl2004.html) +- [Checking Consistency of C and Verilog using Predicate Abstraction + and Induction](http://www.kroening.com/publications/view-publications-kc2004.html) + + +\subsection man_hard-soft-tutorial Tutorial + +### Verilog vs. ANSI-C + +We assume that CBMC is installed on your system. If not so, follow +\ref man_install-cbmc "these instructions". + +The following Verilog module implements a 4-bit counter +(counter.v): + + module top(input clk); + + reg [3:0] counter; + + initial counter=0; + + always @(posedge clk) + counter=counter+1; + + endmodule + +HW-CBMC can take Verilog modules as the one above as additional input. +Similar as in co-simulation, the data in the Verilog modules is +available to the C program by means of global variables. For the example +above, the following C fragment shows the definition of the variable +that holds the value of the `counter` register: + + struct module_top { + unsigned int counter; + }; + + extern struct module_top top; + +Using this definition, the value of the `counter` register in the +Verilog fragment above can be accessed as `top.counter`. Please note +that the name of the variable **must** match the name of the top module. +The C program only has a view of one state of the Verilog model. The +Verilog model makes a transition once the function `next_timeframe()` is +called. + +As CBMC performs Bounded Model Checking, the number of timeframes +available for analysis must be bounded (SATABS). As it is desirable to +change the bound to adjust it to the available computing capacity, the +bound is given on the command line and not as part of the C program. +This makes it easy to use only one C program for arbitrary bounds. The +actual bound is available in the C program using the following +declaration: + + extern const unsigned int bound; + +Also note that the fragment above declares a constant variable of struct +type. Thus, the C program can only read the trace values and is not able +to modify them. We will later on describe how to drive inputs of the +Verilog module from within the C program. + +As described in previous chapters, assertions can be used to verify +properties of the Verilog trace. As an example, the following program +checks two values of the trace of the counter module (counter.c): + + void next_timeframe(); + + struct module_top { + unsigned int counter; + }; + + extern struct module_top top; + + int main() { + next_timeframe(); + next_timeframe(); + assert(top.counter==2); + next_timeframe(); + assert(top.counter==3); + } + +The following CBMC command line checks these assertions with a bound of +20: + + hw-cbmc counter.c counter.v --module top --bound 20 + +Note that a specific version of CBMC is used, called `hw-cbmc`. The +module name given must match the name of the module in the Verilog file. +Multiple Verilog files can be given on the command line. + +The `--bound` parameter is not to be confused with the `--unwind` +parameter. While the `--unwind` parameter specifies the maximum +unwinding depth for loops within the C program, the `--bound` parameter +specifies the number of times the transition relation of the Verilog +module is to be unwound. + +### Counterexamples + +For the given example, the verification is successful. If the first +assertion is changed to + + assert(top.counter==10); + +and the bound on the command line is changed to 6, CBMC will produce a +counterexample. CBMC produces two traces: One for the C program, which +matches the traces described earlier, and a separate trace for the +Verilog module. The values of the registers in the Verilog module are +also shown in the C trace as part of the initial state. + + Initial State + ---------------------------------------------------- + bound=6 (00000000000000000000000000000110) + counter={ 0, 1, 2, 3, 4, 5, 6 } + + Failed assertion: assertion line 6 function main + + Transition system state 0 + ---------------------------------------------------- + counter=0 (0000) + + Transition system state 1 + ---------------------------------------------------- + counter=1 (0001) + + Transition system state 2 + ---------------------------------------------------- + counter=2 (0010) + + Transition system state 3 + ---------------------------------------------------- + counter=3 (0011) + + Transition system state 4 + ---------------------------------------------------- + counter=4 (0100) + + Transition system state 5 + ---------------------------------------------------- + counter=5 (0101) + + Transition system state 6 + ---------------------------------------------------- + counter=6 (0110) + +### Using the Bound + +The following program is using the bound variable to check the counter +value in all cycles: + + void next_timeframe(); + extern const unsigned int bound; + + struct module_top { + unsigned int counter; + }; + + extern struct module_top top; + + int main() { + unsigned cycle; + + for(cycle=0; cycle + #include + + int main() { + printf("sizeof(long int): %d\n", (int)sizeof(long int)); + printf("sizeof(int *): %d\n", (int)sizeof(int *)); + assert(0); + } + +The counterexample trace contains the strings printed by the `printf` +command. + +The effects of endianness are more subtle. Try the following program +with `--big-endian` and `--little-endian`: + + #include + #include + + int main() { + int i=0x01020304; + char *p=(char *)&i; + printf("Bytes of i: %d, %d, %d, %d\n", p[0], p[1], p[2], p[3]); + assert(0); + } + + +\subsection man_instrumentation-properties Property Instrumentation + +### Properties + +We have mentioned *properties* several times so far, but we never +explained *what* kind of properties CBMC and SATABS can verify. We cover +this topic in more detail in this section. + +Both CBMC and SATABS use +[assertions](http://en.wikipedia.org/wiki/Assertion_(computing)) to +specify program properties. Assertions are properties of the state of +the program when the program reaches a particular program location. +Assertions are often written by the programmer by means of the `assert` +macro. + +In addition to the assertions written by the programmer, assertions for +specific properties can also be generated automatically by CBMC and +SATABS, often relieving the programmer from writing "obvious" +assertions. + +CBMC and SATABS come with an assertion generator called +`goto-instrument`, which performs a conservative [static +analysis](http://en.wikipedia.org/wiki/Static_code_analysis) to +determine program locations that potentially contain a bug. Due to the +imprecision of the static analysis, it is important to emphasize that +these generated assertions are only *potential* bugs, and that the Model +Checker first needs to confirm that they are indeed genuine bugs. + +The assertion generator can generate assertions for the verification of +the following properties: + +- **Buffer overflows.** For each array access, check whether the upper + and lower bounds are violated. +- **Pointer safety.** Search for `NULL`-pointer dereferences or + dereferences of other invalid pointers. + +- **Division by zero.** Check whether there is a division by zero in + the program. + +- **Not-a-Number.** Check whether floating-point computation may + result in [NaNs](http://en.wikipedia.org/wiki/NaN). + +- **Unitialized local.** Check whether the program uses an + uninitialized local variable. + +- **Data race.** Check whether a concurrent program accesses a shared + variable at the same time in two threads. + +We refrain from explaining the properties above in detail. Most of them +relate to behaviors that are left undefined by the respective language +semantics. For a discussion on why these behaviors are usually very +undesirable, read [this](http://blog.regehr.org/archives/213) blog post +by John Regehr. + +All the properties described above are *reachability* properties. They +are always of the form + +"*Is there a path through the program such that property ... is +violated?*" + +The counterexamples to such properties are always program paths. Users +of the Eclipse plugin can step through these counterexamples in a way +that is similar to debugging programs. The installation of this plugin +is explained \ref man_install-eclipse "here". + +### Using goto-instrument + +The goto-instrument static analyzer operates on goto-binaries, which is +a binary representation of control-flow graphs. The goto-binary is +extracted from program source code using goto-cc, which is explained +\ref man_instrumentation-goto-cc "here". Given a goto-program, +goto-instrument operates as follows: + +1. A goto-binary is read in. +2. The specified static analyses are performed. +3. Any potential bugs found are transformed into corresponding + assertions, and are added into the program. +4. A new goto-binary (with assertions) is written to disc. + +As an example, we begin with small C program we call `expr.c` (taken +from [here](http://www.spinroot.com/uno/)): + + int *ptr; + + int main(void) { + if (ptr) + *ptr = 0; + if (!ptr) + *ptr = 1; + } + +The program contains an obvious NULL-pointer dereference. We first +compile the example program with goto-cc and then instrument the +resulting goto-binary with pointer checks. + + goto-cc expr.c -o in.gb   goto-instrument in.gb out.gb --pointer-check + +We can now get a list of the assertions that have been generated as +follows: + + goto-instrument out.gb --show-properties + +Using either CBMC or SATABS on `out.gb`, we can obtain a counterexample +trace for the NULL-pointer dereference: + + cbmc out.gb + +The goto-instrument program supports the following checks: + +Flag | Check +-----------------------------|---------------------------------------------- +`--no-assertions` | ignore user assertions +`--bounds-check` | add array bounds checks +`--div-by-zero-check` | add division by zero checks +`--pointer-check` | add pointer checks +`--signed-overflow-check` | add arithmetic over- and underflow checks +`--unsigned-overflow-check` | add arithmetic over- and underflow checks +`--undefined-shift-check` | add range checks for shift distances +`--nan-check` | add floating-point NaN checks +`--uninitialized-check` | add checks for uninitialized locals (experimental) +`--error-label label` | check that given label is unreachable + +\subsection man_instrumentation-api The CPROVER API Reference + +The following sections summarize the functions available to programs +that are passed to the CPROVER tools. + +### Functions + +#### \_\_CPROVER\_assume, \_\_CPROVER\_assert, assert + + void __CPROVER_assume(_Bool assumption); + void __CPROVER_assert(_Bool assertion, const char *description); + void assert(_Bool assertion); + +The function **\_\_CPROVER\_assume** adds an expression as a constraint +to the program. If the expression evaluates to false, the execution +aborts without failure. More detail on the use of assumptions is in the +section on [Assumptions and Assertions](modeling-assertions.shtml). + +#### \_\_CPROVER\_same\_object, \_\_CPROVER\_POINTER\_OBJECT, \_\_CPROVER\_POINTER\_OFFSET, \_\_CPROVER\_DYNAMIC\_OBJECT + + _Bool __CPROVER_same_object(const void *, const void *); + unsigned __CPROVER_POINTER_OBJECT(const void *p); + signed __CPROVER_POINTER_OFFSET(const void *p); + _Bool __CPROVER_DYNAMIC_OBJECT(const void *p); + +The function **\_\_CPROVER\_same\_object** returns true if the two +pointers given as arguments point to the same object. The function +**\_\_CPROVER\_POINTER\_OFFSET** returns the offset of the given pointer +relative to the base address of the object. The function +**\_\_CPROVER\_DYNAMIC\_OBJECT** returns true if the pointer passed as +arguments points to a dynamically allocated object. + +#### \_\_CPROVER\_is\_zero\_string, \_\_CPROVER\_zero\_string\_length, \_\_CPROVER\_buffer\_size + + _Bool __CPROVER_is_zero_string(const void *); + __CPROVER_size_t __CPROVER_zero_string_length(const void *); + __CPROVER_size_t __CPROVER_buffer_size(const void *); + +#### \_\_CPROVER\_initialize + + void __CPROVER_initialize(void); + +The function **\_\_CPROVER\_initialize** computes the initial state of +the program. It is called prior to calling the main procedure of the +program. + +#### \_\_CPROVER\_input, \_\_CPROVER\_output + + void __CPROVER_input(const char *id, ...); + void __CPROVER_output(const char *id, ...); + +The functions **\_\_CPROVER\_input** and **\_\_CPROVER\_output** are +used to report an input or output value. Note that they do not generate +input or output values. The first argument is a string constant to +distinguish multiple inputs and outputs (inputs are typically generated +using nondeterminism, as described [here](modeling-nondet.shtml)). The +string constant is followed by an arbitrary number of values of +arbitrary types. + +#### \_\_CPROVER\_cover + + void __CPROVER_cover(_Bool condition); + +This statement defines a custom coverage criterion, for usage with the +[test suite generation feature](cover.shtml). + +#### \_\_CPROVER\_isnan, \_\_CPROVER\_isfinite, \_\_CPROVER\_isinf, \_\_CPROVER\_isnormal, \_\_CPROVER\_sign + + _Bool __CPROVER_isnan(double f); + _Bool __CPROVER_isfinite(double f); + _Bool __CPROVER_isinf(double f); + _Bool __CPROVER_isnormal(double f); + _Bool __CPROVER_sign(double f); + +The function **\_\_CPROVER\_isnan** returns true if the double-precision +floating-point number passed as argument is a +[NaN](http://en.wikipedia.org/wiki/NaN). + +The function **\_\_CPROVER\_isfinite** returns true if the +double-precision floating-point number passed as argument is a finite +number. + +This function **\_\_CPROVER\_isinf** returns true if the +double-precision floating-point number passed as argument is plus or +minus infinity. + +The function **\_\_CPROVER\_isnormal** returns true if the +double-precision floating-point number passed as argument is a normal +number. + +This function **\_\_CPROVER\_sign** returns true if the double-precision +floating-point number passed as argument is negative. + +#### \_\_CPROVER\_abs, \_\_CPROVER\_labs, \_\_CPROVER\_fabs, \_\_CPROVER\_fabsl, \_\_CPROVER\_fabsf + + int __CPROVER_abs(int x); + long int __CPROVER_labs(long int x); + double __CPROVER_fabs(double x); + long double __CPROVER_fabsl(long double x); + float __CPROVER_fabsf(float x); + +These functions return the absolute value of the given argument. + +#### \_\_CPROVER\_array\_equal, \_\_CPROVER\_array\_copy, \_\_CPROVER\_array\_set + + _Bool __CPROVER_array_equal(const void array1[], const void array2[]); + void __CPROVER_array_copy(const void dest[], const void src[]); + void __CPROVER_array_set(const void dest[], value); + +The function **\_\_CPROVER\_array\_equal** returns true if the values +stored in the given arrays are equal. The function +**\_\_CPROVER\_array\_copy** copies the contents of the array **src** to +the array **dest**. The function **\_\_CPROVER\_array\_set** initializes +the array **dest** with the given value. + +#### Uninterpreted Functions + +Uninterpreted functions are documented \ref man_modelling-nondet "here". + +### Predefined Types and Symbols + +#### \_\_CPROVER\_bitvector + + __CPROVER_bitvector [ expression ] + +This type is only available in the C frontend. It is used to specify a +bit vector with arbitrary but fixed size. The usual integer type +modifiers **signed** and **unsigned** can be applied. The usual +arithmetic promotions will be applied to operands of this type. + +#### \_\_CPROVER\_floatbv + + __CPROVER_floatbv [ expression ] [ expression ] + +This type is only available in the C frontend. It is used to specify an +IEEE-754 floating point number with arbitrary but fixed size. The first +parameter is the total size (in bits) of the number, and the second is +the size (in bits) of the mantissa, or significand (not including the +hidden bit, thus for single precision this should be 23). + +#### \_\_CPROVER\_fixedbv + + __CPROVER_fixedbv [ expression ] [ expression ] + +This type is only available in the C frontend. It is used to specify a +fixed-point bit vector with arbitrary but fixed size. The first +parameter is the total size (in bits) of the type, and the second is the +number of bits after the radix point. + +#### \_\_CPROVER\_size\_t + +The type of sizeof expressions. + +#### \_\_CPROVER\_rounding\_mode + + extern int __CPROVER_rounding_mode; + +This variable contains the IEEE floating-point arithmetic rounding mode. + +#### \_\_CPROVER\_constant\_infinity\_uint + +This is a constant that models a large unsigned integer. + +#### \_\_CPROVER\_integer, \_\_CPROVER\_rational + +**\_\_CPROVER\_integer** is an unbounded, signed integer type. +**\_\_CPROVER\_rational** is an unbounded, signed rational number type. + +#### \_\_CPROVER\_memory + + extern unsigned char __CPROVER_memory[]; + +This array models the contents of integer-addressed memory. + +#### \_\_CPROVER::unsignedbv<N> (C++ only) + +This type is the equivalent of **unsigned \_\_CPROVER\_bitvector\[N\]** +in the C++ front-end. + +#### \_\_CPROVER::signedbv<N> (C++ only) + +This type is the equivalent of **signed \_\_CPROVER\_bitvector\[N\]** in +the C++ front-end. + +#### \_\_CPROVER::fixedbv<N> (C++ only) + +This type is the equivalent of **\_\_CPROVER\_fixedbv\[N,m\]** in the +C++ front-end. + +### Concurrency + +Asynchronous threads are created by preceding an instruction with a +label with the prefix **\_\_CPROVER\_ASYNC\_**. + +\subsection man_goto-cc-linux goto-cc: Extracting Models from the Linux Kernel + +The Linux kernel code consists of more than 11 million lines of +low-level C and is frequently used to evaluate static analysis +techniques. In the following, we show how to extract models from Linux +2.6.39. + +1. First of all, you will need to make sure you have around 100 GB of + free disc space available. + +2. Download the Kernel sources at + . + +3. Now do + +   `bunzip2 linux-2.6.39.tar.bz2`\ +   `tar xvf linux-2.6.39.tar`\ +   `cd linux-2.6.39` + +4. Now ensure that you can actually compile a kernel by doing + +   `make defconfig`\ +   `make` + + These steps need to succeed before you can try to extract models + from the kernel. + +5. Now compile [gcc-wrap.c](gcc-wrap.c) and put the resulting binary + into a directory that is in your PATH variable: + +   `lwp-download http://www.cprover.org/cprover-manual/gcc-wrap.c`\ +   `gcc gcc-wrap.c -o gcc-wrap`\ +   `cp gcc-wrap ~/bin/`\ + + This assumes that the directory `~/bin` exists and is in your + PATH variable. + +6. Now change the variable CC in the kernel Makefile as follows: + + CC = ~/bin/gcc-wrap + +7. Now do + +   make clean +   make + + This will re-compile the kernel, but this time retaining the + preprocessed source files. + +8. You can now compile the preprocessed source files with goto-cc as + follows: + + find ./ -name .tmp_*.i > source-file-list + for a in `cat source-file-list` ; do +   goto-cc -c $a -o $a.gb + done + + Note that it is important that the word-size of the kernel + configuration matches that of goto-cc. Otherwise, compile-time + assertions will fail, generating the error message "bit field size + is negative". For a kernel configured for a 64-bit word-width, pass + the option --64 to goto-cc. + +The resulting `.gb` files can be passed to any of the CPROVER tools. + +\subsection man_goto-cc-apache goto-cc: Extracting Models from the Apache HTTPD + +The [Apache HTTPD](http://httpd.apache.org/) is still the most +frequently used web server. Together with the relevant libraries, it +consists of around 0.4 million lines of C code. In the following, we +show how to extract models from Apache HTTPD 2.4.2. + +1. First of all, we download the sources of Apache HTTPD and two + supporting libraries and uncompress them: + + lwp-download http://www.mirrorservice.org/sites/ftp.apache.org/apr/apr-1.4.6.tar.bz2 + lwp-download http://www.mirrorservice.org/sites/ftp.apache.org/apr/apr-util-1.4.1.tar.bz2 + lwp-download http://mirror.catn.com/pub/apache/httpd/httpd-2.4.2.tar.bz2 + bunzip2 < apr-1.4.6.tar.bz2 | tar x + bunzip2 < apr-util-1.4.1.tar.bz2 | tar x + bunzip2 < httpd-2.4.2.tar.bz2 | tar x + +2. Now compile [gcc-wrap.c](gcc-wrap.c) and put the resulting binary + into a directory that is in your PATH variable: + + lwp-download http://www.cprover.org/cprover-manual/gcc-wrap.c + gcc gcc-wrap.c -o gcc-wrap + cp gcc-wrap ~/bin/ + + This assumes that the directory `~/bin` exists and is in your + PATH variable. + +3. We now build the sources with gcc: + + (cd apr-1.4.6; ./configure; make CC=gcc-wrap) + (cd apr-util-1.4.1; ./configure --with-apr=../apr-1.4.6 ; make CC=gcc-wrap) + (cd httpd-2.4.2; ./configure --with-apr=../apr-1.4.6 --with-apr-util=../apr-util-1.4.1 ; make CC=gcc-wrap) + +4. You can now compile the preprocessed source files with goto-cc as + follows: + + find ./ -name *.i > source-file-list + for a in `cat source-file-list` ; do +   goto-cc -c $a -o $a.gb + done + +The resulting `.gb` files can be passed to any of the CPROVER tools. diff --git a/doc/guide/CBMC-guide.tex b/doc/guide/CBMC-guide.tex deleted file mode 100644 index 0285bf82c17..00000000000 --- a/doc/guide/CBMC-guide.tex +++ /dev/null @@ -1,714 +0,0 @@ -\documentclass{article} - -\newcommand{\dir}[1]{\texttt{#1}} -\newcommand{\file}[1]{\texttt{#1}} -\newcommand{\code}[1]{\texttt{#1}} -\newcommand{\prog}[1]{\texttt{#1}} - -\title{Beginner's Guide to CPROVER} -\author{Martin Brain\thanks{But most of the content is from Michael Tautschnig}} - -\begin{document} - -\maketitle - -\section{Background Information} - -First off; read the CPROVER manual. It describes how to get, build -and use CBMC and SATABS. This document covers the internals of the -system and how to get started on development. - - -\subsection{Documentation} - -Apart from the (user-orientated) CPROVER manual and this document, -most of the rest of the documentation is inline in the code -as \texttt{doxygen} and some comments. A man page for CBMC, goto-cc -and goto-instrument is contained in the \dir{doc/} directory and gives -some options for these tools. All of these could be improved -and patches are very welcome. In some cases the algorithms used are -described in the relevant papers. - -\subsection{Architecture} - -CPROVER is structured in a similar fashion to a compiler. It has -language specific front-ends which perform limited syntactic analysis -and then convert to an intermediate format. The intermediate format -can be output to files (this is what \texttt{goto-cc} does) and are -(informally) referred to as ``goto binaries'' or ``goto programs''. -The back-end are tools process this format, either directly from the -front-end or from it's saved output. These include a wide range of -analysis and transformation tools (see Section \ref{section:other-apps}). - -\subsection{Coding Standards} - -CPROVER is written in a fairly minimalist subset of C++; templates and -meta-programming are avoided except where necessary. The standard -library is used but in many cases there are alternatives provided in -\dir{util/} (see Section \ref{section:util}) which are preferred. -Boost is not used. - -Patches should be formatted so that code is indented with two space -characters, not tab and wrapped to 75 or 72 columns. Headers for -doxygen should be given (and preferably filled!) and the author will -be the person who first created the file. - -Identifiers should be lower case with underscores to separate words. -Types (classes, structures and typedefs) names must\footnote{There are -a couple of exceptions, including the graph classes} end with a -\code{t}. Types that model types (i.e. C types in the program that is -being interpreted) are named with \code{\_typet}. -For example \code{ui\_message\_handlert} rather than -\code{UI\_message\_handlert} or \code{UIMessageHandler} and -\code{union\_typet}. - - - -\subsection{How to Contribute} - -Fixes, changes and enhancements to the CPROVER code base should be -developed against the \texttt{trunk} version and submitted to Daniel -as patches produced by \texttt{diff -Naur} or \texttt{svn diff}. -Entire applications are best developed independently (\texttt{git svn} -is a popular choice for tracking the main trunk but also having local -development) until it is clear what their utility, future and -maintenance is likely to be. - - -\subsection{Other Useful Code} -\label{section:other-apps} - -The CPROVER subversion archive contains a number of separate -programs. Others are developed separately as patches or separate -branches.% New applications are initially developed in their version -%control system and may be merged into the main subversion system -%depending on their utility, popularity and maintenance. -Interfaces are have been and are continuing to stablise but older code -may require work to compile and function correctly. - -In the main archive: - -\begin{description} - \item[\prog{CBMC}]{A bounded model checking tool for C and C++. See - Section \ref{section:CBMC}.} - \item[\prog{goto-cc}]{A drop-in, flag compatible replacement for GCC - and other compilers that produces goto-programs rather than - executable binaries. See Section \ref{section:goto-cc}.} - \item[\prog{goto-instrument}]{A collection of functions for - instrumenting and modifying goto-programs. See Section - \ref{section:goto-instrument}.} -\end{description} - -Model checkers and similar tools: - -\begin{description} - \item[\prog{SatABS}]{A CEGAR model checker using predicate - abstraction. Is roughly 10,000 lines of code (on top of the CPROVER - code base) and is developed in its own subversion archive. It - uses an external model checker to find potentially feasible paths. - Key limitations are related to code with pointers and there is - scope for significant improvement.} - - \item[\prog{Scratch}]{Alistair Donaldson's k-induction based tool. - The front-end is in the old project CVS and some of the - functionality is in \prog{goto-instrument}.} - - \item[\prog{Wolverine}]{An implementation of Ken McMillan's IMPACT - algorithm for sequential programs. In the old project CVS.} - - \item[\prog{C-Impact}]{An implementation of Ken McMillan's IMPACT - algorithm for parallel programs. In the old project CVS.} - - \item[\prog{LoopFrog}]{A loop summarisation tool.} - - \item[\prog{???}]{Christoph's termination analyser.} - -\end{description} - - -Test case generation: - -\begin{description} - \item[\prog{cover}]{A basic test-input generation tool. In the old - project CVS.} - - \item[\prog{FShell}]{A test-input generation tool that allows the - user to specify the desired coverage using a custom language - (which includes regular expressions over paths). It uses - incremental SAT and is thus faster than the na\"ive ``add - assertions one at a time and use the counter-examples'' - approach. Is developed in its own subversion.} -\end{description} - - - -Alternative front-ends and input translators: - -\begin{description} - \item[\prog{Scoot}]{A System-C to C translator. Probably in the old - project CVS.} - - \item[\prog{???}]{A Simulink to C translator. In the old project CVS.} - - \item[\prog{???}]{A Verilog front-end. In the old project CVS.} - - \item[\prog{???}]{A converter from Codewarrior project files to - Makefiles. In the old project CVS.} -\end{description} - - -Other tools: - -\begin{description} - \item[\prog{ai}]{Leo's hybrid abstract interpretation / CEGAR tool.} - - \item[\prog{DeltaCheck?}]{Ajitha's slicing tool, aimed at locating - changes and differential verification. In the old project CVS.} -\end{description} - - -There are tools based on the CPROVER framework from other research -groups which are not listed here. - - - - - - -\section{Source Walkthrough} - -This section walks through the code bases in a rough order of interest -/ comprehensibility to the new developer. - - - -\subsection{\dir{doc}} - -At the moment just contains the CBMC man page. - -\subsection{\dir{regression/}} - -The regression tests are currently being moved from CVS. The -\dir{regression/} directory contains all of those that have been -moved. They are grouped into directories for each of the tools. Each -of these contains a directory per test case, containing a C or C++ -file that triggers the bug and a \file{.dsc} file that describes the -tests, expected output and so on. There is a Perl script, -\file{test.pl} that is used to invoke the tests as: - -\begin{center} - \code{../test.pl -c PATH\_TO\_CBMC} -\end{center} - -The \code{--help} option gives instructions for use and the format of -the description files. - - - -\subsection{\dir{src/}} - -The source code is divided into a number of sub-directories, each -containing the code for a different part of the system. In the top -level files there are only a few files: - -\begin{description} - \item[\file{config.inc}]{The user-editable configuration parameters - for the build process. The main use of this file is setting the - paths for the various external SAT solvers that are used. As - such, anyone building from source will likely need to edit this.} - \item[\file{Makefile}]{The main systems Make file. Parallel builds - are supported and encouraged; please don't break them!} - \item[\file{common}]{System specific magic required to get the - system to build. This should only need to be edited if porting - CBMC to a new platform / build environment.} - \item[\file{doxygen.cfg}]{The config file for doxygen.cfg} -\end{description} - - - -\subsubsection{\dir{util/}} -\label{section:util} - -\dir{util/} contains the low-level data structures and manipulation -functions that are used through-out the CPROVER code-base. For almost -any low-level task, the code required is probably in \dir{util/}. Key -files include: - -\begin{description} - \item[\file{irep.h}]{This contains the definition of \code{irept}, - the basis of many of the data structures in the project. They - should not be used directly; one of the derived classes should be - used. For more information see Section \ref{section:irept}.} - \item[\file{expr.h}]{The parent class for all of the expressions. - Provides a number of generic functions, \code{exprt} can be used - with these but when creating data, subclasses of \code{exprt} - should be used.} - \item[\file{std\_expr.h}]{Provides subclasses of \code{exprt} for - common kinds of expression for example \code{plus\_exprt}, - \code{minus\_exprt}, \code{dereference\_exprt}. These are the - intended interface for creating expressions.} - \item[\file{std\_types.h}]{Provides subclasses of \code{typet} (a - subclass of \code{irept}) to model C and C++ types. This is one - of the preferred interfaces to \code{irept}. The front-ends handle - type promotion and most coercision so the type system and checking - goto-programs is simpler than C.} - \item[\file{dstring.h}]{The CPROVER string class. This enables - sharing between strings which significantly reduces the amount of - memory required and speeds comparison. \code{dstring} should not - be used directly, \code{irep\_idt} should be used instead, which - (dependent on build options) is an alias for \code{dstring}.} - \item[\file{mp\_arith.h}]{The wrapper class for multi-precision - arithmetic within CPROVER. Also see \file{arith\_tools.h}.} - \item[\file{ieee\_float.h}]{The arbitrary precision float model used - within CPROVER. Based on \code{mp\_integer}s.} - \item[\file{context.h}]{A generic container for symbol table like - constructs such as namespaces. Lookup gives type, location of - declaration, name, `pretty name', whether it is static or not.} - \item[\file{namespace.h}]{The preferred interface for the context - class. The key function is \code{lookup} which converts a string - (\code{irep\_idt}) to a symbol which gives the scope of - declaration, type and so on. This works for functions as well as variables.} -\end{description} - - - - -\subsubsection{\dir{langapi/}} - -This contains the basic interfaces and support classes for programming -language front ends. Developers only really need look at this if they -are adding support for a new language. It's main users are the two -(in trunk) language front-ends; \dir{ansi-c/} and \dir{cpp/}. - - -\subsubsection{\dir{ansi-c/}} - -Contains the front-end for ANSI C, plus a variety of common -extensions. This parses the file, performs some basic sanity checks -(this is one area in which the UI could be improved; patches most -welcome) and then produces a goto-program (see below). The parser is -a traditional Flex / Bison system. - -\file{internal\_addition.c} contains the implementation of various -`magic' functions that are that allow control of the analysis from the -source code level. These include assertions, assumptions, atomic -blocks, memory fences and rounding modes. - -The \dir{library/} subdirectory contains versions of some of the C -standard header files that make use of the CPROVER built-in -functions. This allows CPROVER programs to be `aware' of the -functionality and model it correctly. Examples include -\file{stdio.c}, \file{string.c}, \file{setjmp.c} and various threading -interfaces. - - -\subsubsection{\dir{cpp/}} - -This directory contains the C++ front-end. It supports the subset of -C++ commonly found in embedded and system applications. -Consequentially it doesn't have full support for templates and many of -the more advanced and obscure C++ features. The subset of the -language that can be handled is being extended over time so bug -reports of programs that cannot be parsed are useful. - -The functionality is very similar to the ANSI C front end; parsing the -code and converting to goto-programs. It makes use of code from -\dir{langapi} and \dir{ansi-c}. - - - - -\subsubsection{\dir{goto-programs/}} - -Goto programs are the intermediate representation of the CPROVER tool -chain. They are language independent and similar to many of the -compiler intermediate languages. Section \ref{section:goto-programs} -describes the \code{goto\_programt} and \code{goto\_functionst} data -structures in detail. However it useful to understand some of the -basic concepts. Each function is a list of instructions, each of -which has a type (one of 18 kinds of instruction), a code expression, -a guard expression and potentially some targets for the next -instruction. They are not natively in static single-assign (SSA) -form. Transitions are nondeterministic (although in practise the -guards on the transitions normally cover form a disjoint cover of all -possibilities). Local variables have non-deterministic values if they -are not initialised. Variables and data within the program is -commonly one of three types (parameterised by width): -\code{unsignedbv\_typet}, \code{signedbv\_typet} and -\code{floatbv\_typet}, see \file{util/std\_types.h} for more -information. Goto programs can be serialised in a binary (wrapped in -ELF headers) format or in XML (see the various \code{\_serialization} -files). - - -The \prog{cbmc} option \code{--show-goto-programs} is often a -good starting point as it outputs goto-programs in a human -readable form. However there are a few things to be aware of. -Functions have an internal name (for example \code{c::f00}) and a -`pretty name' (for example \code{f00}) and which is used depends on -whether it is internal or being presented to the user. The -\code{main} method is the `logical' main which is not necessarily the -main method from the code. In the output \code{NONDET} is use to -represent a nondeterministic assignment to a variable. Likewise -\code{IF} as a beautified \code{GOTO} instruction where the guard -expression is used as the condition. \code{RETURN} instructions may -be dropped if they precede an \code{END\_FUNCTION} instruction. The -comment lines are generated from the \code{locationt} field of the -\code{instructiont} structure. - -\dir{goto-programs/} is one of the few places in the CPROVER codebase -that templates are used. The intention is to allow the general -architecture of program and functions to be used for other -formalisms. At the moment most of the templates have a single -instantiation; for example \code{goto\_functionst} and -\code{goto\_function\_templatet} and \code{goto\_programt} and \code{goto\_program\_templatet}. - - - -\subsubsection{\dir{goto-symex/}} - -This directory contains a symbolic evaluation system for -goto-programs. This takes a goto-program and translates it to an -equation system by traversing the program, branching and merging and -unwinding loops as needed. Each reverse goto has a separate counter -(the actual counting is handled by \prog{cbmc}, see the \code{--unwind} -and \code{--unwind-set} options). When a counter limit -is reach, an assertion can be added to explicitly show when analysis -is incomplete. The symbolic execution includes constant folding so -loops that have a constant number of iterations will be handled -completely (assuming the unwinding limit is sufficient). - -The output of the symbolic execution is a system of equations; an -object containing a list of \code{symex\_target\_elements}, each of -which are equalities between \prog{expr} expressions. See -\file{symex\_target\_equation.h}. The output is in static, single -assignment (SSA) form, which is \emph{not} the case for goto-programs. - - - -\subsubsection{\dir{pointer-analysis/}} - -To perform symbolic execution on programs with dereferencing of -arbitrary pointers, some alias analysis is needed. -\dir{pointer-analysis} contains the three levels of analysis; flow and -context insensitive, context sensitive and flow and context -sensitive. The code needed is subtle and sophisticated and thus there -may be bugs. - - - - -\subsubsection{\dir{solvers/}} - -The \dir{solvers/} directory contains interfaces to a number of -different decision procedures, roughly one per directory. - -\begin{description} - - \item[prop/]{The basic and common functionality. The key file is - \file{prop\_conv.h} which defines \code{prop\_convt}. This is the - base class that is used to interface to the decision procedures. - The key functions are \code{convert} which takes an \code{exprt} - and converts it to the appropriate, solver specific, data - structures and \code{dec\_solve} (inherited from - \code{decision\_proceduret}) which invokes the actual decision - procedures. Individual decision procedures (named - \code{*\_dect}) objects can be created but \code{prop\_convt} is - the preferred interface for code that uses them.} - - \item[flattening/]{A library that converts operations to - bit-vectors, including calling the conversions in \dir{floatbv} as - necessary. Is implemented as a simple conversion (with caching) - and then a post-processing function that adds extra constraints. - This is not used by the SMT or CVC back-ends.} - - %%%% - - \item[dplib/]{Provides the \code{dplib\_dect} object which used the - decision procedure library from ``Decision Procedures : An - Algorithmic Point of View''.} - - \item[cvc/]{Provides the \code{cvc\_dect} type which interfaces to - the old (pre SMTLib) input format for the CVC family of solvers. - This format is still supported by depreciated in favour of SMTLib 2.} - - \item[smt1/]{Provides the \code{smt1\_dect} type which converts the - formulae to SMTLib version 1 and then invokes one of Boolector, - CVC3, OpenSMT, Yices, MathSAT or Z3. Again, note that this format - is depreciated.} - - \item[smt2/]{Provides the \code{smt2\_dect} type which functions in - a similar way to \code{smt1\_dect}, calling Boolector, CVC3, - MathSAT, Yices or Z3. Note that the interaction with the solver - is batched and uses temporary files rather than using the - interactive command supported by SMTLib 2. With the \code{--fpa} - option, this output mode will not flatten the floating point - arithmetic and instead output the proposed SMTLib floating point - standard.} - - \item[qbf/]{Back-ends for a variety of QBF solvers. Appears to be - no longer used or maintained.} - - \item[sat/]{Back-ends for a variety of SAT solvers and DIMACS - output.} -\end{description} - - - - - -\subsubsection{\dir{cbmc/}} -\label{section:CBMC} - -This contains the first full application. CBMC is a bounded model -checker that uses the front ends (\dir{ansi-c}, \dir{cpp}, goto-program or others) -to create a goto-program, \dir{goto-symex} to unwind the loops the given -number of times and to produce and equation system and finally -\dir{solvers} to find a counter-example (technically, \dir{goto-symex} -is then used to construct the counter-example trace). - - - -\subsubsection{\dir{goto-cc/}} -\label{section:goto-cc} - -\dir{goto-cc} is a compiler replacement that just performs the first -step of the process; converting C or C++ programs to goto-binaries. -It is intended to be dropped in to an existing build procedure in -place of the compiler, thus it emulates flags that would affect the -semantics of the code produced. Which set of flags are emulated -depends on the naming of the \dir{goto-cc/} binary. If it is called -\prog{goto-cc} then it emulates GCC flags, \prog{goto-armcc} emulates -the ARM compiler, \prog{goto-cl} emulates VCC and \prog{goto-cw} -emulates the Code Warrior compiler. The output of this tool can then -be used with \prog{cbmc} or \prog{goto-instrument}. - - - - -\subsubsection{\dir{goto-instrument/}} -\label{section:goto-instrument} - -The \dir{goto-instrument/} directory contains a number of tools, one -per file, that are built into the \prog{goto-instrument} program. All -of them take in a goto-program (produced by \prog{goto-cc}) and either -modify it or perform some analysis. Examples include -\file{nondet\_static.cpp} which initialises static variables to a -non-deterministic value, \file{nondet\_volatile.cpp} which assigns -a non-deterministic value to any volatile variable before it is read -and \file{weak\_memory.h} which performs the necessary transformations -to reason about weak memory models. The exception to the ``one file -for each piece of functionality'' rule are the program instrumentation -options (mostly those given as ``Safety checks'' in the -\prog{goto-instrument} help text) which are included in the -\prog{goto-program/} directory. An example of this is -\file{goto-program/stack\_depth.h} and the general rule seems to be -that transformations and instrumentation that \prog{cbmc} uses should -be in \dir{goto-program/}, others should be in \dir{goto-instrument}. - -\prog{goto-instrument} is a very good template for new analysis -tools. New developers are advised to copy the directory, remove all -files apart from \file{main.*}, \file{parseoptions.*} and the -\file{Makefile} and use these as the skeleton of their application. -The \code{doit()} method in \file{parseoptions.cpp} is the preferred -location for the top level control for the program. - - - -\subsubsection{\dir{linking/}} - -Probably the code to emulate a linker. This allows multiple `object -files' (goto-programs) to be linked into one `executable' (another -goto-program), thus allowing existing build systems to be used to -build complete goto-program binaries. - - -\subsubsection{\dir{big-int/}} - -CPROVER is distributed with its own multi-precision arithmetic -library; mainly for historical and portability reasons. The library is externally -developed and thus \dir{big-int} contains the source as it is -distributed. This should not be used directly, see -\file{util/mp\_arith.h} for the CPROVER interface. - - - -\subsubsection{\dir{xmllang/}} - -CPROVER has optional XML output for results and there is an XML format -for goto-programs. It is used to interface to various IDEs. The -\dir{xmllang/} directory contains the parser and helper functions for -handling this format. - - - -\subsubsection{\dir{floatbv/}} - -This library contains the code that is used to convert floating point -variables (\code{floatbv}) to bit vectors (\code{bv}). This is -referred to as `bit-blasting' and is called in the \dir{solver} code -during conversion to SAT or SMT. It also contains the abstraction -code described in the FMCAD09 paper. - - - - - - - - -\section{Data Structures} - -This section discusses some of the key data-structures used in the -CPROVER codebase. - -\subsection{\code{irept}} -\label{section:irept} - -There are a large number of kind of tree structured or tree-like data -in CPROVER. \code{irept} provides a single, unified representation for -all of these, allowing structure sharing and reference counting of -data. As such \code{irept} is the basic unit of data in CPROVER. -Each \code{irept} contains\footnote{Or references, if reference - counted data sharing is enabled. It is enabled by default; see the - \code{SHARING} macro.} a basic unit of data (of type \code{dt}) -which contains four things: - -\begin{description} -\item[\code{data}]{A string\footnote{When \code{USE\_DSTRING} is enabled (it - is by default), this is actually a \code{dstring} and thus an - integer which is a reference into a string table}, which is - returned when the \code{id()} function is used.} -\item[\code{named\_sub}]{A map from \code{irep\_namet} (a string) to - an \code{irept}. This is used for named children, - i.e. subexpressions, parameters, etc.} -\item[\code{comments}]{Another map from \code{irep\_namet} to - \code{irept} which is used for annotations and other `non-semantic' information} -\item[\code{sub}]{A vector of \code{irept} which is used to store - ordered but unnamed children.} -\end{description} - -The \code{irept::pretty} function outputs the contents of an -\code{irept} directly and can be used to understand an debug problems -with \code{irept}s. - - -On their own \code{irept}s do not ``mean'' anything; they are -effectively generic tree nodes. Their interpretation depends on the -contents of result of the \code{id} function (the \code{data}) field. -\file{util/irep\_ids.txt} contains the complete list of \code{id} -values. During the build process it is used to generate -\file{util/irep\_ids.h} which gives constants for each id (named -\code{ID\_*}). These can then be used to identify what kind of data -\code{irept} stores and thus what can be done with it. - -To simplify this process, there are a variety of classes that inherit -from \code{irept}, roughly corresponding to the ids listed -(i.e. \code{ID\_or} (the string \code{"or''}) corresponds to the class -\code{or\_exprt}). These give semantically relevant accessor -functions for the data; effectively different APIs for the same -underlying data structure. None of these classes add fields (only -methods) and so static casting can be used. The inheritance graph of -the subclasses of \code{irept} is a useful starting point for working -out how to manipulate data. - -There are three main groups of classes (or APIs); those derived from -\code{typet}, \code{codet} and \code{exprt} respectively. Although -all of these inherit from \code{irept}, these are the most abstract -level that code should handle data. If code is manipulating plain -\code{irept}s then something is wrong with the architecture of the -code. - -Many of the key descendent of \code{exprt} are declared in -\file{std\_expr.h}. All expressions have a named subfield / -annotation which gives the type of the expression (slightly -simplified from C/C++ as \code{unsignedbv\_typet}, -\code{signedbv\_typet}, \code{floatbv\_typet}, etc.). All type -conversions are explicit with an expression with \code{id() == - ID\_typecast} and an `interface class' named -\code{typecast\_exprt}. One key descendent of \code{exprt} is -\code{symbol\_exprt} which creates \code{irept} instances with the id -of ``symbol''. These are used to represent variables; the name of -which can be found using the \code{get\_identifier} accessor function. - - -\code{codet} inherits from \code{exprt} and is defined in -\file{std\_code.h}. They represent executable code; statements in C -rather than expressions. In the front-end there are versions of these -that hold whole code blocks, but in goto-programs these have been -flattened so that each \code{irept} represents one sequence point -(almost one line of code / one semi-colon). The most common -descendents of \code{codet} are \code{code\_assignt} so a common -pattern is to cast the \code{codet} to an assignment and then recurse -on the expression on either side. - - - - - - -\subsection{\code{goto-programs}} -\label{section:goto-programs} - -The common starting point for working with goto-programs is the -\code{read\_goto\_binary} function which populates an object of -\code{goto\_functionst} type. This is defined in -\file{goto\_functions.h} and is an instantiation of the template -\code{goto\_functions\_templatet} which is contained in -\file{goto\_functions\_template.h}. They are wrappers around a map from -strings to \code{goto\_programt}'s and iteration macros are provided. -Note that \code{goto\_function\_templatet} (no \code{s}) is defined in -the same header as \code{goto\_functions\_templatet} and is gives the -C type for the function and Boolean which indicates whether the body -is available (before linking this might not always be true). Also -note the slightly counter-intuitive naming; \code{goto\_functionst} -instances are the top level structure representing the program and -contain \code{goto\_programt} instances which represent the individual -functions. At the time of writing \code{goto\_functionst} is the only -instantiation of the template \code{goto\_functions\_templatet} but -other could be produced if a different data-structures / kinds of models -were needed for functions. - -\code{goto\_programt} is also an instantiation of a template. In a -similar fashion it is \code{goto\_program\_templatet} and allows the -types of the guard and expression used in instructions to be -parameterised. Again, this is currently the only use of the template. -As such there are only really helper functions in -\file{goto\_program.h} and thus \code{goto\_program\_template.h} is -probably the key file that describes the representation of (C) -functions in the goto-program format. It is reasonably stable and -reasonably documented and thus is a good place to start looking at the code. - -An instance of \code{goto\_program\_templatet} is effectively a list -of instructions (and inner template called \code{instructiont}). It -is important to use the copy and insertion functions that are provided -as iterators are used to link instructions to their predecessors and -targets and careless manipulation of the list could break these. -Likewise there are helper macros for iterating over the instructions -in an instance of \code{goto\_program\_templatet} and the use of these -is good style and strongly encouraged. - -Individual instructions are instances of type \code{instructiont}. -They represent one step in the function. Each has a type, an instance -of \code{goto\_program\_instruction\_typet} which denotes what kind of -instruction it is. They can be computational (such as \code{ASSIGN} -or \code{FUNCTION\_CALL}), logical (such as \code{ASSUME} and -\code{ASSERT}) or informational (such as \code{LOCATION} and -\code{DEAD}). At the time of writing there are 18 possible values for -\code{goto\_program\_instruction\_typet} / kinds of instruction. -Instructions also have a guard field (the condition under which it is -executed) and a code field (what the instruction does). These may be -empty depending on the kind of instruction. In the default -instantiations these are of type \code{exprt} and \code{codet} -respectively and thus covered by the previous discussion of -\code{irept} and its descendents. The next instructions (remembering -that transitions are guarded by non-deterministic) are given by the -list \code{targets} (with the corresponding list of labels -\code{labels}) and the corresponding set of previous instructions is -get by \code{incoming\_edges}. Finally \code{instructiont} have -informational \code{function} and \code{location} fields that indicate -where they are in the code. - - - -\end{document} diff --git a/doc/html-manual/api.shtml b/doc/html-manual/api.shtml deleted file mode 100644 index 141ae88b80a..00000000000 --- a/doc/html-manual/api.shtml +++ /dev/null @@ -1,323 +0,0 @@ - - -

CPROVER Manual TOC

- -

The CPROVER API Reference

- -

-The following sections summarize the functions available to programs -that are passed to the CPROVER tools. -

- -

Functions

- -

__CPROVER_assume, __CPROVER_assert, assert

- -
- -void __CPROVER_assume(_Bool assumption);
-void __CPROVER_assert(_Bool assertion, const char *description);
-void assert(_Bool assertion); -
-
- -

-The function __CPROVER_assume adds an expression as a constraint -to the program. If the expression evaluates to false, the execution -aborts without failure. More detail on the use of assumptions is -in the section on Assumptions -and Assertions. -

- -

__CPROVER_same_object, __CPROVER_POINTER_OBJECT, -__CPROVER_POINTER_OFFSET, -__CPROVER_DYNAMIC_OBJECT

- -
- -_Bool __CPROVER_same_object(const void *, const void *);
-unsigned __CPROVER_POINTER_OBJECT(const void *p);
-signed __CPROVER_POINTER_OFFSET(const void *p);
-_Bool __CPROVER_DYNAMIC_OBJECT(const void *p); -
-
- -

-The function __CPROVER_same_object returns true -if the two pointers given as arguments point to the same -object. -The function __CPROVER_POINTER_OFFSET returns -the offset of the given pointer relative to the base -address of the object. -The function __CPROVER_DYNAMIC_OBJECT -returns true if the pointer passed -as arguments points to a dynamically allocated object. -

- -

__CPROVER_is_zero_string, -__CPROVER_zero_string_length, -__CPROVER_buffer_size

- -
- -_Bool __CPROVER_is_zero_string(const void *);
-__CPROVER_size_t __CPROVER_zero_string_length(const void *);
-__CPROVER_size_t __CPROVER_buffer_size(const void *); -
-
- -

-

- -

__CPROVER_initialize

- -
- -void __CPROVER_initialize(void); - -
- -

-The function __CPROVER_initialize computes the initial -state of the program. It is called prior to calling the -main procedure of the program. -

- -

__CPROVER_input, __CPROVER_output

- -
- -void __CPROVER_input(const char *id, ...);
-void __CPROVER_output(const char *id, ...); -
-
- -

-The functions __CPROVER_input and __CPROVER_output -are used to report an input or output value. Note that they do not generate -input or output values. The first argument is a string constant -to distinguish multiple inputs and outputs (inputs are typically -generated using nondeterminism, as described -here). -The string constant is followed by an arbitrary number of values of -arbitrary types. -

- -

__CPROVER_cover

- -
- -void __CPROVER_cover(_Bool condition); - -
- -

This statement defines a custom coverage criterion, for usage -with the test suite generation feature.

- -

-

- -

__CPROVER_isnan, __CPROVER_isfinite, __CPROVER_isinf, -__CPROVER_isnormal, __CPROVER_sign

- -
- -_Bool __CPROVER_isnan(double f);
-_Bool __CPROVER_isfinite(double f);
-_Bool __CPROVER_isinf(double f);
-_Bool __CPROVER_isnormal(double f);
-_Bool __CPROVER_sign(double f); -
-
- -

-The function __CPROVER_isnan returns true if the double-precision -floating-point number passed as argument is a -NaN. -

- -

-The function __CPROVER_isfinite returns true if the double-precision -floating-point number passed as argument is a -finite number. -

- -

-This function __CPROVER_isinf returns true if the double-precision -floating-point number passed as argument is plus -or minus infinity. -

- -

-The function __CPROVER_isnormal returns true if the double-precision -floating-point number passed as argument is a -normal number. -

- -

-This function __CPROVER_sign returns true if the double-precision -floating-point number passed as argument is -negative. -

- -

__CPROVER_abs, __CPROVER_labs, __CPROVER_fabs, __CPROVER_fabsl, __CPROVER_fabsf

- -
- -int __CPROVER_abs(int x);
-long int __CPROVER_labs(long int x);
-double __CPROVER_fabs(double x);
-long double __CPROVER_fabsl(long double x);
-float __CPROVER_fabsf(float x); -
-
- -

-These functions return the absolute value of the given -argument. -

- -

__CPROVER_array_equal, __CPROVER_array_copy, __CPROVER_array_set

- -
- -_Bool __CPROVER_array_equal(const void array1[], const void array2[]);
-void __CPROVER_array_copy(const void dest[], const void src[]);
-void __CPROVER_array_set(const void dest[], value); -
-
- -

-The function __CPROVER_array_equal returns true if the values -stored in the given arrays are equal. -The function __CPROVER_array_copy copies the contents of -the array src to the array dest. -The function __CPROVER_array_set initializes the array dest with -the given value. -

- -

Uninterpreted Functions

- -

-Uninterpreted functions are documented here. -

- -

Predefined Types and Symbols

- -

__CPROVER_bitvector

- -
- -__CPROVER_bitvector [ expression ] - -
- -

-This type is only available in the C frontend. It is used -to specify a bit vector with arbitrary but fixed size. The -usual integer type modifiers signed and unsigned -can be applied. The usual arithmetic promotions will be -applied to operands of this type. -

- -

__CPROVER_floatbv

- -
- -__CPROVER_floatbv [ expression ] [ expression ] - -
- -

-This type is only available in the C frontend. It is used -to specify an IEEE-754 floating point number with arbitrary -but fixed size. The first parameter is the total size (in bits) -of the number, and the second is the size (in bits) of the -mantissa, or significand (not including the hidden bit, thus for -single precision this should be 23). -

- -

__CPROVER_fixedbv

- -
- -__CPROVER_fixedbv [ expression ] [ expression ] - -
- -

-This type is only available in the C frontend. It is used -to specify a fixed-point bit vector with arbitrary -but fixed size. The first parameter is the total size (in bits) -of the type, and the second is the number of bits after the radix -point. -

- -

__CPROVER_size_t

- -

-The type of sizeof expressions. -

- -

__CPROVER_rounding_mode

- -
- -extern int __CPROVER_rounding_mode; - -
- -

-This variable contains the IEEE floating-point -arithmetic rounding mode. -

- -

__CPROVER_constant_infinity_uint

- -

-This is a constant that models a large unsigned -integer. -

- -

__CPROVER_integer, __CPROVER_rational

- -

-__CPROVER_integer is an unbounded, signed integer type. -__CPROVER_rational is an unbounded, signed rational -number type. -

- -

__CPROVER_memory

- -
- -extern unsigned char __CPROVER_memory[]; - -
- -

-This array models the contents of integer-addressed memory. -

- -

__CPROVER::unsignedbv (C++ only)

- -

This type is the equivalent of unsigned __CPROVER_bitvector[N] in the C++ front-end. -

- -

__CPROVER::signedbv (C++ only)

- -

This type is the equivalent of signed __CPROVER_bitvector[N] in the C++ front-end. -

- -

__CPROVER::fixedbv (C++ only)

- -

This type is the equivalent of __CPROVER_fixedbv[N,m] in the C++ front-end. -

- -

Concurrency

- -

-Asynchronous threads are created by preceding an instruction with a label with the prefix __CPROVER_ASYNC_. -

- - diff --git a/doc/html-manual/architecture.shtml b/doc/html-manual/architecture.shtml deleted file mode 100644 index d3cd0f612c3..00000000000 --- a/doc/html-manual/architecture.shtml +++ /dev/null @@ -1,93 +0,0 @@ - - -

CPROVER Manual TOC

- -

Build Systems and Libraries

- -

Architectural Settings

- -

The behavior of a C/C++ program depends on a number of -parameters that are specific to the architecture the program was compiled -for. The three most important architectural parameters are:

- -
    -
  • The width of the various scalar types; e.g., compare the value -of sizeof(long int) on various machines.
  • - -
  • The width of pointers; e.g., compare the value -of sizeof(int *) on various machines.
  • - -
  • The endianness -of the architecture.
  • -
- -

-In general, the CPROVER tools attempt to adopt the settings of the -particular architecture the tool itself was compiled for. For example, -when running a 64 bit binary of CBMC on Linux, the program will be processed -assuming that sizeof(long int)==8.

- -

-As a consequence of these architectural parameters, -you may observe different verification results for an identical -program when running CBMC on different machines. In order to get -consistent results, or when aiming at validating a program written -for a different platform, the following command-line arguments can -be passed to the CPROVER tools:

- -
    -
  • The word-width can be set with --16, ---32, --64.
  • -
  • The endianness can be defined with ---little-endian and --big-endian.
  • -
- -

-When using a goto binary, CBMC and the other tools read the configuration -from the binary, i.e., the setting when running goto-cc is the one that -matters; the option given to the model checker is ignored in this case. -

- -

-In order to see the effect of the options --16, ---32 and --64, pass -the following program to CBMC:

- -
- -#include <stdio.h>
-#include <assert.h>
-
-int main() {
-  printf("sizeof(long int): %d\n", (int)sizeof(long int));
-  printf("sizeof(int *): %d\n", (int)sizeof(int *));
-  assert(0);
-} -
-
- -

-The counterexample trace contains the strings printed by the -printf command.

- -

-The effects of endianness are -more subtle. Try the following program with --big-endian -and --little-endian:

- -
- -#include <stdio.h>
-#include <assert.h>
-
-int main() {
-  int i=0x01020304;
-  char *p=(char *)&i;
-  printf("Bytes of i: %d, %d, %d, %d\n",
-         p[0], p[1], p[2], p[3]);
-  assert(0);
-} -
-
- - diff --git a/doc/html-manual/cbmc-loops.shtml b/doc/html-manual/cbmc-loops.shtml deleted file mode 100644 index f8e94175b3a..00000000000 --- a/doc/html-manual/cbmc-loops.shtml +++ /dev/null @@ -1,233 +0,0 @@ - - - - - - -

CPROVER Manual TOC

- -

CBMC: Bounded Model Checking for C/C++ and Java

- -

Understanding Loop Unwinding

- -

Iteration-based Unwinding

- -

-The basic idea of CBMC is to model the computation of the programs up to a -particular depth. Technically, this is achieved by a process that -essentially amounts to unwinding loops. This concept is best -illustrated with a generic example: -

- -
int main(int argc, char **argv) {
-  while(cond) {
-    BODY CODE
-  }
-}
-
- -

-A BMC instance that will find bugs with up to five iterations of the loop would -contain five copies of the loop body, and essentially corresponds to checking -the following loop-free program: -

- -
int main(int argc, char **argv) {
-  if(cond) {
-    BODY CODE COPY 1
-    if(cond) {
-      BODY CODE COPY 2
-      if(cond) {
-        BODY CODE COPY 3
-        if(cond) {
-          BODY CODE COPY 4
-          if(cond) {
-            BODY CODE COPY 5
-          }
-        }
-      }
-    }
-  }
-}
-
- -

-Note the use of the if statement to prevent the execution of -the loop body in the case that the loop ends before five iterations are executed. -The construction above is meant to produce a program that is trace equivalent -with the original programs for those traces that contain up to five iterations -of the loop. -

- -

-In many cases, CBMC is able to automatically determine an upper bound on the - -number of loop iterations. This may even work when the number of loop -unwindings is not constant. Consider the following example: -

- -
_Bool f();
-
-int main() {
-  for(int i=0; i<100; i++) {
-    if(f()) break;
-  }
-  
-  assert(0);
-}
-
- -

-The loop in the program above has an obvious upper bound on the number of -iterations, but note that the loop may abort prematurely depending on the -value that is returned by f(). CBMC is nevertheless able to -automatically unwind the loop to completion.

- -

-This automatic detection of the unwinding -bound may fail if the number of loop iterations is highly data-dependent. -Furthermore, the number of iterations that are executed by any given -loop may be too large or may simply be unbounded. For this case, -CBMC offers the command-line option --unwind B, where -B denotes a number that corresponds to the maximal number -of loop unwindings CBMC performs on any loop. -

- -

-Note that the number of unwindings is measured by counting the number of -backjumps. In the example above, note that the condition -i<100 is in fact evaluated 101 times before the loop -terminates. Thus, the loop requires a limit of 101, and not 100.

- -

Setting Separate Unwinding Limits

- -

-The setting given with --unwind is used globally, -that is, for all loops in the program. In order to set individual -limits for the loops, first use -

- - -  --show-loops - - -

-to obtain a list of all loops in the program. Then identify the loops -you need to set a separate bound for, and note their loop ID. Then -use -

- - -  --unwindset L:B,L:B,... - - -

-where L denotes a loop ID and B denotes -the bound for that loop.

- -

-As an example, consider a program with two loops in the function -main: -

- - -  --unwindset c::main.0:10,c::main.1:20 - - -

-This sets a bound of 10 for the first loop, and a bound of 20 for -the second loop. -

- -

-What if the number of unwindings specified is too small? In this case, bugs -that require paths that are deeper may be missed. In order to address this -problem, CBMC can optionally insert checks that the given unwinding bound is -actually sufficiently large. These checks are called unwinding -assertions, and are enabled with the option ---unwinding-assertions. Continuing the generic example above, -this unwinding assertion for a bound of five corresponds to checking the -following loop-free program: -

- -
int main(int argc, char **argv) {
-  if(cond) {
-    BODY CODE COPY 1
-    if(cond) {
-      BODY CODE COPY 2
-      if(cond) {
-        BODY CODE COPY 3
-        if(cond) {
-          BODY CODE COPY 4
-          if(cond) {
-            BODY CODE COPY 5
-            assert(!cond);
-          }
-        }
-      }
-    }
-  }
-}
-
- -

-The unwinding assertions can be verified just like any other generated -assertion. If all of them are proven to hold, the given loop bounds are -sufficient for the program. This establishes a high-level -worst-case execution time (WCET). -

- -

-In some cases, it is desirable to cut off very deep loops in favor -of code that follows the loop. As an example, consider the -following program: -

- -
int main() {
-  for(int i=0; i<10000; i++) {
-    BODY CODE
-  }
-  
-  assert(0);
-}
-
- -

-In the example above, small values of --unwind will -prevent that the assertion is reached. If the code in the loop -is considered irrelevant to the later assertion, use the option -

- - -  --partial-loops - - -

-This option will allow paths that execute loops only partially, -enabling a counterexample for the assertion above even for -small unwinding bounds. The disadvantage of using this option -is that the resulting path may be spurious, i.e., may not -exist in the original program. -

- -

Depth-based Unwinding

- -

-The loop-based unwinding bound is not always appropriate. In particular, -it is often difficult to control the size of the generated formula -when using the --unwind option. The option -

- - -  --depth nr - - -

-specifies an unwinding bound in terms of the number of instructions that are -executed on a given path, irrespectively of the number of loop iterations. -Note that CBMC uses the number of instructions in the control-flow graph -as the criterion, not the number of instructions in the source code. -

- - diff --git a/doc/html-manual/cbmc.shtml b/doc/html-manual/cbmc.shtml deleted file mode 100644 index 993ce452b62..00000000000 --- a/doc/html-manual/cbmc.shtml +++ /dev/null @@ -1,379 +0,0 @@ - - - - - - -

CPROVER Manual TOC

- -

CBMC: Bounded Model Checking for C/C++ and Java

- -

A Short Tutorial

- -

First Steps

- -

-We assume you have already installed CBMC and the necessary support files -on your system. If not so, please follow -these instructions. -

- -

-Like a compiler, CBMC takes the names of .c files as command line -arguments. CBMC then translates the program and merges the function -definitions from the various .c files, just like a linker. But instead -of producing a binary for execution, CBMC performs symbolic simulation on -the program. -

- -

-As an example, consider the following simple program, named -file1.c: -

- -

int puts(const char *s) { }
-
-int main(int argc, char **argv) {
-  puts(argv[2]);
-}
-
- -

-Of course, this program is faulty, as the argv array might have fewer -than three elements, and then the array access argv[2] is out of bounds. -Now, run CBMC as follows: -

- - -  cbmc file1.c --show-properties --bounds-check --pointer-check - - -

The two options --bounds-check and --pointer-check -instruct CBMC to look for errors related to pointers and array bounds. -CBMC will print the list of properties it checks. Note that it lists, -among others, a property labeled with "object bounds in argv" together with -the location of the faulty array access. As you can see, CBMC largely -determines the property it needs to check itself. This is realized by means -of a preliminary static analysis, which relies on computing a fixed point on -various abstract -domains. More detail on automatically generated properties is provided -here.

- -

-Note that these automatically generated properties need not necessarily -correspond to bugs – these are just potential flaws, as -abstract interpretation might be imprecise. Whether these properties -hold or correspond to actual bugs needs to be determined by further analysis. -

- -

-CBMC performs this analysis using symbolic simulation, which -corresponds to a translation of the program into a formula. The formula is -then combined with the property. Let's look at the formula that is -generated by CBMC's symbolic simulation:

- - -  cbmc file1.c --show-vcc --bounds-check --pointer-check - - -

-With this option, CBMC performs the symbolic simulation and prints the -verification conditions on the screen. A verification condition needs -to be proven to be valid by a -decision procedure in order to assert that the corresponding property -holds. Let's run the decision procedure:

- - -  cbmc file1.c --bounds-check --pointer-check - - -

-CBMC transforms the equation you have seen before into CNF and passes it to -a SAT solver (more background on this step is in the book on Decision Procedures). It -then determines which of the properties that it has generated for the -program hold and which do not. Using the SAT solver, CBMC detects that the -property for the object bounds of argv does not hold, and will -thus print a line as follows: -

- - -[main.pointer_dereference.6] dereference failure: object bounds in argv[(signed long int)2]: FAILURE - - -

Counterexample Traces

- -

-Let us have a closer look at this property and why it fails. To aid the -understanding of the problem, CBMC can generate a counterexample -trace for failed properties. To obtain this trace, run -

- - -  cbmc file1.c --bounds-check --trace - - -

-CBMC then prints a counterexample trace, i.e., a program trace that begins -with main and ends in a state which violates the property. In -our example, the program trace ends in the faulty array access. It also -gives the values the input variables must have for the bug to occur. In -this example, argc must be one to trigger the out-of-bounds -array access. If you add a branch to the example that requires that -argc>=3, the bug is fixed and CBMC will report that the -proofs of all properties have been successful.

- -

Verifying Modules

- -

-In the example above, we used a program that starts with a main -function. However, CBMC is aimed at embedded software, and these -kinds of programs usually have different entry points. Furthermore, CBMC -is also useful for verifying program modules. Consider the following example, -called file2.c: -

- -
int array[10];
-int sum() {
-  unsigned i, sum;
-
-  sum=0;
-  for(i=0; i<10; i++)
-    sum+=array[i];
-}
-
- -

-In order to set the entry point to the sum function, run -

- - -  cbmc file2.c --function sum --bounds-check - - -

-It is often necessary to build a suitable harness for the function -in order to set up the environment appropriately. -

- -

Loop Unwinding

- -

-When running the previous example, you will have noted that CBMC unwinds the -for loop in the program. As CBMC performs Bounded Model -Checking, all loops have to have a finite upper run-time bound in order to -guarantee that all bugs are found. CBMC can optionally check that enough -unwinding is performed. As an example, consider the program binsearch.c: -

- -
int binsearch(int x) {
-  int a[16];
-  signed low=0, high=16;
-
-  while(low<high) {
-    signed middle=low+((high-low)>>1);
-
-    if(a[middle]<x)
-      high=middle;
-    else if(a[middle]>x)
-      low=middle+1;
-    else // a[middle]==x
-      return middle;
-  }
-
-  return -1;
-}
-
- -

-If you run CBMC on this function, you will notice that the unwinding -does not stop on its own. The built-in simplifier is not able to determine -a run time bound for this loop. The unwinding bound has to be given as a -command line argument:

- - -  cbmc binsearch.c --function binsearch --unwind 6 --bounds-check --unwinding-assertions - - -

-CBMC verifies that verifies the array accesses are within the bounds; note -that this actually depends on the result of the right shift. In addition, -as CBMC is given the option ---unwinding-assertions, it also checks that enough -unwinding is done, i.e., it proves a run-time bound. For any lower -unwinding bound, there are traces that require more loop iterations. Thus, -CBMC will report that the unwinding assertion has failed. As usual, a counterexample -trace that documents this can be obtained with the option ---property. -

- -

Unbounded Loops

- -

-CBMC can also be used for programs with unbounded loops. In this -case, CBMC is used for bug hunting only; CBMC does not attempt to find -all bugs. The following program -(lock-example.c) is an example -of a program with a user-specified property:

- -
_Bool nondet_bool();
-_Bool LOCK = 0;
-
-_Bool lock() {
-  if(nondet_bool()) {
-    assert(!LOCK);
-    LOCK=1;
-    return 1; }
-
-  return 0;
-}
-
-void unlock() {
-  assert(LOCK);
-  LOCK=0;
-}
-
-int main() {
-  unsigned got_lock = 0;
-  int times;
-
-  while(times > 0) {
-    if(lock()) {
-      got_lock++;
-      /* critical section */
-    }
-
-    if(got_lock!=0)
-      unlock();
-
-    got_lock--;
-    times--;
-} }
-
- -

-The while loop in the main function has no -(useful) run-time bound. Thus, a bound has to be set on the amount of -unwinding that CBMC performs. There are two ways to do so: -

- -
    - -
  1. The --unwind command-line parameter can to be used to limit -the number of times loops are unwound.
  2. - -
  3. The --depth command-line parameter can be used to limit -the number of program steps to be processed.
  4. - -
- -

-Given the option --unwinding-assertions, CBMC checks whether -the arugment to --unwind is large enough to cover all program -paths. If the argument is too small, CBMC will detect that not enough -unwinding is done reports that an unwinding assertion has failed. -

- -

-Reconsider the example. For a loop unwinding bound of one, no bug is found. -But already for a bound of two, CBMC detects a trace that violates an -assertion. Without unwinding assertions, or when using the --depth -command line switch, CBMC does not prove the program correct, but it can be -helpful to find program bugs. The various command line options that CBMC -offers for loop unwinding are described in the section on -understanding loop unwinding.

- -

A Note About Compilers and the ANSI-C Library

- -

-Most C programs make use of functions provided by a library; instances are -functions from the standard ANSI-C library such as malloc or -printf. The verification of programs that use such functions -has two requirements:

- -
    - -
  1. Appropriate header files have to be provided. These header files -contain declarations of the functions that are to be used. -
  2. - -
  3. Appropriate definitions have to be provided.
  4. - -
- -

-Most C compilers come with header files for the ANSI-C library functions. -We briefly discuss how to obtain/install these library files. -

- -

Linux

- -

-Linux systems that are able to compile software are usually equipped with -the appropriate header files. Consult the documentation of your distribution -on how to install the compiler and the header files. First try to compile -some significant program before attempting to verify it. -

- -

Windows

- -

-On Microsoft Windows, CBMC is pre-configured to use the compiler that is -part of Microsoft's Visual Studio. Microsoft's -Visual Studio Community is fully featured and available for download for -free from the Microsoft webpage. Visual Studio installs the usual set of -header files together with the compiler. However, the Visual Studio -compiler requires a large set of environment variables to function -correctly. It is therefore required to run CBMC from the Visual Studio -Command Prompt, which can be found in the menu Visual Studio -Tools. -

- -

-Note that in both cases, only header files are available. CBMC only -comes with a small set of definitions, which includes functions such as -malloc. Detailed information about the built-in definitions is -here.

- -

Command Line Interface

- -

-This section describes the command line interface of CBMC. Like a C -compiler, CBMC takes the names of the .c source files as arguments. -Additional options allow to customize the behavior of CBMC. Use -cbmc --help to get a full list of the available options. -

- -

-Structured output can be obtained from CBMC using the option --xml-ui. -Any output from CBMC (e.g., counterexamples) will then use an XML -representation. -

- - - - - diff --git a/doc/html-manual/counter.v b/doc/html-manual/counter.v deleted file mode 100644 index 4920568889c..00000000000 --- a/doc/html-manual/counter.v +++ /dev/null @@ -1,10 +0,0 @@ -module top(input clk); - - reg [3:0] counter; - - initial counter=0; - - always @(posedge clk) - counter=counter+1; - -endmodule diff --git a/doc/html-manual/cover.shtml b/doc/html-manual/cover.shtml deleted file mode 100644 index 54480059399..00000000000 --- a/doc/html-manual/cover.shtml +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - -

CPROVER Manual TOC

- -

Automatic Test Suite Generation with CBMC

- -

A Small Tutorial with A Case Study

- -

-We assume that CBMC is installed on your system. If not so, follow -these instructions.

- -

-CBMC can be used to automatically generate test cases that satisfy a certain code coverage -criterion. Common coverage criteria include branch coverage, condition -coverage and Modified -Condition/Decision Coverage (MC/DC). Among others, MC/DC is required -by several avionics software development guidelines to ensure adequate testing -of safety critical software. Briefly, in order to satisfy MC/DC, -for every conditional statement containing boolean decisions, each Boolean -variable should be evaluated one time to "true" and one time to "false", -in a way that affects the outcome of the decision. -

- -

-In the following, we are going to demonstrate how to apply the test suite -generation functionality in CBMC, by means of a case study. The program -pid.c is an excerpt from a real-time embedded benchmark PapaBench, -and implements part of a fly-by-wire autopilot for an Unmanned Aerial Vehicle (UAV). -It is adjusted mildly for our purposes. -

- -

-The aim of function climb_pid_run is to control the vertical climb of the UAV. -Details on the theory behind this operation are documented in the wiki for the Paparazzi UAV project. -The behaviour of this simple controller, supposing that the desired speed is 0.5 meters per second, -is plotted in the Figure below. -

- -
- -The pid controller - -
- -
01: // CONSTANTS:
-02: #define MAX_CLIMB_SUM_ERR 10
-03: #define MAX_CLIMB 1
-04:
-05: #define CLOCK 16
-06: #define MAX_PPRZ (CLOCK*600)
-07:
-08: #define CLIMB_LEVEL_GAZ 0.31
-09: #define CLIMB_GAZ_OF_CLIMB 0.75
-10: #define CLIMB_PITCH_OF_VZ_PGAIN 0.05
-11: #define CLIMB_PGAIN -0.03
-12: #define CLIMB_IGAIN 0.1
-13:
-14: const float pitch_of_vz_pgain=CLIMB_PITCH_OF_VZ_PGAIN;
-15: const float climb_pgain=CLIMB_PGAIN;
-16: const float climb_igain=CLIMB_IGAIN;
-17: const float nav_pitch=0;
-18:
-19: /** PID function INPUTS */
-20: // The user input: target speed in vertical direction
-21: float desired_climb;
-22: // Vertical speed of the UAV detected by GPS sensor
-23: float estimator_z_dot;
-24:
-25: /** PID function OUTPUTS */
-26: float desired_gaz;
-27: float desired_pitch;
-28:
-29: /** The state variable: accumulated error in the control */
-30: float climb_sum_err=0;
-31:
-32: /** Computes desired_gaz and desired_pitch */
-33: void climb_pid_run() 
-34: {
-35:
-36:   float err=estimator_z_dot-desired_climb;
-37:
-38:   float fgaz=climb_pgain*(err+climb_igain*climb_sum_err)+CLIMB_LEVEL_GAZ+CLIMB_GAZ_OF_CLIMB*desired_climb;
-39:
-40:   float pprz=fgaz*MAX_PPRZ;
-41:   desired_gaz=((pprz>=0 && pprz<=MAX_PPRZ) ? pprz : (pprz>MAX_PPRZ ? MAX_PPRZ : 0));
-42:
-43:   /** pitch offset for climb */
-44:   float pitch_of_vz=(desired_climb>0) ? desired_climb*pitch_of_vz_pgain : 0;
-45:   desired_pitch=nav_pitch+pitch_of_vz;
-46:
-47:   climb_sum_err=err+climb_sum_err;
-48:   if (climb_sum_err>MAX_CLIMB_SUM_ERR) climb_sum_err=MAX_CLIMB_SUM_ERR;
-49:   if (climb_sum_err<-MAX_CLIMB_SUM_ERR) climb_sum_err=-MAX_CLIMB_SUM_ERR;
-50:
-51: }
-52:
-53: int main()
-54: {
-55:
-56:   while(1)
-57:   {
-58:     /** Non-deterministic input values */ 
-59:     desired_climb=nondet_float();
-60:     estimator_z_dot=nondet_float();
-61:
-62:     /** Range of input values */ 
-63:     __CPROVER_assume(desired_climb>=-MAX_CLIMB && desired_climb<=MAX_CLIMB);
-64:     __CPROVER_assume(estimator_z_dot>=-MAX_CLIMB && estimator_z_dot<=MAX_CLIMB);
-65:
-66:     __CPROVER_input("desired_climb", desired_climb);
-67:     __CPROVER_input("estimator_z_dot", estimator_z_dot);
-68:
-69:     climb_pid_run();
-70:
-71:     __CPROVER_output("desired_gaz", desired_gaz);
-72:     __CPROVER_output("desired_pitch", desired_pitch);
-73:
-74:   }
-75:
-76:   return 0;
-77: }
-
- -

-In order to test the PID controller, we construct a main control loop, -which repeatedly invokes the function climb_pid_run (line 69). -This PID function has two input variables: the desired speed desired_climb -and the estimated speed estimated_z_dot. -In the beginning of each loop iteration, values of the inputs are assigned non-deterministically. -Subsequently, the __CPROVER_assume statement in lines 63 and 64 guarantees that -both values are bounded within a valid range. -The __CPROVER_input and __CPROVER_output will help clarify the inputs -and outputs of interest for generating test suites. -

- -

-To demonstrate the automatic test suite generation in CBMC, -we call the following command and we are going to explain the command line options one by one. -

- -
cbmc pid.c --cover mcdc --unwind 6 --xml-ui
-
- -

-The option --cover mcdc specifies the code coverage criterion. -There are four conditional statements in the PID function: in line 41, line 44, -line 48 and line 49. -To satisfy MC/DC, the test suite has to meet multiple requirements. -For instance, each conditional statement needs to evaluate to true and false. -Consider the condition "pprz>=0 && pprz<=MAX_PPRZ" in line 41. CBMC -instruments three coverage goals to control the respective evaluated results of "pprz>=0" and -"pprz<=MAX_PPRZ". -We list them in below and they satisfy the MC/DC rules. -Note that MAX_PPRZ is defined as 16 * 600 in line 06 of the program. -

- -
-!(pprz >= (float)0) && pprz <= (float)(16 * 600)  id="climb_pid_run.coverage.1"
-pprz >= (float)0 && !(pprz <= (float)(16 * 600))  id="climb_pid_run.coverage.2"
-pprz >= (float)0 && pprz <= (float)(16 * 600)     id="climb_pid_run.coverage.3"
-
- -

-The "id" of each coverage goal is automatically assigned by CBMC. For every -coverage goal, a test suite (if there exists) that -satisfies such a goal is printed out in XML format, as the parameter ---xml-ui is given. Multiple coverage goals can share a -test suite, when the corresponding execution of the program satisfies all these -goals at the same time. -

- -

-In the end, the following test suites are automatically generated for testing the PID controller. -A test suite consists of a sequence of input parameters that are -passed to the PID function climb_pid_run at each loop iteration. -For example, Test 1 covers the MC/DC goal with id="climb_pid_run.coverage.1". -The complete output from CBMC is in -pid_test_suites.xml, where every test suite and the coverage goals it is for -are clearly described. - -

Test suite:
-Test 1. 
-  (iteration 1) desired_climb=-1.000000f, estimator_z_dot=1.000000f
-
-Test 2.
-  (iteration 1) desired_climb=-1.000000f, estimator_z_dot=1.000000f 
-  (iteration 2) desired_climb=1.000000f, estimator_z_dot=-1.000000f 
-
-Test 3.
-  (iteration 1) desired_climb=0.000000f, estimator_z_dot=-1.000000f
-  (iteration 2) desired_climb=1.000000f, estimator_z_dot=-1.000000f
-
-Test 4.
-  (iteration 1) desired_climb=1.000000f, estimator_z_dot=-1.000000f
-  (iteration 2) desired_climb=1.000000f, estimator_z_dot=-1.000000f
-  (iteration 3) desired_climb=1.000000f, estimator_z_dot=-1.000000f
-  (iteration 4) desired_climb=1.000000f, estimator_z_dot=-1.000000f
-  (iteration 5) desired_climb=0.000000f, estimator_z_dot=-1.000000f
-  (iteration 6) desired_climb=1.000000f, estimator_z_dot=-1.000000f
-
-Test 5.
-  (iteration 1) desired_climb=-1.000000f, estimator_z_dot=1.000000f
-  (iteration 2) desired_climb=-1.000000f, estimator_z_dot=1.000000f
-  (iteration 3) desired_climb=-1.000000f, estimator_z_dot=1.000000f
-  (iteration 4) desired_climb=-1.000000f, estimator_z_dot=1.000000f
-  (iteration 5) desired_climb=-1.000000f, estimator_z_dot=1.000000f
-  (iteration 6) desired_climb=-1.000000f, estimator_z_dot=1.000000f
-
-

- -

-The option --unwind 6 unwinds the loop inside the main -function body six times. In order to achieve the complete coverage on all the instrumented goals -in the PID function climb_pid_run, the loop must be unwound sufficient enough times. -For example, climb_pid_run needs to be called at least six times for evaluating the -condition climb_sum_err>MAX_CLIMB_SUM_ERR in line 48 to true. -This corresponds to the Test 5. -An introduction to the use of loop unwinding can be found -in Understanding Loop Unwinding. -

- -

-In this small tutorial, we present the automatic test suite generation -functionality of CBMC, by applying the MC/DC code coverage criterion to a -PID controller case study. In addition to --cover mcdc, other -coverage criteria like branch, decision, -path etc. are also available when calling CBMC. -

- -

Coverage Criteria

- -

-The table below summarizes the coverage criteria that CBMC supports. -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CriterionDefinition
assertionFor every assertion, generate a test that reaches it
locationFor every location, generate a test that reaches it
branchGenerate a test for every branch outcome
decisionGenerate a test for both outcomes of every Boolean expression -that is not an operand of a propositional connective
conditionGenerate a test for both outcomes of every Boolean expression
mcdcModified Condition/Decision Coverage (MC/DC)
pathBounded path coverage
coverGenerate a test for every __CPROVER_cover statement -
- - diff --git a/doc/html-manual/cprover-source.shtml b/doc/html-manual/cprover-source.shtml deleted file mode 100644 index dd4de2a1b66..00000000000 --- a/doc/html-manual/cprover-source.shtml +++ /dev/null @@ -1,877 +0,0 @@ - - - - - - -

CPROVER Manual TOC

- -

The CPROVER Source Code Reference

- -

-The following sections provide an introduction for anybody who -wishes to modify CBMC or build new tools on top of the APIs used -by CBMC. They summarize key components, data structures and APIs -that are used to build the CPROVER tools. -

- -

Source Code Availability and Compilation

- -

-The most recent source code of CBMC and the CPROVER infrastructure can be obtained -via git at https://github.com/diffblue/cbmc.git. -Tar balls for releases are available at https://github.com/diffblue/cbmc/releases. -

- -

-Detailed instructions on how to build CBMC from source are given -in the file COMPILING. -

- -

Components

- -
-
From C source code file to CPROVER's IR
- -

-The sources of the C frontend are located in the "src/ansi-c" directory. It -uses a standard Flex/Bison setup for scanning and parsing the files. The -Flex scanner produces a token sequence, which is turned into a tree -representation of the input program using the Bison grammar. The -typechecker subsequently annotates this parse tree with types and generates -a symbol table. The symbol table is a map from identifiers (functions, -variables and types) to their definitions. -

- -

-The following example illustrates how to use the frontend for parsing files and -for translating them into a symbol table. A call to parse generates -the parse tree of the program. The conversion into the symbol table is -performed during type checking, which is done by a call to the -typecheck method. The symbol table is a map from identifiers to the -symbolt data structure. -

- -
#include <iostream>
-#include <fstream>
-#include <sstream>
-#include <string>
-
-#include <ansi-c/ansi_c_language.h>
-#include <util/cmdline.h>
-#include <util/config.h>
-
-int main(int argc, const char* argv[])
-{
-   // Command line: parse  -I incl_dir file1 ...
-   cmdlinet cmdl;
-   cmdl.parse(argc, argv, "I:");
-
-   config.init();
-
-   if(cmdl.isset('I'))	
-     config.ansi_c.include_paths=cmdl.get_values('I');
-
-   // Set language to C
-   std::auto_ptr<languaget> clang=new_ansi_c_language();
-
-   // Symbol table
-   symbol_tablet my_symbol_table;
-
-   for(const auto & arg : cmdl.args)
-   {
-     // Source code stream
-     std::ifstream in(arg.c_str());	
-
-     // Parse
-     clang->parse(in, "", std::cerr);
-
-     // Typecheck
-     clang->typecheck(my_symbol_table, arg, std::cerr);
-  }
-
-  // Do some final adjustements
-  clang->final(my_symbol_table, std::cerr);
-
-  my_symbol_table.show(std::cout);
-
-  return 0;
-}
-
- -

-The parse trees are implemented using a class called irept. Its -declaration and definiton can be found in the files "src/util/irep.h" and -"src/util/irep.cpp", respectively. -

- -

-The excerpt below gives some details of the class irept: -

- -
class irept
-{
-public:
-  typedef std::vector subt;
-  typedef std::map named_subt;
-  ...
-
-public:
-  class dt
-  {
-  public:
-    unsigned ref_count;
-    dstring data;
-    named_subt named_sub;
-    named_subt comments;
-    subt sub;
-    ...
-  };
-
-protected:
-  dt *data;
-  ...
-};
-
- -

-Every node of any tree is an object of class irept. Each node has a -pointer to an object of class dt. The dt objects are used -for storing the actual content of nodes. Objects of class dt are -dynamically allocated and can be shared between nodes. A reference-counter -mechanism is implemented to automatically free unreachable dt -objects. A shallow copy of a tree is an O(1) operation. -

- -

-The field data of class dt is a (hashed) string -representing the label of the nodes. The fields named_sub, -comments and sub are links to childs. Edges are either -labeled with a string or ordered. The string-labeled edges are stored in the -map comments if their first character is '#'. Otherwise, they are -stored in the map named_sub. The labels of edges are unique for a -given node; however, their ordering is not preserved. The field sub -is a vector of nodes that is used for storing the ordered children. The order -of edges of this kind is preserved during copy. -

- -
-
Tree for the expression a+b with int a; char -b;.
- -

Interface of Class irept

- -
id
- -
const irep_idt &id();
-void id(const irep_idt &_data);
-
- -

-The first method returns a constant reference to the label of the node. The -second method sets the label of the node. -

- -
is_nil and is_not_nil
- -
virtual bool is_nil() const;
-virtual bool is_not_nil() const;
-
- -

-The first method returns true if the label of the node is equal to "nil". -The second method returns false if the label of the node is equal to "nil". -

- -
find, add and get
- -
const irept &find(const irep_namet &name) const;
-irept &add(const irep_namet &name);
-const irep_idt &get(const irep_namet &name) const;
-
- -
    - -
  1. The first method looks for an edge with label name -and returns the corresponding child. If no edge with label name -is found, then nil_rep is returned.
  2. - -
  3. The second method does the same as the first except that if -no edge with label name if found, then a new child is created -and returned. -
  4. - -
  5. The third method does the same as the first except that the label -of the child is returned (instead of a reference). -If no edge with label name is found, then an empty -string is returned. -
  6. - -
- -
set
- -
void set(const irep_namet &name,
-         const irep_idt &value);
-void set(const irep_namet &name, const long value);
-void set(const irep_namet &name, const irept &irep);
-
- -

-These methods create a new edge with label name. -

- -

-If the second argument is an object of class irept, then it is -assigned to the new child. - -

-If the second argument is a string, then it is set as node-label of the new child. - -

-If the second argument is a number, then it is converted to a -string and set as node-label of the new child. - -

remove
- -
void remove(const irep_namet &name);
-
- -

-This method looks for an edge with label name -and removes it. - -

move_to_sub and move_to_named_sub
- -
void move_to_sub(irept &irep);
-void move_to_named_sub(const irep_namet &name, irept &irep);
-
- -

-The first method creates a new ordered edge with a child equal to -irep. Then it sets irep to nil. The index of the -edge is equal to the size of vector sub before the call. -

- -

-The second method does the same but for labeled edges. -

- -
swap
- -
void swap(irept &irep);
-
- -

-Exchange the content of the invoked node with the one of irep. -

- -
make_nil
- -
void make_nil();
-
- -

-Set the label of the node to "nil" and remove all outgoing edges. -

- -
get_sub and get_named_sub and get_comments
- -
const subt &get_sub();
-const named_subt &get_named_sub();
-const named_subt &get_comments();
-
- -

-Return a constant reference to -sub, named_sub, and comments, respectively. -

- -

Types

- -

-The class typet inherits from irept. Types may have -subtypes. This is modeled with two edges named "subtype" and "subtypes". The -class typet only add specialized methods for accessing the subtype -information to the interface of irept. -

- -

Interface of class typet

- -
has_subtype and has_subtypes
- -
bool has_subtype() const;
-bool has_subtypes() const;
-
- -

-The first method returns true if the a subtype node exists. is not -nil. The second method returns true is a subtypes node exists. -

- -
subtype and subtypes
- -
typet &subtype();
-typest &subtypes();
-
- -

-The first method returns a reference to the 'subtype' node. -The second method returns a reference to the vector of subtypes. -

- -

Subtypes of typet

- -

-A number of subtypes of typet exist which allow convenient -creation and manipulation of typet objects for special types. -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ClassDescription
bool_typetBoolean type
symbol_typetSymbol type. Has edge "identifier" to a string value, which can be accessed with get_identifier and set_identifier.
struct_typet, union_typetRepresent a struct, resp. union types. Convenience functions to access components components().
code_typetThe type of a function/procedure. Convenience functions to access arguments() and return_type().
array_typetConvenience function size() to access size of the array.
pointer_typetPointer type, subtype stores the type of the object pointed to.
reference_typetRepresents a reference type, subtype stores the type of the object referenced to.
bv_typetRepresents a bit vector type with variable width.
fixed_bv_typetRepresents a bit vector that encodes a fixed-point number.
floatbv_typetRepresents a bit vector that encodes a floating-point number.
string_typetRepresents a string type.
- -

Source Locations

- -

-The class source_locationt inherits from the class irept. It -is used to store locations in text files. It adds specialized methods to -manipulate the edges named "file", "line", "column", "function". -

- -

Expressions

- -

-The class exprt inherits from class irept. Expressions -have operands and a type. This is modeled with ordered edges for the -operands and an edge labeled"type", respectively. The class exprt -only adds specialized methods for accessing operands and type information -to the interface of irept. -

- -
-
Representation of a binary expression
- -

Interface of class exprt

- -
constructors
- -
explicit exprt(const irep_idt &id);
-
- -

-Creates an exprt object with a given label and no type. -

- -
exprt(const irep_idt &id, const typet &type);
-
- -

-Creates an exprt object with a given label and type. -

- -
type
- -
const typet &type() const;
-typet &type();
-
- -

-Return a reference to the 'type' node -

- -
has_operands
- -
bool has_operands() const;
-
- -

-Return true if the expression has at least one operand. -

- -
operands
- -
const operandst &operands() const;
-
- -

-Return a reference to the vector of operands. -

- -
const exprt &op0();
-const exprt &op1();
-const exprt &op2();
-const exprt &op3();
-exprt &op0();
-exprt &op1();
-exprt &op2();
-exprt &op3();
-
- -

-Return a reference to a specific operand. Avoid calling -if the operand does not exist. -

- -
Constructing common expressions
- -
void make_true();
-void make_false();
-void make_bool(bool value);
-
- -

-Turn the current exprt instance into a expression of type "bool" -with label "constant" and a single edge labeled "value", which points to -a new node with label either "true" or "false". -

- -
void make_typecast(const typet &_type);
-
- -

-Turns the current exprt instance into a typecast. The old value of -the instance is appended as the single operand of the typecast, i.e., the -result is a typecast-expression of the old expression to the indicated type. -

- -
void make_not();
-
- -

-Turns the current exprt instance into an expression with label -"not" of the same type as the original expression. The old value of the -instance is appended as the operand of the "not"-node. If the original -expression is of type "bool", the result represents the negation of the -original expression with the following simplifications possibly applied: -

- -
    -
  • ¬ ¬ f = f
  • -
  • ¬ true = false
  • -
  • ¬ false = true
  • -
- -
-void negate();
-
- -

-Turns the current exprt instance into a negation of itself, depending -on its type: -

- -
    - -
  • For boolean expressions, make_not is called.
  • - -
  • For integers, the current instance is turned into a numeric negation -expression "unary-" of its old value. Chains of "unary-" nodes and -negations of integer constants are simplified.
  • - -
  • For all other types, irept::make_nil is called.
  • - -
- -
bool sum(const exprt &expr);
-bool mul(const exprt &expr);
-bool subtract(const exprt &expr);
-
- -

-Expect the "this" object and the function argument to be constants of the -same numeric type. Turn the current exprt instance into a -constant expression of the same type, whose "value" edge points to the -result of the sum, product, or difference of the two expressions. If the -operation fails for some reason (e.g., the types are different), -true is returned. -

- -
Testing common expressions
- -
bool is_constant() const;
-
- -

-Returns true if the expression label is "constant". -

- -
bool is_boolean() const;
-
- -

-Returns true if the label of the type is "bool". - -

bool is_false() const;
-bool is_true() const;
-
- -

-The first function returns true if the expression is a boolean constant with -value "false". The second function returns true for any boolean constant -that is not of value "false". -

- -
bool is_zero() const;
-bool is_one() const;
-
- -

-The first function returns true if the expression represents a zero numeric -constant, or if the expression represents a null pointer. The second -function returns true if the expression represents a numeric constant with -value "1". -

- -

Subtypes of exprt

- -

-A number of subtypes of exprt provide further convenience functions -for edge access or other specialized behaviour: -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ClassDescription
transtRepresents an SMV-style transition system with invariants -invar(), initial state init() and transition -function trans().
true_exprtBoolean constant true expression.
false_exprtBoolean constant false expression.
symbol_exprtRepresents a symbol (e.g., a variable occurrence), convenience function for manipulating "identifier"-edge set_identifier and get_identifier
predicate_exprtConvenience constructors to create expressions of type "bool".
binary_relation_exprt : predicate_exprtConvenience functions to create and manipulate binary expressions of type "bool".
equality_exprt : binary_relation_exprtConvenience functions to create and manipulate equality expressions such as "a == b".
ieee_float_equal_exprt : binary_relation_exprtConvenience functions to create and manipulate equality expressions between floating-point numbers. -
index_exprtRepresents an array access expression such as "a[i]". Convenience functions array() and index() for accessing the array expressions and indexing expression.
typecast_exprtRepresents a cast to the type of the expression.
-and_exprt, -implies_exprt, -or_exprt, -not_exprtRepresentations of logical operators with convenience constructors.
address_of_exprtRepresentation of a C-style &a address-of operation. Convenience function object() for accessing operand.
dereference_exprtRepresentation of a C-style *a pointer-dereference operation. Convenience function object() for accessing operand.
if_exprtRepresentation of a conditional expresion, with convenience functions cond(), true_case() and false_case() for accessing operands.
member_exprtRepresents a some_struct.some_field member access.
codetRepresents a segment of code.
- -

Symbols and the Symbol Table

- -

Symbol

- -

-A symbol is an object of class symbolt. This class -is declared in "util/symbol.h". The code below shows a partial -declaration of the interface: -

- -
class symbolt
-{
-public:
-  typet type;
-  exprt value;
-  std::string name;
-  std::string base_name;
-  ...
-};
-
- -

-Symbol names are unique. Scopes are handled by adding prefixes -to symbols: -

- -
int main(int argc, char* argv[]) {
-	
-	               // Symbol name: c::main::0::alice
-   char alice = 0;     // Symbol base: alice
-   
-   {
-	               // Symbol name: c::main::1::alice
-       int alice = 0;  // Symbol base: alice
-   }
-}
- -

Symbol Table

- -

-A symbol table is an object of class contextt. This class -is declared in "util/context.h". The code below shows a partial -declaration of the interface: -

- -
class symbol_tablett
-{
-public:
-                                 // Insert the symbol
-  bool add(const symbolt &symb);
-                                 // Insert symb into the
-                                 // table and erase it.
-                                 // New_symbol points to the
-                                 // newly inserted element.
-  bool move(symbolt &symbol, symbolt *&new_symbol);
-
-                                 // Insert symb into the
-                                 // table. Then symb is erased.
-  bool move(symbolt &symb);
-
-                                 // Return the entry of the
-                                 // symbol with given name.
-  const irept &value(const std::string &name) const;
-};
-
- -

Goto Programs

- -

-Goto programs are a representation of the control flow graph of a program -that uses only guarded goto and assume statements to model non-sequential -flow. The main definition can be found in -"src/goto-programs/goto_program_template.h", which is a template class. The -concrete instantiation of the template that is used in the framework can be -found in "src/goto-programs/goto_program.h". A single instruction in a goto -program is represented by the class goto_programt::instructiont -whose definition can be found again in -"goto-programs/goto_program_template.h". -

- -

-In the class goto_programt, the control flow graph is represented -as a mixture of sequential transitions between nodes, and non-sequential -transitions at goto-nodes. The sequential flow of the program is captured -by the list instructions that is a field of the class -goto_programt. Transitions via goto statements are represented in -the list targets, which is a field of the class -goto_programt::instructiont, i.e., each goto-instruction carries a -list of possible jump destinations. The latter list targets is a -list of iterators which point to elements of the list instructions. -An illustration is given in the figure below. -

- -
-
Representation of program flow in goto_programt
- -

-Instructions can have a number of different types as represented by -enum goto_program_instruction_typet and can be accessed via the -field type in instructiont. These include: -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
GOTORepresents a non-deterministic branch to the instructions given in the -list targets. Goto statements are guarded, i.e., the -non-deterministic branch is only taken if the expression in -guard evaluates to true, otherwise the program continues -sequentially. Guarded gotos can be used, for example, to model if -statements. The guard is then set to the negated condition of the -statement, and goto target is set to bypass the conditionally executed code -if this guard evaluates to true. -
ASSUMEAn assumption statement that restricts viable paths reaching the -instruction location to the ones that make the expression guard -evaluate to true.
ASSERTAn assertion whose guard is checked for validity when the instruction is -reached.
RETURNA return statement in a function.
END_FUNCTIONDenotes the end of a function.
ASSIGNA variable assignment.
SKIPNo operation.
OTHERAny operation not covered by enum -goto_program_instruction_typet.
- -

-A number of convenience functions in instructiont, such as -is_goto(), is_assume(), etc., simplify type queries. -The following code segment gives a partial interface declaration of -goto_program_template and instructiont. -

- -
template <class codeT, class guardT>
-class goto_program_templatet
-{
-public:
-  //list of instruction type
-  typedef std::list<class instructiont> instructionst;
-
-  //a reference to an instruction in the list
-  typedef typename 
-    std::list::iterator targett;
-
-  //Sequential list of instructions, 
-  //representing sequential program flow
-  instructionst instructions;
-
-  typedef typename 
-    std::map target_numberst;
-
-  //A map containing the unique number of each target
-  target_numberst target_numbers;
-
-  //Get the successors of a given instruction 
-  void get_successors(targett target, targetst &successors); 
-
-  ...
-
- 
-  class instructiont
-  {
-  public:
-    codeT code;
-    
-    //identifier of enclosing function
-    irep_idt function;
-    
-    //location in the source file
-    locationt location;
-    
-    //type of instruction?
-    goto_program_instruction_typet type;
-
-    //Guard statement for gotos, assume, assert 
-    guardT guard;
-    
-    //targets for gotos
-    targetst targets;
-   
-    //set of all predecessors (sequential, and gotos)
-    std::set<targett> incoming_edges;
-    
-    // a globally unique number to identify a 
-    // program location. It is guaranteed to be 
-    // ordered in program order within one 
-    // goto_program
-    unsigned location_number;
-    
-    // a globally unique number to identify loops
-    unsigned loop_number;
-    
-    // true if this is a goto jumping back to an 
-    // earlier instruction in the sequential program 
-    // flow
-    bool is_backwards_goto() const;
-  };
-
-}
-
- - - - - - diff --git a/doc/html-manual/footer.inc b/doc/html-manual/footer.inc deleted file mode 100644 index 3e1257f5a2d..00000000000 --- a/doc/html-manual/footer.inc +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/doc/html-manual/goto-cc-apache.shtml b/doc/html-manual/goto-cc-apache.shtml deleted file mode 100644 index 2a54f1b3ae0..00000000000 --- a/doc/html-manual/goto-cc-apache.shtml +++ /dev/null @@ -1,69 +0,0 @@ - - -

CPROVER Manual TOC

- -

Build Systems and Libraries

- -

Example: Extracting Models from the Apache HTTPD

- -

-The Apache HTTPD is still the most -frequently used web server. Together with the relevant libraries, it -consists of around 0.4 million lines of C code. In the following, we show -how to extract models from Apache HTTPD 2.4.2. -

- -
    - -
  1. -First of all, we download the sources of Apache HTTPD and two supporting -libraries and uncompress them:

    - -

    -  lwp-download http://www.mirrorservice.org/sites/ftp.apache.org/apr/apr-1.4.6.tar.bz2
    -  lwp-download http://www.mirrorservice.org/sites/ftp.apache.org/apr/apr-util-1.4.1.tar.bz2
    -  lwp-download http://mirror.catn.com/pub/apache/httpd/httpd-2.4.2.tar.bz2
    -
    -  bunzip2 < apr-1.4.6.tar.bz2 | tar x
    -  bunzip2 < apr-util-1.4.1.tar.bz2 | tar x
    -  bunzip2 < httpd-2.4.2.tar.bz2 | tar x -

  2. - -
  3. Now compile -gcc-wrap.c and put the resulting binary -into a directory that is in your PATH variable:

    -

    -  lwp-download http://www.cprover.org/cprover-manual/gcc-wrap.c
    -  gcc gcc-wrap.c -o gcc-wrap
    -  cp gcc-wrap ~/bin/
    -

    -

    This assumes that the directory ~/bin -exists and is in your PATH variable.

    -
  4. - -
  5. We now build the sources with gcc:

    - -

    -  (cd apr-1.4.6; ./configure; make CC=gcc-wrap)
    -  (cd apr-util-1.4.1; ./configure --with-apr=../apr-1.4.6 ; make CC=gcc-wrap)
    -  (cd httpd-2.4.2; ./configure --with-apr=../apr-1.4.6 --with-apr-util=../apr-util-1.4.1 ; make CC=gcc-wrap) -

    - -
  6. You can now compile the preprocessed -source files with goto-cc as follows:

    -

    -  find ./ -name *.i > source-file-list
    -  for a in `cat source-file-list` ; do
    -    goto-cc -c $a -o $a.gb
    -  done

    -
  7. - -
- -

-The resulting .gb files can be passed to any -of the CPROVER tools. -

- - - diff --git a/doc/html-manual/goto-cc-linux.shtml b/doc/html-manual/goto-cc-linux.shtml deleted file mode 100644 index 52ecbfb2291..00000000000 --- a/doc/html-manual/goto-cc-linux.shtml +++ /dev/null @@ -1,97 +0,0 @@ - - -

CPROVER Manual TOC

- -

Build Systems and Libraries

- -

Example: Extracting Models from the Linux Kernel

- -

- -The Linux kernel code consists of more than 11 million lines of low-level C -and is frequently used to evaluate static analysis techniques. In the -following, we show how to extract models from Linux 2.6.39. -

- -
    -
  1. -First of all, you will need to make sure you have around 100 GB -of free disc space available.

  2. - -
  3. Download the Kernel sources at - -http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.39.tar.bz2 -. -

  4. - -
  5. Now do

    -

    -  bunzip2 linux-2.6.39.tar.bz2
    -  tar xvf linux-2.6.39.tar
    -  cd linux-2.6.39 -

  6. - -
  7. Now ensure that you can actually -compile a kernel by doing

    -

    -  make defconfig
    -  make

    -

    -These steps need to succeed before you can try to extract -models from the kernel. -

  8. - -
  9. Now compile -gcc-wrap.c and put the resulting binary -into a directory that is in your PATH variable:

    -

    -  lwp-download http://www.cprover.org/cprover-manual/gcc-wrap.c
    -  gcc gcc-wrap.c -o gcc-wrap
    -  cp gcc-wrap ~/bin/
    -

    -

    This assumes that the directory ~/bin -exists and is in your PATH variable.

    -
  10. - -
  11. Now change the variable CC in the kernel -Makefile as follows:

    -

    -  CC = ~/bin/gcc-wrap -

    -
  12. - -
  13. Now do

    -

    -  make clean
    -  make

    -

    -This will re-compile the kernel, but this time retaining the -preprocessed source files. -

  14. - -
  15. You can now compile the preprocessed -source files with goto-cc as follows:

    -

    -  find ./ -name .tmp_*.i > source-file-list
    -  for a in `cat source-file-list` ; do
    -    goto-cc -c $a -o $a.gb
    -  done

    - -

    Note that it is important that the -word-size of the kernel configuration matches that of goto-cc. -Otherwise, compile-time assertions will fail, generating -the error message "bit field size is negative". For a kernel -configured for a 64-bit word-width, pass the option ---64 to goto-cc.

    - -
  16. - -
- -

-The resulting .gb files can be passed to any -of the CPROVER tools. -

- - - diff --git a/doc/html-manual/goto-cc-rockbox.shtml b/doc/html-manual/goto-cc-rockbox.shtml deleted file mode 100644 index 7bae0855bf6..00000000000 --- a/doc/html-manual/goto-cc-rockbox.shtml +++ /dev/null @@ -1,83 +0,0 @@ - - -

CPROVER Manual TOC

- -

Build Systems and Libraries

- -

Example: Extracting Models from the Rockbox

- -

-The Rockbox is an open-source software -package for common MP3 players, with about 1 million lines of code in total. -

- -
    -
  1. -First of all, you will need to install one of the cross-compilers. Follow -the instructions here. -

  2. - -
  3. -You will then need to check out the Rockbox sources with GIT, and -configure and compile the code. Follow -these instructions. The build must succeed. -We will assume that one of the ARM-based targets -is used, and that the ARM cross-compiler is installed -at /usr/local/bin/arm-elf-eabi-gcc. -

  4. - -
  5. Now download -gcc-wrap.c:

    -

    -  lwp-download http://www.cprover.org/cprover-manual/gcc-wrap.c
    -

    -
  6. - -
  7. Open gcc-wrap.c in your favorite editor, -and adjust the path to gcc (in the first line) to -/usr/local/bin/arm-elf-eabi-gcc (it is important that the -full path is given). -

  8. - -
  9. Now compile gcc-wrap:

    -

    -  gcc gcc-wrap.c -o gcc-wrap-arm-elf-eabi-gcc
    -  cp gcc-wrap-arm-elf-eabi-gcc ~/bin/
    -

    -

    This assumes that the directory ~/bin -exists and is in your PATH variable.

    -
  10. - -
  11. Now re-compile the Rockbox code as follows:

    -

    -  make clean
    -  make CC=gcc-wrap-arm-elf-eabi-gcc

    -

    -This will re-compile the Rockbox, but this time retaining the -preprocessed source files. -

  12. - -
  13. You can now compile the preprocessed -source files with goto-cc as follows:

    -

    -  find ./ -name \*.i > source-file-list
    -  for a in `cat source-file-list` ; do
    -    goto-cc -std=gnu99 -m32 -c $a -o $a.gb
    -  done

    - -

    Note that it is important that the -word-size of the target platform matches that of goto-cc. -For a 32-bit target, pass the option --m32 to goto-cc.

    - -
  14. - -
- -

-The resulting .gb files can be passed to any -of the CPROVER tools. -

- - - diff --git a/doc/html-manual/goto-cc-variants.shtml b/doc/html-manual/goto-cc-variants.shtml deleted file mode 100644 index f31a6eabd79..00000000000 --- a/doc/html-manual/goto-cc-variants.shtml +++ /dev/null @@ -1,49 +0,0 @@ - - -

CPROVER Manual TOC

- -

Build Systems and Libraries

- -

Variants of goto-cc

- -

-The goto-cc utility comes in several variants, summarised in the following table. -

- -
- - - - - - - - - - - - - - - - - - - -
ExecutableEnvironmentPreprocessor
goto-ccgcc (control-flow graph only)gcc -E
goto-gccgcc ("hybrid" executable)gcc -E
goto-armccARM RVDSarmcc -E
goto-clVisual Studiocl /E
goto-cwFreescale CodeWarriormwcceppc
-
- -

- -The primary difference between the variants is the preprocessor called. -Furthermore, the language recognized varies slightly. The variants can be -obtained by simply renaming the goto-cc executable. On Linux/MacOS, the -variants can be obtained by creating a symbolic link.

- -

-The "hybrid" -executables contain both the control-flow graph for verification purposes -and the usual, executable machine code. -

- - diff --git a/doc/html-manual/goto-cc-visual-studio.shtml b/doc/html-manual/goto-cc-visual-studio.shtml deleted file mode 100644 index a7ab178e9a8..00000000000 --- a/doc/html-manual/goto-cc-visual-studio.shtml +++ /dev/null @@ -1,57 +0,0 @@ - - -

CPROVER Manual TOC

- -

Build Systems and Libraries

- -

Integration into Visual Studio 2008 to 2012

- -

-Visual Studio version 2008 onwards comes with a new XML-based -build system called MSBuild. -The MSBuild system is also activated when triggering a build from the Visual Studio GUI. -The project files created by the Visual Studio GUI are used as input by the MSBuild tool. -

- -

-The MSBuild system can be used to generate goto-binaries from your Visual Studio project -as follows: -

- -
    - -
  1. -Install the goto-cl.exe and goto-link.exe binaries -in some directory that is contained in the PATH environment -variable.

  2. - -
  3. Add a configuration for the goto-cc build for your project -in the configuration manager, named "goto-cc".

  4. - -
  5. Open the Visual Studio Command Prompt (in the Tools menu).

  6. - -
  7. Locate the directory that contains the project. Change into this -directory using "CD".

  8. - -
  9. Type

    -

    - -msbuild /p:CLToolExe=goto-cl.exe /p:LinkToolExe=goto-link.exe
    -   /p:Flavor=goto-cc /p:Platform=x86 -
    -

    - -

    -The platform can be adjusted as required; the "Flavor" given should match -the configuration that was created earlier. -

  10. - -
- -

-Note that the recent versions of goto-cc also support file names with -non-ASCII (Unicode) characters on Windows platforms. -

- - - diff --git a/doc/html-manual/goto-cc.shtml b/doc/html-manual/goto-cc.shtml deleted file mode 100644 index cdc3c7d3406..00000000000 --- a/doc/html-manual/goto-cc.shtml +++ /dev/null @@ -1,144 +0,0 @@ - - -

CPROVER Manual TOC

- -

Build Systems and Libraries

- -

Integration into Build Systems with goto-cc

- -

-Existing software projects usually do not come in a single source file that -may simply be passed to a model checker. They rather come in a multitude of -source files in different directories and refer to external libraries and -system-wide options. A build system then collects the configuration options -from the system and compiles the software according to build rules. -

- -

-The most prevalent build tool on Unix (-based) systems surely is the -make utility. This tool uses build rules given in a -Makefile that comes with the software sources. Running software -verification tools on projects like these is greatly simplified by a -compiler that first collects all the necessary models into a single -model file. goto-cc -is such a model file extractor, which can seamlessly replace gcc -and cl.exe in Makefiles. The normal build system for the -project may be used to build the software, but the outcome will be a -model file with suitable detail for verification, as opposed to a -flat executable program. Note that goto-cc comes in different variants -depending on the compilation environment. These variants -are described here. -

- -

Example: Building wu-ftpd

- -

This example assumes a Unix-like machine.

- -
    - -
  1. Download the sources of wu-ftpd from - - here. -

  2. - -
  3. Unpack the sources by running - tar xfz wu-ftpd-current.tar.gz -

  4. - -
  5. Change to the source directory, by entering, e.g., - cd wu-ftpd-2.6.2 -

  6. - -
  7. Configure the project for verification by running -

    -
    - ./configure YACC=byacc CC=goto-cc --host=none-none-none -
    -
  8. - -
  9. Build the project by running - make. - This creates multiple model files in the src directory. Among - them is a model for the main executable ftpd. -

  10. - -
  11. Run a model-checker, e.g., CBMC, - on the model file: -

    -
    - cbmc src/ftpd -
    -

    CBMC automatically recognizes that the file -is a goto binary. -

    -
  12. - -
- -

Important Notes

- -

-More elaborate build or configuration scripts often make use of -features of the compiler or the system library to detect configuration -options automatically, e.g., in a configure script. -Replacing gcc by goto-cc at this stage may confuse the script, -or detect wrong options. For example, missing library functions do not -cause goto-cc to throw an error (only to issue a warning). Because of -this, configuration scripts sometimes falsely assume the availability -of a system function or library. -

- -

-In the case of this or similar problems, it is more advisable to -configure the project using the normal routine, and replacing the -compiler setting manually in the generated Makefiles, e.g., by -replacing lines like CC=gcc by CC=goto-cc. -

- -

-A helpful command that accomplishes this task successfully for many -projects is the following: -

- - -for i in `find . -name Makefile`; do
-  sed -e 's/^\(\s*CC[ \t]*=\)\(.*$\)/\1goto-cc/g' -i $i
-done -
- -

Here are additional examples on how to use goto-cc:

- - - -

A description -of how to integrate goto-cc into Microsoft's Visual Studio -is here.

- -

Linking Libraries

- -

-Some software projects come with their own libraries; also, the goal may be -to analyze a library by itself. For this purpose it is possible to use -goto-cc to link multiple model files into a library of model files. An -object file can then be linked against this model library. For this purpose, -goto-cc also features a linker mode. -

- -

-To enable this linker mode, create a link to the goto-cc binary by the -name of goto-ld (Linux and Mac) or copy the goto-cc binary to goto-link.exe -(Windows). The goto-ld tool can now be used as a seamless replacement -for the ld tool present on most Unix (-based) systems and -for the link tool on Windows. -

- -

-The default linker may need to be replaced by goto-ld or -goto-link.exe in the build -script, which can be achieved in much the same way as replacing the compiler. -

- - diff --git a/doc/html-manual/header.inc b/doc/html-manual/header.inc deleted file mode 100644 index 4624f036f24..00000000000 --- a/doc/html-manual/header.inc +++ /dev/null @@ -1,23 +0,0 @@ - - - - - -CPROVER Manual - - - - - - -
-
- - diff --git a/doc/html-manual/highlight/CHANGES.md b/doc/html-manual/highlight/CHANGES.md deleted file mode 100644 index 377202d8bd8..00000000000 --- a/doc/html-manual/highlight/CHANGES.md +++ /dev/null @@ -1,1429 +0,0 @@ -## Version 9.4.0 - -New languages: - -- *PureBASIC* by [Tristano Ajmone][] -- *BNF* by [Oleg Efimov][] -- *Ada* by [Lars Schulna][] - -New styles: - -- *PureBASIC* by [Tristano Ajmone][] - -Improvements to existing languages and styles: - -- We now highlight function declarations in Go. -- [Taisuke Fujimoto][] contributed very convoluted rules for raw and - interpolated strings in C#. -- [Boone Severson][] updated Verilog to comply with IEEE 1800-2012 - SystemVerilog. -- [Victor Zhou][] improved rules for comments and strings in PowerShell files. -- [Janis Voigtländer][] updated the definition of Elm to version 0.17 of the - languages. Elm is now featured on the front page of . -- Special variable `$this` is highlighted as a keyword in PHP. -- `usize` and `isize` are now highlighted in Rust. -- Fixed labels and directives in x86 assembler. - -[Tristano Ajmone]: https://github.com/tajmone -[Taisuke Fujimoto]: https://github.com/temp-impl -[Oleg Efimov]: https://github.com/Sannis -[Boone Severson]: https://github.com/BooneJS -[Victor Zhou]: https://github.com/OiCMudkips -[Lars Schulna]: https://github.com/captain-hanuta -[Janis Voigtländer]: https://github.com/jvoigtlaender - - -## Version 9.3.0 - -New languages: - -- *Tagger Script* by [Philipp Wolfer][] -- *MoonScript* by [Billy Quith][] - -New styles: - -- *xt256* by [Herbert Shin][] - -Improvements to existing languages and styles: - -- More robust handling of unquoted HTML tag attributes -- Relevance tuning for QML which was unnecessary eager at seizing other - languages' code -- Improve GAMS language parsing -- Fixed a bunch of bugs around selectors in Less -- Kotlin's got a new definition for annotations, updated keywords and other - minor improvements -- Added `move` to Rust keywords -- Markdown now recognizes \`\`\`-fenced code blocks -- Improved detection of function declarations in C++ and C# - -[Philipp Wolfer]: https://github.com/phw -[Billy Quith]: https://github.com/billyquith -[Herbert Shin]: https://github.com/initbar - - -## Version 9.2.0 - -New languages: - -- *QML* by [John Foster][] -- *HTMLBars* by [Michael Johnston][] -- *CSP* by [Taras][] -- *Maxima* by [Robert Dodier][] - -New styles: - -- *Gruvbox* by [Qeole][] -- *Dracula* by [Denis Ciccale][] - -Improvements to existing languages and styles: - -- We now correctly handle JSX with arbitrary node tree depth. -- Argument list for `(lambda)` in Scheme is no longer highlighted as a function - call. -- Stylus syntax doesn't break on valid CSS. -- More correct handling of comments and strings and other improvements for - VimScript. -- More subtle work on the default style. -- We now use anonymous modules for AMD. -- `macro_rules!` is now recognized as a built-in in Rust. - -[John Foster]: https://github.com/jf990 -[Qeole]: https://github.com/Qeole -[Denis Ciccale]: https://github.com/dciccale -[Michael Johnston]: https://github.com/lastobelus -[Taras]: https://github.com/oxdef -[Robert Dodier]: https://github.com/robert-dodier - - -## Version 9.1.0 - -New languages: - -- *Stan* by [Brendan Rocks][] -- *BASIC* by [Raphaël Assénat][] -- *GAUSS* by [Matt Evans][] -- *DTS* by [Martin Braun][] -- *Arduino* by [Stefania Mellai][] - -New Styles: - -- *Arduino Light* by [Stefania Mellai][] - -Improvements to existing languages and styles: - -- Handle return type annotations in Python -- Allow shebang headers in Javascript -- Support strings in Rust meta -- Recognize `struct` as a class-level definition in Rust -- Recognize b-prefixed chars and strings in Rust -- Better numbers handling in Verilog - -[Brendan Rocks]: http://brendanrocks.com -[Raphaël Assénat]: https://github.com/raphnet -[Matt Evans]: https://github.com/matthewevans -[Martin Braun]: https://github.com/mbr0wn -[Stefania Mellai]: https://github.com/smellai - - -## Version 9.0.0 - -The new major version brings a reworked styling system. Highlight.js now defines -a limited set of highlightable classes giving a consistent result across all the -styles and languages. You can read a more detailed explanation and background in -the [tracking issue][#348] that started this long process back in May. - -This change is backwards incompatible for those who uses highlight.js with a -custom stylesheet. The [new style guide][sg] explains how to write styles -in this new world. - -Bundled themes have also suffered a significant amount of improvements and may -look different in places, but all the things now consistent and make more sense. -Among others, the Default style has got a refresh and will probably be tweaked -some more in next releases. Please do give your feedback in our -[issue tracker][issues]. - -New languages in this release: - -- *Caché Object Script* by [Nikita Savchenko][] -- *YAML* by [Stefan Wienert][] -- *MIPS Assembler* by [Nebuleon Fumika][] -- *HSP* by [prince][] - -Improvements to existing languages and styles: - -- ECMAScript 6 modules import now do not require closing semicolon. -- ECMAScript 6 classes constructors now highlighted. -- Template string support for Typescript, as for ECMAScript 6. -- Scala case classes params highlight fixed. -- Built-in names introduced in Julia v0.4 added by [Kenta Sato][]. -- Refreshed Default style. - -Other notable changes: - -- [Web workers support][webworkers] added bu [Jan Kühle][]. -- We now have tests for compressed browser builds as well. -- The building tool chain has been switched to node.js 4.x. and is now - shamelessly uses ES6 features all over the place, courtesy of [Jeremy Hull][]. -- License added to non-compressed browser build. - -[Jan Kühle]: https://github.com/frigus02 -[Stefan Wienert]: https://github.com/zealot128 -[Kenta Sato]: https://github.com/bicycle1885 -[Nikita Savchenko]: https://github.com/ZitRos -[webworkers]: https://github.com/isagalaev/highlight.js#web-workers -[Jeremy Hull]: https://github.com/sourrust -[#348]: https://github.com/isagalaev/highlight.js/issues/348 -[sg]: http://highlightjs.readthedocs.org/en/latest/style-guide.html -[issues]: https://github.com/isagalaev/highlight.js/issues -[Nebuleon Fumika]: https://github.com/Nebuleon -[prince]: https://github.com/prince-0203 - - -## Version 8.9.1 - -Some last-minute changes reverted due to strange bug with minified browser build: - -- Scala case classes params highlight fixed -- ECMAScript 6 modules import now do not require closing semicolon -- ECMAScript 6 classes constructors now highlighted -- Template string support for Typescript, as for ECMAScript 6 -- License added to not minified browser build - - -## Version 8.9.0 - -New languages: - -- *crmsh* by [Kristoffer Gronlund][] -- *SQF* by [Soren Enevoldsen][] - -[Kristoffer Gronlund]: https://github.com/krig -[Soren Enevoldsen]: https://github.com/senevoldsen90 - -Notable fixes and improvements to existing languages: - -- Added `abstract` and `namespace` keywords to TypeScript by [Daniel Rosenwasser][] -- Added `label` support to Dockerfile by [Ladislav Prskavec][] -- Crystal highlighting improved by [Tsuyusato Kitsune][] -- Missing Swift keywords added by [Nate Cook][] -- Improve detection of C block comments -- ~~Scala case classes params highlight fixed~~ -- ~~ECMAScript 6 modules import now do not require closing semicolon~~ -- ~~ECMAScript 6 classes constructors now highlighted~~ -- ~~Template string support for Typescript, as for ECMAScript 6~~ - -Other notable changes: - -- ~~License added to not minified browser build~~ - -[Kristoffer Gronlund]: https://github.com/krig -[Søren Enevoldsen]: https://github.com/senevoldsen90 -[Daniel Rosenwasser]: https://github.com/DanielRosenwasser -[Ladislav Prskavec]: https://github.com/abtris -[Tsuyusato Kitsune]: https://github.com/MakeNowJust -[Nate Cook]: https://github.com/natecook1000 - - -## Version 8.8.0 - -New languages: - -- *Golo* by [Philippe Charrière][] -- *GAMS* by [Stefan Bechert][] -- *IRPF90* by [Anthony Scemama][] -- *Access logs* by [Oleg Efimov][] -- *Crystal* by [Tsuyusato Kitsune][] - -Notable fixes and improvements to existing languages: - -- JavaScript highlighting no longer fails with ES6 default parameters -- Added keywords `async` and `await` to Python -- PHP heredoc support improved -- Allow preprocessor directives within C++ functions - -Other notable changes: - -- Change versions to X.Y.Z SemVer-compatible format -- Added ability to build all targets at once - -[Philippe Charrière]: https://github.com/k33g -[Stefan Bechert]: https://github.com/b-pos465 -[Anthony Scemama]: https://github.com/scemama -[Oleg Efimov]: https://github.com/Sannis -[Tsuyusato Kitsune]: https://github.com/MakeNowJust - - -## Version 8.7 - -New languages: - -- *Zephir* by [Oleg Efimov][] -- *Elm* by [Janis Voigtländer][] -- *XQuery* by [Dirk Kirsten][] -- *Mojolicious* by [Dotan Dimet][] -- *AutoIt* by Manh Tuan from [J2TeaM][] -- *Toml* (ini extension) by [Guillaume Gomez][] - -New styles: - -- *Hopscotch* by [Jan T. Sott][] -- *Grayscale* by [MY Sun][] - -Notable fixes and improvements to existing languages: - -- Fix encoding of images when copied over in certain builds -- Fix incorrect highlighting of the word "bug" in comments -- Treat decorators different from matrix multiplication in Python -- Fix traits inheritance highlighting in Rust -- Fix incorrect document -- Oracle keywords added to SQL language definition by [Vadimtro][] -- Postgres keywords added to SQL language definition by [Benjamin Auder][] -- Fix registers in x86asm being highlighted as a hex number -- Fix highlighting for numbers with a leading decimal point -- Correctly highlight numbers and strings inside of C/C++ macros -- C/C++ functions now support pointer, reference, and move returns - -[Oleg Efimov]: https://github.com/Sannis -[Guillaume Gomez]: https://github.com/GuillaumeGomez -[Janis Voigtländer]: https://github.com/jvoigtlaender -[Jan T. Sott]: https://github.com/idleberg -[Dirk Kirsten]: https://github.com/dirkk -[MY Sun]: https://github.com/simonmysun -[Vadimtro]: https://github.com/Vadimtro -[Benjamin Auder]: https://github.com/ghost -[Dotan Dimet]: https://github.com/dotandimet -[J2TeaM]: https://github.com/J2TeaM - - -## Version 8.6 - -New languages: - -- *C/AL* by [Kenneth Fuglsang][] -- *DNS zone file* by [Tim Schumacher][] -- *Ceylon* by [Lucas Werkmeister][] -- *OpenSCAD* by [Dan Panzarella][] -- *Inform7* by [Bruno Dias][] -- *armasm* by [Dan Panzarella][] -- *TP* by [Jay Strybis][] - -New styles: - -- *Atelier Cave*, *Atelier Estuary*, - *Atelier Plateau* and *Atelier Savanna* by [Bram de Haan][] -- *Github Gist* by [Louis Barranqueiro][] - -Notable fixes and improvements to existing languages: - -- Multi-line raw strings from C++11 are now supported -- Fix class names with dashes in HAML -- The `async` keyword from ES6/7 is now supported -- TypeScript functions handle type and parameter complexity better -- We unified phpdoc/javadoc/yardoc etc modes across all languages -- CSS .class selectors relevance was dropped to prevent wrong language detection -- Images is now included to CDN build -- Release process is now automated - -[Bram de Haan]: https://github.com/atelierbram -[Kenneth Fuglsang]: https://github.com/kfuglsang -[Louis Barranqueiro]: https://github.com/LouisBarranqueiro -[Tim Schumacher]: https://github.com/enko -[Lucas Werkmeister]: https://github.com/lucaswerkmeister -[Dan Panzarella]: https://github.com/pzl -[Bruno Dias]: https://github.com/sequitur -[Jay Strybis]: https://github.com/unreal - - -## Version 8.5 - -New languages: - -- *pf.conf* by [Peter Piwowarski][] -- *Julia* by [Kenta Sato][] -- *Prolog* by [Raivo Laanemets][] -- *Docker* by [Alexis Hénaut][] -- *Fortran* by [Anthony Scemama][] and [Thomas Applencourt][] -- *Kotlin* by [Sergey Mashkov][] - -New styles: - -- *Agate* by [Taufik Nurrohman][] -- *Darkula* by [Jet Brains][] -- *Atelier Sulphurpool* by [Bram de Haan][] -- *Android Studio* by [Pedro Oliveira][] - -Notable fixes and improvements to existing languages: - -- ES6 features in JavaScript are better supported now by [Gu Yiling][]. -- Swift now recognizes body-less method definitions. -- Single expression functions `def foo, do: ... ` now work in Elixir. -- More uniform detection of built-in classes in Objective C. -- Fixes for number literals and processor directives in Rust. -- HTML ` - ``` - -- `tabReplace` and `useBR` that were used in different places are also unified - into the global options object and are to be set using `configure(options)`. - This function is documented in our [API docs][]. Also note that these - parameters are gone from `highlightBlock` and `fixMarkup` which are now also - rely on `configure`. - -- We removed public-facing (though undocumented) object `hljs.LANGUAGES` which - was used to register languages with the library in favor of two new methods: - `registerLanguage` and `getLanguage`. Both are documented in our [API docs][]. - -- Result returned from `highlight` and `highlightAuto` no longer contains two - separate attributes contributing to relevance score, `relevance` and - `keyword_count`. They are now unified in `relevance`. - -Another technically compatible change that nonetheless might need attention: - -- The structure of the NPM package was refactored, so if you had installed it - locally, you'll have to update your paths. The usual `require('highlight.js')` - works as before. This is contributed by [Dmitry Smolin][]. - -New features: - -- Languages now can be recognized by multiple names like "js" for JavaScript or - "html" for, well, HTML (which earlier insisted on calling it "xml"). These - aliases can be specified in the class attribute of the code container in your - HTML as well as in various API calls. For now there are only a few very common - aliases but we'll expand it in the future. All of them are listed in the - [class reference][cr]. - -- Language detection can now be restricted to a subset of languages relevant in - a given context — a web page or even a single highlighting call. This is - especially useful for node.js build that includes all the known languages. - Another example is a StackOverflow-style site where users specify languages - as tags rather than in the markdown-formatted code snippets. This is - documented in the [API reference][] (see methods `highlightAuto` and - `configure`). - -- Language definition syntax streamlined with [variants][] and - [beginKeywords][]. - -New languages and styles: - -- *Oxygene* by [Carlo Kok][] -- *Mathematica* by [Daniel Kvasnička][] -- *Autohotkey* by [Seongwon Lee][] -- *Atelier* family of styles in 10 variants by [Bram de Haan][] -- *Paraíso* styles by [Jan T. Sott][] - -Miscellaneous improvements: - -- Highlighting `=>` prompts in Clojure. -- [Jeremy Hull][] fixed a lot of styles for consistency. -- Finally, highlighting PHP and HTML [mixed in peculiar ways][php-html]. -- Objective C and C# now properly highlight titles in method definition. -- Big overhaul of relevance counting for a number of languages. Please do report - bugs about mis-detection of non-trivial code snippets! - -[API reference]: http://highlightjs.readthedocs.org/en/latest/api.html - -[cr]: http://highlightjs.readthedocs.org/en/latest/css-classes-reference.html -[api docs]: http://highlightjs.readthedocs.org/en/latest/api.html -[variants]: https://groups.google.com/d/topic/highlightjs/VoGC9-1p5vk/discussion -[beginKeywords]: https://github.com/isagalaev/highlight.js/commit/6c7fdea002eb3949577a85b3f7930137c7c3038d -[php-html]: https://twitter.com/highlightjs/status/408890903017689088 - -[Carlo Kok]: https://github.com/carlokok -[Bram de Haan]: https://github.com/atelierbram -[Daniel Kvasnička]: https://github.com/dkvasnicka -[Dmitry Smolin]: https://github.com/dimsmol -[Jeremy Hull]: https://github.com/sourrust -[Seongwon Lee]: https://github.com/dlimpid -[Jan T. Sott]: https://github.com/idleberg - - -## Version 7.5 - -A catch-up release dealing with some of the accumulated contributions. This one -is probably will be the last before the 8.0 which will be slightly backwards -incompatible regarding some advanced use-cases. - -One outstanding change in this version is the addition of 6 languages to the -[hosted script][d]: Markdown, ObjectiveC, CoffeeScript, Apache, Nginx and -Makefile. It now weighs about 6K more but we're going to keep it under 30K. - -New languages: - -- OCaml by [Mehdi Dogguy][mehdid] and [Nicolas Braud-Santoni][nbraud] -- [LiveCode Server][lcs] by [Ralf Bitter][revig] -- Scilab by [Sylvestre Ledru][sylvestre] -- basic support for Makefile by [Ivan Sagalaev][isagalaev] - -Improvements: - -- Ruby's got support for characters like `?A`, `?1`, `?\012` etc. and `%r{..}` - regexps. -- Clojure now allows a function call in the beginning of s-expressions - `(($filter "myCount") (arr 1 2 3 4 5))`. -- Haskell's got new keywords and now recognizes more things like pragmas, - preprocessors, modules, containers, FFIs etc. Thanks to [Zena Treep][treep] - for the implementation and to [Jeremy Hull][sourrust] for guiding it. -- Miscellaneous fixes in PHP, Brainfuck, SCSS, Asciidoc, CMake, Python and F#. - -[mehdid]: https://github.com/mehdid -[nbraud]: https://github.com/nbraud -[revig]: https://github.com/revig -[lcs]: http://livecode.com/developers/guides/server/ -[sylvestre]: https://github.com/sylvestre -[isagalaev]: https://github.com/isagalaev -[treep]: https://github.com/treep -[sourrust]: https://github.com/sourrust -[d]: http://highlightjs.org/download/ - - -## New core developers - -The latest long period of almost complete inactivity in the project coincided -with growing interest to it led to a decision that now seems completely obvious: -we need more core developers. - -So without further ado let me welcome to the core team two long-time -contributors: [Jeremy Hull][] and [Oleg -Efimov][]. - -Hope now we'll be able to work through stuff faster! - -P.S. The historical commit is [here][1] for the record. - -[Jeremy Hull]: https://github.com/sourrust -[Oleg Efimov]: https://github.com/sannis -[1]: https://github.com/isagalaev/highlight.js/commit/f3056941bda56d2b72276b97bc0dd5f230f2473f - - -## Version 7.4 - -This long overdue version is a snapshot of the current source tree with all the -changes that happened during the past year. Sorry for taking so long! - -Along with the changes in code highlight.js has finally got its new home at -, moving from its cradle on Software Maniacs which it -outgrew a long time ago. Be sure to report any bugs about the site to -. - -On to what's new… - -New languages: - -- Handlebars templates by [Robin Ward][] -- Oracle Rules Language by [Jason Jacobson][] -- F# by [Joans Follesø][] -- AsciiDoc and Haml by [Dan Allen][] -- Lasso by [Eric Knibbe][] -- SCSS by [Kurt Emch][] -- VB.NET by [Poren Chiang][] -- Mizar by [Kelley van Evert][] - -[Robin Ward]: https://github.com/eviltrout -[Jason Jacobson]: https://github.com/jayce7 -[Joans Follesø]: https://github.com/follesoe -[Dan Allen]: https://github.com/mojavelinux -[Eric Knibbe]: https://github.com/EricFromCanada -[Kurt Emch]: https://github.com/kemch -[Poren Chiang]: https://github.com/rschiang -[Kelley van Evert]: https://github.com/kelleyvanevert - -New style themes: - -- Monokai Sublime by [noformnocontent][] -- Railscasts by [Damien White][] -- Obsidian by [Alexander Marenin][] -- Docco by [Simon Madine][] -- Mono Blue by [Ivan Sagalaev][] (uses a single color hue for everything) -- Foundation by [Dan Allen][] - -[noformnocontent]: http://nn.mit-license.org/ -[Damien White]: https://github.com/visoft -[Alexander Marenin]: https://github.com/ioncreature -[Simon Madine]: https://github.com/thingsinjars -[Ivan Sagalaev]: https://github.com/isagalaev - -Other notable changes: - -- Corrected many corner cases in CSS. -- Dropped Python 2 version of the build tool. -- Implemented building for the AMD format. -- Updated Rust keywords (thanks to [Dmitry Medvinsky][]). -- Literal regexes can now be used in language definitions. -- CoffeeScript highlighting is now significantly more robust and rich due to - input from [Cédric Néhémie][]. - -[Dmitry Medvinsky]: https://github.com/dmedvinsky -[Cédric Néhémie]: https://github.com/abe33 - - -## Version 7.3 - -- Since this version highlight.js no longer works in IE version 8 and older. - It's made it possible to reduce the library size and dramatically improve code - readability and made it easier to maintain. Time to go forward! - -- New languages: AppleScript (by [Nathan Grigg][ng] and [Dr. Drang][dd]) and - Brainfuck (by [Evgeny Stepanischev][bolk]). - -- Improvements to existing languages: - - - interpreter prompt in Python (`>>>` and `...`) - - @-properties and classes in CoffeeScript - - E4X in JavaScript (by [Oleg Efimov][oe]) - - new keywords in Perl (by [Kirk Kimmel][kk]) - - big Ruby syntax update (by [Vasily Polovnyov][vast]) - - small fixes in Bash - -- Also Oleg Efimov did a great job of moving all the docs for language and style - developers and contributors from the old wiki under the source code in the - "docs" directory. Now these docs are nicely presented at - . - -[ng]: https://github.com/nathan11g -[dd]: https://github.com/drdrang -[bolk]: https://github.com/bolknote -[oe]: https://github.com/Sannis -[kk]: https://github.com/kimmel -[vast]: https://github.com/vast - - -## Version 7.2 - -A regular bug-fix release without any significant new features. Enjoy! - - -## Version 7.1 - -A Summer crop: - -- [Marc Fornos][mf] made the definition for Clojure along with the matching - style Rainbow (which, of course, works for other languages too). -- CoffeeScript support continues to improve getting support for regular - expressions. -- Yoshihide Jimbo ported to highlight.js [five Tomorrow styles][tm] from the - [project by Chris Kempson][tm0]. -- Thanks to [Casey Duncun][cd] the library can now be built in the popular - [AMD format][amd]. -- And last but not least, we've got a fair number of correctness and consistency - fixes, including a pretty significant refactoring of Ruby. - -[mf]: https://github.com/mfornos -[tm]: http://jmblog.github.com/color-themes-for-highlightjs/ -[tm0]: https://github.com/ChrisKempson/Tomorrow-Theme -[cd]: https://github.com/caseman -[amd]: http://requirejs.org/docs/whyamd.html - - -## Version 7.0 - -The reason for the new major version update is a global change of keyword syntax -which resulted in the library getting smaller once again. For example, the -hosted build is 2K less than at the previous version while supporting two new -languages. - -Notable changes: - -- The library now works not only in a browser but also with [node.js][]. It is - installable with `npm install highlight.js`. [API][] docs are available on our - wiki. - -- The new unique feature (apparently) among syntax highlighters is highlighting - *HTTP* headers and an arbitrary language in the request body. The most useful - languages here are *XML* and *JSON* both of which highlight.js does support. - Here's [the detailed post][p] about the feature. - -- Two new style themes: a dark "south" *[Pojoaque][]* by Jason Tate and an - emulation of*XCode* IDE by [Angel Olloqui][ao]. - -- Three new languages: *D* by [Aleksandar Ružičić][ar], *R* by [Joe Cheng][jc] - and *GLSL* by [Sergey Tikhomirov][st]. - -- *Nginx* syntax has become a million times smaller and more universal thanks to - remaking it in a more generic manner that doesn't require listing all the - directives in the known universe. - -- Function titles are now highlighted in *PHP*. - -- *Haskell* and *VHDL* were significantly reworked to be more rich and correct - by their respective maintainers [Jeremy Hull][sr] and [Igor Kalnitsky][ik]. - -And last but not least, many bugs have been fixed around correctness and -language detection. - -Overall highlight.js currently supports 51 languages and 20 style themes. - -[node.js]: http://nodejs.org/ -[api]: http://softwaremaniacs.org/wiki/doku.php/highlight.js:api -[p]: http://softwaremaniacs.org/blog/2012/05/10/http-and-json-in-highlight-js/en/ -[pojoaque]: http://web-cms-designs.com/ftopict-10-pojoaque-style-for-highlight-js-code-highlighter.html -[ao]: https://github.com/angelolloqui -[ar]: https://github.com/raleksandar -[jc]: https://github.com/jcheng5 -[st]: https://github.com/tikhomirov -[sr]: https://github.com/sourrust -[ik]: https://github.com/ikalnitsky - - -## Version 6.2 - -A lot of things happened in highlight.js since the last version! We've got nine -new contributors, the discussion group came alive, and the main branch on GitHub -now counts more than 350 followers. Here are most significant results coming -from all this activity: - -- 5 (five!) new languages: Rust, ActionScript, CoffeeScript, MatLab and - experimental support for markdown. Thanks go to [Andrey Vlasovskikh][av], - [Alexander Myadzel][am], [Dmytrii Nagirniak][dn], [Oleg Efimov][oe], [Denis - Bardadym][db] and [John Crepezzi][jc]. - -- 2 new style themes: Monokai by [Luigi Maselli][lm] and stylistic imitation of - another well-known highlighter Google Code Prettify by [Aahan Krish][ak]. - -- A vast number of [correctness fixes and code refactorings][log], mostly made - by [Oleg Efimov][oe] and [Evgeny Stepanischev][es]. - -[av]: https://github.com/vlasovskikh -[am]: https://github.com/myadzel -[dn]: https://github.com/dnagir -[oe]: https://github.com/Sannis -[db]: https://github.com/btd -[jc]: https://github.com/seejohnrun -[lm]: http://grigio.org/ -[ak]: https://github.com/geekpanth3r -[es]: https://github.com/bolknote -[log]: https://github.com/isagalaev/highlight.js/commits/ - - -## Version 6.1 — Solarized - -[Jeremy Hull][jh] has implemented my dream feature — a port of [Solarized][] -style theme famous for being based on the intricate color theory to achieve -correct contrast and color perception. It is now available for highlight.js in -both variants — light and dark. - -This version also adds a new original style Arta. Its author pumbur maintains a -[heavily modified fork of highlight.js][pb] on GitHub. - -[jh]: https://github.com/sourrust -[solarized]: http://ethanschoonover.com/solarized -[pb]: https://github.com/pumbur/highlight.js - - -## Version 6.0 - -New major version of the highlighter has been built on a significantly -refactored syntax. Due to this it's even smaller than the previous one while -supporting more languages! - -New languages are: - -- Haskell by [Jeremy Hull][sourrust] -- Erlang in two varieties — module and REPL — made collectively by [Nikolay - Zakharov][desh], [Dmitry Kovega][arhibot] and [Sergey Ignatov][ignatov] -- Objective C by [Valerii Hiora][vhbit] -- Vala by [Antono Vasiljev][antono] -- Go by [Stephan Kountso][steplg] - -[sourrust]: https://github.com/sourrust -[desh]: http://desh.su/ -[arhibot]: https://github.com/arhibot -[ignatov]: https://github.com/ignatov -[vhbit]: https://github.com/vhbit -[antono]: https://github.com/antono -[steplg]: https://github.com/steplg - -Also this version is marginally faster and fixes a number of small long-standing -bugs. - -Developer overview of the new language syntax is available in a [blog post about -recent beta release][beta]. - -[beta]: http://softwaremaniacs.org/blog/2011/04/25/highlight-js-60-beta/en/ - -P.S. New version is not yet available on a Yandex CDN, so for now you have to -download [your own copy][d]. - -[d]: /soft/highlight/en/download/ - - -## Version 5.14 - -Fixed bugs in HTML/XML detection and relevance introduced in previous -refactoring. - -Also test.html now shows the second best result of language detection by -relevance. - - -## Version 5.13 - -Past weekend began with a couple of simple additions for existing languages but -ended up in a big code refactoring bringing along nice improvements for language -developers. - -### For users - -- Description of C++ has got new keywords from the upcoming [C++ 0x][] standard. -- Description of HTML has got new tags from [HTML 5][]. -- CSS-styles have been unified to use consistent padding and also have lost - pop-outs with names of detected languages. -- [Igor Kalnitsky][ik] has sent two new language descriptions: CMake & VHDL. - -This makes total number of languages supported by highlight.js to reach 35. - -Bug fixes: - -- Custom classes on `
` tags are not being overridden anymore
-- More correct highlighting of code blocks inside non-`
` containers:
-  highlighter now doesn't insist on replacing them with its own container and
-  just replaces the contents.
-- Small fixes in browser compatibility and heuristics.
-
-[c++ 0x]: http://ru.wikipedia.org/wiki/C%2B%2B0x
-[html 5]: http://en.wikipedia.org/wiki/HTML5
-[ik]: http://kalnitsky.org.ua/
-
-### For developers
-
-The most significant change is the ability to include language submodes right
-under `contains` instead of defining explicit named submodes in the main array:
-
-    contains: [
-      'string',
-      'number',
-      {begin: '\\n', end: hljs.IMMEDIATE_RE}
-    ]
-
-This is useful for auxiliary modes needed only in one place to define parsing.
-Note that such modes often don't have `className` and hence won't generate a
-separate `` in the resulting markup. This is similar in effect to
-`noMarkup: true`. All existing languages have been refactored accordingly.
-
-Test file test.html has at last become a real test. Now it not only puts the
-detected language name under the code snippet but also tests if it matches the
-expected one. Test summary is displayed right above all language snippets.
-
-
-## CDN
-
-Fine people at [Yandex][] agreed to host highlight.js on their big fast servers.
-[Link up][l]!
-
-[yandex]: http://yandex.com/
-[l]: http://softwaremaniacs.org/soft/highlight/en/download/
-
-
-## Version 5.10 — "Paris".
-
-Though I'm on a vacation in Paris, I decided to release a new version with a
-couple of small fixes:
-
-- Tomas Vitvar discovered that TAB replacement doesn't always work when used
-  with custom markup in code
-- SQL parsing is even more rigid now and doesn't step over SmallTalk in tests
-
-
-## Version 5.9
-
-A long-awaited version is finally released.
-
-New languages:
-
-- Andrew Fedorov made a definition for Lua
-- a long-time highlight.js contributor [Peter Leonov][pl] made a definition for
-  Nginx config
-- [Vladimir Moskva][vm] made a definition for TeX
-
-[pl]: http://kung-fu-tzu.ru/
-[vm]: http://fulc.ru/
-
-Fixes for existing languages:
-
-- [Loren Segal][ls] reworked the Ruby definition and added highlighting for
-  [YARD][] inline documentation
-- the definition of SQL has become more solid and now it shouldn't be overly
-  greedy when it comes to language detection
-
-[ls]: http://gnuu.org/
-[yard]: http://yardoc.org/
-
-The highlighter has become more usable as a library allowing to do highlighting
-from initialization code of JS frameworks and in ajax methods (see.
-readme.eng.txt).
-
-Also this version drops support for the [WordPress][wp] plugin. Everyone is
-welcome to [pick up its maintenance][p] if needed.
-
-[wp]: http://wordpress.org/
-[p]: http://bazaar.launchpad.net/~isagalaev/+junk/highlight/annotate/342/src/wp_highlight.js.php
-
-
-## Version 5.8
-
-- Jan Berkel has contributed a definition for Scala. +1 to hotness!
-- All CSS-styles are rewritten to work only inside `
` tags to avoid
-  conflicts with host site styles.
-
-
-## Version 5.7.
-
-Fixed escaping of quotes in VBScript strings.
-
-
-## Version 5.5
-
-This version brings a small change: now .ini-files allow digits, underscores and
-square brackets in key names.
-
-
-## Version 5.4
-
-Fixed small but upsetting bug in the packer which caused incorrect highlighting
-of explicitly specified languages. Thanks to Andrew Fedorov for precise
-diagnostics!
-
-
-## Version 5.3
-
-The version to fulfil old promises.
-
-The most significant change is that highlight.js now preserves custom user
-markup in code along with its own highlighting markup. This means that now it's
-possible to use, say, links in code. Thanks to [Vladimir Dolzhenko][vd] for the
-[initial proposal][1] and for making a proof-of-concept patch.
-
-Also in this version:
-
-- [Vasily Polovnyov][vp] has sent a GitHub-like style and has implemented
-  support for CSS @-rules and Ruby symbols.
-- Yura Zaripov has sent two styles: Brown Paper and School Book.
-- Oleg Volchkov has sent a definition for [Parser 3][p3].
-
-[1]: http://softwaremaniacs.org/forum/highlightjs/6612/
-[p3]: http://www.parser.ru/
-[vp]: http://vasily.polovnyov.ru/
-[vd]: http://dolzhenko.blogspot.com/
-
-
-## Version 5.2
-
-- at last it's possible to replace indentation TABs with something sensible
-  (e.g. 2 or 4 spaces)
-- new keywords and built-ins for 1C by Sergey Baranov
-- a couple of small fixes to Apache highlighting
-
-
-## Version 5.1
-
-This is one of those nice version consisting entirely of new and shiny
-contributions!
-
-- [Vladimir Ermakov][vooon] created highlighting for AVR Assembler
-- [Ruslan Keba][rukeba] created highlighting for Apache config file. Also his
-  original visual style for it is now available for all highlight.js languages
-  under the name "Magula".
-- [Shuen-Huei Guan][drake] (aka Drake) sent new keywords for RenderMan
-  languages. Also thanks go to [Konstantin Evdokimenko][ke] for his advice on
-  the matter.
-
-[vooon]: http://vehq.ru/about/
-[rukeba]: http://rukeba.com/
-[drake]: http://drakeguan.org/
-[ke]: http://k-evdokimenko.moikrug.ru/
-
-
-## Version 5.0
-
-The main change in the new major version of highlight.js is a mechanism for
-packing several languages along with the library itself into a single compressed
-file. Now sites using several languages will load considerably faster because
-the library won't dynamically include additional files while loading.
-
-Also this version fixes a long-standing bug with Javascript highlighting that
-couldn't distinguish between regular expressions and division operations.
-
-And as usually there were a couple of minor correctness fixes.
-
-Great thanks to all contributors! Keep using highlight.js.
-
-
-## Version 4.3
-
-This version comes with two contributions from [Jason Diamond][jd]:
-
-- language definition for C# (yes! it was a long-missed thing!)
-- Visual Studio-like highlighting style
-
-Plus there are a couple of minor bug fixes for parsing HTML and XML attributes.
-
-[jd]: http://jason.diamond.name/weblog/
-
-
-## Version 4.2
-
-The biggest news is highlighting for Lisp, courtesy of Vasily Polovnyov. It's
-somewhat experimental meaning that for highlighting "keywords" it doesn't use
-any pre-defined set of a Lisp dialect. Instead it tries to highlight first word
-in parentheses wherever it makes sense. I'd like to ask people programming in
-Lisp to confirm if it's a good idea and send feedback to [the forum][f].
-
-Other changes:
-
-- Smalltalk was excluded from DEFAULT_LANGUAGES to save traffic
-- [Vladimir Epifanov][voldmar] has implemented javascript style switcher for
-  test.html
-- comments now allowed inside Ruby function definition
-- [MEL][] language from [Shuen-Huei Guan][drake]
-- whitespace now allowed between `
` and ``
-- better auto-detection of C++ and PHP
-- HTML allows embedded VBScript (`<% .. %>`)
-
-[f]: http://softwaremaniacs.org/forum/highlightjs/
-[voldmar]: http://voldmar.ya.ru/
-[mel]: http://en.wikipedia.org/wiki/Maya_Embedded_Language
-[drake]: http://drakeguan.org/
-
-
-## Version 4.1
-
-Languages:
-
-- Bash from Vah
-- DOS bat-files from Alexander Makarov (Sam)
-- Diff files from Vasily Polovnyov
-- Ini files from myself though initial idea was from Sam
-
-Styles:
-
-- Zenburn from Vladimir Epifanov, this is an imitation of a
-  [well-known theme for Vim][zenburn].
-- Ascetic from myself, as a realization of ideals of non-flashy highlighting:
-  just one color in only three gradations :-)
-
-In other news. [One small bug][bug] was fixed, built-in keywords were added for
-Python and C++ which improved auto-detection for the latter (it was shame that
-[my wife's blog][alenacpp] had issues with it from time to time). And lastly
-thanks go to Sam for getting rid of my stylistic comments in code that were
-getting in the way of [JSMin][].
-
-[zenburn]: http://en.wikipedia.org/wiki/Zenburn
-[alenacpp]: http://alenacpp.blogspot.com/
-[bug]: http://softwaremaniacs.org/forum/viewtopic.php?id=1823
-[jsmin]: http://code.google.com/p/jsmin-php/
-
-
-## Version 4.0
-
-New major version is a result of vast refactoring and of many contributions.
-
-Visible new features:
-
-- Highlighting of embedded languages. Currently is implemented highlighting of
-  Javascript and CSS inside HTML.
-- Bundled 5 ready-made style themes!
-
-Invisible new features:
-
-- Highlight.js no longer pollutes global namespace. Only one object and one
-  function for backward compatibility.
-- Performance is further increased by about 15%.
-
-Changing of a major version number caused by a new format of language definition
-files. If you use some third-party language files they should be updated.
-
-
-## Version 3.5
-
-A very nice version in my opinion fixing a number of small bugs and slightly
-increased speed in a couple of corner cases. Thanks to everybody who reports
-bugs in he [forum][f] and by email!
-
-There is also a new language — XML. A custom XML formerly was detected as HTML
-and didn't highlight custom tags. In this version I tried to make custom XML to
-be detected and highlighted by its own rules. Which by the way include such
-things as CDATA sections and processing instructions (``).
-
-[f]: http://softwaremaniacs.org/forum/viewforum.php?id=6
-
-
-## Version 3.3
-
-[Vladimir Gubarkov][xonix] has provided an interesting and useful addition.
-File export.html contains a little program that shows and allows to copy and
-paste an HTML code generated by the highlighter for any code snippet. This can
-be useful in situations when one can't use the script itself on a site.
-
-
-[xonix]: http://xonixx.blogspot.com/
-
-
-## Version 3.2 consists completely of contributions:
-
-- Vladimir Gubarkov has described SmallTalk
-- Yuri Ivanov has described 1C
-- Peter Leonov has packaged the highlighter as a Firefox extension
-- Vladimir Ermakov has compiled a mod for phpBB
-
-Many thanks to you all!
-
-
-## Version 3.1
-
-Three new languages are available: Django templates, SQL and Axapta. The latter
-two are sent by [Dmitri Roudakov][1]. However I've almost entirely rewrote an
-SQL definition but I'd never started it be it from the ground up :-)
-
-The engine itself has got a long awaited feature of grouping keywords
-("keyword", "built-in function", "literal"). No more hacks!
-
-[1]: http://roudakov.ru/
-
-
-## Version 3.0
-
-It is major mainly because now highlight.js has grown large and has become
-modular. Now when you pass it a list of languages to highlight it will
-dynamically load into a browser only those languages.
-
-Also:
-
-- Konstantin Evdokimenko of [RibKit][] project has created a highlighting for
-  RenderMan Shading Language and RenderMan Interface Bytestream. Yay for more
-  languages!
-- Heuristics for C++ and HTML got better.
-- I've implemented (at last) a correct handling of backslash escapes in C-like
-  languages.
-
-There is also a small backwards incompatible change in the new version. The
-function initHighlighting that was used to initialize highlighting instead of
-initHighlightingOnLoad a long time ago no longer works. If you by chance still
-use it — replace it with the new one.
-
-[RibKit]: http://ribkit.sourceforge.net/
-
-
-## Version 2.9
-
-Highlight.js is a parser, not just a couple of regular expressions. That said
-I'm glad to announce that in the new version 2.9 has support for:
-
-- in-string substitutions for Ruby -- `#{...}`
-- strings from from numeric symbol codes (like #XX) for Delphi
-
-
-## Version 2.8
-
-A maintenance release with more tuned heuristics. Fully backwards compatible.
-
-
-## Version 2.7
-
-- Nikita Ledyaev presents highlighting for VBScript, yay!
-- A couple of bugs with escaping in strings were fixed thanks to Mickle
-- Ongoing tuning of heuristics
-
-Fixed bugs were rather unpleasant so I encourage everyone to upgrade!
-
-
-## Version 2.4
-
-- Peter Leonov provides another improved highlighting for Perl
-- Javascript gets a new kind of keywords — "literals". These are the words
-  "true", "false" and "null"
-
-Also highlight.js homepage now lists sites that use the library. Feel free to
-add your site by [dropping me a message][mail] until I find the time to build a
-submit form.
-
-[mail]: mailto:Maniac@SoftwareManiacs.Org
-
-
-## Version 2.3
-
-This version fixes IE breakage in previous version. My apologies to all who have
-already downloaded that one!
-
-
-## Version 2.2
-
-- added highlighting for Javascript
-- at last fixed parsing of Delphi's escaped apostrophes in strings
-- in Ruby fixed highlighting of keywords 'def' and 'class', same for 'sub' in
-  Perl
-
-
-## Version 2.0
-
-- Ruby support by [Anton Kovalyov][ak]
-- speed increased by orders of magnitude due to new way of parsing
-- this same way allows now correct highlighting of keywords in some tricky
-  places (like keyword "End" at the end of Delphi classes)
-
-[ak]: http://anton.kovalyov.net/
-
-
-## Version 1.0
-
-Version 1.0 of javascript syntax highlighter is released!
-
-It's the first version available with English description. Feel free to post
-your comments and question to [highlight.js forum][forum]. And don't be afraid
-if you find there some fancy Cyrillic letters -- it's for Russian users too :-)
-
-[forum]: http://softwaremaniacs.org/forum/viewforum.php?id=6
diff --git a/doc/html-manual/highlight/LICENSE b/doc/html-manual/highlight/LICENSE
deleted file mode 100644
index 422deb7350f..00000000000
--- a/doc/html-manual/highlight/LICENSE
+++ /dev/null
@@ -1,24 +0,0 @@
-Copyright (c) 2006, Ivan Sagalaev
-All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright
-      notice, this list of conditions and the following disclaimer in the
-      documentation and/or other materials provided with the distribution.
-    * Neither the name of highlight.js nor the names of its contributors 
-      may be used to endorse or promote products derived from this software 
-      without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
-EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/doc/html-manual/highlight/README.md b/doc/html-manual/highlight/README.md
deleted file mode 100644
index 3afbde3127c..00000000000
--- a/doc/html-manual/highlight/README.md
+++ /dev/null
@@ -1,141 +0,0 @@
-# Highlight.js
-
-[![Build Status](https://travis-ci.org/isagalaev/highlight.js.svg?branch=master)](https://travis-ci.org/isagalaev/highlight.js)
-
-Highlight.js is a syntax highlighter written in JavaScript. It works in
-the browser as well as on the server. It works with pretty much any
-markup, doesn’t depend on any framework and has automatic language
-detection.
-
-## Getting Started
-
-The bare minimum for using highlight.js on a web page is linking to the
-library along with one of the styles and calling
-[`initHighlightingOnLoad`][1]:
-
-```html
-
-
-
-```
-
-This will find and highlight code inside of `
` tags; it tries
-to detect the language automatically. If automatic detection doesn’t
-work for you, you can specify the language in the `class` attribute:
-
-```html
-
...
-``` - -The list of supported language classes is available in the [class -reference][2]. Classes can also be prefixed with either `language-` or -`lang-`. - -To disable highlighting altogether use the `nohighlight` class: - -```html -
...
-``` - -## Custom Initialization - -When you need a bit more control over the initialization of -highlight.js, you can use the [`highlightBlock`][3] and [`configure`][4] -functions. This allows you to control *what* to highlight and *when*. - -Here’s an equivalent way to calling [`initHighlightingOnLoad`][1] using -jQuery: - -```javascript -$(document).ready(function() { - $('pre code').each(function(i, block) { - hljs.highlightBlock(block); - }); -}); -``` - -You can use any tags instead of `
` to mark up your code. If
-you don't use a container that preserve line breaks you will need to
-configure highlight.js to use the `
` tag: - -```javascript -hljs.configure({useBR: true}); - -$('div.code').each(function(i, block) { - hljs.highlightBlock(block); -}); -``` - -For other options refer to the documentation for [`configure`][4]. - - -## Web Workers - -You can run highlighting inside a web worker to avoid freezing the browser -window while dealing with very big chunks of code. - -In your main script: - -```javascript -addEventListener('load', function() { - var code = document.querySelector('#code'); - var worker = new Worker('worker.js'); - worker.onmessage = function(event) { code.innerHTML = event.data; } - worker.postMessage(code.textContent); -}) -``` - -In worker.js: - -```javascript -onmessage = function(event) { - importScripts('/highlight.pack.js'); - var result = self.hljs.highlightAuto(event.data); - postMessage(result.value); -} -``` - - -## Getting the Library - -You can get highlight.js as a hosted, or custom-build, browser script or -as a server module. Right out of the box the browser script supports -both AMD and CommonJS, so if you wish you can use RequireJS or -Browserify without having to build from source. The server module also -works perfectly fine with Browserify, but there is the option to use a -build specific to browsers rather than something meant for a server. -Head over to the [download page][5] for all the options. - -**Note:** the library is not supposed to work straight from the source -on GitHub; it requires building. If none of the pre-packaged options -work for you refer to the [building documentation][6]. - -Also, if you are using something like almond, you need to use the -optimizer to give the module a name. The basic example would be: - -``` -r.js -o name=hljs paths.hljs=/path/to/highlight out=highlight.js -``` - -## License - -Highlight.js is released under the BSD License. See [LICENSE][7] file -for details. - -## Links - -The official site for the library is at . - -Further in-depth documentation for the API and other topics is at -. - -Authors and contributors are listed in the [AUTHORS.en.txt][8] file. - -[1]: http://highlightjs.readthedocs.org/en/latest/api.html#inithighlightingonload -[2]: http://highlightjs.readthedocs.org/en/latest/css-classes-reference.html -[3]: http://highlightjs.readthedocs.org/en/latest/api.html#highlightblock-block -[4]: http://highlightjs.readthedocs.org/en/latest/api.html#configure-options -[5]: https://highlightjs.org/download/ -[6]: http://highlightjs.readthedocs.org/en/latest/building-testing.html -[7]: https://github.com/isagalaev/highlight.js/blob/master/LICENSE -[8]: https://github.com/isagalaev/highlight.js/blob/master/AUTHORS.en.txt diff --git a/doc/html-manual/highlight/README.ru.md b/doc/html-manual/highlight/README.ru.md deleted file mode 100644 index c429d7dda4c..00000000000 --- a/doc/html-manual/highlight/README.ru.md +++ /dev/null @@ -1,128 +0,0 @@ -# Highlight.js - -Highlight.js — это инструмент для подсветки синтаксиса, написанный на JavaScript. Он работает -и в браузере, и на сервере. Он работает с практически любой HTML разметкой, не -зависит от каких-либо фреймворков и умеет автоматически определять язык. - - -## Начало работы - -Минимум, что нужно сделать для использования highlight.js на веб-странице — это -подключить библиотеку, CSS-стили и вызывать [`initHighlightingOnLoad`][1]: - -```html - - - -``` - -Библиотека найдёт и раскрасит код внутри тегов `
`, попытавшись
-автоматически определить язык. Когда автоопределение не срабатывает, можно явно
-указать язык в атрибуте class:
-
-```html
-
...
-``` - -Список поддерживаемых классов языков доступен в [справочнике по классам][8]. -Класс также можно предварить префиксами `language-` или `lang-`. - -Чтобы отключить подсветку для какого-то блока, используйте класс `nohighlight`: - -```html -
...
-``` - -## Инициализация вручную - -Чтобы иметь чуть больше контроля за инициализацией подсветки, вы можете -использовать функции [`highlightBlock`][2] и [`configure`][3]. Таким образом -можно управлять тем, *что* и *когда* подсвечивать. - -Вот пример инициализации, эквивалентной вызову [`initHighlightingOnLoad`][1], но -с использованием jQuery: - -```javascript -$(document).ready(function() { - $('pre code').each(function(i, block) { - hljs.highlightBlock(block); - }); -}); -``` - -Вы можете использовать любые теги разметки вместо `
`. Если
-используете контейнер, не сохраняющий переводы строк, вам нужно сказать
-highlight.js использовать для них тег `
`: - -```javascript -hljs.configure({useBR: true}); - -$('div.code').each(function(i, block) { - hljs.highlightBlock(block); -}); -``` - -Другие опции можно найти в документации функции [`configure`][3]. - - -## Web Workers - -Подсветку можно запустить внутри web worker'а, чтобы окно -браузера не подтормаживало при работе с большими кусками кода. - -В основном скрипте: - -```javascript -addEventListener('load', function() { - var code = document.querySelector('#code'); - var worker = new Worker('worker.js'); - worker.onmessage = function(event) { code.innerHTML = event.data; } - worker.postMessage(code.textContent); -}) -``` - -В worker.js: - -```javascript -onmessage = function(event) { - importScripts('/highlight.pack.js'); - var result = self.hljs.highlightAuto(event.data); - postMessage(result.value); -} -``` - - -## Установка библиотеки - -Highlight.js можно использовать в браузере прямо с CDN хостинга или скачать -индивидуальную сборку, а также установив модуль на сервере. На -[странице загрузки][4] подробно описаны все варианты. - -Обратите внимание, что библиотека не предназначена для использования в виде -исходного кода на GitHub, а требует отдельной сборки. Если вам не подходит ни -один из готовых вариантов, читайте [документацию по сборке][5]. - - -## Лицензия - -Highlight.js распространяется под лицензией BSD. Подробнее читайте файл -[LICENSE][10]. - - -## Ссылки - -Официальный сайт билиотеки расположен по адресу . - -Более подробная документация по API и другим темам расположена на -. - -Авторы и контрибьюторы перечислены в файле [AUTHORS.ru.txt][9] file. - -[1]: http://highlightjs.readthedocs.org/en/latest/api.html#inithighlightingonload -[2]: http://highlightjs.readthedocs.org/en/latest/api.html#highlightblock-block -[3]: http://highlightjs.readthedocs.org/en/latest/api.html#configure-options -[4]: https://highlightjs.org/download/ -[5]: http://highlightjs.readthedocs.org/en/latest/building-testing.html -[8]: http://highlightjs.readthedocs.org/en/latest/css-classes-reference.html -[9]: https://github.com/isagalaev/highlight.js/blob/master/AUTHORS.ru.txt -[10]: https://github.com/isagalaev/highlight.js/blob/master/LICENSE diff --git a/doc/html-manual/highlight/highlight.pack.js b/doc/html-manual/highlight/highlight.pack.js deleted file mode 100644 index fa635608228..00000000000 --- a/doc/html-manual/highlight/highlight.pack.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! highlight.js v9.4.0 | BSD3 License | git.io/hljslicense */ -!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/&/gm,"&").replace(//gm,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0==t.index}function a(e){return/^(no-?highlight|plain|text)$/i.test(e)}function i(e){var n,t,r,i=e.className+" ";if(i+=e.parentNode?e.parentNode.className:"",t=/\blang(?:uage)?-([\w-]+)\b/i.exec(i))return w(t[1])?t[1]:"no-highlight";for(i=i.split(/\s+/),n=0,r=i.length;r>n;n++)if(w(i[n])||a(i[n]))return i[n]}function o(e,n){var t,r={};for(t in e)r[t]=e[t];if(n)for(t in n)r[t]=n[t];return r}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3==i.nodeType?a+=i.nodeValue.length:1==i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!=r[0].offset?e[0].offset"}function u(e){f+=""}function c(e){("start"==e.event?o:u)(e.node)}for(var s=0,f="",l=[];e.length||r.length;){var g=i();if(f+=n(a.substr(s,g[0].offset-s)),s=g[0].offset,g==e){l.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g==e&&g.length&&g[0].offset==s);l.reverse().forEach(o)}else"start"==g[0].event?l.push(g[0].node):l.pop(),c(g.splice(0,1)[0])}return f+n(a.substr(s))}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var u={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");u[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?c("keyword",a.k):Object.keys(a.k).forEach(function(e){c(e,a.k[e])}),a.k=u}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),void 0===a.r&&(a.r=1),a.c||(a.c=[]);var s=[];a.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push("self"==e?a:e)}),a.c=s,a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var f=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=f.length?t(f.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e,n){for(var t=0;t";return i+=e+'">',i+n+o}function h(){if(!k.k)return n(M);var e="",t=0;k.lR.lastIndex=0;for(var r=k.lR.exec(M);r;){e+=n(M.substr(t,r.index-t));var a=g(k,r);a?(B+=a[1],e+=p(a[0],n(r[0]))):e+=n(r[0]),t=k.lR.lastIndex,r=k.lR.exec(M)}return e+n(M.substr(t))}function d(){var e="string"==typeof k.sL;if(e&&!R[k.sL])return n(M);var t=e?f(k.sL,M,!0,y[k.sL]):l(M,k.sL.length?k.sL:void 0);return k.r>0&&(B+=t.r),e&&(y[k.sL]=t.top),p(t.language,t.value,!1,!0)}function b(){L+=void 0!==k.sL?d():h(),M=""}function v(e,n){L+=e.cN?p(e.cN,"",!0):"",k=Object.create(e,{parent:{value:k}})}function m(e,n){if(M+=e,void 0===n)return b(),0;var t=o(n,k);if(t)return t.skip?M+=n:(t.eB&&(M+=n),b(),t.rB||t.eB||(M=n)),v(t,n),t.rB?0:n.length;var r=u(k,n);if(r){var a=k;a.skip?M+=n:(a.rE||a.eE||(M+=n),b(),a.eE&&(M=n));do k.cN&&(L+=""),k.skip||(B+=k.r),k=k.parent;while(k!=r.parent);return r.starts&&v(r.starts,""),a.rE?0:n.length}if(c(n,k))throw new Error('Illegal lexeme "'+n+'" for mode "'+(k.cN||"")+'"');return M+=n,n.length||1}var N=w(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var x,k=i||N,y={},L="";for(x=k;x!=N;x=x.parent)x.cN&&(L=p(x.cN,"",!0)+L);var M="",B=0;try{for(var C,j,I=0;;){if(k.t.lastIndex=I,C=k.t.exec(t),!C)break;j=m(t.substr(I,C.index-I),C[0]),I=C.index+j}for(m(t.substr(I)),x=k;x.parent;x=x.parent)x.cN&&(L+="");return{r:B,value:L,language:e,top:k}}catch(O){if(-1!=O.message.indexOf("Illegal"))return{r:0,value:n(t)};throw O}}function l(e,t){t=t||E.languages||Object.keys(R);var r={r:0,value:n(e)},a=r;return t.filter(w).forEach(function(n){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function g(e){return E.tabReplace&&(e=e.replace(/^((<[^>]+>|\t)+)/gm,function(e,n){return n.replace(/\t/g,E.tabReplace)})),E.useBR&&(e=e.replace(/\n/g,"
")),e}function p(e,n,t){var r=n?x[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function h(e){var n=i(e);if(!a(n)){var t;E.useBR?(t=document.createElementNS("http://www.w3.org/1999/xhtml","div"),t.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):t=e;var r=t.textContent,o=n?f(n,r,!0):l(r),s=u(t);if(s.length){var h=document.createElementNS("http://www.w3.org/1999/xhtml","div");h.innerHTML=o.value,o.value=c(s,u(h),r)}o.value=g(o.value),e.innerHTML=o.value,e.className=p(e.className,n,o.language),e.result={language:o.language,re:o.r},o.second_best&&(e.second_best={language:o.second_best.language,re:o.second_best.r})}}function d(e){E=o(E,e)}function b(){if(!b.called){b.called=!0;var e=document.querySelectorAll("pre code");Array.prototype.forEach.call(e,h)}}function v(){addEventListener("DOMContentLoaded",b,!1),addEventListener("load",b,!1)}function m(n,t){var r=R[n]=t(e);r.aliases&&r.aliases.forEach(function(e){x[e]=n})}function N(){return Object.keys(R)}function w(e){return e=(e||"").toLowerCase(),R[e]||R[x[e]]}var E={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},R={},x={};return e.highlight=f,e.highlightAuto=l,e.fixMarkup=g,e.highlightBlock=h,e.configure=d,e.initHighlighting=b,e.initHighlightingOnLoad=v,e.registerLanguage=m,e.listLanguages=N,e.getLanguage=w,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|like)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("json",function(e){var i={literal:"true false null"},n=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:n,k:i},t={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(r,{b:/:/})],i:"\\S"},c={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return n.splice(n.length,0,t,c),{c:n,k:i,i:"\\S"}});hljs.registerLanguage("java",function(e){var t=e.UIR+"(<"+e.UIR+"(\\s*,\\s*"+e.UIR+")*>)?",a="false synchronized int abstract float private char boolean static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports",r="\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",s={cN:"number",b:r,r:0};return{aliases:["jsp"],k:a,i:/<\/|#/,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{b:/\w+@/,r:0},{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return else",r:0},{cN:"function",b:"("+t+"\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:a,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:a,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},s,{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("verilog",function(e){var n={keyword:"accept_on alias always always_comb always_ff always_latch and assert assign assume automatic before begin bind bins binsof bit break buf|0 bufif0 bufif1 byte case casex casez cell chandle checker class clocking cmos config const constraint context continue cover covergroup coverpoint cross deassign default defparam design disable dist do edge else end endcase endchecker endclass endclocking endconfig endfunction endgenerate endgroup endinterface endmodule endpackage endprimitive endprogram endproperty endspecify endsequence endtable endtask enum event eventually expect export extends extern final first_match for force foreach forever fork forkjoin function generate|5 genvar global highz0 highz1 if iff ifnone ignore_bins illegal_bins implements implies import incdir include initial inout input inside instance int integer interconnect interface intersect join join_any join_none large let liblist library local localparam logic longint macromodule matches medium modport module nand negedge nettype new nexttime nmos nor noshowcancelled not notif0 notif1 or output package packed parameter pmos posedge primitive priority program property protected pull0 pull1 pulldown pullup pulsestyle_ondetect pulsestyle_onevent pure rand randc randcase randsequence rcmos real realtime ref reg reject_on release repeat restrict return rnmos rpmos rtran rtranif0 rtranif1 s_always s_eventually s_nexttime s_until s_until_with scalared sequence shortint shortreal showcancelled signed small soft solve specify specparam static string strong strong0 strong1 struct super supply0 supply1 sync_accept_on sync_reject_on table tagged task this throughout time timeprecision timeunit tran tranif0 tranif1 tri tri0 tri1 triand trior trireg type typedef union unique unique0 unsigned until until_with untyped use uwire var vectored virtual void wait wait_order wand weak weak0 weak1 while wildcard wire with within wor xnor xor",literal:"null",built_in:"$finish $stop $exit $fatal $error $warning $info $realtime $time $printtimescale $bitstoreal $bitstoshortreal $itor $signed $cast $bits $stime $timeformat $realtobits $shortrealtobits $rtoi $unsigned $asserton $assertkill $assertpasson $assertfailon $assertnonvacuouson $assertoff $assertcontrol $assertpassoff $assertfailoff $assertvacuousoff $isunbounded $sampled $fell $changed $past_gclk $fell_gclk $changed_gclk $rising_gclk $steady_gclk $coverage_control $coverage_get $coverage_save $set_coverage_db_name $rose $stable $past $rose_gclk $stable_gclk $future_gclk $falling_gclk $changing_gclk $display $coverage_get_max $coverage_merge $get_coverage $load_coverage_db $typename $unpacked_dimensions $left $low $increment $clog2 $ln $log10 $exp $sqrt $pow $floor $ceil $sin $cos $tan $countbits $onehot $isunknown $fatal $warning $dimensions $right $high $size $asin $acos $atan $atan2 $hypot $sinh $cosh $tanh $asinh $acosh $atanh $countones $onehot0 $error $info $random $dist_chi_square $dist_erlang $dist_exponential $dist_normal $dist_poisson $dist_t $dist_uniform $q_initialize $q_remove $q_exam $async$and$array $async$nand$array $async$or$array $async$nor$array $sync$and$array $sync$nand$array $sync$or$array $sync$nor$array $q_add $q_full $psprintf $async$and$plane $async$nand$plane $async$or$plane $async$nor$plane $sync$and$plane $sync$nand$plane $sync$or$plane $sync$nor$plane $system $display $displayb $displayh $displayo $strobe $strobeb $strobeh $strobeo $write $readmemb $readmemh $writememh $value$plusargs $dumpvars $dumpon $dumplimit $dumpports $dumpportson $dumpportslimit $writeb $writeh $writeo $monitor $monitorb $monitorh $monitoro $writememb $dumpfile $dumpoff $dumpall $dumpflush $dumpportsoff $dumpportsall $dumpportsflush $fclose $fdisplay $fdisplayb $fdisplayh $fdisplayo $fstrobe $fstrobeb $fstrobeh $fstrobeo $swrite $swriteb $swriteh $swriteo $fscanf $fread $fseek $fflush $feof $fopen $fwrite $fwriteb $fwriteh $fwriteo $fmonitor $fmonitorb $fmonitorh $fmonitoro $sformat $sformatf $fgetc $ungetc $fgets $sscanf $rewind $ftell $ferror"};return{aliases:["v","sv","svh"],cI:!1,k:n,l:/[\w\$]+/,c:[e.CBCM,e.CLCM,e.QSM,{cN:"number",c:[e.BE],v:[{b:"\\b((\\d+'(b|h|o|d|B|H|O|D))[0-9xzXZa-fA-F_]+)"},{b:"\\B(('(b|h|o|d|B|H|O|D))[0-9xzXZa-fA-F_]+)"},{b:"\\b([0-9_])+",r:0}]},{cN:"variable",v:[{b:"#\\((?!parameter).+\\)"},{b:"\\.\\w+",r:0}]},{cN:"meta",b:"`",e:"$",k:{"meta-keyword":"define __FILE__ __LINE__ begin_keywords celldefine default_nettype define else elsif end_keywords endcelldefine endif ifdef ifndef include line nounconnected_drive pragma resetall timescale unconnected_drive undef undefineall"},r:0}]}});hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/-?[a-z\.]+/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"meta",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,s,a,t]}});hljs.registerLanguage("cpp",function(t){var e={cN:"keyword",b:"\\b[a-z\\d_]*_t\\b"},r={cN:"string",v:[t.inherit(t.QSM,{b:'((u8?|U)|L)?"'}),{b:'(u8?|U)?R"',e:'"',c:[t.BE]},{b:"'\\\\?.",e:"'",i:"."}]},s={cN:"number",v:[{b:"\\b(\\d+(\\.\\d*)?|\\.\\d+)(u|U|l|L|ul|UL|f|F)"},{b:t.CNR}],r:0},i={cN:"meta",b:/#[a-z]+\b/,e:/$/,k:{"meta-keyword":"if else elif endif define undef warning error line pragma ifdef ifndef include"},c:[{b:/\\\n/,r:0},t.inherit(r,{cN:"meta-string"}),{cN:"meta-string",b:"<",e:">",i:"\\n"},t.CLCM,t.CBCM]},a=t.IR+"\\s*\\(",c={keyword:"int float while private char catch export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const struct for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using class asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignof constexpr decltype noexcept static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong new throw return",built_in:"std string cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr",literal:"true false nullptr NULL"},n=[e,t.CLCM,t.CBCM,s,r];return{aliases:["c","cc","h","c++","h++","hpp"],k:c,i:"",k:c,c:["self",e]},{b:t.IR+"::",k:c},{v:[{b:/=/,e:/;/},{b:/\(/,e:/\)/},{bK:"new throw return else",e:/;/}],k:c,c:n.concat([{b:/\(/,e:/\)/,k:c,c:n.concat(["self"]),r:0}]),r:0},{cN:"function",b:"("+t.IR+"[\\*&\\s]+)+"+a,rB:!0,e:/[{;=]/,eE:!0,k:c,i:/[^\w\s\*&]/,c:[{b:a,rB:!0,c:[t.TM],r:0},{cN:"params",b:/\(/,e:/\)/,k:c,r:0,c:[t.CLCM,t.CBCM,r,s,e]},t.CLCM,t.CBCM,i]}]),exports:{preprocessor:i,strings:r,k:c}}}); \ No newline at end of file diff --git a/doc/html-manual/highlight/styles/agate.css b/doc/html-manual/highlight/styles/agate.css deleted file mode 100644 index 8d64547c587..00000000000 --- a/doc/html-manual/highlight/styles/agate.css +++ /dev/null @@ -1,108 +0,0 @@ -/*! - * Agate by Taufik Nurrohman - * ---------------------------------------------------- - * - * #ade5fc - * #a2fca2 - * #c6b4f0 - * #d36363 - * #fcc28c - * #fc9b9b - * #ffa - * #fff - * #333 - * #62c8f3 - * #888 - * - */ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #333; - color: white; -} - -.hljs-name, -.hljs-strong { - font-weight: bold; -} - -.hljs-code, -.hljs-emphasis { - font-style: italic; -} - -.hljs-tag { - color: #62c8f3; -} - -.hljs-variable, -.hljs-template-variable, -.hljs-selector-id, -.hljs-selector-class { - color: #ade5fc; -} - -.hljs-string, -.hljs-bullet { - color: #a2fca2; -} - -.hljs-type, -.hljs-title, -.hljs-section, -.hljs-attribute, -.hljs-quote, -.hljs-built_in, -.hljs-builtin-name { - color: #ffa; -} - -.hljs-number, -.hljs-symbol, -.hljs-bullet { - color: #d36363; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-literal { - color: #fcc28c; -} - -.hljs-comment, -.hljs-deletion, -.hljs-code { - color: #888; -} - -.hljs-regexp, -.hljs-link { - color: #c6b4f0; -} - -.hljs-meta { - color: #fc9b9b; -} - -.hljs-deletion { - background-color: #fc9b9b; - color: #333; -} - -.hljs-addition { - background-color: #a2fca2; - color: #333; -} - -.hljs a { - color: inherit; -} - -.hljs a:focus, -.hljs a:hover { - color: inherit; - text-decoration: underline; -} diff --git a/doc/html-manual/highlight/styles/androidstudio.css b/doc/html-manual/highlight/styles/androidstudio.css deleted file mode 100644 index bc8e473b593..00000000000 --- a/doc/html-manual/highlight/styles/androidstudio.css +++ /dev/null @@ -1,66 +0,0 @@ -/* -Date: 24 Fev 2015 -Author: Pedro Oliveira -*/ - -.hljs { - color: #a9b7c6; - background: #282b2e; - display: block; - overflow-x: auto; - padding: 0.5em; -} - -.hljs-number, -.hljs-literal, -.hljs-symbol, -.hljs-bullet { - color: #6897BB; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-deletion { - color: #cc7832; -} - -.hljs-variable, -.hljs-template-variable, -.hljs-link { - color: #629755; -} - -.hljs-comment, -.hljs-quote { - color: #808080; -} - -.hljs-meta { - color: #bbb529; -} - -.hljs-string, -.hljs-attribute, -.hljs-addition { - color: #6A8759; -} - -.hljs-section, -.hljs-title, -.hljs-type { - color: #ffc66d; -} - -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #e8bf6a; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/arduino-light.css b/doc/html-manual/highlight/styles/arduino-light.css deleted file mode 100644 index 4b8b7fd3c93..00000000000 --- a/doc/html-manual/highlight/styles/arduino-light.css +++ /dev/null @@ -1,88 +0,0 @@ -/* - -Arduino® Light Theme - Stefania Mellai - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #FFFFFF; -} - -.hljs, -.hljs-subst { - color: #434f54; -} - -.hljs-keyword, -.hljs-attribute, -.hljs-selector-tag, -.hljs-doctag, -.hljs-name { - color: #00979D; -} - -.hljs-built_in, -.hljs-literal, -.hljs-bullet, -.hljs-code, -.hljs-addition { - color: #D35400; -} - -.hljs-regexp, -.hljs-symbol, -.hljs-variable, -.hljs-template-variable, -.hljs-link, -.hljs-selector-attr, -.hljs-selector-pseudo { - color: #00979D; -} - -.hljs-type, -.hljs-string, -.hljs-selector-id, -.hljs-selector-class, -.hljs-quote, -.hljs-template-tag, -.hljs-deletion { - color: #005C5F; -} - -.hljs-title, -.hljs-section { - color: #880000; - font-weight: bold; -} - -.hljs-comment { - color: rgba(149,165,166,.8); -} - -.hljs-meta-keyword { - color: #728E00; -} - -.hljs-meta { - color: #728E00; - color: #434f54; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} - -.hljs-function { - color: #728E00; -} - -.hljs-number { - color: #8A7B52; -} diff --git a/doc/html-manual/highlight/styles/arta.css b/doc/html-manual/highlight/styles/arta.css deleted file mode 100644 index 75ef3a9e595..00000000000 --- a/doc/html-manual/highlight/styles/arta.css +++ /dev/null @@ -1,73 +0,0 @@ -/* -Date: 17.V.2011 -Author: pumbur -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #222; -} - -.hljs, -.hljs-subst { - color: #aaa; -} - -.hljs-section { - color: #fff; -} - -.hljs-comment, -.hljs-quote, -.hljs-meta { - color: #444; -} - -.hljs-string, -.hljs-symbol, -.hljs-bullet, -.hljs-regexp { - color: #ffcc33; -} - -.hljs-number, -.hljs-addition { - color: #00cc66; -} - -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-template-variable, -.hljs-attribute, -.hljs-link { - color: #32aaee; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #6644aa; -} - -.hljs-title, -.hljs-variable, -.hljs-deletion, -.hljs-template-tag { - color: #bb1166; -} - -.hljs-section, -.hljs-doctag, -.hljs-strong { - font-weight: bold; -} - -.hljs-emphasis { - font-style: italic; -} diff --git a/doc/html-manual/highlight/styles/ascetic.css b/doc/html-manual/highlight/styles/ascetic.css deleted file mode 100644 index 48397e889dd..00000000000 --- a/doc/html-manual/highlight/styles/ascetic.css +++ /dev/null @@ -1,45 +0,0 @@ -/* - -Original style from softwaremaniacs.org (c) Ivan Sagalaev - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: white; - color: black; -} - -.hljs-string, -.hljs-variable, -.hljs-template-variable, -.hljs-symbol, -.hljs-bullet, -.hljs-section, -.hljs-addition, -.hljs-attribute, -.hljs-link { - color: #888; -} - -.hljs-comment, -.hljs-quote, -.hljs-meta, -.hljs-deletion { - color: #ccc; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-section, -.hljs-name, -.hljs-type, -.hljs-strong { - font-weight: bold; -} - -.hljs-emphasis { - font-style: italic; -} diff --git a/doc/html-manual/highlight/styles/atelier-cave-dark.css b/doc/html-manual/highlight/styles/atelier-cave-dark.css deleted file mode 100644 index 65428f3b12a..00000000000 --- a/doc/html-manual/highlight/styles/atelier-cave-dark.css +++ /dev/null @@ -1,83 +0,0 @@ -/* Base16 Atelier Cave Dark - Theme */ -/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave) */ -/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ - -/* Atelier-Cave Comment */ -.hljs-comment, -.hljs-quote { - color: #7e7887; -} - -/* Atelier-Cave Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-attribute, -.hljs-regexp, -.hljs-link, -.hljs-tag, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #be4678; -} - -/* Atelier-Cave Orange */ -.hljs-number, -.hljs-meta, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params { - color: #aa573c; -} - -/* Atelier-Cave Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet { - color: #2a9292; -} - -/* Atelier-Cave Blue */ -.hljs-title, -.hljs-section { - color: #576ddb; -} - -/* Atelier-Cave Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #955ae7; -} - -.hljs-deletion, -.hljs-addition { - color: #19171c; - display: inline-block; - width: 100%; -} - -.hljs-deletion { - background-color: #be4678; -} - -.hljs-addition { - background-color: #2a9292; -} - -.hljs { - display: block; - overflow-x: auto; - background: #19171c; - color: #8b8792; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/atelier-cave-light.css b/doc/html-manual/highlight/styles/atelier-cave-light.css deleted file mode 100644 index b419f9fd8f8..00000000000 --- a/doc/html-manual/highlight/styles/atelier-cave-light.css +++ /dev/null @@ -1,85 +0,0 @@ -/* Base16 Atelier Cave Light - Theme */ -/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave) */ -/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ - -/* Atelier-Cave Comment */ -.hljs-comment, -.hljs-quote { - color: #655f6d; -} - -/* Atelier-Cave Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-attribute, -.hljs-tag, -.hljs-name, -.hljs-regexp, -.hljs-link, -.hljs-name, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #be4678; -} - -/* Atelier-Cave Orange */ -.hljs-number, -.hljs-meta, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params { - color: #aa573c; -} - -/* Atelier-Cave Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet { - color: #2a9292; -} - -/* Atelier-Cave Blue */ -.hljs-title, -.hljs-section { - color: #576ddb; -} - -/* Atelier-Cave Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #955ae7; -} - -.hljs-deletion, -.hljs-addition { - color: #19171c; - display: inline-block; - width: 100%; -} - -.hljs-deletion { - background-color: #be4678; -} - -.hljs-addition { - background-color: #2a9292; -} - -.hljs { - display: block; - overflow-x: auto; - background: #efecf4; - color: #585260; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/atelier-dune-dark.css b/doc/html-manual/highlight/styles/atelier-dune-dark.css deleted file mode 100644 index 1684f5225af..00000000000 --- a/doc/html-manual/highlight/styles/atelier-dune-dark.css +++ /dev/null @@ -1,69 +0,0 @@ -/* Base16 Atelier Dune Dark - Theme */ -/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune) */ -/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ - -/* Atelier-Dune Comment */ -.hljs-comment, -.hljs-quote { - color: #999580; -} - -/* Atelier-Dune Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-attribute, -.hljs-tag, -.hljs-name, -.hljs-regexp, -.hljs-link, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #d73737; -} - -/* Atelier-Dune Orange */ -.hljs-number, -.hljs-meta, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params { - color: #b65611; -} - -/* Atelier-Dune Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet { - color: #60ac39; -} - -/* Atelier-Dune Blue */ -.hljs-title, -.hljs-section { - color: #6684e1; -} - -/* Atelier-Dune Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #b854d4; -} - -.hljs { - display: block; - overflow-x: auto; - background: #20201d; - color: #a6a28c; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/atelier-dune-light.css b/doc/html-manual/highlight/styles/atelier-dune-light.css deleted file mode 100644 index 547719de826..00000000000 --- a/doc/html-manual/highlight/styles/atelier-dune-light.css +++ /dev/null @@ -1,69 +0,0 @@ -/* Base16 Atelier Dune Light - Theme */ -/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune) */ -/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ - -/* Atelier-Dune Comment */ -.hljs-comment, -.hljs-quote { - color: #7d7a68; -} - -/* Atelier-Dune Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-attribute, -.hljs-tag, -.hljs-name, -.hljs-regexp, -.hljs-link, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #d73737; -} - -/* Atelier-Dune Orange */ -.hljs-number, -.hljs-meta, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params { - color: #b65611; -} - -/* Atelier-Dune Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet { - color: #60ac39; -} - -/* Atelier-Dune Blue */ -.hljs-title, -.hljs-section { - color: #6684e1; -} - -/* Atelier-Dune Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #b854d4; -} - -.hljs { - display: block; - overflow-x: auto; - background: #fefbec; - color: #6e6b5e; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/atelier-estuary-dark.css b/doc/html-manual/highlight/styles/atelier-estuary-dark.css deleted file mode 100644 index a5e507187e9..00000000000 --- a/doc/html-manual/highlight/styles/atelier-estuary-dark.css +++ /dev/null @@ -1,84 +0,0 @@ -/* Base16 Atelier Estuary Dark - Theme */ -/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/estuary) */ -/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ - -/* Atelier-Estuary Comment */ -.hljs-comment, -.hljs-quote { - color: #878573; -} - -/* Atelier-Estuary Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-attribute, -.hljs-tag, -.hljs-name, -.hljs-regexp, -.hljs-link, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #ba6236; -} - -/* Atelier-Estuary Orange */ -.hljs-number, -.hljs-meta, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params { - color: #ae7313; -} - -/* Atelier-Estuary Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet { - color: #7d9726; -} - -/* Atelier-Estuary Blue */ -.hljs-title, -.hljs-section { - color: #36a166; -} - -/* Atelier-Estuary Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #5f9182; -} - -.hljs-deletion, -.hljs-addition { - color: #22221b; - display: inline-block; - width: 100%; -} - -.hljs-deletion { - background-color: #ba6236; -} - -.hljs-addition { - background-color: #7d9726; -} - -.hljs { - display: block; - overflow-x: auto; - background: #22221b; - color: #929181; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/atelier-estuary-light.css b/doc/html-manual/highlight/styles/atelier-estuary-light.css deleted file mode 100644 index 1daee5d9855..00000000000 --- a/doc/html-manual/highlight/styles/atelier-estuary-light.css +++ /dev/null @@ -1,84 +0,0 @@ -/* Base16 Atelier Estuary Light - Theme */ -/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/estuary) */ -/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ - -/* Atelier-Estuary Comment */ -.hljs-comment, -.hljs-quote { - color: #6c6b5a; -} - -/* Atelier-Estuary Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-attribute, -.hljs-tag, -.hljs-name, -.hljs-regexp, -.hljs-link, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #ba6236; -} - -/* Atelier-Estuary Orange */ -.hljs-number, -.hljs-meta, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params { - color: #ae7313; -} - -/* Atelier-Estuary Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet { - color: #7d9726; -} - -/* Atelier-Estuary Blue */ -.hljs-title, -.hljs-section { - color: #36a166; -} - -/* Atelier-Estuary Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #5f9182; -} - -.hljs-deletion, -.hljs-addition { - color: #22221b; - display: inline-block; - width: 100%; -} - -.hljs-deletion { - background-color: #ba6236; -} - -.hljs-addition { - background-color: #7d9726; -} - -.hljs { - display: block; - overflow-x: auto; - background: #f4f3ec; - color: #5f5e4e; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/atelier-forest-dark.css b/doc/html-manual/highlight/styles/atelier-forest-dark.css deleted file mode 100644 index 0ef4fae3174..00000000000 --- a/doc/html-manual/highlight/styles/atelier-forest-dark.css +++ /dev/null @@ -1,69 +0,0 @@ -/* Base16 Atelier Forest Dark - Theme */ -/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/forest) */ -/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ - -/* Atelier-Forest Comment */ -.hljs-comment, -.hljs-quote { - color: #9c9491; -} - -/* Atelier-Forest Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-attribute, -.hljs-tag, -.hljs-name, -.hljs-regexp, -.hljs-link, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #f22c40; -} - -/* Atelier-Forest Orange */ -.hljs-number, -.hljs-meta, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params { - color: #df5320; -} - -/* Atelier-Forest Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet { - color: #7b9726; -} - -/* Atelier-Forest Blue */ -.hljs-title, -.hljs-section { - color: #407ee7; -} - -/* Atelier-Forest Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #6666ea; -} - -.hljs { - display: block; - overflow-x: auto; - background: #1b1918; - color: #a8a19f; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/atelier-forest-light.css b/doc/html-manual/highlight/styles/atelier-forest-light.css deleted file mode 100644 index bbedde18a0a..00000000000 --- a/doc/html-manual/highlight/styles/atelier-forest-light.css +++ /dev/null @@ -1,69 +0,0 @@ -/* Base16 Atelier Forest Light - Theme */ -/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/forest) */ -/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ - -/* Atelier-Forest Comment */ -.hljs-comment, -.hljs-quote { - color: #766e6b; -} - -/* Atelier-Forest Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-attribute, -.hljs-tag, -.hljs-name, -.hljs-regexp, -.hljs-link, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #f22c40; -} - -/* Atelier-Forest Orange */ -.hljs-number, -.hljs-meta, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params { - color: #df5320; -} - -/* Atelier-Forest Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet { - color: #7b9726; -} - -/* Atelier-Forest Blue */ -.hljs-title, -.hljs-section { - color: #407ee7; -} - -/* Atelier-Forest Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #6666ea; -} - -.hljs { - display: block; - overflow-x: auto; - background: #f1efee; - color: #68615e; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/atelier-heath-dark.css b/doc/html-manual/highlight/styles/atelier-heath-dark.css deleted file mode 100644 index fe01ff721b9..00000000000 --- a/doc/html-manual/highlight/styles/atelier-heath-dark.css +++ /dev/null @@ -1,69 +0,0 @@ -/* Base16 Atelier Heath Dark - Theme */ -/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/heath) */ -/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ - -/* Atelier-Heath Comment */ -.hljs-comment, -.hljs-quote { - color: #9e8f9e; -} - -/* Atelier-Heath Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-attribute, -.hljs-tag, -.hljs-name, -.hljs-regexp, -.hljs-link, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #ca402b; -} - -/* Atelier-Heath Orange */ -.hljs-number, -.hljs-meta, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params { - color: #a65926; -} - -/* Atelier-Heath Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet { - color: #918b3b; -} - -/* Atelier-Heath Blue */ -.hljs-title, -.hljs-section { - color: #516aec; -} - -/* Atelier-Heath Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #7b59c0; -} - -.hljs { - display: block; - overflow-x: auto; - background: #1b181b; - color: #ab9bab; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/atelier-heath-light.css b/doc/html-manual/highlight/styles/atelier-heath-light.css deleted file mode 100644 index ee43786d12e..00000000000 --- a/doc/html-manual/highlight/styles/atelier-heath-light.css +++ /dev/null @@ -1,69 +0,0 @@ -/* Base16 Atelier Heath Light - Theme */ -/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/heath) */ -/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ - -/* Atelier-Heath Comment */ -.hljs-comment, -.hljs-quote { - color: #776977; -} - -/* Atelier-Heath Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-attribute, -.hljs-tag, -.hljs-name, -.hljs-regexp, -.hljs-link, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #ca402b; -} - -/* Atelier-Heath Orange */ -.hljs-number, -.hljs-meta, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params { - color: #a65926; -} - -/* Atelier-Heath Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet { - color: #918b3b; -} - -/* Atelier-Heath Blue */ -.hljs-title, -.hljs-section { - color: #516aec; -} - -/* Atelier-Heath Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #7b59c0; -} - -.hljs { - display: block; - overflow-x: auto; - background: #f7f3f7; - color: #695d69; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/atelier-lakeside-dark.css b/doc/html-manual/highlight/styles/atelier-lakeside-dark.css deleted file mode 100644 index a937d3bf5f7..00000000000 --- a/doc/html-manual/highlight/styles/atelier-lakeside-dark.css +++ /dev/null @@ -1,69 +0,0 @@ -/* Base16 Atelier Lakeside Dark - Theme */ -/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/lakeside) */ -/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ - -/* Atelier-Lakeside Comment */ -.hljs-comment, -.hljs-quote { - color: #7195a8; -} - -/* Atelier-Lakeside Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-attribute, -.hljs-tag, -.hljs-name, -.hljs-regexp, -.hljs-link, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #d22d72; -} - -/* Atelier-Lakeside Orange */ -.hljs-number, -.hljs-meta, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params { - color: #935c25; -} - -/* Atelier-Lakeside Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet { - color: #568c3b; -} - -/* Atelier-Lakeside Blue */ -.hljs-title, -.hljs-section { - color: #257fad; -} - -/* Atelier-Lakeside Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #6b6bb8; -} - -.hljs { - display: block; - overflow-x: auto; - background: #161b1d; - color: #7ea2b4; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/atelier-lakeside-light.css b/doc/html-manual/highlight/styles/atelier-lakeside-light.css deleted file mode 100644 index 6c7e8f9ef2d..00000000000 --- a/doc/html-manual/highlight/styles/atelier-lakeside-light.css +++ /dev/null @@ -1,69 +0,0 @@ -/* Base16 Atelier Lakeside Light - Theme */ -/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/lakeside) */ -/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ - -/* Atelier-Lakeside Comment */ -.hljs-comment, -.hljs-quote { - color: #5a7b8c; -} - -/* Atelier-Lakeside Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-attribute, -.hljs-tag, -.hljs-name, -.hljs-regexp, -.hljs-link, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #d22d72; -} - -/* Atelier-Lakeside Orange */ -.hljs-number, -.hljs-meta, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params { - color: #935c25; -} - -/* Atelier-Lakeside Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet { - color: #568c3b; -} - -/* Atelier-Lakeside Blue */ -.hljs-title, -.hljs-section { - color: #257fad; -} - -/* Atelier-Lakeside Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #6b6bb8; -} - -.hljs { - display: block; - overflow-x: auto; - background: #ebf8ff; - color: #516d7b; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/atelier-plateau-dark.css b/doc/html-manual/highlight/styles/atelier-plateau-dark.css deleted file mode 100644 index 3bb052693c1..00000000000 --- a/doc/html-manual/highlight/styles/atelier-plateau-dark.css +++ /dev/null @@ -1,84 +0,0 @@ -/* Base16 Atelier Plateau Dark - Theme */ -/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/plateau) */ -/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ - -/* Atelier-Plateau Comment */ -.hljs-comment, -.hljs-quote { - color: #7e7777; -} - -/* Atelier-Plateau Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-attribute, -.hljs-tag, -.hljs-name, -.hljs-regexp, -.hljs-link, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #ca4949; -} - -/* Atelier-Plateau Orange */ -.hljs-number, -.hljs-meta, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params { - color: #b45a3c; -} - -/* Atelier-Plateau Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet { - color: #4b8b8b; -} - -/* Atelier-Plateau Blue */ -.hljs-title, -.hljs-section { - color: #7272ca; -} - -/* Atelier-Plateau Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #8464c4; -} - -.hljs-deletion, -.hljs-addition { - color: #1b1818; - display: inline-block; - width: 100%; -} - -.hljs-deletion { - background-color: #ca4949; -} - -.hljs-addition { - background-color: #4b8b8b; -} - -.hljs { - display: block; - overflow-x: auto; - background: #1b1818; - color: #8a8585; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/atelier-plateau-light.css b/doc/html-manual/highlight/styles/atelier-plateau-light.css deleted file mode 100644 index 5f0222bec1f..00000000000 --- a/doc/html-manual/highlight/styles/atelier-plateau-light.css +++ /dev/null @@ -1,84 +0,0 @@ -/* Base16 Atelier Plateau Light - Theme */ -/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/plateau) */ -/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ - -/* Atelier-Plateau Comment */ -.hljs-comment, -.hljs-quote { - color: #655d5d; -} - -/* Atelier-Plateau Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-attribute, -.hljs-tag, -.hljs-name, -.hljs-regexp, -.hljs-link, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #ca4949; -} - -/* Atelier-Plateau Orange */ -.hljs-number, -.hljs-meta, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params { - color: #b45a3c; -} - -/* Atelier-Plateau Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet { - color: #4b8b8b; -} - -/* Atelier-Plateau Blue */ -.hljs-title, -.hljs-section { - color: #7272ca; -} - -/* Atelier-Plateau Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #8464c4; -} - -.hljs-deletion, -.hljs-addition { - color: #1b1818; - display: inline-block; - width: 100%; -} - -.hljs-deletion { - background-color: #ca4949; -} - -.hljs-addition { - background-color: #4b8b8b; -} - -.hljs { - display: block; - overflow-x: auto; - background: #f4ecec; - color: #585050; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/atelier-savanna-dark.css b/doc/html-manual/highlight/styles/atelier-savanna-dark.css deleted file mode 100644 index 38f831431c3..00000000000 --- a/doc/html-manual/highlight/styles/atelier-savanna-dark.css +++ /dev/null @@ -1,84 +0,0 @@ -/* Base16 Atelier Savanna Dark - Theme */ -/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/savanna) */ -/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ - -/* Atelier-Savanna Comment */ -.hljs-comment, -.hljs-quote { - color: #78877d; -} - -/* Atelier-Savanna Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-attribute, -.hljs-tag, -.hljs-name, -.hljs-regexp, -.hljs-link, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #b16139; -} - -/* Atelier-Savanna Orange */ -.hljs-number, -.hljs-meta, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params { - color: #9f713c; -} - -/* Atelier-Savanna Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet { - color: #489963; -} - -/* Atelier-Savanna Blue */ -.hljs-title, -.hljs-section { - color: #478c90; -} - -/* Atelier-Savanna Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #55859b; -} - -.hljs-deletion, -.hljs-addition { - color: #171c19; - display: inline-block; - width: 100%; -} - -.hljs-deletion { - background-color: #b16139; -} - -.hljs-addition { - background-color: #489963; -} - -.hljs { - display: block; - overflow-x: auto; - background: #171c19; - color: #87928a; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/atelier-savanna-light.css b/doc/html-manual/highlight/styles/atelier-savanna-light.css deleted file mode 100644 index 1ccd7c6858f..00000000000 --- a/doc/html-manual/highlight/styles/atelier-savanna-light.css +++ /dev/null @@ -1,84 +0,0 @@ -/* Base16 Atelier Savanna Light - Theme */ -/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/savanna) */ -/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ - -/* Atelier-Savanna Comment */ -.hljs-comment, -.hljs-quote { - color: #5f6d64; -} - -/* Atelier-Savanna Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-attribute, -.hljs-tag, -.hljs-name, -.hljs-regexp, -.hljs-link, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #b16139; -} - -/* Atelier-Savanna Orange */ -.hljs-number, -.hljs-meta, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params { - color: #9f713c; -} - -/* Atelier-Savanna Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet { - color: #489963; -} - -/* Atelier-Savanna Blue */ -.hljs-title, -.hljs-section { - color: #478c90; -} - -/* Atelier-Savanna Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #55859b; -} - -.hljs-deletion, -.hljs-addition { - color: #171c19; - display: inline-block; - width: 100%; -} - -.hljs-deletion { - background-color: #b16139; -} - -.hljs-addition { - background-color: #489963; -} - -.hljs { - display: block; - overflow-x: auto; - background: #ecf4ee; - color: #526057; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/atelier-seaside-dark.css b/doc/html-manual/highlight/styles/atelier-seaside-dark.css deleted file mode 100644 index df29949c69f..00000000000 --- a/doc/html-manual/highlight/styles/atelier-seaside-dark.css +++ /dev/null @@ -1,69 +0,0 @@ -/* Base16 Atelier Seaside Dark - Theme */ -/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/seaside) */ -/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ - -/* Atelier-Seaside Comment */ -.hljs-comment, -.hljs-quote { - color: #809980; -} - -/* Atelier-Seaside Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-attribute, -.hljs-tag, -.hljs-name, -.hljs-regexp, -.hljs-link, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #e6193c; -} - -/* Atelier-Seaside Orange */ -.hljs-number, -.hljs-meta, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params { - color: #87711d; -} - -/* Atelier-Seaside Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet { - color: #29a329; -} - -/* Atelier-Seaside Blue */ -.hljs-title, -.hljs-section { - color: #3d62f5; -} - -/* Atelier-Seaside Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #ad2bee; -} - -.hljs { - display: block; - overflow-x: auto; - background: #131513; - color: #8ca68c; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/atelier-seaside-light.css b/doc/html-manual/highlight/styles/atelier-seaside-light.css deleted file mode 100644 index 9d960f29f38..00000000000 --- a/doc/html-manual/highlight/styles/atelier-seaside-light.css +++ /dev/null @@ -1,69 +0,0 @@ -/* Base16 Atelier Seaside Light - Theme */ -/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/seaside) */ -/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ - -/* Atelier-Seaside Comment */ -.hljs-comment, -.hljs-quote { - color: #687d68; -} - -/* Atelier-Seaside Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-attribute, -.hljs-tag, -.hljs-name, -.hljs-regexp, -.hljs-link, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #e6193c; -} - -/* Atelier-Seaside Orange */ -.hljs-number, -.hljs-meta, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params { - color: #87711d; -} - -/* Atelier-Seaside Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet { - color: #29a329; -} - -/* Atelier-Seaside Blue */ -.hljs-title, -.hljs-section { - color: #3d62f5; -} - -/* Atelier-Seaside Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #ad2bee; -} - -.hljs { - display: block; - overflow-x: auto; - background: #f4fbf4; - color: #5e6e5e; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/atelier-sulphurpool-dark.css b/doc/html-manual/highlight/styles/atelier-sulphurpool-dark.css deleted file mode 100644 index c2ab7938d84..00000000000 --- a/doc/html-manual/highlight/styles/atelier-sulphurpool-dark.css +++ /dev/null @@ -1,69 +0,0 @@ -/* Base16 Atelier Sulphurpool Dark - Theme */ -/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/sulphurpool) */ -/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ - -/* Atelier-Sulphurpool Comment */ -.hljs-comment, -.hljs-quote { - color: #898ea4; -} - -/* Atelier-Sulphurpool Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-attribute, -.hljs-tag, -.hljs-name, -.hljs-regexp, -.hljs-link, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #c94922; -} - -/* Atelier-Sulphurpool Orange */ -.hljs-number, -.hljs-meta, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params { - color: #c76b29; -} - -/* Atelier-Sulphurpool Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet { - color: #ac9739; -} - -/* Atelier-Sulphurpool Blue */ -.hljs-title, -.hljs-section { - color: #3d8fd1; -} - -/* Atelier-Sulphurpool Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #6679cc; -} - -.hljs { - display: block; - overflow-x: auto; - background: #202746; - color: #979db4; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/atelier-sulphurpool-light.css b/doc/html-manual/highlight/styles/atelier-sulphurpool-light.css deleted file mode 100644 index 96c47d08608..00000000000 --- a/doc/html-manual/highlight/styles/atelier-sulphurpool-light.css +++ /dev/null @@ -1,69 +0,0 @@ -/* Base16 Atelier Sulphurpool Light - Theme */ -/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/sulphurpool) */ -/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ - -/* Atelier-Sulphurpool Comment */ -.hljs-comment, -.hljs-quote { - color: #6b7394; -} - -/* Atelier-Sulphurpool Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-attribute, -.hljs-tag, -.hljs-name, -.hljs-regexp, -.hljs-link, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #c94922; -} - -/* Atelier-Sulphurpool Orange */ -.hljs-number, -.hljs-meta, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params { - color: #c76b29; -} - -/* Atelier-Sulphurpool Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet { - color: #ac9739; -} - -/* Atelier-Sulphurpool Blue */ -.hljs-title, -.hljs-section { - color: #3d8fd1; -} - -/* Atelier-Sulphurpool Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #6679cc; -} - -.hljs { - display: block; - overflow-x: auto; - background: #f5f7ff; - color: #5e6687; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/brown-paper.css b/doc/html-manual/highlight/styles/brown-paper.css deleted file mode 100644 index f0197b924c1..00000000000 --- a/doc/html-manual/highlight/styles/brown-paper.css +++ /dev/null @@ -1,64 +0,0 @@ -/* - -Brown Paper style from goldblog.com.ua (c) Zaripov Yura - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background:#b7a68e url(./brown-papersq.png); -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-literal { - color:#005599; - font-weight:bold; -} - -.hljs, -.hljs-subst { - color: #363c69; -} - -.hljs-string, -.hljs-title, -.hljs-section, -.hljs-type, -.hljs-attribute, -.hljs-symbol, -.hljs-bullet, -.hljs-built_in, -.hljs-addition, -.hljs-variable, -.hljs-template-tag, -.hljs-template-variable, -.hljs-link, -.hljs-name { - color: #2c009f; -} - -.hljs-comment, -.hljs-quote, -.hljs-meta, -.hljs-deletion { - color: #802022; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-literal, -.hljs-doctag, -.hljs-title, -.hljs-section, -.hljs-type, -.hljs-name, -.hljs-strong { - font-weight: bold; -} - -.hljs-emphasis { - font-style: italic; -} diff --git a/doc/html-manual/highlight/styles/brown-papersq.png b/doc/html-manual/highlight/styles/brown-papersq.png deleted file mode 100644 index 3813903dbf9..00000000000 Binary files a/doc/html-manual/highlight/styles/brown-papersq.png and /dev/null differ diff --git a/doc/html-manual/highlight/styles/codepen-embed.css b/doc/html-manual/highlight/styles/codepen-embed.css deleted file mode 100644 index 195c4a07843..00000000000 --- a/doc/html-manual/highlight/styles/codepen-embed.css +++ /dev/null @@ -1,60 +0,0 @@ -/* - codepen.io Embed Theme - Author: Justin Perry - Original theme - https://github.com/chriskempson/tomorrow-theme -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #222; - color: #fff; -} - -.hljs-comment, -.hljs-quote { - color: #777; -} - -.hljs-variable, -.hljs-template-variable, -.hljs-tag, -.hljs-regexp, -.hljs-meta, -.hljs-number, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-params, -.hljs-symbol, -.hljs-bullet, -.hljs-link, -.hljs-deletion { - color: #ab875d; -} - -.hljs-section, -.hljs-title, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class, -.hljs-type, -.hljs-attribute { - color: #9b869b; -} - -.hljs-string, -.hljs-keyword, -.hljs-selector-tag, -.hljs-addition { - color: #8f9c6c; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/color-brewer.css b/doc/html-manual/highlight/styles/color-brewer.css deleted file mode 100644 index 7934d986a7e..00000000000 --- a/doc/html-manual/highlight/styles/color-brewer.css +++ /dev/null @@ -1,71 +0,0 @@ -/* - -Colorbrewer theme -Original: https://github.com/mbostock/colorbrewer-theme (c) Mike Bostock -Ported by Fabrício Tavares de Oliveira - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #fff; -} - -.hljs, -.hljs-subst { - color: #000; -} - -.hljs-string, -.hljs-meta, -.hljs-symbol, -.hljs-template-tag, -.hljs-template-variable, -.hljs-addition { - color: #756bb1; -} - -.hljs-comment, -.hljs-quote { - color: #636363; -} - -.hljs-number, -.hljs-regexp, -.hljs-literal, -.hljs-bullet, -.hljs-link { - color: #31a354; -} - -.hljs-deletion, -.hljs-variable { - color: #88f; -} - - - -.hljs-keyword, -.hljs-selector-tag, -.hljs-title, -.hljs-section, -.hljs-built_in, -.hljs-doctag, -.hljs-type, -.hljs-tag, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class, -.hljs-strong { - color: #3182bd; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-attribute { - color: #e6550d; -} diff --git a/doc/html-manual/highlight/styles/dark.css b/doc/html-manual/highlight/styles/dark.css deleted file mode 100644 index b4724f5f50d..00000000000 --- a/doc/html-manual/highlight/styles/dark.css +++ /dev/null @@ -1,63 +0,0 @@ -/* - -Dark style from softwaremaniacs.org (c) Ivan Sagalaev - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #444; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-literal, -.hljs-section, -.hljs-link { - color: white; -} - -.hljs, -.hljs-subst { - color: #ddd; -} - -.hljs-string, -.hljs-title, -.hljs-name, -.hljs-type, -.hljs-attribute, -.hljs-symbol, -.hljs-bullet, -.hljs-built_in, -.hljs-addition, -.hljs-variable, -.hljs-template-tag, -.hljs-template-variable { - color: #d88; -} - -.hljs-comment, -.hljs-quote, -.hljs-deletion, -.hljs-meta { - color: #777; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-literal, -.hljs-title, -.hljs-section, -.hljs-doctag, -.hljs-type, -.hljs-name, -.hljs-strong { - font-weight: bold; -} - -.hljs-emphasis { - font-style: italic; -} diff --git a/doc/html-manual/highlight/styles/darkula.css b/doc/html-manual/highlight/styles/darkula.css deleted file mode 100644 index c01f9a7fced..00000000000 --- a/doc/html-manual/highlight/styles/darkula.css +++ /dev/null @@ -1,74 +0,0 @@ -/* - -Darkula color scheme from the JetBrains family of IDEs - -*/ - - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #2b2b2b; -} - -.hljs { - color: #bababa; -} - -.hljs-strong, -.hljs-emphasis { - color: #a8a8a2; -} - -.hljs-bullet, -.hljs-quote, -.hljs-link, -.hljs-number, -.hljs-regexp, -.hljs-literal { - color: #6896ba; -} - -.hljs-code, -.hljs-selector-class { - color: #a6e22e; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-section, -.hljs-attribute, -.hljs-name, -.hljs-variable { - color: #cb7832; -} - -.hljs-params { - color: #b9b9b9; -} - -.hljs-string, -.hljs-subst, -.hljs-type, -.hljs-built_in, -.hljs-builtin-name, -.hljs-symbol, -.hljs-selector-id, -.hljs-selector-attr, -.hljs-selector-pseudo, -.hljs-template-tag, -.hljs-template-variable, -.hljs-addition { - color: #e0c46c; -} - -.hljs-comment, -.hljs-deletion, -.hljs-meta { - color: #7f7f7f; -} diff --git a/doc/html-manual/highlight/styles/default.css b/doc/html-manual/highlight/styles/default.css deleted file mode 100644 index f1bfade31e5..00000000000 --- a/doc/html-manual/highlight/styles/default.css +++ /dev/null @@ -1,99 +0,0 @@ -/* - -Original highlight.js style (c) Ivan Sagalaev - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #F0F0F0; -} - - -/* Base color: saturation 0; */ - -.hljs, -.hljs-subst { - color: #444; -} - -.hljs-comment { - color: #888888; -} - -.hljs-keyword, -.hljs-attribute, -.hljs-selector-tag, -.hljs-meta-keyword, -.hljs-doctag, -.hljs-name { - font-weight: bold; -} - - -/* User color: hue: 0 */ - -.hljs-type, -.hljs-string, -.hljs-number, -.hljs-selector-id, -.hljs-selector-class, -.hljs-quote, -.hljs-template-tag, -.hljs-deletion { - color: #880000; -} - -.hljs-title, -.hljs-section { - color: #880000; - font-weight: bold; -} - -.hljs-regexp, -.hljs-symbol, -.hljs-variable, -.hljs-template-variable, -.hljs-link, -.hljs-selector-attr, -.hljs-selector-pseudo { - color: #BC6060; -} - - -/* Language color: hue: 90; */ - -.hljs-literal { - color: #78A960; -} - -.hljs-built_in, -.hljs-bullet, -.hljs-code, -.hljs-addition { - color: #397300; -} - - -/* Meta color: hue: 200 */ - -.hljs-meta { - color: #1f7199; -} - -.hljs-meta-string { - color: #4d99bf; -} - - -/* Misc effects */ - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/docco.css b/doc/html-manual/highlight/styles/docco.css deleted file mode 100644 index db366be372b..00000000000 --- a/doc/html-manual/highlight/styles/docco.css +++ /dev/null @@ -1,97 +0,0 @@ -/* -Docco style used in http://jashkenas.github.com/docco/ converted by Simon Madine (@thingsinjars) -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - color: #000; - background: #f8f8ff; -} - -.hljs-comment, -.hljs-quote { - color: #408080; - font-style: italic; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-literal, -.hljs-subst { - color: #954121; -} - -.hljs-number { - color: #40a070; -} - -.hljs-string, -.hljs-doctag { - color: #219161; -} - -.hljs-selector-id, -.hljs-selector-class, -.hljs-section, -.hljs-type { - color: #19469d; -} - -.hljs-params { - color: #00f; -} - -.hljs-title { - color: #458; - font-weight: bold; -} - -.hljs-tag, -.hljs-name, -.hljs-attribute { - color: #000080; - font-weight: normal; -} - -.hljs-variable, -.hljs-template-variable { - color: #008080; -} - -.hljs-regexp, -.hljs-link { - color: #b68; -} - -.hljs-symbol, -.hljs-bullet { - color: #990073; -} - -.hljs-built_in, -.hljs-builtin-name { - color: #0086b3; -} - -.hljs-meta { - color: #999; - font-weight: bold; -} - -.hljs-deletion { - background: #fdd; -} - -.hljs-addition { - background: #dfd; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/dracula.css b/doc/html-manual/highlight/styles/dracula.css deleted file mode 100644 index d591db6801e..00000000000 --- a/doc/html-manual/highlight/styles/dracula.css +++ /dev/null @@ -1,76 +0,0 @@ -/* - -Dracula Theme v1.2.0 - -https://github.com/zenorocha/dracula-theme - -Copyright 2015, All rights reserved - -Code licensed under the MIT license -http://zenorocha.mit-license.org - -@author Éverton Ribeiro -@author Zeno Rocha - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #282a36; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-literal, -.hljs-section, -.hljs-link { - color: #8be9fd; -} - -.hljs-function .hljs-keyword { - color: #ff79c6; -} - -.hljs, -.hljs-subst { - color: #f8f8f2; -} - -.hljs-string, -.hljs-title, -.hljs-name, -.hljs-type, -.hljs-attribute, -.hljs-symbol, -.hljs-bullet, -.hljs-addition, -.hljs-variable, -.hljs-template-tag, -.hljs-template-variable { - color: #f1fa8c; -} - -.hljs-comment, -.hljs-quote, -.hljs-deletion, -.hljs-meta { - color: #6272a4; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-literal, -.hljs-title, -.hljs-section, -.hljs-doctag, -.hljs-type, -.hljs-name, -.hljs-strong { - font-weight: bold; -} - -.hljs-emphasis { - font-style: italic; -} diff --git a/doc/html-manual/highlight/styles/far.css b/doc/html-manual/highlight/styles/far.css deleted file mode 100644 index 2b3f87b5623..00000000000 --- a/doc/html-manual/highlight/styles/far.css +++ /dev/null @@ -1,71 +0,0 @@ -/* - -FAR Style (c) MajestiC - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #000080; -} - -.hljs, -.hljs-subst { - color: #0ff; -} - -.hljs-string, -.hljs-attribute, -.hljs-symbol, -.hljs-bullet, -.hljs-built_in, -.hljs-builtin-name, -.hljs-template-tag, -.hljs-template-variable, -.hljs-addition { - color: #ff0; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-section, -.hljs-type, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class, -.hljs-variable { - color: #fff; -} - -.hljs-comment, -.hljs-quote, -.hljs-doctag, -.hljs-deletion { - color: #888; -} - -.hljs-number, -.hljs-regexp, -.hljs-literal, -.hljs-link { - color: #0f0; -} - -.hljs-meta { - color: #008080; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-title, -.hljs-section, -.hljs-name, -.hljs-strong { - font-weight: bold; -} - -.hljs-emphasis { - font-style: italic; -} diff --git a/doc/html-manual/highlight/styles/foundation.css b/doc/html-manual/highlight/styles/foundation.css deleted file mode 100644 index f1fe64b3771..00000000000 --- a/doc/html-manual/highlight/styles/foundation.css +++ /dev/null @@ -1,88 +0,0 @@ -/* -Description: Foundation 4 docs style for highlight.js -Author: Dan Allen -Website: http://foundation.zurb.com/docs/ -Version: 1.0 -Date: 2013-04-02 -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #eee; color: black; -} - -.hljs-link, -.hljs-emphasis, -.hljs-attribute, -.hljs-addition { - color: #070; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong, -.hljs-string, -.hljs-deletion { - color: #d14; -} - -.hljs-strong { - font-weight: bold; -} - -.hljs-quote, -.hljs-comment { - color: #998; - font-style: italic; -} - -.hljs-section, -.hljs-title { - color: #900; -} - -.hljs-class .hljs-title, -.hljs-type { - color: #458; -} - -.hljs-variable, -.hljs-template-variable { - color: #336699; -} - -.hljs-bullet { - color: #997700; -} - -.hljs-meta { - color: #3344bb; -} - -.hljs-code, -.hljs-number, -.hljs-literal, -.hljs-keyword, -.hljs-selector-tag { - color: #099; -} - -.hljs-regexp { - background-color: #fff0ff; - color: #880088; -} - -.hljs-symbol { - color: #990073; -} - -.hljs-tag, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #007700; -} diff --git a/doc/html-manual/highlight/styles/github-gist.css b/doc/html-manual/highlight/styles/github-gist.css deleted file mode 100644 index 155f0b9160d..00000000000 --- a/doc/html-manual/highlight/styles/github-gist.css +++ /dev/null @@ -1,71 +0,0 @@ -/** - * GitHub Gist Theme - * Author : Louis Barranqueiro - https://github.com/LouisBarranqueiro - */ - -.hljs { - display: block; - background: white; - padding: 0.5em; - color: #333333; - overflow-x: auto; -} - -.hljs-comment, -.hljs-meta { - color: #969896; -} - -.hljs-string, -.hljs-variable, -.hljs-template-variable, -.hljs-strong, -.hljs-emphasis, -.hljs-quote { - color: #df5000; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-type { - color: #a71d5d; -} - -.hljs-literal, -.hljs-symbol, -.hljs-bullet, -.hljs-attribute { - color: #0086b3; -} - -.hljs-section, -.hljs-name { - color: #63a35c; -} - -.hljs-tag { - color: #333333; -} - -.hljs-title, -.hljs-attr, -.hljs-selector-id, -.hljs-selector-class, -.hljs-selector-attr, -.hljs-selector-pseudo { - color: #795da3; -} - -.hljs-addition { - color: #55a532; - background-color: #eaffea; -} - -.hljs-deletion { - color: #bd2c00; - background-color: #ffecec; -} - -.hljs-link { - text-decoration: underline; -} diff --git a/doc/html-manual/highlight/styles/github.css b/doc/html-manual/highlight/styles/github.css deleted file mode 100644 index 791932b87ea..00000000000 --- a/doc/html-manual/highlight/styles/github.css +++ /dev/null @@ -1,99 +0,0 @@ -/* - -github.com style (c) Vasily Polovnyov - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - color: #333; - background: #f8f8f8; -} - -.hljs-comment, -.hljs-quote { - color: #998; - font-style: italic; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-subst { - color: #333; - font-weight: bold; -} - -.hljs-number, -.hljs-literal, -.hljs-variable, -.hljs-template-variable, -.hljs-tag .hljs-attr { - color: #008080; -} - -.hljs-string, -.hljs-doctag { - color: #d14; -} - -.hljs-title, -.hljs-section, -.hljs-selector-id { - color: #900; - font-weight: bold; -} - -.hljs-subst { - font-weight: normal; -} - -.hljs-type, -.hljs-class .hljs-title { - color: #458; - font-weight: bold; -} - -.hljs-tag, -.hljs-name, -.hljs-attribute { - color: #000080; - font-weight: normal; -} - -.hljs-regexp, -.hljs-link { - color: #009926; -} - -.hljs-symbol, -.hljs-bullet { - color: #990073; -} - -.hljs-built_in, -.hljs-builtin-name { - color: #0086b3; -} - -.hljs-meta { - color: #999; - font-weight: bold; -} - -.hljs-deletion { - background: #fdd; -} - -.hljs-addition { - background: #dfd; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/googlecode.css b/doc/html-manual/highlight/styles/googlecode.css deleted file mode 100644 index 884ad63538e..00000000000 --- a/doc/html-manual/highlight/styles/googlecode.css +++ /dev/null @@ -1,89 +0,0 @@ -/* - -Google Code style (c) Aahan Krish - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: white; - color: black; -} - -.hljs-comment, -.hljs-quote { - color: #800; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-section, -.hljs-title, -.hljs-name { - color: #008; -} - -.hljs-variable, -.hljs-template-variable { - color: #660; -} - -.hljs-string, -.hljs-selector-attr, -.hljs-selector-pseudo, -.hljs-regexp { - color: #080; -} - -.hljs-literal, -.hljs-symbol, -.hljs-bullet, -.hljs-meta, -.hljs-number, -.hljs-link { - color: #066; -} - -.hljs-title, -.hljs-doctag, -.hljs-type, -.hljs-attr, -.hljs-built_in, -.hljs-builtin-name, -.hljs-params { - color: #606; -} - -.hljs-attribute, -.hljs-subst { - color: #000; -} - -.hljs-formula { - background-color: #eee; - font-style: italic; -} - -.hljs-selector-id, -.hljs-selector-class { - color: #9B703F -} - -.hljs-addition { - background-color: #baeeba; -} - -.hljs-deletion { - background-color: #ffc8bd; -} - -.hljs-doctag, -.hljs-strong { - font-weight: bold; -} - -.hljs-emphasis { - font-style: italic; -} diff --git a/doc/html-manual/highlight/styles/grayscale.css b/doc/html-manual/highlight/styles/grayscale.css deleted file mode 100644 index 5376f340648..00000000000 --- a/doc/html-manual/highlight/styles/grayscale.css +++ /dev/null @@ -1,101 +0,0 @@ -/* - -grayscale style (c) MY Sun - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - color: #333; - background: #fff; -} - -.hljs-comment, -.hljs-quote { - color: #777; - font-style: italic; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-subst { - color: #333; - font-weight: bold; -} - -.hljs-number, -.hljs-literal { - color: #777; -} - -.hljs-string, -.hljs-doctag, -.hljs-formula { - color: #333; - background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAAJ0lEQVQIW2O8e/fufwYGBgZBQUEQxcCIIfDu3Tuwivfv30NUoAsAALHpFMMLqZlPAAAAAElFTkSuQmCC) repeat; -} - -.hljs-title, -.hljs-section, -.hljs-selector-id { - color: #000; - font-weight: bold; -} - -.hljs-subst { - font-weight: normal; -} - -.hljs-class .hljs-title, -.hljs-type, -.hljs-name { - color: #333; - font-weight: bold; -} - -.hljs-tag { - color: #333; -} - -.hljs-regexp { - color: #333; - background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAICAYAAADA+m62AAAAPUlEQVQYV2NkQAN37979r6yszIgujiIAU4RNMVwhuiQ6H6wQl3XI4oy4FMHcCJPHcDS6J2A2EqUQpJhohQDexSef15DBCwAAAABJRU5ErkJggg==) repeat; -} - -.hljs-symbol, -.hljs-bullet, -.hljs-link { - color: #000; - background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAKElEQVQIW2NkQAO7d+/+z4gsBhJwdXVlhAvCBECKwIIwAbhKZBUwBQA6hBpm5efZsgAAAABJRU5ErkJggg==) repeat; -} - -.hljs-built_in, -.hljs-builtin-name { - color: #000; - text-decoration: underline; -} - -.hljs-meta { - color: #999; - font-weight: bold; -} - -.hljs-deletion { - color: #fff; - background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAADCAYAAABS3WWCAAAAE0lEQVQIW2MMDQ39zzhz5kwIAQAyxweWgUHd1AAAAABJRU5ErkJggg==) repeat; -} - -.hljs-addition { - color: #000; - background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAALUlEQVQYV2N89+7dfwYk8P79ewZBQUFkIQZGOiu6e/cuiptQHAPl0NtNxAQBAM97Oejj3Dg7AAAAAElFTkSuQmCC) repeat; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/gruvbox-dark.css b/doc/html-manual/highlight/styles/gruvbox-dark.css deleted file mode 100644 index f563811a862..00000000000 --- a/doc/html-manual/highlight/styles/gruvbox-dark.css +++ /dev/null @@ -1,108 +0,0 @@ -/* - -Gruvbox style (dark) (c) Pavel Pertsev (original style at https://github.com/morhetz/gruvbox) - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #282828; -} - -.hljs, -.hljs-subst { - color: #ebdbb2; -} - -/* Gruvbox Red */ -.hljs-deletion, -.hljs-formula, -.hljs-keyword, -.hljs-link, -.hljs-selector-tag { - color: #fb4934; -} - -/* Gruvbox Blue */ -.hljs-built_in, -.hljs-emphasis, -.hljs-name, -.hljs-quote, -.hljs-strong, -.hljs-title, -.hljs-variable { - color: #83a598; -} - -/* Gruvbox Yellow */ -.hljs-attr, -.hljs-params, -.hljs-template-tag, -.hljs-type { - color: #fabd2f; -} - -/* Gruvbox Purple */ -.hljs-builtin-name, -.hljs-doctag, -.hljs-literal, -.hljs-number { - color: #8f3f71; -} - -/* Gruvbox Orange */ -.hljs-code, -.hljs-meta, -.hljs-regexp, -.hljs-selector-id, -.hljs-template-variable { - color: #fe8019; -} - -/* Gruvbox Green */ -.hljs-addition, -.hljs-meta-string, -.hljs-section, -.hljs-selector-attr, -.hljs-selector-class, -.hljs-string, -.hljs-symbol { - color: #b8bb26; -} - -/* Gruvbox Aqua */ -.hljs-attribute, -.hljs-bullet, -.hljs-class, -.hljs-function, -.hljs-function .hljs-keyword, -.hljs-meta-keyword, -.hljs-selector-pseudo, -.hljs-tag { - color: #8ec07c; -} - -/* Gruvbox Gray */ -.hljs-comment { - color: #928374; -} - -/* Gruvbox Purple */ -.hljs-link_label, -.hljs-literal, -.hljs-number { - color: #d3869b; -} - -.hljs-comment, -.hljs-emphasis { - font-style: italic; -} - -.hljs-section, -.hljs-strong, -.hljs-tag { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/gruvbox-light.css b/doc/html-manual/highlight/styles/gruvbox-light.css deleted file mode 100644 index ff45468eb2e..00000000000 --- a/doc/html-manual/highlight/styles/gruvbox-light.css +++ /dev/null @@ -1,108 +0,0 @@ -/* - -Gruvbox style (light) (c) Pavel Pertsev (original style at https://github.com/morhetz/gruvbox) - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #fbf1c7; -} - -.hljs, -.hljs-subst { - color: #3c3836; -} - -/* Gruvbox Red */ -.hljs-deletion, -.hljs-formula, -.hljs-keyword, -.hljs-link, -.hljs-selector-tag { - color: #9d0006; -} - -/* Gruvbox Blue */ -.hljs-built_in, -.hljs-emphasis, -.hljs-name, -.hljs-quote, -.hljs-strong, -.hljs-title, -.hljs-variable { - color: #076678; -} - -/* Gruvbox Yellow */ -.hljs-attr, -.hljs-params, -.hljs-template-tag, -.hljs-type { - color: #b57614; -} - -/* Gruvbox Purple */ -.hljs-builtin-name, -.hljs-doctag, -.hljs-literal, -.hljs-number { - color: #8f3f71; -} - -/* Gruvbox Orange */ -.hljs-code, -.hljs-meta, -.hljs-regexp, -.hljs-selector-id, -.hljs-template-variable { - color: #af3a03; -} - -/* Gruvbox Green */ -.hljs-addition, -.hljs-meta-string, -.hljs-section, -.hljs-selector-attr, -.hljs-selector-class, -.hljs-string, -.hljs-symbol { - color: #79740e; -} - -/* Gruvbox Aqua */ -.hljs-attribute, -.hljs-bullet, -.hljs-class, -.hljs-function, -.hljs-function .hljs-keyword, -.hljs-meta-keyword, -.hljs-selector-pseudo, -.hljs-tag { - color: #427b58; -} - -/* Gruvbox Gray */ -.hljs-comment { - color: #928374; -} - -/* Gruvbox Purple */ -.hljs-link_label, -.hljs-literal, -.hljs-number { - color: #8f3f71; -} - -.hljs-comment, -.hljs-emphasis { - font-style: italic; -} - -.hljs-section, -.hljs-strong, -.hljs-tag { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/hopscotch.css b/doc/html-manual/highlight/styles/hopscotch.css deleted file mode 100644 index 32e60d230a5..00000000000 --- a/doc/html-manual/highlight/styles/hopscotch.css +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Hopscotch - * by Jan T. Sott - * https://github.com/idleberg/Hopscotch - * - * This work is licensed under the Creative Commons CC0 1.0 Universal License - */ - -/* Comment */ -.hljs-comment, -.hljs-quote { - color: #989498; -} - -/* Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-attribute, -.hljs-tag, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class, -.hljs-regexp, -.hljs-link, -.hljs-deletion { - color: #dd464c; -} - -/* Orange */ -.hljs-number, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params { - color: #fd8b19; -} - -/* Yellow */ -.hljs-class .hljs-title { - color: #fdcc59; -} - -/* Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet, -.hljs-addition { - color: #8fc13e; -} - -/* Aqua */ -.hljs-meta { - color: #149b93; -} - -/* Blue */ -.hljs-function, -.hljs-section, -.hljs-title { - color: #1290bf; -} - -/* Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #c85e7c; -} - -.hljs { - display: block; - background: #322931; - color: #b9b5b8; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/hybrid.css b/doc/html-manual/highlight/styles/hybrid.css deleted file mode 100644 index 29735a18904..00000000000 --- a/doc/html-manual/highlight/styles/hybrid.css +++ /dev/null @@ -1,102 +0,0 @@ -/* - -vim-hybrid theme by w0ng (https://github.com/w0ng/vim-hybrid) - -*/ - -/*background color*/ -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #1d1f21; -} - -/*selection color*/ -.hljs::selection, -.hljs span::selection { - background: #373b41; -} - -.hljs::-moz-selection, -.hljs span::-moz-selection { - background: #373b41; -} - -/*foreground color*/ -.hljs { - color: #c5c8c6; -} - -/*color: fg_yellow*/ -.hljs-title, -.hljs-name { - color: #f0c674; -} - -/*color: fg_comment*/ -.hljs-comment, -.hljs-meta, -.hljs-meta .hljs-keyword { - color: #707880; -} - -/*color: fg_red*/ -.hljs-number, -.hljs-symbol, -.hljs-literal, -.hljs-deletion, -.hljs-link { - color: #cc6666 -} - -/*color: fg_green*/ -.hljs-string, -.hljs-doctag, -.hljs-addition, -.hljs-regexp, -.hljs-selector-attr, -.hljs-selector-pseudo { - color: #b5bd68; -} - -/*color: fg_purple*/ -.hljs-attribute, -.hljs-code, -.hljs-selector-id { - color: #b294bb; -} - -/*color: fg_blue*/ -.hljs-keyword, -.hljs-selector-tag, -.hljs-bullet, -.hljs-tag { - color: #81a2be; -} - -/*color: fg_aqua*/ -.hljs-subst, -.hljs-variable, -.hljs-template-tag, -.hljs-template-variable { - color: #8abeb7; -} - -/*color: fg_orange*/ -.hljs-type, -.hljs-built_in, -.hljs-builtin-name, -.hljs-quote, -.hljs-section, -.hljs-selector-class { - color: #de935f; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/idea.css b/doc/html-manual/highlight/styles/idea.css deleted file mode 100644 index 3bf1892bd4a..00000000000 --- a/doc/html-manual/highlight/styles/idea.css +++ /dev/null @@ -1,97 +0,0 @@ -/* - -Intellij Idea-like styling (c) Vasily Polovnyov - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - color: #000; - background: #fff; -} - -.hljs-subst, -.hljs-title { - font-weight: normal; - color: #000; -} - -.hljs-comment, -.hljs-quote { - color: #808080; - font-style: italic; -} - -.hljs-meta { - color: #808000; -} - -.hljs-tag { - background: #efefef; -} - -.hljs-section, -.hljs-name, -.hljs-literal, -.hljs-keyword, -.hljs-selector-tag, -.hljs-type, -.hljs-selector-id, -.hljs-selector-class { - font-weight: bold; - color: #000080; -} - -.hljs-attribute, -.hljs-number, -.hljs-regexp, -.hljs-link { - font-weight: bold; - color: #0000ff; -} - -.hljs-number, -.hljs-regexp, -.hljs-link { - font-weight: normal; -} - -.hljs-string { - color: #008000; - font-weight: bold; -} - -.hljs-symbol, -.hljs-bullet, -.hljs-formula { - color: #000; - background: #d0eded; - font-style: italic; -} - -.hljs-doctag { - text-decoration: underline; -} - -.hljs-variable, -.hljs-template-variable { - color: #660e7a; -} - -.hljs-addition { - background: #baeeba; -} - -.hljs-deletion { - background: #ffc8bd; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/ir-black.css b/doc/html-manual/highlight/styles/ir-black.css deleted file mode 100644 index bd4c755ed8a..00000000000 --- a/doc/html-manual/highlight/styles/ir-black.css +++ /dev/null @@ -1,73 +0,0 @@ -/* - IR_Black style (c) Vasily Mikhailitchenko -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #000; - color: #f8f8f8; -} - -.hljs-comment, -.hljs-quote, -.hljs-meta { - color: #7c7c7c; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-tag, -.hljs-name { - color: #96cbfe; -} - -.hljs-attribute, -.hljs-selector-id { - color: #ffffb6; -} - -.hljs-string, -.hljs-selector-attr, -.hljs-selector-pseudo, -.hljs-addition { - color: #a8ff60; -} - -.hljs-subst { - color: #daefa3; -} - -.hljs-regexp, -.hljs-link { - color: #e9c062; -} - -.hljs-title, -.hljs-section, -.hljs-type, -.hljs-doctag { - color: #ffffb6; -} - -.hljs-symbol, -.hljs-bullet, -.hljs-variable, -.hljs-template-variable, -.hljs-literal { - color: #c6c5fe; -} - -.hljs-number, -.hljs-deletion { - color:#ff73fd; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/kimbie.dark.css b/doc/html-manual/highlight/styles/kimbie.dark.css deleted file mode 100644 index d139cb5d0c9..00000000000 --- a/doc/html-manual/highlight/styles/kimbie.dark.css +++ /dev/null @@ -1,74 +0,0 @@ -/* - Name: Kimbie (dark) - Author: Jan T. Sott - License: Creative Commons Attribution-ShareAlike 4.0 Unported License - URL: https://github.com/idleberg/Kimbie-highlight.js -*/ - -/* Kimbie Comment */ -.hljs-comment, -.hljs-quote { - color: #d6baad; -} - -/* Kimbie Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-tag, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class, -.hljs-regexp, -.hljs-meta { - color: #dc3958; -} - -/* Kimbie Orange */ -.hljs-number, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params, -.hljs-deletion, -.hljs-link { - color: #f79a32; -} - -/* Kimbie Yellow */ -.hljs-title, -.hljs-section, -.hljs-attribute { - color: #f06431; -} - -/* Kimbie Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet, -.hljs-addition { - color: #889b4a; -} - -/* Kimbie Purple */ -.hljs-keyword, -.hljs-selector-tag, -.hljs-function { - color: #98676a; -} - -.hljs { - display: block; - overflow-x: auto; - background: #221a0f; - color: #d3af86; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/kimbie.light.css b/doc/html-manual/highlight/styles/kimbie.light.css deleted file mode 100644 index 04ff6ed3a2d..00000000000 --- a/doc/html-manual/highlight/styles/kimbie.light.css +++ /dev/null @@ -1,74 +0,0 @@ -/* - Name: Kimbie (light) - Author: Jan T. Sott - License: Creative Commons Attribution-ShareAlike 4.0 Unported License - URL: https://github.com/idleberg/Kimbie-highlight.js -*/ - -/* Kimbie Comment */ -.hljs-comment, -.hljs-quote { - color: #a57a4c; -} - -/* Kimbie Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-tag, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class, -.hljs-regexp, -.hljs-meta { - color: #dc3958; -} - -/* Kimbie Orange */ -.hljs-number, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params, -.hljs-deletion, -.hljs-link { - color: #f79a32; -} - -/* Kimbie Yellow */ -.hljs-title, -.hljs-section, -.hljs-attribute { - color: #f06431; -} - -/* Kimbie Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet, -.hljs-addition { - color: #889b4a; -} - -/* Kimbie Purple */ -.hljs-keyword, -.hljs-selector-tag, -.hljs-function { - color: #98676a; -} - -.hljs { - display: block; - overflow-x: auto; - background: #fbebd4; - color: #84613d; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/magula.css b/doc/html-manual/highlight/styles/magula.css deleted file mode 100644 index 44dee5e8e10..00000000000 --- a/doc/html-manual/highlight/styles/magula.css +++ /dev/null @@ -1,70 +0,0 @@ -/* -Description: Magula style for highligh.js -Author: Ruslan Keba -Website: http://rukeba.com/ -Version: 1.0 -Date: 2009-01-03 -Music: Aphex Twin / Xtal -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background-color: #f4f4f4; -} - -.hljs, -.hljs-subst { - color: black; -} - -.hljs-string, -.hljs-title, -.hljs-symbol, -.hljs-bullet, -.hljs-attribute, -.hljs-addition, -.hljs-variable, -.hljs-template-tag, -.hljs-template-variable { - color: #050; -} - -.hljs-comment, -.hljs-quote { - color: #777; -} - -.hljs-number, -.hljs-regexp, -.hljs-literal, -.hljs-type, -.hljs-link { - color: #800; -} - -.hljs-deletion, -.hljs-meta { - color: #00e; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-doctag, -.hljs-title, -.hljs-section, -.hljs-built_in, -.hljs-tag, -.hljs-name { - font-weight: bold; - color: navy; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/mono-blue.css b/doc/html-manual/highlight/styles/mono-blue.css deleted file mode 100644 index 884c97c7673..00000000000 --- a/doc/html-manual/highlight/styles/mono-blue.css +++ /dev/null @@ -1,59 +0,0 @@ -/* - Five-color theme from a single blue hue. -*/ -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #eaeef3; -} - -.hljs { - color: #00193a; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-title, -.hljs-section, -.hljs-doctag, -.hljs-name, -.hljs-strong { - font-weight: bold; -} - -.hljs-comment { - color: #738191; -} - -.hljs-string, -.hljs-title, -.hljs-section, -.hljs-built_in, -.hljs-literal, -.hljs-type, -.hljs-addition, -.hljs-tag, -.hljs-quote, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #0048ab; -} - -.hljs-meta, -.hljs-subst, -.hljs-symbol, -.hljs-regexp, -.hljs-attribute, -.hljs-deletion, -.hljs-variable, -.hljs-template-variable, -.hljs-link, -.hljs-bullet { - color: #4c81c9; -} - -.hljs-emphasis { - font-style: italic; -} diff --git a/doc/html-manual/highlight/styles/monokai-sublime.css b/doc/html-manual/highlight/styles/monokai-sublime.css deleted file mode 100644 index 2864170daf6..00000000000 --- a/doc/html-manual/highlight/styles/monokai-sublime.css +++ /dev/null @@ -1,83 +0,0 @@ -/* - -Monokai Sublime style. Derived from Monokai by noformnocontent http://nn.mit-license.org/ - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #23241f; -} - -.hljs, -.hljs-tag, -.hljs-subst { - color: #f8f8f2; -} - -.hljs-strong, -.hljs-emphasis { - color: #a8a8a2; -} - -.hljs-bullet, -.hljs-quote, -.hljs-number, -.hljs-regexp, -.hljs-literal, -.hljs-link { - color: #ae81ff; -} - -.hljs-code, -.hljs-title, -.hljs-section, -.hljs-selector-class { - color: #a6e22e; -} - -.hljs-strong { - font-weight: bold; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-name, -.hljs-attr { - color: #f92672; -} - -.hljs-symbol, -.hljs-attribute { - color: #66d9ef; -} - -.hljs-params, -.hljs-class .hljs-title { - color: #f8f8f2; -} - -.hljs-string, -.hljs-type, -.hljs-built_in, -.hljs-builtin-name, -.hljs-selector-id, -.hljs-selector-attr, -.hljs-selector-pseudo, -.hljs-addition, -.hljs-variable, -.hljs-template-variable { - color: #e6db74; -} - -.hljs-comment, -.hljs-deletion, -.hljs-meta { - color: #75715e; -} diff --git a/doc/html-manual/highlight/styles/monokai.css b/doc/html-manual/highlight/styles/monokai.css deleted file mode 100644 index 775d53f91aa..00000000000 --- a/doc/html-manual/highlight/styles/monokai.css +++ /dev/null @@ -1,70 +0,0 @@ -/* -Monokai style - ported by Luigi Maselli - http://grigio.org -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #272822; color: #ddd; -} - -.hljs-tag, -.hljs-keyword, -.hljs-selector-tag, -.hljs-literal, -.hljs-strong, -.hljs-name { - color: #f92672; -} - -.hljs-code { - color: #66d9ef; -} - -.hljs-class .hljs-title { - color: white; -} - -.hljs-attribute, -.hljs-symbol, -.hljs-regexp, -.hljs-link { - color: #bf79db; -} - -.hljs-string, -.hljs-bullet, -.hljs-subst, -.hljs-title, -.hljs-section, -.hljs-emphasis, -.hljs-type, -.hljs-built_in, -.hljs-builtin-name, -.hljs-selector-attr, -.hljs-selector-pseudo, -.hljs-addition, -.hljs-variable, -.hljs-template-tag, -.hljs-template-variable { - color: #a6e22e; -} - -.hljs-comment, -.hljs-quote, -.hljs-deletion, -.hljs-meta { - color: #75715e; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-literal, -.hljs-doctag, -.hljs-title, -.hljs-section, -.hljs-type, -.hljs-selector-id { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/obsidian.css b/doc/html-manual/highlight/styles/obsidian.css deleted file mode 100644 index 356630fa234..00000000000 --- a/doc/html-manual/highlight/styles/obsidian.css +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Obsidian style - * ported by Alexander Marenin (http://github.com/ioncreature) - */ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #282b2e; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-literal, -.hljs-selector-id { - color: #93c763; -} - -.hljs-number { - color: #ffcd22; -} - -.hljs { - color: #e0e2e4; -} - -.hljs-attribute { - color: #668bb0; -} - -.hljs-code, -.hljs-class .hljs-title, -.hljs-section { - color: white; -} - -.hljs-regexp, -.hljs-link { - color: #d39745; -} - -.hljs-meta { - color: #557182; -} - -.hljs-tag, -.hljs-name, -.hljs-bullet, -.hljs-subst, -.hljs-emphasis, -.hljs-type, -.hljs-built_in, -.hljs-selector-attr, -.hljs-selector-pseudo, -.hljs-addition, -.hljs-variable, -.hljs-template-tag, -.hljs-template-variable { - color: #8cbbad; -} - -.hljs-string, -.hljs-symbol { - color: #ec7600; -} - -.hljs-comment, -.hljs-quote, -.hljs-deletion { - color: #818e96; -} - -.hljs-selector-class { - color: #A082BD -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-literal, -.hljs-doctag, -.hljs-title, -.hljs-section, -.hljs-type, -.hljs-name, -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/paraiso-dark.css b/doc/html-manual/highlight/styles/paraiso-dark.css deleted file mode 100644 index e7292401c6e..00000000000 --- a/doc/html-manual/highlight/styles/paraiso-dark.css +++ /dev/null @@ -1,72 +0,0 @@ -/* - Paraíso (dark) - Created by Jan T. Sott (http://github.com/idleberg) - Inspired by the art of Rubens LP (http://www.rubenslp.com.br) -*/ - -/* Paraíso Comment */ -.hljs-comment, -.hljs-quote { - color: #8d8687; -} - -/* Paraíso Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-tag, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class, -.hljs-regexp, -.hljs-link, -.hljs-meta { - color: #ef6155; -} - -/* Paraíso Orange */ -.hljs-number, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params, -.hljs-deletion { - color: #f99b15; -} - -/* Paraíso Yellow */ -.hljs-title, -.hljs-section, -.hljs-attribute { - color: #fec418; -} - -/* Paraíso Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet, -.hljs-addition { - color: #48b685; -} - -/* Paraíso Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #815ba4; -} - -.hljs { - display: block; - overflow-x: auto; - background: #2f1e2e; - color: #a39e9b; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/paraiso-light.css b/doc/html-manual/highlight/styles/paraiso-light.css deleted file mode 100644 index 944857cd8d3..00000000000 --- a/doc/html-manual/highlight/styles/paraiso-light.css +++ /dev/null @@ -1,72 +0,0 @@ -/* - Paraíso (light) - Created by Jan T. Sott (http://github.com/idleberg) - Inspired by the art of Rubens LP (http://www.rubenslp.com.br) -*/ - -/* Paraíso Comment */ -.hljs-comment, -.hljs-quote { - color: #776e71; -} - -/* Paraíso Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-tag, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class, -.hljs-regexp, -.hljs-link, -.hljs-meta { - color: #ef6155; -} - -/* Paraíso Orange */ -.hljs-number, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params, -.hljs-deletion { - color: #f99b15; -} - -/* Paraíso Yellow */ -.hljs-title, -.hljs-section, -.hljs-attribute { - color: #fec418; -} - -/* Paraíso Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet, -.hljs-addition { - color: #48b685; -} - -/* Paraíso Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #815ba4; -} - -.hljs { - display: block; - overflow-x: auto; - background: #e7e9db; - color: #4f424c; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/pojoaque.css b/doc/html-manual/highlight/styles/pojoaque.css deleted file mode 100644 index 2e07847b2b2..00000000000 --- a/doc/html-manual/highlight/styles/pojoaque.css +++ /dev/null @@ -1,83 +0,0 @@ -/* - -Pojoaque Style by Jason Tate -http://web-cms-designs.com/ftopict-10-pojoaque-style-for-highlight-js-code-highlighter.html -Based on Solarized Style from http://ethanschoonover.com/solarized - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - color: #dccf8f; - background: url(./pojoaque.jpg) repeat scroll left top #181914; -} - -.hljs-comment, -.hljs-quote { - color: #586e75; - font-style: italic; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-literal, -.hljs-addition { - color: #b64926; -} - -.hljs-number, -.hljs-string, -.hljs-doctag, -.hljs-regexp { - color: #468966; -} - -.hljs-title, -.hljs-section, -.hljs-built_in, -.hljs-name { - color: #ffb03b; -} - -.hljs-variable, -.hljs-template-variable, -.hljs-class .hljs-title, -.hljs-type, -.hljs-tag { - color: #b58900; -} - -.hljs-attribute { - color: #b89859; -} - -.hljs-symbol, -.hljs-bullet, -.hljs-link, -.hljs-subst, -.hljs-meta { - color: #cb4b16; -} - -.hljs-deletion { - color: #dc322f; -} - -.hljs-selector-id, -.hljs-selector-class { - color: #d3a60c; -} - -.hljs-formula { - background: #073642; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/pojoaque.jpg b/doc/html-manual/highlight/styles/pojoaque.jpg deleted file mode 100644 index 9c07d4ab40b..00000000000 Binary files a/doc/html-manual/highlight/styles/pojoaque.jpg and /dev/null differ diff --git a/doc/html-manual/highlight/styles/purebasic.css b/doc/html-manual/highlight/styles/purebasic.css deleted file mode 100644 index 5ce9b9e0710..00000000000 --- a/doc/html-manual/highlight/styles/purebasic.css +++ /dev/null @@ -1,96 +0,0 @@ -/* - -PureBASIC native IDE style ( version 1.0 - April 2016 ) - -by Tristano Ajmone - -Public Domain - -NOTE_1: PureBASIC code syntax highlighting only applies the following classes: - .hljs-comment - .hljs-function - .hljs-keywords - .hljs-string - .hljs-symbol - - Other classes are added here for the benefit of styling other languages with the look and feel of PureBASIC native IDE style. - If you need to customize a stylesheet for PureBASIC only, remove all non-relevant classes -- PureBASIC-related classes are followed by - a "--- used for PureBASIC ... ---" comment on same line. - -NOTE_2: Color names provided in comments were derived using "Name that Color" online tool: - http://chir.ag/projects/name-that-color -*/ - -.hljs { /* Common set of rules required by highlight.js (don'r remove!) */ - display: block; - overflow-x: auto; - padding: 0.5em; - background: #FFFFDF; /* Half and Half (approx.) */ -/* --- Uncomment to add PureBASIC native IDE styled font! - font-family: Consolas; -*/ -} - -.hljs, /* --- used for PureBASIC base color --- */ -.hljs-type, /* --- used for PureBASIC Procedures return type --- */ -.hljs-function, /* --- used for wrapping PureBASIC Procedures definitions --- */ -.hljs-name, -.hljs-number, -.hljs-attr, -.hljs-params, -.hljs-subst { - color: #000000; /* Black */ -} - -.hljs-comment, /* --- used for PureBASIC Comments --- */ -.hljs-regexp, -.hljs-section, -.hljs-selector-pseudo, -.hljs-addition { - color: #00AAAA; /* Persian Green (approx.) */ -} - -.hljs-title, /* --- used for PureBASIC Procedures Names --- */ -.hljs-tag, -.hljs-variable, -.hljs-code { - color: #006666; /* Blue Stone (approx.) */ -} - -.hljs-keyword, /* --- used for PureBASIC Keywords --- */ -.hljs-class, -.hljs-meta-keyword, -.hljs-selector-class, -.hljs-built_in, -.hljs-builtin-name { - color: #006666; /* Blue Stone (approx.) */ - font-weight: bold; -} - -.hljs-string, /* --- used for PureBASIC Strings --- */ -.hljs-selector-attr { - color: #0080FF; /* Azure Radiance (approx.) */ -} - -.hljs-symbol, /* --- used for PureBASIC Constants --- */ -.hljs-link, -.hljs-deletion, -.hljs-attribute { - color: #924B72; /* Cannon Pink (approx.) */ -} - -.hljs-meta, -.hljs-literal, -.hljs-selector-id { - color: #924B72; /* Cannon Pink (approx.) */ - font-weight: bold; -} - -.hljs-strong, -.hljs-name { - font-weight: bold; -} - -.hljs-emphasis { - font-style: italic; -} diff --git a/doc/html-manual/highlight/styles/qtcreator_dark.css b/doc/html-manual/highlight/styles/qtcreator_dark.css deleted file mode 100644 index 7aa56a3655f..00000000000 --- a/doc/html-manual/highlight/styles/qtcreator_dark.css +++ /dev/null @@ -1,83 +0,0 @@ -/* - -Qt Creator dark color scheme - -*/ - - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #000000; -} - -.hljs, -.hljs-subst, -.hljs-tag, -.hljs-title { - color: #aaaaaa; -} - -.hljs-strong, -.hljs-emphasis { - color: #a8a8a2; -} - -.hljs-bullet, -.hljs-quote, -.hljs-number, -.hljs-regexp, -.hljs-literal { - color: #ff55ff; -} - -.hljs-code -.hljs-selector-class { - color: #aaaaff; -} - -.hljs-emphasis, -.hljs-stronge, -.hljs-type { - font-style: italic; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-function, -.hljs-section, -.hljs-symbol, -.hljs-name { - color: #ffff55; -} - -.hljs-attribute { - color: #ff5555; -} - -.hljs-variable, -.hljs-params, -.hljs-class .hljs-title { - color: #8888ff; -} - -.hljs-string, -.hljs-selector-id, -.hljs-selector-attr, -.hljs-selector-pseudo, -.hljs-type, -.hljs-built_in, -.hljs-builtin-name, -.hljs-template-tag, -.hljs-template-variable, -.hljs-addition, -.hljs-link { - color: #ff55ff; -} - -.hljs-comment, -.hljs-meta, -.hljs-deletion { - color: #55ffff; -} diff --git a/doc/html-manual/highlight/styles/qtcreator_light.css b/doc/html-manual/highlight/styles/qtcreator_light.css deleted file mode 100644 index 1efa2c660f0..00000000000 --- a/doc/html-manual/highlight/styles/qtcreator_light.css +++ /dev/null @@ -1,83 +0,0 @@ -/* - -Qt Creator light color scheme - -*/ - - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #ffffff; -} - -.hljs, -.hljs-subst, -.hljs-tag, -.hljs-title { - color: #000000; -} - -.hljs-strong, -.hljs-emphasis { - color: #000000; -} - -.hljs-bullet, -.hljs-quote, -.hljs-number, -.hljs-regexp, -.hljs-literal { - color: #000080; -} - -.hljs-code -.hljs-selector-class { - color: #800080; -} - -.hljs-emphasis, -.hljs-stronge, -.hljs-type { - font-style: italic; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-function, -.hljs-section, -.hljs-symbol, -.hljs-name { - color: #808000; -} - -.hljs-attribute { - color: #800000; -} - -.hljs-variable, -.hljs-params, -.hljs-class .hljs-title { - color: #0055AF; -} - -.hljs-string, -.hljs-selector-id, -.hljs-selector-attr, -.hljs-selector-pseudo, -.hljs-type, -.hljs-built_in, -.hljs-builtin-name, -.hljs-template-tag, -.hljs-template-variable, -.hljs-addition, -.hljs-link { - color: #008000; -} - -.hljs-comment, -.hljs-meta, -.hljs-deletion { - color: #008000; -} diff --git a/doc/html-manual/highlight/styles/railscasts.css b/doc/html-manual/highlight/styles/railscasts.css deleted file mode 100644 index 008cdc5bf14..00000000000 --- a/doc/html-manual/highlight/styles/railscasts.css +++ /dev/null @@ -1,106 +0,0 @@ -/* - -Railscasts-like style (c) Visoft, Inc. (Damien White) - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #232323; - color: #e6e1dc; -} - -.hljs-comment, -.hljs-quote { - color: #bc9458; - font-style: italic; -} - -.hljs-keyword, -.hljs-selector-tag { - color: #c26230; -} - -.hljs-string, -.hljs-number, -.hljs-regexp, -.hljs-variable, -.hljs-template-variable { - color: #a5c261; -} - -.hljs-subst { - color: #519f50; -} - -.hljs-tag, -.hljs-name { - color: #e8bf6a; -} - -.hljs-type { - color: #da4939; -} - - -.hljs-symbol, -.hljs-bullet, -.hljs-built_in, -.hljs-builtin-name, -.hljs-attr, -.hljs-link { - color: #6d9cbe; -} - -.hljs-params { - color: #d0d0ff; -} - -.hljs-attribute { - color: #cda869; -} - -.hljs-meta { - color: #9b859d; -} - -.hljs-title, -.hljs-section { - color: #ffc66d; -} - -.hljs-addition { - background-color: #144212; - color: #e6e1dc; - display: inline-block; - width: 100%; -} - -.hljs-deletion { - background-color: #600; - color: #e6e1dc; - display: inline-block; - width: 100%; -} - -.hljs-selector-class { - color: #9b703f; -} - -.hljs-selector-id { - color: #8b98ab; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} - -.hljs-link { - text-decoration: underline; -} diff --git a/doc/html-manual/highlight/styles/rainbow.css b/doc/html-manual/highlight/styles/rainbow.css deleted file mode 100644 index 905eb8ef187..00000000000 --- a/doc/html-manual/highlight/styles/rainbow.css +++ /dev/null @@ -1,85 +0,0 @@ -/* - -Style with support for rainbow parens - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #474949; - color: #d1d9e1; -} - - -.hljs-comment, -.hljs-quote { - color: #969896; - font-style: italic; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-literal, -.hljs-type, -.hljs-addition { - color: #cc99cc; -} - -.hljs-number, -.hljs-selector-attr, -.hljs-selector-pseudo { - color: #f99157; -} - -.hljs-string, -.hljs-doctag, -.hljs-regexp { - color: #8abeb7; -} - -.hljs-title, -.hljs-name, -.hljs-section, -.hljs-built_in { - color: #b5bd68; -} - -.hljs-variable, -.hljs-template-variable, -.hljs-selector-id, -.hljs-class .hljs-title { - color: #ffcc66; -} - -.hljs-section, -.hljs-name, -.hljs-strong { - font-weight: bold; -} - -.hljs-symbol, -.hljs-bullet, -.hljs-subst, -.hljs-meta, -.hljs-link { - color: #f99157; -} - -.hljs-deletion { - color: #dc322f; -} - -.hljs-formula { - background: #eee8d5; -} - -.hljs-attr, -.hljs-attribute { - color: #81a2be; -} - -.hljs-emphasis { - font-style: italic; -} diff --git a/doc/html-manual/highlight/styles/school-book.css b/doc/html-manual/highlight/styles/school-book.css deleted file mode 100644 index 964b51d8414..00000000000 --- a/doc/html-manual/highlight/styles/school-book.css +++ /dev/null @@ -1,72 +0,0 @@ -/* - -School Book style from goldblog.com.ua (c) Zaripov Yura - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 15px 0.5em 0.5em 30px; - font-size: 11px; - line-height:16px; -} - -pre{ - background:#f6f6ae url(./school-book.png); - border-top: solid 2px #d2e8b9; - border-bottom: solid 1px #d2e8b9; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-literal { - color:#005599; - font-weight:bold; -} - -.hljs, -.hljs-subst { - color: #3e5915; -} - -.hljs-string, -.hljs-title, -.hljs-section, -.hljs-type, -.hljs-symbol, -.hljs-bullet, -.hljs-attribute, -.hljs-built_in, -.hljs-builtin-name, -.hljs-addition, -.hljs-variable, -.hljs-template-tag, -.hljs-template-variable, -.hljs-link { - color: #2c009f; -} - -.hljs-comment, -.hljs-quote, -.hljs-deletion, -.hljs-meta { - color: #e60415; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-literal, -.hljs-doctag, -.hljs-title, -.hljs-section, -.hljs-type, -.hljs-name, -.hljs-selector-id, -.hljs-strong { - font-weight: bold; -} - -.hljs-emphasis { - font-style: italic; -} diff --git a/doc/html-manual/highlight/styles/school-book.png b/doc/html-manual/highlight/styles/school-book.png deleted file mode 100644 index 956e9790a0e..00000000000 Binary files a/doc/html-manual/highlight/styles/school-book.png and /dev/null differ diff --git a/doc/html-manual/highlight/styles/solarized-dark.css b/doc/html-manual/highlight/styles/solarized-dark.css deleted file mode 100644 index b4c0da1f786..00000000000 --- a/doc/html-manual/highlight/styles/solarized-dark.css +++ /dev/null @@ -1,84 +0,0 @@ -/* - -Orginal Style from ethanschoonover.com/solarized (c) Jeremy Hull - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #002b36; - color: #839496; -} - -.hljs-comment, -.hljs-quote { - color: #586e75; -} - -/* Solarized Green */ -.hljs-keyword, -.hljs-selector-tag, -.hljs-addition { - color: #859900; -} - -/* Solarized Cyan */ -.hljs-number, -.hljs-string, -.hljs-meta .hljs-meta-string, -.hljs-literal, -.hljs-doctag, -.hljs-regexp { - color: #2aa198; -} - -/* Solarized Blue */ -.hljs-title, -.hljs-section, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #268bd2; -} - -/* Solarized Yellow */ -.hljs-attribute, -.hljs-attr, -.hljs-variable, -.hljs-template-variable, -.hljs-class .hljs-title, -.hljs-type { - color: #b58900; -} - -/* Solarized Orange */ -.hljs-symbol, -.hljs-bullet, -.hljs-subst, -.hljs-meta, -.hljs-meta .hljs-keyword, -.hljs-selector-attr, -.hljs-selector-pseudo, -.hljs-link { - color: #cb4b16; -} - -/* Solarized Red */ -.hljs-built_in, -.hljs-deletion { - color: #dc322f; -} - -.hljs-formula { - background: #073642; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/solarized-light.css b/doc/html-manual/highlight/styles/solarized-light.css deleted file mode 100644 index fdcfcc72c45..00000000000 --- a/doc/html-manual/highlight/styles/solarized-light.css +++ /dev/null @@ -1,84 +0,0 @@ -/* - -Orginal Style from ethanschoonover.com/solarized (c) Jeremy Hull - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #fdf6e3; - color: #657b83; -} - -.hljs-comment, -.hljs-quote { - color: #93a1a1; -} - -/* Solarized Green */ -.hljs-keyword, -.hljs-selector-tag, -.hljs-addition { - color: #859900; -} - -/* Solarized Cyan */ -.hljs-number, -.hljs-string, -.hljs-meta .hljs-meta-string, -.hljs-literal, -.hljs-doctag, -.hljs-regexp { - color: #2aa198; -} - -/* Solarized Blue */ -.hljs-title, -.hljs-section, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #268bd2; -} - -/* Solarized Yellow */ -.hljs-attribute, -.hljs-attr, -.hljs-variable, -.hljs-template-variable, -.hljs-class .hljs-title, -.hljs-type { - color: #b58900; -} - -/* Solarized Orange */ -.hljs-symbol, -.hljs-bullet, -.hljs-subst, -.hljs-meta, -.hljs-meta .hljs-keyword, -.hljs-selector-attr, -.hljs-selector-pseudo, -.hljs-link { - color: #cb4b16; -} - -/* Solarized Red */ -.hljs-built_in, -.hljs-deletion { - color: #dc322f; -} - -.hljs-formula { - background: #eee8d5; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/sunburst.css b/doc/html-manual/highlight/styles/sunburst.css deleted file mode 100644 index f56dd5e9b61..00000000000 --- a/doc/html-manual/highlight/styles/sunburst.css +++ /dev/null @@ -1,102 +0,0 @@ -/* - -Sunburst-like style (c) Vasily Polovnyov - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #000; - color: #f8f8f8; -} - -.hljs-comment, -.hljs-quote { - color: #aeaeae; - font-style: italic; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-type { - color: #e28964; -} - -.hljs-string { - color: #65b042; -} - -.hljs-subst { - color: #daefa3; -} - -.hljs-regexp, -.hljs-link { - color: #e9c062; -} - -.hljs-title, -.hljs-section, -.hljs-tag, -.hljs-name { - color: #89bdff; -} - -.hljs-class .hljs-title, -.hljs-doctag { - text-decoration: underline; -} - -.hljs-symbol, -.hljs-bullet, -.hljs-number { - color: #3387cc; -} - -.hljs-params, -.hljs-variable, -.hljs-template-variable { - color: #3e87e3; -} - -.hljs-attribute { - color: #cda869; -} - -.hljs-meta { - color: #8996a8; -} - -.hljs-formula { - background-color: #0e2231; - color: #f8f8f8; - font-style: italic; -} - -.hljs-addition { - background-color: #253b22; - color: #f8f8f8; -} - -.hljs-deletion { - background-color: #420e09; - color: #f8f8f8; -} - -.hljs-selector-class { - color: #9b703f; -} - -.hljs-selector-id { - color: #8b98ab; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/tomorrow-night-blue.css b/doc/html-manual/highlight/styles/tomorrow-night-blue.css deleted file mode 100644 index 78e59cc8cb0..00000000000 --- a/doc/html-manual/highlight/styles/tomorrow-night-blue.css +++ /dev/null @@ -1,75 +0,0 @@ -/* Tomorrow Night Blue Theme */ -/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ -/* Original theme - https://github.com/chriskempson/tomorrow-theme */ -/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ - -/* Tomorrow Comment */ -.hljs-comment, -.hljs-quote { - color: #7285b7; -} - -/* Tomorrow Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-tag, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class, -.hljs-regexp, -.hljs-deletion { - color: #ff9da4; -} - -/* Tomorrow Orange */ -.hljs-number, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params, -.hljs-meta, -.hljs-link { - color: #ffc58f; -} - -/* Tomorrow Yellow */ -.hljs-attribute { - color: #ffeead; -} - -/* Tomorrow Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet, -.hljs-addition { - color: #d1f1a9; -} - -/* Tomorrow Blue */ -.hljs-title, -.hljs-section { - color: #bbdaff; -} - -/* Tomorrow Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #ebbbff; -} - -.hljs { - display: block; - overflow-x: auto; - background: #002451; - color: white; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/tomorrow-night-bright.css b/doc/html-manual/highlight/styles/tomorrow-night-bright.css deleted file mode 100644 index e05af8ae245..00000000000 --- a/doc/html-manual/highlight/styles/tomorrow-night-bright.css +++ /dev/null @@ -1,74 +0,0 @@ -/* Tomorrow Night Bright Theme */ -/* Original theme - https://github.com/chriskempson/tomorrow-theme */ -/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ - -/* Tomorrow Comment */ -.hljs-comment, -.hljs-quote { - color: #969896; -} - -/* Tomorrow Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-tag, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class, -.hljs-regexp, -.hljs-deletion { - color: #d54e53; -} - -/* Tomorrow Orange */ -.hljs-number, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params, -.hljs-meta, -.hljs-link { - color: #e78c45; -} - -/* Tomorrow Yellow */ -.hljs-attribute { - color: #e7c547; -} - -/* Tomorrow Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet, -.hljs-addition { - color: #b9ca4a; -} - -/* Tomorrow Blue */ -.hljs-title, -.hljs-section { - color: #7aa6da; -} - -/* Tomorrow Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #c397d8; -} - -.hljs { - display: block; - overflow-x: auto; - background: black; - color: #eaeaea; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/tomorrow-night-eighties.css b/doc/html-manual/highlight/styles/tomorrow-night-eighties.css deleted file mode 100644 index 08fd51c742a..00000000000 --- a/doc/html-manual/highlight/styles/tomorrow-night-eighties.css +++ /dev/null @@ -1,74 +0,0 @@ -/* Tomorrow Night Eighties Theme */ -/* Original theme - https://github.com/chriskempson/tomorrow-theme */ -/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ - -/* Tomorrow Comment */ -.hljs-comment, -.hljs-quote { - color: #999999; -} - -/* Tomorrow Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-tag, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class, -.hljs-regexp, -.hljs-deletion { - color: #f2777a; -} - -/* Tomorrow Orange */ -.hljs-number, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params, -.hljs-meta, -.hljs-link { - color: #f99157; -} - -/* Tomorrow Yellow */ -.hljs-attribute { - color: #ffcc66; -} - -/* Tomorrow Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet, -.hljs-addition { - color: #99cc99; -} - -/* Tomorrow Blue */ -.hljs-title, -.hljs-section { - color: #6699cc; -} - -/* Tomorrow Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #cc99cc; -} - -.hljs { - display: block; - overflow-x: auto; - background: #2d2d2d; - color: #cccccc; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/tomorrow-night.css b/doc/html-manual/highlight/styles/tomorrow-night.css deleted file mode 100644 index ddd270a4e76..00000000000 --- a/doc/html-manual/highlight/styles/tomorrow-night.css +++ /dev/null @@ -1,75 +0,0 @@ -/* Tomorrow Night Theme */ -/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ -/* Original theme - https://github.com/chriskempson/tomorrow-theme */ -/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ - -/* Tomorrow Comment */ -.hljs-comment, -.hljs-quote { - color: #969896; -} - -/* Tomorrow Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-tag, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class, -.hljs-regexp, -.hljs-deletion { - color: #cc6666; -} - -/* Tomorrow Orange */ -.hljs-number, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params, -.hljs-meta, -.hljs-link { - color: #de935f; -} - -/* Tomorrow Yellow */ -.hljs-attribute { - color: #f0c674; -} - -/* Tomorrow Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet, -.hljs-addition { - color: #b5bd68; -} - -/* Tomorrow Blue */ -.hljs-title, -.hljs-section { - color: #81a2be; -} - -/* Tomorrow Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #b294bb; -} - -.hljs { - display: block; - overflow-x: auto; - background: #1d1f21; - color: #c5c8c6; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/tomorrow.css b/doc/html-manual/highlight/styles/tomorrow.css deleted file mode 100644 index 026a62fe3be..00000000000 --- a/doc/html-manual/highlight/styles/tomorrow.css +++ /dev/null @@ -1,72 +0,0 @@ -/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ - -/* Tomorrow Comment */ -.hljs-comment, -.hljs-quote { - color: #8e908c; -} - -/* Tomorrow Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-tag, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class, -.hljs-regexp, -.hljs-deletion { - color: #c82829; -} - -/* Tomorrow Orange */ -.hljs-number, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params, -.hljs-meta, -.hljs-link { - color: #f5871f; -} - -/* Tomorrow Yellow */ -.hljs-attribute { - color: #eab700; -} - -/* Tomorrow Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet, -.hljs-addition { - color: #718c00; -} - -/* Tomorrow Blue */ -.hljs-title, -.hljs-section { - color: #4271ae; -} - -/* Tomorrow Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #8959a8; -} - -.hljs { - display: block; - overflow-x: auto; - background: white; - color: #4d4d4c; - padding: 0.5em; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/vs.css b/doc/html-manual/highlight/styles/vs.css deleted file mode 100644 index c5d07d3115d..00000000000 --- a/doc/html-manual/highlight/styles/vs.css +++ /dev/null @@ -1,68 +0,0 @@ -/* - -Visual Studio-like style based on original C# coloring by Jason Diamond - -*/ -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: white; - color: black; -} - -.hljs-comment, -.hljs-quote, -.hljs-variable { - color: #008000; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-built_in, -.hljs-name, -.hljs-tag { - color: #00f; -} - -.hljs-string, -.hljs-title, -.hljs-section, -.hljs-attribute, -.hljs-literal, -.hljs-template-tag, -.hljs-template-variable, -.hljs-type, -.hljs-addition { - color: #a31515; -} - -.hljs-deletion, -.hljs-selector-attr, -.hljs-selector-pseudo, -.hljs-meta { - color: #2b91af; -} - -.hljs-doctag { - color: #808080; -} - -.hljs-attr { - color: #f00; -} - -.hljs-symbol, -.hljs-bullet, -.hljs-link { - color: #00b0e8; -} - - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/highlight/styles/xcode.css b/doc/html-manual/highlight/styles/xcode.css deleted file mode 100644 index 43dddad84d7..00000000000 --- a/doc/html-manual/highlight/styles/xcode.css +++ /dev/null @@ -1,93 +0,0 @@ -/* - -XCode style (c) Angel Garcia - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #fff; - color: black; -} - -.hljs-comment, -.hljs-quote { - color: #006a00; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-literal { - color: #aa0d91; -} - -.hljs-name { - color: #008; -} - -.hljs-variable, -.hljs-template-variable { - color: #660; -} - -.hljs-string { - color: #c41a16; -} - -.hljs-regexp, -.hljs-link { - color: #080; -} - -.hljs-title, -.hljs-tag, -.hljs-symbol, -.hljs-bullet, -.hljs-number, -.hljs-meta { - color: #1c00cf; -} - -.hljs-section, -.hljs-class .hljs-title, -.hljs-type, -.hljs-attr, -.hljs-built_in, -.hljs-builtin-name, -.hljs-params { - color: #5c2699; -} - -.hljs-attribute, -.hljs-subst { - color: #000; -} - -.hljs-formula { - background-color: #eee; - font-style: italic; -} - -.hljs-addition { - background-color: #baeeba; -} - -.hljs-deletion { - background-color: #ffc8bd; -} - -.hljs-selector-id, -.hljs-selector-class { - color: #9b703f; -} - -.hljs-doctag, -.hljs-strong { - font-weight: bold; -} - -.hljs-emphasis { - font-style: italic; -} diff --git a/doc/html-manual/highlight/styles/xt256.css b/doc/html-manual/highlight/styles/xt256.css deleted file mode 100644 index 58df82cb751..00000000000 --- a/doc/html-manual/highlight/styles/xt256.css +++ /dev/null @@ -1,92 +0,0 @@ - -/* - xt256.css - - Contact: initbar [at] protonmail [dot] ch - : github.com/initbar -*/ - -.hljs { - display: block; - overflow-x: auto; - color: #eaeaea; - background: #000; - padding: 0.5; -} - -.hljs-subst { - color: #eaeaea; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} - -.hljs-builtin-name, -.hljs-type { - color: #eaeaea; -} - -.hljs-params { - color: #da0000; -} - -.hljs-literal, -.hljs-number, -.hljs-name { - color: #ff0000; - font-weight: bolder; -} - -.hljs-comment { - color: #969896; -} - -.hljs-selector-id, -.hljs-quote { - color: #00ffff; -} - -.hljs-template-variable, -.hljs-variable, -.hljs-title { - color: #00ffff; - font-weight: bold; -} - -.hljs-selector-class, -.hljs-keyword, -.hljs-symbol { - color: #fff000; -} - -.hljs-string, -.hljs-bullet { - color: #00ff00; -} - -.hljs-tag, -.hljs-section { - color: #000fff; -} - -.hljs-selector-tag { - color: #000fff; - font-weight: bold; -} - -.hljs-attribute, -.hljs-built_in, -.hljs-regexp, -.hljs-link { - color: #ff00ff; -} - -.hljs-meta { - color: #fff; - font-weight: bolder; -} diff --git a/doc/html-manual/highlight/styles/zenburn.css b/doc/html-manual/highlight/styles/zenburn.css deleted file mode 100644 index 07be502016b..00000000000 --- a/doc/html-manual/highlight/styles/zenburn.css +++ /dev/null @@ -1,80 +0,0 @@ -/* - -Zenburn style from voldmar.ru (c) Vladimir Epifanov -based on dark.css by Ivan Sagalaev - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #3f3f3f; - color: #dcdcdc; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-tag { - color: #e3ceab; -} - -.hljs-template-tag { - color: #dcdcdc; -} - -.hljs-number { - color: #8cd0d3; -} - -.hljs-variable, -.hljs-template-variable, -.hljs-attribute { - color: #efdcbc; -} - -.hljs-literal { - color: #efefaf; -} - -.hljs-subst { - color: #8f8f8f; -} - -.hljs-title, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class, -.hljs-section, -.hljs-type { - color: #efef8f; -} - -.hljs-symbol, -.hljs-bullet, -.hljs-link { - color: #dca3a3; -} - -.hljs-deletion, -.hljs-string, -.hljs-built_in, -.hljs-builtin-name { - color: #cc9393; -} - -.hljs-addition, -.hljs-comment, -.hljs-quote, -.hljs-meta { - color: #7f9f7f; -} - - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/html-manual/hwsw-inputs.shtml b/doc/html-manual/hwsw-inputs.shtml deleted file mode 100644 index 9a63293ff4f..00000000000 --- a/doc/html-manual/hwsw-inputs.shtml +++ /dev/null @@ -1,106 +0,0 @@ - - - - - - -

CPROVER Manual TOC

- -

Hardware and Software Equivalence and Co-Verification

- -

Synchronizing Inputs

- -

Driving Primary Inputs

- -

-The examples in the tutorial are trivial -in the sense that the model has only one possible trace. The -initial state is deterministic, and there is only one possible transition, -so the verification problem can be solved by testing a single run. In contrast, -consider the following Verilog module: -

- -
module top(input clk, input i);
-
-  reg [3:0] counter;
-
-  initial counter=0;
-
-  always @(posedge clk)
-    if(i)
-      counter=counter+1;
-
-endmodule
-
- -

-The module above has an input named i. The top-level inputs -of the Verilog design have to be generated by the C program. -This is done by assigning the desired values to the corresponding struct -member, and then calling the set_inputs() function -before calling next_timeframe(). -Consider the following example: -

- -
void next_timeframe();
-void set_inputs();
-extern const unsigned int bound;
-
-struct module_top {
-  unsigned int counter;
-  _Bool i;
-};
-
-extern struct module_top top;
-
-int main() {
-  assert(top.counter==0);
-
-  top.i=1;
-  set_inputs(); next_timeframe();
-  assert(top.counter==1);
-
-  top.i=1;
-  set_inputs(); next_timeframe();
-  assert(top.counter==2);
-
-  top.i=0;
-  set_inputs(); next_timeframe();
-  assert(top.counter==2);
-}
-
- -

-As an example, consider a -Verilog module that has a signal reset as an input, which is -active-low. The following C fragment drives this input to be active in the -first cycle, and not active in any subsequent cycle: -

- -
  top.resetn=0;
-  set_inputs(); next_timeframe();
-
-  for(i=1; i<bound; i++) {
-    top.resetn=1;
-    set_inputs(); next_timeframe();
-  }
-
- -

-Note that the value of the input must be set before -calling next_timeframe(). The effect of the -input values on values derived in a combinatorial way -is immediately visible. The effect on clocked values -becomes visible in the next time frame. -

- -

Using Nondeterminism

- -

-The examples above use particular, constant values to drive the primary -inputs. In order to check the behavior of the Verilog model for more than -one specific input, use nondeterminism. -

- - - diff --git a/doc/html-manual/hwsw-mapping.shtml b/doc/html-manual/hwsw-mapping.shtml deleted file mode 100644 index c206ca753ea..00000000000 --- a/doc/html-manual/hwsw-mapping.shtml +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - -

CPROVER Manual TOC

- -

Hardware and Software Equivalence and Co-Verification

- -

Mapping Variables

- -

Mapping Variables within the Module Hierarchy

- -

-Verilog modules are hierarchical. The extern declarations shown above -only allow reading the values of signals and registers that are in the top -module. In order to read values from sub-modules, CBMC uses structures. -

- -

-As an example, consider the following Verilog file -(hierarchy.v): -

- -
module counter(input clk, input [7:0] increment);
-
-  reg [7:0] counter;
-
-  initial counter=0;
-
-  always @(posedge clk)
-    counter=counter+increment;
-
-endmodule
-
-module top(input clk);
-
-  counter c1(clk, 1);
-  counter c2(clk, 2);
-
-endmodule
-
- -

-The file has two modules: a top module and a counter module. The counter -module is instantiated twice within the top module. A reference to the -register counter within the C program would be ambiguous, as the two -module instances have separate instances of the register. CBMC and SATABS -use the following data structures for this example: -

- -
void next_timeframe();
-extern const unsigned int bound;
-
-struct counter {
-  unsigned char increment;
-  unsigned char counter;
-};
-
-struct module_top {
-  struct module_counter c1, c2;
-};
-
-extern struct module_top top;
-
-int main() {
-  next_timeframe();
-  next_timeframe();
-  next_timeframe();
-  assert(top.c1.counter==3);
-  assert(top.c2.counter==6);
-}
-
- -

-The main function reads both counter values for cycle 3. A deeper -hierarchy (modules in modules) is realized by using additional structure -members. Writing these data structures for large Verilog designs is error -prone, and thus, HW-CBMC can generate them automatically. The declarations -above are generated using the command line -

- -
- -hw-cbmc --gen-interface --module top hierarchy.v - -
- -

Mapping Verilog Vectors to Arrays or Scalars

- -

-In Verilog, a definition such as -

- - -  wire [31:0] x; - - -

-can be used for arithmetic (as in x+10) and as array of Booleans -(as in x[2]). ANSI-C does not allow both, so when mapping variables -from Verilog to C, the user has to choose one option for each such variable. -As an example, the C declaration -

- - -  unsigned int x; - - -

-will allow using x in arithmetic expressions, while the C declaration -

- - -  __CPROVER_bool x[32]; - - -

-will allow accessing the individual bits of x using the syntax -x[bit]. The --gen-interface option of HW-CBMC -will generate the first variant if the vector has the same size as one of -the standard integer types, and will use the __CPROVER_bitvector[] type if -not so. This choice can be changed by adjusting the declaration -accordingly. Note that both SpecC and SystemC offer bit-extraction -operators, which means that it unnecessary to use the declaration as array -in order to access individual bits of a vector. -

- - - diff --git a/doc/html-manual/hwsw-tutorial.shtml b/doc/html-manual/hwsw-tutorial.shtml deleted file mode 100644 index 926264d81bf..00000000000 --- a/doc/html-manual/hwsw-tutorial.shtml +++ /dev/null @@ -1,220 +0,0 @@ - - - - - - -

CPROVER Manual TOC

- -

Hardware and Software Equivalence and Co-Verification

- -

A Small Tutorial

- -

Verilog vs. ANSI-C

- -

-We assume that CBMC is installed on your system. If not so, follow -these instructions.

- -

-The following Verilog module implements a 4-bit counter -(counter.v): -

- -
module top(input clk);
-
-  reg [3:0] counter;
-
-  initial counter=0;
-
-  always @(posedge clk)
-    counter=counter+1;
-
-endmodule
-
- -

-HW-CBMC can take Verilog modules as the one above as additional input. Similar -as in co-simulation, the data in the Verilog modules is available to the C -program by means of global variables. For the example above, the following C -fragment shows the definition of the variable that holds the value -of the counter register: -

- -
struct module_top {
-  unsigned int counter;
-};
-
-extern struct module_top top;
-
- -

-Using this definition, the value of the counter register in the -Verilog fragment above can be accessed as top.counter. Please note -that the name of the variable must match the name of the top module. -The C program only has a view of one state of the Verilog model. The Verilog -model makes a transition once the function next_timeframe() is -called. -

- -

-As CBMC performs Bounded Model Checking, the number of timeframes available -for analysis must be bounded (SATABS -has no such restriction). As it is -desirable to change the bound to adjust it to the available computing -capacity, the bound is given on the command line and not as part of the C -program. This makes it easy to use only one C program for arbitrary bounds. -The actual bound is available in the C program using the following -declaration: -

- - -extern const unsigned int bound; - - -

-Also note that the fragment above declares a constant variable of struct -type. Thus, the C program can only read the trace values and is not able to -modify them. We will later on describe how to drive inputs of the Verilog -module from within the C program. -

- -

-As described in previous chapters, assertions can be used to verify -properties of the Verilog trace. As an example, the following program checks -two values of the trace of the counter module -(counter.c): -

- -
void next_timeframe();
-
-struct module_top {
-  unsigned int counter;
-};
-
-extern struct module_top top;
-
-int main() {
-  next_timeframe();
-  next_timeframe();
-  assert(top.counter==2);
-  next_timeframe();
-  assert(top.counter==3);
-}
-
- -

-The following CBMC command line checks these assertions with a bound of -20: -

- -
- -hw-cbmc counter.c counter.v --module top --bound 20 - -
- -

-Note that a specific version of CBMC is used, called hw-cbmc. -The module name given must match the name of the module in the Verilog -file. Multiple Verilog files can be given on the command line. -

- -

-The --bound parameter is not to be confused with the --unwind -parameter. While the --unwind parameter specifies the maximum -unwinding depth for loops within the C program, the --bound parameter -specifies the number of times the transition relation of the Verilog module -is to be unwound. -

- -

Counterexamples

- -

-For the given example, the verification is successful. If the first -assertion is changed to -

- - -  assert(top.counter==10); - - -

-and the bound on the command line is changed to 6, CBMC will produce a -counterexample. CBMC produces two traces: One for the C program, which -matches the traces described earlier, and a separate trace for the Verilog -module. The values of the registers in the Verilog module are also shown in -the C trace as part of the initial state. -

- - -Initial State
-----------------------------------------------------
-  bound=6 (00000000000000000000000000000110)
-  counter={ 0, 1, 2, 3, 4, 5, 6 }
-
-Failed assertion: assertion line 6 function main
-
-Transition system state 0
-----------------------------------------------------
-  counter=0 (0000)
-
-Transition system state 1
-----------------------------------------------------
-  counter=1 (0001)
-
-Transition system state 2
-----------------------------------------------------
-  counter=2 (0010)
-
-Transition system state 3
-----------------------------------------------------
-  counter=3 (0011)
-
-Transition system state 4
-----------------------------------------------------
-  counter=4 (0100)
-
-Transition system state 5
-----------------------------------------------------
-  counter=5 (0101)
-
-Transition system state 6
-----------------------------------------------------
-  counter=6 (0110) -
- -

Using the Bound

- -

-The following program is using the bound variable to check the counter value -in all cycles: -

- -
void next_timeframe();
-extern const unsigned int bound;
-
-struct module_top {
-  unsigned int counter;
-};
-
-extern struct module_top top;
-
-int main() {
-  unsigned cycle;
-
-  for(cycle=0; cycle<bound; cycle++) {
-    assert(top.counter==(cycle & 15));
-    next_timeframe();
-  }
-}
-
- -

-CBMC performs bounds checking, and restricts the number of times that -next_timeframe() can be called. SATABS does not re­quire a bound, -and thus, next_timeframe() can be called arbitrarily many times. -

- - - diff --git a/doc/html-manual/hwsw.shtml b/doc/html-manual/hwsw.shtml deleted file mode 100644 index 298b78f9a08..00000000000 --- a/doc/html-manual/hwsw.shtml +++ /dev/null @@ -1,117 +0,0 @@ - - -

CPROVER Manual TOC

- -

Hardware and Software Equivalence and Co-Verification

- -

Introduction

- -

-A common hardware design approach employed by many companies is to first -write a quick prototype that behaves like the planned circuit in a language -like ANSI-C. This program is then used for extensive testing and debugging, -in particular of any embedded software that will later on be shipped with -the circuit. An example is the hardware of a cell phone and its software. -After testing and debugging of the program, the actual hardware design is -written using hardware description languages like -VHDL or -Verilog. -

- -

-Thus, there are two implementations of the same design: one written in -ANSI-C, which is written for simulation, and one written in register -transfer level HDL, which is the actual product. The ANSI-C implementation -is usually thoroughly tested and debugged. -

- -

-Due to market constraints, companies aim to sell the chip as soon as -possible, i.e., shortly after the HDL implementation is designed. There is -usually little time for additional debugging and testing of the HDL -implementation. Thus, an automated, or nearly automated way of establishing -the consistency of the HDL implementation is highly desirable. -

- -

-This motivates the verification problem: we want to verify the consistency -of the HDL implementation, i.e., the product, - -using the ANSI-C implementation as a reference. Es­ta­bli­shing the consistency -does not re­quire a formal specification. However, formal methods to verify -either the hardware or software design are still desirable. -

- -

Related Work

- -

-There have been several attempts in the past to tackle the problem. - -Semeria et al. describe a tool for verifying the combinational equivalence of -RTL-C and an HDL. They translate the C code into HDL and use -standard equivalence checkers to establish the equivalence. The C code has -to be very close to a hardware description (RTL level), which implies that -the source and target have to be implemented in a very similar way. There -are also variants of C specifically for this purpose. The SystemC standard defines a -subset of C++ that can be used for synthesis. Further -variants of ANSI-C for specifying hardware are SpecC and Handel C, among -others.

- -

-The concept of verifying the equivalence of a software implementation and a -synchronous transition system was introduced by -Pnueli, Siegel, and -Shtrichman. The C program is re­quired to be in a very -specific form, since a mechanical translation is assumed. -

- -

-In 2000, -Currie, Hu, and Rajan transform DSP assembly language -into an equation for the Stanford Validity Checker. -The symbolic execution of programs for comparison with RTL is now -common practice. -

- -

-The previous work focuses on a small subset of ANSI-C that is particularly -close to register transfer language. Thus, the designer is often re­quired to -rewrite the C program manually in order to comply with these constraints. We -extend the methodology to handle the full set of ANSI-C language features. -This is a challenge in the presence of complex, dynamic data structures and -pointers that may dynamically point to multiple objects. Furthermore, our -methodology allows arbitrary loop constructs. -

- -

Further Material

- -

We provide a small -tutorial and a description on -how to synchronize inputs between the C model and the Verilog model. -There is also a collection of -benchmark problems available. -

- -
-
Further Reading
- -

-

-

- - - diff --git a/doc/html-manual/index.shtml b/doc/html-manual/index.shtml deleted file mode 100644 index 1e5690411fc..00000000000 --- a/doc/html-manual/index.shtml +++ /dev/null @@ -1,62 +0,0 @@ - - -

Table of Contents

- -

1. Introduction

- -

2. Installation

-

-CBMC, -SATABS, -Eclipse plugin -

- -

3. CBMC – Bounded Model Checking

- -

-A Short Tutorial, -Loop Unwinding, -Test Suite Generation -

- -

4. SATABS – Predicate Abstraction -with SAT

- -

-Introduction, -Background, -Tutorials -

- -

5. Modeling

- -

-Nondeterminism, -Assumptions and Assertions, -Pointers, -Floating Point -

- -

6. Hardware/Software Co-Verification

- -

-Introduction, -Tutorial, -Mapping Variables, -Synchronizing Inputs -

- -

7. Build Systems, Libraries and Instrumentation

- -

-Introduction, -Integration into Build Systems with goto-cc, -Visual Studio Builds, -Variants of goto-cc, -Architectural Settings, -Property Instrumentation -with goto-instrument, -The CPROVER API Reference -

- - diff --git a/doc/html-manual/installation-cbmc.shtml b/doc/html-manual/installation-cbmc.shtml deleted file mode 100644 index 2ee1a8df0ea..00000000000 --- a/doc/html-manual/installation-cbmc.shtml +++ /dev/null @@ -1,80 +0,0 @@ - - -

CPROVER Manual TOC

- -

Installing CBMC

- -

Requirements

- -

-CBMC is available for Windows, i86 Linux, and MacOS X. -CBMC requires a code pre-processing environment comprising of a -suitable preprocessor and an a set of header files.

- -
    - -
  1. -Linux: the preprocessor and the header files typically come with a -package called gcc, which must be installed prior to the installation -of CBMC. -

  2. - -
  3. -Windows: The Windows version of CBMC requires the preprocessor -cl.exe, which is part of Microsoft Visual Studio. We recommend -the free Visual -Studio Community 2013. -

  4. - -
  5. -MacOS: Install the -XCode Command Line Utilities -prior to installing CBMC. Just installing XCode alone is not enough. -

  6. - -
- -

-Important note for Windows users: Visual Studio's -cl.exe relies on a -complex set of environment variables to identify the target architecture and -the directories that contain the header files. -You must run CBMC -from within the Visual Studio Command Prompt. -

- -

-Note that the distribution files for the -Eclipse plugin include the -CBMC executable. Therefore, if you intend to run CBMC -exclusively within Eclipse, you can skip the installation of the -CBMC executable. However, you still have to install the compiler -environment as described above.

- -

Installing the CBMC Binaries

- -
    -
  1. Download CBMC for your operating system. -The binaries are available from -http://www.cprover.org/cbmc/. -
  2. - -
  3. Unzip/untar the archive into a directory of your choice. -We recommend to add this directory to your PATH environment -variable.
  4. - -
- -

-You are now ready to use CBMC!

- -

Building CBMC from Source

- -

-Alternatively, the CBMC source code is available via SVN. -To compile the source code, follow -these instructions. -

- - - diff --git a/doc/html-manual/installation-plugin.shtml b/doc/html-manual/installation-plugin.shtml deleted file mode 100644 index 39e32cfe1b1..00000000000 --- a/doc/html-manual/installation-plugin.shtml +++ /dev/null @@ -1,42 +0,0 @@ - - -

CPROVER Manual TOC

- -

Installing the Eclipse Plugin

- -

Requirements

- -

-We provide a graphical user interface to CBMC and SATABS, which is -realized as a plugin to the Eclipse framework. Eclipse is available at http://www.eclipse.org. We do not provide -installation instructions for Eclipse (basically, you only have to download -the current version and extract the files to your hard-disk) and assume that -you have already installed the current version.

- -

-CBMC and SATABS have their own requirements. As an example, both CBMC -and SATABS require a suitable preprocessor and a set of header files. As -first step, you should therefore follow the installation instructions for CBMC and SATABS. - -

-Important note for Windows users: Visual Studio's -cl.exe relies on a -complex set of environment variables to identify the target architecture and -the directories that contain the header files. -You must run Eclipse from within the -Visual Studio Command Prompt. -

- -

Installing the Eclipse Plugin

- -

-The installation instructions for the Eclipse Plugin, including the -link to the download site, are available -here. This includes a small tutorial on how to use the Eclipse plugin. -

- - - diff --git a/doc/html-manual/installation-satabs.shtml b/doc/html-manual/installation-satabs.shtml deleted file mode 100644 index 46ca303bd6c..00000000000 --- a/doc/html-manual/installation-satabs.shtml +++ /dev/null @@ -1,139 +0,0 @@ - - -

CPROVER Manual TOC

- -

Installing SATABS

- -

Requirements

- -

-SATABS is available for Windows, i86 Linux, and MacOS X. -SATABS requires a code pre-processing environment comprising of a -suitable preprocessor and an a set of header files.

- -
    - -
  1. Linux: the preprocessor and the header files typically come with a -package called gcc, which must be installed prior to the installation -of SATABS.
  2. - -
  3. Windows: The Windows version of SATABS requires the preprocessor -cl.exe, which is part of Visual Studio (including -the free Visual -Studio Express).
  4. - -
  5. MacOS: Install XCode -prior to installing SATABS.
  6. - -
- -

-Important note for Windows users: Visual Studio's -cl.exe relies on a -complex set of environment variables to identify the target architecture and -the directories that contain the header files. -You must run SATABS -from within the Visual Studio Command Prompt. -

- -

-Note that the distribution files for the -Eclipse plugin include the -command-line tools. Therefore, if you intend to run SATABS -exclusively within Eclipse, you can skip the installation of the -command-line tools. However, you still have to install the compiler -environment as described above.

- -

Choosing and Installing a Model Checker

- -You need to install a Model Checker in order to be able -to run SATABS. You can choose between following alternatives: -
    -
  • -Cadence SMV. -Available from -http://www.kenmcmil.com/smv.html. -Cadence SMV is a commercial model checker. The free version -that is available on the homepage above must not be used for -commercial purposes (read the license agreement thoroughly -before you download the tool). -The documentation for SMV can be found in the directory where -you unzip/untar SMV under ./smv/doc/smv/. Read the installation -instructions carefully. The Linux/MacOS versions require -setting environment variables. You must add -add the directory containing the smv binary -(located in ./smv/bin/, relative to the path where you -unpacked it) to your PATH environment variable. -SATABS uses Cadence SMV by default.

    -
  • - -
  • -NuSMV. Available from -http://nusmv.irst.itc.it/. -NuSMV is the open source alternative to Cadence SMV. Installation -instructions and documentation can be found on the NuSMV homepage. -The directory containing the NuSMV binary should be added -to your PATH environment variable. -Use the option

    - -
    ---modelchecker nusmv -
    - -

    -to instruct SATABS to use NuSMV.

    -
  • - -
  • -BOPPO. Available from -http://www.cprover.org/boppo/. -BOPPO is a model checker that uses SAT-solving algorithms. -BOPPO relies on a built-in SAT solver and Quantor, a solver -for quantified boolean formulas that is currently bundled -with BOPPO, but also available separately from -http://fmv.jku.at/quantor/. -We recommend to add the directories containing both tools to your -PATH environment variable. -Use the option

    - -
    ---modelchecker boppo -
    - -

    -when you call SATABS and want it to use BOPPO instead of SMV. -

    -
  • - -
  • -BOOM. Available from -http://www.cprover.org/boom/. Boom has a number of unique features, -including the verification of programs with unbounded thread creation. -

    -
  • - -
- -

Installing SATABS

- -
    -
  1. Download SATABS for your operating system. -The binaries are available from -http://www.cprover.org/satabs/. -
  2. - -
  3. Unzip/untar the archive into a directory of your choice. -We recommend to add this directory to your PATH environment -variable.
  4. - -
- -

-Now you can execute SATABS. Try running SATABS -on the small examples presented in the -tutorial section. If you use the Cadence SMV model checker, the only -command line arguments you have to specify are the names -of the files that contain your program. -

- - diff --git a/doc/html-manual/introduction.shtml b/doc/html-manual/introduction.shtml deleted file mode 100644 index 49d3af2b818..00000000000 --- a/doc/html-manual/introduction.shtml +++ /dev/null @@ -1,164 +0,0 @@ - - -

CPROVER Manual TOC

- -

Introduction

- -

Motivation

- -

-Numerous tools to hunt down functional design flaws in silicon have -been available for many years, mainly due to the enormous cost of hardware -bugs. The use of such tools is wide-spread. In contrast, the market -for tools that address the need for quality software is still in its -infancy.

- -

-Research in software quality has an enormous breadth. -We focus the presentation using two criteria:

- -
    - -
  1. -We believe that any form of quality requires a specific -guarantee, in theory and practice.
  2. - -
  3. The sheer size of software designs requires techniques that -are highly automated.
  4. - -
- -

-In practice, quality guarantees usually do not refer to "total -correctness" of a design, as ensuring the absence of all bugs is too -expensive for most applications. In contrast, a guarantee of the -absence of specific flaws is achievable, and is a good metric of -quality.

- -

-We document two programs that try to achieve formal guarantees of -the absence of specific problems: CBMC and SATABS. The algorithms -implemented by CBMC and SATABS are complementary, and often, one tool -is able to solve a problem that the other cannot solve.

- -

-Both CBMC and SATABS are verification tools for ANSI-C/C++ programs. They -verify array bounds (buffer overflows), pointer safety, exceptions and -user-specified assertions. Both tools model integer arithmetic accurately, -and are able to reason about machine-level artifacts such as integer -overflow. CBMC and SATABS are therefore able to detect a class of bugs that -has so far gone unnoticed by many other verification tools. This manual -also covers some variants of CBMC, which includes HW-CBMC -for hardware/software co-verification.

- -

Bounded Model Checking with CBMC

- -

-CBMC implements a technique called Bounded Model Checking (BMC). In -BMC, the transition relation for a complex state machine and its -specification are jointly unwound to obtain a Boolean formula, which is then -checked for satisfiability by using an efficient SAT procedure. If the -formula is satisfiable, a counterexample is extracted from the output of the -SAT procedure. If the formula is not satisfiable, the program can be unwound -more to determine if a longer counterexample exists.

- -

-In many engineering domains, real-time guarantees are a strict requirement. -An example is software embedded in automotive controllers. As a consequence, -the loop constructs in these types of programs often have a strict bound -on the number of iterations. CBMC is able to formally verify such bounds -by means of unwinding assertions. Once this bound is established, -CBMC is able to prove the absence of errors.

- -

-A more detailed description of how to apply CBMC verify programs is -here.

- -

Automatic Program Verification with SATABS

- -

-In many cases, lightweight properties such as array bounds do not rely on -the entire program. A large fraction of the program is irrelevant to -the property. SATABS exploits this observation and computes an -abstraction of the program in order to handle large amounts of code. -

- -

-In order to use SATABS it is not necessary to understand the abstraction -refinement process. For the interested reader, a high-level introduction -to abstraction refinement is provided -here. We also provide -tutorials on how to use SATABS. -

- -

-Just as CBMC, SATABS attempts to build counterexamples that refute the -property. If such a counterexample is found, it is presented to the engineer -to facilitate localization and repair of the program. -

- -
-
Example: Buffer Overflows
- -

-In order to give a brief overview of the capabilities of CBMC and SATABS we -start with a small example. -The issue of buffer -overflows has obtained wide public attention. A -buffer is a contiguously-allocated chunk of memory, represented by an array or -a pointer in C. Programs written in C do not provide automatic bounds -checking on the buffer, which means a program can – accidentally or -maliciously – write past a buffer. The following example is a perfectly -valid C program (in the sense that a compiler compiles it without any -errors):

- - -int main() {
-  int buffer[10];
-  buffer[20] = 10;
-}
- -

-However, the write access to an address outside the allocated memory -region can lead to unexpected behavior. In particular, such bugs can be -exploited to overwrite the return address of a function, thus enabling the -execution of arbitrary user-induced code. CBMC and SATABS are able to -detect this problem and reports that the "upper bound property" of the -buffer is violated. CBMC and SATABS are capable of checking these lower and -upper bounds, even for arrays with dynamic size. A detailed discussion -of the properties that CBMC and SATABS can check automatically -is here.

-
- -

Hardware/Software Co-Verification

- -

-Software programs often interact with hardware in a non-trivial manner, and -many properties of the overall design only arise from the interplay of both -components. CBMC and SATABS therefore support Co-Verification, -i.e., are able to reason about a C/C++ program together with a circuit -description given in Verilog.

- -

-These co-verification capabilities can also be applied to perform refinement -proofs. Software programs are often used as high-level descriptions of -circuitry. While both describe the same functionality, the hardware -implementation usually contains more detail. It is highly desirable to -establish some form for equivalence between the two descriptions. -Hardware/Software co-verification and equivalence checking with CBMC and -SATABS are described here. -

- - - - - diff --git a/doc/html-manual/libraries.shtml b/doc/html-manual/libraries.shtml deleted file mode 100644 index 7ea2fe1bff3..00000000000 --- a/doc/html-manual/libraries.shtml +++ /dev/null @@ -1,54 +0,0 @@ - - -

CPROVER Manual TOC

- -

Build Systems and Libraries

- -

The Problem

- -

-Similar to unit testing, the model checking approach requires -the user to clearly define what parts of the program should -be tested and what the behavior of these parts is. -This requirement has following reasons: -

- -
    - -
  • Despite recent advances, the size of the programs that - model checkers can cope with is still restricted. -

  • - -
  • Typically, you want to verify your program and - not the libraries or the operating that it uses (the correctness of these - libraries and the OS us usually addressed separately). -

  • - -
  • CBMC and SATABS cannot verify binary libraries. -

  • - -
  • CBMC and SATABS does not provide a - model for the hardware - (e.g., hard disk, input/output devices) the tested program - runs on. Since CBMC and SATABS are supposed to examine the - behavior of the tested program for all possible inputs - and outputs, it is reasonable to model input and output - by means of non-deterministic choice. -

  • - -
- -

Further Reading

- -

-Existing software projects usually do not come in a single source file that -may simply be passed to a model checker, but is a collection of files held -together by a build system. The ex­trac­tion of models from such -a build system using goto-cc is described here. -The ap­pli­ca­tion of goto-cc to the entire Linux kernel is described -here. The problem of architectural -pa­ram­e­ters (word with, endianness) is explained -here. -

- - diff --git a/doc/html-manual/modeling-assertions.shtml b/doc/html-manual/modeling-assertions.shtml deleted file mode 100644 index d85909a6795..00000000000 --- a/doc/html-manual/modeling-assertions.shtml +++ /dev/null @@ -1,152 +0,0 @@ - - - - - - -

CPROVER Manual TOC

- -

Modeling with Assertions and Assumptions

- -

Assertions

- -

Assertions -are statements within the program that attempt to capture the programmer's -intent. The ANSI-C standard defines a header file assert.h, which offers a -macro assert(cond). When executing a statement such -as

- -
  assert(p!=NULL);
-
- -

the execution is aborted with an error message if the -condition evaluates to false, i.e., if p is NULL in the -example above. The CPROVER tools can check the validity of the -programmer-annotated assertions statically. Specifically, the CPROVER tools -will check that the assertions hold for any nondeterministic choice -that the program can make. The static assertion checks can be disabled -using the --no-assertions command line option.

- -

In addition, there is a CPROVER-specific way -to specify assertions, using the built-in function __CPROVER_assert:

- -
  __CPROVER_assert(p!=NULL, "p is not NULL");
-
- -

The (mandatory) string that is passed as the -second argument provides an informal description of the assertion. -It is shown in the list of properties together with the condition.

- -

The assertion language of the CPROVER tools is -identical to the language used for expressions. Note that nondeterminism can be exploited in order -to check a range of choices. As an example, the following code fragment -asserts that all elements of the array are zero: -

- -
  int a[100], i;
-
-  ...
-
-  i=nondet_uint();
-  if(i>=0 && i<100)
-    assert(a[i]==0);
-
- -

The nondeterministic choice will guess the -element of the array that is nonzero. The code fragment above -is therefore equivalent to -

- -
  int a[100], i;
-
-  ...
-
-  for(i=0; i<100; i++)
-    assert(a[i]==0);
-
- -

Future CPROVER releases will -support explicit quantifiers with a syntax that resembles Spec#: -

- - -
-__CPROVER_forall { type identifier ; expression }
-__CPROVER_exists { type identifier ; expression } -
-
- -

Assumptions

- -

Assumptions are used to restrict nondeterministic -choices made by the program. As an example, suppose we wish to model -a nondeterministic choice that returns a number from 1 to 100. There -is no integer type with this range. We therefore use __CPROVER_assume -to restrict the range of a nondeterministically chosen integer:

- -
unsigned int nondet_uint();
-
-unsigned int one_to_hundred()
-{
-  unsigned int result=nondet_uint();
-  __CPROVER_assume(result>=1 && result<=100);
-  return result;
-}
- -

The function above returns the desired integer from 1 -to 100. You must ensure that the condition given as -an assumption is actually satisfiable by some nondeterministic choice, or -otherwise the model checking step will pass vacuously.

- -

Also note that assumptions are never retroactive: They -only affect assertions (or other properties) that follow them in program -order. This is best illustrated with an example. In the following fragment, -the assumption has no effect on the assertion, which means that -the assertion will fail: -

- -
  x=nondet_uint();
-  assert(x==100);
-  __CPROVER_assume(x==100);
-
- -

-Assumptions do restrict the search space, but only for assertions that follow. -As an example, the following program will pass:

- -
int main() {
-  int x;
-
-  __CPROVER_assume(x>=1 && x<=100000);
-
-  x*=-1;
-
-  __CPROVER_assert(x<0, "x is negative");
-}
-
- -

Beware that nondeterminism cannot be used to obtain -the effect of universal quantification in assumptions. As an example, -

- -
int main() {
-  int a[10], x, y;
-
-  x=nondet_int();
-  y=nondet_int();
-  __CPROVER_assume(x>=0 && x<10 && y>=0 && y<10);
-
-  __CPROVER_assume(a[x]>=0);
-
-  assert(a[y]>=0);
-}
-
- -

fails, as there is a choice of x and y which -results in a counterexample (any choice in which x and y are different). -

- - diff --git a/doc/html-manual/modeling-floating-point.shtml b/doc/html-manual/modeling-floating-point.shtml deleted file mode 100644 index 8c0cdbeec41..00000000000 --- a/doc/html-manual/modeling-floating-point.shtml +++ /dev/null @@ -1,140 +0,0 @@ - - -

CPROVER Manual TOC

- -

Floating Point

- -

The CPROVER tools support bit-accurate reasoning about - IEEE-754 floating-point and fixed-point arithmetic. The C standard - contains a number of areas of implementation-defined behaviour with regard - to floating-point arithmetic:

- -
    - -
  • - CPROVER supports C99 Appendix F, and thus, - the __STD_IEC_559__ macro is defined. This means that - the C float data type maps to IEEE - 754 binary32 and double maps - to binary64 and operations on them are as specified in - IEEE 754.

  • - -
  • - long double can be configured to - be binary64, binary128 (quad precision) or - a 96 bit type with 15 exponent bits and 80 significant bits. The - last is an approximation of Intel's x87 extended precision double data - type. As the C standard allows a implementations a fairly wide set - of options for long double, it is best avoided for both - portable code and bit-precise analysis. The default is to match the - build architecture as closely as possible. -

  • - -
  • - In CPROVER, floating-point expressions are evaluated at the - 'natural precision' (the greatest of the arguments) and not at a - higher precision. This corresponds to FLT_EVAL_METHOD - set to 0. Note that this is a different policy to - some platforms (see below). -

  • - -
  • - Expression contraction (for example, converting x * y + - c to fma(x,y,c)) is not performed. In effect, - the FP_CONTRACT pragma is always off. -

  • - -
  • - Constant expressions are evaluated at `run' time wherever possible - and so will respect changes in the rounding mode. In effect, - the FENV_ACCESS pragma is always off. Note that - floating point constants are treated as doubles (unless they are - followed by f when they are float) as specified in the - C standard. goto-cc - supports -fsingle-precision-constant, which allows the - (non-standard) treatment of constants as floats. -

  • - -
  • - Casts from int to float and float to float make use of the current - rounding mode. Note that the standard requires that casts from - float to int use round-to-zero (i.e. truncation). -

  • -
- -

x86 and Other Platform-specific Issues

- -

Not all platforms have the same implementation-defined - behaviour as CPROVER. This can cause mismatches between the verification - environment and the execution environment. If this occurs, check the - compiler manual for the choices listed above. There are two common cases - that can cause these problems: 32-bit x86 code and the use of unsafe - optimisations.

- -

Many compilers that target 32-bit x86 platforms - employ a different evaluation method. The extended precision - format of the x87 unit is used for all computations regardless of - their native precision. Most of the time, this results in more - accurate results and avoids edge cases. However, it can result in - some obscure and difficult to debug behaviour. Checking - if the FLT_EVAL_METHOD macro is non-zero (for these - platforms it will typically be 2), should warn of these problems. - Changing the compiler flags to use the SSE registers will resolve - many of them, give a more standards-compliant platform and will - likely perform better. Thus it is highly recommended. - Use -msse2 -mfpmath=sse to enable this option for - GCC. Visual C++ does not have an option to force the exclusive use - of SSE instructions, but /arch:SSE2 will pick SSE - instructions "when it [the compiler] determines that it is faster to - use the SSE/SSE2 instructions" and is thus better - than /arch:IA32, which exclusively uses the x87 unit.

- -

The other common cause of discrepancy between - CPROVER results and the actual platform are the use of unsafe - optimisations. Some higher optimisation levels enable - transformations that are unsound with respect to the IEEE-754 - standard. Consult the compiler manual and disable any - optimisations that are described as unsafe (for - example, the GCC options -ffast-math). - The options -ffp-contract=off (which replaces - -mno-fused-madd), -frounding-math - and -fsignaling-nans are needed for GCC to be strictly - compliant with IEEE-754.

- -

Rounding Mode

- -

CPROVER supports the four rounding modes given by - IEEE-754 1985; round to nearest (ties to even), round up, round - down and round towards zero. By default, round to nearest is used. - However, command line options (--round-to-zero, etc.) can - be used to over-ride this. If more control is needed, CPROVER has - models of fesetround (for POSIX systems) - and _controlfp (for Windows), which can be used to change - the rounding mode during program execution. Furthermore, - the inline assembly commands fstcw/fnstcw/fldcw (on x86) can - be used.

- -

The rounding mode is stored in the (thread local) - variable __CPROVER_rounding_mode, but users are strongly advised - not to use this directly.

- -

Math Library

- -

CPROVER implements some of math.h, - including fabs, fpclassify - and signbit. It has very limited support for - elementary functions. Care must be taken when verifying properties - that are dependent on these functions as the accuracy of - implementations can vary considerably. The C compilers can (and - many do) say that the accuracy of these functions is unknown.

- -

Fixed-point Arithmetic

- -

CPROVER also has support for fixed-point types. - The --fixedbv flag - switches float, double and long - double to fixed-point types. The length of these types is - platform specific. The upper half of each type is the integer - component and the lower half is the fractional part.

- - diff --git a/doc/html-manual/modeling-nondet.shtml b/doc/html-manual/modeling-nondet.shtml deleted file mode 100644 index 3b0809ffb79..00000000000 --- a/doc/html-manual/modeling-nondet.shtml +++ /dev/null @@ -1,65 +0,0 @@ - - -

CPROVER Manual TOC

- -

Nondeterminism

- -

Rationale

- -

Programs typically read inputs from an environment. -These inputs can take the form of data read from a file, keyboard or network -socket, or arguments passed on the command line. It is usually desirable to -analyze the program for any choice of these inputs. In Model Checking, -inputs are therefore modeled by means of nondeterminism, which means -that the value of the input is not specified. The program may follow any -computation that results from any choice of inputs.

- -

Sources of Nondeterminism

- -

The CPROVER tools support the following sources of nondeterminism:

- -
    -
  • functions that read inputs from the environments;
  • -
  • the thread schedule in concurrent programs;
  • -
  • initial values of local-scoped variables and memory allocated with -malloc;
  • -
  • initial values of variables that are extern in all -compilation units;
  • -
  • explicit functions for generating nondeterminism.
  • -
- -

The CPROVER tools are shipped with a number of stubs -for the most commonly used library functions. When executing a statement -such as getchar(), a nondeterministic value is chosen instead -of reading a character from the keyboard. - -

When desired, nondeterminism can be introduced -explicitly into the program by means of functions that begin with the -prefix nondet_. As an example, the following function -returns a nondeterministically chosen unsigned short int: -

- -
unsigned short int nondet_ushortint();
-
- -

Note that the body of the function is not defined. The -name of the function itself is irrelevant (save for the prefix), but must be -unique. Also note that a nondeterministic choice is not to be confused with -a probabilistic (or random) choice.

- -

Uninterpreted Functions

- -

It may be necessary to check parts of a program -independently. Nondeterminism can be used to over-approximate the -behaviour of part of the system which is not being checked. Rather -than calling a complex or unrelated function, a nondeterministic stub -is used. However, separate calls to the function can return different -results, even for the same inputs. If the function output only -depends on its inputs then this can introduce spurious errors. To -avoid this problem, functions whose names begin with the -prefix __CPROVER_uninterpreted_ are treated as -uninterpreted functions. Their value is non-deterministic but different -invocations will return the same value if their inputs are the same. -Note that uninterpreted functions are not supported by all back-end solvers.

- - diff --git a/doc/html-manual/modeling-pointers.shtml b/doc/html-manual/modeling-pointers.shtml deleted file mode 100644 index d8cfa7f31c4..00000000000 --- a/doc/html-manual/modeling-pointers.shtml +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - -

CPROVER Manual TOC

- -

Pointer Model

- -

Pointers in C

- -

C programs (and sometimes C++ programs as well) make -intensive use of pointers in order to decouple program code from specific -data. A pointer variable does not store data such as numbers or letters, -but instead points to a location in memory that hold the relevant data. -This section describes the way the CPROVER tools model pointers. -

- -

Objects and Offsets

- -

The CPROVER tools represent pointers as a pair. The -first member of the pair is the object the pointer points to, and the -second is the offset within the object.

- -

In C, objects are simply continuous fragments of memory -(this definition of "object" is not to be confused with the use of the term -in object-oriented programming). Variables of any type are guaranteed to be -stored as one object, irrespectively of their type. As an example, all -members of a struct or array belong to the same object. CPROVER simply -assigns a number to each active object. The object number of a pointer -p can be extracted using the expression -__CPROVER_POINTER_OBJECT(p). As a consequence, pointers to -different objects are always different, which is not sound. - -

- -

The offset (the second member of the pair that forms a -pointer) is relative to the beginning of the object; it uses byte -granularity. As an example, the code fragment -

- -
  unsigned array[10];
-  char *p;
-
-  p=(char *)(array+1);
-  p++;
-
- -

will result in a pointer with offset 5. The offset of -a pointer p can be extracted using the expression -__CPROVER_POINTER_OFFSET(p).

- -

Dereferencing Pointers

- -

The CPROVER tools require that pointers that -are dereferenced point to a valid object. Assertions that check -this requirement can be generated using the option --pointer-check -and, if desired, --bounds-check. These options will ensure -that NULL pointers are not dereferenced, and that dynamically -allocated objects have not yet been deallocated.

- -

Furthermore, the CPROVER -tools check that dynamically allocated memory is not -deallocated twice. The goto-instrument tool is also able -to add checks for memory leaks, i.e., it detects dynamically -allocated objects that are not deallocated once the program -terminates.

- -

The CPROVER tools support pointer typecasts. Most -casts are supported, with the following exceptions: -

- -
    -
  1. -One notable exception is that pointers can only be -accessed using a pointer type. The conversion of a pointer into an -integer-type using a pointer typecast is not supported. -

  2. - -
  3. -Casts from integers to pointers yield a pointer that is either -NULL (if the integer is zero) or that point into a special -array for modeling -memory-mapped I/O. Such pointers are assumed not to -overlap with any other objects. This is, of course, only sound if -a corresponding range check is instrumented. -

  4. - -
  5. -Accesses to arrays via pointers that have the array subtype need -to be well-aligned. -

  6. - -
- -

Pointers in Open Programs

- -

It is frequently desired to validate an open program, -i.e., a fragment of a program. Some variables are left undefined. In case -an undefined pointer is dereferenced, CBMC assumes that the pointer -points to a separate object of appropriate type with unbounded size. -The object is assumed not to alias with any other object. -This assumption may obviously be wrong in specific extensions -of the program. -

- - diff --git a/doc/html-manual/pid_test_suites.xml b/doc/html-manual/pid_test_suites.xml deleted file mode 100644 index 014fea12294..00000000000 --- a/doc/html-manual/pid_test_suites.xml +++ /dev/null @@ -1,500 +0,0 @@ - - -CBMC 5.5 - - CBMC version 5.5 64-bit x86_64 macos - - - - Parsing pid.c - - - - Converting - - - - Type-checking pid - - - - - function `nondet_float' is not declared - - - - Generating GOTO Program - - - - Adding CPROVER library (x86_64) - - - - Removal of function pointers and virtual functions - - - - Partial Inlining - - - - Generic Property Instrumentation - - -criterion: mcdc - - - Instrumenting coverage goals - - - - Starting Bounded Model Checking - - - - Unwinding loop main.0 iteration 1 (6 max) file pid.c line 56 function main thread 0 - - - - Unwinding loop main.0 iteration 2 (6 max) file pid.c line 56 function main thread 0 - - - - Unwinding loop main.0 iteration 3 (6 max) file pid.c line 56 function main thread 0 - - - - Unwinding loop main.0 iteration 4 (6 max) file pid.c line 56 function main thread 0 - - - - Unwinding loop main.0 iteration 5 (6 max) file pid.c line 56 function main thread 0 - - - - Not unwinding loop main.0 iteration 6 (6 max) file pid.c line 56 function main thread 0 - - - - size of program expression: 416 steps - - - - Generated 114 VCC(s), 108 remaining after simplification - - - - Passing problem to propositional reduction - - - - converting SSA - - - - Aiming to cover 19 goal(s) - - - - Running propositional reduction - - - - Post-processing - - - - Solving with MiniSAT 2.2.1 with simplifier - - - - 131818 variables, 553801 clauses - - - - SAT checker: instance is SATISFIABLE - - - - Covered decision/condition `1 != 0' true - - - - Solving with MiniSAT 2.2.1 with simplifier - - - - 131818 variables, 395675 clauses - - - - SAT checker: instance is SATISFIABLE - - - - Covered MC/DC independence condition `!(pprz >= (float)0) && pprz <= (float)(16 * 600)' - - - - Covered decision `pprz >= (float)0 && pprz <= (float)(16 * 600)' false - - - - Covered condition `pprz >= (float)0' false - - - - Covered decision/condition `pprz > (float)(16 * 600)' false - - - - Covered condition `pprz <= (float)(16 * 600)' true - - - - Covered decision/condition `desired_climb > (float)0' false - - - - Covered decision/condition `climb_sum_err > (float)10' false - - - - Covered decision/condition `climb_sum_err < (float)-10' false - - - - Solving with MiniSAT 2.2.1 with simplifier - - - - 131818 variables, 393279 clauses - - - - SAT checker: instance is SATISFIABLE - - - - Covered MC/DC independence condition `pprz >= (float)0 && !(pprz <= (float)(16 * 600))' - - - - Covered condition `pprz >= (float)0' true - - - - Covered decision/condition `pprz > (float)(16 * 600)' true - - - - Covered condition `pprz <= (float)(16 * 600)' false - - - - Covered decision/condition `desired_climb > (float)0' true - - - - Solving with MiniSAT 2.2.1 with simplifier - - - - 131818 variables, 391285 clauses - - - - SAT checker: instance is SATISFIABLE - - - - Covered MC/DC independence condition `pprz >= (float)0 && pprz <= (float)(16 * 600)' - - - - Covered decision `pprz >= (float)0 && pprz <= (float)(16 * 600)' true - - - - Solving with MiniSAT 2.2.1 with simplifier - - - - 131818 variables, 390122 clauses - - - - SAT checker: instance is SATISFIABLE - - - - Covered decision/condition `climb_sum_err < (float)-10' true - - - - Solving with MiniSAT 2.2.1 with simplifier - - - - 131818 variables, 390121 clauses - - - - SAT checker: instance is SATISFIABLE - - - - Covered decision/condition `climb_sum_err > (float)10' true - - - - Solving with MiniSAT 2.2.1 with simplifier - - - - 131818 variables, 387493 clauses - - - - SAT checker inconsistent: instance is UNSATISFIABLE - - - - Runtime decision procedure: 3.806s - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -1.000000 - - - 1.000000 - - - - - - - - - - - - - - - - -1.000000 - - - 1.000000 - - - 1.000000 - - - -1.000000 - - - - - - - - - - - - - 0.000000 - - - -1.000000 - - - 1.000000 - - - -1.000000 - - - - - - - - - - 1.000000 - - - -1.000000 - - - 1.000000 - - - -1.000000 - - - 1.000000 - - - -1.000000 - - - 1.000000 - - - -1.000000 - - - 0.000000 - - - -1.000000 - - - 1.000000 - - - -1.000000 - - - - - - - - - -1.000000 - - - 1.000000 - - - -1.000000 - - - 1.000000 - - - -1.000000 - - - 1.000000 - - - -1.000000 - - - 1.000000 - - - -1.000000 - - - 1.000000 - - - -1.000000 - - - 1.000000 - - - - - - - ** 18 of 19 covered (94.7%) - - - - ** Used 7 iterations - - - diff --git a/doc/html-manual/properties.shtml b/doc/html-manual/properties.shtml deleted file mode 100644 index aba408fc4c8..00000000000 --- a/doc/html-manual/properties.shtml +++ /dev/null @@ -1,212 +0,0 @@ - - -

CPROVER Manual TOC

- -

Property Instrumentation

- -

Properties

- -

-We have mentioned properties several times so far, but we never -explained what kind of properties CBMC -and SATABS can verify. We -cover this topic in more detail in this section.

- -

-Both CBMC and SATABS use -assertions to specify program properties. Assertions are properties of -the state of the program when the program reaches a particular program -location. Assertions are often written by the programmer by means of the -assert macro.

- -

-In addition to the assertions written by the programmer, assertions -for specific properties can also be generated automatically -by CBMC and SATABS, often relieving the programmer from writing -"obvious" assertions.

- -

-CBMC and SATABS come with an assertion generator called -goto-instrument, which performs a conservative -static analysis -to determine program locations that potentially -contain a bug. Due to the imprecision of the static -analysis, it is important to emphasize that these -generated assertions are only potential bugs, and -that the Model Checker first needs to confirm that -they are indeed genuine bugs.

- -

-The assertion generator can generate assertions for -the verification of the following properties:

- -
    -
  • -

    -Buffer overflows. -For each array access, check whether the upper and lower bounds -are violated. -

  • - -
  • -Pointer safety. Search for NULL-pointer -dereferences or dereferences of other invalid pointers. -

    -
  • - -
  • -Division by zero. -Check whether there is a division by zero in the program. -

    -
  • - -
  • -Not-a-Number. -Check whether floating-point computation may result in -NaNs. -

    -
  • - -
  • -Unitialized local. -Check whether the program uses an uninitialized local variable. -

    -
  • - -
  • -Data race. -Check whether a concurrent program accesses a shared variable -at the same time in two threads. -

    -
  • - -
- -

We refrain from explaining the properties above in -detail. Most of them relate to behaviors that are left undefined by the -respective language semantics. For a discussion on why these behaviors are -usually very undesirable, read this blog post by John -Regehr.

- -

-All the properties described above are reachability properties. -They are always of the form -

- -

-"Is there a path through the program such that property ... -is violated?" -

- -

-The counterexamples to such properties are always -program paths. Users of the Eclipse plugin can step through -these counterexamples in a way that is similar to debugging programs. -The installation of this plugin is explained -here. -

- -

Using goto-instrument

- -

-The goto-instrument static analyzer operates on goto-binaries, which -is a binary representation of control-flow graphs. The goto-binary -is extracted from program source code using goto-cc, which -is explained here. -Given a goto-program, goto-instrument operates as follows: -

- -

-

    -
  1. A goto-binary is read in.
  2. -
  3. The specified static analyses are performed.
  4. -
  5. Any potential bugs found are transformed into corresponding -assertions, and are added into the program.
  6. -
  7. A new goto-binary (with assertions) is written to disc.
  8. -
-

- -
-

-As an example, we begin with small C program we call -expr.c -(taken from here): -

- -
-
int *ptr;
-
-int main(void) {
-  if (ptr)
-    *ptr = 0;
-  if (!ptr)
-    *ptr = 1;
-}
-
- -

-The program contains an obvious NULL-pointer dereference. -We first compile the example program with goto-cc and -then instrument the resulting goto-binary with -pointer checks. -

- -

- -  goto-cc expr.c -o in.gb
-  goto-instrument in.gb out.gb --pointer-check -
-

- -

-We can now get a list of the assertions that have been generated -as follows: -

- -

- -  goto-instrument out.gb --show-properties - -

- -

Using either CBMC or SATABS on out.gb, -we can obtain a counterexample trace for the NULL-pointer dereference: -

- -

- -  cbmc out.gb - -

-
- -

The goto-instrument program supports the following -checks: -

- -

- - - - - - - - - - - -
--no-assertions ignore user assertions
--bounds-check add array bounds checks
--div-by-zero-check add division by zero checks
--pointer-check add pointer checks
--signed-overflow-check add arithmetic over- and underflow checks
--unsigned-overflow-check add arithmetic over- and underflow checks
--undefined-shift-check add range checks for shift distances
--nan-check add floating-point NaN checks
--uninitialized-check add checks for uninitialized locals (experimental)
--error-label labelcheck that given label is unreachable
-

- - - - diff --git a/doc/html-manual/satabs-aeon.shtml b/doc/html-manual/satabs-aeon.shtml deleted file mode 100644 index ac40245b830..00000000000 --- a/doc/html-manual/satabs-aeon.shtml +++ /dev/null @@ -1,266 +0,0 @@ - - - - - - -

CPROVER Manual TOC

- -

SATABS – Predicate Abstraction with SAT

- -

Tutorials

- -

Example: Buffer Overflow in a Mail Transfer Agent

- -

- -We explain how to model check Aeon version 0.2a, a small -mail transfer agent written by Piotr Benetkiewicz. The description -advertises Aeon as a "good choice for hardened or -minimalistic boxes". The sources are available - -here.

- -

-Our first naive attempt to verify Aeon using -

- -

-satabs *.c -

- -

-produces a positive result, but also warns us that the property holds -trivially. It also reveals that a large number library functions are -missing: SATABS is unable to find the source code for library functions like -send, write and close. -

- -

-Now, do you have to provide a body for all missing library functions? -There is no easy answer to this question, but a viable answer would -be "most likely not". It is necessary to understand how SATABS -handles functions without bodies: It simply assumes that such a function -returns an arbitrary value, but that no other -locations than the one on the left hand side of the assignment are -changed. Obviously, there are cases in which this assumption is -un­sound, since the function potentially modifies all memory locations -that it can somehow address. -

- -

-We now use static analysis to generate array bounds checks for -Aeon: -

- -

-satabs *.c --pointer-check --bounds-check --show-properties -

- -

-SATABS will show about 300 properties in various functions -(read this for more information -on the property instrumentation). -Now consider the first few lines of the main function -of Aeon: -

- -
int main(int argc, char **argv)
-{
-  char settings[MAX_SETTINGS][MAX_LEN];
-  ...
-  numSet = getConfig(settings);
-  if (numSet == -1) {
-    logEntry("Missing config file!");
-    exit(1);
-  }
-  ...
-
- -

-and the function getConfig in lib_aeon.c: -

- - - - - - - - - - - - - - - - - - -
int getConfig(char settings[MAX_SETTINGS][MAX_LEN])
{
  char home[MAX_LEN];
FILE *fp; /* .rc file handler */
int numSet = 0; /* number of settings */
 
strcpy(home, getenv("HOME"));  /* get home path */
strcat(home, "/.aeonrc"); /* full path to rc file */
fp = fopen(home, "r");
if (fp == NULL) return -1; /* no cfg - ERROR */
-
  while (fgets(settings[numSet], MAX_LEN-1, fp)
    && (numSet < MAX_SETTINGS)) numSet++;
fclose(fp);
 
return numSet;
}
-
- -

-The function getConfig makes calls to -strcpy, strcat, getenv, fopen, -fgets, and fclose. -It is very easy to provide an implementation for the functions from -the string library (string.h), and SATABS comes with meaningful definitions -for most of them. -The definition of getenv is not so straight-forward. -The man-page of getenv (which we obtain by entering -man 3 getenv in a Unix or cygwin command prompt) tells us: -

- -
- -`getenv' searches the list of en­vi­ron­ment -variable names and values -(using the global pointer char **environ) -for a variable whose name -matches the string at NAME. If a variable name matches, -getenv returns a pointer to the associated value. - -
- -

-SATABS has no information whatsoever about the content of -environ. Even if SATABS could access the -en­vi­ron­ment variables on your computer, a successful verification -of Aeon would then only guarantee that the properties for -this program hold on your computer with a specific set of -en­vi­ron­ment variables. We have to assume that environ -contains en­vi­ron­ment variables that have an arbitrary content -of arbitrary length. The content of en­vi­ron­ment -variables is not only arbitrary but could be malefic, since it -can be modified by the user. The approximation of the behavior of -getenv that is shipped with SATABS completely ignores the -content of the string.

- -

-Now let us have another look at the properties that SATABS generates for the -models of the the string library and for getenv. Most of these -properties require that we verify that the upper and lower bounds of buffers or -arrays are not violated. Let us look at one of the properties that SATABS -generates for the code in function getConfig: -

- -

- -Claim getConfig.3:
-  file lib_aeon.c line 19 function getConfig
-  dereference failure: NULL plus offset pointer
-  !(SAME-OBJECT(src, NULL)) -
-

- -

The model of the function strcpy -dereferences the pointer returned by getenv, which may -return a NULL pointer. This possibility is detected by the static -analysis, and thus a corresponding property is generated. Let us -check this specific property: -

- -

-satabs *.c --pointer-check --bounds-check --property getConfig.3 -

- -

SATABS immediately returns a counterexample path -that demonstrates how getenv returns a NULL, which -is subsequently dereferenced. We have identified the first -bug in this program: it requires that the environment variable -HOME is set, and crashes otherwise. -

- -

Let us examine one more property in the -same function:

- -

-Claim getConfig.7:
-  file lib_aeon.c line 19 function getConfig
-  dereference failure: array `home' upper bound
-  !(POINTER_OFFSET(dst) + (int)i >= 512) || !(SAME-OBJECT(dst, &home[0]))
-

- -

-This property asserts that the upper bound of the array home -is not violated. The variable home -looks familiar: We encountered it in the function getConfig -given above. The function getenv in combination with functions -strcpy, strcat or sprintf is indeed -often the source for buffer overflows. Therefore, we try to use SATABS -to check the upper bound of the array home: -

- -

-satabs *.c --pointer-check --bounds-check --property getConfig.7 -

- -

-SATABS runs for quite a while and will eventually give up, -telling us that its upper bound for abstraction refinement iterations -has been exceeded. This is not exactly the result we were hoping for, -and we could now increase the bound for iterations with help of the ---iterations command line switch of SATABS. -

- -

-Before we do this, let us investigate why SATABS has failed to provide -a useful result. The function strcpy contains a loop -that counts from 1 to the length of the input string. Predicate -abstraction, the mechanism SATABS is based on, is unable to detect -such loops and will therefore unroll the loop body as often as necessary. -The array home has MAX_LEN elements, and -MAX_LEN is defined to be 512 in aeon.h. -Therefore, SATABS would have to run through at least 512 iterations, only to -verify (or reject) one of the more than 300 properties! Does this fact -defeat the purpose of static verification? -

- -

-We can make the job easier: after reducing the value of MAX_LEN -in aeon.h to a small value, say to 10, SATABS provides a -counterexample trace that demonstrates how the buffer overflow be -reproduced. If you use the Eclipse plugin (as described here), you can step through this -counterexample. The trace contains the string that is returned -by getenv. -

- - - - - diff --git a/doc/html-manual/satabs-background.shtml b/doc/html-manual/satabs-background.shtml deleted file mode 100644 index b6d20fb08fa..00000000000 --- a/doc/html-manual/satabs-background.shtml +++ /dev/null @@ -1,152 +0,0 @@ - - -

CPROVER Manual TOC

- -

SATABS – Predicate Abstraction with SAT

- -

Background

- -

Sound Abstractions

- -

-This section provides background information on how SATABS operates. Even -for very trivial C programs it is impossible to exhaustively examine their -state space (which is potentially unbounded). However, not all details in a -C program necessarily contribute to a bug, so it may be sufficient to only -examine those parts of the program that are somehow related to a bug.

- -

-In practice, many static verification tools (such as lint) try to -achieve this goal by applying heuristics. This approach comes at a cost: -bugs might be overlooked because the heuristics do not cover all relevant -aspects of the program. Therefore, the conclusion that a program is correct -whenever such a static verification tool is unable to find an error is -invalid. -

- -
-CEGAR Loop -
- -

-A more sophisticated approach that has been very successful recently -is to generate a sound abstraction of the original program. -In this context, soundness refers to the fact that the abstract program -contains (at least) all relevant behaviors (i.e., bugs) that are present -in the original program. In the Figure above, the first component -strips details from the original program. The number of possible behaviors -increases as the number of details in the abstract program decreases. -Intuitively, the reason is that whenever the model checking tool lacks the -information that is necessary to make an accurate decision on whether a -branch of an control flow statement can be taken or not, both branches -have to be considered.

- -

-In the resulting abstract program, a set of concrete -states is subsumed by means of a single abstract state. Consider -the following figure: -

- -
- -
- -

-The concrete states x1 -and x2 are mapped to an -abstract state X, and similarly -Y subsumes -y1 -and y2. -However, all transitions that are possible in the concrete program are also -possible in the abstract model. The abstract transition -XY -summarizes the concrete transitions -x1y1 -and x1 → -x1, and Y → -X -corresponds to x1 → -x2. The -behavior -XY → -X is feasible in the original program, -because it maps to -x1 → -x1 → -x2. However, -Y → -X → -Y -is feasible only in the abstract model.

- -

Spurious Counterexamples

- -

-The consequence is that the model checker (component number two in the -figure above) possibly reports a spurious counterexample. We call a -counterexample spurious whenever it is feasible in the current abstract -model but not in the original program. However, whenever the model checker -is unable to find an execution trace that violates the given property, we -can conclude that there is no such trace in the original program, either. -

- -

-The feasibility of counterexamples is checked by symbolic simulation -(performed by component three in the figure above). If the counterexample -is indeed feasible, SATABS found a bug in the original program and reports -it to the user. -

- -

Automatic Refinement

- -

-On the other hand, infeasible counterexamples -(that originate from abstract behaviors that -result from the omission of details and are not present in the original -program) are never reported to the user. Instead, the information is used -in order to refine the abstraction such that the spurious counterexample is -not part of the refined model anymore. For instance, the reason for the -infeasibility of Y -→ X → -Y is -that neither -y1 nor -x1 can -be reached from -x2. -Therefore, the abstraction can be refined by partitioning -X. -

- -

-The refinement steps can be illustrated as follows: -

- -
-Iterative refinement -
- -

-The first step (1) is to generate a very coarse abstraction with -a very small state space. This abstraction is then successively -refined (2, 3, ...) until either a feasible counterexample is found or the -abstract program is detailed enough to show that there is no -path that leads to a violation of the given property. The problem -is that this point is not necessarily reached for every input program, -i.e., it is possible that the the abstraction refinement loop never -terminates. Therefore, SATABS allows to specify an upper -bound for the number of iterations. -

- -
-

-When this upper bound is reached and no counterexample was found, -this does not necessarily mean that there is none. In this case, -you cannot make any conclusions at all with respect to the correctness -of the input program. -

-
- - diff --git a/doc/html-manual/satabs-driver.shtml b/doc/html-manual/satabs-driver.shtml deleted file mode 100644 index b4b34954986..00000000000 --- a/doc/html-manual/satabs-driver.shtml +++ /dev/null @@ -1,264 +0,0 @@ - - - - - - -

CPROVER Manual TOC

- -

SATABS – Predicate Abstraction with SAT

- -

Tutorials

- -

Example: Reference Counting in Linux Device Drivers

- -

-Microsoft's SLAM toolkit -has been successfully used to find bugs in Windows device drivers. SLAM -automatically verifies device driver whether a device driver adheres to a -set of specifications. SLAM provides a test harness for device drivers that -calls the device driver dispatch routines in a non-deterministic order. -Therefore, the Model Checker examines all combinations of calls. Motivated -by the success this approach, we provide a toy example based on Linux device -drivers. For a more complete approach to the verification of Linux -device drivers, consider DDVerify. -

- -

-Dynamically loadable modules enable the Linux Kernel to load device drivers -on demand and to release them when they are not needed anymore. When a -device driver is registered, the kernel provides a major number that is used -to uniquely identify the device driver. The corresponding device can be -accessed through special files in the filesystem; by convention, they are -located in the /dev directory. If a process accesses a device file -the kernel calls the corresponding open, read and -write functions of the device driver. Since a driver must not be -released by the kernel as long as it is used by at least one process, the -device driver must maintain a usage counter (in more recent Linux kernels, this -is done automatically, however, drivers that must maintain backward -compatibility have to adjust this counter). -

- -

-We provide a skeleton of such a driver. Download the -files -spec.c, -driver.c, -driver.h, -kdev_t.h, and -modules.h. -

- -

-The driver contains following functions:

- -
    - -
  1. register_chrdev: - (in spec.c) - Registers a character device. In - our implementation, the function sets the variable usecount - to zero and returns a major number for this device (a constant, if - the user provides 0 as argument for the major number, and the value - specified by the user otherwise). -

    - -
    int usecount;
    -
    -int register_chrdev (unsigned int major, const char* name)
    -{
    -  usecount = 0;
    -  if (major == 0)
    -    return MAJOR_NUMBER;
    -  return major;
    -}
    - -
  2. - -
  3. unregister_chrdev: (in spec.c) - Unregisters a character device. - This function asserts that the device is not used by any process - anymore (we use the macro MOD_IN_USE to check this). -

    - -
    int unregister_chrdev (unsigned int major, const char* name)
    -{
    -  if (MOD_IN_USE)
    -    {
    -    ERROR: assert (0);
    -    }
    -  else
    -    return 0;
    -}
    -
  4. - -
  5. dummy_open: (in - driver.c) This function - increases the usecount. If the device is locked by - some other process dummy_open returns -1. Otherwise - it locks the device for the caller. -

    -
  6. - -
  7. dummy_read: (in driver.c) This function - "simulates" a read access to the device. In fact it does - nothing, since we are currently not interested in the potential buffer - overflow that may result from a call to this function. - Note the usage of - the function nondet_int: - This is an internal SATABS-function that non­determi­nistically - returns an arbitrary integer - value. The function __CPROVER_assume - tells SATABS to ignore - all traces that do not adhere to the given assumption. Therefore, - whenever the lock is held, dummy_read will - return a value between 0 and max. If the lock is not held, - then dummy_read returns -1. -

    -
  8. - -
  9. dummy_release: (in driver.c) If the lock -is held, then dummy_release decreases -the usecount, releases the lock, and returns 0. Otherwise, -the function returns -1. -

  10. - -
- -

-We now want to check if any valid sequence of calls of the -dispatch functions (in driver.c) can lead to the violation -of the assertion (in spec.c). -Obviously, a call to dummy_open that is immediately followed -by a call to unregister_chrdev violates the assertion. -

- -

-The function main in spec.c gives an example of -how these functions are called. First, a character device -"dummy" is registered. The major number is stored -in the inode structure of the device. The values -for the file structure are assigned non-deterministically. -We rule out invalid sequences of calls by ensuring -that no device is unregistered while it is still locked. -We use the following model checking harness for calling the -dispatching functions: -

- -
      random = nondet_uchar ();
-      __CPROVER_assume (0 <= random && random <= 3);
-
-      switch (random)
-      {
-      case 1: 
-        rval = dummy_open (&inode, &my_file);
-        if (rval == 0)
-          lock_held = TRUE;
-        break;
-      case 2:
-        __CPROVER_assume (lock_held);
-        count = dummy_read (&my_file, buffer, BUF_SIZE); 
-        break;
-      case 3:
-        dummy_release (&inode, &my_file);
-        lock_held = FALSE;
-        break;
-      default:
-        break;
-      }
-
- -

-The variable random is assigned non-deterministically. -Subsequently, the value of random -is restricted to be 0 &le random ≤ 3 by a call to -__CPROVER_assume. Whenever the value of random is -not in this interval, the corresponding execution trace is simply -discarded by SATABS. Depending on the value of random, the -harness calls either dummy_open, dummy_read or -dummy_close. Therefore, -if there is a sequence of calls to these three -functions that leads to a violation of the assertion in -unregister_chrdev, then SATABS -will eventually consider it. -

- -

-If we ask SATABS to show us the properties it verifies with -

- -
-satabs driver.c spec.c --show-properties -
- -

-for our example, we obtain -

- -
    - -
  1. -Claim unregister_chrdev.1:
    -    file spec.c line 18 function unregister_chrdev
    -    MOD_IN_USE in unregister_chrdev
    -    FALSE -

    -
  2. - -
  3. -Claim dummy_open.1:
    -    file driver.c line 15 function dummy_open
    -    i_rdev mismatch
    -    (unsigned int)inode->i_rdev >> 8 == (unsigned int)dummy_major -

    -
  4. - -
- -

-It seems obvious that the property dummy_open.1 -can never be violated. SATABS confirms -this assumption: We call -

- -
-satabs driver.c spec.c --property dummy_open.1 -
- -

-and SATABS reports VERIFICATION SUCCESSFUL after a few iterations. -

- -

If we try to verify property unregister_chrdev.1, SATABS -reports that the property in line 18 in file spec.c is violated (i.e., the -assertion does not hold, therefore the VERIFICATION FAILED). -Furthermore, SATABS provides a detailed description of the problem in the -form of a counterexample (i.e., an execution trace that violates the -property). On this trace, dummy_open is called twice, -leading to a usecount of 2. The second call of course fails -with rval=-1, but the counter is increased nevertheless: -

- -
int dummy_open (struct inode *inode, struct file *filp)
-{
-  __CPROVER_assert(MAJOR (inode->i_rdev) == dummy_major,
-      "i_rdev mismatch");
-  MOD_INC_USE_COUNT;
-
-  if (locked)
-    return -1;
-  locked = TRUE;
-
-  return 0; /* success */
-}
-
- -

-Then, dummy_release is called to release the lock on the -device. Finally, the loop is left and the call to -unregister_chrdev results in a violation of the assertion -(since usecount is still 1, even though locked=0). -

- - - diff --git a/doc/html-manual/satabs-tutorials.shtml b/doc/html-manual/satabs-tutorials.shtml deleted file mode 100644 index f842f6a30c4..00000000000 --- a/doc/html-manual/satabs-tutorials.shtml +++ /dev/null @@ -1,25 +0,0 @@ - - -

CPROVER Manual TOC

- -

SATABS – Predicate Abstraction with SAT

- -

Tutorials

- -

-We provide an introduction to model checking "real" -C programs with SATABS using two small examples: -

- -
    - -
  • An example based on Linux device drivers. -
  • - -
  • An example based on a Mail Transfer Agent. -
  • - -

    - - - diff --git a/doc/html-manual/satabs.shtml b/doc/html-manual/satabs.shtml deleted file mode 100644 index 6ec21bb45b3..00000000000 --- a/doc/html-manual/satabs.shtml +++ /dev/null @@ -1,180 +0,0 @@ - - - - - - -

    CPROVER Manual TOC

    - -

    SATABS – Predicate Abstraction with SAT

    - -

    Overview

    - -

    -This section describes SATABS from the point of view of the user. To learn -about the technology implemented in SATABS, read this -section. -

    - -

    -We assume you have already installed SATABS and the necessary support files -on your system. If not so, please follow -these instructions. -

    - -

    -While users of SATABS -almost never have to be concerned about the underlying refinement -abstraction algorithms, understanding the classes of properties that -can be verified is crucial. Predicate abstraction is most effective -when applied to control-flow dominated properties. As -an example, reconsider the following program -(lock-example-fixed.c): -

    - -
    _Bool nondet_bool();
    -_Bool LOCK = 0;
    -
    -_Bool lock() {
    -  if(nondet_bool()) {
    -    assert(!LOCK);
    -    LOCK=1;
    -    return 1; }
    -
    -  return 0;
    -}
    -
    -void unlock() {
    -  assert(LOCK);
    -  LOCK=0;
    -}
    -
    -int main() {
    -  unsigned got_lock = 0;
    -  int times;
    -
    -  while(times > 0) {
    -    if(lock()) {
    -      got_lock++;
    -      /* critical section */
    -    }
    -
    -    if(got_lock!=0) {
    -      unlock();
    -      got_lock--;
    -    }
    -
    -    times--;
    -} }
    -
    - -

    -The two assertions in the program model that the functions lock() -and unlock() are called in the right order. Note that the value -of times is chosen non-deterministically and is not bounded. The program has -no run-time bound, and thus, unwinding the code with -CBMC will never terminate.

    - -

    Working with Claims

    - -

    -The two assertions will give rise to two properties. -Each property is associated to a specific line of code, i.e., a property is violated when -some condition can become false at the corresponding program location. -SATABS will generate a list of all properties for the programs as follows: -

    - -
    - -satabs lock-example-fixed.c --show-properties - -
    - -

    SATABS will list two properties; each property corresponds to one of the -two assertions. We can use SATABS to verify both properties -as follows: -

    - -
    - -satabs lock-example-fixed.c - -
    - -

    -SATABS will conclude the verification successfully, that is, both -assertions hold for execution traces of any length. -

    - -

    -By default, SATABS attempts to verify all properties at once. -A single property can be verified (or refuted) by using the ---property id option of SATABS, -where id denotes the identifier of the property in the list -obtained by calling SATABS with the --show-properties flag. Whenever -a property is violated, SATABS reports a feasible path that leads to a state -in which the condition that corresponds to the violated property evaluates to -false. -

    - -

    Programs that use Libraries

    - -

    -SATABS cannot check programs that use functions that are -only available in binary (compiled) form (this restriction -is not imposed by the verification algorithms that are used by SATABS – -they also work on assembly code). The reason is simply that so far -no assembly language frontend is available for SATABS. At the moment, -(library) functions for which no C source code is available have to be -replaced by stubs. The usage of stubs and harnesses (as known from unit -testing) also allows to check more complicated properties (like, for -example, whether function fopen is always called before -fclose). This technique is explained in detail -in the SATABS tutorials. -

    - -

    Unit Testing with SATABS

    - -

    -The example presented here is obviously a -toy example and can hardly be used to convince your project manager to use -static verification in your next project. Even though we recommend to use -formal verification and specification already in the early phases of your -project, the sad truth is that in most projects verification (of any kind) -is still pushed to the very end of the development cycle. Therefore, this -section is dedicated to the verification of legacy code. However, the -techniques presented here can also be used for unit testing. -

    - -

    -Unit testing is used in most software development projects, and static -verification with SATABS can be very well combined with this technique. -Unit testing relies on a number test cases that yield the desired code -coverage. Such test cases are implemented by a software testing engineer in -terms of a test harness (aka test driver) and a set of function stubs. -Typically, a slight modification to the test harness allows it to be used -with SATABS. Replacing the explicit input values with non-deterministic -inputs (as explained in here and -here) guarantees that SATABS will try to -achieve full path and state coverage (due to the fact that -predicate abstraction implicitly detects equivalence classes). -However, it is not guaranteed that SATABS terminates in all cases. -Keep in mind that you must not make any assumptions about the -validity of the properties if SATABS did not run to completion! -

    - -
    -
    Further Reading
    - -

    -

    -

    - - diff --git a/regression/Makefile b/regression/Makefile index 296f583cc5e..87dcd7c93f3 100644 --- a/regression/Makefile +++ b/regression/Makefile @@ -1,4 +1,3 @@ - DIRS = ansi-c \ cbmc \ cpp \ @@ -6,9 +5,18 @@ DIRS = ansi-c \ goto-analyzer \ goto-instrument \ goto-instrument-typedef \ + goto-diff \ + invariants \ test-script \ # Empty last line test: $(foreach var,$(DIRS), $(MAKE) -C $(var) test || exit 1;) + +clean: + @for dir in *; do \ + if [ -d "$$dir" ]; then \ + $(MAKE) -C "$$dir" clean; \ + fi; \ + done; diff --git a/regression/ansi-c/Array_Declarator8/main.c b/regression/ansi-c/Array_Declarator8/main.c new file mode 100644 index 00000000000..4320252ca8d --- /dev/null +++ b/regression/ansi-c/Array_Declarator8/main.c @@ -0,0 +1,20 @@ +typedef unsigned char u1; +typedef unsigned short u2; +typedef unsigned long long u4; + +// Not resolved (as expected) +u4 B[( (u1)( ( (u1)15 ) / ( ( (((sizeof(u4))/(sizeof(u1)))*((u1)15)) > ((u1)64)) ? (0) : (1) ) ) )]; + +// Correctly resolved +u2 C[( (u1)( ( (u1)11 ) / ( ( (((sizeof(u2))/(sizeof(u1)))*((u1)11)) > ((u1)64)) ? (0) : (1) ) ) )]; + +int main() +{ + // Correctly resolved + u2 A[( (u1)( ( (u1)1 ) / ( ( (((sizeof(u2))/(sizeof(u1)))*((u1)1)) > ((u1)64)) ? (0) : (1) ) ) )]; + + // Correctly resolved + static u4 D[( (u1)( ( (u1)4 ) / ( ( (((sizeof(u4))/(sizeof(u1)))*((u1)4)) > ((u1)64)) ? (0) : (1) ) ) )]; + + return 0; +} diff --git a/regression/ansi-c/Array_Declarator8/test.desc b/regression/ansi-c/Array_Declarator8/test.desc new file mode 100644 index 00000000000..d42f8db33a9 --- /dev/null +++ b/regression/ansi-c/Array_Declarator8/test.desc @@ -0,0 +1,9 @@ +CORE +main.c + +^EXIT=(64|1)$ +^SIGNAL=0$ +^CONVERSION ERROR$ +array size of static symbol `B' is not constant$ +-- +^warning: ignoring diff --git a/regression/ansi-c/Struct_Initialization1/main.c b/regression/ansi-c/Struct_Initialization1/main.c index b497a0b60dd..f2e75463d6c 100644 --- a/regression/ansi-c/Struct_Initialization1/main.c +++ b/regression/ansi-c/Struct_Initialization1/main.c @@ -1,13 +1,19 @@ #define STATIC_ASSERT(condition) \ int some_array##__LINE__[(condition) ? 1 : -1] +struct A { + int x; + int y; +}; + struct _classinfo { char a; + struct A s; int *interfaces[]; }; -struct _classinfo nullclass1 = { 42, 0, 0 }; -struct _classinfo nullclass2 = { 42, { 0, 0 } }; +struct _classinfo nullclass1 = { 42, 1, 2, 3, 4 }; +struct _classinfo nullclass2 = { 42, { 1, 2 }, { 3, 4 } }; STATIC_ASSERT(sizeof(nullclass1)==sizeof(struct _classinfo)); STATIC_ASSERT(sizeof(nullclass2)==sizeof(struct _classinfo)); diff --git a/regression/ansi-c/Struct_Initialization1/test.desc b/regression/ansi-c/Struct_Initialization1/test.desc index fc2b1874059..466da18b2b5 100644 --- a/regression/ansi-c/Struct_Initialization1/test.desc +++ b/regression/ansi-c/Struct_Initialization1/test.desc @@ -1,4 +1,4 @@ -KNOWNBUG +CORE main.c ^EXIT=0$ diff --git a/regression/ansi-c/Struct_Initialization2/main.c b/regression/ansi-c/Struct_Initialization2/main.c new file mode 100644 index 00000000000..98cce21ebc8 --- /dev/null +++ b/regression/ansi-c/Struct_Initialization2/main.c @@ -0,0 +1,24 @@ +#define STATIC_ASSERT(condition) \ + int some_array##__LINE__[(condition) ? 1 : -1] + +struct A { + int x; + int y; + int arr[]; +}; + +struct _classinfo { + char a; + struct A s; + int *interfaces[]; +}; + +struct _classinfo nullclass1 = { 42, 1, 2, 0, 3, 4 }; +struct _classinfo nullclass2 = { 42, { 1, 2, 0 }, { 3, 4 } }; + +STATIC_ASSERT(sizeof(nullclass1)==sizeof(struct _classinfo)); +STATIC_ASSERT(sizeof(nullclass2)==sizeof(struct _classinfo)); + +int main() +{ +} diff --git a/regression/ansi-c/Struct_Initialization2/test.desc b/regression/ansi-c/Struct_Initialization2/test.desc new file mode 100644 index 00000000000..73c2caa52cd --- /dev/null +++ b/regression/ansi-c/Struct_Initialization2/test.desc @@ -0,0 +1,10 @@ +CORE +main.c + +^EXIT=(64|1)$ +^SIGNAL=0$ +^CONVERSION ERROR$ +-- +^warning: ignoring +-- +variable-length arrays in the middle of a struct are not permitted diff --git a/regression/ansi-c/arch_flags_mcpu_bad/object.intel b/regression/ansi-c/arch_flags_mcpu_bad/object.intel new file mode 100644 index 00000000000..cc6ea40a25e Binary files /dev/null and b/regression/ansi-c/arch_flags_mcpu_bad/object.intel differ diff --git a/regression/ansi-c/arch_flags_mcpu_bad/preproc.i b/regression/ansi-c/arch_flags_mcpu_bad/preproc.i new file mode 100644 index 00000000000..40378b80eb1 --- /dev/null +++ b/regression/ansi-c/arch_flags_mcpu_bad/preproc.i @@ -0,0 +1 @@ +int foo() { return 3; } diff --git a/regression/ansi-c/arch_flags_mcpu_bad/source.c b/regression/ansi-c/arch_flags_mcpu_bad/source.c new file mode 100644 index 00000000000..a7fc7966665 --- /dev/null +++ b/regression/ansi-c/arch_flags_mcpu_bad/source.c @@ -0,0 +1 @@ +int bar(){ return 9; } diff --git a/regression/ansi-c/arch_flags_mcpu_bad/test.desc b/regression/ansi-c/arch_flags_mcpu_bad/test.desc new file mode 100644 index 00000000000..c62fc66cad3 --- /dev/null +++ b/regression/ansi-c/arch_flags_mcpu_bad/test.desc @@ -0,0 +1,20 @@ +CORE +preproc.i +-mcpu=cortex-a15 -o linked-object.gb object.intel +^EXIT=(64|1)$ +^SIGNAL=0$ +-- +^warning: ignoring +^CONVERSION ERROR$ +-- +This tests the -mcpu=cortex=a15 flag that should activate ARM-32 mode. +The object file 'object.intel' was compiled from 'source.c' with goto-cc +on a 64-bit platform: + + goto-cc -c source.c + +preproc.i is already pre-processed so that it can be linked in without +needing to invoke a pre-processor from a cross-compile toolchain on your +local machine. Linking it together with the Intel object file, while +passing -mcpu=cortex-a15 on the command line, should fail because +-mcpu=cortex-a15 implies that we're trying to make an ARM executable. diff --git a/regression/ansi-c/arch_flags_mcpu_good/object.arm b/regression/ansi-c/arch_flags_mcpu_good/object.arm new file mode 100644 index 00000000000..7c14d169f62 Binary files /dev/null and b/regression/ansi-c/arch_flags_mcpu_good/object.arm differ diff --git a/regression/ansi-c/arch_flags_mcpu_good/preproc.i b/regression/ansi-c/arch_flags_mcpu_good/preproc.i new file mode 100644 index 00000000000..40378b80eb1 --- /dev/null +++ b/regression/ansi-c/arch_flags_mcpu_good/preproc.i @@ -0,0 +1 @@ +int foo() { return 3; } diff --git a/regression/ansi-c/arch_flags_mcpu_good/source.c b/regression/ansi-c/arch_flags_mcpu_good/source.c new file mode 100644 index 00000000000..a7fc7966665 --- /dev/null +++ b/regression/ansi-c/arch_flags_mcpu_good/source.c @@ -0,0 +1 @@ +int bar(){ return 9; } diff --git a/regression/ansi-c/arch_flags_mcpu_good/test.desc b/regression/ansi-c/arch_flags_mcpu_good/test.desc new file mode 100644 index 00000000000..c02992dcb8d --- /dev/null +++ b/regression/ansi-c/arch_flags_mcpu_good/test.desc @@ -0,0 +1,20 @@ +CORE +preproc.i +-mcpu=cortex-a15 -o linked-object.gb object.arm +^EXIT=0$ +^SIGNAL=0$ +-- +^warning: ignoring +^CONVERSION ERROR$ +-- +This tests the -mcpu=cortex-a15 flag that should activate ARM-32 mode. +The object file 'object.arm' was compiled from 'source.c' with goto-cc +along with an ARM cross-compiler on a 64-bit platform with the following +command line: + + goto-cc --native-compiler=arm-none-eabi-gcc -mcpu=cortex-a15 -c source.c + +preproc.i is already pre-processed so that it can be linked in without +needing to invoke a pre-processor from a cross-compile toolchain on your +local machine. Linking it together with the ARM object file, while +passing -mcpu=cortex-a15 on the command line, should succeed. diff --git a/regression/ansi-c/arch_flags_mthumb_bad/object.intel b/regression/ansi-c/arch_flags_mthumb_bad/object.intel new file mode 100644 index 00000000000..cc6ea40a25e Binary files /dev/null and b/regression/ansi-c/arch_flags_mthumb_bad/object.intel differ diff --git a/regression/ansi-c/arch_flags_mthumb_bad/preproc.i b/regression/ansi-c/arch_flags_mthumb_bad/preproc.i new file mode 100644 index 00000000000..40378b80eb1 --- /dev/null +++ b/regression/ansi-c/arch_flags_mthumb_bad/preproc.i @@ -0,0 +1 @@ +int foo() { return 3; } diff --git a/regression/ansi-c/arch_flags_mthumb_bad/source.c b/regression/ansi-c/arch_flags_mthumb_bad/source.c new file mode 100644 index 00000000000..a7fc7966665 --- /dev/null +++ b/regression/ansi-c/arch_flags_mthumb_bad/source.c @@ -0,0 +1 @@ +int bar(){ return 9; } diff --git a/regression/ansi-c/arch_flags_mthumb_bad/test.desc b/regression/ansi-c/arch_flags_mthumb_bad/test.desc new file mode 100644 index 00000000000..b3616051bd2 --- /dev/null +++ b/regression/ansi-c/arch_flags_mthumb_bad/test.desc @@ -0,0 +1,20 @@ +CORE +preproc.i +-mthumb -o linked-object.gb object.intel +^EXIT=(64|1)$ +^SIGNAL=0$ +-- +^warning: ignoring +^CONVERSION ERROR$ +-- +This tests the -mthumb flag that should activate ARM-32 mode. The object +file 'object.intel' was compiled from 'source.c' with goto-cc on a +64-bit platform: + + goto-cc -c source.c + +preproc.i is already pre-processed so that it can be linked in without +needing to invoke a pre-processor from a cross-compile toolchain on your +local machine. Linking it together with the Intel object file, while +passing -mthumb on the command line, should fail because -mthumb implies +that we're trying to make an ARM executable. diff --git a/regression/ansi-c/arch_flags_mthumb_good/object.arm b/regression/ansi-c/arch_flags_mthumb_good/object.arm new file mode 100644 index 00000000000..7c14d169f62 Binary files /dev/null and b/regression/ansi-c/arch_flags_mthumb_good/object.arm differ diff --git a/regression/ansi-c/arch_flags_mthumb_good/preproc.i b/regression/ansi-c/arch_flags_mthumb_good/preproc.i new file mode 100644 index 00000000000..40378b80eb1 --- /dev/null +++ b/regression/ansi-c/arch_flags_mthumb_good/preproc.i @@ -0,0 +1 @@ +int foo() { return 3; } diff --git a/regression/ansi-c/arch_flags_mthumb_good/source.c b/regression/ansi-c/arch_flags_mthumb_good/source.c new file mode 100644 index 00000000000..a7fc7966665 --- /dev/null +++ b/regression/ansi-c/arch_flags_mthumb_good/source.c @@ -0,0 +1 @@ +int bar(){ return 9; } diff --git a/regression/ansi-c/arch_flags_mthumb_good/test.desc b/regression/ansi-c/arch_flags_mthumb_good/test.desc new file mode 100644 index 00000000000..02a5c7389e3 --- /dev/null +++ b/regression/ansi-c/arch_flags_mthumb_good/test.desc @@ -0,0 +1,20 @@ +CORE +preproc.i +-mthumb -o linked-object.gb object.arm +^EXIT=0$ +^SIGNAL=0$ +-- +^warning: ignoring +^CONVERSION ERROR$ +-- +This tests the -mthumb flag that should activate ARM-32 mode. The object +file 'object.arm' was compiled from 'source.c' with goto-cc along with +an ARM cross-compiler on a 64-bit platform with the following command +line: + + goto-cc --native-compiler=arm-none-eabi-gcc -mthumb -c source.c + +preproc.i is already pre-processed so that it can be linked in without +needing to invoke a pre-processor from a cross-compile toolchain on your +local machine. Linking it together with the ARM object file, while +passing -mthumb on the command line, should succeed. diff --git a/regression/ansi-c/gcc_attributes10/main.c b/regression/ansi-c/gcc_attributes10/main.c new file mode 100644 index 00000000000..cf52787176e --- /dev/null +++ b/regression/ansi-c/gcc_attributes10/main.c @@ -0,0 +1,19 @@ +#define STATIC_ASSERT(condition) \ + int array##__LINE__[(condition) ? 1 : -1] + +#ifdef __GNUC__ + +int x __attribute__ ((__vector_size__ (12), __may_alias__)); +int x2 __attribute__ ((__may_alias__)); +int x3 __attribute__ ((__may_alias__, __vector_size__ (12))); + +STATIC_ASSERT(sizeof(x)==12); +STATIC_ASSERT(sizeof(x2)==sizeof(int)); +STATIC_ASSERT(sizeof(x3)==12); + +#endif + +int main(int argc, char* argv[]) +{ + return 0; +} diff --git a/regression/ansi-c/gcc_attributes10/test.desc b/regression/ansi-c/gcc_attributes10/test.desc new file mode 100644 index 00000000000..466da18b2b5 --- /dev/null +++ b/regression/ansi-c/gcc_attributes10/test.desc @@ -0,0 +1,8 @@ +CORE +main.c + +^EXIT=0$ +^SIGNAL=0$ +-- +^warning: ignoring +^CONVERSION ERROR$ diff --git a/regression/ansi-c/gcc_attributes5/test.desc b/regression/ansi-c/gcc_attributes5/test.desc index fc2b1874059..466da18b2b5 100644 --- a/regression/ansi-c/gcc_attributes5/test.desc +++ b/regression/ansi-c/gcc_attributes5/test.desc @@ -1,4 +1,4 @@ -KNOWNBUG +CORE main.c ^EXIT=0$ diff --git a/regression/ansi-c/gcc_builtins6/main.c b/regression/ansi-c/gcc_builtins6/main.c new file mode 100644 index 00000000000..706dd6196be --- /dev/null +++ b/regression/ansi-c/gcc_builtins6/main.c @@ -0,0 +1,23 @@ +#include + +struct S +{ + int x; + union { + int y; + struct S2 + { + int z; + } s[1]; + } u[2]; +}; + +int main() +{ + int A[offsetof(struct S, u[0].y)==sizeof(int)?1:-1]; +#if defined(__GNUC__) && !defined(__clang__) + int B[offsetof(struct S, u->y)==sizeof(int)?1:-1]; + int C[offsetof(struct S, u->s[0].z)==sizeof(int)?1:-1]; +#endif + return 0; +} diff --git a/regression/ansi-c/gcc_builtins6/test.desc b/regression/ansi-c/gcc_builtins6/test.desc new file mode 100644 index 00000000000..466da18b2b5 --- /dev/null +++ b/regression/ansi-c/gcc_builtins6/test.desc @@ -0,0 +1,8 @@ +CORE +main.c + +^EXIT=0$ +^SIGNAL=0$ +-- +^warning: ignoring +^CONVERSION ERROR$ diff --git a/regression/ansi-c/message_handling1/main.c b/regression/ansi-c/message_handling1/main.c new file mode 100644 index 00000000000..00193b44b77 --- /dev/null +++ b/regression/ansi-c/message_handling1/main.c @@ -0,0 +1,9 @@ +int main() +{ + goto bla; + + for(int i=0; i<5; ++i) + { +bla: i=10; + } +} diff --git a/regression/ansi-c/message_handling1/test.desc b/regression/ansi-c/message_handling1/test.desc new file mode 100644 index 00000000000..277edf65161 --- /dev/null +++ b/regression/ansi-c/message_handling1/test.desc @@ -0,0 +1,7 @@ +CORE +main.c +--verbosity 2 +^EXIT=0$ +^SIGNAL=0$ +-- +encountered goto `bla' that enters one or more lexical blocks diff --git a/regression/ansi-c/sizeof4/main.c b/regression/ansi-c/sizeof4/main.c new file mode 100644 index 00000000000..364f64bb797 --- /dev/null +++ b/regression/ansi-c/sizeof4/main.c @@ -0,0 +1,12 @@ + +#define STATIC_ASSERT(condition) \ + int some_array##__LINE__[(condition) ? 1 : -1]; + +// The result of boolean operators is always an int +STATIC_ASSERT(sizeof(1.0 && 1.0)==sizeof(int)); +STATIC_ASSERT(sizeof(1.0 || 1.0)==sizeof(int)); +STATIC_ASSERT(sizeof(!1.0)==sizeof(int)); + +int main() +{ +} diff --git a/regression/ansi-c/sizeof4/test.desc b/regression/ansi-c/sizeof4/test.desc new file mode 100644 index 00000000000..fc2b1874059 --- /dev/null +++ b/regression/ansi-c/sizeof4/test.desc @@ -0,0 +1,8 @@ +KNOWNBUG +main.c + +^EXIT=0$ +^SIGNAL=0$ +-- +^warning: ignoring +^CONVERSION ERROR$ diff --git a/regression/cbmc-java/LocalVarTable5/test.desc b/regression/cbmc-java/LocalVarTable5/test.desc index bfe77ab09ad..6f55a0d2bc6 100644 --- a/regression/cbmc-java/LocalVarTable5/test.desc +++ b/regression/cbmc-java/LocalVarTable5/test.desc @@ -4,7 +4,7 @@ test.class dead anonlocal::1i dead anonlocal::2i dead anonlocal::3a -dead new_tmp0 +dead new_tmp[0-9]+ ^EXIT=0$ ^SIGNAL=0$ -- diff --git a/regression/cbmc-java/array2/test.class b/regression/cbmc-java/array2/test.class new file mode 100644 index 00000000000..507d6622e5c Binary files /dev/null and b/regression/cbmc-java/array2/test.class differ diff --git a/regression/cbmc-java/array2/test.desc b/regression/cbmc-java/array2/test.desc new file mode 100644 index 00000000000..6d2226bb26b --- /dev/null +++ b/regression/cbmc-java/array2/test.desc @@ -0,0 +1,6 @@ +CORE +test.class +--function test.f --cover location +\d+ of \d+ covered +-- +^warning: ignoring diff --git a/regression/cbmc-java/array2/test.java b/regression/cbmc-java/array2/test.java new file mode 100644 index 00000000000..075017405ee --- /dev/null +++ b/regression/cbmc-java/array2/test.java @@ -0,0 +1,16 @@ +public class test { + + public void f(int unknown) { + + int[] arr; + if(unknown > 0) + arr = new int[1]; + else + arr = new int[0]; + + if(unknown > 0) + arr[0]=1; + + } + +} diff --git a/regression/cbmc-java/destructor1/test.desc b/regression/cbmc-java/destructor1/test.desc index 53856821b22..32dea0b83f5 100644 --- a/regression/cbmc-java/destructor1/test.desc +++ b/regression/cbmc-java/destructor1/test.desc @@ -5,4 +5,4 @@ Break.class ^SIGNAL=0$ dead i; -- -GOTO 10 +GOTO 11 diff --git a/regression/cbmc-java/integer_without_simplify1/test.class b/regression/cbmc-java/integer_without_simplify1/test.class new file mode 100644 index 00000000000..1ee5d36d95a Binary files /dev/null and b/regression/cbmc-java/integer_without_simplify1/test.class differ diff --git a/regression/cbmc-java/integer_without_simplify1/test.desc b/regression/cbmc-java/integer_without_simplify1/test.desc new file mode 100644 index 00000000000..284277c7b4a --- /dev/null +++ b/regression/cbmc-java/integer_without_simplify1/test.desc @@ -0,0 +1,7 @@ +CORE +test.class +--no-simplify --function test.f --cover location +^EXIT=0$ +^SIGNAL=0$ +-- +^warning: ignoring diff --git a/regression/cbmc-java/integer_without_simplify1/test.java b/regression/cbmc-java/integer_without_simplify1/test.java new file mode 100644 index 00000000000..62b2060b7c0 --- /dev/null +++ b/regression/cbmc-java/integer_without_simplify1/test.java @@ -0,0 +1,10 @@ + +public class test { + + public void f() { + + int x = 50; + + } + +} diff --git a/regression/cbmc-java/stack_var1/README b/regression/cbmc-java/stack_var1/README new file mode 100644 index 00000000000..7a032cccbcd --- /dev/null +++ b/regression/cbmc-java/stack_var1/README @@ -0,0 +1,9 @@ +This regression test is created from the .j file with the jasmin assembler. +https://github.com/Sable/jasmin + +On Ubuntu, it is available as jasmin-sable. To convert a .j file, it is +sufficient to do + +> jasmin $FILE.j + +and it will create the corresponding $FILE.class file. diff --git a/regression/cbmc-java/stack_var1/stack_test.class b/regression/cbmc-java/stack_var1/stack_test.class new file mode 100644 index 00000000000..2b723f49df8 Binary files /dev/null and b/regression/cbmc-java/stack_var1/stack_test.class differ diff --git a/regression/cbmc-java/stack_var1/stack_test.java b/regression/cbmc-java/stack_var1/stack_test.java new file mode 100644 index 00000000000..cb404e89473 --- /dev/null +++ b/regression/cbmc-java/stack_var1/stack_test.java @@ -0,0 +1,7 @@ +public class stack_test { + public static void main(String[] args) { + stack_var1 s = new stack_var1(); + int n = s.f(1); + assert(n==0); + } +} diff --git a/regression/cbmc-java/stack_var1/stack_var1.class b/regression/cbmc-java/stack_var1/stack_var1.class new file mode 100644 index 00000000000..67a2f733081 Binary files /dev/null and b/regression/cbmc-java/stack_var1/stack_var1.class differ diff --git a/regression/cbmc-java/stack_var1/stack_var1.j b/regression/cbmc-java/stack_var1/stack_var1.j new file mode 100644 index 00000000000..a3736df18e2 --- /dev/null +++ b/regression/cbmc-java/stack_var1/stack_var1.j @@ -0,0 +1,22 @@ +.class public stack_var1 +.super java/lang/Object + +.method public ()V + aload_0 + invokenonvirtual java/lang/Object/()V + return +.end method + +.method public f(I)I + .limit stack 2 + .limit locals 2 + + ;; copy of arg on stack + iload_1 + ;; increment arg + iinc 1 1 + ;; incremented copy on stack + iload_1 + isub + ireturn +.end method diff --git a/regression/cbmc-java/stack_var1/test.desc b/regression/cbmc-java/stack_var1/test.desc new file mode 100644 index 00000000000..3bf59401a5a --- /dev/null +++ b/regression/cbmc-java/stack_var1/test.desc @@ -0,0 +1,9 @@ +CORE +stack_test.class + +^EXIT=10$ +^SIGNAL=0$ +^.*assertion at file stack_test.java line 5 function.*: FAILURE$ +^VERIFICATION FAILED$ +-- +^warning: ignoring diff --git a/regression/cbmc-java/stack_var10/README b/regression/cbmc-java/stack_var10/README new file mode 100644 index 00000000000..7a032cccbcd --- /dev/null +++ b/regression/cbmc-java/stack_var10/README @@ -0,0 +1,9 @@ +This regression test is created from the .j file with the jasmin assembler. +https://github.com/Sable/jasmin + +On Ubuntu, it is available as jasmin-sable. To convert a .j file, it is +sufficient to do + +> jasmin $FILE.j + +and it will create the corresponding $FILE.class file. diff --git a/regression/cbmc-java/stack_var10/stack_test.class b/regression/cbmc-java/stack_var10/stack_test.class new file mode 100644 index 00000000000..09a5b5a8de9 Binary files /dev/null and b/regression/cbmc-java/stack_var10/stack_test.class differ diff --git a/regression/cbmc-java/stack_var10/stack_test.java b/regression/cbmc-java/stack_var10/stack_test.java new file mode 100644 index 00000000000..3831ddea4ab --- /dev/null +++ b/regression/cbmc-java/stack_var10/stack_test.java @@ -0,0 +1,7 @@ +public class stack_test { + public static void main(String[] args) { + stack_var10 s = new stack_var10(); + int n = s.f(); + assert(n==0); + } +} diff --git a/regression/cbmc-java/stack_var10/stack_var10.class b/regression/cbmc-java/stack_var10/stack_var10.class new file mode 100644 index 00000000000..68bab7d3abd Binary files /dev/null and b/regression/cbmc-java/stack_var10/stack_var10.class differ diff --git a/regression/cbmc-java/stack_var10/stack_var10.j b/regression/cbmc-java/stack_var10/stack_var10.j new file mode 100644 index 00000000000..0d6fe63957f --- /dev/null +++ b/regression/cbmc-java/stack_var10/stack_var10.j @@ -0,0 +1,28 @@ +.class public stack_var10 +.super java/lang/Object + +.field private static n I + +.method public ()V +.limit stack 5 + aload_0 + invokenonvirtual java/lang/Object/()V + return +.end method + +.method public f()I + .limit stack 8 + .limit locals 5 + + iconst_1 + istore_1 + iconst_0 + istore_2 + ;; lvar1 is 1, lvar2 is 0 + iload_1 + iload_2 + ;; on stack 1, 0 + istore_1 + ;; store 0 into lvar1 + ireturn +.end method diff --git a/regression/cbmc-java/stack_var10/test.desc b/regression/cbmc-java/stack_var10/test.desc new file mode 100644 index 00000000000..3bf59401a5a --- /dev/null +++ b/regression/cbmc-java/stack_var10/test.desc @@ -0,0 +1,9 @@ +CORE +stack_test.class + +^EXIT=10$ +^SIGNAL=0$ +^.*assertion at file stack_test.java line 5 function.*: FAILURE$ +^VERIFICATION FAILED$ +-- +^warning: ignoring diff --git a/regression/cbmc-java/stack_var11/README b/regression/cbmc-java/stack_var11/README new file mode 100644 index 00000000000..7a032cccbcd --- /dev/null +++ b/regression/cbmc-java/stack_var11/README @@ -0,0 +1,9 @@ +This regression test is created from the .j file with the jasmin assembler. +https://github.com/Sable/jasmin + +On Ubuntu, it is available as jasmin-sable. To convert a .j file, it is +sufficient to do + +> jasmin $FILE.j + +and it will create the corresponding $FILE.class file. diff --git a/regression/cbmc-java/stack_var11/stack_test.class b/regression/cbmc-java/stack_var11/stack_test.class new file mode 100644 index 00000000000..3d46a551ddc Binary files /dev/null and b/regression/cbmc-java/stack_var11/stack_test.class differ diff --git a/regression/cbmc-java/stack_var11/stack_test.java b/regression/cbmc-java/stack_var11/stack_test.java new file mode 100644 index 00000000000..59c979f849b --- /dev/null +++ b/regression/cbmc-java/stack_var11/stack_test.java @@ -0,0 +1,7 @@ +public class stack_test { + public static void main(String[] args) { + stack_var11 s = new stack_var11(); + int n = s.f(); + assert(n==0); + } +} diff --git a/regression/cbmc-java/stack_var11/stack_var11.class b/regression/cbmc-java/stack_var11/stack_var11.class new file mode 100644 index 00000000000..a19f186ab03 Binary files /dev/null and b/regression/cbmc-java/stack_var11/stack_var11.class differ diff --git a/regression/cbmc-java/stack_var11/stack_var11.j b/regression/cbmc-java/stack_var11/stack_var11.j new file mode 100644 index 00000000000..16818a4a4e3 --- /dev/null +++ b/regression/cbmc-java/stack_var11/stack_var11.j @@ -0,0 +1,31 @@ +.class public stack_var11 +.super java/lang/Object + +.field private arr [I + +.method public ()V +.limit stack 5 + aload_0 + invokenonvirtual java/lang/Object/()V + aload_0 + iconst_2 + newarray int + putfield stack_var11/arr [I + return +.end method + +.method public f()I + .limit stack 8 + .limit locals 5 + aload_0 + getfield stack_var11/arr [I + iconst_0 + iaload ;; put arr[0] on stack (currently 0) + aload_0 + getfield stack_var11/arr [I + iconst_0 + iconst_1 + iastore ;; store 1 in arr[0], + ;; value on stack should not be touched + ireturn +.end method diff --git a/regression/cbmc-java/stack_var2/README b/regression/cbmc-java/stack_var2/README new file mode 100644 index 00000000000..7a032cccbcd --- /dev/null +++ b/regression/cbmc-java/stack_var2/README @@ -0,0 +1,9 @@ +This regression test is created from the .j file with the jasmin assembler. +https://github.com/Sable/jasmin + +On Ubuntu, it is available as jasmin-sable. To convert a .j file, it is +sufficient to do + +> jasmin $FILE.j + +and it will create the corresponding $FILE.class file. diff --git a/regression/cbmc-java/stack_var2/stack_test.class b/regression/cbmc-java/stack_var2/stack_test.class new file mode 100644 index 00000000000..f26c64d43d4 Binary files /dev/null and b/regression/cbmc-java/stack_var2/stack_test.class differ diff --git a/regression/cbmc-java/stack_var2/stack_test.java b/regression/cbmc-java/stack_var2/stack_test.java new file mode 100644 index 00000000000..822716f691c --- /dev/null +++ b/regression/cbmc-java/stack_var2/stack_test.java @@ -0,0 +1,7 @@ +public class stack_test { + public static void main(String[] args) { + stack_var2 s = new stack_var2(); + int n = s.f(1); + assert(n==0); + } +} diff --git a/regression/cbmc-java/stack_var2/stack_var2.class b/regression/cbmc-java/stack_var2/stack_var2.class new file mode 100644 index 00000000000..6db13604864 Binary files /dev/null and b/regression/cbmc-java/stack_var2/stack_var2.class differ diff --git a/regression/cbmc-java/stack_var2/stack_var2.j b/regression/cbmc-java/stack_var2/stack_var2.j new file mode 100644 index 00000000000..e20a174070c --- /dev/null +++ b/regression/cbmc-java/stack_var2/stack_var2.j @@ -0,0 +1,25 @@ +.class public stack_var2 +.super java/lang/Object + +.method public ()V + aload_0 + invokenonvirtual java/lang/Object/()V + return +.end method + +.method public f(I)I + .limit stack 3 + .limit locals 2 + + ;; push local var1 + iload_1 + ;; duplicate + dup + ;; increment local var1 + iinc 1 1 + ;; push local var1 + iload_1 + isub + ;; incremented copy on stack + ireturn +.end method diff --git a/regression/cbmc-java/stack_var2/test.desc b/regression/cbmc-java/stack_var2/test.desc new file mode 100644 index 00000000000..3bf59401a5a --- /dev/null +++ b/regression/cbmc-java/stack_var2/test.desc @@ -0,0 +1,9 @@ +CORE +stack_test.class + +^EXIT=10$ +^SIGNAL=0$ +^.*assertion at file stack_test.java line 5 function.*: FAILURE$ +^VERIFICATION FAILED$ +-- +^warning: ignoring diff --git a/regression/cbmc-java/stack_var3/README b/regression/cbmc-java/stack_var3/README new file mode 100644 index 00000000000..7a032cccbcd --- /dev/null +++ b/regression/cbmc-java/stack_var3/README @@ -0,0 +1,9 @@ +This regression test is created from the .j file with the jasmin assembler. +https://github.com/Sable/jasmin + +On Ubuntu, it is available as jasmin-sable. To convert a .j file, it is +sufficient to do + +> jasmin $FILE.j + +and it will create the corresponding $FILE.class file. diff --git a/regression/cbmc-java/stack_var3/stack_test.class b/regression/cbmc-java/stack_var3/stack_test.class new file mode 100644 index 00000000000..a42cc9101a1 Binary files /dev/null and b/regression/cbmc-java/stack_var3/stack_test.class differ diff --git a/regression/cbmc-java/stack_var3/stack_test.java b/regression/cbmc-java/stack_var3/stack_test.java new file mode 100644 index 00000000000..7ffc016070c --- /dev/null +++ b/regression/cbmc-java/stack_var3/stack_test.java @@ -0,0 +1,7 @@ +public class stack_test { + public static void main(String[] args) { + stack_var3 s = new stack_var3(); + int n = s.f(); + assert(n==0); + } +} diff --git a/regression/cbmc-java/stack_var3/stack_var3.class b/regression/cbmc-java/stack_var3/stack_var3.class new file mode 100644 index 00000000000..9a3a0d6d370 Binary files /dev/null and b/regression/cbmc-java/stack_var3/stack_var3.class differ diff --git a/regression/cbmc-java/stack_var3/stack_var3.j b/regression/cbmc-java/stack_var3/stack_var3.j new file mode 100644 index 00000000000..f215d15b4bc --- /dev/null +++ b/regression/cbmc-java/stack_var3/stack_var3.j @@ -0,0 +1,33 @@ +.class public stack_var3 +.super java/lang/Object + +.method public ()V + aload_0 + invokenonvirtual java/lang/Object/()V + return +.end method + +.method public f()I + .limit stack 5 + .limit locals 3 + + ;; 1->var1 + ;; 0->var2 + iconst_1 + istore_1 + iconst_0 + istore_2 + ;; push local var2 / var1 + iload_2 + iload_1 + ;; dup var1 + dup_x1 + ;; sub one from var1 + iinc 1 -1 + ;; pop first var1 + pop + ;; sub + isub + ;; incremented copy on stack + ireturn +.end method diff --git a/regression/cbmc-java/stack_var3/test.desc b/regression/cbmc-java/stack_var3/test.desc new file mode 100644 index 00000000000..3bf59401a5a --- /dev/null +++ b/regression/cbmc-java/stack_var3/test.desc @@ -0,0 +1,9 @@ +CORE +stack_test.class + +^EXIT=10$ +^SIGNAL=0$ +^.*assertion at file stack_test.java line 5 function.*: FAILURE$ +^VERIFICATION FAILED$ +-- +^warning: ignoring diff --git a/regression/cbmc-java/stack_var4/README b/regression/cbmc-java/stack_var4/README new file mode 100644 index 00000000000..7a032cccbcd --- /dev/null +++ b/regression/cbmc-java/stack_var4/README @@ -0,0 +1,9 @@ +This regression test is created from the .j file with the jasmin assembler. +https://github.com/Sable/jasmin + +On Ubuntu, it is available as jasmin-sable. To convert a .j file, it is +sufficient to do + +> jasmin $FILE.j + +and it will create the corresponding $FILE.class file. diff --git a/regression/cbmc-java/stack_var4/stack_test.class b/regression/cbmc-java/stack_var4/stack_test.class new file mode 100644 index 00000000000..cfbb80f78e8 Binary files /dev/null and b/regression/cbmc-java/stack_var4/stack_test.class differ diff --git a/regression/cbmc-java/stack_var4/stack_test.java b/regression/cbmc-java/stack_var4/stack_test.java new file mode 100644 index 00000000000..1088dd5ac2e --- /dev/null +++ b/regression/cbmc-java/stack_var4/stack_test.java @@ -0,0 +1,7 @@ +public class stack_test { + public static void main(String[] args) { + stack_var4 s = new stack_var4(); + int n = s.f(); + assert(n==0); + } +} diff --git a/regression/cbmc-java/stack_var4/stack_var4.class b/regression/cbmc-java/stack_var4/stack_var4.class new file mode 100644 index 00000000000..782443dd6e3 Binary files /dev/null and b/regression/cbmc-java/stack_var4/stack_var4.class differ diff --git a/regression/cbmc-java/stack_var4/stack_var4.j b/regression/cbmc-java/stack_var4/stack_var4.j new file mode 100644 index 00000000000..99eecf3794a --- /dev/null +++ b/regression/cbmc-java/stack_var4/stack_var4.j @@ -0,0 +1,37 @@ +.class public stack_var4 +.super java/lang/Object + +.method public ()V + aload_0 + invokenonvirtual java/lang/Object/()V + return +.end method + +.method public f()I + .limit stack 5 + .limit locals 4 + + ;; 0->var1 + ;; 1->var2 + ;; 2->var3 + iconst_0 + istore_1 + iconst_1 + istore_2 + iconst_2 + istore_3 + + ;; push local var3 / var2 / var1 + iload_3 + iload_2 + iload_1 + ;; push var1 in front of var3 + dup_x2 + ;; add one to local var 1 + iinc 1 1 + pop + pop + pop + ;; incremented copy on stack + ireturn +.end method diff --git a/regression/cbmc-java/stack_var4/test.desc b/regression/cbmc-java/stack_var4/test.desc new file mode 100644 index 00000000000..805e44acccd --- /dev/null +++ b/regression/cbmc-java/stack_var4/test.desc @@ -0,0 +1,10 @@ +CORE +stack_test.class + +^EXIT=0$ +^SIGNAL=0$ +^.*assertion at file stack_test.java line 5 function.*: SUCCESS +$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc-java/stack_var5/README b/regression/cbmc-java/stack_var5/README new file mode 100644 index 00000000000..7a032cccbcd --- /dev/null +++ b/regression/cbmc-java/stack_var5/README @@ -0,0 +1,9 @@ +This regression test is created from the .j file with the jasmin assembler. +https://github.com/Sable/jasmin + +On Ubuntu, it is available as jasmin-sable. To convert a .j file, it is +sufficient to do + +> jasmin $FILE.j + +and it will create the corresponding $FILE.class file. diff --git a/regression/cbmc-java/stack_var5/stack_test.class b/regression/cbmc-java/stack_var5/stack_test.class new file mode 100644 index 00000000000..57cf43dac86 Binary files /dev/null and b/regression/cbmc-java/stack_var5/stack_test.class differ diff --git a/regression/cbmc-java/stack_var5/stack_test.java b/regression/cbmc-java/stack_var5/stack_test.java new file mode 100644 index 00000000000..bfcbe79325d --- /dev/null +++ b/regression/cbmc-java/stack_var5/stack_test.java @@ -0,0 +1,7 @@ +public class stack_test { + public static void main(String[] args) { + stack_var5 s = new stack_var5(); + int n = s.f(); + assert(n==1); + } +} diff --git a/regression/cbmc-java/stack_var5/stack_var5.class b/regression/cbmc-java/stack_var5/stack_var5.class new file mode 100644 index 00000000000..6230e78a9c7 Binary files /dev/null and b/regression/cbmc-java/stack_var5/stack_var5.class differ diff --git a/regression/cbmc-java/stack_var5/stack_var5.j b/regression/cbmc-java/stack_var5/stack_var5.j new file mode 100644 index 00000000000..0871fb68e0b --- /dev/null +++ b/regression/cbmc-java/stack_var5/stack_var5.j @@ -0,0 +1,33 @@ +.class public stack_var5 +.super java/lang/Object + +.method public ()V + aload_0 + invokenonvirtual java/lang/Object/()V + return +.end method + +.method public f()I + .limit stack 4 + .limit locals 4 + + ;; 1->var1 + ;; 2->var2 + iconst_1 + istore_1 + iconst_2 + istore_2 + + ;; push local var2 / var1 + iload_2 + iload_1 + + ;; duplicate var2 / var1 + dup2 + ;; add one to local var 1 + iinc 1 1 + ;; sub + isub + ;; incremented copy on stack + ireturn +.end method diff --git a/regression/cbmc-java/stack_var5/test.desc b/regression/cbmc-java/stack_var5/test.desc new file mode 100644 index 00000000000..805e44acccd --- /dev/null +++ b/regression/cbmc-java/stack_var5/test.desc @@ -0,0 +1,10 @@ +CORE +stack_test.class + +^EXIT=0$ +^SIGNAL=0$ +^.*assertion at file stack_test.java line 5 function.*: SUCCESS +$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc-java/stack_var6/README b/regression/cbmc-java/stack_var6/README new file mode 100644 index 00000000000..7a032cccbcd --- /dev/null +++ b/regression/cbmc-java/stack_var6/README @@ -0,0 +1,9 @@ +This regression test is created from the .j file with the jasmin assembler. +https://github.com/Sable/jasmin + +On Ubuntu, it is available as jasmin-sable. To convert a .j file, it is +sufficient to do + +> jasmin $FILE.j + +and it will create the corresponding $FILE.class file. diff --git a/regression/cbmc-java/stack_var6/stack_test.class b/regression/cbmc-java/stack_var6/stack_test.class new file mode 100644 index 00000000000..c5e765b667b Binary files /dev/null and b/regression/cbmc-java/stack_var6/stack_test.class differ diff --git a/regression/cbmc-java/stack_var6/stack_test.java b/regression/cbmc-java/stack_var6/stack_test.java new file mode 100644 index 00000000000..392d200d370 --- /dev/null +++ b/regression/cbmc-java/stack_var6/stack_test.java @@ -0,0 +1,7 @@ +public class stack_test { + public static void main(String[] args) { + stack_var6 s = new stack_var6(); + int n = s.f(1,2,4); + assert(n==-2); + } +} diff --git a/regression/cbmc-java/stack_var6/stack_var6.class b/regression/cbmc-java/stack_var6/stack_var6.class new file mode 100644 index 00000000000..05223a9a349 Binary files /dev/null and b/regression/cbmc-java/stack_var6/stack_var6.class differ diff --git a/regression/cbmc-java/stack_var6/stack_var6.j b/regression/cbmc-java/stack_var6/stack_var6.j new file mode 100644 index 00000000000..19108f70e36 --- /dev/null +++ b/regression/cbmc-java/stack_var6/stack_var6.j @@ -0,0 +1,25 @@ +.class public stack_var6 +.super java/lang/Object + +.method public ()V + aload_0 + invokenonvirtual java/lang/Object/()V + return +.end method + +.method public f(III)I + .limit stack 8 + .limit locals 5 + + ;; push local var3 / var2 / var1 + iload_1 + iload_2 + iload_3 + dup2_x1 + ;; add one to local var 2 + iinc 2 1 + ;; sub + isub + ;; incremented copy on stack + ireturn +.end method diff --git a/regression/cbmc-java/stack_var6/test.desc b/regression/cbmc-java/stack_var6/test.desc new file mode 100644 index 00000000000..805e44acccd --- /dev/null +++ b/regression/cbmc-java/stack_var6/test.desc @@ -0,0 +1,10 @@ +CORE +stack_test.class + +^EXIT=0$ +^SIGNAL=0$ +^.*assertion at file stack_test.java line 5 function.*: SUCCESS +$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc-java/stack_var7/README b/regression/cbmc-java/stack_var7/README new file mode 100644 index 00000000000..7a032cccbcd --- /dev/null +++ b/regression/cbmc-java/stack_var7/README @@ -0,0 +1,9 @@ +This regression test is created from the .j file with the jasmin assembler. +https://github.com/Sable/jasmin + +On Ubuntu, it is available as jasmin-sable. To convert a .j file, it is +sufficient to do + +> jasmin $FILE.j + +and it will create the corresponding $FILE.class file. diff --git a/regression/cbmc-java/stack_var7/stack_test.class b/regression/cbmc-java/stack_var7/stack_test.class new file mode 100644 index 00000000000..21eabe9a029 Binary files /dev/null and b/regression/cbmc-java/stack_var7/stack_test.class differ diff --git a/regression/cbmc-java/stack_var7/stack_test.java b/regression/cbmc-java/stack_var7/stack_test.java new file mode 100644 index 00000000000..b742878507e --- /dev/null +++ b/regression/cbmc-java/stack_var7/stack_test.java @@ -0,0 +1,7 @@ +public class stack_test { + public static void main(String[] args) { + stack_var7 s = new stack_var7(); + int n = s.f(); + assert(n==1); + } +} diff --git a/regression/cbmc-java/stack_var7/stack_var7.class b/regression/cbmc-java/stack_var7/stack_var7.class new file mode 100644 index 00000000000..dcc6f0fc1b6 Binary files /dev/null and b/regression/cbmc-java/stack_var7/stack_var7.class differ diff --git a/regression/cbmc-java/stack_var7/stack_var7.j b/regression/cbmc-java/stack_var7/stack_var7.j new file mode 100644 index 00000000000..e75f96b833d --- /dev/null +++ b/regression/cbmc-java/stack_var7/stack_var7.j @@ -0,0 +1,43 @@ +.class public stack_var7 +.super java/lang/Object + +.method public ()V + aload_0 + invokenonvirtual java/lang/Object/()V + return +.end method + +.method public f()I + .limit stack 8 + .limit locals 5 + + ;; 1->var1 + ;; 2->var2 + ;; 4->var3 + ;; 8->var4 + iconst_1 + istore_1 + iconst_2 + istore_2 + iconst_4 + istore_3 + bipush 8 + istore 4 + ;; push local var4 / var3 / var2 / var1 + iload 4 + iload_3 + iload_2 + iload 1 + ;; push var2 / var1 in on head + dup2_x2 + ;; add one to local var 1 + iinc 1 1 + pop + pop + pop + pop + ;; sub + isub + ;; incremented copy on stack + ireturn +.end method diff --git a/regression/cbmc-java/stack_var7/test.desc b/regression/cbmc-java/stack_var7/test.desc new file mode 100644 index 00000000000..805e44acccd --- /dev/null +++ b/regression/cbmc-java/stack_var7/test.desc @@ -0,0 +1,10 @@ +CORE +stack_test.class + +^EXIT=0$ +^SIGNAL=0$ +^.*assertion at file stack_test.java line 5 function.*: SUCCESS +$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc-java/stack_var8/README b/regression/cbmc-java/stack_var8/README new file mode 100644 index 00000000000..7a032cccbcd --- /dev/null +++ b/regression/cbmc-java/stack_var8/README @@ -0,0 +1,9 @@ +This regression test is created from the .j file with the jasmin assembler. +https://github.com/Sable/jasmin + +On Ubuntu, it is available as jasmin-sable. To convert a .j file, it is +sufficient to do + +> jasmin $FILE.j + +and it will create the corresponding $FILE.class file. diff --git a/regression/cbmc-java/stack_var8/stack_test.class b/regression/cbmc-java/stack_var8/stack_test.class new file mode 100644 index 00000000000..8ea61591cbc Binary files /dev/null and b/regression/cbmc-java/stack_var8/stack_test.class differ diff --git a/regression/cbmc-java/stack_var8/stack_test.java b/regression/cbmc-java/stack_var8/stack_test.java new file mode 100644 index 00000000000..3a288890e69 --- /dev/null +++ b/regression/cbmc-java/stack_var8/stack_test.java @@ -0,0 +1,7 @@ +public class stack_test { + public static void main(String[] args) { + stack_var8 s = new stack_var8(); + int n = s.f(); + assert(n==0); + } +} diff --git a/regression/cbmc-java/stack_var8/stack_var8.class b/regression/cbmc-java/stack_var8/stack_var8.class new file mode 100644 index 00000000000..5298a7d8c92 Binary files /dev/null and b/regression/cbmc-java/stack_var8/stack_var8.class differ diff --git a/regression/cbmc-java/stack_var8/stack_var8.j b/regression/cbmc-java/stack_var8/stack_var8.j new file mode 100644 index 00000000000..d5bec33279d --- /dev/null +++ b/regression/cbmc-java/stack_var8/stack_var8.j @@ -0,0 +1,27 @@ +.class public stack_var8 +.super java/lang/Object + +.field private n I + +.method public ()V +.limit stack 5 + aload_0 + invokenonvirtual java/lang/Object/()V + aload_0 + iconst_0 + putfield stack_var8/n I + return +.end method + +.method public f()I + .limit stack 8 + .limit locals 5 + + aload_0 + getfield stack_var8/n I + aload_0 + iconst_1 + putfield stack_var8/n I + + ireturn +.end method diff --git a/regression/cbmc-java/stack_var9/README b/regression/cbmc-java/stack_var9/README new file mode 100644 index 00000000000..7a032cccbcd --- /dev/null +++ b/regression/cbmc-java/stack_var9/README @@ -0,0 +1,9 @@ +This regression test is created from the .j file with the jasmin assembler. +https://github.com/Sable/jasmin + +On Ubuntu, it is available as jasmin-sable. To convert a .j file, it is +sufficient to do + +> jasmin $FILE.j + +and it will create the corresponding $FILE.class file. diff --git a/regression/cbmc-java/stack_var9/stack_test.class b/regression/cbmc-java/stack_var9/stack_test.class new file mode 100644 index 00000000000..4f20f14f7d1 Binary files /dev/null and b/regression/cbmc-java/stack_var9/stack_test.class differ diff --git a/regression/cbmc-java/stack_var9/stack_test.java b/regression/cbmc-java/stack_var9/stack_test.java new file mode 100644 index 00000000000..994e7974026 --- /dev/null +++ b/regression/cbmc-java/stack_var9/stack_test.java @@ -0,0 +1,7 @@ +public class stack_test { + public static void main(String[] args) { + stack_var9 s = new stack_var9(); + int n = s.f(); + assert(n==0); + } +} diff --git a/regression/cbmc-java/stack_var9/stack_var9.class b/regression/cbmc-java/stack_var9/stack_var9.class new file mode 100644 index 00000000000..1fa90019a0e Binary files /dev/null and b/regression/cbmc-java/stack_var9/stack_var9.class differ diff --git a/regression/cbmc-java/stack_var9/stack_var9.j b/regression/cbmc-java/stack_var9/stack_var9.j new file mode 100644 index 00000000000..aeee091def0 --- /dev/null +++ b/regression/cbmc-java/stack_var9/stack_var9.j @@ -0,0 +1,24 @@ +.class public stack_var9 +.super java/lang/Object + +.field private static n I + +.method public ()V +.limit stack 5 + aload_0 + invokenonvirtual java/lang/Object/()V + iconst_0 + putstatic stack_var9/n I + return +.end method + +.method public f()I + .limit stack 8 + .limit locals 5 + + getstatic stack_var9/n I + iconst_1 + putstatic stack_var9/n I + + ireturn +.end method diff --git a/regression/cbmc/Float-Rounding3/main.c b/regression/cbmc/Float-Rounding3/main.c new file mode 100644 index 00000000000..bc4062b91fd --- /dev/null +++ b/regression/cbmc/Float-Rounding3/main.c @@ -0,0 +1,31 @@ +// This is C99, but currently only works with clang. +// gcc and Visual Studio appear to hard-wire FLT_ROUNDS to 1. + +#ifdef __clang__ + +#include +#include +#include + +int main() +{ + fesetround(FE_DOWNWARD); + assert(FLT_ROUNDS==3); + + fesetround(FE_TONEAREST); + assert(FLT_ROUNDS==1); + + fesetround(FE_TOWARDZERO); + assert(FLT_ROUNDS==0); + + fesetround(FE_UPWARD); + assert(FLT_ROUNDS==2); +} + +#else + +int main() +{ +} + +#endif diff --git a/regression/cbmc/Float-Rounding3/test.desc b/regression/cbmc/Float-Rounding3/test.desc new file mode 100644 index 00000000000..9efefbc7362 --- /dev/null +++ b/regression/cbmc/Float-Rounding3/test.desc @@ -0,0 +1,8 @@ +CORE +main.c + +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc/Linking5/test.desc b/regression/cbmc/Linking5/test.desc index 14350cd4399..d88e6744dbd 100644 --- a/regression/cbmc/Linking5/test.desc +++ b/regression/cbmc/Linking5/test.desc @@ -1,4 +1,4 @@ -KNOWNBUG +CORE link1.c link2.c ^EXIT=0$ diff --git a/regression/cbmc/Linking6/main.c b/regression/cbmc/Linking6/main.c new file mode 100644 index 00000000000..ff1234d5cd4 --- /dev/null +++ b/regression/cbmc/Linking6/main.c @@ -0,0 +1,23 @@ +#include + +void set(); + +char buffer[10]; + +void init() { + int i; + for (i = 0; i < 10; i++) {buffer[i] = 0;} +} + +void print() { + printf("buffer = %s\n",buffer); +} + +void main () { + init(); + set(); + print(); +} + + + diff --git a/regression/cbmc/Linking6/module.c b/regression/cbmc/Linking6/module.c new file mode 100644 index 00000000000..a4353324f3d --- /dev/null +++ b/regression/cbmc/Linking6/module.c @@ -0,0 +1,9 @@ +#include + +extern char buffer[]; + +static size_t _debug_tempBufferHead = ((size_t)(&buffer)); + +void set() { + *(char *)_debug_tempBufferHead = 'a'; +} diff --git a/regression/cbmc/Linking6/test.desc b/regression/cbmc/Linking6/test.desc new file mode 100644 index 00000000000..67f1dd7303f --- /dev/null +++ b/regression/cbmc/Linking6/test.desc @@ -0,0 +1,8 @@ +CORE +main.c +module.c --pointer-check +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc/Local_out_of_scope3/main.c b/regression/cbmc/Local_out_of_scope3/main.c new file mode 100644 index 00000000000..977efe689a7 --- /dev/null +++ b/regression/cbmc/Local_out_of_scope3/main.c @@ -0,0 +1,24 @@ +unsigned int *GLOBAL_POINTER[1]; + +int index; + +void f(void) +{ + unsigned int actual=0u; + GLOBAL_POINTER[0] = &actual; + + if(index==0) + *GLOBAL_POINTER[index] = 1u; + else + actual = 2u; + + __CPROVER_assume(1u == actual); +} + +void main(void) +{ + index=nondet_int(); + f(); + f(); + __CPROVER_assert(0==1, ""); +} diff --git a/regression/cbmc/Local_out_of_scope3/test.desc b/regression/cbmc/Local_out_of_scope3/test.desc new file mode 100644 index 00000000000..6de79559914 --- /dev/null +++ b/regression/cbmc/Local_out_of_scope3/test.desc @@ -0,0 +1,8 @@ +CORE +main.c + +^EXIT=10$ +^SIGNAL=0$ +^VERIFICATION FAILED$ +-- +^warning: ignoring diff --git a/regression/cbmc/Malloc19/test.desc b/regression/cbmc/Malloc19/test.desc index a27d6e3414c..9c96469df12 100644 --- a/regression/cbmc/Malloc19/test.desc +++ b/regression/cbmc/Malloc19/test.desc @@ -1,4 +1,4 @@ -KNOWNBUG +CORE main.c ^EXIT=0$ diff --git a/regression/cbmc/Malloc20/test.desc b/regression/cbmc/Malloc20/test.desc index a27d6e3414c..9c96469df12 100644 --- a/regression/cbmc/Malloc20/test.desc +++ b/regression/cbmc/Malloc20/test.desc @@ -1,4 +1,4 @@ -KNOWNBUG +CORE main.c ^EXIT=0$ diff --git a/regression/cbmc/byte_update8/main.c b/regression/cbmc/byte_update8/main.c new file mode 100644 index 00000000000..85b3582585c --- /dev/null +++ b/regression/cbmc/byte_update8/main.c @@ -0,0 +1,12 @@ +#include + +int main() +{ + int x=0x01020304; + short *p=((short*)&x)+1; + *p=0xABCD; + assert(x==0xABCD0304); + p=(short*)(((char*)&x)+1); + *p=0xABCD; + assert(x==0xABABCD04); +} diff --git a/regression/cbmc/byte_update8/test.desc b/regression/cbmc/byte_update8/test.desc new file mode 100644 index 00000000000..9efefbc7362 --- /dev/null +++ b/regression/cbmc/byte_update8/test.desc @@ -0,0 +1,8 @@ +CORE +main.c + +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc/byte_update9/main.c b/regression/cbmc/byte_update9/main.c new file mode 100644 index 00000000000..21e0a4d3a46 --- /dev/null +++ b/regression/cbmc/byte_update9/main.c @@ -0,0 +1,12 @@ +#include + +int main() +{ + int x=0x01020304; + short *p=((short*)&x)+1; + *p=0xABCD; + assert(x==0x0102ABCD); + p=(short*)(((char*)&x)+1); + *p=0xABCD; + assert(x==0x01ABCDCD); +} diff --git a/regression/cbmc/byte_update9/test.desc b/regression/cbmc/byte_update9/test.desc new file mode 100644 index 00000000000..81ceb4c6dc0 --- /dev/null +++ b/regression/cbmc/byte_update9/test.desc @@ -0,0 +1,8 @@ +CORE +main.c +--big-endian +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc/constructor1/main.c b/regression/cbmc/constructor1/main.c new file mode 100644 index 00000000000..868b7f4d268 --- /dev/null +++ b/regression/cbmc/constructor1/main.c @@ -0,0 +1,22 @@ +#include + +#ifdef __GNUC__ +int x; + +static __attribute__((constructor)) void format_init(void); + +static __attribute__((constructor)) +void format_init(void) +{ + x=42; + return; +} +#endif + +int main() +{ +#ifdef __GNUC__ + assert(x==42); +#endif + return 0; +} diff --git a/regression/cbmc/constructor1/test.desc b/regression/cbmc/constructor1/test.desc new file mode 100644 index 00000000000..9efefbc7362 --- /dev/null +++ b/regression/cbmc/constructor1/test.desc @@ -0,0 +1,8 @@ +CORE +main.c + +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc/coverage_report1/main.c b/regression/cbmc/coverage_report1/main.c new file mode 100644 index 00000000000..f8f25fab97f --- /dev/null +++ b/regression/cbmc/coverage_report1/main.c @@ -0,0 +1,23 @@ +int main(int argc, char* argv[]) +{ + if(argc>2) + { + argc=1; + } + else + { + argc=2; + } + + switch(argc) + { + case 0: + argc=3; + break; + case 1: + argc=2; + break; + } + + return 0; +} diff --git a/regression/cbmc/coverage_report1/test.desc b/regression/cbmc/coverage_report1/test.desc new file mode 100644 index 00000000000..81ec99da0b5 --- /dev/null +++ b/regression/cbmc/coverage_report1/test.desc @@ -0,0 +1,9 @@ +CORE +main.c +--symex-coverage-report - + +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc/dynamic_size1/main.c b/regression/cbmc/dynamic_size1/main.c new file mode 100644 index 00000000000..6cf9465f50f --- /dev/null +++ b/regression/cbmc/dynamic_size1/main.c @@ -0,0 +1,14 @@ +#include + +int main() +{ + unsigned x; + + int *A=malloc(x*sizeof(int)); + + char *p=&A[1]; + + char c=*p; + + return c; +} diff --git a/regression/cbmc/dynamic_size1/test.desc b/regression/cbmc/dynamic_size1/test.desc new file mode 100644 index 00000000000..d110065a9cf --- /dev/null +++ b/regression/cbmc/dynamic_size1/test.desc @@ -0,0 +1,9 @@ +CORE +main.c +--pointer-check +^EXIT=10$ +^SIGNAL=0$ +^VERIFICATION FAILED$ +-- +^warning: ignoring +^unknown or invalid type size: diff --git a/regression/cbmc/enum6/main.c b/regression/cbmc/enum6/main.c new file mode 100644 index 00000000000..79d64e0ae71 --- /dev/null +++ b/regression/cbmc/enum6/main.c @@ -0,0 +1,19 @@ +#include + +int main(void) +{ + enum A { zero, one, two, three } a = two, b = one, c = three; + + a <<= b; + assert(a==4); + + c += b; + assert(c==4); + + enum E { fortytwo=42 } e = fortytwo; + double res; + res = -42.0 + (double) e; + assert ((res >= -0.000005) && (res <= 0.000005)); + + return 0; +} diff --git a/regression/cbmc/enum6/test.desc b/regression/cbmc/enum6/test.desc new file mode 100644 index 00000000000..52168c7eba4 --- /dev/null +++ b/regression/cbmc/enum6/test.desc @@ -0,0 +1,8 @@ +KNOWNBUG +main.c + +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc/fgets1/main.c b/regression/cbmc/fgets1/main.c new file mode 100644 index 00000000000..8c4e418885b --- /dev/null +++ b/regression/cbmc/fgets1/main.c @@ -0,0 +1,22 @@ +#include +#include + +int main() +{ + char buffer[3]={'a', 'b', '\0'}; + FILE *f=fdopen(0, "r"); + if(!f) + return 1; + + char *p=fgets(buffer, 3, f); + if(p) + { + assert(buffer[1]==p[1]); + assert(buffer[2]=='\0'); + assert(p[1]=='b'); // expected to fail + } + + fclose(f); + + return 0; +} diff --git a/regression/cbmc/fgets1/test.desc b/regression/cbmc/fgets1/test.desc new file mode 100644 index 00000000000..3a8c4e6a733 --- /dev/null +++ b/regression/cbmc/fgets1/test.desc @@ -0,0 +1,10 @@ +CORE +main.c +--bounds-check --pointer-check +^EXIT=10$ +^SIGNAL=0$ +^VERIFICATION FAILED$ +\[main.assertion.3\] assertion p\[1\]=='b': FAILURE +\*\* 1 of 38 failed \(2 iterations\) +-- +^warning: ignoring diff --git a/regression/cbmc/full_slice1/main.c b/regression/cbmc/full_slice1/main.c new file mode 100644 index 00000000000..144b1ec60b5 --- /dev/null +++ b/regression/cbmc/full_slice1/main.c @@ -0,0 +1,51 @@ +#include + +typedef enum { + A, + B, + C +} node_t; + +void doit(node_t *node); + +static inline void foo(node_t *node) { } +static inline void bar(node_t *node) { } + +void doit(node_t *node) +{ + switch (*node) + { + case A: + foo(node); + *node=B; + bar(node); + return; + case C: + *node=B; + bar(node); + return; + } +} + +int main() +{ + node_t node=A; + + char count=0; + while(count++<10) + { + char c; + + doit(&node); + + static char q=0; + q=0; + + if(c==0) + { + assert(node == A); + } + } + + return 0; +} diff --git a/regression/cbmc/full_slice1/test.desc b/regression/cbmc/full_slice1/test.desc new file mode 100644 index 00000000000..77b2ad2d1a8 --- /dev/null +++ b/regression/cbmc/full_slice1/test.desc @@ -0,0 +1,8 @@ +CORE +main.c +--full-slice --property main.assertion.1 --unwind 1 +^EXIT=10$ +^SIGNAL=0$ +^VERIFICATION FAILED +-- +^warning: ignoring diff --git a/regression/cbmc/full_slice2/main.c b/regression/cbmc/full_slice2/main.c new file mode 100644 index 00000000000..5f129867516 --- /dev/null +++ b/regression/cbmc/full_slice2/main.c @@ -0,0 +1,53 @@ +#include + +typedef enum { + A, + B, + C +} node_t; + +void doit(node_t *node); + +static inline void foo(node_t *node) { } +static inline void bar(node_t *node) { } + +void doit(node_t *node) +{ + switch (*node) + { + case A: + foo(node); + *node=B; + bar(node); + return; + case C: + *node=B; + bar(node); + return; + } +} + +int main() +{ + node_t node=A; + + assert(&node); + + char count=0; + while(count++<10) + { + char c; + + doit(&node); + + static char q=0; + q=0; + + if(c==0) + { + assert(node==A); + } + } + + return 0; +} diff --git a/regression/cbmc/full_slice2/test.desc b/regression/cbmc/full_slice2/test.desc new file mode 100644 index 00000000000..ab7f16df02b --- /dev/null +++ b/regression/cbmc/full_slice2/test.desc @@ -0,0 +1,10 @@ +CORE +main.c +--full-slice --property main.assertion.2 --unwind 1 +^EXIT=10$ +^SIGNAL=0$ +^VERIFICATION FAILED +-- +^warning: ignoring +-- +Tests whether properties are not relabelled after slicing. \ No newline at end of file diff --git a/regression/cbmc/hex_string1/main.c b/regression/cbmc/hex_string1/main.c new file mode 100644 index 00000000000..77b163df8b4 --- /dev/null +++ b/regression/cbmc/hex_string1/main.c @@ -0,0 +1,16 @@ +#include + +#define static_assert(x) ((struct { char some[(x)?1:-1]; }*)0) + +int main() +{ + static_assert('\xe8'==(char)0xe8); + static_assert(sizeof("abc")==4); + static_assert(sizeof("\u0201")==3); + static_assert(sizeof("\xe8")==2); + static_assert(sizeof("\u0201\xe8")==4); + + if("\xe8"[0]!=(char)0xe8) + assert(0); + return 0; +} diff --git a/regression/cbmc/hex_string1/test.desc b/regression/cbmc/hex_string1/test.desc new file mode 100644 index 00000000000..12fc8ce06e1 --- /dev/null +++ b/regression/cbmc/hex_string1/test.desc @@ -0,0 +1,9 @@ +CORE +main.c + +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring +^CONVERSION ERROR$ diff --git a/regression/cbmc/little-endian-array1/main.c b/regression/cbmc/little-endian-array1/main.c new file mode 100644 index 00000000000..5919db3e3c1 --- /dev/null +++ b/regression/cbmc/little-endian-array1/main.c @@ -0,0 +1,30 @@ +#include + +int *array; + +int main() +{ + unsigned size; + __CPROVER_assume(size==1); + + // produce unbounded array that does not have byte granularity + array=malloc(size*sizeof(int)); + array[0]=0x01020304; + + int array0=array[0]; + __CPROVER_assert(array0==0x01020304, "array[0] matches"); + + char *p=(char *)array; + char p0=p[0]; + char p1=p[1]; + char p2=p[2]; + char p3=p[3]; + __CPROVER_assert(p0==4, "p[0] matches"); + __CPROVER_assert(p1==3, "p[1] matches"); + __CPROVER_assert(p2==2, "p[2] matches"); + __CPROVER_assert(p3==1, "p[3] matches"); + + unsigned short *q=(unsigned short *)array; + unsigned short q0=q[0]; + __CPROVER_assert(q0==0x0304, "p[0,1] matches"); +} diff --git a/regression/cbmc/little-endian-array1/test.desc b/regression/cbmc/little-endian-array1/test.desc new file mode 100644 index 00000000000..9845e70d84b --- /dev/null +++ b/regression/cbmc/little-endian-array1/test.desc @@ -0,0 +1,8 @@ +CORE +main.c +--little-endian +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc/memory_allocation1/main.c b/regression/cbmc/memory_allocation1/main.c new file mode 100644 index 00000000000..3d9a3e59810 --- /dev/null +++ b/regression/cbmc/memory_allocation1/main.c @@ -0,0 +1,14 @@ +#include + +int main() +{ + int *p=0x10; + + __CPROVER_allocated_memory(0x10, sizeof(int)); + *p=42; + assert(*p==42); + *(p+1)=42; + assert(*(p+1)==42); + + return 0; +} diff --git a/regression/cbmc/memory_allocation1/test.desc b/regression/cbmc/memory_allocation1/test.desc new file mode 100644 index 00000000000..218000c3650 --- /dev/null +++ b/regression/cbmc/memory_allocation1/test.desc @@ -0,0 +1,12 @@ +CORE +main.c +--pointer-check +^EXIT=10$ +^SIGNAL=0$ +\[main.pointer_dereference.2\] dereference failure: pointer invalid in \*p: SUCCESS +\[main.assertion.1\] assertion \*p==42: SUCCESS +\[main.pointer_dereference.14\] dereference failure: pointer invalid in p\[.*1\]: FAILURE +\[main.assertion.2\] assertion \*\(p\+1\)==42: SUCCESS +\*\* 12 of 26 failed \(2 iterations\) +-- +^warning: ignoring diff --git a/regression/cbmc/memset1/main.c b/regression/cbmc/memset1/main.c new file mode 100644 index 00000000000..bd42b5e256e --- /dev/null +++ b/regression/cbmc/memset1/main.c @@ -0,0 +1,29 @@ +#include +#include +#include + +int main() +{ + int A[5]; + memset(A, 0, sizeof(int)*5); + assert(A[0]==0); + assert(A[1]==0); + assert(A[2]==0); + assert(A[3]==0); + assert(A[4]==0); + + A[3]=42; + memset(A, 0xFFFFFF01, sizeof(int)*3); + assert(A[0]==0x01010101); + assert(A[1]==0x01010111); + assert(A[2]==0x01010101); + assert(A[3]==42); + assert(A[4]==0); + + int *B=malloc(sizeof(int)*2); + memset(B, 2, sizeof(int)*2); + assert(B[0]==0x02020202); + assert(B[1]==0x02020202); + + return 0; +} diff --git a/regression/cbmc/memset1/test.desc b/regression/cbmc/memset1/test.desc new file mode 100644 index 00000000000..aef7e29d151 --- /dev/null +++ b/regression/cbmc/memset1/test.desc @@ -0,0 +1,10 @@ +CORE +main.c + +^EXIT=10$ +^SIGNAL=0$ +^VERIFICATION FAILED$ +\[main.assertion.7\] assertion A\[1\]==0x01010111: FAILURE +\*\* 1 of 12 failed \(2 iterations\) +-- +^warning: ignoring diff --git a/regression/cbmc/memset2/main.c b/regression/cbmc/memset2/main.c new file mode 100644 index 00000000000..c317d161215 --- /dev/null +++ b/regression/cbmc/memset2/main.c @@ -0,0 +1,22 @@ +#include +#include + +typedef struct { + int a; + int b; +} TEST; + +static TEST test; + +main() +{ + test.a = 1; + test.b = 2; + memset(&test.b, 0, sizeof(test.b)); + assert(test.a); + assert(!test.b); + test.b = 2; + memset(&test.a, 0, sizeof(test.a)); + assert(!test.a); + assert(test.b); +} diff --git a/regression/cbmc/memset2/test.desc b/regression/cbmc/memset2/test.desc new file mode 100644 index 00000000000..9efefbc7362 --- /dev/null +++ b/regression/cbmc/memset2/test.desc @@ -0,0 +1,8 @@ +CORE +main.c + +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc/mm_io1/main.c b/regression/cbmc/mm_io1/main.c new file mode 100644 index 00000000000..2f1638f63c3 --- /dev/null +++ b/regression/cbmc/mm_io1/main.c @@ -0,0 +1,32 @@ +char __CPROVER_mm_io_r(void *a, unsigned s) +{ + if((long)a==0x10) + return 1; + else if((long)a==0x11) + return 2; +} + +void __CPROVER_mm_io_w(void *a, unsigned s, char value) +{ + if((long)a==0x10) + __CPROVER_assert(value==2, "correct value written"); +} + +int main() +{ + long i=0x10; + char *p=(char *)i; + char some_var=100; + + char z; + z=p[1]; + __CPROVER_assert(z==2, "reading 0x11"); + + // write + p[0]=2; + + p=&some_var; + z=p[0]; + __CPROVER_assert(z==100, "reading &some_var"); +} + diff --git a/regression/cbmc/mm_io1/test.desc b/regression/cbmc/mm_io1/test.desc new file mode 100644 index 00000000000..9efefbc7362 --- /dev/null +++ b/regression/cbmc/mm_io1/test.desc @@ -0,0 +1,8 @@ +CORE +main.c + +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc/printf1/main.c b/regression/cbmc/printf1/main.c new file mode 100644 index 00000000000..b488946fd73 --- /dev/null +++ b/regression/cbmc/printf1/main.c @@ -0,0 +1,11 @@ +#include +#include + +int main() +{ + printf("PRINT d1 %d, %d\n", 123, -123); + printf("PRINT g1 %g, %g, %g, %g\n", 123.0, -123.0, 123.123, 0.123); + printf("PRINT e1 %e, %e, %e, %e\n", 123.0, -123.0, 123.123, 0.123); + printf("PRINT f1 %f, %f, %f, %f\n", 123.0, -123.0, 123.123, 0.123); + assert(0); +} diff --git a/regression/cbmc/printf1/test.desc b/regression/cbmc/printf1/test.desc new file mode 100644 index 00000000000..b5c8583e4ff --- /dev/null +++ b/regression/cbmc/printf1/test.desc @@ -0,0 +1,11 @@ +CORE +main.c +--trace +^EXIT=10$ +^SIGNAL=0$ +^PRINT d1 123, -123$ +^PRINT g1 123, -123, 123\.123, 0\.123$ +^PRINT e1 1\.230000e\+2, -1\.230000e\+2, 1\.231230e\+2, 1\.230000e-1$ +^PRINT f1 123\.000000, -123\.000000, 123\.123000, 0\.123000$ +-- +^warning: ignoring diff --git a/regression/cbmc/union9/main.c b/regression/cbmc/union9/main.c new file mode 100644 index 00000000000..676048e49c8 --- /dev/null +++ b/regression/cbmc/union9/main.c @@ -0,0 +1,35 @@ +#include +#include + +typedef union { + struct { + uint8_t x; + uint8_t z; + } b; +} union_t; + +typedef struct { + uint32_t magic; + union_t unions[]; +} flex; + +int flex_init(flex * flex, size_t num) +{ + if (num == 0 || num >= 200) { + return -1; + } + flex->unions[num - 1].b.z = 255; + return 0; +} + +int main() { + uint8_t num = nondet_size(); + flex * pool = (flex *) malloc(sizeof(flex) + num * sizeof(union_t)); + int ret = flex_init(pool, num); + if (num > 0 && num < 200) { + __CPROVER_assert(ret == 0, "Accept inside range"); + } else { + __CPROVER_assert(ret != 0, "Reject outside range"); + } +} + diff --git a/regression/cbmc/union9/test.desc b/regression/cbmc/union9/test.desc new file mode 100644 index 00000000000..9efefbc7362 --- /dev/null +++ b/regression/cbmc/union9/test.desc @@ -0,0 +1,8 @@ +CORE +main.c + +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc/unwind_counters1/main.c b/regression/cbmc/unwind_counters1/main.c new file mode 100644 index 00000000000..6668d3a3914 --- /dev/null +++ b/regression/cbmc/unwind_counters1/main.c @@ -0,0 +1,6 @@ +int main() +{ + for(int i=0; i<2; ++i) + for(int j=0; j<10; ++j); + return 0; +} diff --git a/regression/cbmc/unwind_counters1/test.desc b/regression/cbmc/unwind_counters1/test.desc new file mode 100644 index 00000000000..46efb30683e --- /dev/null +++ b/regression/cbmc/unwind_counters1/test.desc @@ -0,0 +1,7 @@ +CORE +main.c +--unwind 11 --unwinding-assertions +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- diff --git a/regression/cbmc/unwind_counters2/main.c b/regression/cbmc/unwind_counters2/main.c new file mode 100644 index 00000000000..447015074c9 --- /dev/null +++ b/regression/cbmc/unwind_counters2/main.c @@ -0,0 +1,8 @@ +int main() +{ + l2: goto l1; + l1: int x=5; + goto l2; + + return 0; +} diff --git a/regression/cbmc/unwind_counters2/test.desc b/regression/cbmc/unwind_counters2/test.desc new file mode 100644 index 00000000000..70b64ab793d --- /dev/null +++ b/regression/cbmc/unwind_counters2/test.desc @@ -0,0 +1,7 @@ +CORE +main.c +--unwind 3 --unwinding-assertions +^EXIT=10$ +^SIGNAL=0$ +^VERIFICATION FAILED$ +-- diff --git a/regression/cbmc/unwind_counters3/main.c b/regression/cbmc/unwind_counters3/main.c new file mode 100644 index 00000000000..caa1d607594 --- /dev/null +++ b/regression/cbmc/unwind_counters3/main.c @@ -0,0 +1,9 @@ +int main() +{ + int i=0; + l2: if(i==1) int y=0; + l1: int x=5; + goto l2; + + return 0; +} diff --git a/regression/cbmc/unwind_counters3/test.desc b/regression/cbmc/unwind_counters3/test.desc new file mode 100644 index 00000000000..70b64ab793d --- /dev/null +++ b/regression/cbmc/unwind_counters3/test.desc @@ -0,0 +1,7 @@ +CORE +main.c +--unwind 3 --unwinding-assertions +^EXIT=10$ +^SIGNAL=0$ +^VERIFICATION FAILED$ +-- diff --git a/regression/cbmc/void_pointer1/main.c b/regression/cbmc/void_pointer1/main.c new file mode 100644 index 00000000000..db79440d471 --- /dev/null +++ b/regression/cbmc/void_pointer1/main.c @@ -0,0 +1,12 @@ +char buffer[2]; +int length = 2; + +void func(void* buf, int len) +{ + while( len-- ) + *(char *)buf++; +} + +void main(){ + func(buffer,length); +} diff --git a/regression/cbmc/void_pointer1/test.desc b/regression/cbmc/void_pointer1/test.desc new file mode 100644 index 00000000000..39c491ba8bb --- /dev/null +++ b/regression/cbmc/void_pointer1/test.desc @@ -0,0 +1,8 @@ +CORE +main.c +--pointer-check +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc/void_pointer2/main.c b/regression/cbmc/void_pointer2/main.c new file mode 100644 index 00000000000..db79440d471 --- /dev/null +++ b/regression/cbmc/void_pointer2/main.c @@ -0,0 +1,12 @@ +char buffer[2]; +int length = 2; + +void func(void* buf, int len) +{ + while( len-- ) + *(char *)buf++; +} + +void main(){ + func(buffer,length); +} diff --git a/regression/cbmc/void_pointer2/test.desc b/regression/cbmc/void_pointer2/test.desc new file mode 100644 index 00000000000..3556481d977 --- /dev/null +++ b/regression/cbmc/void_pointer2/test.desc @@ -0,0 +1,8 @@ +CORE +main.c +--pointer-check --no-simplify --unwind 3 +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cpp-linter/assert/main.cpp b/regression/cpp-linter/assert/main.cpp new file mode 100644 index 00000000000..cceff0cb2ea --- /dev/null +++ b/regression/cpp-linter/assert/main.cpp @@ -0,0 +1,10 @@ +// Author: Martin Brain, martin.brain@diffblue.com + +#include +#include + +int main(int argc, char **argv) +{ + assert(0); + return 0; +} diff --git a/regression/cpp-linter/assert/test.desc b/regression/cpp-linter/assert/test.desc new file mode 100644 index 00000000000..cda85742156 --- /dev/null +++ b/regression/cpp-linter/assert/test.desc @@ -0,0 +1,6 @@ +CORE +main.cpp + +^main\.cpp:8: assert is deprecated, use INVARIANT instead \[build/deprecated\] \[4\] +^Total errors found: 1$ +^SIGNAL=0$ diff --git a/regression/cpp-linter/namespace/main.cpp b/regression/cpp-linter/namespace/main.cpp new file mode 100644 index 00000000000..f1c1ebd0a6e --- /dev/null +++ b/regression/cpp-linter/namespace/main.cpp @@ -0,0 +1,34 @@ +// Author: Pascal Kesseli, pascal.kesseli@diffblue.com + +namespace asdf {} + +namespace +asdf +{} + +namespace +asdf + {} + + namespace + + +asdf +{} + +namespace xyz = my::nested::namespaces; + + + +namespace {} + +namespace +{ } + +namespace +{ +} + + namespace +{ +} diff --git a/regression/cpp-linter/namespace/test.desc b/regression/cpp-linter/namespace/test.desc new file mode 100644 index 00000000000..06525f7f9a1 --- /dev/null +++ b/regression/cpp-linter/namespace/test.desc @@ -0,0 +1,11 @@ +CORE +main.cpp + +main\.cpp:3: Do not use namespaces \[readability/namespace\] \[4\] +main\.cpp:5: Do not use namespaces \[readability/namespace\] \[4\] +main\.cpp:9: Do not use namespaces \[readability/namespace\] \[4\] +main\.cpp:13: Do not use namespaces \[readability/namespace\] \[4\] +main\.cpp:19: Do not use namespaces \[readability/namespace\] \[4\] +^EXIT=1$ +^SIGNAL=0$ +-- diff --git a/regression/failed-tests-printer.pl b/regression/failed-tests-printer.pl index 40767185d5c..aa5f28b5933 100755 --- a/regression/failed-tests-printer.pl +++ b/regression/failed-tests-printer.pl @@ -6,21 +6,25 @@ my $printed_this_test = 1; my $current_test = ""; +my $output_file = ""; +my $descriptor_file = ""; while () { chomp; if (/^Test '(.+)'/) { $current_test = $1; $printed_this_test = 0; + } elsif (/Descriptor:\s+([^\s]+)/) { + $descriptor_file = $1; + } elsif (/Output:\s+([^\s]+)/) { + $output_file = $1; } elsif (/\[FAILED\]\s*$/) { if(0 == $printed_this_test) { $printed_this_test = 1; print "\n\n"; print "Failed test: $current_test\n"; - my $outf = `sed -n '2p' $current_test/test.desc`; - $outf =~ s/\..*$/.out/; - system("cat $current_test/$outf"); - print "\n\nFailed test.desc lines:\n"; + system("cat $current_test/$output_file"); + print "\n\nFailed $descriptor_file lines:\n"; } print "$_\n"; } diff --git a/regression/goto-analyzer/approx-array-variable-const-fp/test.desc b/regression/goto-analyzer/approx-array-variable-const-fp/test.desc index 38027f70600..c0e6ab6bfc2 100644 --- a/regression/goto-analyzer/approx-array-variable-const-fp/test.desc +++ b/regression/goto-analyzer/approx-array-variable-const-fp/test.desc @@ -14,3 +14,4 @@ main.c ^\s*IF fp_tbl\[\(signed (long )*long int\)i\] == f8 THEN GOTO [0-9]$ ^\s*IF fp_tbl\[\(signed (long )*long int\)i\] == f9 THEN GOTO [0-9]$ ^warning: ignoring +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/approx-const-fp-array-variable-cast-const-fp/test.desc b/regression/goto-analyzer/approx-const-fp-array-variable-cast-const-fp/test.desc index e6f1f4b5752..0d2ddf970da 100644 --- a/regression/goto-analyzer/approx-const-fp-array-variable-cast-const-fp/test.desc +++ b/regression/goto-analyzer/approx-const-fp-array-variable-cast-const-fp/test.desc @@ -14,3 +14,4 @@ main.c ^\s*IF fp_tbl\[\(signed long int\)i\] == f7 THEN GOTO [0-9]$ ^\s*IF fp_tbl\[\(signed long int\)i\] == f8 THEN GOTO [0-9]$ ^\s*IF fp_tbl\[\(signed long int\)i\] == f9 THEN GOTO [0-9]$ +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/approx-const-fp-array-variable-const-fp-with-null/test.desc b/regression/goto-analyzer/approx-const-fp-array-variable-const-fp-with-null/test.desc index e6f1f4b5752..383f5ad956c 100644 --- a/regression/goto-analyzer/approx-const-fp-array-variable-const-fp-with-null/test.desc +++ b/regression/goto-analyzer/approx-const-fp-array-variable-const-fp-with-null/test.desc @@ -5,6 +5,7 @@ main.c ^\s*IF fp == f2 THEN GOTO [0-9]$ ^\s*IF fp == f3 THEN GOTO [0-9]$ ^\s*IF fp == f4 THEN GOTO [0-9]$ +replacing function pointer by 3 possible targets ^SIGNAL=0$ -- ^warning: ignoring @@ -14,3 +15,4 @@ main.c ^\s*IF fp_tbl\[\(signed long int\)i\] == f7 THEN GOTO [0-9]$ ^\s*IF fp_tbl\[\(signed long int\)i\] == f8 THEN GOTO [0-9]$ ^\s*IF fp_tbl\[\(signed long int\)i\] == f9 THEN GOTO [0-9]$ +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/approx-const-fp-array-variable-const-fp/test.desc b/regression/goto-analyzer/approx-const-fp-array-variable-const-fp/test.desc index e6f1f4b5752..0d2ddf970da 100644 --- a/regression/goto-analyzer/approx-const-fp-array-variable-const-fp/test.desc +++ b/regression/goto-analyzer/approx-const-fp-array-variable-const-fp/test.desc @@ -14,3 +14,4 @@ main.c ^\s*IF fp_tbl\[\(signed long int\)i\] == f7 THEN GOTO [0-9]$ ^\s*IF fp_tbl\[\(signed long int\)i\] == f8 THEN GOTO [0-9]$ ^\s*IF fp_tbl\[\(signed long int\)i\] == f9 THEN GOTO [0-9]$ +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/approx-const-fp-array-variable-const-pointer-const-struct-non-const-fp/test.desc b/regression/goto-analyzer/approx-const-fp-array-variable-const-pointer-const-struct-non-const-fp/test.desc index e6f1f4b5752..0d2ddf970da 100644 --- a/regression/goto-analyzer/approx-const-fp-array-variable-const-pointer-const-struct-non-const-fp/test.desc +++ b/regression/goto-analyzer/approx-const-fp-array-variable-const-pointer-const-struct-non-const-fp/test.desc @@ -14,3 +14,4 @@ main.c ^\s*IF fp_tbl\[\(signed long int\)i\] == f7 THEN GOTO [0-9]$ ^\s*IF fp_tbl\[\(signed long int\)i\] == f8 THEN GOTO [0-9]$ ^\s*IF fp_tbl\[\(signed long int\)i\] == f9 THEN GOTO [0-9]$ +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/approx-const-fp-array-variable-const-struct-non-const-fp/test.desc b/regression/goto-analyzer/approx-const-fp-array-variable-const-struct-non-const-fp/test.desc index e6f1f4b5752..0d2ddf970da 100644 --- a/regression/goto-analyzer/approx-const-fp-array-variable-const-struct-non-const-fp/test.desc +++ b/regression/goto-analyzer/approx-const-fp-array-variable-const-struct-non-const-fp/test.desc @@ -14,3 +14,4 @@ main.c ^\s*IF fp_tbl\[\(signed long int\)i\] == f7 THEN GOTO [0-9]$ ^\s*IF fp_tbl\[\(signed long int\)i\] == f8 THEN GOTO [0-9]$ ^\s*IF fp_tbl\[\(signed long int\)i\] == f9 THEN GOTO [0-9]$ +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/approx-const-fp-array-variable-invalid-cast-const-fp/test.desc b/regression/goto-analyzer/approx-const-fp-array-variable-invalid-cast-const-fp/test.desc index 661ac93a14f..b2f2a12d4ee 100644 --- a/regression/goto-analyzer/approx-const-fp-array-variable-invalid-cast-const-fp/test.desc +++ b/regression/goto-analyzer/approx-const-fp-array-variable-invalid-cast-const-fp/test.desc @@ -14,3 +14,4 @@ main.c ^\s*IF fp_tbl\[\(signed long int\)i\] == f7 THEN GOTO [0-9]$ ^\s*IF fp_tbl\[\(signed long int\)i\] == f8 THEN GOTO [0-9]$ ^\s*IF fp_tbl\[\(signed long int\)i\] == f9 THEN GOTO [0-9]$ +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/approx-const-fp-array-variable-struct-const-fp-with-zero/main.c b/regression/goto-analyzer/approx-const-fp-array-variable-struct-const-fp-with-zero/main.c new file mode 100644 index 00000000000..bc7c67957e2 --- /dev/null +++ b/regression/goto-analyzer/approx-const-fp-array-variable-struct-const-fp-with-zero/main.c @@ -0,0 +1,42 @@ +#include + +void f1 (void) { printf("%i\n", 1); } +void f2 (void) { printf("%i\n", 2); } +void f3 (void) { printf("%i\n", 3); } +void f4 (void) { printf("%i\n", 4); } +void f5 (void) { printf("%i\n", 5); } +void f6 (void) { printf("%i\n", 6); } +void f7 (void) { printf("%i\n", 7); } +void f8 (void) { printf("%i\n", 8); } +void f9 (void) { printf("%i\n", 9); } + +typedef void(*void_fp)(void); + +struct action +{ + int x; + void_fp fun; +}; + +// Array with an empty final element +const struct action fp_tbl[5] = {{1, f2}, {2, f3} ,{3, f4},}; + +// There is a basic check that excludes all functions that aren't used anywhere +// This ensures that check can't work in this example +const void_fp fp_all[] = {f1, f2 ,f3, f4, f5 ,f6, f7, f8, f9}; + +void func(int i) +{ + const void_fp fp = fp_tbl[i].fun; + fp(); +} + +int main() +{ + for(int i=0;i<3;i++) + { + func(i); + } + + return 0; +} diff --git a/regression/goto-analyzer/approx-const-fp-array-variable-struct-const-fp-with-zero/test.desc b/regression/goto-analyzer/approx-const-fp-array-variable-struct-const-fp-with-zero/test.desc new file mode 100644 index 00000000000..fab84bc077c --- /dev/null +++ b/regression/goto-analyzer/approx-const-fp-array-variable-struct-const-fp-with-zero/test.desc @@ -0,0 +1,18 @@ +CORE +main.c +--show-goto-functions --verbosity 10 --pointer-check +^Removing function pointers and virtual functions$ +^\s*IF fp == f2 THEN GOTO [0-9]$ +^\s*IF fp == f3 THEN GOTO [0-9]$ +^\s*IF fp == f4 THEN GOTO [0-9]$ +^\s*ASSERT FALSE // invalid function pointer$ +^SIGNAL=0$ +-- +^warning: ignoring +^\s*IF fp == f1 THEN GOTO [0-9]$ +^\s*IF fp == f5 THEN GOTO [0-9]$ +^\s*IF fp == f6 THEN GOTO [0-9]$ +^\s*IF fp == f7 THEN GOTO [0-9]$ +^\s*IF fp == f8 THEN GOTO [0-9]$ +^\s*IF fp == f9 THEN GOTO [0-9]$ +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/constant_propagation_10/constant_propagation_10.c b/regression/goto-analyzer/constant_propagation_10/constant_propagation_10.c index 169f7965b9d..f0dea39a424 100644 --- a/regression/goto-analyzer/constant_propagation_10/constant_propagation_10.c +++ b/regression/goto-analyzer/constant_propagation_10/constant_propagation_10.c @@ -4,7 +4,7 @@ int main() signed int i; signed int j; i = 0; - if(!(i >= 2)) + if(!(i >= 2)) { j = j + 1; i = i + 1; diff --git a/regression/goto-analyzer/no-match-array-literal-const-fp-null/test.desc b/regression/goto-analyzer/no-match-array-literal-const-fp-null/test.desc index 4786993cade..90a60c56a40 100644 --- a/regression/goto-analyzer/no-match-array-literal-const-fp-null/test.desc +++ b/regression/goto-analyzer/no-match-array-literal-const-fp-null/test.desc @@ -4,5 +4,6 @@ main.c ^Removing function pointers and virtual functions$ ^\s*ASSERT FALSE // invalid function pointer$ ^SIGNAL=0$ +function func: replacing function pointer by 0 possible targets -- ^warning: ignoring diff --git a/regression/goto-analyzer/no-match-const-fp-const-fp-null/test.desc b/regression/goto-analyzer/no-match-const-fp-const-fp-null/test.desc index 4786993cade..1299353033d 100644 --- a/regression/goto-analyzer/no-match-const-fp-const-fp-null/test.desc +++ b/regression/goto-analyzer/no-match-const-fp-const-fp-null/test.desc @@ -4,5 +4,6 @@ main.c ^Removing function pointers and virtual functions$ ^\s*ASSERT FALSE // invalid function pointer$ ^SIGNAL=0$ +replacing function pointer by 0 possible targets -- ^warning: ignoring diff --git a/regression/goto-analyzer/no-match-const-fp-const-pointer-const-struct-const-fp-null/test.desc b/regression/goto-analyzer/no-match-const-fp-const-pointer-const-struct-const-fp-null/test.desc index 4786993cade..40a2b941d75 100644 --- a/regression/goto-analyzer/no-match-const-fp-const-pointer-const-struct-const-fp-null/test.desc +++ b/regression/goto-analyzer/no-match-const-fp-const-pointer-const-struct-const-fp-null/test.desc @@ -3,6 +3,7 @@ main.c --show-goto-functions --verbosity 10 --pointer-check ^Removing function pointers and virtual functions$ ^\s*ASSERT FALSE // invalid function pointer$ +replacing function pointer by 9 possible targets ^SIGNAL=0$ -- ^warning: ignoring diff --git a/regression/goto-analyzer/no-match-const-fp-dereference-const-pointer-null/test.desc b/regression/goto-analyzer/no-match-const-fp-dereference-const-pointer-null/test.desc index 4786993cade..40a2b941d75 100644 --- a/regression/goto-analyzer/no-match-const-fp-dereference-const-pointer-null/test.desc +++ b/regression/goto-analyzer/no-match-const-fp-dereference-const-pointer-null/test.desc @@ -3,6 +3,7 @@ main.c --show-goto-functions --verbosity 10 --pointer-check ^Removing function pointers and virtual functions$ ^\s*ASSERT FALSE // invalid function pointer$ +replacing function pointer by 9 possible targets ^SIGNAL=0$ -- ^warning: ignoring diff --git a/regression/goto-analyzer/no-match-const-fp-null/test.desc b/regression/goto-analyzer/no-match-const-fp-null/test.desc index d8e8d833238..bea1fb7c356 100644 --- a/regression/goto-analyzer/no-match-const-fp-null/test.desc +++ b/regression/goto-analyzer/no-match-const-fp-null/test.desc @@ -3,5 +3,6 @@ main.c --show-goto-functions --verbosity 10 --pointer-check ^Removing function pointers and virtual functions$ ^\s*ASSERT FALSE // invalid function pointer$ +function func: replacing function pointer by 0 possible targets -- ^warning: ignoring diff --git a/regression/goto-analyzer/no-match-const-struct-non-const-fp-null/test.desc b/regression/goto-analyzer/no-match-const-struct-non-const-fp-null/test.desc index 4786993cade..1299353033d 100644 --- a/regression/goto-analyzer/no-match-const-struct-non-const-fp-null/test.desc +++ b/regression/goto-analyzer/no-match-const-struct-non-const-fp-null/test.desc @@ -4,5 +4,6 @@ main.c ^Removing function pointers and virtual functions$ ^\s*ASSERT FALSE // invalid function pointer$ ^SIGNAL=0$ +replacing function pointer by 0 possible targets -- ^warning: ignoring diff --git a/regression/goto-analyzer/precise-array-calculation-const-fp/test.desc b/regression/goto-analyzer/precise-array-calculation-const-fp/test.desc index fad0e6c7a1d..98fc0ff815c 100644 --- a/regression/goto-analyzer/precise-array-calculation-const-fp/test.desc +++ b/regression/goto-analyzer/precise-array-calculation-const-fp/test.desc @@ -6,3 +6,4 @@ main.c ^SIGNAL=0$ -- ^warning: ignoring +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/precise-array-literal-const-fp/test.desc b/regression/goto-analyzer/precise-array-literal-const-fp/test.desc index fad0e6c7a1d..98fc0ff815c 100644 --- a/regression/goto-analyzer/precise-array-literal-const-fp/test.desc +++ b/regression/goto-analyzer/precise-array-literal-const-fp/test.desc @@ -6,3 +6,4 @@ main.c ^SIGNAL=0$ -- ^warning: ignoring +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/precise-const-fp-array-const-variable-const-fp/test.desc b/regression/goto-analyzer/precise-const-fp-array-const-variable-const-fp/test.desc index fad0e6c7a1d..98fc0ff815c 100644 --- a/regression/goto-analyzer/precise-const-fp-array-const-variable-const-fp/test.desc +++ b/regression/goto-analyzer/precise-const-fp-array-const-variable-const-fp/test.desc @@ -6,3 +6,4 @@ main.c ^SIGNAL=0$ -- ^warning: ignoring +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/precise-const-fp-array-literal-const-fp-run-time/test.desc b/regression/goto-analyzer/precise-const-fp-array-literal-const-fp-run-time/test.desc index ab2a0acefba..bb3ac1b5cf1 100644 --- a/regression/goto-analyzer/precise-const-fp-array-literal-const-fp-run-time/test.desc +++ b/regression/goto-analyzer/precise-const-fp-array-literal-const-fp-run-time/test.desc @@ -5,3 +5,4 @@ main.c ^\s*f3\(\);$ -- ^warning: ignoring +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/precise-const-fp-array-literal-const-fp/test.desc b/regression/goto-analyzer/precise-const-fp-array-literal-const-fp/test.desc index fad0e6c7a1d..98fc0ff815c 100644 --- a/regression/goto-analyzer/precise-const-fp-array-literal-const-fp/test.desc +++ b/regression/goto-analyzer/precise-const-fp-array-literal-const-fp/test.desc @@ -6,3 +6,4 @@ main.c ^SIGNAL=0$ -- ^warning: ignoring +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/precise-const-fp-array-literal-const-struct-non-const-fp/test.desc b/regression/goto-analyzer/precise-const-fp-array-literal-const-struct-non-const-fp/test.desc index fad0e6c7a1d..98fc0ff815c 100644 --- a/regression/goto-analyzer/precise-const-fp-array-literal-const-struct-non-const-fp/test.desc +++ b/regression/goto-analyzer/precise-const-fp-array-literal-const-struct-non-const-fp/test.desc @@ -6,3 +6,4 @@ main.c ^SIGNAL=0$ -- ^warning: ignoring +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/precise-const-fp-array-variable-const-pointer-const-struct-non-const-fp/test.desc b/regression/goto-analyzer/precise-const-fp-array-variable-const-pointer-const-struct-non-const-fp/test.desc index 90cd2485ce1..153ca97de3b 100644 --- a/regression/goto-analyzer/precise-const-fp-array-variable-const-pointer-const-struct-non-const-fp/test.desc +++ b/regression/goto-analyzer/precise-const-fp-array-variable-const-pointer-const-struct-non-const-fp/test.desc @@ -6,3 +6,4 @@ main.c ^SIGNAL=0$ -- ^warning: ignoring +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/precise-const-fp-const-fp/test.desc b/regression/goto-analyzer/precise-const-fp-const-fp/test.desc index 40361f6ccc2..27df5bd2f67 100644 --- a/regression/goto-analyzer/precise-const-fp-const-fp/test.desc +++ b/regression/goto-analyzer/precise-const-fp-const-fp/test.desc @@ -6,3 +6,4 @@ main.c ^SIGNAL=0$ -- ^warning: ignoring +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/precise-const-fp-const-struct-const-array-literal-fp/test.desc b/regression/goto-analyzer/precise-const-fp-const-struct-const-array-literal-fp/test.desc index fad0e6c7a1d..98fc0ff815c 100644 --- a/regression/goto-analyzer/precise-const-fp-const-struct-const-array-literal-fp/test.desc +++ b/regression/goto-analyzer/precise-const-fp-const-struct-const-array-literal-fp/test.desc @@ -6,3 +6,4 @@ main.c ^SIGNAL=0$ -- ^warning: ignoring +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/precise-const-fp-const-struct-non-const-array-literal-fp/test.desc b/regression/goto-analyzer/precise-const-fp-const-struct-non-const-array-literal-fp/test.desc index fad0e6c7a1d..98fc0ff815c 100644 --- a/regression/goto-analyzer/precise-const-fp-const-struct-non-const-array-literal-fp/test.desc +++ b/regression/goto-analyzer/precise-const-fp-const-struct-non-const-array-literal-fp/test.desc @@ -6,3 +6,4 @@ main.c ^SIGNAL=0$ -- ^warning: ignoring +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/precise-const-fp-const-struct-non-const-fp/test.desc b/regression/goto-analyzer/precise-const-fp-const-struct-non-const-fp/test.desc index 90cd2485ce1..153ca97de3b 100644 --- a/regression/goto-analyzer/precise-const-fp-const-struct-non-const-fp/test.desc +++ b/regression/goto-analyzer/precise-const-fp-const-struct-non-const-fp/test.desc @@ -6,3 +6,4 @@ main.c ^SIGNAL=0$ -- ^warning: ignoring +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/precise-const-fp-dereference-const-pointer-const-fp/test.desc b/regression/goto-analyzer/precise-const-fp-dereference-const-pointer-const-fp/test.desc index fad0e6c7a1d..98fc0ff815c 100644 --- a/regression/goto-analyzer/precise-const-fp-dereference-const-pointer-const-fp/test.desc +++ b/regression/goto-analyzer/precise-const-fp-dereference-const-pointer-const-fp/test.desc @@ -6,3 +6,4 @@ main.c ^SIGNAL=0$ -- ^warning: ignoring +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/precise-const-fp-supurious-const-loss/main.c b/regression/goto-analyzer/precise-const-fp-supurious-const-loss/main.c new file mode 100644 index 00000000000..4041b2f6aa1 --- /dev/null +++ b/regression/goto-analyzer/precise-const-fp-supurious-const-loss/main.c @@ -0,0 +1,41 @@ +#include + +void f1 (void) { printf("%i\n", 1); } +void f2 (void) { printf("%i\n", 2); } +void f3 (void) { printf("%i\n", 3); } +void f4 (void) { printf("%i\n", 4); } +void f5 (void) { printf("%i\n", 5); } +void f6 (void) { printf("%i\n", 6); } +void f7 (void) { printf("%i\n", 7); } +void f8 (void) { printf("%i\n", 8); } +void f9 (void) { printf("%i\n", 9); } + +typedef void(*void_fp)(void); + +// There is a basic check that excludes all functions that aren't used anywhere +// This ensures that check can't work in this example +const void_fp fp_all[] = {f1, f2 ,f3, f4, f5 ,f6, f7, f8, f9}; + +const int const_number=4; + +void func() +{ + // Here we 'lose' const-ness except it is a copy so we shouldn't care + int non_const_number=const_number; + const void_fp fp = f2; + + + // Here also we lose const-ness except it is a copy of pointer so we + // shouldn't care + const void_fp * const p2fp = &f2; + const void_fp * p2fp_non_const = &p2fp; + + fp(); +} + +int main() +{ + func(); + + return 0; +} diff --git a/regression/goto-analyzer/precise-const-fp-supurious-const-loss/test.desc b/regression/goto-analyzer/precise-const-fp-supurious-const-loss/test.desc new file mode 100644 index 00000000000..76734999981 --- /dev/null +++ b/regression/goto-analyzer/precise-const-fp-supurious-const-loss/test.desc @@ -0,0 +1,18 @@ +CORE +main.c +--show-goto-functions --verbosity 10 --pointer-check +^Removing function pointers and virtual functions$ +^\s*f2\(\); +-- +^warning: ignoring +^\s*\d+:\s*f1\(\); +^\s*\d+:\s*f3\(\); +^\s*\d+:\s*f4\(\); +^\s*\d+:\s*f5\(\); +^\s*\d+:\s*f6\(\); +^\s*\d+:\s*f7\(\); +^\s*\d+:\s*f8\(\); +^\s*\d+:\s*f9\(\); +-- +Though this example program appears to lose const-ness, since it is a primitive +it is a copy so it is irrelevant. diff --git a/regression/goto-analyzer/precise-const-fp/test.desc b/regression/goto-analyzer/precise-const-fp/test.desc index 4dd6e7fd098..402774c29b7 100644 --- a/regression/goto-analyzer/precise-const-fp/test.desc +++ b/regression/goto-analyzer/precise-const-fp/test.desc @@ -5,3 +5,4 @@ main.c ^\s*f2\(\); -- ^warning: ignoring +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/precise-const-pointer-const-struct-fp/test.desc b/regression/goto-analyzer/precise-const-pointer-const-struct-fp/test.desc index 40361f6ccc2..27df5bd2f67 100644 --- a/regression/goto-analyzer/precise-const-pointer-const-struct-fp/test.desc +++ b/regression/goto-analyzer/precise-const-pointer-const-struct-fp/test.desc @@ -6,3 +6,4 @@ main.c ^SIGNAL=0$ -- ^warning: ignoring +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/precise-const-struct-non-const-fp/test.desc b/regression/goto-analyzer/precise-const-struct-non-const-fp/test.desc index 90cd2485ce1..153ca97de3b 100644 --- a/regression/goto-analyzer/precise-const-struct-non-const-fp/test.desc +++ b/regression/goto-analyzer/precise-const-struct-non-const-fp/test.desc @@ -6,3 +6,4 @@ main.c ^SIGNAL=0$ -- ^warning: ignoring +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/precise-derefence-const-pointer-const-fp/test.desc b/regression/goto-analyzer/precise-derefence-const-pointer-const-fp/test.desc index fad0e6c7a1d..98fc0ff815c 100644 --- a/regression/goto-analyzer/precise-derefence-const-pointer-const-fp/test.desc +++ b/regression/goto-analyzer/precise-derefence-const-pointer-const-fp/test.desc @@ -6,3 +6,4 @@ main.c ^SIGNAL=0$ -- ^warning: ignoring +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/precise-derefence/test.desc b/regression/goto-analyzer/precise-derefence/test.desc index 4dd6e7fd098..402774c29b7 100644 --- a/regression/goto-analyzer/precise-derefence/test.desc +++ b/regression/goto-analyzer/precise-derefence/test.desc @@ -5,3 +5,4 @@ main.c ^\s*f2\(\); -- ^warning: ignoring +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/precise-dereference-address-pointer-const-fp/test.desc b/regression/goto-analyzer/precise-dereference-address-pointer-const-fp/test.desc index fad0e6c7a1d..98fc0ff815c 100644 --- a/regression/goto-analyzer/precise-dereference-address-pointer-const-fp/test.desc +++ b/regression/goto-analyzer/precise-dereference-address-pointer-const-fp/test.desc @@ -6,3 +6,4 @@ main.c ^SIGNAL=0$ -- ^warning: ignoring +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/precise-dereference-const-struct-const-pointer-const-fp/test.desc b/regression/goto-analyzer/precise-dereference-const-struct-const-pointer-const-fp/test.desc index fad0e6c7a1d..98fc0ff815c 100644 --- a/regression/goto-analyzer/precise-dereference-const-struct-const-pointer-const-fp/test.desc +++ b/regression/goto-analyzer/precise-dereference-const-struct-const-pointer-const-fp/test.desc @@ -6,3 +6,4 @@ main.c ^SIGNAL=0$ -- ^warning: ignoring +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/precise-dereference-const-struct-const-pointer-const-struct-const-fp/test.desc b/regression/goto-analyzer/precise-dereference-const-struct-const-pointer-const-struct-const-fp/test.desc index fad0e6c7a1d..98fc0ff815c 100644 --- a/regression/goto-analyzer/precise-dereference-const-struct-const-pointer-const-struct-const-fp/test.desc +++ b/regression/goto-analyzer/precise-dereference-const-struct-const-pointer-const-struct-const-fp/test.desc @@ -6,3 +6,4 @@ main.c ^SIGNAL=0$ -- ^warning: ignoring +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/goto-analyzer/precise-dereference-const-struct-pointer-const-fp/test.desc b/regression/goto-analyzer/precise-dereference-const-struct-pointer-const-fp/test.desc index fad0e6c7a1d..98fc0ff815c 100644 --- a/regression/goto-analyzer/precise-dereference-const-struct-pointer-const-fp/test.desc +++ b/regression/goto-analyzer/precise-dereference-const-struct-pointer-const-fp/test.desc @@ -6,3 +6,4 @@ main.c ^SIGNAL=0$ -- ^warning: ignoring +function \w+: replacing function pointer by 9 possible targets diff --git a/regression/taint/aliasing1/aliasing1.class b/regression/goto-analyzer/taint-aliasing1/aliasing1.class similarity index 100% rename from regression/taint/aliasing1/aliasing1.class rename to regression/goto-analyzer/taint-aliasing1/aliasing1.class diff --git a/regression/taint/aliasing1/aliasing1.java b/regression/goto-analyzer/taint-aliasing1/aliasing1.java similarity index 100% rename from regression/taint/aliasing1/aliasing1.java rename to regression/goto-analyzer/taint-aliasing1/aliasing1.java diff --git a/regression/taint/aliasing1/taint.json b/regression/goto-analyzer/taint-aliasing1/taint.json similarity index 100% rename from regression/taint/aliasing1/taint.json rename to regression/goto-analyzer/taint-aliasing1/taint.json diff --git a/regression/goto-analyzer/taint-aliasing1/test.desc b/regression/goto-analyzer/taint-aliasing1/test.desc new file mode 100644 index 00000000000..49818c9c42b --- /dev/null +++ b/regression/goto-analyzer/taint-aliasing1/test.desc @@ -0,0 +1,9 @@ +CORE +aliasing1.class +--taint taint.json +^EXIT=0$ +^SIGNAL=0$ +^file aliasing1.java line 10( function .*)?: There is a flow \(taint rule my_sink\)$ +-- +^file aliasing1.java line 8( function .*)?: There is a flow \(taint rule my_sink\)$ +^warning: ignoring diff --git a/regression/taint/basic1/basic1.class b/regression/goto-analyzer/taint-basic1/basic1.class similarity index 100% rename from regression/taint/basic1/basic1.class rename to regression/goto-analyzer/taint-basic1/basic1.class diff --git a/regression/taint/basic1/basic1.java b/regression/goto-analyzer/taint-basic1/basic1.java similarity index 100% rename from regression/taint/basic1/basic1.java rename to regression/goto-analyzer/taint-basic1/basic1.java diff --git a/regression/taint/basic1/taint.json b/regression/goto-analyzer/taint-basic1/taint.json similarity index 100% rename from regression/taint/basic1/taint.json rename to regression/goto-analyzer/taint-basic1/taint.json diff --git a/regression/goto-analyzer/taint-basic1/test.desc b/regression/goto-analyzer/taint-basic1/test.desc new file mode 100644 index 00000000000..0da443b9d31 --- /dev/null +++ b/regression/goto-analyzer/taint-basic1/test.desc @@ -0,0 +1,9 @@ +CORE +basic1.class +--taint taint.json +^EXIT=0$ +^SIGNAL=0$ +^file basic1.java line 8( function .*)?: There is a T1 flow \(taint rule my_h1\)$ +^file basic1.java line 11( function .*)?: There is a T2 flow \(taint rule my_h2\)$ +-- +^warning: ignoring diff --git a/regression/taint/basic2/basic2.class b/regression/goto-analyzer/taint-basic2/basic2.class similarity index 100% rename from regression/taint/basic2/basic2.class rename to regression/goto-analyzer/taint-basic2/basic2.class diff --git a/regression/taint/basic2/basic2.java b/regression/goto-analyzer/taint-basic2/basic2.java similarity index 100% rename from regression/taint/basic2/basic2.java rename to regression/goto-analyzer/taint-basic2/basic2.java diff --git a/regression/taint/basic2/taint.json b/regression/goto-analyzer/taint-basic2/taint.json similarity index 100% rename from regression/taint/basic2/taint.json rename to regression/goto-analyzer/taint-basic2/taint.json diff --git a/regression/goto-analyzer/taint-basic2/test.desc b/regression/goto-analyzer/taint-basic2/test.desc new file mode 100644 index 00000000000..b40e010d8f2 --- /dev/null +++ b/regression/goto-analyzer/taint-basic2/test.desc @@ -0,0 +1,9 @@ +CORE +basic2.class +--taint taint.json +^EXIT=0$ +^SIGNAL=0$ +^file basic2.java line 8( function .*)?: There is a T1 flow \(taint rule my_h1\)$ +^file basic2.java line 11( function .*)?: There is a T2 flow \(taint rule my_h2\)$ +-- +^warning: ignoring diff --git a/regression/taint/interface1/interface1.class b/regression/goto-analyzer/taint-interface1/interface1.class similarity index 97% rename from regression/taint/interface1/interface1.class rename to regression/goto-analyzer/taint-interface1/interface1.class index 31a3578bcdf..056ea5d7b3a 100644 Binary files a/regression/taint/interface1/interface1.class and b/regression/goto-analyzer/taint-interface1/interface1.class differ diff --git a/regression/taint/interface1/interface1.java b/regression/goto-analyzer/taint-interface1/interface1.java similarity index 100% rename from regression/taint/interface1/interface1.java rename to regression/goto-analyzer/taint-interface1/interface1.java diff --git a/regression/goto-analyzer/taint-interface1/my_I.class b/regression/goto-analyzer/taint-interface1/my_I.class new file mode 100644 index 00000000000..f2560c4dda7 Binary files /dev/null and b/regression/goto-analyzer/taint-interface1/my_I.class differ diff --git a/regression/goto-analyzer/taint-interface1/some_class.class b/regression/goto-analyzer/taint-interface1/some_class.class new file mode 100644 index 00000000000..b3261423efd Binary files /dev/null and b/regression/goto-analyzer/taint-interface1/some_class.class differ diff --git a/regression/taint/interface1/taint.json b/regression/goto-analyzer/taint-interface1/taint.json similarity index 100% rename from regression/taint/interface1/taint.json rename to regression/goto-analyzer/taint-interface1/taint.json diff --git a/regression/goto-analyzer/taint-interface1/test.desc b/regression/goto-analyzer/taint-interface1/test.desc new file mode 100644 index 00000000000..bbbbdcd0443 --- /dev/null +++ b/regression/goto-analyzer/taint-interface1/test.desc @@ -0,0 +1,8 @@ +CORE +interface1.class +--taint taint.json +^EXIT=0$ +^SIGNAL=0$ +^file interface1.java line 18( function .*)?: There is a flow! \(taint rule sink_rule\)$ +-- +^warning: ignoring diff --git a/regression/goto-analyzer/taint-interproc1/interproc1.class b/regression/goto-analyzer/taint-interproc1/interproc1.class new file mode 100644 index 00000000000..6d8559b3085 Binary files /dev/null and b/regression/goto-analyzer/taint-interproc1/interproc1.class differ diff --git a/regression/goto-analyzer/taint-interproc1/interproc1.java b/regression/goto-analyzer/taint-interproc1/interproc1.java new file mode 100644 index 00000000000..d092c38a536 --- /dev/null +++ b/regression/goto-analyzer/taint-interproc1/interproc1.java @@ -0,0 +1,19 @@ +class interproc1 +{ + static void my_method() + { + Object o=null; + + my_f(o); // T1 source + my_g(o); + } + + static void my_g(Object p) + { + my_h(p); // T1 sink + } + + static void my_f(Object p) { } + static void my_h(Object p) { } +}; + diff --git a/regression/goto-analyzer/taint-interproc1/taint.json b/regression/goto-analyzer/taint-interproc1/taint.json new file mode 100644 index 00000000000..26fadfb2775 --- /dev/null +++ b/regression/goto-analyzer/taint-interproc1/taint.json @@ -0,0 +1,4 @@ +[ +{ "id": "my_f", "kind": "source", "where": "parameter1", "taint": "T1", "function": "interproc1.my_f" }, +{ "id": "my_h1", "kind": "sink", "where": "parameter1", "taint": "T1", "function": "interproc1.my_h", "message": "There is a T1 flow" } +] diff --git a/regression/goto-analyzer/taint-interproc1/test.desc b/regression/goto-analyzer/taint-interproc1/test.desc new file mode 100644 index 00000000000..1a60e0a17f0 --- /dev/null +++ b/regression/goto-analyzer/taint-interproc1/test.desc @@ -0,0 +1,8 @@ +CORE +interproc1.class +--taint taint.json +^EXIT=0$ +^SIGNAL=0$ +^file interproc1.java line 13( function .*)?: There is a T1 flow \(taint rule my_h1\)$ +-- +^warning: ignoring diff --git a/regression/taint/map1/map1.class b/regression/goto-analyzer/taint-map1/map1.class similarity index 100% rename from regression/taint/map1/map1.class rename to regression/goto-analyzer/taint-map1/map1.class diff --git a/regression/taint/map1/map1.java b/regression/goto-analyzer/taint-map1/map1.java similarity index 100% rename from regression/taint/map1/map1.java rename to regression/goto-analyzer/taint-map1/map1.java diff --git a/regression/taint/map1/taint.json b/regression/goto-analyzer/taint-map1/taint.json similarity index 100% rename from regression/taint/map1/taint.json rename to regression/goto-analyzer/taint-map1/taint.json diff --git a/regression/goto-analyzer/taint-map1/test.desc b/regression/goto-analyzer/taint-map1/test.desc new file mode 100644 index 00000000000..5d7ad41dc91 --- /dev/null +++ b/regression/goto-analyzer/taint-map1/test.desc @@ -0,0 +1,8 @@ +KNOWNBUG +map1.class +--taint taint.json +^EXIT=0$ +^SIGNAL=0$ +^file map1.java line 12( function .*)?: There is a flow \(taint rule my_sink\)$ +-- +^warning: ignoring diff --git a/regression/goto-diff/Makefile b/regression/goto-diff/Makefile new file mode 100644 index 00000000000..266f02032bb --- /dev/null +++ b/regression/goto-diff/Makefile @@ -0,0 +1,24 @@ +default: tests.log + +test: + @if ! ../test.pl -c ../../../src/goto-diff/goto-diff ; then \ + ../failed-tests-printer.pl ; \ + exit 1 ; \ + fi + +tests.log: ../test.pl + @if ! ../test.pl -c ../../../src/goto-diff/goto-diff ; then \ + ../failed-tests-printer.pl ; \ + exit 1 ; \ + fi + +show: + @for dir in *; do \ + if [ -d "$$dir" ]; then \ + vim -o "$$dir/*.c" "$$dir/*.out"; \ + fi; \ + done; + +clean: + find -name '*.out' -execdir $(RM) '{}' \; + $(RM) tests.log diff --git a/regression/goto-diff/syntactic-diff1/a.c b/regression/goto-diff/syntactic-diff1/a.c new file mode 100644 index 00000000000..95ce6e1c1ac --- /dev/null +++ b/regression/goto-diff/syntactic-diff1/a.c @@ -0,0 +1,11 @@ +int main() +{ + int x; + + return 0; +} + +void foo() +{ + int y; +} diff --git a/regression/goto-diff/syntactic-diff1/a.gb b/regression/goto-diff/syntactic-diff1/a.gb new file mode 100644 index 00000000000..2bf7c7b9947 Binary files /dev/null and b/regression/goto-diff/syntactic-diff1/a.gb differ diff --git a/regression/goto-diff/syntactic-diff1/b.c b/regression/goto-diff/syntactic-diff1/b.c new file mode 100644 index 00000000000..c4e6c425cd3 --- /dev/null +++ b/regression/goto-diff/syntactic-diff1/b.c @@ -0,0 +1,11 @@ +int main() +{ + int x=42; + + return 0; +} + +void bar() +{ + int z; +} diff --git a/regression/goto-diff/syntactic-diff1/b.gb b/regression/goto-diff/syntactic-diff1/b.gb new file mode 100644 index 00000000000..b1db4ddb9e3 Binary files /dev/null and b/regression/goto-diff/syntactic-diff1/b.gb differ diff --git a/regression/goto-diff/syntactic-diff1/test.desc b/regression/goto-diff/syntactic-diff1/test.desc new file mode 100644 index 00000000000..6a47a3b1a36 --- /dev/null +++ b/regression/goto-diff/syntactic-diff1/test.desc @@ -0,0 +1,10 @@ +CORE +b.gb +a.gb +// Enable multi-line checking +activate-multi-line-match +EXIT=0 +SIGNAL=0 +new functions:\n\s+b.c: bar\nmodified functions:\n\s+b.c: main\ndeleted functions:\n\s+a.c: foo +-- +^warning: ignoring diff --git a/regression/goto-instrument/dump-vararg1/main.c b/regression/goto-instrument/dump-vararg1/main.c new file mode 100644 index 00000000000..9ce2bce8d03 --- /dev/null +++ b/regression/goto-instrument/dump-vararg1/main.c @@ -0,0 +1,19 @@ +#include +#include + +void bb_verror_msg(const char *s, va_list p, const char *strerr) { +} + +void bb_error_msg(const char *s, ...) +{ + va_list p; + va_start(p, s); + bb_verror_msg(s, p, NULL); + va_end(p); +} + +int main() { + bb_error_msg("FOOO"); + return 0; +} + diff --git a/regression/goto-instrument/dump-vararg1/test.desc b/regression/goto-instrument/dump-vararg1/test.desc new file mode 100644 index 00000000000..d1a6d2f2d6f --- /dev/null +++ b/regression/goto-instrument/dump-vararg1/test.desc @@ -0,0 +1,8 @@ +CORE +main.c +--dump-c +^EXIT=0$ +^SIGNAL=0$ +va_list +-- +^warning: ignoring diff --git a/regression/goto-instrument/print-internal-representation/main.c b/regression/goto-instrument/print-internal-representation/main.c new file mode 100644 index 00000000000..029bfdaa638 --- /dev/null +++ b/regression/goto-instrument/print-internal-representation/main.c @@ -0,0 +1,6 @@ +char stage2_start[100]; + +int main(){ + int x = 3; + unsigned y = 4; +} diff --git a/regression/goto-instrument/print-internal-representation/test.desc b/regression/goto-instrument/print-internal-representation/test.desc new file mode 100644 index 00000000000..d9bbe50625d --- /dev/null +++ b/regression/goto-instrument/print-internal-representation/test.desc @@ -0,0 +1,12 @@ +CORE +main.c +--print-internal-representation +^EXIT=0$ +^SIGNAL=0$ +^ \* identifier: __CPROVER_initialize$ +^ \* identifier: main::1::x$ +^ \* identifier: main::1::y$ +-- +-- +Ensures that the output from pretty() is printed when +--print-internal-representation is passed to goto-instrument. diff --git a/regression/goto-instrument/remove-function-body1/main.c b/regression/goto-instrument/remove-function-body1/main.c new file mode 100644 index 00000000000..14e576db99f --- /dev/null +++ b/regression/goto-instrument/remove-function-body1/main.c @@ -0,0 +1,21 @@ +#include + +int foo() +{ + int a; + assert(a>0); + return a; +} + +int bar() +{ + int b; + assert(b>0); + return b; +} + +int main() +{ + foo(); + bar(); +} diff --git a/regression/goto-instrument/remove-function-body1/test.desc b/regression/goto-instrument/remove-function-body1/test.desc new file mode 100644 index 00000000000..45369a31184 --- /dev/null +++ b/regression/goto-instrument/remove-function-body1/test.desc @@ -0,0 +1,10 @@ +CORE +main.c +--remove-function-body foo --remove-function-body bar +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring +^bar +^foo diff --git a/regression/goto-instrument/typedef1/main.c b/regression/goto-instrument/typedef1/main.c new file mode 100644 index 00000000000..8c80dc61e34 --- /dev/null +++ b/regression/goto-instrument/typedef1/main.c @@ -0,0 +1,69 @@ +typedef long int off_t; +typedef signed char smallint; + +typedef struct chain_s { + struct node_s *first; + struct node_s *last; + const char *programname; +} chain; + +typedef struct func_s { + struct chain_s body; +} func; + +typedef struct node_s { + struct node_s *n; +} node; + +typedef struct dumper_t_x { + node n; + off_t dump_skip; + signed int dump_length; + smallint dump_vflag; +} dumper_t; + +typedef struct FS_x { + struct FS *nextfs; + signed int bcnt; +} FS; + +dumper_t * alloc_dumper(void) { + return (void*) 0; +} + +typedef unsigned int uint32_t; + +const uint32_t xx[2]; + +typedef struct node_s2 { + uint32_t info; +} node2; + +typedef struct { + int x; +} anon_name; + +typedef struct node_s3 { + union { + struct node_s *n; + func *f; + } r; +} node3; + +typedef int x_int; +typedef int y_int; +typedef x_int *p_int; + +int main() { + node n; + chain c; + dumper_t a; + dumper_t b[3]; + node2* sn; + anon_name d; + node3* s3; + y_int y; + p_int p; + alloc_dumper(); + return 0; +} diff --git a/regression/goto-instrument/typedef1/test.desc b/regression/goto-instrument/typedef1/test.desc new file mode 100644 index 00000000000..8047eddf32b --- /dev/null +++ b/regression/goto-instrument/typedef1/test.desc @@ -0,0 +1,10 @@ +CORE +main.c +--dump-c +^EXIT=0$ +^SIGNAL=0$ +-- +^warning: ignoring +-- +This test should be run via chain.sh, which will try to recompile the dumped C +code. Missing/incomplete typedef output would cause a failure. diff --git a/regression/goto-instrument/typedef2/main.c b/regression/goto-instrument/typedef2/main.c new file mode 100644 index 00000000000..928abcfde9a --- /dev/null +++ b/regression/goto-instrument/typedef2/main.c @@ -0,0 +1,16 @@ +typedef struct +{ + char bogus; +} bb_mbstate_t; + +int bb_wcrtomb(char *s, char wc, bb_mbstate_t *ps); + +int bb_wcrtomb(char *s, char wc, bb_mbstate_t *ps) +{ + return 1; +} + +int main() { + bb_wcrtomb("foo", 'Z', (void*)1); + return 0; +} diff --git a/regression/goto-instrument/typedef2/test.desc b/regression/goto-instrument/typedef2/test.desc new file mode 100644 index 00000000000..8047eddf32b --- /dev/null +++ b/regression/goto-instrument/typedef2/test.desc @@ -0,0 +1,10 @@ +CORE +main.c +--dump-c +^EXIT=0$ +^SIGNAL=0$ +-- +^warning: ignoring +-- +This test should be run via chain.sh, which will try to recompile the dumped C +code. Missing/incomplete typedef output would cause a failure. diff --git a/regression/goto-instrument/typedef3/main.c b/regression/goto-instrument/typedef3/main.c new file mode 100644 index 00000000000..4ca41b69451 --- /dev/null +++ b/regression/goto-instrument/typedef3/main.c @@ -0,0 +1,30 @@ +extern void* memset(void *, int, unsigned long); + +typedef void (*__sighandler_t) (int); + +typedef __sighandler_t sighandler_t; + +typedef struct siginfo { + int si_signo; +} siginfo_t; + +struct sigaction { + union { + __sighandler_t _sa_handler; + void (*_sa_sigaction)(int, struct siginfo *, void *); + } _u; +}; + +#define sa_sigaction _u._sa_sigaction +#define sa_handler _u._sa_handler + +static void askpass_timeout(signed int ignore) { + ; +} + +int main() { + struct sigaction sa, oldsa; + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = askpass_timeout; + return 0; +} diff --git a/regression/goto-instrument/typedef3/test.desc b/regression/goto-instrument/typedef3/test.desc new file mode 100644 index 00000000000..8047eddf32b --- /dev/null +++ b/regression/goto-instrument/typedef3/test.desc @@ -0,0 +1,10 @@ +CORE +main.c +--dump-c +^EXIT=0$ +^SIGNAL=0$ +-- +^warning: ignoring +-- +This test should be run via chain.sh, which will try to recompile the dumped C +code. Missing/incomplete typedef output would cause a failure. diff --git a/regression/goto-instrument/typedef4/main.c b/regression/goto-instrument/typedef4/main.c new file mode 100644 index 00000000000..7290f9c9ba5 --- /dev/null +++ b/regression/goto-instrument/typedef4/main.c @@ -0,0 +1,23 @@ +#ifndef _WIN32 + +#include +#include + +void sig_block(int sig) +{ + sigset_t ss; + sigemptyset(&ss); + sigaddset(&ss, sig); + sigprocmask(SIG_BLOCK, &ss, NULL); +} + +int main() { + sig_block(0); + return 0; +} +#else +int main() +{ + return 0; +} +#endif diff --git a/regression/goto-instrument/typedef4/test.desc b/regression/goto-instrument/typedef4/test.desc new file mode 100644 index 00000000000..8047eddf32b --- /dev/null +++ b/regression/goto-instrument/typedef4/test.desc @@ -0,0 +1,10 @@ +CORE +main.c +--dump-c +^EXIT=0$ +^SIGNAL=0$ +-- +^warning: ignoring +-- +This test should be run via chain.sh, which will try to recompile the dumped C +code. Missing/incomplete typedef output would cause a failure. diff --git a/regression/invariants/.gitignore b/regression/invariants/.gitignore new file mode 100644 index 00000000000..e54525b1ee9 --- /dev/null +++ b/regression/invariants/.gitignore @@ -0,0 +1 @@ +driver diff --git a/regression/invariants/Makefile b/regression/invariants/Makefile new file mode 100644 index 00000000000..b561a960830 --- /dev/null +++ b/regression/invariants/Makefile @@ -0,0 +1,32 @@ +default: tests.log + +SRC = driver.cpp + +INCLUDES = -I ../../src + +OBJ += ../../src/util/util$(LIBEXT) + +include ../../src/config.inc +include ../../src/common + +test: driver$(EXEEXT) + @if ! ../test.pl -c ../driver ; then \ + ../failed-tests-printer.pl ; \ + exit 1 ; \ + fi + +tests.log: ../test.pl driver$(EXEEXT) + @if ! ../test.pl -c ../driver ; then \ + ../failed-tests-printer.pl ; \ + exit 1 ; \ + fi + +show: + @for dir in *; do \ + if [ -d "$$dir" ]; then \ + vim -o "$$dir/*.c" "$$dir/*.out"; \ + fi; \ + done; + +driver$(EXEEXT): $(OBJ) + $(LINKBIN) diff --git a/regression/invariants/driver.cpp b/regression/invariants/driver.cpp new file mode 100644 index 00000000000..824ae588c03 --- /dev/null +++ b/regression/invariants/driver.cpp @@ -0,0 +1,88 @@ +/*******************************************************************\ + +Module: Invariant violation testing + +Author: Chris Smowton, chris.smowton@diffblue.com + +\*******************************************************************/ + +/// \file +/// Invariant violation testing + +#include +#include +#include + +/// An example of structured invariants-- this contains fields to +/// describe the error to a catcher, and also produces a human-readable +/// message containing all the information for use by the current aborting +/// invariant implementation and/or any generic error catcher in the future. +class structured_error_testt: public invariant_failedt +{ + std::string pretty_print(int code, const std::string &desc) + { + std::ostringstream ret; + ret << "Error code: " << code + << "\nDescription: " << desc; + return ret.str(); + } + +public: + const int error_code; + const std::string description; + + structured_error_testt( + const std::string &file, + const std::string &function, + int line, + const std::string &backtrace, + int code, + const std::string &_description): + invariant_failedt( + file, + function, + line, + backtrace, + pretty_print(code, _description)), + error_code(code), + description(_description) + { + } +}; + +/// Causes an invariant failure dependent on first argument value. +/// One ignored argument is accepted to conform with the test.pl script, +/// which would be the input source file for other cbmc driver programs. +/// Returns 1 on unexpected arguments. +int main(int argc, char** argv) +{ + if(argc!=3) + return 1; + std::string arg=argv[1]; + if(arg=="structured") + INVARIANT_STRUCTURED(false, structured_error_testt, 1, "Structured error"); // NOLINT + else if(arg=="string") + INVARIANT(false, "Test invariant failure"); + else if(arg=="precondition-structured") + PRECONDITION_STRUCTURED(false, structured_error_testt, 1, "Structured error"); // NOLINT + else if(arg=="precondition-string") + PRECONDITION(false); + else if(arg=="postcondition-structured") + POSTCONDITION_STRUCTURED(false, structured_error_testt, 1, "Structured error"); // NOLINT + else if(arg=="postcondition-string") + POSTCONDITION(false); + else if(arg=="check-return-structured") + CHECK_RETURN_STRUCTURED(false, structured_error_testt, 1, "Structured error"); // NOLINT + else if(arg=="check-return-string") + CHECK_RETURN(false); + else if(arg=="unreachable-structured") + UNREACHABLE_STRUCTURED(structured_error_testt, 1, "Structured error"); // NOLINT + else if(arg=="unreachable-string") + UNREACHABLE; + else if(arg=="data-invariant-structured") + DATA_INVARIANT_STRUCTURED(false, structured_error_testt, 1, "Structured error"); // NOLINT + else if(arg=="data-invariant-string") + DATA_INVARIANT(false, "Test invariant failure"); + else + return 1; +} diff --git a/regression/invariants/invariant-failure/test.desc b/regression/invariants/invariant-failure/test.desc new file mode 100644 index 00000000000..70628a2e064 --- /dev/null +++ b/regression/invariants/invariant-failure/test.desc @@ -0,0 +1,12 @@ +CORE +dummy_parameter.c +string +^EXIT=(0|127|134|137)$ +^SIGNAL=0$ +--- begin invariant violation report --- +Test invariant failure +Invariant check failed +^(Backtrace)|(Backtraces not supported)$ +-- +^warning: ignoring +^VERIFICATION SUCCESSFUL$ diff --git a/regression/invariants/invariant-failure10/test.desc b/regression/invariants/invariant-failure10/test.desc new file mode 100644 index 00000000000..fae345f2b2a --- /dev/null +++ b/regression/invariants/invariant-failure10/test.desc @@ -0,0 +1,13 @@ +CORE +dummy_parameter.c +unreachable-structured +^EXIT=(0|127|134|137)$ +^SIGNAL=0$ +--- begin invariant violation report --- +Invariant check failed +Error code: 1 +Description: Structured error +^(Backtrace)|(Backtraces not supported)$ +-- +^warning: ignoring +^VERIFICATION SUCCESSFUL$ diff --git a/regression/invariants/invariant-failure11/test.desc b/regression/invariants/invariant-failure11/test.desc new file mode 100644 index 00000000000..fc160b21308 --- /dev/null +++ b/regression/invariants/invariant-failure11/test.desc @@ -0,0 +1,12 @@ +CORE +dummy_parameter.c +data-invariant-string +^EXIT=(0|127|134|137)$ +^SIGNAL=0$ +--- begin invariant violation report --- +Test invariant failure +Invariant check failed +^(Backtrace)|(Backtraces not supported)$ +-- +^warning: ignoring +^VERIFICATION SUCCESSFUL$ diff --git a/regression/invariants/invariant-failure12/test.desc b/regression/invariants/invariant-failure12/test.desc new file mode 100644 index 00000000000..498af6f2cc5 --- /dev/null +++ b/regression/invariants/invariant-failure12/test.desc @@ -0,0 +1,13 @@ +CORE +dummy_parameter.c +data-invariant-structured +^EXIT=(0|127|134|137)$ +^SIGNAL=0$ +--- begin invariant violation report --- +Invariant check failed +Error code: 1 +Description: Structured error +^(Backtrace)|(Backtraces not supported)$ +-- +^warning: ignoring +^VERIFICATION SUCCESSFUL$ diff --git a/regression/invariants/invariant-failure2/test.desc b/regression/invariants/invariant-failure2/test.desc new file mode 100644 index 00000000000..daadab22c44 --- /dev/null +++ b/regression/invariants/invariant-failure2/test.desc @@ -0,0 +1,13 @@ +CORE +dummy_parameter.c +structured +^EXIT=(0|127|134|137)$ +^SIGNAL=0$ +--- begin invariant violation report --- +Invariant check failed +Error code: 1 +Description: Structured error +^(Backtrace)|(Backtraces not supported)$ +-- +^warning: ignoring +^VERIFICATION SUCCESSFUL$ diff --git a/regression/invariants/invariant-failure3/test.desc b/regression/invariants/invariant-failure3/test.desc new file mode 100644 index 00000000000..42aba0fc5bd --- /dev/null +++ b/regression/invariants/invariant-failure3/test.desc @@ -0,0 +1,12 @@ +CORE +dummy_parameter.c +precondition-string +^EXIT=(0|127|134|137)$ +^SIGNAL=0$ +--- begin invariant violation report --- +Precondition +Invariant check failed +^(Backtrace)|(Backtraces not supported)$ +-- +^warning: ignoring +^VERIFICATION SUCCESSFUL$ diff --git a/regression/invariants/invariant-failure4/test.desc b/regression/invariants/invariant-failure4/test.desc new file mode 100644 index 00000000000..6339338d491 --- /dev/null +++ b/regression/invariants/invariant-failure4/test.desc @@ -0,0 +1,13 @@ +CORE +dummy_parameter.c +precondition-structured +^EXIT=(0|127|134|137)$ +^SIGNAL=0$ +--- begin invariant violation report --- +Invariant check failed +Error code: 1 +Description: Structured error +^(Backtrace)|(Backtraces not supported)$ +-- +^warning: ignoring +^VERIFICATION SUCCESSFUL$ diff --git a/regression/invariants/invariant-failure5/test.desc b/regression/invariants/invariant-failure5/test.desc new file mode 100644 index 00000000000..f6f6971351f --- /dev/null +++ b/regression/invariants/invariant-failure5/test.desc @@ -0,0 +1,12 @@ +CORE +dummy_parameter.c +postcondition-string +^EXIT=(0|127|134|137)$ +^SIGNAL=0$ +--- begin invariant violation report --- +Postcondition +Invariant check failed +^(Backtrace)|(Backtraces not supported)$ +-- +^warning: ignoring +^VERIFICATION SUCCESSFUL$ diff --git a/regression/invariants/invariant-failure6/test.desc b/regression/invariants/invariant-failure6/test.desc new file mode 100644 index 00000000000..1b83f2630b1 --- /dev/null +++ b/regression/invariants/invariant-failure6/test.desc @@ -0,0 +1,13 @@ +CORE +dummy_parameter.c +postcondition-structured +^EXIT=(0|127|134|137)$ +^SIGNAL=0$ +--- begin invariant violation report --- +Invariant check failed +Error code: 1 +Description: Structured error +^(Backtrace)|(Backtraces not supported)$ +-- +^warning: ignoring +^VERIFICATION SUCCESSFUL$ diff --git a/regression/invariants/invariant-failure7/test.desc b/regression/invariants/invariant-failure7/test.desc new file mode 100644 index 00000000000..9b25a5ac5e8 --- /dev/null +++ b/regression/invariants/invariant-failure7/test.desc @@ -0,0 +1,12 @@ +CORE +dummy_parameter.c +check-return-string +^EXIT=(0|127|134|137)$ +^SIGNAL=0$ +--- begin invariant violation report --- +Check return value +Invariant check failed +^(Backtrace)|(Backtraces not supported)$ +-- +^warning: ignoring +^VERIFICATION SUCCESSFUL$ diff --git a/regression/invariants/invariant-failure8/test.desc b/regression/invariants/invariant-failure8/test.desc new file mode 100644 index 00000000000..1165b32a25f --- /dev/null +++ b/regression/invariants/invariant-failure8/test.desc @@ -0,0 +1,13 @@ +CORE +dummy_parameter.c +check-return-structured +^EXIT=(0|127|134|137)$ +^SIGNAL=0$ +--- begin invariant violation report --- +Invariant check failed +Error code: 1 +Description: Structured error +^(Backtrace)|(Backtraces not supported)$ +-- +^warning: ignoring +^VERIFICATION SUCCESSFUL$ diff --git a/regression/invariants/invariant-failure9/test.desc b/regression/invariants/invariant-failure9/test.desc new file mode 100644 index 00000000000..38aebd70d61 --- /dev/null +++ b/regression/invariants/invariant-failure9/test.desc @@ -0,0 +1,12 @@ +CORE +dummy_parameter.c +unreachable-string +^EXIT=(0|127|134|137)$ +^SIGNAL=0$ +--- begin invariant violation report --- +Unreachable +Invariant check failed +^(Backtrace)|(Backtraces not supported)$ +-- +^warning: ignoring +^VERIFICATION SUCCESSFUL$ diff --git a/regression/taint/Makefile b/regression/taint/Makefile deleted file mode 100644 index 40dbe9c53be..00000000000 --- a/regression/taint/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -default: tests.log - -test: - @../test.pl -c ../../../src/goto-analyzer/goto-analyzer - -tests.log: ../test.pl - @../test.pl -c ../../../src/goto-analyzer/goto-analyzer - -show: - @for dir in *; do \ - if [ -d "$$dir" ]; then \ - vim -o "$$dir/*.java" "$$dir/*.out"; \ - fi; \ - done; - -clean: - find -name '*.out' -execdir $(RM) '{}' \; - find -name '*.gb' -execdir $(RM) '{}' \; - $(RM) tests.log diff --git a/regression/taint/aliasing1/test.desc b/regression/taint/aliasing1/test.desc deleted file mode 100644 index a0ac6401d67..00000000000 --- a/regression/taint/aliasing1/test.desc +++ /dev/null @@ -1,9 +0,0 @@ -CORE -aliasing1.class ---taint taint.json -^EXIT=0$ -^SIGNAL=0$ -^file aliasing1.java line 10: There is a flow \(taint rule my_sink\)$ --- -^file aliasing1.java line 8: There is a flow \(taint rule my_sink\)$ -^warning: ignoring diff --git a/regression/taint/basic1/test.desc b/regression/taint/basic1/test.desc deleted file mode 100644 index c4384ac9655..00000000000 --- a/regression/taint/basic1/test.desc +++ /dev/null @@ -1,9 +0,0 @@ -CORE -basic1.class ---taint taint.json -^EXIT=0$ -^SIGNAL=0$ -^file basic1.java line 8: There is a T1 flow \(taint rule my_h1\)$ -^file basic1.java line 11: There is a T2 flow \(taint rule my_h2\)$ --- -^warning: ignoring diff --git a/regression/taint/basic2/test.desc b/regression/taint/basic2/test.desc deleted file mode 100644 index 428281280c8..00000000000 --- a/regression/taint/basic2/test.desc +++ /dev/null @@ -1,9 +0,0 @@ -CORE -basic2.class ---taint taint.json -^EXIT=0$ -^SIGNAL=0$ -^file basic2.java line 8: There is a T1 flow \(taint rule my_h1\)$ -^file basic2.java line 11: There is a T2 flow \(taint rule my_h2\)$ --- -^warning: ignoring diff --git a/regression/taint/interface1/test.desc b/regression/taint/interface1/test.desc deleted file mode 100644 index 6ac81f15786..00000000000 --- a/regression/taint/interface1/test.desc +++ /dev/null @@ -1,8 +0,0 @@ -CORE -interface1.class ---taint taint.json -^EXIT=0$ -^SIGNAL=0$ -^file interface1.java line 18: There is a flow! \(taint rule sink_rule\)$ --- -^warning: ignoring diff --git a/regression/taint/map1/test.desc b/regression/taint/map1/test.desc deleted file mode 100644 index 5526aa21b3a..00000000000 --- a/regression/taint/map1/test.desc +++ /dev/null @@ -1,8 +0,0 @@ -CORE -map1.class ---taint taint.json -^EXIT=0$ -^SIGNAL=0$ -^file map1.java line 12: There is a flow \(taint rule my_sink\)$ --- -^warning: ignoring diff --git a/regression/test.pl b/regression/test.pl index d27c663b0aa..f309a293ba9 100755 --- a/regression/test.pl +++ b/regression/test.pl @@ -35,7 +35,6 @@ ($$$$$) print LOG " Core: $dumped_core\n"; if($signal_num != 0) { - $failed = 1; print "Killed by signal $signal_num"; if($dumped_core) { print " (code dumped)"; @@ -72,7 +71,9 @@ ($$$$$) $options =~ s/$ign//g if(defined($ign)); - my $output = $input; + my $descriptor = $test; + $descriptor =~ s/^.*\///; + my $output = $descriptor; $output =~ s/\.[^.]*$/.out/; if($output eq $input) { @@ -83,6 +84,7 @@ ($$$$$) print LOG "Test '$name'\n"; print LOG " Level: $level\n"; print LOG " Input: $input\n"; + print LOG " Descriptor: $descriptor\n"; print LOG " Output: $output\n"; print LOG " Options: $options\n"; print LOG " Results:\n"; @@ -182,7 +184,7 @@ () my @list; opendir CWD, "."; - @list = grep { !/^\./ && -d "$_" && !/CVS/ && -s "$_/test.desc" } readdir CWD; + @list = grep { !/^\./ && -d "$_" && !/CVS/ } readdir CWD; closedir CWD; @list = sort @list; diff --git a/scripts/compare_postprocessor_output.py b/scripts/compare_postprocessor_output.py new file mode 100644 index 00000000000..10dcb0f2709 --- /dev/null +++ b/scripts/compare_postprocessor_output.py @@ -0,0 +1,99 @@ +import difflib, argparse, subprocess, sys, os, multiprocessing, itertools + + +def preprocess(compiler, file_contents): + """ Get output from the preprocessing pass on a file. """ + output = subprocess.Popen( + [compiler, '-E', '-'], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + stdin=subprocess.PIPE).communicate(input=file_contents)[0] + + def should_keep(line): + return str.strip(line) and line[0] != '#' + + return filter(should_keep, output.splitlines()) + + +def preprocess_file(compiler, filename): + """ Open a file and get the preprocessor output. """ + with open(filename, 'rb') as f: + return preprocess(compiler, f.read()) + + +def file_contents_from_branch(filename, branch): + """ Get a copy of a file from another branch and return its contents. """ + return subprocess.check_output( + ['git', 'show', '%s:%s' % (branch, filename)]) + + +def equal_to_file_on_branch(filename, branch, compiler): + """ + Open a file on this branch and preprocess it. Preprocess the same file + from another branch, and return a diff. + """ + with open(filename, 'rb') as f: + def p(text): + return preprocess(compiler, text) + return difflib.unified_diff(p(f.read()), + p(file_contents_from_branch(filename, branch)), + fromfile=filename, + tofile=filename, + lineterm='') + + +def is_source(filename): + """ Return whether the file appears to be a C++ source file. """ + _, ext = os.path.splitext(filename) + return ext == '.h' or ext == '.cpp' + + +def process(tup): + """ + Check a single file, and return its name if the check fails, otherwise + return None. + """ + filename, branch, compiler = tup + failed = '\n'.join(equal_to_file_on_branch(filename, branch, compiler)) + return failed if failed else None + + +def main(): + """ + Open a file and compare its preprocessor output to the output from the same + file on a different branch. Return 0 if the outputs match, or 1 otherwise. + """ + parser = argparse.ArgumentParser() + parser.add_argument( + '--branch', type=str, default='upstream/master', + help='The branch to compare') + parser.add_argument( + '--compiler', type=str, default='g++', + help='The compiler to use') + args = parser.parse_args() + + all_files = [os.path.join(root, file) + for root, _, files in os.walk('.') for file in files] + source_files = filter(is_source, all_files) + + zipped = zip( + source_files, + itertools.cycle([args.branch]), + itertools.cycle([args.compiler])) + + pool = multiprocessing.Pool(10) + + results = filter(None, pool.map(process, zipped)) + + pool.close() + pool.join() + + if results: + print('\n\n'.join(results)) + return 1 + + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/scripts/cpplint.py b/scripts/cpplint.py index 4346bd7a4ae..84da2ae8ac9 100755 --- a/scripts/cpplint.py +++ b/scripts/cpplint.py @@ -235,6 +235,7 @@ 'readability/function_comment' 'runtime/arrays', 'runtime/casting', + 'runtime/endl', 'runtime/explicit', 'runtime/int', 'runtime/init', @@ -1966,7 +1967,9 @@ def GetHeaderGuardCPPVariable(filename): fileinfo = FileInfo(filename) file_path_from_root = fileinfo.RepositoryName() - file_path_from_root = 'CPROVER_' + file_path_from_root[4:] + # Remove first path component + offset=len(file_path_from_root.split(os.path.sep)[0])+1 + file_path_from_root = 'CPROVER_' + file_path_from_root[offset:] if _root: suffix = os.sep # On Windows using directory separator will leave us with @@ -4628,6 +4631,27 @@ def CheckAltTokens(filename, clean_lines, linenum, error): _ALT_TOKEN_REPLACEMENT[match.group(1)], match.group(1))) +def CheckAssert(filename, clean_lines, linenum, error): + """Check for uses of assert. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + line = clean_lines.elided[linenum] + match = Match(r'.*\s+assert\(.*\).*', line) + if match: + if Match(r'.*\s+assert\((0|false)\).*', line): + error(filename, linenum, 'build/deprecated', 4, + 'assert is deprecated, use UNREACHABLE instead') + else: + error(filename, linenum, 'build/deprecated', 4, + 'assert is deprecated, use INVARIANT, PRECONDITION, CHECK_RETURN, etc. instead') + + + def GetLineWidth(line): """Determines the width of the line in column positions. @@ -4852,6 +4876,7 @@ def CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state, CheckSpacingForFunctionCall(filename, clean_lines, linenum, error) CheckCheck(filename, clean_lines, linenum, error) CheckAltTokens(filename, clean_lines, linenum, error) + CheckAssert(filename, clean_lines, linenum, error) classinfo = nesting_state.InnermostClass() if classinfo: CheckSectionSpacing(filename, clean_lines, classinfo, linenum, error) @@ -6191,13 +6216,32 @@ def CheckItemIndentationInNamespace(filename, raw_lines_no_comments, linenum, def CheckNamespaceOrUsing(filename, clean_lines, linenum, error): line = clean_lines.elided[linenum] - if Match(r'^namespace(\s|$)', line): - error(filename, linenum, 'readability/namespace', 4, - 'Do not use namespaces') + if Match(r'^\s*namespace(\s+.*)?$', line): + num_lines=len(clean_lines.elided) + current_linenum=linenum + while current_linenum>sys.stderr, "Usage: filter_by_diff.py diffed_file diff.patch repository_root_directory < warnings.txt" + sys.exit(1) + +diffed_file = sys.argv[1] +diff_file = sys.argv[2] +repository_root = sys.argv[3] + +# Create a set of all the files and the specific lines within that file that are in the diff +added_lines = set() +for diff_file in unidiff.PatchSet.from_filename(diff_file): + filename = diff_file.target_file + # Skip files deleted in the tip (b side of the diff): + if filename == "/dev/null": + continue + assert filename.startswith("b/") + filename = os.path.join(repository_root, filename[2:]) + if filename != diffed_file: + continue + added_lines.add((filename, 0)) + for diff_hunk in diff_file: + for diff_line in diff_hunk: + if diff_line.line_type == "+": + added_lines.add((filename, diff_line.target_line_no)) + +# Print the lines that are in the set +found = False +for line in sys.stdin: + line_parts = line.split(":") + if len(line_parts) < 3: + if found: + # Print lines between a matching warning and the next warning + sys.stdout.write(line) + continue + try: + linenum = int(line_parts[1]) + found = False + filename = line_parts[0] + if not repository_root in filename: + filename = os.path.join(repository_root, line_parts[0]) + if (filename, linenum) in added_lines: + found = True + sys.stdout.write(line) + except ValueError: + if found: + sys.stdout.write(line) + continue diff --git a/scripts/filter_lint_by_diff.py b/scripts/filter_lint_by_diff.py deleted file mode 100755 index e018cce315c..00000000000 --- a/scripts/filter_lint_by_diff.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python - -import sys -import unidiff -import os.path - -if len(sys.argv) != 3: - print >>sys.stderr, "Usage: filter_lint_by_diff.py diff.patch repository_root_directory < cpplint_warnings.txt" - sys.exit(1) - -repository_root = sys.argv[2] - -# Create a set of all the files and the specific lines within that file that are in the diff -added_lines = set() -for diff_file in unidiff.PatchSet.from_filename(sys.argv[1]): - filename = diff_file.target_file - # Skip files deleted in the tip (b side of the diff): - if filename == "/dev/null": - continue - assert filename.startswith("b/") - filename = os.path.join(repository_root, filename[2:]) - added_lines.add((filename, 0)) - for diff_hunk in diff_file: - for diff_line in diff_hunk: - if diff_line.line_type == "+": - added_lines.add((filename, diff_line.target_line_no)) - -# Print the lines that are in the set -for line in sys.stdin: - line_parts = line.split(":") - if len(line_parts) < 3: - continue - filename = os.path.join(repository_root, line_parts[0]) - linenum = int(line_parts[1]) - if (filename, linenum) in added_lines: - sys.stdout.write(line) diff --git a/scripts/ls_parse.py b/scripts/ls_parse.py new file mode 100755 index 00000000000..556b55fa50d --- /dev/null +++ b/scripts/ls_parse.py @@ -0,0 +1,520 @@ +#!/usr/bin/env python3 +# +# Dump info about linker script symbols that pertain to addresses and sizes. +# +# Author: Kareem Khazem +# Copyright Amazon, Inc. 2017 + + +import argparse +import json +import logging +from logging import error, warning, info, debug +import os +import re +import subprocess +import sys +import textwrap + + +def epilog(): + return textwrap.dedent(""" + This script generates a C file containing two kinds of information: + + - The values of symbols that are defined in a linker script; these + are printed as C definitions, like + char *bss_start = (char *)4070047185u; + + - The extent of ELF sections that are defined in a linker script; + these are printed as CPROVER annotations, like + __CPROVER_allocated_memory(0xe9fda44b, 4096); + + A goto-binary of this C file can be linked into the rest of the + codebase that you wish to analyse. This provides CPROVER with + definitions that it otherwise would not have access to, since they + are defined in a linker script rather than C code. This information + can also be printed in JSON rather than as a C file, so that CPROVER + can invoke and use this script without user intervention. + + This script needs a list of symbols declared but never defined in C + code. The hacky way of supplying this list is by passing the path to + the codebase with the --dir flag; this script will scan the codebase + for extern-declared variables. A better way is to generate that list + with CPROVER, and pass that list in using --sym-file. The argument + to --sym-file can be a filename, or '-' for stdin. + """) + + +"""`Running-regex' linker script parser. We don't currently use a full +grammar, as we only need a fraction of the information contained in +linker scripts to give to CBMC. If in the future we need a more +sophisticated parser, we should use an actual grammar from a real +parser. GNU LD uses a YACC/Flex setup and has a very complete grammar, +but we cannot use it (GPL 3). LLD (the LLVM project's linker script +parser) is hand-written (so no explicit grammar), but they do not aim to +support all of GNU LD's syntax, so LLD doesn't work on some real linker +scripts. So in summary: use this regex parser while it's practical; +switch to LLD when needed, and possibly contribute to LLD development to +support parsing your use case.""" +def get_linker_script_data(script): + try: + with open(script) as f: + lines = f.read().splitlines() + except IOError: + error("Linker script '%s' not found", script) + exit(1) + + text = " ".join(lines) + text = re.sub(r"\s+", " ", text) + + # In these regexes, we always start by matching a whitespace. This + # is so that we don't match every substring of an identifier. i.e. + # if we have a section definition .text : { ..., then we only want + # to recognise a section called ".text", and not also "text", "ext", + # "xt", and "t". + # + # Just to be safe, ensure that the first character of the linker + # script is a whitespace. + text = " %s" % text + + close_brace = re.compile(r"\s}") + memory_cmd = re.compile(r"\sMEMORY\s*{") + sections_cmd = re.compile(r"\sSECTIONS\s*{") + assign_current = re.compile(r"\s(?P\w+)\s*=\s*\.\s*;") + sec_def = re.compile(r"\s(?P([-\.\w]+)|(/DISCARD/))" + r"\s+([^:{};]*?):([^:{};])*?{") + assign_size = re.compile(r"\s(?P\w+)\s*=\s*SIZEOF\(" + r"(?P\.\w+)\)\s*;") + memory_block = re.compile(r"\s(?P\w+)\s*:\s*ORIGIN\s*=\s*" + r"(?P0x[a-fA-F0-9]+)\s*,\s*" + r"LENGTH\s*=\s*(?P\d+)\s*" + r"(?P[KMG])") + exp = r"(ORIGIN\(\w+\)|LENGTH\(\w+\))" + op = r"(\+|\-)" + assign_expr = re.compile(r"\s(?P\w+)\s*=\s*" + r"(?P{exp}(\s*{op}\s*{exp})*)" + r"\s*;".format(exp=exp, op=op)) + + # If we match a regex, call the right function to update the state + # with the info gleaned from the matched string. + jump_table = { + close_brace : close_brace_fun, + memory_cmd : memory_cmd_fun, + sections_cmd : sections_cmd_fun, + assign_current : assign_current_fun, + memory_block : memory_block_fun, + sec_def : sec_def_fun, + assign_size : assign_size_fun, + assign_expr : assign_expr_fun, + } + + # Whenever we match an interesting regex, we'll update the state + # with whatever information we want to rip from that bit of text. + state = {} + + # The section definition that we were last in. + state["cur-sec"] = None + + # If we know what section *start* the current address (.) points to, + # then this will not be None. It's used to match an assignment to + # the start of a section. + state["start-valid"] = None + + # If we have just seen an assignment, then this will not be None. + # It's used to match up an assignment with the end of a section. + state["end-valid"] = None + + # Each entry here maps a section name to a map. That map maps "size" + # to the symbol pointing to the size of the section, and "start" + # to the symbol pointing to the start address of the section. One of + # "start" or "size" may be absent, if we couldn't get that bit of + # information from the linker script. + state["sections"] = {} + + # We can use the list of valid addresses to sanity-check that the + # start addresses of sections are genuinely addresses. + state["valid-addresses"] = [] + + # Symbols that get some expression assigned to them, either inside + # or outside a section definition. We'll match them up later. + state["expr-assigns"] = [] + + # These are to sanity-check the parsing. + state["MEM"] = False + state["SEC"] = False + state["DEF"] = False + + i = 0 + while i < len(text): + buf = text[i:] + i += 1 + asrt(not (state["MEM"] and state["SEC"]), + "memory & sections", buf) + asrt(not state["DEF"] or state["SEC"], + "def outside SECTION", buf) + + jump_fun = None + matched_str = None + matched_re = None + match = None + for regex, fun in jump_table.items(): + m = regex.match(buf) + if m: + if jump_fun is not None: + error("matched multiple regexes\n%s", buf) + exit(1) + jump_fun = fun + match = m + matched_str = buf[m.span()[0]:m.span()[1]] + for s, v in locals().items(): + if v is regex and s is not "regex": + matched_re = s + if jump_fun is not None: + info("regex '%s' matched '%s'", matched_re, matched_str) + jump_fun(state, match, buf) + i = i + match.span()[1] - 1 + else: + debug("Clobbering due to '%s'...", buf[:20]) + # There may have been some intermediate command between the + # start of a section definition and where we are. So we have + # no idea what address the current address pointer refers to + state["start-valid"] = None + # There may have been an intermediate command between the + # last assignment and the end of the section. + state["end-valid"] = None + match_up_expr_assigns(state) + return state + + +def assign_expr_fun(state, match, _): + # Do NOT invalidate 'start-valid' here. Assignments from expressions + # do not actually advance the current address pointer. + sym, expr = match.group("sym"), match.group("expr") + origin_pat = r"ORIGIN\((?P\w+?)\)" + origins = re.findall(origin_pat, expr) + if len(origins) != 1: + info("assign with %d origins, skipping: %s", len(origins), + match.string()) + return + ret = {"origin": origins[0], "sym": sym} + for block_name, data in state["blocks"].items(): + for op in ["ORIGIN", "LENGTH"]: + old_expr = str(expr) + expr = re.sub(r"%s\(%s\)" % (op, block_name), str(data[op]), + expr) + if expr != old_expr: + info("Subbed %s(%s) with %d", op, block_name, data[op]) + info("Final expression is '%s'. Evaluating; " + "may the angels have mercy on my soul.", expr) + try: + ret["addr"] = eval(expr) + except RuntimeError: + warning("Unable to evaluate '%s'" , expr) + info("Evaluated '%s' to %d", expr, ret["addr"]) + state["expr-assigns"].append(ret) + + +def sec_def_fun(state, match, buf): + asrt(not state["DEF"], "nested sec def", buf) + state["DEF"] = True + sec = match.group("sec") + info("Current section is now '%s'", sec) + state["cur-sec"] = sec + state["start-valid"] = True + + +def assign_size_fun(state, match, buf): + asrt(state["SEC"], "assignment outside SECTIONS", buf) + sec = match.group("sec") + if sec not in state["sections"]: + state["sections"][sec] = {} + sym = match.group("sym") + info("'%s' marks the size of section '%s'", sym, sec) + state["sections"][sec]["size"] = sym + + +def assign_current_fun(state, match, buf): + asrt(state["SEC"], "assignment outside SECTIONS", buf) + sec = state["cur-sec"] + state["end-valid"] = match + if state["start-valid"]: + if sec not in state["sections"]: + state["sections"][sec] = {} + sym = match.group("sym") + info("'%s' marks the start of section '%s'", sym, sec) + state["sections"][sec]["start"] = sym + else: + info("Don't know where we are.") + + +def close_brace_fun(state, _, buf): + # We might have seen an assignment immediately before this. + if state["end-valid"]: + asrt(state["DEF"], "end-valid outside sec-def", buf) + sec = state["cur-sec"] + if sec in state["sections"]: + sym = state["end-valid"].group("sym") + info("'%s' marks the end of section '%s'", sym, sec) + state["sections"][sec]["end"] = sym + else: + # Linker script assigned end-of-section to a symbol, but not + # the start. this is useless to us. + pass + + if state["DEF"]: + info("Closing sec-def") + state["DEF"] = False + elif state["SEC"]: + info("Closing sections") + state["SEC"] = False + elif state["MEM"]: + info("Closing memory command") + state["MEM"] = False + else: + error("Not in block\n%s", buf) + exit(1) + + +def memory_block_fun(state, m, buf): + asrt(state["MEM"], "memory block outside MEMORY", buf) + start, length, unit = m.group("orig"), m.group("len"), m.group("unit") + length = int(length) + dec_start = int(start, 16) + mul = {"K": 1000, "M": 1000000, "G": 1000000000} + length = length * mul[unit] + end = dec_start + length + info("mem block %s from %d to %d (%d%s long)", start, dec_start, end, + length, unit) + state["valid-addresses"].append({"from": dec_start, "to": end}) + + name = m.group("name") + if "blocks" not in state: + state["blocks"] = {} + state["blocks"][name] = {"ORIGIN": int(start, 16), "LENGTH": length} + + +def sections_cmd_fun(state, _, buf): + asrt(not state["SEC"], "encountered SECTIONS twice", buf) + state["SEC"] = True + + +def memory_cmd_fun(state, _, buf): + asrt(not state["MEM"], "encountered MEMORY twice", buf) + state["MEM"] = True + + +def match_up_expr_assigns(state): + blocks = set([data["origin"] for data in state["expr-assigns"]]) + for block in blocks: + assigns = [a for a in state["expr-assigns"] + if a["origin"] == block] + assigns = sorted(assigns, key=(lambda a: a["addr"])) + if len(assigns) < 2: + warning("Only 1 assignment to expr involving %s", block) + continue + start_addr, end_addr = assigns[0]["addr"], assigns[-1]["addr"] + start_sym, end_sym = assigns[0]["sym"], assigns[-1]["sym"] + info("Valid memory from %s (%d) to %s (%s) [%s block]", + start_sym, start_addr, end_sym, end_addr, block) + tmp = {"start": start_sym, "end": end_sym} + sec_name = "BLOCK_%s_%s-%s" % (block, start_sym, end_sym) + state["sections"][sec_name] = tmp + + +def asrt(cond, msg, buf): + if not cond: + error("%s\n%s", msg, buf) + exit(1) + + +def needed_definitions(all_symbols, root_dir): + ret = [] + pat = re.compile(r"extern\s+char\s+(?P\w+)\[\];") + allowed = [".c", ".cpp", ".h"] + for root, _, files in os.walk(root_dir): + for file in files: + file = os.path.join(root, file) + _, ext = os.path.splitext(file) + if ext not in allowed: + continue + with open(file) as f: + for line in f: + m = pat.match(line) + if m: + ret.append(m.group("var")) + bad = [v for v in ret if v not in all_symbols] + if bad: + logging.error("These symbols need definitions but are not " + "in the object file: %s", ", ".join(bad)) + exit(1) + logging.info("need symbols:\n%s", "\n".join(ret)) + return ret + + +def symbols_from(object_file): + cmd = ["objdump", "--syms", object_file] + proc = subprocess.Popen(cmd, universal_newlines=True, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + if proc.wait(): + logging.error("`%s` failed. Output:\n%s", " ".join(cmd), + proc.stdout.read()) + exit(1) + pat = re.compile(r"(?P[^\s]+)\s+" + r"(?P[lgu! ][w ][C ][W ][Ii ][Dd ][FfO ])\s+" + r"(?P
    [^\s]+)\s+" + r"(?P[0-9a-f]+)\s+" + r"(?P[^\s]*)" # Can be empty! + ) + matching = False + ret = {} + for line in proc.stdout.read().splitlines(): + if not line: + continue + if not matching and re.match("SYMBOL TABLE:", line): + matching = True + continue + if not matching: + continue + m = pat.match(line) + if not m: + logging.error("Unexpected line from `%s`:\n%s", + " ".join(cmd), line) + exit(1) + ret[m.group("name")] = m.group("addr") + logging.info("found symbols:\n%s", "\n".join( + ["0x%-16s %s" % (v, k) for k, v in ret.items()])) + return ret + + +def match_up_addresses(script_data, symbol_table): + ret = [] + for data in script_data["sections"].values(): + ok = False + if "size" in data and "start" in data: + ok = True + if "end" in data and "start" in data: + ok = True + if not ok: + continue + region = {} + for sym, value in symbol_table.items(): + if "size" in data and sym == data["size"]: + region["size"] = {"sym": sym, "val": value} + if "start" in data and sym == data["start"]: + region["start"] = {"sym": sym, "val": value} + if "end" in data and sym == data["end"]: + region["end"] = {"sym": sym, "val": value} + append = False + if "size" in region and "start" in region: + append = True + if "end" in region and "start" in region: + append = True + if append: + ret.append(region) + return ret + + +def get_region_range(region): + ret = {} + if "end" in region: + start = int(region["start"]["val"], 16) + end = int(region["end"]["val"], 16) + size = end - start + s_var = region["start"]["sym"] + e_var = region["end"]["sym"] + ret["start"] = start + ret["size"] = size + ret["annot"] = "__CPROVER_allocated_memory(%s, %d);" % (hex(start), size) + ret["commt"] = "from %s to %s" % (s_var, e_var) + elif "size" in region: + start = int(region["start"]["val"], 16) + size = int(region["size"]["val"], 16) + s_var = region["start"]["sym"] + z_var = region["size"]["sym"] + ret["start"] = start + ret["size"] = size + ret["annot"] = "__CPROVER_allocated_memory(%s, %d);" % (hex(start), size) + ret["commt"] = "from %s for %s bytes" % (s_var, z_var) + else: + raise "Malformatted region\n%s" % str(region) + return ret + + +def final_json_output(regions, symbol_table): + ret = {"regions": [], "addresses": []} + for s, v in symbol_table.items(): + ret["addresses"].append({"sym": s, "val": int(v, 16)}) + for region in regions: + ret["regions"].append(get_region_range(region)) + return ret + + + +def symbols_from_file(sym_file): + if sym_file == "-": + return [s.strip() for s in sys.stdin.readlines()] + else: + with open(sym_file) as f: + return [s.strip() for s in f.readlines()] + + +def main(): + pars = argparse.ArgumentParser( + description="Generate info about linker-defined symbols and regions.", + epilog=epilog(), + formatter_class=argparse.RawDescriptionHelpFormatter) + pars.add_argument("-s", "--script", metavar="S", required=True, + help="path to linker script") + pars.add_argument("-o", "--object", metavar="O", required=True, + help="path to fully-linked binary") + + sym_source = pars.add_mutually_exclusive_group(required=True) + sym_source.add_argument("-d", "--dir", metavar="D", + help="path to top-level of codebase") + sym_source.add_argument("-i", "--sym-file", + metavar="F", help="file of names of linker symbols") + + pars.add_argument("-t", "--out-file", metavar="F", + help="default: stdout", default=None) + + verbs = pars.add_mutually_exclusive_group() + verbs.add_argument("-v", "--verbose", action="store_true") + verbs.add_argument("-w", "--very-verbose", action="store_true") + + args = pars.parse_args() + + if args.verbose: + lvl = logging.INFO + elif args.very_verbose: + lvl = logging.DEBUG + else: + lvl = logging.WARNING + form = "linkerscript parse %(levelname)s: %(message)s" + logging.basicConfig(format=form, level=lvl) + + script_data = get_linker_script_data(args.script) + symbol_table = symbols_from(args.object) + if args.dir: + needed = needed_definitions(symbol_table.keys(), args.dir) + else: + needed = symbols_from_file(args.sym_file) + symbol_table = {k:v for k, v in symbol_table.items() if k in needed} + + regions = match_up_addresses(script_data, symbol_table) + + info(json.dumps(symbol_table, indent=2)) + info(json.dumps(script_data, indent=2)) + info(json.dumps(regions, indent=2)) + + final = json.dumps(final_json_output(regions, symbol_table), + indent=2) + if args.out_file: + with open(args.out_file, "w") as f: + f.write(final) + info(final) + else: + print(final) + + +if __name__ == "__main__": + main() diff --git a/scripts/reformat_docs.py b/scripts/reformat_docs.py new file mode 100644 index 00000000000..eadc5359052 --- /dev/null +++ b/scripts/reformat_docs.py @@ -0,0 +1,267 @@ +import re, collections, textwrap, sys, argparse, platform + +Field = collections.namedtuple('Field', ['name', 'contents']) + +Header = collections.namedtuple('Header', ['module']) + +Function = collections.namedtuple('Function', + ['name', 'purpose', 'inputs', 'returns']) + +Class = collections.namedtuple('Class', ['name', 'purpose']) + + +def warn(message): + """ Print a labelled message to stderr. """ + sys.stderr.write('Warning: %s\n' % message) + + +def header_from_block(block): + """ Create a Header structure from a parsed Block. """ + return Header(block.fields['Module']) + + +def function_from_block(block): + """ Create a Function structure from a parsed Block. """ + return Function(block.fields.get('Function', None), + block.fields.get('Purpose', None), block.fields.get('Inputs', None), + block.fields.get('Outputs', None)) + + +def make_field(name, contents): + return Field(name, contents if contents.strip() else None) + + +def class_from_block(block): + """ Create a Class structure from a parsed Block. """ + return Class(block.fields.get('Class', None), + block.fields.get('Purpose', None)) + + +def parse_fields(block_contents): + """ Extract the named fields of an old-style comment block. """ + + field_re = re.compile( + r'(?:\n *(Purpose):(.*))|(?:\n *([a-zA-Z0-9]+?):\n?(.*?)?^$)', + re.MULTILINE | re.DOTALL) + for m in field_re.finditer(block_contents): + # If the field is a Purpose field + if m.lastindex == 2: + yield make_field(m.group(1), textwrap.dedent(m.group(2))) + # If the field is any other field + elif m.lastindex == 3 or m.lastindex == 4: + yield make_field(m.group(3), textwrap.dedent(m.group(4))) + + +Block = collections.namedtuple('Block', ['fields']) + + +def has_field(block, field_name): + """ Return whether the block has a field with the given name. """ + return field_name in block.fields + + +def make_doxy_comment(text): + text = re.sub(r'^(?!$)', r'/// ', text, flags=re.MULTILINE) + return re.sub(r'^(?=$)', r'///' , text, flags=re.MULTILINE) + + +class GenericFormatter(object): + def __init__(self, doc_width): + self.text_wrapper = textwrap.TextWrapper(width=doc_width) + self.indented_wrapper = textwrap.TextWrapper(width=doc_width, + subsequent_indent=r' ') + self.whitespace_re = re.compile(r'\n\s*', re.MULTILINE | re.DOTALL) + + def convert(self, block): + sections = filter(None, self.convert_sections(block)) + if sections: + return make_doxy_comment('\n'.join(sections)) + '\n' + return '' + + +class HeaderFormatter(GenericFormatter): + def format_module(self, header): + if not header.module: + return None + + subbed = self.whitespace_re.sub(' ', header.module) + # The file directive must be followed by a newline in order to refer to + # the current file + return '\\file\n' + self.indented_wrapper.fill(subbed) + + def is_block_valid(self, block): + return has_field(block, 'Module') + + def convert_sections(self, block): + return [self.format_module(block)] + + def needs_new_header(self, file_contents): + return (re.search(r'^\/\/\/ \\file$', file_contents, flags=re.MULTILINE) + is None) + + +class FunctionFormatter(GenericFormatter): + def __init__(self, doc_width): + super(FunctionFormatter, self).__init__(doc_width) + self.paragraph_re = re.compile(r'(.*?)^$(.*)', re.MULTILINE | re.DOTALL) + + def format_purpose(self, function): + if not function.purpose: + return None + + match = self.paragraph_re.match(function.purpose) + first_paragraph = match.group(1) + first_paragraph = self.whitespace_re.sub(' ', + first_paragraph) if first_paragraph else '' + + tail_paragraphs = (('\n' + match.group(2)) if match.group(2) else '') + formatted_purpose = (self.text_wrapper.fill(first_paragraph) + + tail_paragraphs) + + return formatted_purpose.strip() + + def format_inputs(self, function): + if not function.inputs: + return None + + if re.match(r'^\s*\S+\s*$', function.inputs): + return None + + def param_replacement(match): + return r'\param %s:' % match.group(1) + + lines = function.inputs.split('\n') + tail = '\n'.join(lines[1:]) + + dedented = lines[0] + '\n' + textwrap.dedent(tail) + + text = re.sub(r'\n\s+', ' ', dedented, flags=re.MULTILINE) + text, num_replacements = re.subn(r'^([a-zA-Z0-9_]+)\s*[:-]', + param_replacement, text, flags=re.MULTILINE) + + if num_replacements == 0: + text = r'\par parameters: %s' % text + + text = '\n'.join( + self.indented_wrapper.fill(t) for t in text.split('\n')) + return text.strip() + + def format_returns(self, function): + if not function.returns: + return None + + subbed = self.whitespace_re.sub(' ', function.returns) + return self.indented_wrapper.fill(r'\return %s' % subbed) + + def is_block_valid(self, block): + return has_field(block, 'Function') + + def convert_sections(self, block): + return [ + self.format_purpose(block), + self.format_inputs(block), + self.format_returns(block)] + + +class ClassFormatter(GenericFormatter): + def __init__(self, doc_width): + super(ClassFormatter, self).__init__(doc_width) + self.paragraph_re = re.compile(r'(.*?)^$(.*)', re.MULTILINE | re.DOTALL) + + def format_purpose(self, klass): + if not klass.purpose: + return None + + match = self.paragraph_re.match(klass.purpose) + first_paragraph = match.group(1) + first_paragraph = self.whitespace_re.sub(' ', + first_paragraph) if first_paragraph else '' + + tail_paragraphs = (('\n' + match.group(2)) if match.group(2) else '') + formatted_purpose = (self.text_wrapper.fill(first_paragraph) + + tail_paragraphs) + + return formatted_purpose.strip() + + def is_block_valid(self, block): + return has_field(block, 'Class') + + def convert_sections(self, block): + return [self.format_purpose(block)] + + +def replace_block( + block_contents, + file_contents, + file, + header_formatter, + class_formatter, + function_formatter): + """ + Replace an old-style documentation block with the doxygen equivalent + """ + block = Block( + {f.name: f.contents for f in parse_fields(block_contents.group(1))}) + + if header_formatter.is_block_valid(block): + converted = header_formatter.convert(header_from_block(block)) + if header_formatter.needs_new_header(file_contents) and converted: + return block_contents.group(0) + converted + '\n' + return block_contents.group(0) + + if class_formatter.is_block_valid(block): + return class_formatter.convert(class_from_block(block)) + + if function_formatter.is_block_valid(block): + return function_formatter.convert(function_from_block(block)) + + warn('block in "%s" has unrecognised format:\n%s' % + (file, block_contents.group(1))) + + return '' + + +def convert_file(file, inplace): + """ Replace documentation in file with doxygen-styled comments. """ + with open(file) as f: + contents = f.read() + + doc_width = 76 + + header_formatter = HeaderFormatter(doc_width) + class_formatter = ClassFormatter(doc_width) + function_formatter = FunctionFormatter(doc_width) + + block_re = re.compile( + r'^/\*+\\$(.*?)^\\\*+/$\s*', re.MULTILINE | re.DOTALL) + new_contents = block_re.sub( + lambda match: replace_block( + match, + contents, + file, + header_formatter, + class_formatter, + function_formatter), contents) + + if inplace: + with open(file, 'w') as f: + f.write(new_contents) + else: + sys.stdout.write(new_contents) + + +def main(): + """ Run convert_file from the command-line. """ + parser = argparse.ArgumentParser() + parser.add_argument('file', type=str, help='The file to process') + parser.add_argument('-i', '--inplace', action='store_true', + help='Process in place') + args = parser.parse_args() + + convert_file(args.file, args.inplace) + + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/scripts/run_diff.sh b/scripts/run_diff.sh new file mode 100755 index 00000000000..43d43f7577a --- /dev/null +++ b/scripts/run_diff.sh @@ -0,0 +1,109 @@ +#!/bin/bash + +set -e + +script_folder=`dirname $0` +absolute_repository_root=`git rev-parse --show-toplevel` +mode=$1 +modes="CPPLINT | DOXYGEN" + +if [[ "$#" -gt 3 ]] +then + echo "Script for running a checker script only on modified lines. Arguments:" + echo "mode - tool to run: $modes" + echo "target - a git reference to the branch we want to compare against (default: 'master')" + echo "tip - a git reference to the commit with changes (default: current working tree)" + exit 1 +fi + +if ! [[ -e $script_folder/filter_by_diff.py ]] +then + echo "Filter script could not be found in the $script_folder directory" + echo "Ensure filter_by_diff.py is inside the $script_folder directory then run again" + exit 1 +fi + +if [[ "$mode" == "CPPLINT" ]] +then + if ! [[ -e $script_folder/cpplint.py ]] + then + echo "Lint script could not be found in the $script_folder directory" + echo "Ensure cpplint.py is inside the $script_folder directory then run again" + exit 1 + else + cmd='$script_folder/cpplint.py $file 2>&1 >/dev/null' + fi +elif [[ "$mode" == "DOXYGEN" ]] +then + doxygen=doxygen + doxygenlogdir="doc/html" + doxygenlog="$doxygenlogdir/doxygen.log" + if ! $doxygen --version &>/dev/null + then + echo "Lint script could not be found in the $script_folder directory" + echo "Ensure cpplint.py is inside the $script_folder directory then run again" + exit 1 + else + mkdir -p $doxygenlogdir && cd src && $doxygen &> ../$doxygenlog && cd .. + cmd='cat $doxygenlog' + fi +else + echo "Mode $mode not recognized" + echo "Possible values: $modes" + exit 1 +fi + +if [[ "$#" -gt 1 ]] +then + git_start=$2 +else + git_start="master" +fi + +if [[ "$#" -gt 2 ]] +then + git_end=$3 + git_merge_base_end=$3 +else + git_end="" + git_merge_base_end="HEAD" +fi + +git_start=`git merge-base $git_start $git_merge_base_end` + +cleanup() +{ + rm -f $diff_file +} + +trap cleanup EXIT + +diff_file=`mktemp` + +git diff $git_start $git_end > $diff_file + +# Get the list of files that have changed +diff_files=`git diff --name-only $git_start $git_end` + +for file in $diff_files; do + file=$absolute_repository_root/$file + # If the file has been deleted we don't want to run the linter on it + if ! [[ -e $file ]] + then + continue + fi + + # Run the linting script and filter: + # The errors from the linter go to STDERR so must be redirected to STDOUT + result=`eval $cmd | $script_folder/filter_by_diff.py $file $diff_file $absolute_repository_root` + + # Providing some errors were relevant we print them out + if [ "$result" ] + then + are_errors=1 + (>&2 echo "$result") + fi +done + +# Return an error code if errors are found +exit $are_errors diff --git a/scripts/run_lint.sh b/scripts/run_lint.sh index fa588f084a3..434fb7a2472 100755 --- a/scripts/run_lint.sh +++ b/scripts/run_lint.sh @@ -1,83 +1,5 @@ #!/bin/bash -set -e - script_folder=`dirname $0` -absolute_repository_root=`git rev-parse --show-toplevel` - -if [[ "$#" -gt 2 ]] -then - echo "Script for running the CPP linter only on modified lines. Arguments:" - echo "target - a git reference to the branch we want to compare against (default: 'master')" - echo "tip - a git reference to the commit with changes (default: current working tree)" - exit 1 -fi - -if ! [[ -e $script_folder/cpplint.py ]] -then - echo "Lint script could not be found in the $script_folder directory" - echo "Ensure cpplint.py is inside the $script_folder directory then run again" - exit 1 -fi - -if ! [[ -e $script_folder/filter_lint_by_diff.py ]] -then - echo "Lint filter script could not be found in the $script_folder directory" - echo "Ensure filter_lint_by_diff.py is inside the $script_folder directory then run again" - exit 1 -fi - -if [[ "$#" -gt 0 ]] -then - git_start=$1 -else - git_start="master" -fi - -if [[ "$#" -gt 1 ]] -then - git_end=$2 - git_merge_base_end=$2 -else - git_end="" - git_merge_base_end="HEAD" -fi - -git_start=`git merge-base $git_start $git_merge_base_end` - -cleanup() -{ - rm -f $diff_file -} - -trap cleanup EXIT - -diff_file=`mktemp` - -git diff $git_start $git_end > $diff_file - -# Get the list of files that have changed -diff_files=`git diff --name-only $git_start $git_end` - -for file in $diff_files; do - file=$absolute_repository_root/$file - # If the file has been deleted we don't want to run the linter on it - if ! [[ -e $file ]] - then - continue - fi - - # Run the linting script and filter: - # The errors from the linter go to STDERR so must be redirected to STDOUT - result=`$script_folder/cpplint.py $file 2>&1 >/dev/null | $script_folder/filter_lint_by_diff.py $diff_file $absolute_repository_root` - - # Providing some errors were relevant we print them out - if [ "$result" ] - then - are_errors=1 - (>&2 echo "$result") - fi -done -# Return an error code if errors are found -exit $are_errors +$script_folder/run_diff.sh CPPLINT "$@" diff --git a/scripts/travis_doxygen.sh b/scripts/travis_doxygen.sh new file mode 100755 index 00000000000..78adcff3c13 --- /dev/null +++ b/scripts/travis_doxygen.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -e + +script_folder=`dirname $0` +pip install --user unidiff + +if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then + $script_folder/run_diff.sh DOXYGEN HEAD~1 # Check for errors introduced in last commit +else + $script_folder/run_diff.sh DOXYGEN $TRAVIS_BRANCH # Check for errors compared to merge target +fi diff --git a/scripts/travis_lint.sh b/scripts/travis_lint.sh index dc1ffb0b81b..036605237ee 100755 --- a/scripts/travis_lint.sh +++ b/scripts/travis_lint.sh @@ -6,8 +6,7 @@ script_folder=`dirname $0` pip install --user unidiff if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then - $script_folder/run_lint.sh HEAD~1 # Check for errors introduced in last commit + $script_folder/run_diff.sh CPPLINT HEAD~1 # Check for errors introduced in last commit else - $script_folder/run_lint.sh $TRAVIS_BRANCH # Check for errors compared to merge target + $script_folder/run_diff.sh CPPLINT $TRAVIS_BRANCH # Check for errors compared to merge target fi - diff --git a/src/analyses/ai.cpp b/src/analyses/ai.cpp index 45d4b83c92c..10653ada420 100644 --- a/src/analyses/ai.cpp +++ b/src/analyses/ai.cpp @@ -6,27 +6,88 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Abstract Interpretation + +#include "ai.h" + #include #include +#include +#include #include #include #include "is_threaded.h" -#include "ai.h" - -/*******************************************************************\ - -Function: ai_baset::output +jsont ai_domain_baset::output_json( + const ai_baset &ai, + const namespacet &ns) const +{ + std::ostringstream out; + output(out, ai, ns); + json_stringt json(out.str()); + return json; +} - Inputs: +xmlt ai_domain_baset::output_xml( + const ai_baset &ai, + const namespacet &ns) const +{ + std::ostringstream out; + output(out, ai, ns); + xmlt xml("domain"); + xml.data=out.str(); + return xml; +} - Outputs: +/// Use the information in the domain to simplify the expression on the LHS of +/// an assignment. This for example won't simplify symbols to their values, but +/// does simplify indices in arrays, members of structs and dereferencing of +/// pointers +/// \param condition: the expression to simplify +/// \param ns: the namespace +/// \return True if condition did not change. False otherwise. condition will be +/// updated with the simplified condition if it has worked +bool ai_domain_baset::ai_simplify_lhs( + exprt &condition, const namespacet &ns) const +{ + // Care must be taken here to give something that is still writable + if(condition.id()==ID_index) + { + index_exprt ie=to_index_expr(condition); + bool no_simplification=ai_simplify(ie.index(), ns); + if(!no_simplification) + condition=simplify_expr(ie, ns); - Purpose: + return no_simplification; + } + else if(condition.id()==ID_dereference) + { + dereference_exprt de=to_dereference_expr(condition); + bool no_simplification=ai_simplify(de.pointer(), ns); + if(!no_simplification) + condition=simplify_expr(de, ns); // So *(&x) -> x -\*******************************************************************/ + return no_simplification; + } + else if(condition.id()==ID_member) + { + member_exprt me=to_member_expr(condition); + // Since simplify_ai_lhs is required to return an addressable object + // (so remains a valid left hand side), to simplify + // `(something_simplifiable).b` we require that `something_simplifiable` + // must also be addressable + bool no_simplification=ai_simplify_lhs(me.compound(), ns); + if(!no_simplification) + condition=simplify_expr(me, ns); + + return no_simplification; + } + else + return true; +} void ai_baset::output( const namespacet &ns, @@ -47,18 +108,6 @@ void ai_baset::output( } } -/*******************************************************************\ - -Function: ai_baset::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ai_baset::output( const namespacet &ns, const goto_programt &goto_program, @@ -79,18 +128,9 @@ void ai_baset::output( } } -/*******************************************************************\ - -Function: ai_baset::output_json - - Inputs: The namespace and goto_functions - - Outputs: The JSON object - - Purpose: Output the domains for the whole program as JSON - -\*******************************************************************/ - +/// Output the domains for the whole program as JSON +/// \par parameters: The namespace and goto_functions +/// \return The JSON object jsont ai_baset::output_json( const namespacet &ns, const goto_functionst &goto_functions) const @@ -113,18 +153,9 @@ jsont ai_baset::output_json( return result; } -/*******************************************************************\ - -Function: ai_baset::output_json - - Inputs: The namespace, goto_program and it's identifier - - Outputs: The JSON object - - Purpose: Output the domains for a single function as JSON - -\*******************************************************************/ - +/// Output the domains for a single function as JSON +/// \par parameters: The namespace, goto_program and it's identifier +/// \return The JSON object jsont ai_baset::output_json( const namespacet &ns, const goto_programt &goto_program, @@ -152,18 +183,9 @@ jsont ai_baset::output_json( return contents; } -/*******************************************************************\ - -Function: ai_baset::output_xml - - Inputs: The namespace and goto_functions - - Outputs: The XML object - - Purpose: Output the domains for the whole program as XML - -\*******************************************************************/ - +/// Output the domains for the whole program as XML +/// \par parameters: The namespace and goto_functions +/// \return The XML object xmlt ai_baset::output_xml( const namespacet &ns, const goto_functionst &goto_functions) const @@ -189,18 +211,9 @@ xmlt ai_baset::output_xml( return program; } -/*******************************************************************\ - -Function: ai_baset::output_xml - - Inputs: The namespace, goto_program and it's identifier - - Outputs: The XML object - - Purpose: Output the domains for a single function as XML - -\*******************************************************************/ - +/// Output the domains for a single function as XML +/// \par parameters: The namespace, goto_program and it's identifier +/// \return The XML object xmlt ai_baset::output_xml( const namespacet &ns, const goto_programt &goto_program, @@ -231,18 +244,6 @@ xmlt ai_baset::output_xml( return function_body; } -/*******************************************************************\ - -Function: ai_baset::entry_state - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ai_baset::entry_state(const goto_functionst &goto_functions) { // find the 'entry function' @@ -254,53 +255,17 @@ void ai_baset::entry_state(const goto_functionst &goto_functions) entry_state(f_it->second.body); } -/*******************************************************************\ - -Function: ai_baset::entry_state - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ai_baset::entry_state(const goto_programt &goto_program) { // The first instruction of 'goto_program' is the entry point get_state(goto_program.instructions.begin()).make_entry(); } -/*******************************************************************\ - -Function: ai_baset::initialize - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ai_baset::initialize(const goto_functionst::goto_functiont &goto_function) { initialize(goto_function.body); } -/*******************************************************************\ - -Function: ai_baset::initialize - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ai_baset::initialize(const goto_programt &goto_program) { // we mark everything as unreachable as starting point @@ -309,36 +274,12 @@ void ai_baset::initialize(const goto_programt &goto_program) get_state(i_it).make_bottom(); } -/*******************************************************************\ - -Function: ai_baset::initialize - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ai_baset::initialize(const goto_functionst &goto_functions) { forall_goto_functions(it, goto_functions) initialize(it->second); } -/*******************************************************************\ - -Function: ai_baset::get_next - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - ai_baset::locationt ai_baset::get_next( working_sett &working_set) { @@ -351,18 +292,6 @@ ai_baset::locationt ai_baset::get_next( return l; } -/*******************************************************************\ - -Function: ai_baset::fixedpoint - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool ai_baset::fixedpoint( const goto_programt &goto_program, const goto_functionst &goto_functions, @@ -389,18 +318,6 @@ bool ai_baset::fixedpoint( return new_data; } -/*******************************************************************\ - -Function: ai_baset::visit - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool ai_baset::visit( locationt l, working_sett &working_set, @@ -459,18 +376,6 @@ bool ai_baset::visit( return new_data; } -/*******************************************************************\ - -Function: ai_baset::do_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool ai_baset::do_function_call( locationt l_call, locationt l_return, const goto_functionst &goto_functions, @@ -534,18 +439,6 @@ bool ai_baset::do_function_call( } } -/*******************************************************************\ - -Function: ai_baset::do_function_call_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool ai_baset::do_function_call_rec( locationt l_call, locationt l_return, const exprt &function, @@ -630,18 +523,6 @@ bool ai_baset::do_function_call_rec( return new_data; } -/*******************************************************************\ - -Function: ai_baset::sequential_fixedpoint - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ai_baset::sequential_fixedpoint( const goto_functionst &goto_functions, const namespacet &ns) @@ -653,18 +534,6 @@ void ai_baset::sequential_fixedpoint( fixedpoint(f_it->second.body, goto_functions, ns); } -/*******************************************************************\ - -Function: ai_baset::concurrent_fixedpoint - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ai_baset::concurrent_fixedpoint( const goto_functionst &goto_functions, const namespacet &ns) diff --git a/src/analyses/ai.h b/src/analyses/ai.h index 2894cde3b10..5e0d1db3b2e 100644 --- a/src/analyses/ai.h +++ b/src/analyses/ai.h @@ -6,15 +6,18 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Abstract Interpretation + #ifndef CPROVER_ANALYSES_AI_H #define CPROVER_ANALYSES_AI_H #include #include -#include #include #include +#include #include @@ -59,24 +62,11 @@ class ai_domain_baset virtual jsont output_json( const ai_baset &ai, - const namespacet &ns) const - { - std::ostringstream out; - output(out, ai, ns); - json_stringt json(out.str()); - return json; - } + const namespacet &ns) const; virtual xmlt output_xml( const ai_baset &ai, - const namespacet &ns) const - { - std::ostringstream out; - output(out, ai, ns); - xmlt xml("domain"); - xml.data=out.str(); - return xml; - } + const namespacet &ns) const; // no states virtual void make_bottom()=0; @@ -94,6 +84,23 @@ class ai_domain_baset // // This computes the join between "this" and "b". // Return true if "this" has changed. + + // This method allows an expression to be simplified / evaluated using the + // current state. It is used to evaluate assertions and in program + // simplification + + // return true if unchanged + virtual bool ai_simplify( + exprt &condition, + const namespacet &ns) const + { + return true; + } + + // Simplifies the expression but keeps it as an l-value + virtual bool ai_simplify_lhs( + exprt &condition, + const namespacet &ns) const; }; // don't use me -- I am just a base class @@ -273,7 +280,7 @@ class ai_baset std::pair(l->location_number, l)); } - // true = found s.th. new + // true = found something new bool fixedpoint( const goto_programt &goto_program, const goto_functionst &goto_functions, @@ -290,7 +297,7 @@ class ai_baset const goto_functionst &goto_functions, const namespacet &ns); - // true = found s.th. new + // true = found something new bool visit( locationt l, working_sett &working_set, diff --git a/src/analyses/call_graph.cpp b/src/analyses/call_graph.cpp index a4a1ff65ec1..26d144af4b4 100644 --- a/src/analyses/call_graph.cpp +++ b/src/analyses/call_graph.cpp @@ -6,41 +6,19 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Function Call Graphs + #include "call_graph.h" -#include -#include #include #include - - -/*******************************************************************\ - -Function: call_grapht::call_grapht - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include call_grapht::call_grapht() { } -/*******************************************************************\ - -Function: call_grapht::call_grapht - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - call_grapht::call_grapht(const goto_functionst &goto_functions) { forall_goto_functions(f_it, goto_functions) @@ -50,18 +28,6 @@ call_grapht::call_grapht(const goto_functionst &goto_functions) } } -/*******************************************************************\ - -Function: call_grapht::add - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void call_grapht::add( const irep_idt &function, const goto_programt &body) @@ -77,18 +43,6 @@ void call_grapht::add( } } -/*******************************************************************\ - -Function: call_grapht::swap - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void call_grapht::swap(call_grapht &other) { std::swap(graph, other.graph); @@ -96,19 +50,6 @@ void call_grapht::swap(call_grapht &other) other.map_from_edges_to_call_locations); } - -/*******************************************************************\ - -Function: call_grapht::add - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void call_grapht::add( const irep_idt &caller, const irep_idt &callee) @@ -116,18 +57,6 @@ void call_grapht::add( graph.insert(std::pair(caller, callee)); } -/*******************************************************************\ - -Function: call_grapht::add - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void call_grapht::add( const irep_idt &caller, const irep_idt &callee, @@ -150,19 +79,6 @@ void call_grapht::add( std::back_inserter(map_from_edges_to_call_locations[{caller, callee}])); } - -/*******************************************************************\ - -Function: call_grapht::output_dot - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void call_grapht::output_dot(std::ostream &out) const { out << "digraph call_graph {\n" @@ -186,19 +102,6 @@ void call_grapht::output_dot(std::ostream &out) const out << "}\n"; } - -/*******************************************************************\ - -Function: call_grapht::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void call_grapht::output(std::ostream &out) const { for(const auto &edge : graph) @@ -207,18 +110,6 @@ void call_grapht::output(std::ostream &out) const } } -/*******************************************************************\ - -Function: call_grapht::output_xml - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void call_grapht::output_xml(std::ostream &out) const { for(const auto &edge : graph) @@ -231,40 +122,21 @@ void call_grapht::output_xml(std::ostream &out) const } } -/*******************************************************************\ - -Function: call_grapht::out_edges - - Inputs: `caller`: node to search for - - Outputs: Returns list of edges whose first component is `caller`. - - Purpose: - -\*******************************************************************/ - +/// \par parameters: `caller`: node to search for +/// \return Returns list of edges whose first component is `caller`. call_grapht::call_edges_ranget call_grapht::out_edges(const irep_idt &caller) const { return graph.equal_range(caller); } -/*******************************************************************\ - -Function: inverted_partial_topological_order - - Inputs: `call_graph`: Call graph - `start_function`: start node, must occur in call graph - `processed_functions`: set of functions already seen - - Outputs: `output`: inverted topological sort of the graph reachable - from start node (i.e. leaves first, root last) - `processed_functions`: set of functions already seen - - Purpose: Get reverse-top-sorted subgraph - -\*******************************************************************/ - +/// Get reverse-top-sorted subgraph +/// \par parameters: `call_graph`: Call graph +/// `start_function`: start node, must occur in call graph +/// `processed_functions`: set of functions already seen +/// \return `output`: inverted topological sort of the graph reachable from +/// start node (i.e. leaves first, root last) `processed_functions`: set of +/// functions already seen void inverted_partial_topological_order( const call_grapht &call_graph, const irep_idt &start_function, @@ -285,22 +157,12 @@ void inverted_partial_topological_order( output.push_back(start_function); } -/*******************************************************************\ - -Function: get_inverted_topological_order - - Inputs: `call_graph`: Call graph - `functions`: map containing all functions of interest; - only function names are used to index into call graph; - function bodies are ignored. - - Outputs: `output`: inverted topological sort of the graph reachable - from start node (i.e. leaves first, root last) - - Purpose: Get reverse-top-sorted call graph - -\*******************************************************************/ - +/// Get reverse-top-sorted call graph +/// \par parameters: `call_graph`: Call graph +/// `functions`: map containing all functions of interest; only function names +/// are used to index into call graph; function bodies are ignored. +/// \return `output`: inverted topological sort of the graph reachable from +/// start node (i.e. leaves first, root last) void get_inverted_topological_order( const call_grapht& call_graph, const goto_functionst& functions, @@ -315,21 +177,11 @@ void get_inverted_topological_order( output); } -/*******************************************************************\ - -Function: exists_direct_call - - Inputs: `call_graph`: Call graph - `caller`: Caller - `callee`: Potential callee - - Outputs: Returns true if call graph says caller calls callee. - - Purpose: See output - -\*******************************************************************/ - - +/// See output +/// \par parameters: `call_graph`: Call graph +/// `caller`: Caller +/// `callee`: Potential callee +/// \return Returns true if call graph says caller calls callee. bool exists_direct_call( const call_grapht &call_graph, const irep_idt &caller, @@ -343,24 +195,14 @@ bool exists_direct_call( return false; } -/*******************************************************************\ - -Function: exists_direct_or_indirect_call - - Inputs: `call_graph`: Call graph - `caller`: Caller - `callee`: Potential callee - `ignored_functions`: Functions to exclude from call graph - for the purposes of finding a path - - Outputs: Returns true if call graph says caller can reach callee - via any intermediate sequence of callees not occurring - in ignored_functions - - Purpose: See output - -\*******************************************************************/ - +/// See output +/// \par parameters: `call_graph`: Call graph +/// `caller`: Caller +/// `callee`: Potential callee +/// `ignored_functions`: Functions to exclude from call graph for the purposes +/// of finding a path +/// \return Returns true if call graph says caller can reach callee via any +/// intermediate sequence of callees not occurring in ignored_functions bool exists_direct_or_indirect_call( const call_grapht &call_graph, const irep_idt &caller, @@ -384,21 +226,12 @@ bool exists_direct_or_indirect_call( return false; } -/*******************************************************************\ - -Function: exists_direct_or_indirect_call - - Inputs: `call_graph`: Call graph - `caller`: Caller - `callee`: Potential callee - - Outputs: Returns true if call graph says caller can reach callee - via any intermediate sequence of callees - - Purpose: See output - -\*******************************************************************/ - +/// See output +/// \par parameters: `call_graph`: Call graph +/// `caller`: Caller +/// `callee`: Potential callee +/// \return Returns true if call graph says caller can reach callee via any +/// intermediate sequence of callees bool exists_direct_or_indirect_call( const call_grapht &call_graph, const irep_idt &caller, @@ -408,19 +241,10 @@ bool exists_direct_or_indirect_call( return exists_direct_or_indirect_call(call_graph, caller, callee, ignored); } -/*******************************************************************\ - -Function: computed_inverted_call_graph - - Inputs: `original_call_graph`: call graph - - Outputs: `output_inverted_call_graph`: input call graph with caller-> - callee edges reversed. - - Purpose: See output - -\*******************************************************************/ - +/// See output +/// \par parameters: `original_call_graph`: call graph +/// \return `output_inverted_call_graph`: input call graph with caller-> callee +/// edges reversed. void compute_inverted_call_graph( const call_grapht &original_call_graph, call_grapht &output_inverted_call_graph) @@ -433,23 +257,12 @@ void compute_inverted_call_graph( {elem.first, elem.second})); } -/*******************************************************************\ - -Function: find_leaves_below_function - - Inputs: `call_graph`: call graph - `function`: start node - `to_avoid`: functions already visited - - Outputs: `output`: set of leaves reachable from 'function' - `to_avoid`: functions already visited (with 'function' - added) - - Purpose: See output - -\*******************************************************************/ - - +/// See output +/// \par parameters: `call_graph`: call graph +/// `function`: start node +/// `to_avoid`: functions already visited +/// \return `output`: set of leaves reachable from 'function' `to_avoid`: +/// functions already visited (with 'function' added) void find_leaves_below_function( const call_grapht &call_graph, const irep_idt &function, @@ -470,19 +283,10 @@ void find_leaves_below_function( } } -/*******************************************************************\ - -Function: find_leaves_below_function - - Inputs: `call_graph`: call graph - `function`: start node - - Outputs: `output`: set of leaves reachable from 'function' - - Purpose: See output - -\*******************************************************************/ - +/// See output +/// \par parameters: `call_graph`: call graph +/// `function`: start node +/// \return `output`: set of leaves reachable from 'function' void find_leaves_below_function( const call_grapht &call_graph, const irep_idt &function, @@ -492,18 +296,6 @@ void find_leaves_below_function( find_leaves_below_function(call_graph, function, to_avoid, output); } -/*******************************************************************\ - -Function: find_direct_or_indirect_callees_of_function - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void find_direct_or_indirect_callees_of_function( const call_grapht &call_graph, const irep_idt &function, @@ -514,18 +306,6 @@ void find_direct_or_indirect_callees_of_function( output.insert(leaves.cbegin(), leaves.cend()); } -/*******************************************************************\ - -Function: find_nearest_common_callees - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void find_nearest_common_callees( const call_grapht &call_graph, const std::set &functions, diff --git a/src/analyses/call_graph.h b/src/analyses/call_graph.h index 5f43aa680e0..d55a4f46812 100644 --- a/src/analyses/call_graph.h +++ b/src/analyses/call_graph.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Function Call Graphs + #ifndef CPROVER_ANALYSES_CALL_GRAPH_H #define CPROVER_ANALYSES_CALL_GRAPH_H @@ -87,48 +90,38 @@ class call_grapht map_from_edges_to_call_locationst map_from_edges_to_call_locations; }; -/*******************************************************************\ - -Function: inverted_partial_topological_order - - Inputs: See purpose - - Outputs: See purpose - - Purpose: - -For DAG call graphs it computes an inverted topological order of all -functions in the call graph. Otherwise, it computes only a partial -inverted topological order (all loops are broken at some (randomly) -chosen edge to get a DAG). The topolocical order is stored in the -'output' vector. - -Since the algorithm is implemented using DFS, those 'breaks' are -implemented naturally by a set of processed (vidited) functions. - -The function actually performs only one DFS from a passed 'start_function'. -So, to get whole inverted (partial) topological order of all functions in -the call graph, this function has to be called for all functions in the -program. - -NOTE: The order is 'inverted'. It means that - -Typical usage: - // Let's assume there is 'goto_modelt GM' and 'call_grapht CG' - std::vector result; // Here we will store the topological order. - { - std::unordered_set processed; - for (const auto &elem : GM.goto_functions.function_map) - partial_topological_order(CG, elem.first, processed, result); - // Now we reverse the result to get the classic (partial) - // topological order instead of the inverted one. - std::reverse(result.begin(), result.end()); - } - std::cout << "A (partial) topological order of my call graph is: "; - for (const irep_idt &fn_name : result) - std::cout << fn_name << ", "; - -\*******************************************************************/ +/// For DAG call graphs it computes an inverted topological order of all +/// functions in the call graph. Otherwise, it computes only a partial +/// inverted topological order (all loops are broken at some (randomly) +/// chosen edge to get a DAG). The topolocical order is stored in the +/// 'output' vector. +/// +/// Since the algorithm is implemented using DFS, those 'breaks' are +/// implemented naturally by a set of processed (vidited) functions. +/// +/// The function actually performs only one DFS from a passed 'start_function'. +/// So, to get whole inverted (partial) topological order of all functions in +/// the call graph, this function has to be called for all functions in the +/// program. +/// +/// NOTE: The order is 'inverted'. It means that +/// +/// Typical usage: +/// // Let's assume there is 'goto_modelt GM' and 'call_grapht CG' +/// std::vector result; // Here we will store the topological order. +/// { +/// std::unordered_set processed; +/// for (const auto &elem : GM.goto_functions.function_map) +/// partial_topological_order(CG, elem.first, processed, result); +/// // Now we reverse the result to get the classic (partial) +/// // topological order instead of the inverted one. +/// std::reverse(result.begin(), result.end()); +/// } +/// std::cout << "A (partial) topological order of my call graph is: "; +/// for (const irep_idt &fn_name : result) +/// std::cout << fn_name << ", "; +/// \par parameters: See purpose +/// \return See purpose void inverted_partial_topological_order( const call_grapht &call_graph, const irep_idt &start_function, diff --git a/src/analyses/cfg_dominators.h b/src/analyses/cfg_dominators.h index 930d0ae69b9..fa7d23ccf0a 100644 --- a/src/analyses/cfg_dominators.h +++ b/src/analyses/cfg_dominators.h @@ -6,6 +6,9 @@ Author: Georg Weissenbacher, georg@weissenbacher.name \*******************************************************************/ +/// \file +/// Compute dominators for CFG of goto_function + #ifndef CPROVER_ANALYSES_CFG_DOMINATORS_H #define CPROVER_ANALYSES_CFG_DOMINATORS_H @@ -44,18 +47,7 @@ class cfg_dominators_templatet void fixedpoint(P &program); }; -/*******************************************************************\ - -Function: operator << - - Inputs: - - Outputs: - - Purpose: Print the result of the dominator computation - -\*******************************************************************/ - +/// Print the result of the dominator computation template std::ostream &operator << ( std::ostream &out, @@ -65,18 +57,7 @@ std::ostream &operator << ( return out; } -/*******************************************************************\ - -Function: operator () - - Inputs: - - Outputs: - - Purpose: Compute dominators - -\*******************************************************************/ - +/// Compute dominators template void cfg_dominators_templatet::operator()(P &program) { @@ -84,36 +65,14 @@ void cfg_dominators_templatet::operator()(P &program) fixedpoint(program); } -/*******************************************************************\ - -Function: cfg_dominators_templatet::initialise - - Inputs: - - Outputs: - - Purpose: Initialises the elements of the fixed point analysis - -\*******************************************************************/ - +/// Initialises the elements of the fixed point analysis template void cfg_dominators_templatet::initialise(P &program) { cfg(program); } -/*******************************************************************\ - -Function: cfg_dominators_templatet::fixedpoint - - Inputs: - - Outputs: - - Purpose: Computes the MOP for the dominator analysis - -\*******************************************************************/ - +/// Computes the MOP for the dominator analysis template void cfg_dominators_templatet::fixedpoint(P &program) { @@ -205,19 +164,9 @@ void cfg_dominators_templatet::fixedpoint(P &program) } } -/*******************************************************************\ - -Function: dominators_pretty_print_node - - Inputs: `node` to print and stream `out` to pretty-print it to - - Outputs: - - Purpose: Pretty-print a single node in the dominator tree. - Supply a specialisation if operator<< is not sufficient. - -\*******************************************************************/ - +/// Pretty-print a single node in the dominator tree. Supply a specialisation if +/// operator<< is not sufficient. +/// \par parameters: `node` to print and stream `out` to pretty-print it to template void dominators_pretty_print_node(const T &node, std::ostream &out) { @@ -231,18 +180,7 @@ inline void dominators_pretty_print_node( out << target->code.pretty(); } -/*******************************************************************\ - -Function: cfg_dominators_templatet::output - - Inputs: - - Outputs: - - Purpose: Print the result of the dominator computation - -\*******************************************************************/ - +/// Print the result of the dominator computation template void cfg_dominators_templatet::output(std::ostream &out) const { diff --git a/src/analyses/constant_propagator.cpp b/src/analyses/constant_propagator.cpp index 6735d558cc3..02913f9360a 100644 --- a/src/analyses/constant_propagator.cpp +++ b/src/analyses/constant_propagator.cpp @@ -6,6 +6,11 @@ Author: Peter Schrammel \*******************************************************************/ +/// \file +/// Constant Propagation + +#include "constant_propagator.h" + #ifdef DEBUG #include #endif @@ -14,20 +19,6 @@ Author: Peter Schrammel #include #include -#include "constant_propagator.h" - -/*******************************************************************\ - -Function: concatenate_array_id - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt concatenate_array_id( const exprt &array, const exprt &index, const typet &type) @@ -47,18 +38,6 @@ exprt concatenate_array_id( return new_expr; } -/*******************************************************************\ - -Function: concatenate_array_id - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt concatenate_array_id( const exprt &array, const mp_integer &index, const typet &type) @@ -71,18 +50,6 @@ exprt concatenate_array_id( return new_expr; } -/*******************************************************************\ - -Function: constant_propagator_domaint::assign_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void constant_propagator_domaint::assign_rec( valuest &values, const exprt &lhs, const exprt &rhs, @@ -93,7 +60,7 @@ void constant_propagator_domaint::assign_rec( #ifdef DEBUG std::cout << "assign: " << from_expr(ns, "", lhs) - << " := " << from_type(ns, "", rhs_type) << std::endl; + << " := " << from_type(ns, "", rhs_type) << '\n'; #endif if(lhs.id()==ID_symbol && rhs.id()==ID_if) @@ -154,18 +121,6 @@ void constant_propagator_domaint::assign_rec( #endif } -/*******************************************************************\ - -Function: constant_propagator_domaint::transform - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void constant_propagator_domaint::transform( locationt from, locationt to, @@ -255,18 +210,7 @@ void constant_propagator_domaint::transform( } -/*******************************************************************\ - -Function: constant_propagator_domaint::two_way_propagate_rec - - Inputs: - - Outputs: - - Purpose: handles equalities and conjunctions containing equalities - -\*******************************************************************/ - +/// handles equalities and conjunctions containing equalities bool constant_propagator_domaint::two_way_propagate_rec( const exprt &expr, const namespacet &ns) @@ -308,18 +252,6 @@ bool constant_propagator_domaint::two_way_propagate_rec( return change; } -/*******************************************************************\ - -Function: constant_propagator_domaint::assign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void constant_propagator_domaint::assign( valuest &dest, const symbol_exprt &lhs, @@ -331,17 +263,19 @@ void constant_propagator_domaint::assign( dest.set_to(lhs, rhs); } -/*******************************************************************\ - -Function: constant_propagator_domaint::is_array_constant - - Inputs: - - Outputs: - - Purpose: +/// Simplify the condition given context-sensitive knowledge from the abstract +/// state. +/// \par parameters: The condition to simplify and its namespace. +/// \return The simplified condition. +bool constant_propagator_domaint::ai_simplify( + exprt &condition, + const namespacet &ns) const +{ + bool b=values.replace_const.replace(condition); + b&=simplify(condition, ns); -\*******************************************************************/ + return b; +} bool constant_propagator_domaint::valuest::is_array_constant(const exprt &expr) const { @@ -355,18 +289,6 @@ bool constant_propagator_domaint::valuest::is_array_constant(const exprt &expr) return true; } -/*******************************************************************\ - -Function: constant_propagator_domaint::valuest::is_constant - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool constant_propagator_domaint::valuest::is_constant(const exprt &expr) const { if(expr.id()==ID_side_effect && @@ -395,18 +317,6 @@ bool constant_propagator_domaint::valuest::is_constant(const exprt &expr) const return true; } -/*******************************************************************\ - -Function: constant_propagator_domaint::valuest::is_constant_address_of - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool constant_propagator_domaint::valuest::is_constant_address_of( const exprt &expr) const { @@ -426,18 +336,7 @@ bool constant_propagator_domaint::valuest::is_constant_address_of( return true; } -/*******************************************************************\ - -Function: constant_propagator_domaint::valuest::set_to_top - - Inputs: - - Outputs: - - Purpose: Do not call this when iterating over replace_const.expr_map! - -\*******************************************************************/ - +/// Do not call this when iterating over replace_const.expr_map! bool constant_propagator_domaint::valuest::set_to_top(const irep_idt &id) { bool result = false; @@ -455,18 +354,6 @@ bool constant_propagator_domaint::valuest::set_to_top(const irep_idt &id) return result; } -/*******************************************************************\ - -Function: constant_propagator_domaint::valuest::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void constant_propagator_domaint::valuest::output( std::ostream &out, const namespacet &ns) const @@ -481,18 +368,6 @@ void constant_propagator_domaint::valuest::output( << from_expr(ns, "", replace_pair.second) << '\n'; } -/*******************************************************************\ - -Function: constant_propagator_domaint::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void constant_propagator_domaint::output( std::ostream &out, const ai_baset &ai, @@ -501,18 +376,8 @@ void constant_propagator_domaint::output( values.output(out, ns); } -/*******************************************************************\ - -Function: constant_propagator_domaint::valuest::merge - - Inputs: - - Outputs: Return true if "this" has changed. - - Purpose: join - -\*******************************************************************/ - +/// join +/// \return Return true if "this" has changed. bool constant_propagator_domaint::valuest::merge(const valuest &src) { // nothing to do @@ -557,18 +422,8 @@ bool constant_propagator_domaint::valuest::merge(const valuest &src) return changed; } -/*******************************************************************\ - -Function: constant_propagator_domaint::valuest::meet - - Inputs: - - Outputs: Return true if "this" has changed. - - Purpose: meet - -\*******************************************************************/ - +/// meet +/// \return Return true if "this" has changed. bool constant_propagator_domaint::valuest::meet(const valuest &src) { if(src.is_bottom || is_bottom) @@ -600,18 +455,7 @@ bool constant_propagator_domaint::valuest::meet(const valuest &src) return changed; } -/*******************************************************************\ - -Function: constant_propagator_domaint::merge - - Inputs: - - Outputs: Return true if "this" has changed. - - Purpose: - -\*******************************************************************/ - +/// \return Return true if "this" has changed. bool constant_propagator_domaint::merge( const constant_propagator_domaint &other, locationt from, @@ -620,18 +464,6 @@ bool constant_propagator_domaint::merge( return values.merge(other.values); } -/*******************************************************************\ - -Function: constant_propagator_ait::replace - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void constant_propagator_ait::replace( goto_functionst &goto_functions, const namespacet &ns) @@ -640,18 +472,6 @@ void constant_propagator_ait::replace( replace(f_it->second, ns); } -/*******************************************************************\ - -Function: constant_propagator_ait::replace_array_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void constant_propagator_ait::replace_array_symbol(exprt &expr) { if (expr.id()==ID_index) @@ -668,18 +488,6 @@ void constant_propagator_ait::replace_array_symbol(exprt &expr) } -/*******************************************************************\ - -Function: constant_propagator_ait::replace - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void constant_propagator_ait::replace( goto_functionst::goto_functiont &goto_function, const namespacet &ns) @@ -732,18 +540,6 @@ void constant_propagator_ait::replace( } } -/*******************************************************************\ - -Function: constant_propagator_ait::replace_types_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void constant_propagator_ait::replace_types_rec( const replace_symbolt &replace_const, exprt &expr) diff --git a/src/analyses/constant_propagator.h b/src/analyses/constant_propagator.h index 0766b458f7d..0b54c79bdb8 100644 --- a/src/analyses/constant_propagator.h +++ b/src/analyses/constant_propagator.h @@ -6,6 +6,9 @@ Author: Peter Schrammel \*******************************************************************/ +/// \file +/// Constant propagation + #ifndef CPROVER_ANALYSES_CONSTANT_PROPAGATOR_H #define CPROVER_ANALYSES_CONSTANT_PROPAGATOR_H @@ -30,6 +33,10 @@ class constant_propagator_domaint:public ai_domain_baset void make_entry() final { values.set_to_top(); } bool merge(const constant_propagator_domaint &, locationt, locationt); + virtual bool ai_simplify( + exprt &condition, + const namespacet &ns) const override; + struct valuest { public: diff --git a/src/analyses/custom_bitvector_analysis.cpp b/src/analyses/custom_bitvector_analysis.cpp index 01947636402..da5bd52fb61 100644 --- a/src/analyses/custom_bitvector_analysis.cpp +++ b/src/analyses/custom_bitvector_analysis.cpp @@ -6,24 +6,15 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include -#include +/// \file +/// Field-insensitive, location-sensitive bitvector analysis #include "custom_bitvector_analysis.h" -#include - -/*******************************************************************\ - -Function: custom_bitvector_domaint::set_bit - - Inputs: - - Outputs: - - Purpose: +#include +#include -\*******************************************************************/ +#include void custom_bitvector_domaint::set_bit( const irep_idt &identifier, @@ -32,36 +23,24 @@ void custom_bitvector_domaint::set_bit( { switch(mode) { - case SET_MUST: + case modet::SET_MUST: set_bit(must_bits[identifier], bit_nr); break; - case CLEAR_MUST: + case modet::CLEAR_MUST: clear_bit(must_bits[identifier], bit_nr); break; - case SET_MAY: + case modet::SET_MAY: set_bit(may_bits[identifier], bit_nr); break; - case CLEAR_MAY: + case modet::CLEAR_MAY: clear_bit(may_bits[identifier], bit_nr); break; } } -/*******************************************************************\ - -Function: custom_bitvector_domaint::set_bit - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void custom_bitvector_domaint::set_bit( const exprt &lhs, unsigned bit_nr, @@ -72,18 +51,6 @@ void custom_bitvector_domaint::set_bit( set_bit(id, bit_nr, mode); } -/*******************************************************************\ - -Function: custom_bitvector_domaint::object2id - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - irep_idt custom_bitvector_domaint::object2id(const exprt &src) { if(src.id()==ID_symbol) @@ -117,18 +84,6 @@ irep_idt custom_bitvector_domaint::object2id(const exprt &src) return irep_idt(); } -/*******************************************************************\ - -Function: custom_bitvector_domaint::assign_lhs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void custom_bitvector_domaint::assign_lhs( const exprt &lhs, const vectorst &vectors) @@ -138,18 +93,6 @@ void custom_bitvector_domaint::assign_lhs( assign_lhs(id, vectors); } -/*******************************************************************\ - -Function: custom_bitvector_domaint::assign_lhs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void custom_bitvector_domaint::assign_lhs( const irep_idt &identifier, const vectorst &vectors) @@ -167,18 +110,6 @@ void custom_bitvector_domaint::assign_lhs( may_bits[identifier]=vectors.may_bits; } -/*******************************************************************\ - -Function: custom_bitvector_domaint::get_rhs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - custom_bitvector_domaint::vectorst custom_bitvector_domaint::get_rhs(const irep_idt &identifier) const { @@ -195,18 +126,6 @@ custom_bitvector_domaint::vectorst return vectors; } -/*******************************************************************\ - -Function: custom_bitvector_domaint::get_rhs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - custom_bitvector_domaint::vectorst custom_bitvector_domaint::get_rhs(const exprt &rhs) const { @@ -231,18 +150,6 @@ custom_bitvector_domaint::vectorst return vectorst(); } -/*******************************************************************\ - -Function: custom_bitvector_analysist::get_bit_nr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - unsigned custom_bitvector_analysist::get_bit_nr( const exprt &string_expr) { @@ -261,18 +168,6 @@ unsigned custom_bitvector_analysist::get_bit_nr( return bits("(unknown)"); } -/*******************************************************************\ - -Function: custom_bitvector_domaint::aliases - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::set custom_bitvector_analysist::aliases( const exprt &src, locationt loc) @@ -309,27 +204,12 @@ std::set custom_bitvector_analysist::aliases( return std::set(); } -/*******************************************************************\ - -Function: custom_bitvector_domaint::transform - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void custom_bitvector_domaint::transform( locationt from, locationt to, ai_baset &ai, const namespacet &ns) { - if(has_values.is_false()) - return; - // upcast of ai custom_bitvector_analysist &cba= static_cast(ai); @@ -408,13 +288,13 @@ void custom_bitvector_domaint::transform( modet mode; if(identifier=="__CPROVER_set_must") - mode=SET_MUST; + mode=modet::SET_MUST; else if(identifier=="__CPROVER_clear_must") - mode=CLEAR_MUST; + mode=modet::CLEAR_MUST; else if(identifier=="__CPROVER_set_may") - mode=SET_MAY; + mode=modet::SET_MAY; else if(identifier=="__CPROVER_clear_may") - mode=CLEAR_MAY; + mode=modet::CLEAR_MAY; else assert(false); @@ -423,7 +303,7 @@ void custom_bitvector_domaint::transform( if(lhs.is_constant() && to_constant_expr(lhs).get_value()==ID_NULL) // NULL means all { - if(mode==CLEAR_MAY) + if(mode==modet::CLEAR_MAY) { for(auto &bit : may_bits) clear_bit(bit.second, bit_nr); @@ -431,7 +311,7 @@ void custom_bitvector_domaint::transform( // erase blank ones erase_blank_vectors(may_bits); } - else if(mode==CLEAR_MUST) + else if(mode==modet::CLEAR_MUST) { for(auto &bit : must_bits) clear_bit(bit.second, bit_nr); @@ -454,6 +334,54 @@ void custom_bitvector_domaint::transform( } } } + else + { + goto_programt::const_targett next=from; + ++next; + + // only if there is an actual call, i.e., we have a body + if(next!=to) + { + const code_typet &code_type= + to_code_type(ns.lookup(identifier).type); + + code_function_callt::argumentst::const_iterator arg_it= + code_function_call.arguments().begin(); + for(const auto ¶m : code_type.parameters()) + { + const irep_idt &p_identifier=param.get_identifier(); + if(p_identifier.empty()) + continue; + + // there may be a mismatch in the number of arguments + if(arg_it==code_function_call.arguments().end()) + break; + + // assignments arguments -> parameters + symbol_exprt p=ns.lookup(p_identifier).symbol_expr(); + // may alias other stuff + std::set lhs_set=cba.aliases(p, from); + + vectorst rhs_vectors=get_rhs(*arg_it); + + for(const auto &lhs : lhs_set) + { + assign_lhs(lhs, rhs_vectors); + } + + // is it a pointer? + if(p.type().id()==ID_pointer) + { + dereference_exprt lhs_deref(p); + dereference_exprt rhs_deref(*arg_it); + vectorst rhs_vectors=get_rhs(rhs_deref); + assign_lhs(lhs_deref, rhs_vectors); + } + + ++arg_it; + } + } + } } } break; @@ -475,13 +403,13 @@ void custom_bitvector_domaint::transform( modet mode; if(statement=="set_must") - mode=SET_MUST; + mode=modet::SET_MUST; else if(statement=="clear_must") - mode=CLEAR_MUST; + mode=modet::CLEAR_MUST; else if(statement=="set_may") - mode=SET_MAY; + mode=modet::SET_MAY; else if(statement=="clear_may") - mode=CLEAR_MAY; + mode=modet::CLEAR_MAY; else assert(false); @@ -490,7 +418,7 @@ void custom_bitvector_domaint::transform( if(lhs.is_constant() && to_constant_expr(lhs).get_value()==ID_NULL) // NULL means all { - if(mode==CLEAR_MAY) + if(mode==modet::CLEAR_MAY) { for(bitst::iterator b_it=may_bits.begin(); b_it!=may_bits.end(); @@ -500,7 +428,7 @@ void custom_bitvector_domaint::transform( // erase blank ones erase_blank_vectors(may_bits); } - else if(mode==CLEAR_MUST) + else if(mode==modet::CLEAR_MUST) { for(bitst::iterator b_it=must_bits.begin(); b_it!=must_bits.end(); @@ -549,18 +477,6 @@ void custom_bitvector_domaint::transform( } } -/*******************************************************************\ - -Function: custom_bitvector_domaint::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void custom_bitvector_domaint::output( std::ostream &out, const ai_baset &ai, @@ -608,61 +524,60 @@ void custom_bitvector_domaint::output( } } -/*******************************************************************\ - -Function: custom_bitvector_domaint::merge - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool custom_bitvector_domaint::merge( const custom_bitvector_domaint &b, locationt from, locationt to) { - if(b.has_values.is_false()) - return false; // no change - - if(has_values.is_false()) - { - *this=b; - return true; // change - } - - bool changed=false; + bool changed=has_values.is_false(); + has_values=tvt::unknown(); // first do MAY - for(const auto &bit : may_bits) + bitst::iterator it=may_bits.begin(); + for(const auto &bit : b.may_bits) { - bit_vectort &a_bits=may_bits[bit.first]; - bit_vectort old=a_bits; - a_bits|=bit.second; - if(old!=a_bits) + while(it!=may_bits.end() && it->firstfirst) + { + may_bits.insert(it, bit); changed=true; + } + else if(it!=may_bits.end()) + { + bit_vectort &a_bits=it->second; + bit_vectort old=a_bits; + a_bits|=bit.second; + if(old!=a_bits) + changed=true; + + ++it; + } } // now do MUST - for(auto &bit : must_bits) + it=must_bits.begin(); + for(auto &bit : b.must_bits) { - bitst::const_iterator b_it= - b.must_bits.find(bit.first); - - if(b_it==b.must_bits.end()) + while(it!=must_bits.end() && it->firstfirst) + { + must_bits.insert(it, bit); + changed=true; + } + else if(it!=must_bits.end()) { - bit_vectort old=bit.second; - bit.second&=bit.second; - if(old!=bit.second) + bit_vectort &a_bits=it->second; + bit_vectort old=a_bits; + a_bits&=bit.second; + if(old!=a_bits) changed=true; + + ++it; } } @@ -673,18 +588,7 @@ bool custom_bitvector_domaint::merge( return changed; } -/*******************************************************************\ - -Function: custom_bitvector_domaint::erase_blank_vectors - - Inputs: - - Outputs: - - Purpose: erase blank bitvectors - -\*******************************************************************/ - +/// erase blank bitvectors void custom_bitvector_domaint::erase_blank_vectors(bitst &bits) { for(bitst::iterator a_it=bits.begin(); @@ -698,18 +602,6 @@ void custom_bitvector_domaint::erase_blank_vectors(bitst &bits) } } -/*******************************************************************\ - -Function: custom_bitvector_domaint::has_get_must_or_may - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool custom_bitvector_domaint::has_get_must_or_may(const exprt &src) { if(src.id()=="get_must" || @@ -723,18 +615,6 @@ bool custom_bitvector_domaint::has_get_must_or_may(const exprt &src) return false; } -/*******************************************************************\ - -Function: custom_bitvector_domaint::eval - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt custom_bitvector_domaint::eval( const exprt &src, custom_bitvector_analysist &custom_bitvector_analysis) const @@ -797,34 +677,10 @@ exprt custom_bitvector_domaint::eval( } } -/*******************************************************************\ - -Function: custom_bitvector_analysist::instrument - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void custom_bitvector_analysist::instrument(goto_functionst &) { } -/*******************************************************************\ - -Function: custom_bitvector_analysist::check - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void custom_bitvector_analysist::check( const namespacet &ns, const goto_functionst &goto_functions, diff --git a/src/analyses/custom_bitvector_analysis.h b/src/analyses/custom_bitvector_analysis.h index ceb2ba691be..5ef03adbaf2 100644 --- a/src/analyses/custom_bitvector_analysis.h +++ b/src/analyses/custom_bitvector_analysis.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Field-insensitive, location-sensitive bitvector analysis + #ifndef CPROVER_ANALYSES_CUSTOM_BITVECTOR_ANALYSIS_H #define CPROVER_ANALYSES_CUSTOM_BITVECTOR_ANALYSIS_H @@ -15,14 +18,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "ai.h" #include "local_may_alias.h" -/*******************************************************************\ - - Class: custom_bitvector_domaint - - Purpose: - -\*******************************************************************/ - class custom_bitvector_analysist; class custom_bitvector_domaint:public ai_domain_baset @@ -92,7 +87,7 @@ class custom_bitvector_domaint:public ai_domain_baset tvt has_values; - custom_bitvector_domaint():has_values(true) + custom_bitvector_domaint():has_values(false) { } @@ -102,7 +97,7 @@ class custom_bitvector_domaint:public ai_domain_baset custom_bitvector_analysist &) const; private: - typedef enum { SET_MUST, CLEAR_MUST, SET_MAY, CLEAR_MAY } modet; + enum class modet { SET_MUST, CLEAR_MUST, SET_MAY, CLEAR_MAY }; void set_bit(const exprt &, unsigned bit_nr, modet); void set_bit(const irep_idt &, unsigned bit_nr, modet); @@ -150,6 +145,7 @@ class custom_bitvector_analysist:public ait protected: virtual void initialize(const goto_functionst &_goto_functions) { + ait::initialize(_goto_functions); local_may_alias_factory(_goto_functions); } diff --git a/src/analyses/dependence_graph.cpp b/src/analyses/dependence_graph.cpp index 93588e209a7..9707f9a3eb9 100644 --- a/src/analyses/dependence_graph.cpp +++ b/src/analyses/dependence_graph.cpp @@ -9,23 +9,17 @@ Date: August 2013 \*******************************************************************/ -#include - -#include "goto_rw.h" +/// \file +/// Field-Sensitive Program Dependence Analysis, Litvak et al., FSE 2010 #include "dependence_graph.h" -/*******************************************************************\ - -Function: dep_graph_domaint::merge - - Inputs: - - Outputs: +#include - Purpose: +#include +#include -\*******************************************************************/ +#include "goto_rw.h" bool dep_graph_domaint::merge( const dep_graph_domaint &src, @@ -66,18 +60,6 @@ bool dep_graph_domaint::merge( return changed; } -/*******************************************************************\ - -Function: dep_graph_domaint::control_dependencies - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dep_graph_domaint::control_dependencies( goto_programt::const_targett from, goto_programt::const_targett to, @@ -141,21 +123,9 @@ void dep_graph_domaint::control_dependencies( // add edges to the graph for(const auto &c_dep : control_deps) - dep_graph.add_dep(dep_edget::CTRL, c_dep, to); + dep_graph.add_dep(dep_edget::kindt::CTRL, c_dep, to); } -/*******************************************************************\ - -Function: may_be_def_use_pair - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static bool may_be_def_use_pair( const mp_integer &w_start, const mp_integer &w_end, @@ -177,18 +147,6 @@ static bool may_be_def_use_pair( return false; } -/*******************************************************************\ - -Function: dep_graph_domaint::data_depdendencies - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dep_graph_domaint::data_dependencies( goto_programt::const_targett from, goto_programt::const_targett to, @@ -234,22 +192,10 @@ void dep_graph_domaint::data_dependencies( // *it might be handled in a future call call to visit only, // depending on the sequence of successors; make sure it exists dep_graph.get_state(d_dep); - dep_graph.add_dep(dep_edget::DATA, d_dep, to); + dep_graph.add_dep(dep_edget::kindt::DATA, d_dep, to); } } -/*******************************************************************\ - -Function: dep_graph_domaint::transform - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dep_graph_domaint::transform( goto_programt::const_targett from, goto_programt::const_targett to, @@ -297,18 +243,6 @@ void dep_graph_domaint::transform( data_dependencies(from, to, *dep_graph, ns); } -/*******************************************************************\ - -Function: dep_graph_domaint::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dep_graph_domaint::output( std::ostream &out, const ai_baset &ai, @@ -326,7 +260,7 @@ void dep_graph_domaint::output( out << ","; out << (*it)->location_number; } - out << std::endl; + out << '\n'; } if(!data_deps.empty()) @@ -341,21 +275,40 @@ void dep_graph_domaint::output( out << ","; out << (*it)->location_number; } - out << std::endl; + out << '\n'; } } -/*******************************************************************\ - -Function: dependence_grapht::add_dep - - Inputs: +/// Outputs the current value of the domain. +/// \par parameters: The abstract interpreter and the namespace. +/// \return The domain, formatted as a JSON object. +jsont dep_graph_domaint::output_json( + const ai_baset &ai, + const namespacet &ns) const +{ + json_arrayt graph; - Outputs: + for(const auto &cd : control_deps) + { + json_objectt &link=graph.push_back().make_object(); + link["locationNumber"]= + json_numbert(std::to_string(cd->location_number)); + link["sourceLocation"]=json(cd->source_location); + link["type"]=json_stringt("control"); + } - Purpose: + for(const auto &dd : data_deps) + { + json_objectt &link=graph.push_back().make_object(); + link["locationNumber"]= + json_numbert(std::to_string(dd->location_number)); + link["sourceLocation"]=json(dd->source_location); + json_stringt(dd->source_location.as_string()); + link["type"]=json_stringt("data"); + } -\*******************************************************************/ + return graph; +} void dependence_grapht::add_dep( dep_edget::kindt kind, diff --git a/src/analyses/dependence_graph.h b/src/analyses/dependence_graph.h index 8b627dd36b0..4cd7be4c589 100644 --- a/src/analyses/dependence_graph.h +++ b/src/analyses/dependence_graph.h @@ -9,6 +9,9 @@ Date: August 2013 \*******************************************************************/ +/// \file +/// Field-Sensitive Program Dependence Analysis, Litvak et al., FSE 2010 + #ifndef CPROVER_ANALYSES_DEPENDENCE_GRAPH_H #define CPROVER_ANALYSES_DEPENDENCE_GRAPH_H @@ -24,27 +27,21 @@ class dependence_grapht; class dep_edget { public: - typedef enum - { - NONE, - CTRL, - DATA, - BOTH - } kindt; + enum class kindt { NONE, CTRL, DATA, BOTH }; void add(kindt _kind) { switch(kind) { - case NONE: + case kindt::NONE: kind=_kind; break; - case DATA: - case CTRL: + case kindt::DATA: + case kindt::CTRL: if(kind!=_kind) - kind=BOTH; + kind=kindt::BOTH; break; - case BOTH: + case kindt::BOTH: break; } } @@ -93,7 +90,11 @@ class dep_graph_domaint:public ai_domain_baset const ai_baset &ai, const namespacet &ns) const final; - void make_top() final + jsont output_json( + const ai_baset &ai, + const namespacet &ns) const override; + + void make_top() final override { assert(node_id!=std::numeric_limits::max()); diff --git a/src/analyses/dirty.cpp b/src/analyses/dirty.cpp index a159f6ddef2..0231b50c77c 100644 --- a/src/analyses/dirty.cpp +++ b/src/analyses/dirty.cpp @@ -8,21 +8,12 @@ Date: March 2013 \*******************************************************************/ -#include +/// \file +/// Local variables whose address is taken #include "dirty.h" -/*******************************************************************\ - -Function: dirtyt::build - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void dirtyt::build(const goto_functiont &goto_function) { @@ -33,18 +24,6 @@ void dirtyt::build(const goto_functiont &goto_function) } } -/*******************************************************************\ - -Function: dirtyt::find_dirty - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dirtyt::find_dirty(const exprt &expr) { if(expr.id()==ID_address_of) @@ -58,18 +37,6 @@ void dirtyt::find_dirty(const exprt &expr) find_dirty(*it); } -/*******************************************************************\ - -Function: dirtyt::find_dirty_address_of - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dirtyt::find_dirty_address_of(const exprt &expr) { if(expr.id()==ID_symbol) @@ -100,20 +67,8 @@ void dirtyt::find_dirty_address_of(const exprt &expr) } } -/*******************************************************************\ - -Function: dirtyt::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dirtyt::output(std::ostream &out) const { for(const auto &d : dirty) - out << d << std::endl; + out << d << '\n'; } diff --git a/src/analyses/dirty.h b/src/analyses/dirty.h index f60b86703c4..52801d05281 100644 --- a/src/analyses/dirty.h +++ b/src/analyses/dirty.h @@ -8,6 +8,9 @@ Date: March 2013 \*******************************************************************/ +/// \file +/// Variables whose address is taken + #ifndef CPROVER_ANALYSES_DIRTY_H #define CPROVER_ANALYSES_DIRTY_H diff --git a/src/analyses/does_remove_const.cpp b/src/analyses/does_remove_const.cpp index fcccd8219c9..98ebd1315a5 100644 --- a/src/analyses/does_remove_const.cpp +++ b/src/analyses/does_remove_const.cpp @@ -6,6 +6,11 @@ \*******************************************************************/ +/// \file +/// Analyses + +#include "does_remove_const.h" + #include #include #include @@ -13,23 +18,10 @@ #include #include -#include "does_remove_const.h" - -/*******************************************************************\ - -Function: does_remove_constt::does_remove_constt - - Inputs: - goto_program - the goto program to check - ns - the namespace of the goto program (used for checking type equality) - - Outputs: - - Purpose: A naive analysis to look for casts that remove const-ness from - pointers. - -\*******************************************************************/ - +/// A naive analysis to look for casts that remove const-ness from pointers. +/// \param goto_program: the goto program to check +/// \param ns: the namespace of the goto program (used for checking type +/// equality) does_remove_constt::does_remove_constt( const goto_programt &goto_program, const namespacet &ns): @@ -37,19 +29,8 @@ does_remove_constt::does_remove_constt( ns(ns) {} -/*******************************************************************\ - -Function: does_remove_constt::operator() - - Inputs: - - Outputs: Returns true if the program contains a const-removing cast - - Purpose: A naive analysis to look for casts that remove const-ness from - pointers. - -\*******************************************************************/ - +/// A naive analysis to look for casts that remove const-ness from pointers. +/// \return Returns true if the program contains a const-removing cast bool does_remove_constt::operator()() const { for(const goto_programt::instructiont &instruction : @@ -66,7 +47,7 @@ bool does_remove_constt::operator()() const // Compare the types recursively for a point where the rhs is more // const that the lhs - if(!is_type_at_least_as_const_as(&lhs_type, &rhs_type)) + if(!does_type_preserve_const_correctness(&lhs_type, &rhs_type)) { return true; } @@ -80,22 +61,12 @@ bool does_remove_constt::operator()() const return false; } -/*******************************************************************\ - -Function: does_remove_constt::does_expr_lose_const() - - Inputs: - expr - The expression to check - - Outputs: Returns true if somewhere in the passed expression tree the const-ness - is lost. - - Purpose: Search the expression tree to look for any children that have the - same base type, but a less strict const qualification. - If one is found, we return true. - -\*******************************************************************/ - +/// Search the expression tree to look for any children that have the same base +/// type, but a less strict const qualification. If one is found, we return +/// true. +/// \param expr: The expression to check +/// \return Returns true if somewhere in the passed expression tree the const- +/// ness is lost. bool does_remove_constt::does_expr_lose_const(const exprt &expr) const { const typet &root_type=expr.type(); @@ -107,7 +78,7 @@ bool does_remove_constt::does_expr_lose_const(const exprt &expr) const if(base_type_eq(op_type, root_type, ns)) { // Is this child more const-qualified than the root - if(!is_type_at_least_as_const_as(&root_type, &op_type)) + if(!does_type_preserve_const_correctness(&root_type, &op_type)) { return true; } @@ -122,46 +93,78 @@ bool does_remove_constt::does_expr_lose_const(const exprt &expr) const return false; } -/*******************************************************************\ - -Function: does_remove_constt::is_type_at_least_as_const_as - - Inputs: - type_more_const - the type we are expecting to be at least as const qualified - type_compare - the type we are comparing against which may be less const - qualified - - Outputs: Returns true if type_more_const is at least as const as type_compare - - Purpose: A recursive check to check the type_more_const is at least as const - as type compare. - - type_more_const | type_compare || result - ---------------------------------------- - const int * | const int * -> true - int * | const int * -> false - const int * | int * -> true - int * | int * const -> false - -\*******************************************************************/ - -bool does_remove_constt::is_type_at_least_as_const_as( - const typet *type_more_const, const typet *type_compare) const +/// A recursive check that handles when assigning a source value to a target, is +/// the assignment a loss of const-correctness. +/// +/// For primitive types, it always returns true since these are copied +/// +/// For pointers we requires that if in the source it's value couldn't +/// be modified, then it still can't be modified in the target +/// +/// target_type | source_type || result +/// ---------------------------------------- +/// const int | int -> true +/// int | const int -> true +/// const int | const int -> true +/// int | int -> true +/// +/// int * | int * const -> true +/// int * | const int * -> false +/// const int * | int * -> true +/// const int * | const int * -> true +/// int * const | int * -> true +/// +/// See unit/analyses/does_type_preserve_const_correcness for +/// comprehensive list +/// \param target_type: the resulting type +/// \param source_type: the starting type +/// \return Returns true if a value of type source_type could be assigned into a +/// a value of target_type without losing const-correctness +bool does_remove_constt::does_type_preserve_const_correctness( + const typet *target_type, const typet *source_type) const { - while(type_compare->id()!=ID_nil && type_more_const->id()!=ID_nil) + while(target_type->id()==ID_pointer) { - const c_qualifierst rhs_qualifiers(*type_compare); - const c_qualifierst lhs_qualifiers(*type_more_const); - if(rhs_qualifiers.is_constant && !lhs_qualifiers.is_constant) - { + bool direct_subtypes_at_least_as_const= + is_type_at_least_as_const_as( + target_type->subtype(), source_type->subtype()); + // We have a pointer to something, but the thing it is pointing to can't be + // modified normally, but can through this pointer + if(!direct_subtypes_at_least_as_const) return false; - } - - type_compare=&type_compare->subtype(); - type_more_const=&type_more_const->subtype(); + // Check the subtypes if they are pointers + target_type=&target_type->subtype(); + source_type=&source_type->subtype(); } - - // Both the types should have the same number of subtypes - assert(type_compare->id()==ID_nil && type_more_const->id()==ID_nil); return true; } + +/// A simple check to check the type_more_const is at least as const as type +/// compare. This only checks the exact type, use +/// `is_pointer_at_least_as_constant_as` for dealing with nested types +/// +/// type_more_const | type_compare || result +/// ---------------------------------------- +/// const int | int -> true +/// int | const int -> false +/// const int | const int -> true +/// int | int -> true +/// int * | int * const -> false +/// int * | const int * -> true +/// const int * | int * -> true +/// int * const | int * -> true +/// +/// See unit/analyses/is_type_as_least_as_const_as for comprehensive list +/// \param type_more_const: the type we are expecting to be at least as const +/// qualified +/// \param type_compare: the type we are comparing against which may be less +/// const qualified +/// \return Returns true if type_more_const is at least as const as type_compare +bool does_remove_constt::is_type_at_least_as_const_as( + const typet &type_more_const, const typet &type_compare) const +{ + const c_qualifierst type_compare_qualifiers(type_compare); + const c_qualifierst more_constant_qualifiers(type_more_const); + return !type_compare_qualifiers.is_constant || + more_constant_qualifiers.is_constant; +} diff --git a/src/analyses/does_remove_const.h b/src/analyses/does_remove_const.h index 594682c7d50..ca602eb4a39 100644 --- a/src/analyses/does_remove_const.h +++ b/src/analyses/does_remove_const.h @@ -5,12 +5,18 @@ Author: DiffBlue Limited. All rights reserved. \*******************************************************************/ +/// \file +/// Analyses + #ifndef CPROVER_ANALYSES_DOES_REMOVE_CONST_H #define CPROVER_ANALYSES_DOES_REMOVE_CONST_H #include +#include class goto_programt; +class namespacet; +class exprt; class does_remove_constt { @@ -22,10 +28,15 @@ class does_remove_constt bool does_expr_lose_const(const exprt &expr) const; bool is_type_at_least_as_const_as( - const typet *type_more_const, const typet *type_compare) const; + const typet &type_more_const, const typet &type_compare) const; + + bool does_type_preserve_const_correctness( + const typet *target_type, const typet *source_type) const; const goto_programt &goto_program; const namespacet &ns; + + friend class does_remove_const_testt; }; #endif // CPROVER_ANALYSES_DOES_REMOVE_CONST_H diff --git a/src/analyses/escape_analysis.cpp b/src/analyses/escape_analysis.cpp index 1382e9d1689..a9b7c71db08 100644 --- a/src/analyses/escape_analysis.cpp +++ b/src/analyses/escape_analysis.cpp @@ -6,21 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Field-insensitive, location-sensitive escape analysis #include "escape_analysis.h" -/*******************************************************************\ - -Function: escape_domaint::is_tracked - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include bool escape_domaint::is_tracked(const symbol_exprt &symbol) { @@ -34,18 +25,6 @@ bool escape_domaint::is_tracked(const symbol_exprt &symbol) return true; } -/*******************************************************************\ - -Function: escape_domaint::get_function - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - irep_idt escape_domaint::get_function(const exprt &lhs) { if(lhs.id()==ID_address_of) @@ -61,18 +40,6 @@ irep_idt escape_domaint::get_function(const exprt &lhs) return irep_idt(); } -/*******************************************************************\ - -Function: escape_domaint::assign_lhs_cleanup - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void escape_domaint::assign_lhs_cleanup( const exprt &lhs, const std::set &cleanup_functions) @@ -92,18 +59,6 @@ void escape_domaint::assign_lhs_cleanup( } } -/*******************************************************************\ - -Function: escape_domaint::assign_lhs_aliases - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void escape_domaint::assign_lhs_aliases( const exprt &lhs, const std::set &alias_set) @@ -125,18 +80,6 @@ void escape_domaint::assign_lhs_aliases( } } -/*******************************************************************\ - -Function: escape_domaint::get_rhs_cleanup - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void escape_domaint::get_rhs_cleanup( const exprt &rhs, std::set &cleanup_functions) @@ -167,18 +110,6 @@ void escape_domaint::get_rhs_cleanup( } } -/*******************************************************************\ - -Function: escape_domaint::get_rhs_aliases - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void escape_domaint::get_rhs_aliases( const exprt &rhs, std::set &alias_set) @@ -211,18 +142,6 @@ void escape_domaint::get_rhs_aliases( } } -/*******************************************************************\ - -Function: escape_domaint::get_rhs_aliases_address_of - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void escape_domaint::get_rhs_aliases_address_of( const exprt &rhs, std::set &alias_set) @@ -242,18 +161,6 @@ void escape_domaint::get_rhs_aliases_address_of( } } -/*******************************************************************\ - -Function: escape_domaint::transform - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void escape_domaint::transform( locationt from, locationt to, @@ -346,18 +253,6 @@ void escape_domaint::transform( } } -/*******************************************************************\ - -Function: escape_domaint::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void escape_domaint::output( std::ostream &out, const ai_baset &ai, @@ -404,18 +299,6 @@ void escape_domaint::output( } } -/*******************************************************************\ - -Function: escape_domaint::merge - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool escape_domaint::merge( const escape_domaint &b, locationt from, @@ -480,18 +363,6 @@ bool escape_domaint::merge( return changed; } -/*******************************************************************\ - -Function: escape_domaint::check_lhs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void escape_domaint::check_lhs( const exprt &lhs, std::set &cleanup_functions) @@ -500,7 +371,7 @@ void escape_domaint::check_lhs( { const irep_idt &identifier=to_symbol_expr(lhs).get_identifier(); - // pointer with aleanup function? + // pointer with cleanup function? const escape_domaint::cleanup_mapt::const_iterator m_it= cleanup_map.find(identifier); @@ -527,18 +398,6 @@ void escape_domaint::check_lhs( } } -/*******************************************************************\ - -Function: escape_analysist::insert_cleanup - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void escape_analysist::insert_cleanup( goto_functionst::goto_functiont &goto_function, goto_programt::targett location, @@ -576,18 +435,6 @@ void escape_analysist::insert_cleanup( } } -/*******************************************************************\ - -Function: escape_analysist::instrument - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void escape_analysist::instrument( goto_functionst &goto_functions, const namespacet &ns) diff --git a/src/analyses/escape_analysis.h b/src/analyses/escape_analysis.h index 948bed3fea8..00f865b45e4 100644 --- a/src/analyses/escape_analysis.h +++ b/src/analyses/escape_analysis.h @@ -7,6 +7,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Field-insensitive, location-sensitive, over-approximative escape analysis + #ifndef CPROVER_ANALYSES_ESCAPE_ANALYSIS_H #define CPROVER_ANALYSES_ESCAPE_ANALYSIS_H @@ -16,14 +19,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "ai.h" -/*******************************************************************\ - - Class: escape_domaint - - Purpose: - -\*******************************************************************/ - class escape_analysist; class escape_domaint:public ai_domain_baset diff --git a/src/analyses/flow_insensitive_analysis.cpp b/src/analyses/flow_insensitive_analysis.cpp index bc4dd11e889..b8ad09a4b5b 100644 --- a/src/analyses/flow_insensitive_analysis.cpp +++ b/src/analyses/flow_insensitive_analysis.cpp @@ -7,24 +7,15 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - -#include -#include +/// \file +/// Flow Insensitive Static Analysis #include "flow_insensitive_analysis.h" -/*******************************************************************\ - -Function: flow_insensitive_abstract_domain_baset::get_guard - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include +#include exprt flow_insensitive_abstract_domain_baset::get_guard( locationt from, @@ -46,18 +37,6 @@ exprt flow_insensitive_abstract_domain_baset::get_guard( return from->guard; } -/*******************************************************************\ - -Function: flow_insensitive_abstract_domain_baset::get_return_lhs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt flow_insensitive_abstract_domain_baset::get_return_lhs(locationt to) const { // get predecessor of "to" @@ -76,18 +55,6 @@ exprt flow_insensitive_abstract_domain_baset::get_return_lhs(locationt to) const return code.lhs(); } -/*******************************************************************\ - -Function: flow_insensitive_analysis_baset::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void flow_insensitive_analysis_baset::operator()( const goto_functionst &goto_functions) { @@ -95,18 +62,6 @@ void flow_insensitive_analysis_baset::operator()( fixedpoint(goto_functions); } -/*******************************************************************\ - -Function: flow_insensitive_analysis_baset::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void flow_insensitive_analysis_baset::operator()( const goto_programt &goto_program) { @@ -115,45 +70,18 @@ void flow_insensitive_analysis_baset::operator()( fixedpoint(goto_program, goto_functions); } -/*******************************************************************\ - -Function: flow_insensitive_analysis_baset::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void flow_insensitive_analysis_baset::output( const goto_functionst &goto_functions, std::ostream &out) { forall_goto_functions(f_it, goto_functions) { - out << "////" << std::endl; - out << "//// Function: " << f_it->first << std::endl; - out << "////" << std::endl; - out << std::endl; + out << "////\n" << "//// Function: " << f_it->first << "\n////\n\n"; output(f_it->second.body, f_it->first, out); } } -/*******************************************************************\ - -Function: flow_insensitive_analysis_baset::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void flow_insensitive_analysis_baset::output( const goto_programt &goto_program, const irep_idt &identifier, @@ -162,18 +90,6 @@ void flow_insensitive_analysis_baset::output( get_state().output(ns, out); } -/*******************************************************************\ - -Function: flow_insensitive_analysis_baset::get_next - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - flow_insensitive_analysis_baset::locationt flow_insensitive_analysis_baset::get_next( working_sett &working_set) @@ -191,18 +107,6 @@ flow_insensitive_analysis_baset::get_next( return l; } -/*******************************************************************\ - -Function: flow_insensitive_analysis_baset::fixedpoint - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool flow_insensitive_analysis_baset::fixedpoint( const goto_programt &goto_program, const goto_functionst &goto_functions) @@ -231,18 +135,6 @@ bool flow_insensitive_analysis_baset::fixedpoint( return new_data; } -/*******************************************************************\ - -Function: flow_insensitive_analysis_baset::visit - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool flow_insensitive_analysis_baset::visit( locationt l, working_sett &working_set, @@ -253,7 +145,7 @@ bool flow_insensitive_analysis_baset::visit( #if 0 std::cout << "Visiting: " << l->function << " " << - l->location_number << std::endl; + l->location_number << '\n'; #endif seen_locations.insert(l); @@ -294,14 +186,14 @@ bool flow_insensitive_analysis_baset::visit( } // if (id2string(l->function).find("debug")!=std::string::npos) -// std::cout << l->function << std::endl; //=="messages::debug") +// std::cout << l->function << '\n'; //=="messages::debug") // { // static unsigned state_cntr=0; // std::string s("pastate"); s += std::to_string(state_cntr); // std::ofstream f(s.c_str()); // goto_program.output_instruction(ns, "", f, l); -// f << std::endl; +// f << '\n'; // get_state().output(ns, f); // f.close(); // state_cntr++; @@ -310,18 +202,6 @@ bool flow_insensitive_analysis_baset::visit( return new_data; } -/*******************************************************************\ - -Function: flow_insensitive_analysis_baset::do_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool flow_insensitive_analysis_baset::do_function_call( locationt l_call, const goto_functionst &goto_functions, @@ -402,18 +282,6 @@ bool flow_insensitive_analysis_baset::do_function_call( return new_data; } -/*******************************************************************\ - -Function: flow_insensitive_analysis_baset::do_function_call_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool flow_insensitive_analysis_baset::do_function_call_rec( locationt l_call, const exprt &function, @@ -523,18 +391,6 @@ bool flow_insensitive_analysis_baset::do_function_call_rec( return new_data; } -/*******************************************************************\ - -Function: flow_insensitive_analysis_baset::fixedpoint - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void flow_insensitive_analysis_baset::fixedpoint( const goto_functionst &goto_functions) { @@ -548,18 +404,6 @@ void flow_insensitive_analysis_baset::fixedpoint( } } -/*******************************************************************\ - -Function: flow_insensitive_analysis_baset::fixedpoint - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool flow_insensitive_analysis_baset::fixedpoint( const goto_functionst::function_mapt::const_iterator it, const goto_functionst &goto_functions) @@ -568,36 +412,12 @@ bool flow_insensitive_analysis_baset::fixedpoint( return fixedpoint(it->second.body, goto_functions); } -/*******************************************************************\ - -Function: flow_insensitive_analysis_baset::update - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void flow_insensitive_analysis_baset::update( const goto_functionst &goto_functions) { // no need to copy value sets around } -/*******************************************************************\ - -Function: flow_insensitive_analysis_baset::update - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void flow_insensitive_analysis_baset::update( const goto_programt &goto_program) { diff --git a/src/analyses/flow_insensitive_analysis.h b/src/analyses/flow_insensitive_analysis.h index 07d1f0f77cd..b2f1553c6f0 100644 --- a/src/analyses/flow_insensitive_analysis.h +++ b/src/analyses/flow_insensitive_analysis.h @@ -7,6 +7,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Flow Insensitive Static Analysis + #ifndef CPROVER_ANALYSES_FLOW_INSENSITIVE_ANALYSIS_H #define CPROVER_ANALYSES_FLOW_INSENSITIVE_ANALYSIS_H @@ -22,7 +25,8 @@ Author: Daniel Kroening, kroening@kroening.com class flow_insensitive_abstract_domain_baset { public: - flow_insensitive_abstract_domain_baset() + flow_insensitive_abstract_domain_baset(): + changed(false) { } @@ -158,7 +162,7 @@ class flow_insensitive_analysis_baset working_set.push(l); } - // true = found s.th. new + // true = found something new bool fixedpoint( const goto_programt &goto_program, const goto_functionst &goto_functions); @@ -170,7 +174,7 @@ class flow_insensitive_analysis_baset void fixedpoint( const goto_functionst &goto_functions); - // true = found s.th. new + // true = found something new bool visit( locationt l, working_sett &working_set, diff --git a/src/analyses/global_may_alias.cpp b/src/analyses/global_may_alias.cpp index 33ad0f7f186..82c1f5a72dc 100644 --- a/src/analyses/global_may_alias.cpp +++ b/src/analyses/global_may_alias.cpp @@ -1,24 +1,15 @@ /*******************************************************************\ -Module: Field-insensitive, location-sensitive gobal may alias analysis +Module: Field-insensitive, location-sensitive global may alias analysis Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "global_may_alias.h" - -/*******************************************************************\ - -Function: global_may_alias_domaint::assign_lhs_aliases - - Inputs: - - Outputs: - - Purpose: +/// \file +/// Field-insensitive, location-sensitive global may alias analysis -\*******************************************************************/ +#include "global_may_alias.h" void global_may_alias_domaint::assign_lhs_aliases( const exprt &lhs, @@ -37,18 +28,6 @@ void global_may_alias_domaint::assign_lhs_aliases( } } -/*******************************************************************\ - -Function: global_may_alias_domaint::get_rhs_aliases - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void global_may_alias_domaint::get_rhs_aliases( const exprt &rhs, std::set &alias_set) @@ -77,18 +56,6 @@ void global_may_alias_domaint::get_rhs_aliases( } } -/*******************************************************************\ - -Function: global_may_alias_domaint::get_rhs_aliases_address_of - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void global_may_alias_domaint::get_rhs_aliases_address_of( const exprt &rhs, std::set &alias_set) @@ -108,18 +75,6 @@ void global_may_alias_domaint::get_rhs_aliases_address_of( } } -/*******************************************************************\ - -Function: global_may_alias_domaint::transform - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void global_may_alias_domaint::transform( locationt from, locationt to, @@ -163,18 +118,6 @@ void global_may_alias_domaint::transform( } } -/*******************************************************************\ - -Function: global_may_alias_domaint::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void global_may_alias_domaint::output( std::ostream &out, const ai_baset &ai, @@ -213,18 +156,6 @@ void global_may_alias_domaint::output( } } -/*******************************************************************\ - -Function: global_may_alias_domaint::merge - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool global_may_alias_domaint::merge( const global_may_alias_domaint &b, locationt from, diff --git a/src/analyses/global_may_alias.h b/src/analyses/global_may_alias.h index 2f4a49b2d0a..d946b371c05 100644 --- a/src/analyses/global_may_alias.h +++ b/src/analyses/global_may_alias.h @@ -7,6 +7,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Field-insensitive, location-sensitive, over-approximative escape analysis + #ifndef CPROVER_ANALYSES_GLOBAL_MAY_ALIAS_H #define CPROVER_ANALYSES_GLOBAL_MAY_ALIAS_H @@ -16,14 +19,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "ai.h" -/*******************************************************************\ - - Class: global_may_alias_domaint - - Purpose: - -\*******************************************************************/ - class global_may_alias_analysist; class global_may_alias_domaint:public ai_domain_baset diff --git a/src/analyses/goto_check.cpp b/src/analyses/goto_check.cpp index cc418d6aed9..be4edbf288f 100644 --- a/src/analyses/goto_check.cpp +++ b/src/analyses/goto_check.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// GOTO Programs + +#include "goto_check.h" + #include #include @@ -24,7 +29,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include "local_bitvector_analysis.h" -#include "goto_check.h" class goto_checkt { @@ -33,7 +37,7 @@ class goto_checkt const namespacet &_ns, const optionst &_options): ns(_ns), - local_bitvector_analysis(0) + local_bitvector_analysis(nullptr) { enable_bounds_check=_options.get_bool_option("bounds-check"); enable_pointer_check=_options.get_bool_option("pointer-check"); @@ -64,6 +68,8 @@ class goto_checkt void goto_check(goto_functiont &goto_function, const irep_idt &mode); + void collect_allocations(const goto_functionst &goto_functions); + protected: const namespacet &ns; local_bitvector_analysist *local_bitvector_analysis; @@ -134,19 +140,43 @@ class goto_checkt typedef optionst::value_listt error_labelst; error_labelst error_labels; -}; -/*******************************************************************\ - -Function: goto_checkt::invalidate - - Inputs: - - Outputs: + typedef std::pair allocationt; + typedef std::list allocationst; + allocationst allocations; +}; - Purpose: +void goto_checkt::collect_allocations( + const goto_functionst &goto_functions) +{ + if(!enable_pointer_check) + return; -\*******************************************************************/ + forall_goto_functions(itf, goto_functions) + forall_goto_program_instructions(it, itf->second.body) + { + const goto_programt::instructiont &instruction=*it; + if(!instruction.is_function_call()) + continue; + + const code_function_callt &call= + to_code_function_call(instruction.code); + if(call.function().id()!=ID_symbol || + to_symbol_expr(call.function()).get_identifier()!= + CPROVER_PREFIX "allocated_memory") + continue; + + const code_function_callt::argumentst &args= call.arguments(); + if(args.size()!=2 || + args[0].type().id()!=ID_unsignedbv || + args[1].type().id()!=ID_unsignedbv) + throw "expected two unsigned arguments to " + CPROVER_PREFIX "allocated_memory"; + + assert(args[0].type()==args[1].type()); + allocations.push_back({args[0], args[1]}); + } +} void goto_checkt::invalidate(const exprt &lhs) { @@ -182,18 +212,6 @@ void goto_checkt::invalidate(const exprt &lhs) } } -/*******************************************************************\ - -Function: goto_checkt::div_by_zero_check - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_checkt::div_by_zero_check( const div_exprt &expr, const guardt &guard) @@ -220,18 +238,6 @@ void goto_checkt::div_by_zero_check( guard); } -/*******************************************************************\ - -Function: goto_checkt::undefined_shift_check - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_checkt::undefined_shift_check( const shift_exprt &expr, const guardt &guard) @@ -283,18 +289,6 @@ void goto_checkt::undefined_shift_check( } } -/*******************************************************************\ - -Function: goto_checkt::mod_by_zero_check - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_checkt::mod_by_zero_check( const mod_exprt &expr, const guardt &guard) @@ -321,18 +315,6 @@ void goto_checkt::mod_by_zero_check( guard); } -/*******************************************************************\ - -Function: goto_checkt::conversion_check - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_checkt::conversion_check( const exprt &expr, const guardt &guard) @@ -512,18 +494,6 @@ void goto_checkt::conversion_check( } } -/*******************************************************************\ - -Function: goto_checkt::integer_overflow_check - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_checkt::integer_overflow_check( const exprt &expr, const guardt &guard) @@ -645,18 +615,6 @@ void goto_checkt::integer_overflow_check( } } -/*******************************************************************\ - -Function: goto_checkt::float_overflow_check - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_checkt::float_overflow_check( const exprt &expr, const guardt &guard) @@ -779,18 +737,6 @@ void goto_checkt::float_overflow_check( } } -/*******************************************************************\ - -Function: goto_checkt::nan_check - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_checkt::nan_check( const exprt &expr, const guardt &guard) @@ -900,18 +846,6 @@ void goto_checkt::nan_check( guard); } -/*******************************************************************\ - -Function: goto_checkt::pointer_rel_check - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_checkt::pointer_rel_check( const exprt &expr, const guardt &guard) @@ -942,18 +876,6 @@ void goto_checkt::pointer_rel_check( } } -/*******************************************************************\ - -Function: goto_checkt::pointer_overflow_check - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_checkt::pointer_overflow_check( const exprt &expr, const guardt &guard) @@ -980,18 +902,6 @@ void goto_checkt::pointer_overflow_check( } } -/*******************************************************************\ - -Function: goto_checkt::pointer_validity_check - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_checkt::pointer_validity_check( const dereference_exprt &expr, const guardt &guard, @@ -1031,10 +941,49 @@ void goto_checkt::pointer_validity_check( } else { + exprt allocs=false_exprt(); + + if(!allocations.empty()) + { + exprt::operandst disjuncts; + + for(const auto &a : allocations) + { + typecast_exprt int_ptr(pointer, a.first.type()); + + exprt lb(int_ptr); + if(access_lb.is_not_nil()) + { + if(!base_type_eq(lb.type(), access_lb.type(), ns)) + lb=plus_exprt(lb, typecast_exprt(access_lb, lb.type())); + else + lb=plus_exprt(lb, access_lb); + } + + binary_relation_exprt lb_check(a.first, ID_le, lb); + + exprt ub(int_ptr); + if(access_ub.is_not_nil()) + { + if(!base_type_eq(ub.type(), access_ub.type(), ns)) + ub=plus_exprt(ub, typecast_exprt(access_ub, ub.type())); + else + ub=plus_exprt(ub, access_ub); + } + + binary_relation_exprt ub_check( + ub, ID_le, plus_exprt(a.first, a.second)); + + disjuncts.push_back(and_exprt(lb_check, ub_check)); + } + + allocs=disjunction(disjuncts); + } + if(flags.is_unknown() || flags.is_null()) { add_guarded_claim( - not_exprt(null_pointer(pointer)), + or_exprt(allocs, not_exprt(null_pointer(pointer))), "dereference failure: pointer NULL", "pointer dereference", expr.find_source_location(), @@ -1044,7 +993,7 @@ void goto_checkt::pointer_validity_check( if(flags.is_unknown()) add_guarded_claim( - not_exprt(invalid_pointer(pointer)), + or_exprt(allocs, not_exprt(invalid_pointer(pointer))), "dereference failure: pointer invalid", "pointer dereference", expr.find_source_location(), @@ -1053,7 +1002,7 @@ void goto_checkt::pointer_validity_check( if(flags.is_uninitialized()) add_guarded_claim( - not_exprt(invalid_pointer(pointer)), + or_exprt(allocs, not_exprt(invalid_pointer(pointer))), "dereference failure: pointer uninitialized", "pointer dereference", expr.find_source_location(), @@ -1062,7 +1011,7 @@ void goto_checkt::pointer_validity_check( if(flags.is_unknown() || flags.is_dynamic_heap()) add_guarded_claim( - not_exprt(deallocated(pointer, ns)), + or_exprt(allocs, not_exprt(deallocated(pointer, ns))), "dereference failure: deallocated dynamic object", "pointer dereference", expr.find_source_location(), @@ -1071,7 +1020,7 @@ void goto_checkt::pointer_validity_check( if(flags.is_unknown() || flags.is_dynamic_local()) add_guarded_claim( - not_exprt(dead_object(pointer, ns)), + or_exprt(allocs, not_exprt(dead_object(pointer, ns))), "dereference failure: dead object", "pointer dereference", expr.find_source_location(), @@ -1089,7 +1038,11 @@ void goto_checkt::pointer_validity_check( access_ub)); add_guarded_claim( - implies_exprt(malloc_object(pointer, ns), not_exprt(dynamic_bounds)), + or_exprt( + allocs, + implies_exprt( + malloc_object(pointer, ns), + not_exprt(dynamic_bounds))), "dereference failure: pointer outside dynamic object bounds", "pointer dereference", expr.find_source_location(), @@ -1110,7 +1063,7 @@ void goto_checkt::pointer_validity_check( access_ub)); add_guarded_claim( - or_exprt(dynamic_object(pointer), not_exprt(object_bounds)), + or_exprt(allocs, dynamic_object(pointer), not_exprt(object_bounds)), "dereference failure: pointer outside object bounds", "pointer dereference", expr.find_source_location(), @@ -1120,35 +1073,11 @@ void goto_checkt::pointer_validity_check( } } -/*******************************************************************\ - -Function: goto_checkt::array_name - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string goto_checkt::array_name(const exprt &expr) { return ::array_name(ns, expr); } -/*******************************************************************\ - -Function: goto_checkt::bounds_check - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_checkt::bounds_check( const index_exprt &expr, const guardt &guard) @@ -1238,7 +1167,8 @@ void goto_checkt::bounds_check( plus_exprt effective_offset(ode.offset(), pointer_offset(pointer)); assert(effective_offset.op0().type()==effective_offset.op1().type()); - assert(effective_offset.type()==size.type()); + if(effective_offset.type()!=size.type()) + size.make_typecast(effective_offset.type()); binary_relation_exprt inequality(effective_offset, ID_lt, size); @@ -1303,18 +1233,6 @@ void goto_checkt::bounds_check( } } -/*******************************************************************\ - -Function: goto_checkt::add_guarded_claim - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_checkt::add_guarded_claim( const exprt &_expr, const std::string &comment, @@ -1362,18 +1280,6 @@ void goto_checkt::add_guarded_claim( } } -/*******************************************************************\ - -Function: goto_checkt::check_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_checkt::check_rec( const exprt &expr, guardt &guard, @@ -1554,36 +1460,12 @@ void goto_checkt::check_rec( mode); } -/*******************************************************************\ - -Function: goto_checkt::check - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_checkt::check(const exprt &expr, const irep_idt &mode) { guardt guard; check_rec(expr, guard, false, mode); } -/*******************************************************************\ - -Function: goto_checkt::goto_check - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_checkt::goto_check( goto_functiont &goto_function, const irep_idt &mode) @@ -1679,7 +1561,7 @@ void goto_checkt::goto_check( add_guarded_claim( not_eq_null, - "this is null on method invokation", + "this is null on method invocation", "pointer dereference", i.source_location, pointer, @@ -1808,21 +1690,21 @@ void goto_checkt::goto_check( { i_it->source_location.id(irep_idt()); - if(it->source_location.get_file()!=irep_idt()) + if(!it->source_location.get_file().empty()) i_it->source_location.set_file(it->source_location.get_file()); - if(it->source_location.get_line()!=irep_idt()) + if(!it->source_location.get_line().empty()) i_it->source_location.set_line(it->source_location.get_line()); - if(it->source_location.get_function()!=irep_idt()) + if(!it->source_location.get_function().empty()) i_it->source_location.set_function( it->source_location.get_function()); - if(it->source_location.get_column()!=irep_idt()) + if(!it->source_location.get_column().empty()) i_it->source_location.set_column(it->source_location.get_column()); } - if(i_it->function==irep_idt()) + if(i_it->function.empty()) i_it->function=it->function; } @@ -1837,18 +1719,6 @@ void goto_checkt::goto_check( } } -/*******************************************************************\ - -Function: goto_check - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_check( const namespacet &ns, const optionst &options, @@ -1858,18 +1728,6 @@ void goto_check( goto_check.goto_check(goto_function, irep_idt()); } -/*******************************************************************\ - -Function: goto_check - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_check( const namespacet &ns, const optionst &options, @@ -1877,6 +1735,8 @@ void goto_check( { goto_checkt goto_check(ns, options); + goto_check.collect_allocations(goto_functions); + Forall_goto_functions(it, goto_functions) { irep_idt mode=ns.lookup(it->first).mode; @@ -1884,18 +1744,6 @@ void goto_check( } } -/*******************************************************************\ - -Function: goto_check - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_check( const optionst &options, goto_modelt &goto_model) diff --git a/src/analyses/goto_check.h b/src/analyses/goto_check.h index 2089d744fd2..44d98069de9 100644 --- a/src/analyses/goto_check.h +++ b/src/analyses/goto_check.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Program Transformation + #ifndef CPROVER_ANALYSES_GOTO_CHECK_H #define CPROVER_ANALYSES_GOTO_CHECK_H diff --git a/src/analyses/goto_rw.cpp b/src/analyses/goto_rw.cpp index 239918240ab..49827bd2bd3 100644 --- a/src/analyses/goto_rw.cpp +++ b/src/analyses/goto_rw.cpp @@ -8,6 +8,8 @@ Date: April 2010 \*******************************************************************/ +#include "goto_rw.h" + #include #include @@ -23,36 +25,10 @@ Date: April 2010 #include -#include "goto_rw.h" - -/*******************************************************************\ - -Function: range_domain_baset::~range_domain_baset - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - range_domain_baset::~range_domain_baset() { } -/*******************************************************************\ - -Function: range_domaint::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void range_domaint::output( const namespacet &ns, std::ostream &out) const { @@ -68,18 +44,6 @@ void range_domaint::output( out << "]"; } -/*******************************************************************\ - -Function: rw_range_sett::~rw_range_sett - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - rw_range_sett::~rw_range_sett() { for(rw_range_sett::objectst::iterator it=r_range_set.begin(); @@ -93,51 +57,27 @@ rw_range_sett::~rw_range_sett() delete it->second; } -/*******************************************************************\ - -Function: rw_range_sett::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rw_range_sett::output(std::ostream &out) const { - out << "READ:" << std::endl; + out << "READ:\n"; forall_rw_range_set_r_objects(it, *this) { out << " " << it->first; it->second->output(ns, out); - out << std::endl; + out << '\n'; } - out << std::endl; + out << '\n'; - out << "WRITE:" << std::endl; + out << "WRITE:\n"; forall_rw_range_set_w_objects(it, *this) { out << " " << it->first; it->second->output(ns, out); - out << std::endl; + out << '\n'; } } -/*******************************************************************\ - -Function: rw_range_sett::get_objects_complex - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rw_range_sett::get_objects_complex( get_modet mode, const exprt &expr, @@ -149,24 +89,13 @@ void rw_range_sett::get_objects_complex( range_spect sub_size= to_range_spect(pointer_offset_bits(op.type().subtype(), ns)); + assert(sub_size>0); range_spect offset= (range_start==-1 || expr.id()==ID_complex_real) ? 0 : sub_size; get_objects_rec(mode, op, range_start+offset, size); } -/*******************************************************************\ - -Function: rw_range_sett::get_objects_if - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rw_range_sett::get_objects_if( get_modet mode, const if_exprt &if_expr, @@ -179,25 +108,13 @@ void rw_range_sett::get_objects_if( get_objects_rec(mode, if_expr.true_case(), range_start, size); else { - get_objects_rec(READ, if_expr.cond()); + get_objects_rec(get_modet::READ, if_expr.cond()); get_objects_rec(mode, if_expr.false_case(), range_start, size); get_objects_rec(mode, if_expr.true_case(), range_start, size); } } -/*******************************************************************\ - -Function: rw_range_sett::get_objects_dereference - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rw_range_sett::get_objects_dereference( get_modet mode, const dereference_exprt &deref, @@ -205,23 +122,11 @@ void rw_range_sett::get_objects_dereference( const range_spect &size) { const exprt &pointer=deref.pointer(); - get_objects_rec(READ, pointer); - if(mode!=READ) + get_objects_rec(get_modet::READ, pointer); + if(mode!=get_modet::READ) get_objects_rec(mode, pointer); } -/*******************************************************************\ - -Function: rw_range_sett::get_objects_byte_extract - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rw_range_sett::get_objects_byte_extract( get_modet mode, const byte_extract_exprt &be, @@ -249,18 +154,6 @@ void rw_range_sett::get_objects_byte_extract( } } -/*******************************************************************\ - -Function: rw_range_sett::get_objects_shift - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rw_range_sett::get_objects_shift( get_modet mode, const shift_exprt &shift, @@ -309,18 +202,6 @@ void rw_range_sett::get_objects_shift( } } -/*******************************************************************\ - -Function: rw_range_sett::get_objects_member - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rw_range_sett::get_objects_member( get_modet mode, const member_exprt &expr, @@ -351,18 +232,6 @@ void rw_range_sett::get_objects_member( get_objects_rec(mode, expr.struct_op(), offset, size); } -/*******************************************************************\ - -Function: rw_range_sett::get_objects_index - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rw_range_sett::get_objects_index( get_modet mode, const index_exprt &expr, @@ -395,7 +264,7 @@ void rw_range_sett::get_objects_index( mp_integer index; if(to_integer(simp_index, index)) { - get_objects_rec(READ, expr.index()); + get_objects_rec(get_modet::READ, expr.index()); index=-1; } @@ -411,18 +280,6 @@ void rw_range_sett::get_objects_index( size); } -/*******************************************************************\ - -Function: rw_range_sett::get_objects_array - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rw_range_sett::get_objects_array( get_modet mode, const array_exprt &expr, @@ -463,18 +320,6 @@ void rw_range_sett::get_objects_array( } } -/*******************************************************************\ - -Function: rw_range_sett::get_objects_struct - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rw_range_sett::get_objects_struct( get_modet mode, const struct_exprt &expr, @@ -535,18 +380,6 @@ void rw_range_sett::get_objects_struct( } } -/*******************************************************************\ - -Function: rw_range_sett::get_objects_typecast - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rw_range_sett::get_objects_typecast( get_modet mode, const typecast_exprt &tc, @@ -572,18 +405,6 @@ void rw_range_sett::get_objects_typecast( get_objects_rec(mode, op, range_start, new_size); } -/*******************************************************************\ - -Function: rw_range_sett::get_objects_address_of - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rw_range_sett::get_objects_address_of(const exprt &object) { if(object.id()==ID_string_constant || @@ -593,88 +414,65 @@ void rw_range_sett::get_objects_address_of(const exprt &object) // constant, nothing to do return; else if(object.id()==ID_symbol) - get_objects_rec(READ, object); + get_objects_rec(get_modet::READ, object); else if(object.id()==ID_dereference) - get_objects_rec(READ, object); + get_objects_rec(get_modet::READ, object); else if(object.id()==ID_index) { const index_exprt &index=to_index_expr(object); - get_objects_rec(READ, address_of_exprt(index.array())); - get_objects_rec(READ, index.index()); + get_objects_rec(get_modet::READ, address_of_exprt(index.array())); + get_objects_rec(get_modet::READ, index.index()); } else if(object.id()==ID_member) { const member_exprt &member=to_member_expr(object); - get_objects_rec(READ, address_of_exprt(member.struct_op())); + get_objects_rec(get_modet::READ, address_of_exprt(member.struct_op())); } else if(object.id()==ID_if) { const if_exprt &if_expr=to_if_expr(object); - get_objects_rec(READ, if_expr.cond()); - get_objects_rec(READ, address_of_exprt(if_expr.true_case())); - get_objects_rec(READ, address_of_exprt(if_expr.false_case())); + get_objects_rec(get_modet::READ, if_expr.cond()); + get_objects_rec(get_modet::READ, address_of_exprt(if_expr.true_case())); + get_objects_rec(get_modet::READ, address_of_exprt(if_expr.false_case())); } else if(object.id()==ID_byte_extract_little_endian || object.id()==ID_byte_extract_big_endian) { const byte_extract_exprt &be=to_byte_extract_expr(object); - get_objects_rec(READ, address_of_exprt(be.op())); + get_objects_rec(get_modet::READ, address_of_exprt(be.op())); } else if(object.id()==ID_typecast) { const typecast_exprt &tc=to_typecast_expr(object); - get_objects_rec(READ, address_of_exprt(tc.op())); + get_objects_rec(get_modet::READ, address_of_exprt(tc.op())); } else throw "rw_range_sett: address_of `"+object.id_string()+"' not handled"; } -/*******************************************************************\ - -Function: rw_range_sett::add - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rw_range_sett::add( get_modet mode, const irep_idt &identifier, const range_spect &range_start, const range_spect &range_end) { - objectst::iterator entry=(mode==LHS_W ? w_range_set : r_range_set). + objectst::iterator entry=(mode==get_modet::LHS_W ? w_range_set : r_range_set). insert( - std::pair(identifier, 0)).first; + std::pair( + identifier, nullptr)).first; - if(entry->second==0) + if(entry->second==nullptr) entry->second=new range_domaint(); static_cast(entry->second)->push_back( std::make_pair(range_start, range_end)); } -/*******************************************************************\ - -Function: rw_range_sett::get_objects_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rw_range_sett::get_objects_rec( get_modet mode, const exprt &expr, @@ -742,9 +540,9 @@ void rw_range_sett::get_objects_rec( else add(mode, identifier, 0, -1); } - else if(mode==READ && expr.id()==ID_address_of) + else if(mode==get_modet::READ && expr.id()==ID_address_of) get_objects_address_of(to_address_of_expr(expr).object()); - else if(mode==READ) + else if(mode==get_modet::READ) { // possibly affects the full object size, even if range_start/size // are only a subset of the bytes (e.g., when using the result of @@ -757,7 +555,7 @@ void rw_range_sett::get_objects_rec( { // dereferencing may yield some weird ones, ignore these } - else if(mode==LHS_W) + else if(mode==get_modet::LHS_W) { forall_operands(it, expr) get_objects_rec(mode, *it); @@ -766,18 +564,6 @@ void rw_range_sett::get_objects_rec( throw "rw_range_sett: assignment to `"+expr.id_string()+"' not handled"; } -/*******************************************************************\ - -Function: rw_range_sett::get_objects_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rw_range_sett::get_objects_rec(get_modet mode, const exprt &expr) { range_spect size= @@ -785,40 +571,16 @@ void rw_range_sett::get_objects_rec(get_modet mode, const exprt &expr) get_objects_rec(mode, expr, 0, size); } -/*******************************************************************\ - -Function: rw_range_sett::get_objects_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rw_range_sett::get_objects_rec(const typet &type) { // TODO should recurse into various composite types if(type.id()==ID_array) { get_objects_rec(type.subtype()); - get_objects_rec(READ, to_array_type(type).size()); + get_objects_rec(get_modet::READ, to_array_type(type).size()); } } -/*******************************************************************\ - -Function: rw_range_set_value_sett::get_objects_dereference - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rw_range_set_value_sett::get_objects_dereference( get_modet mode, const dereference_exprt &deref, @@ -852,18 +614,6 @@ void rw_range_set_value_sett::get_objects_dereference( get_objects_rec(mode, object, range_start, new_size); } -/*******************************************************************\ - -Function: guarded_range_domaint::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void guarded_range_domaint::output( const namespacet &ns, std::ostream &out) const { @@ -880,18 +630,6 @@ void guarded_range_domaint::output( out << "]"; } -/*******************************************************************\ - -Function: rw_guarded_range_set_value_sett::get_objects_if - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rw_guarded_range_set_value_sett::get_objects_if( get_modet mode, const if_exprt &if_expr, @@ -904,7 +642,7 @@ void rw_guarded_range_set_value_sett::get_objects_if( get_objects_rec(mode, if_expr.true_case(), range_start, size); else { - get_objects_rec(READ, if_expr.cond()); + get_objects_rec(get_modet::READ, if_expr.cond()); guardt guard_bak1(guard), guard_bak2(guard); @@ -918,29 +656,18 @@ void rw_guarded_range_set_value_sett::get_objects_if( } } -/*******************************************************************\ - -Function: rw_guarded_range_set_value_sett::add - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rw_guarded_range_set_value_sett::add( get_modet mode, const irep_idt &identifier, const range_spect &range_start, const range_spect &range_end) { - objectst::iterator entry=(mode==LHS_W ? w_range_set : r_range_set). + objectst::iterator entry=(mode==get_modet::LHS_W ? w_range_set : r_range_set). insert( - std::pair(identifier, 0)).first; + std::pair( + identifier, nullptr)).first; - if(entry->second==0) + if(entry->second==nullptr) entry->second=new guarded_range_domaint(); static_cast(entry->second)->insert( @@ -948,38 +675,14 @@ void rw_guarded_range_set_value_sett::add( std::make_pair(range_end, guard.as_expr()))); } -/*******************************************************************\ - -Function: goto_rw - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_rw(goto_programt::const_targett target, const code_assignt &assign, rw_range_sett &rw_set) { - rw_set.get_objects_rec(target, rw_range_sett::LHS_W, assign.lhs()); - rw_set.get_objects_rec(target, rw_range_sett::READ, assign.rhs()); + rw_set.get_objects_rec(target, rw_range_sett::get_modet::LHS_W, assign.lhs()); + rw_set.get_objects_rec(target, rw_range_sett::get_modet::READ, assign.rhs()); } -/*******************************************************************\ - -Function: goto_rw - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_rw(goto_programt::const_targett target, const code_function_callt &function_call, rw_range_sett &rw_set) @@ -987,30 +690,18 @@ void goto_rw(goto_programt::const_targett target, if(function_call.lhs().is_not_nil()) rw_set.get_objects_rec( target, - rw_range_sett::LHS_W, + rw_range_sett::get_modet::LHS_W, function_call.lhs()); rw_set.get_objects_rec( target, - rw_range_sett::READ, + rw_range_sett::get_modet::READ, function_call.function()); forall_expr(it, function_call.arguments()) - rw_set.get_objects_rec(target, rw_range_sett::READ, *it); + rw_set.get_objects_rec(target, rw_range_sett::get_modet::READ, *it); } -/*******************************************************************\ - -Function: goto_rw - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_rw(goto_programt::const_targett target, rw_range_sett &rw_set) { @@ -1025,7 +716,7 @@ void goto_rw(goto_programt::const_targett target, case ASSERT: rw_set.get_objects_rec( target, - rw_range_sett::READ, + rw_range_sett::get_modet::READ, target->guard); break; @@ -1036,7 +727,7 @@ void goto_rw(goto_programt::const_targett target, if(code_return.has_return_value()) rw_set.get_objects_rec( target, - rw_range_sett::READ, + rw_range_sett::get_modet::READ, code_return.return_value()); } break; @@ -1046,7 +737,7 @@ void goto_rw(goto_programt::const_targett target, if(target->code.get(ID_statement)==ID_printf) { forall_expr(it, target->code.operands()) - rw_set.get_objects_rec(target, rw_range_sett::READ, *it); + rw_set.get_objects_rec(target, rw_range_sett::get_modet::READ, *it); } break; @@ -1069,7 +760,7 @@ void goto_rw(goto_programt::const_targett target, case DEAD: rw_set.get_objects_rec( target, - rw_range_sett::LHS_W, + rw_range_sett::get_modet::LHS_W, to_code_dead(target->code).symbol()); break; @@ -1078,7 +769,7 @@ void goto_rw(goto_programt::const_targett target, to_code_decl(target->code).symbol().type()); rw_set.get_objects_rec( target, - rw_range_sett::LHS_W, + rw_range_sett::get_modet::LHS_W, to_code_decl(target->code).symbol()); break; @@ -1088,36 +779,12 @@ void goto_rw(goto_programt::const_targett target, } } -/*******************************************************************\ - -Function: goto_rw - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_rw(const goto_programt &goto_program, rw_range_sett &rw_set) { forall_goto_program_instructions(i_it, goto_program) goto_rw(i_it, rw_set); } -/*******************************************************************\ - -Function: goto_rw - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_rw(const goto_functionst &goto_functions, const irep_idt &function, rw_range_sett &rw_set) diff --git a/src/analyses/goto_rw.h b/src/analyses/goto_rw.h index 6c9ae6d9dec..1f92c3e0e14 100644 --- a/src/analyses/goto_rw.h +++ b/src/analyses/goto_rw.h @@ -8,6 +8,7 @@ Date: April 2010 \*******************************************************************/ + #ifndef CPROVER_ANALYSES_GOTO_RW_H #define CPROVER_ANALYSES_GOTO_RW_H @@ -107,11 +108,11 @@ class rw_range_sett const range_domaint &get_ranges(objectst::const_iterator it) const { - assert(dynamic_cast(it->second)!=0); + PRECONDITION(dynamic_cast(it->second)!=nullptr); return *static_cast(it->second); } - typedef enum { LHS_W, READ } get_modet; + enum class get_modet { LHS_W, READ }; virtual void get_objects_rec( goto_programt::const_targett _target, @@ -276,7 +277,7 @@ class rw_guarded_range_set_value_sett:public rw_range_set_value_sett const guarded_range_domaint &get_ranges(objectst::const_iterator it) const { - assert(dynamic_cast(it->second)!=0); + PRECONDITION(dynamic_cast(it->second)!=nullptr); return *static_cast(it->second); } diff --git a/src/analyses/interval_analysis.cpp b/src/analyses/interval_analysis.cpp index 17c3dd68562..c6d739c8bfd 100644 --- a/src/analyses/interval_analysis.cpp +++ b/src/analyses/interval_analysis.cpp @@ -6,22 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Interval Analysis -#include "interval_domain.h" #include "interval_analysis.h" -/*******************************************************************\ - -Function: instrument_intervals - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include "interval_domain.h" void instrument_intervals( const ait &interval_analysis, @@ -84,18 +76,6 @@ void instrument_intervals( } } -/*******************************************************************\ - -Function: interval_analysis - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interval_analysis( const namespacet &ns, goto_functionst &goto_functions) diff --git a/src/analyses/interval_analysis.h b/src/analyses/interval_analysis.h index be86a6c65f8..1c85fc9a193 100644 --- a/src/analyses/interval_analysis.h +++ b/src/analyses/interval_analysis.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Interval Analysis + #ifndef CPROVER_ANALYSES_INTERVAL_ANALYSIS_H #define CPROVER_ANALYSES_INTERVAL_ANALYSIS_H diff --git a/src/analyses/interval_domain.cpp b/src/analyses/interval_domain.cpp index 1faf8c52364..5f1b9a314b5 100644 --- a/src/analyses/interval_domain.cpp +++ b/src/analyses/interval_domain.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Interval Domain + +#include "interval_domain.h" + #ifdef DEBUG #include #endif @@ -14,20 +19,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "interval_domain.h" - -/*******************************************************************\ - -Function: interval_domaint::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interval_domaint::output( std::ostream &out, const ai_baset &ai, @@ -64,18 +55,6 @@ void interval_domaint::output( } } -/*******************************************************************\ - -Function: interval_domaint::transform - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interval_domaint::transform( locationt from, locationt to, @@ -127,22 +106,20 @@ void interval_domaint::transform( } } -/*******************************************************************\ - -Function: interval_domaint::merge - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -bool interval_domaint::merge( - const interval_domaint &b, - locationt from, - locationt to) +/// Sets *this to the mathematical join between the two domains. This can be +/// thought of as an abstract version of union; *this is increased so that it +/// contains all of the values that are represented by b as well as its original +/// intervals. The result is an overapproximation, for example: +/// "[0,1]".join("[3,4]") --> "[0,4]" includes 2 which isn't in [0,1] or [3,4]. +/// +/// Join is used in several places, the most significant being +/// merge, which uses it to bring together two different paths +/// of analysis. +/// \par parameters: The interval domain, b, to join to this domain. +/// \return True if the join increases the set represented by *this, False if +/// there is no change. +bool interval_domaint::join( + const interval_domaint &b) { if(b.bottom) return false; @@ -157,8 +134,8 @@ bool interval_domaint::merge( for(int_mapt::iterator it=int_map.begin(); it!=int_map.end(); ) // no it++ { - //search for the variable that needs to be merged - //containers have different size and variable order + // search for the variable that needs to be merged + // containers have different size and variable order const int_mapt::const_iterator b_it=b.int_map.find(it->first); if(b_it==b.int_map.end()) { @@ -199,36 +176,12 @@ bool interval_domaint::merge( return result; } -/*******************************************************************\ - -Function: interval_domaint::assign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interval_domaint::assign(const code_assignt &code_assign) { havoc_rec(code_assign.lhs()); assume_rec(code_assign.lhs(), ID_equal, code_assign.rhs()); } -/*******************************************************************\ - -Function: interval_domaint::havoc_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interval_domaint::havoc_rec(const exprt &lhs) { if(lhs.id()==ID_if) @@ -251,18 +204,6 @@ void interval_domaint::havoc_rec(const exprt &lhs) } } -/*******************************************************************\ - -Function: interval_domaint::assume_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interval_domaint::assume_rec( const exprt &lhs, irep_idt id, const exprt &rhs) { @@ -377,18 +318,6 @@ void interval_domaint::assume_rec( } } -/*******************************************************************\ - -Function: interval_domaint::assume_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interval_domaint::assume( const exprt &cond, const namespacet &ns) @@ -396,18 +325,6 @@ void interval_domaint::assume( assume_rec(simplify_expr(cond, ns), false); } -/*******************************************************************\ - -Function: interval_domaint::assume_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interval_domaint::assume_rec( const exprt &cond, bool negation) @@ -454,18 +371,6 @@ void interval_domaint::assume_rec( } } -/*******************************************************************\ - -Function: interval_domaint::make_expression - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt interval_domaint::make_expression(const symbol_exprt &src) const { if(is_int(src.type())) @@ -527,3 +432,58 @@ exprt interval_domaint::make_expression(const symbol_exprt &src) const else return true_exprt(); } + +/// Uses the abstract state to simplify a given expression using context- +/// specific information. +/// \par parameters: The expression to simplify. +/// \return A simplified version of the expression. +/* + * This implementation is aimed at reducing assertions to true, particularly + * range checks for arrays and other bounds checks. + * + * Rather than work with the various kinds of exprt directly, we use assume, + * join and is_bottom. It is sufficient for the use case and avoids duplicating + * functionality that is in assume anyway. + * + * As some expressions (1<=a && a<=2) can be represented exactly as intervals + * and some can't (a<1 || a>2), the way these operations are used varies + * depending on the structure of the expression to try to give the best results. + * For example negating a disjunction makes it easier for assume to handle. + */ + +bool interval_domaint::ai_simplify( + exprt &condition, + const namespacet &ns) const +{ + bool unchanged=true; + interval_domaint d(*this); + + // merge intervals to properly handle conjunction + if(condition.id()==ID_and) // May be directly representable + { + interval_domaint a; + a.make_top(); // a is everything + a.assume(condition, ns); // Restrict a to an over-approximation + // of when condition is true + if(!a.join(d)) // If d (this) is included in a... + { // Then the condition is always true + unchanged=condition.is_true(); + condition.make_true(); + } + } + else if(condition.id()==ID_symbol) + { + // TODO: we have to handle symbol expression + } + else // Less likely to be representable + { + d.assume(not_exprt(condition), ns); // Restrict to when condition is false + if(d.is_bottom()) // If there there are none... + { // Then the condition is always true + unchanged=condition.is_true(); + condition.make_true(); + } + } + + return unchanged; +} diff --git a/src/analyses/interval_domain.h b/src/analyses/interval_domain.h index 7e95c65e9de..d078324679f 100644 --- a/src/analyses/interval_domain.h +++ b/src/analyses/interval_domain.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Interval Domain + #ifndef CPROVER_ANALYSES_INTERVAL_DOMAIN_H #define CPROVER_ANALYSES_INTERVAL_DOMAIN_H @@ -15,8 +18,8 @@ Author: Daniel Kroening, kroening@kroening.com #include "ai.h" #include "interval_template.h" -typedef interval_template integer_intervalt; -typedef interval_template ieee_float_intervalt; +typedef interval_templatet integer_intervalt; +typedef interval_templatet ieee_float_intervalt; class interval_domaint:public ai_domain_baset { @@ -40,10 +43,17 @@ class interval_domaint:public ai_domain_baset const ai_baset &ai, const namespacet &ns) const final; +protected: + bool join(const interval_domaint &b); + +public: bool merge( const interval_domaint &b, locationt from, - locationt to); + locationt to) + { + return join(b); + } // no states void make_bottom() final @@ -85,7 +95,11 @@ class interval_domaint:public ai_domain_baset return bottom; } -private: + virtual bool ai_simplify( + exprt &condition, + const namespacet &ns) const override; + +protected: bool bottom; typedef std::map int_mapt; diff --git a/src/analyses/interval_template.h b/src/analyses/interval_template.h index f59d1da1f8f..eeeb5f32653 100644 --- a/src/analyses/interval_template.h +++ b/src/analyses/interval_template.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_ANALYSES_INTERVAL_TEMPLATE_H #define CPROVER_ANALYSES_INTERVAL_TEMPLATE_H @@ -14,15 +15,15 @@ Author: Daniel Kroening, kroening@kroening.com #include -template class interval_template +template class interval_templatet { public: - interval_template():lower_set(false), upper_set(false) + interval_templatet():lower_set(false), upper_set(false) { // this is 'top' } - explicit interval_template(const T &x): + explicit interval_templatet(const T &x): lower_set(true), upper_set(true), lower(x), @@ -30,7 +31,7 @@ template class interval_template { } - explicit interval_template(const T &l, const T &u): + explicit interval_templatet(const T &l, const T &u): lower_set(true), upper_set(true), lower(l), @@ -101,18 +102,18 @@ template class interval_template } // Union or disjunction - void join(const interval_template &i) + void join(const interval_templatet &i) { approx_union_with(i); } // Intersection or conjunction - void meet(const interval_template &i) + void meet(const interval_templatet &i) { intersect_with(i); } - void intersect_with(const interval_template &i) + void intersect_with(const interval_templatet &i) { if(i.lower_set) { @@ -141,7 +142,7 @@ template class interval_template } } - void approx_union_with(const interval_template &i) + void approx_union_with(const interval_templatet &i) { if(i.lower_set && lower_set) lower=std::min(lower, i.lower); @@ -156,7 +157,7 @@ template class interval_template }; template -tvt operator<=(const interval_template &a, const interval_template &b) +tvt operator<=(const interval_templatet &a, const interval_templatet &b) { if(a.upper_set && b.lower_set && a.upper<=b.lower) return tvt(true); @@ -167,25 +168,25 @@ tvt operator<=(const interval_template &a, const interval_template &b) } template -tvt operator>=(const interval_template &a, const interval_template &b) +tvt operator>=(const interval_templatet &a, const interval_templatet &b) { return b<=a; } template -tvt operator<(const interval_template &a, const interval_template &b) +tvt operator<(const interval_templatet &a, const interval_templatet &b) { return !(a>=b); } template -tvt operator>(const interval_template &a, const interval_template &b) +tvt operator>(const interval_templatet &a, const interval_templatet &b) { return !(a<=b); } template -bool operator==(const interval_template &a, const interval_template &b) +bool operator==(const interval_templatet &a, const interval_templatet &b) { if(a.lower_set!=b.lower_set) return false; @@ -201,31 +202,31 @@ bool operator==(const interval_template &a, const interval_template &b) } template -bool operator!=(const interval_template &a, const interval_template &b) +bool operator!=(const interval_templatet &a, const interval_templatet &b) { return !(a==b); } template -interval_template upper_interval(const T &u) +interval_templatet upper_interval(const T &u) { - interval_template i; + interval_templatet i; i.upper_set=true; i.upper=u; return i; } template -interval_template lower_interval(const T &l) +interval_templatet lower_interval(const T &l) { - interval_template i; + interval_templatet i; i.lower_set=true; i.lower=l; return i; } template -std::ostream &operator << (std::ostream &out, const interval_template &i) +std::ostream &operator << (std::ostream &out, const interval_templatet &i) { if(i.lower_set) out << '[' << i.lower; diff --git a/src/analyses/invariant_propagation.cpp b/src/analyses/invariant_propagation.cpp index 2da2d7278f4..97211760f52 100644 --- a/src/analyses/invariant_propagation.cpp +++ b/src/analyses/invariant_propagation.cpp @@ -6,61 +6,28 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Invariant Propagation + +#include "invariant_propagation.h" + #include #include #include #include -#include "invariant_propagation.h" - -/*******************************************************************\ - -Function: invariant_propagationt::make_all_true - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void invariant_propagationt::make_all_true() { for(auto &state : state_map) state.second.invariant_set.make_true(); } -/*******************************************************************\ - -Function: invariant_propagationt::make_all_false - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void invariant_propagationt::make_all_false() { for(auto &state : state_map) state.second.invariant_set.make_false(); } -/*******************************************************************\ - -Function: invariant_propagationt::add_objects - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void invariant_propagationt::add_objects( const goto_programt &goto_program) { @@ -108,18 +75,6 @@ void invariant_propagationt::add_objects( } } -/*******************************************************************\ - -Function: invariant_propagationt::get_objects - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void invariant_propagationt::get_objects( const symbolt &symbol, object_listt &dest) @@ -132,18 +87,6 @@ void invariant_propagationt::get_objects( dest.push_back(object_store.add(expr)); } -/*******************************************************************\ - -Function: invariant_propagationt::get_objects_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void invariant_propagationt::get_objects_rec( const exprt &src, std::list &dest) @@ -179,18 +122,6 @@ void invariant_propagationt::get_objects_rec( } } -/*******************************************************************\ - -Function: invariant_propagationt::add_vars - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void invariant_propagationt::add_objects( const goto_functionst &goto_functions) { @@ -243,18 +174,6 @@ void invariant_propagationt::add_objects( } } -/*******************************************************************\ - -Function: invariant_propagationt::get_globals - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void invariant_propagationt::get_globals( object_listt &dest) { @@ -265,18 +184,6 @@ void invariant_propagationt::get_globals( get_objects(it->second, dest); } -/*******************************************************************\ - -Function: invariant_propagationt::check_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool invariant_propagationt::check_type(const typet &type) const { if(type.id()==ID_pointer) @@ -297,18 +204,6 @@ bool invariant_propagationt::check_type(const typet &type) const return false; } -/*******************************************************************\ - -Function: invariant_propagationt::initialize - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void invariant_propagationt::initialize(const goto_programt &goto_program) { baset::initialize(goto_program); @@ -330,18 +225,6 @@ void invariant_propagationt::initialize(const goto_programt &goto_program) add_objects(goto_program); } -/*******************************************************************\ - -Function: invariant_propagationt::initialize - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void invariant_propagationt::initialize(const goto_functionst &goto_functions) { baset::initialize(goto_functions); @@ -350,36 +233,12 @@ void invariant_propagationt::initialize(const goto_functionst &goto_functions) initialize(f_it->second.body); } -/*******************************************************************\ - -Function: invariant_propagationt::simplify - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void invariant_propagationt::simplify(goto_functionst &goto_functions) { Forall_goto_functions(it, goto_functions) simplify(it->second.body); } -/*******************************************************************\ - -Function: invariant_propagationt::simplify - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void invariant_propagationt::simplify(goto_programt &goto_program) { Forall_goto_program_instructions(i_it, goto_program) diff --git a/src/analyses/invariant_propagation.h b/src/analyses/invariant_propagation.h index 0884ba85d07..d21f6373bcb 100644 --- a/src/analyses/invariant_propagation.h +++ b/src/analyses/invariant_propagation.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Invariant Propagation + #ifndef CPROVER_ANALYSES_INVARIANT_PROPAGATION_H #define CPROVER_ANALYSES_INVARIANT_PROPAGATION_H diff --git a/src/analyses/invariant_set.cpp b/src/analyses/invariant_set.cpp index 15c350f0e0f..a91c0349bbb 100644 --- a/src/analyses/invariant_set.cpp +++ b/src/analyses/invariant_set.cpp @@ -6,8 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Invariant Set + +#include "invariant_set.h" + #include +#include #include #include #include @@ -16,41 +22,15 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include +#include #include -#include "invariant_set.h" - -/*******************************************************************\ - -Function: inv_object_storet::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void inv_object_storet::output(std::ostream &out) const { for(unsigned i=0; iget(expr, n); } -/*******************************************************************\ - -Function: inv_object_storet::is_constant_address - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool inv_object_storet::is_constant_address(const exprt &expr) { if(expr.id()==ID_address_of) @@ -250,18 +158,6 @@ bool inv_object_storet::is_constant_address(const exprt &expr) return false; } -/*******************************************************************\ - -Function: inv_object_storet::is_constant_address_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool inv_object_storet::is_constant_address_rec(const exprt &expr) { if(expr.id()==ID_symbol) @@ -281,18 +177,6 @@ bool inv_object_storet::is_constant_address_rec(const exprt &expr) return false; } -/*******************************************************************\ - -Function: invariant_sett::add - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void invariant_sett::add( const std::pair &p, ineq_sett &dest) @@ -315,18 +199,6 @@ void invariant_sett::add( } } -/*******************************************************************\ - -Function: invariant_sett::add_eq - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void invariant_sett::add_eq(const std::pair &p) { eq_set.make_union(p.first, p.second); @@ -364,18 +236,6 @@ void invariant_sett::add_eq(const std::pair &p) add_eq(ne_set, p, ne); } -/*******************************************************************\ - -Function: invariant_sett::add_eq - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void invariant_sett::add_eq( ineq_sett &dest, const std::pair &eq, @@ -414,18 +274,6 @@ void invariant_sett::add_eq( } } -/*******************************************************************\ - -Function: invariant_sett::is_eq - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt invariant_sett::is_eq(std::pair p) const { std::pair s=p; @@ -440,18 +288,6 @@ tvt invariant_sett::is_eq(std::pair p) const return tvt::unknown(); } -/*******************************************************************\ - -Function: invariant_sett::is_le - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt invariant_sett::is_le(std::pair p) const { std::pair s=p; @@ -470,29 +306,18 @@ tvt invariant_sett::is_le(std::pair p) const return tvt::unknown(); } -/*******************************************************************\ - -Function: invariant_sett::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void invariant_sett::output( const irep_idt &identifier, std::ostream &out) const { if(is_false) { - out << "FALSE" << std::endl; + out << "FALSE\n"; return; } - assert(object_store!=NULL); + INVARIANT_STRUCTURED( + object_store!=nullptr, nullptr_exceptiont, "Object store is null"); for(unsigned i=0; isecond; } -/*******************************************************************\ - -Function: invariant_sett::nnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void invariant_sett::nnf(exprt &expr, bool negate) { if(expr.type().id()!=ID_bool) @@ -1075,18 +816,6 @@ void invariant_sett::nnf(exprt &expr, bool negate) } } -/*******************************************************************\ - -Function: invariant_sett::simplify - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void invariant_sett::simplify( exprt &expr) const { @@ -1105,18 +834,6 @@ void invariant_sett::simplify( } } -/*******************************************************************\ - -Function: invariant_sett::get_constant - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt invariant_sett::get_constant(const exprt &expr) const { unsigned a; @@ -1172,18 +889,6 @@ exprt invariant_sett::get_constant(const exprt &expr) const return static_cast(get_nil_irep()); } -/*******************************************************************\ - -Function: inv_object_storet::to_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string inv_object_storet::to_string( unsigned a, const irep_idt &identifier) const @@ -1192,38 +897,14 @@ std::string inv_object_storet::to_string( return id2string(map[a]); } -/*******************************************************************\ - -Function: invariant_sett::to_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string invariant_sett::to_string( unsigned a, const irep_idt &identifier) const { - assert(object_store!=NULL); + PRECONDITION(object_store!=nullptr); return object_store->to_string(a, identifier); } -/*******************************************************************\ - -Function: invariant_sett::make_union - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool invariant_sett::make_union(const invariant_sett &other) { if(other.threaded && @@ -1275,18 +956,6 @@ bool invariant_sett::make_union(const invariant_sett &other) return false; // no change } -/*******************************************************************\ - -Function: invariant_sett::make_union_bounds_map - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool invariant_sett::make_union_bounds_map(const bounds_mapt &other) { bool changed=false; @@ -1319,18 +988,6 @@ bool invariant_sett::make_union_bounds_map(const bounds_mapt &other) return changed; } -/*******************************************************************\ - -Function: invariant_sett::modifies - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void invariant_sett::modifies(unsigned a) { eq_set.isolate(a); @@ -1339,18 +996,6 @@ void invariant_sett::modifies(unsigned a) bounds_map.erase(a); } -/*******************************************************************\ - -Function: invariant_sett::modifies - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void invariant_sett::modifies(const exprt &lhs) { if(lhs.id()==ID_symbol || @@ -1411,18 +1056,6 @@ void invariant_sett::modifies(const exprt &lhs) throw "modifies: unexpected lhs: "+lhs.id_string(); } -/*******************************************************************\ - -Function: invariant_sett::assignment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void invariant_sett::assignment( const exprt &lhs, const exprt &rhs) @@ -1442,18 +1075,6 @@ void invariant_sett::assignment( strengthen(equality); } -/*******************************************************************\ - -Function: invariant_sett::apply_code - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void invariant_sett::apply_code(const codet &code) { const irep_idt &statement=code.get(ID_statement); @@ -1484,7 +1105,7 @@ void invariant_sett::apply_code(const codet &code) } else if(statement==ID_function_call) { - // may be a desaster + // may be a disaster make_true(); } else if(statement==ID_cpp_delete || @@ -1508,7 +1129,7 @@ void invariant_sett::apply_code(const codet &code) } else { - std::cerr << code.pretty() << std::endl; + std::cerr << code.pretty() << '\n'; throw "invariant_sett: unexpected statement: "+id2string(statement); } } diff --git a/src/analyses/invariant_set.h b/src/analyses/invariant_set.h index d5f0a31003c..b65ce7897f3 100644 --- a/src/analyses/invariant_set.h +++ b/src/analyses/invariant_set.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Value Set + #ifndef CPROVER_ANALYSES_INVARIANT_SET_H #define CPROVER_ANALYSES_INVARIANT_SET_H @@ -85,7 +88,7 @@ class invariant_sett ineq_sett ne_set; // bounds - typedef interval_template boundst; + typedef interval_templatet boundst; typedef std::map bounds_mapt; bounds_mapt bounds_map; @@ -95,9 +98,9 @@ class invariant_sett invariant_sett(): threaded(false), is_false(false), - value_sets(NULL), - object_store(NULL), - ns(NULL) + value_sets(nullptr), + object_store(nullptr), + ns(nullptr) { } @@ -105,7 +108,7 @@ class invariant_sett const irep_idt &identifier, std::ostream &out) const; - // true = added s.th. + // true = added something bool make_union(const invariant_sett &other_invariants); void strengthen(const exprt &expr); @@ -211,7 +214,7 @@ class invariant_sett void get_bounds(unsigned a, boundst &dest) const; - // true = added s.th. + // true = added something bool make_union_bounds_map(const bounds_mapt &other); void modifies(unsigned a); diff --git a/src/analyses/invariant_set_domain.cpp b/src/analyses/invariant_set_domain.cpp index 5f8512c55b5..3132591eb42 100644 --- a/src/analyses/invariant_set_domain.cpp +++ b/src/analyses/invariant_set_domain.cpp @@ -6,21 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Invariant Set Domain #include "invariant_set_domain.h" -/*******************************************************************\ - -Function: invariant_set_domaint::transform - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void invariant_set_domaint::transform( locationt from_l, diff --git a/src/analyses/invariant_set_domain.h b/src/analyses/invariant_set_domain.h index 2e231524cbb..4d38b6b2657 100644 --- a/src/analyses/invariant_set_domain.h +++ b/src/analyses/invariant_set_domain.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Value Set + #ifndef CPROVER_ANALYSES_INVARIANT_SET_DOMAIN_H #define CPROVER_ANALYSES_INVARIANT_SET_DOMAIN_H diff --git a/src/analyses/is_threaded.cpp b/src/analyses/is_threaded.cpp index 905cd6b91ac..1ac32d2341c 100644 --- a/src/analyses/is_threaded.cpp +++ b/src/analyses/is_threaded.cpp @@ -8,9 +8,13 @@ Date: October 2012 \*******************************************************************/ -#include "ai.h" +/// \file +/// Over-approximate Concurrency for Threaded Goto Programs + #include "is_threaded.h" +#include "ai.h" + class is_threaded_domaint:public ai_domain_baset { public: @@ -78,18 +82,6 @@ class is_threaded_domaint:public ai_domain_baset } }; -/*******************************************************************\ - -Function: is_threadedt::compute - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void is_threadedt::compute(const goto_functionst &goto_functions) { // the analysis doesn't actually use the namespace, fake one diff --git a/src/analyses/is_threaded.h b/src/analyses/is_threaded.h index 738857b8b8a..5a3823b867e 100644 --- a/src/analyses/is_threaded.h +++ b/src/analyses/is_threaded.h @@ -8,6 +8,9 @@ Date: October 2012 \*******************************************************************/ +/// \file +/// Over-approximate Concurrency for Threaded Goto Programs + #ifndef CPROVER_ANALYSES_IS_THREADED_H #define CPROVER_ANALYSES_IS_THREADED_H diff --git a/src/analyses/local_bitvector_analysis.cpp b/src/analyses/local_bitvector_analysis.cpp index 3fc0d10bb09..f48b34a760d 100644 --- a/src/analyses/local_bitvector_analysis.cpp +++ b/src/analyses/local_bitvector_analysis.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Field-insensitive, location-sensitive may-alias analysis + +#include "local_bitvector_analysis.h" + #include #include @@ -13,23 +18,9 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include +#include #include -#include "local_bitvector_analysis.h" - -/*******************************************************************\ - -Function: local_bitvector_analysist::flagst::print - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void local_bitvector_analysist::flagst::print(std::ostream &out) const { if(is_unknown()) @@ -50,18 +41,6 @@ void local_bitvector_analysist::flagst::print(std::ostream &out) const out << "+integer_address"; } -/*******************************************************************\ - -Function: local_bitvector_analysist::loc_infot::merge - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool local_bitvector_analysist::loc_infot::merge(const loc_infot &src) { bool result=false; @@ -78,19 +57,7 @@ bool local_bitvector_analysist::loc_infot::merge(const loc_infot &src) return result; } -/*******************************************************************\ - -Function: local_bitvector_analysist::is_tracked - - Inputs: - - Outputs: return 'true' iff we track the object with given - identifier - - Purpose: - -\*******************************************************************/ - +/// \return return 'true' iff we track the object with given identifier bool local_bitvector_analysist::is_tracked(const irep_idt &identifier) { localst::locals_mapt::const_iterator it=locals.locals_map.find(identifier); @@ -102,18 +69,6 @@ bool local_bitvector_analysist::is_tracked(const irep_idt &identifier) return true; } -/*******************************************************************\ - -Function: local_bitvector_analysist::assign_lhs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void local_bitvector_analysist::assign_lhs( const exprt &lhs, const exprt &rhs, @@ -154,18 +109,6 @@ void local_bitvector_analysist::assign_lhs( } } -/*******************************************************************\ - -Function: local_bitvector_analysist::get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - local_bitvector_analysist::flagst local_bitvector_analysist::get( const goto_programt::const_targett t, const exprt &rhs) @@ -179,18 +122,6 @@ local_bitvector_analysist::flagst local_bitvector_analysist::get( return get_rec(rhs, loc_info_src); } -/*******************************************************************\ - -Function: local_bitvector_analysist::get_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - local_bitvector_analysist::flagst local_bitvector_analysist::get_rec( const exprt &rhs, const loc_infot &loc_info_src) @@ -312,18 +243,6 @@ local_bitvector_analysist::flagst local_bitvector_analysist::get_rec( return flagst::mk_unknown(); } -/*******************************************************************\ - -Function: local_bitvector_analysist::build - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void local_bitvector_analysist::build(const goto_functiont &goto_function) { if(cfg.nodes.empty()) @@ -400,24 +319,13 @@ void local_bitvector_analysist::build(const goto_functiont &goto_function) for(const auto &succ : node.successors) { + assert(succ #include @@ -14,25 +19,11 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include +#include #include #endif -#include "local_cfg.h" - -/*******************************************************************\ - -Function: local_cfgt::build - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void local_cfgt::build(const goto_programt &goto_program) { nodes.resize(goto_program.instructions.size()); diff --git a/src/analyses/local_cfg.h b/src/analyses/local_cfg.h index a0187be8177..d2e53cfdab0 100644 --- a/src/analyses/local_cfg.h +++ b/src/analyses/local_cfg.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// CFG for One Function + #ifndef CPROVER_ANALYSES_LOCAL_CFG_H #define CPROVER_ANALYSES_LOCAL_CFG_H @@ -13,14 +16,6 @@ Author: Daniel Kroening, kroening@kroening.com #include -/*******************************************************************\ - - Class: local_cfgt - - Purpose: - -\*******************************************************************/ - class local_cfgt { public: diff --git a/src/analyses/local_may_alias.cpp b/src/analyses/local_may_alias.cpp index ffaefe73667..e1af3b4e883 100644 --- a/src/analyses/local_may_alias.cpp +++ b/src/analyses/local_may_alias.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Field-insensitive, location-sensitive may-alias analysis + +#include "local_may_alias.h" + #include #include @@ -13,23 +18,10 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include +#include #include -#include "local_may_alias.h" - -/*******************************************************************\ - -Function: local_may_aliast::loc_infot::merge - - Inputs: - - Outputs: return 'true' iff changed - - Purpose: - -\*******************************************************************/ - +/// \return return 'true' iff changed bool local_may_aliast::loc_infot::merge(const loc_infot &src) { bool changed=false; @@ -49,18 +41,6 @@ bool local_may_aliast::loc_infot::merge(const loc_infot &src) return changed; } -/*******************************************************************\ - -Function: local_may_aliast::assign_lhs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void local_may_aliast::assign_lhs( const exprt &lhs, const exprt &rhs, @@ -132,18 +112,6 @@ void local_may_aliast::assign_lhs( } } -/*******************************************************************\ - -Function: local_may_aliast::get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::set local_may_aliast::get( const goto_programt::const_targett t, const exprt &rhs) const @@ -170,18 +138,6 @@ std::set local_may_aliast::get( return result; } -/*******************************************************************\ - -Function: local_may_aliast::aliases - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool local_may_aliast::aliases( const goto_programt::const_targett t, const exprt &src1, const exprt &src2) const @@ -210,18 +166,6 @@ bool local_may_aliast::aliases( return !result.empty(); } -/*******************************************************************\ - -Function: local_may_aliast::get_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void local_may_aliast::get_rec( object_sett &dest, const exprt &rhs, @@ -369,18 +313,6 @@ void local_may_aliast::get_rec( dest.insert(unknown_object); } -/*******************************************************************\ - -Function: local_may_aliast::build - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void local_may_aliast::build(const goto_functiont &goto_function) { if(cfg.nodes.empty()) @@ -502,18 +434,6 @@ void local_may_aliast::build(const goto_functiont &goto_function) } } -/*******************************************************************\ - -Function: local_may_aliast::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void local_may_aliast::output( std::ostream &out, const goto_functiont &goto_function, diff --git a/src/analyses/local_may_alias.h b/src/analyses/local_may_alias.h index 109ca2b5e19..5e04ff01a75 100644 --- a/src/analyses/local_may_alias.h +++ b/src/analyses/local_may_alias.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Field-insensitive, location-sensitive may-alias analysis + #ifndef CPROVER_ANALYSES_LOCAL_MAY_ALIAS_H #define CPROVER_ANALYSES_LOCAL_MAY_ALIAS_H @@ -18,14 +21,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "dirty.h" #include "local_cfg.h" -/*******************************************************************\ - - Class: local_may_aliast - - Purpose: - -\*******************************************************************/ - class local_may_aliast { public: @@ -99,7 +94,7 @@ class local_may_aliast class local_may_alias_factoryt { public: - local_may_alias_factoryt():goto_functions(NULL) + local_may_alias_factoryt():goto_functions(nullptr) { } @@ -114,7 +109,7 @@ class local_may_alias_factoryt local_may_aliast &operator()(const irep_idt &fkt) { - assert(goto_functions!=NULL); + PRECONDITION(goto_functions!=nullptr); fkt_mapt::iterator f_it=fkt_map.find(fkt); if(f_it!=fkt_map.end()) return *f_it->second; diff --git a/src/analyses/locals.cpp b/src/analyses/locals.cpp index 7f30c1c008b..8d146f9713f 100644 --- a/src/analyses/locals.cpp +++ b/src/analyses/locals.cpp @@ -8,21 +8,12 @@ Date: March 2013 \*******************************************************************/ -#include +/// \file +/// Local variables #include "locals.h" -/*******************************************************************\ - -Function: localst::build - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void localst::build(const goto_functiont &goto_function) { @@ -39,18 +30,6 @@ void localst::build(const goto_functiont &goto_function) symbol_exprt(param.get_identifier(), param.type()); } -/*******************************************************************\ - -Function: localst::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void localst::output(std::ostream &out) const { for(const auto &local : locals_map) diff --git a/src/analyses/locals.h b/src/analyses/locals.h index 3cd52254c41..c9c59aaf340 100644 --- a/src/analyses/locals.h +++ b/src/analyses/locals.h @@ -8,6 +8,9 @@ Date: March 2013 \*******************************************************************/ +/// \file +/// Local variables whose address is taken + #ifndef CPROVER_ANALYSES_LOCALS_H #define CPROVER_ANALYSES_LOCALS_H diff --git a/src/analyses/natural_loops.cpp b/src/analyses/natural_loops.cpp index 593fc78006d..7101613e417 100644 --- a/src/analyses/natural_loops.cpp +++ b/src/analyses/natural_loops.cpp @@ -6,32 +6,23 @@ Author: Georg Weissenbacher, georg@weissenbacher.name \*******************************************************************/ -#include +/// \file +/// Dominators #include "natural_loops.h" -/*******************************************************************\ - -Function: show_natural_loops - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void show_natural_loops(const goto_functionst &goto_functions) { forall_goto_functions(it, goto_functions) { - std::cout << "*** " << it->first << std::endl; + std::cout << "*** " << it->first << '\n'; natural_loopst natural_loops; natural_loops(it->second.body); natural_loops.output(std::cout); - std::cout << std::endl; + std::cout << '\n'; } } diff --git a/src/analyses/natural_loops.h b/src/analyses/natural_loops.h index ff56c687c93..ce27a306882 100644 --- a/src/analyses/natural_loops.h +++ b/src/analyses/natural_loops.h @@ -6,6 +6,9 @@ Author: Georg Weissenbacher, georg@weissenbacher.name \*******************************************************************/ +/// \file +/// Compute natural loops in a goto_function + #ifndef CPROVER_ANALYSES_NATURAL_LOOPS_H #define CPROVER_ANALYSES_NATURAL_LOOPS_H @@ -69,18 +72,7 @@ typedef natural_loops_templatet void show_natural_loops(const goto_functionst &goto_functions); -/*******************************************************************\ - -Function: natural_loops_templatet::compute - - Inputs: - - Outputs: - - Purpose: Finds all back-edges and computes the natural loops - -\*******************************************************************/ - +/// Finds all back-edges and computes the natural loops #ifdef DEBUG #include #endif @@ -123,19 +115,7 @@ void natural_loops_templatet::compute(P &program) } } -/*******************************************************************\ - -Function: natural_loops_templatet::compute_natural_loop - - Inputs: - - Outputs: - - Purpose: Computes the natural loop for a given back-edge - (see Muchnick section 7.4) - -\*******************************************************************/ - +/// Computes the natural loop for a given back-edge (see Muchnick section 7.4) template void natural_loops_templatet::compute_natural_loop(T m, T n) { @@ -170,18 +150,7 @@ void natural_loops_templatet::compute_natural_loop(T m, T n) } } -/*******************************************************************\ - -Function: natural_loops_templatet::output - - Inputs: - - Outputs: - - Purpose: Print all natural loops that were found - -\*******************************************************************/ - +/// Print all natural loops that were found template void natural_loops_templatet::output(std::ostream &out) const { diff --git a/src/analyses/reaching_definitions.cpp b/src/analyses/reaching_definitions.cpp index 81c3c1c5069..89b31da543b 100644 --- a/src/analyses/reaching_definitions.cpp +++ b/src/analyses/reaching_definitions.cpp @@ -9,6 +9,12 @@ Date: February 2013 \*******************************************************************/ +/// \file +/// Range-based reaching definitions analysis (following Field- Sensitive +/// Program Dependence Analysis, Litvak et al., FSE 2010) + +#include "reaching_definitions.h" + #include #include @@ -17,20 +23,6 @@ Date: February 2013 #include "is_threaded.h" #include "dirty.h" -#include "reaching_definitions.h" - -/*******************************************************************\ - -Function: rd_range_domaint::populate_cache - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rd_range_domaint::populate_cache(const irep_idt &identifier) const { assert(bv_container); @@ -51,18 +43,6 @@ void rd_range_domaint::populate_cache(const irep_idt &identifier) const } } -/*******************************************************************\ - -Function: rd_range_domaint::transform - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rd_range_domaint::transform( locationt from, locationt to, @@ -71,7 +51,10 @@ void rd_range_domaint::transform( { reaching_definitions_analysist *rd= dynamic_cast(&ai); - assert(rd!=0); + INVARIANT_STRUCTURED( + rd!=nullptr, + bad_cast_exceptiont, + "ai has type reaching_definitions_analysist"); assert(bv_container); @@ -87,7 +70,7 @@ void rd_range_domaint::transform( // cleanup parameters else if(from->is_end_function()) transform_end_function(ns, from, to, *rd); - // lhs assignements + // lhs assignments else if(from->is_assign()) transform_assign(ns, from, from, *rd); // initial (non-deterministic) value @@ -129,18 +112,6 @@ void rd_range_domaint::transform( #endif } -/*******************************************************************\ - -Function: rd_range_domaint::transform_dead - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rd_range_domaint::transform_dead( const namespacet &ns, locationt from) @@ -157,18 +128,6 @@ void rd_range_domaint::transform_dead( } } -/*******************************************************************\ - -Function: rd_range_domaint::transform_start_thread - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rd_range_domaint::transform_start_thread( const namespacet &ns, reaching_definitions_analysist &rd) @@ -194,18 +153,6 @@ void rd_range_domaint::transform_start_thread( } } -/*******************************************************************\ - -Function: rd_range_domaint::transform_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rd_range_domaint::transform_function_call( const namespacet &ns, locationt from, @@ -269,18 +216,6 @@ void rd_range_domaint::transform_function_call( } } -/*******************************************************************\ - -Function: rd_range_domaint::transform_end_function - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rd_range_domaint::transform_end_function( const namespacet &ns, locationt from, @@ -349,18 +284,6 @@ void rd_range_domaint::transform_end_function( } } -/*******************************************************************\ - -Function: rd_range_domaint::transform_assign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rd_range_domaint::transform_assign( const namespacet &ns, locationt from, @@ -378,7 +301,10 @@ void rd_range_domaint::transform_assign( const symbolt *symbol_ptr; if(ns.lookup(identifier, symbol_ptr)) continue; - assert(symbol_ptr!=0); + INVARIANT_STRUCTURED( + symbol_ptr!=nullptr, + nullptr_exceptiont, + "Symbol is in symbol table"); const range_domaint &ranges=rw_set.get_ranges(it); @@ -394,18 +320,6 @@ void rd_range_domaint::transform_assign( } } -/*******************************************************************\ - -Function: rd_range_domaint::kill - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rd_range_domaint::kill( const irep_idt &identifier, const range_spect &range_start, @@ -506,18 +420,6 @@ void rd_range_domaint::kill( } } -/*******************************************************************\ - -Function: rd_range_domaint::kill_inf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rd_range_domaint::kill_inf( const irep_idt &identifier, const range_spect &range_start) @@ -552,18 +454,6 @@ void rd_range_domaint::kill_inf( #endif } -/*******************************************************************\ - -Function: rd_range_domaint::gen - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool rd_range_domaint::gen( locationt from, const irep_idt &identifier, @@ -636,21 +526,9 @@ bool rd_range_domaint::gen( return true; } -/*******************************************************************\ - -Function: rd_range_domaint::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rd_range_domaint::output(std::ostream &out) const { - out << "Reaching definitions:" << std::endl; + out << "Reaching definitions:\n"; if(has_values.is_known()) { @@ -681,24 +559,13 @@ void rd_range_domaint::output(std::ostream &out) const out << "@" << itl->first->location_number; } - out << "]" << std::endl; + out << "]\n"; clear_cache(identifier); } } -/*******************************************************************\ - -Function: rd_range_domaint::merge_inner - - Inputs: - - Outputs: returns true iff there is s.th. new - - Purpose: - -\*******************************************************************/ - +/// \return returns true iff there is something new bool rd_range_domaint::merge_inner( values_innert &dest, const values_innert &other) @@ -749,18 +616,7 @@ bool rd_range_domaint::merge_inner( return more; } -/*******************************************************************\ - -Function: rd_range_domaint::merge - - Inputs: - - Outputs: returns true iff there is s.th. new - - Purpose: - -\*******************************************************************/ - +/// \return returns true iff there is something new bool rd_range_domaint::merge( const rd_range_domaint &other, locationt from, @@ -796,18 +652,7 @@ bool rd_range_domaint::merge( return changed; } -/*******************************************************************\ - -Function: rd_range_domaint::merge_shared - - Inputs: - - Outputs: returns true iff there is s.th. new - - Purpose: - -\*******************************************************************/ - +/// \return returns true iff there is something new bool rd_range_domaint::merge_shared( const rd_range_domaint &other, goto_programt::const_targett from, @@ -857,18 +702,6 @@ bool rd_range_domaint::merge_shared( return changed; } -/*******************************************************************\ - -Function: rd_range_domaint::get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const rd_range_domaint::ranges_at_loct &rd_range_domaint::get( const irep_idt &identifier) const { @@ -884,18 +717,6 @@ const rd_range_domaint::ranges_at_loct &rd_range_domaint::get( return entry->second; } -/*******************************************************************\ - -Function: reaching_definitions_analysist::~reaching_definitions_analysist - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - reaching_definitions_analysist::~reaching_definitions_analysist() { if(is_dirty) @@ -906,18 +727,6 @@ reaching_definitions_analysist::~reaching_definitions_analysist() delete value_sets; } -/*******************************************************************\ - -Function: reaching_definitions_analysist::initialize - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void reaching_definitions_analysist::initialize( const goto_functionst &goto_functions) { diff --git a/src/analyses/reaching_definitions.h b/src/analyses/reaching_definitions.h index a48a271a9a6..21cbd1ed377 100644 --- a/src/analyses/reaching_definitions.h +++ b/src/analyses/reaching_definitions.h @@ -9,9 +9,14 @@ Date: February 2013 \*******************************************************************/ +/// \file +/// Range-based reaching definitions analysis (following Field- Sensitive +/// Program Dependence Analysis, Litvak et al., FSE 2010) + #ifndef CPROVER_ANALYSES_REACHING_DEFINITIONS_H #define CPROVER_ANALYSES_REACHING_DEFINITIONS_H +#include #include #include "ai.h" @@ -98,7 +103,7 @@ class rd_range_domaint:public ai_domain_baset rd_range_domaint(): ai_domain_baset(), has_values(false), - bv_container(0) + bv_container(nullptr) { } @@ -143,7 +148,7 @@ class rd_range_domaint:public ai_domain_baset make_top(); } - // returns true iff there is s.th. new + // returns true iff there is something new bool merge( const rd_range_domaint &other, locationt from, @@ -239,9 +244,9 @@ class reaching_definitions_analysist: explicit reaching_definitions_analysist(const namespacet &_ns): concurrency_aware_ait(), ns(_ns), - value_sets(0), - is_threaded(0), - is_dirty(0) + value_sets(nullptr), + is_threaded(nullptr), + is_dirty(nullptr) { } @@ -255,7 +260,10 @@ class reaching_definitions_analysist: statet &s=concurrency_aware_ait::get_state(l); rd_range_domaint *rd_state=dynamic_cast(&s); - assert(rd_state!=0); + INVARIANT_STRUCTURED( + rd_state!=nullptr, + bad_cast_exceptiont, + "rd_state has type rd_range_domaint"); rd_state->set_bitvector_container(*this); diff --git a/src/analyses/replace_symbol_ext.cpp b/src/analyses/replace_symbol_ext.cpp index 568ea45e090..18e0474629b 100644 --- a/src/analyses/replace_symbol_ext.cpp +++ b/src/analyses/replace_symbol_ext.cpp @@ -6,23 +6,15 @@ Author: Peter Schrammel \*******************************************************************/ -#include -#include +/// \file +/// Modified expression replacement for constant propagator #include "replace_symbol_ext.h" -/*******************************************************************\ - -Function: replace_symbol_extt::replace - - Inputs: - - Outputs: - - Purpose: does not replace object in address_of expressions - -\*******************************************************************/ +#include +#include +/// does not replace object in address_of expressions bool replace_symbol_extt::replace(exprt &dest) const { bool result=true; diff --git a/src/analyses/replace_symbol_ext.h b/src/analyses/replace_symbol_ext.h index 5a2152db17f..05d7226be40 100644 --- a/src/analyses/replace_symbol_ext.h +++ b/src/analyses/replace_symbol_ext.h @@ -6,6 +6,9 @@ Author: Peter Schrammel \*******************************************************************/ +/// \file +/// Modified expression replacement for constant propagator + #ifndef CPROVER_ANALYSES_REPLACE_SYMBOL_EXT_H #define CPROVER_ANALYSES_REPLACE_SYMBOL_EXT_H diff --git a/src/analyses/static_analysis.cpp b/src/analyses/static_analysis.cpp index d76a888c769..acd7f5e19f8 100644 --- a/src/analyses/static_analysis.cpp +++ b/src/analyses/static_analysis.cpp @@ -6,6 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Value Set Propagation + +#define USE_DEPRECATED_STATIC_ANALYSIS_H +#include "static_analysis.h" + #include #include @@ -14,21 +20,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "is_threaded.h" -#define USE_DEPRECATED_STATIC_ANALYSIS_H -#include "static_analysis.h" - -/*******************************************************************\ - -Function: static_analysis_baset::get_guard - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt static_analysis_baset::get_guard( locationt from, locationt to) @@ -49,18 +40,6 @@ exprt static_analysis_baset::get_guard( return from->guard; } -/*******************************************************************\ - -Function: static_analysis_baset::get_return_lhs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt static_analysis_baset::get_return_lhs(locationt to) { // get predecessor of "to" @@ -79,18 +58,6 @@ exprt static_analysis_baset::get_return_lhs(locationt to) return code.lhs(); } -/*******************************************************************\ - -Function: static_analysis_baset::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void static_analysis_baset::operator()( const goto_functionst &goto_functions) { @@ -98,18 +65,6 @@ void static_analysis_baset::operator()( fixedpoint(goto_functions); } -/*******************************************************************\ - -Function: static_analysis_baset::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void static_analysis_baset::operator()( const goto_programt &goto_program) { @@ -118,18 +73,6 @@ void static_analysis_baset::operator()( fixedpoint(goto_program, goto_functions); } -/*******************************************************************\ - -Function: static_analysis_baset::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void static_analysis_baset::output( const goto_functionst &goto_functions, std::ostream &out) const @@ -148,18 +91,6 @@ void static_analysis_baset::output( } } -/*******************************************************************\ - -Function: static_analysis_baset::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void static_analysis_baset::output( const goto_programt &goto_program, const irep_idt &identifier, @@ -179,18 +110,6 @@ void static_analysis_baset::output( } } -/*******************************************************************\ - -Function: static_analysis_baset::generate_states - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void static_analysis_baset::generate_states( const goto_functionst &goto_functions) { @@ -198,18 +117,6 @@ void static_analysis_baset::generate_states( generate_states(f_it->second.body); } -/*******************************************************************\ - -Function: static_analysis_baset::generate_states - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void static_analysis_baset::generate_states( const goto_programt &goto_program) { @@ -217,18 +124,6 @@ void static_analysis_baset::generate_states( generate_state(i_it); } -/*******************************************************************\ - -Function: static_analysis_baset::update - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void static_analysis_baset::update( const goto_functionst &goto_functions) { @@ -236,18 +131,6 @@ void static_analysis_baset::update( update(f_it->second.body); } -/*******************************************************************\ - -Function: static_analysis_baset::generate_states - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void static_analysis_baset::update( const goto_programt &goto_program) { @@ -270,18 +153,6 @@ void static_analysis_baset::update( } } -/*******************************************************************\ - -Function: static_analysis_baset::get_next - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static_analysis_baset::locationt static_analysis_baset::get_next( working_sett &working_set) { @@ -294,18 +165,6 @@ static_analysis_baset::locationt static_analysis_baset::get_next( return l; } -/*******************************************************************\ - -Function: static_analysis_baset::fixedpoint - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool static_analysis_baset::fixedpoint( const goto_programt &goto_program, const goto_functionst &goto_functions) @@ -333,18 +192,6 @@ bool static_analysis_baset::fixedpoint( return new_data; } -/*******************************************************************\ - -Function: static_analysis_baset::visit - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool static_analysis_baset::visit( locationt l, working_sett &working_set, @@ -398,18 +245,6 @@ bool static_analysis_baset::visit( return new_data; } -/*******************************************************************\ - -Function: static_analysis_baset::do_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void static_analysis_baset::do_function_call( locationt l_call, locationt l_return, const goto_functionst &goto_functions, @@ -486,18 +321,6 @@ void static_analysis_baset::do_function_call( } } -/*******************************************************************\ - -Function: static_analysis_baset::do_function_call_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void static_analysis_baset::do_function_call_rec( locationt l_call, locationt l_return, const exprt &function, @@ -617,18 +440,6 @@ void static_analysis_baset::do_function_call_rec( } } -/*******************************************************************\ - -Function: static_analysis_baset::sequential_fixedpoint - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void static_analysis_baset::sequential_fixedpoint( const goto_functionst &goto_functions) { @@ -639,18 +450,6 @@ void static_analysis_baset::sequential_fixedpoint( fixedpoint(it->second.body, goto_functions); } -/*******************************************************************\ - -Function: static_analysis_baset::concurrent_fixedpoint - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void static_analysis_baset::concurrent_fixedpoint( const goto_functionst &goto_functions) { diff --git a/src/analyses/static_analysis.h b/src/analyses/static_analysis.h index 5e3e5c7688a..ed54cf783af 100644 --- a/src/analyses/static_analysis.h +++ b/src/analyses/static_analysis.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Static Analysis + #ifndef CPROVER_ANALYSES_STATIC_ANALYSIS_H #define CPROVER_ANALYSES_STATIC_ANALYSIS_H @@ -189,7 +192,7 @@ class static_analysis_baset std::pair(l->location_number, l)); } - // true = found s.th. new + // true = found something new bool fixedpoint( const goto_programt &goto_program, const goto_functionst &goto_functions); @@ -202,7 +205,7 @@ class static_analysis_baset void concurrent_fixedpoint( const goto_functionst &goto_functions); - // true = found s.th. new + // true = found something new bool visit( locationt l, working_sett &working_set, diff --git a/src/analyses/uninitialized_domain.cpp b/src/analyses/uninitialized_domain.cpp index 8a6e8dd52a5..48830ed204e 100644 --- a/src/analyses/uninitialized_domain.cpp +++ b/src/analyses/uninitialized_domain.cpp @@ -8,22 +8,13 @@ Date: January 2010 \*******************************************************************/ -#include -#include +/// \file +/// Detection for Uninitialized Local Variables #include "uninitialized_domain.h" -/*******************************************************************\ - -Function: uninitialized_domaint::transform - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include void uninitialized_domaint::transform( locationt from, @@ -60,18 +51,6 @@ void uninitialized_domaint::transform( } } -/*******************************************************************\ - -Function: uninitialized_domaint::assign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void uninitialized_domaint::assign(const exprt &lhs) { if(lhs.id()==ID_index) @@ -82,18 +61,6 @@ void uninitialized_domaint::assign(const exprt &lhs) uninitialized.erase(to_symbol_expr(lhs).get_identifier()); } -/*******************************************************************\ - -Function: uninitialized_domaint::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void uninitialized_domaint::output( std::ostream &out, const ai_baset &ai, @@ -108,18 +75,7 @@ void uninitialized_domaint::output( } } -/*******************************************************************\ - -Function: uninitialized_domaint::merge - - Inputs: - - Outputs: returns true iff there is s.th. new - - Purpose: - -\*******************************************************************/ - +/// \return returns true iff there is something new bool uninitialized_domaint::merge( const uninitialized_domaint &other, locationt from, diff --git a/src/analyses/uninitialized_domain.h b/src/analyses/uninitialized_domain.h index 6ca27f341b0..11dcaa02170 100644 --- a/src/analyses/uninitialized_domain.h +++ b/src/analyses/uninitialized_domain.h @@ -8,6 +8,9 @@ Date: January 2010 \*******************************************************************/ +/// \file +/// Detection for Uninitialized Local Variables + #ifndef CPROVER_ANALYSES_UNINITIALIZED_DOMAIN_H #define CPROVER_ANALYSES_UNINITIALIZED_DOMAIN_H @@ -54,7 +57,7 @@ class uninitialized_domaint:public ai_domain_baset make_top(); } - // returns true iff there is s.th. new + // returns true iff there is something new bool merge( const uninitialized_domaint &other, locationt from, diff --git a/src/ansi-c/Makefile b/src/ansi-c/Makefile index cfee8e68f07..90bdd1e6a56 100644 --- a/src/ansi-c/Makefile +++ b/src/ansi-c/Makefile @@ -24,7 +24,6 @@ SRC = anonymous_member.cpp \ c_typecheck_initializer.cpp \ c_typecheck_type.cpp \ c_typecheck_typecast.cpp \ - c_types.cpp \ cprover_library.cpp \ designator.cpp \ expr2c.cpp \ @@ -55,7 +54,11 @@ CLEANFILES = ansi-c$(LIBEXT) \ arm_builtin_headers.inc cw_builtin_headers.inc \ gcc_builtin_headers_arm.inc gcc_builtin_headers_alpha.inc \ gcc_builtin_headers_mips.inc gcc_builtin_headers_power.inc \ - clang_builtin_headers.inc gcc_builtin_headers_ia32-2.inc + clang_builtin_headers.inc gcc_builtin_headers_ia32-2.inc \ + gcc_builtin_headers_math.inc gcc_builtin_headers_omp.inc \ + gcc_builtin_headers_tm.inc gcc_builtin_headers_ubsan.inc \ + gcc_builtin_headers_mem_string.inc \ + gcc_builtin_headers_ia32-3.inc gcc_builtin_headers_ia32-4.inc all: ansi-c$(LIBEXT) @@ -116,10 +119,17 @@ cprover_library.cpp: cprover_library.inc ansi_c_internal_additions$(OBJEXT): gcc_builtin_headers_generic.inc ansi_c_internal_additions$(OBJEXT): gcc_builtin_headers_ia32.inc ansi_c_internal_additions$(OBJEXT): gcc_builtin_headers_ia32-2.inc +ansi_c_internal_additions$(OBJEXT): gcc_builtin_headers_ia32-3.inc +ansi_c_internal_additions$(OBJEXT): gcc_builtin_headers_ia32-4.inc ansi_c_internal_additions$(OBJEXT): gcc_builtin_headers_alpha.inc ansi_c_internal_additions$(OBJEXT): gcc_builtin_headers_arm.inc +ansi_c_internal_additions$(OBJEXT): gcc_builtin_headers_math.inc +ansi_c_internal_additions$(OBJEXT): gcc_builtin_headers_mem_string.inc ansi_c_internal_additions$(OBJEXT): gcc_builtin_headers_mips.inc +ansi_c_internal_additions$(OBJEXT): gcc_builtin_headers_omp.inc ansi_c_internal_additions$(OBJEXT): gcc_builtin_headers_power.inc +ansi_c_internal_additions$(OBJEXT): gcc_builtin_headers_tm.inc +ansi_c_internal_additions$(OBJEXT): gcc_builtin_headers_ubsan.inc ansi_c_internal_additions$(OBJEXT): arm_builtin_headers.inc ansi_c_internal_additions$(OBJEXT): cw_builtin_headers.inc ansi_c_internal_additions$(OBJEXT): clang_builtin_headers.inc @@ -129,7 +139,11 @@ generated_files: cprover_library.inc gcc_builtin_headers_generic.inc \ gcc_builtin_headers_arm.inc gcc_builtin_headers_mips.inc \ gcc_builtin_headers_power.inc arm_builtin_headers.inc \ cw_builtin_headers.inc ansi_c_y.tab.cpp ansi_c_lex.yy.cpp \ - ansi_c_y.tab.h clang_builtin_headers.inc gcc_builtin_headers_ia32-2.inc + ansi_c_y.tab.h clang_builtin_headers.inc gcc_builtin_headers_ia32-2.inc \ + gcc_builtin_headers_math.inc gcc_builtin_headers_omp.inc \ + gcc_builtin_headers_tm.inc gcc_builtin_headers_ubsan.inc \ + gcc_builtin_headers_mem_string.inc \ + gcc_builtin_headers_ia32-3.inc gcc_builtin_headers_ia32-4.inc ############################################################################### diff --git a/src/ansi-c/anonymous_member.cpp b/src/ansi-c/anonymous_member.cpp index adaff8d4680..524d725dd9c 100644 --- a/src/ansi-c/anonymous_member.cpp +++ b/src/ansi-c/anonymous_member.cpp @@ -6,22 +6,13 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include -#include +/// \file +/// ANSI-C Language Type Checking #include "anonymous_member.h" -/*******************************************************************\ - -Function: make_member_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include static exprt make_member_expr( const exprt &struct_union, @@ -46,18 +37,6 @@ static exprt make_member_expr( return result; } -/*******************************************************************\ - -Function: get_component_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt get_component_rec( const exprt &struct_union, const irep_idt &component_name, @@ -90,18 +69,6 @@ exprt get_component_rec( return nil_exprt(); } -/*******************************************************************\ - -Function: has_component_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool has_component_rec( const typet &type, const irep_idt &component_name, diff --git a/src/ansi-c/anonymous_member.h b/src/ansi-c/anonymous_member.h index d9b00394b6f..3c58ad70efb 100644 --- a/src/ansi-c/anonymous_member.h +++ b/src/ansi-c/anonymous_member.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// C Language Type Checking + #ifndef CPROVER_ANSI_C_ANONYMOUS_MEMBER_H #define CPROVER_ANSI_C_ANONYMOUS_MEMBER_H diff --git a/src/ansi-c/ansi_c_convert_type.cpp b/src/ansi-c/ansi_c_convert_type.cpp index 7dc6f2165cf..23be0fdb935 100644 --- a/src/ansi-c/ansi_c_convert_type.cpp +++ b/src/ansi-c/ansi_c_convert_type.cpp @@ -6,28 +6,20 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// SpecC Language Conversion + +#include "ansi_c_convert_type.h" + #include +#include #include #include #include #include #include -#include "ansi_c_convert_type.h" - -/*******************************************************************\ - -Function: ansi_c_convert_typet::convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ansi_c_convert_typet::read(const typet &type) { clear(); @@ -35,18 +27,6 @@ void ansi_c_convert_typet::read(const typet &type) read_rec(type); } -/*******************************************************************\ - -Function: ansi_c_convert_typet::read_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ansi_c_convert_typet::read_rec(const typet &type) { if(type.id()==ID_merged_type) @@ -240,18 +220,6 @@ void ansi_c_convert_typet::read_rec(const typet &type) other.push_back(type); } -/*******************************************************************\ - -Function: ansi_c_convert_typet::write - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ansi_c_convert_typet::write(typet &type) { type.clear(); @@ -271,6 +239,15 @@ void ansi_c_convert_typet::write(typet &type) throw 0; } + // asm blocks (cf. regression/ansi-c/asm1) - ignore the asm + if(other.size()==2) + { + if(other.front().id()==ID_asm && other.back().id()==ID_empty) + other.pop_front(); + else if(other.front().id()==ID_empty && other.back().id()==ID_asm) + other.pop_back(); + } + if(other.size()!=1) { error().source_location=source_location; @@ -463,14 +440,25 @@ void ansi_c_convert_typet::write(typet &type) } if(int8_cnt) - type=is_signed?signed_char_type():unsigned_char_type(); + if(is_signed) + type=signed_char_type(); + else + type=unsigned_char_type(); else if(int16_cnt) - type=is_signed?signed_short_int_type():unsigned_short_int_type(); + if(is_signed) + type=signed_short_int_type(); + else + type=unsigned_short_int_type(); else if(int32_cnt) - type=is_signed?signed_int_type():unsigned_int_type(); + if(is_signed) + type=signed_int_type(); + else + type=unsigned_int_type(); else if(int64_cnt) // Visual Studio: equivalent to long long int - type= - is_signed?signed_long_long_int_type():unsigned_long_long_int_type(); + if(is_signed) + type=signed_long_long_int_type(); + else + type=unsigned_long_long_int_type(); else assert(false); } @@ -508,19 +496,31 @@ void ansi_c_convert_typet::write(typet &type) throw 0; } - type=is_signed?signed_short_int_type():unsigned_short_int_type(); + if(is_signed) + type=signed_short_int_type(); + else + type=unsigned_short_int_type(); } else if(long_cnt==0) { - type=is_signed?signed_int_type():unsigned_int_type(); + if(is_signed) + type=signed_int_type(); + else + type=unsigned_int_type(); } else if(long_cnt==1) { - type=is_signed?signed_long_int_type():unsigned_long_int_type(); + if(is_signed) + type=signed_long_int_type(); + else + type=unsigned_long_int_type(); } else if(long_cnt==2) { - type=is_signed?signed_long_long_int_type():unsigned_long_long_int_type(); + if(is_signed) + type=signed_long_long_int_type(); + else + type=unsigned_long_long_int_type(); } else { diff --git a/src/ansi-c/ansi_c_convert_type.h b/src/ansi-c/ansi_c_convert_type.h index 0fef20b4928..47c6c70564b 100644 --- a/src/ansi-c/ansi_c_convert_type.h +++ b/src/ansi-c/ansi_c_convert_type.h @@ -6,12 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// ANSI-C Language Conversion + #ifndef CPROVER_ANSI_C_ANSI_C_CONVERT_TYPE_H #define CPROVER_ANSI_C_ANSI_C_CONVERT_TYPE_H #include -#include "c_types.h" #include "c_qualifiers.h" #include "c_storage_spec.h" @@ -51,6 +53,7 @@ class ansi_c_convert_typet:public messaget explicit ansi_c_convert_typet(message_handlert &_message_handler): messaget(_message_handler) + // class members are initialized by calling read() { } diff --git a/src/ansi-c/ansi_c_declaration.cpp b/src/ansi-c/ansi_c_declaration.cpp index 7f9d0980583..00beb3a92cf 100644 --- a/src/ansi-c/ansi_c_declaration.cpp +++ b/src/ansi-c/ansi_c_declaration.cpp @@ -6,26 +6,17 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// ANSI-C Language Type Checking + +#include "ansi_c_declaration.h" + #include #include #include #include -#include "ansi_c_declaration.h" - -/*******************************************************************\ - -Function: ansi_c_declaratort::build - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ansi_c_declaratort::build(irept &src) { typet *p=static_cast(&src); @@ -42,7 +33,7 @@ void ansi_c_declaratort::build(irept &src) t.make_nil(); break; } - else if(t.id()==irep_idt() || + else if(t.id().empty() || t.is_nil()) { assert(0); @@ -66,18 +57,6 @@ void ansi_c_declaratort::build(irept &src) value().make_nil(); } -/*******************************************************************\ - -Function: ansi_c_declarationt::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ansi_c_declarationt::output(std::ostream &out) const { out << "Flags:"; @@ -109,18 +88,6 @@ void ansi_c_declarationt::output(std::ostream &out) const out << "Declarator: " << declarator.pretty() << "\n"; } -/*******************************************************************\ - -Function: ansi_c_declarationt::full_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet ansi_c_declarationt::full_type( const ansi_c_declaratort &declarator) const { @@ -153,18 +120,6 @@ typet ansi_c_declarationt::full_type( return result; } -/*******************************************************************\ - -Function: ansi_c_declarationt::to_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ansi_c_declarationt::to_symbol( const ansi_c_declaratort &declarator, symbolt &symbol) const @@ -173,6 +128,7 @@ void ansi_c_declarationt::to_symbol( symbol.value=declarator.value(); symbol.type=full_type(declarator); symbol.name=declarator.get_name(); + symbol.pretty_name=symbol.name; symbol.base_name=declarator.get_base_name(); symbol.is_type=get_is_typedef(); symbol.location=declarator.source_location(); diff --git a/src/ansi-c/ansi_c_declaration.h b/src/ansi-c/ansi_c_declaration.h index 3143c2090a5..af5db98e32e 100644 --- a/src/ansi-c/ansi_c_declaration.h +++ b/src/ansi-c/ansi_c_declaration.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// ANSI-CC Language Type Checking + #ifndef CPROVER_ANSI_C_ANSI_C_DECLARATION_H #define CPROVER_ANSI_C_ANSI_C_DECLARATION_H diff --git a/src/ansi-c/ansi_c_entry_point.cpp b/src/ansi-c/ansi_c_entry_point.cpp index ecb2dcc73cd..b22896bd7f7 100644 --- a/src/ansi-c/ansi_c_entry_point.cpp +++ b/src/ansi-c/ansi_c_entry_point.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "ansi_c_entry_point.h" + #include #include @@ -17,27 +19,14 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include +#include #include #include #include -#include "ansi_c_entry_point.h" #include "c_nondet_symbol_factory.h" -/*******************************************************************\ - -Function: build_function_environment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt::operandst build_function_environment( const code_typet::parameterst ¶meters, code_blockt &init_code, @@ -68,18 +57,6 @@ exprt::operandst build_function_environment( return main_arguments; } -/*******************************************************************\ - -Function: record_function_outputs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void record_function_outputs( const symbolt &function, code_blockt &init_code, @@ -141,18 +118,6 @@ void record_function_outputs( #endif } -/*******************************************************************\ - -Function: ansi_c_entry_point - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool ansi_c_entry_point( symbol_tablet &symbol_table, const std::string &standard_main, @@ -362,16 +327,13 @@ bool ansi_c_entry_point( zero_string.type().set(ID_size, "infinity"); exprt index(ID_index, char_type()); index.copy_to_operands(zero_string, from_integer(0, uint_type())); - exprt address_of("address_of", pointer_typet()); - address_of.type().subtype()=char_type(); - address_of.copy_to_operands(index); + exprt address_of=address_of_exprt(index, pointer_type(char_type())); if(argv_symbol.type.subtype()!=address_of.type()) address_of.make_typecast(argv_symbol.type.subtype()); // assign argv[*] to the address of a string-object - exprt array_of("array_of", argv_symbol.type); - array_of.copy_to_operands(address_of); + array_of_exprt array_of(address_of, argv_symbol.type); init_code.copy_to_operands( code_assignt(argv_symbol.symbol_expr(), array_of)); @@ -435,17 +397,18 @@ bool ansi_c_entry_point( { const exprt &arg1=parameters[1]; + const pointer_typet &pointer_type= + to_pointer_type(arg1.type()); - exprt index_expr(ID_index, arg1.type().subtype()); - index_expr.copy_to_operands( + index_exprt index_expr( argv_symbol.symbol_expr(), - from_integer(0, index_type())); + from_integer(0, index_type()), + pointer_type.subtype()); // disable bounds check on that one index_expr.set("bounds_check", false); - op1=exprt(ID_address_of, arg1.type()); - op1.move_to_operands(index_expr); + op1=address_of_exprt(index_expr, pointer_type); } // do we need envp? @@ -455,13 +418,15 @@ bool ansi_c_entry_point( exprt &op2=operands[2]; const exprt &arg2=parameters[2]; + const pointer_typet &pointer_type= + to_pointer_type(arg2.type()); - exprt index_expr(ID_index, arg2.type().subtype()); - index_expr.copy_to_operands( - envp_symbol.symbol_expr(), from_integer(0, index_type())); + index_exprt index_expr( + envp_symbol.symbol_expr(), + from_integer(0, index_type()), + pointer_type.subtype()); - op2=exprt(ID_address_of, arg2.type()); - op2.move_to_operands(index_expr); + op2=address_of_exprt(index_expr, pointer_type); } } } diff --git a/src/ansi-c/ansi_c_entry_point.h b/src/ansi-c/ansi_c_entry_point.h index 07d09ae2d44..835dd31845d 100644 --- a/src/ansi-c/ansi_c_entry_point.h +++ b/src/ansi-c/ansi_c_entry_point.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_ANSI_C_ANSI_C_ENTRY_POINT_H #define CPROVER_ANSI_C_ANSI_C_ENTRY_POINT_H diff --git a/src/ansi-c/ansi_c_internal_additions.cpp b/src/ansi-c/ansi_c_internal_additions.cpp index eb564038e2e..aa1d82e0102 100644 --- a/src/ansi-c/ansi_c_internal_additions.cpp +++ b/src/ansi-c/ansi_c_internal_additions.cpp @@ -6,15 +6,40 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "ansi_c_internal_additions.h" +#include + const char gcc_builtin_headers_generic[]= "# 1 \"gcc_builtin_headers_generic.h\"\n" #include "gcc_builtin_headers_generic.inc" ; // NOLINT(whitespace/semicolon) +const char gcc_builtin_headers_math[]= +"# 1 \"gcc_builtin_headers_math.h\"\n" +#include "gcc_builtin_headers_math.inc" +; // NOLINT(whitespace/semicolon) + +const char gcc_builtin_headers_mem_string[]= +"# 1 \"gcc_builtin_headers_mem_string.h\"\n" +#include "gcc_builtin_headers_mem_string.inc" +; // NOLINT(whitespace/semicolon) + +const char gcc_builtin_headers_omp[]= +"# 1 \"gcc_builtin_headers_omp.h\"\n" +#include "gcc_builtin_headers_omp.inc" +; // NOLINT(whitespace/semicolon) + +const char gcc_builtin_headers_tm[]= +"# 1 \"gcc_builtin_headers_tm.h\"\n" +#include "gcc_builtin_headers_tm.inc" +; // NOLINT(whitespace/semicolon) + +const char gcc_builtin_headers_ubsan[]= +"# 1 \"gcc_builtin_headers_ubsan.h\"\n" +#include "gcc_builtin_headers_ubsan.inc" +; // NOLINT(whitespace/semicolon) + const char gcc_builtin_headers_ia32[]= "# 1 \"gcc_builtin_headers_ia32.h\"\n" #include "gcc_builtin_headers_ia32.inc" @@ -22,6 +47,12 @@ const char gcc_builtin_headers_ia32[]= const char gcc_builtin_headers_ia32_2[]= #include "gcc_builtin_headers_ia32-2.inc" ; // NOLINT(whitespace/semicolon) +const char gcc_builtin_headers_ia32_3[]= +#include "gcc_builtin_headers_ia32-3.inc" +; // NOLINT(whitespace/semicolon) +const char gcc_builtin_headers_ia32_4[]= +#include "gcc_builtin_headers_ia32-4.inc" +; // NOLINT(whitespace/semicolon) const char gcc_builtin_headers_alpha[]= "# 1 \"gcc_builtin_headers_alpha.h\"\n" @@ -58,18 +89,6 @@ const char clang_builtin_headers[]= #include "clang_builtin_headers.inc" ; // NOLINT(whitespace/semicolon) -/*******************************************************************\ - -Function: architecture_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static std::string architecture_string(const std::string &value, const char *s) { return std::string("const char *__CPROVER_architecture_")+ @@ -77,18 +96,6 @@ static std::string architecture_string(const std::string &value, const char *s) "=\""+value+"\";\n"; } -/*******************************************************************\ - -Function: architecture_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static std::string architecture_string(int value, const char *s) { return std::string("const int __CPROVER_architecture_")+ @@ -96,18 +103,6 @@ static std::string architecture_string(int value, const char *s) "="+std::to_string(value)+";\n"; } -/*******************************************************************\ - -Function: ansi_c_internal_additions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ansi_c_internal_additions(std::string &code) { code+= @@ -158,6 +153,8 @@ void ansi_c_internal_additions(std::string &code) "signed __CPROVER_POINTER_OFFSET(const void *p);\n" "__CPROVER_bool __CPROVER_DYNAMIC_OBJECT(const void *p);\n" "extern unsigned char __CPROVER_memory[__CPROVER_constant_infinity_uint];\n" + // NOLINTNEXTLINE(whitespace/line_length) + "void __CPROVER_allocated_memory(__CPROVER_size_t address, __CPROVER_size_t extent);\n" // malloc "void *__CPROVER_malloc(__CPROVER_size_t size);\n" @@ -199,6 +196,18 @@ void ansi_c_internal_additions(std::string &code) "long double __CPROVER_infl(void);\n" "int __CPROVER_thread_local __CPROVER_rounding_mode="+ std::to_string(config.ansi_c.rounding_mode)+";\n" + "int __CPROVER_isgreaterf(float f, float g);\n" + "int __CPROVER_isgreaterd(double f, double g);\n" + "int __CPROVER_isgreaterequalf(float f, float g);\n" + "int __CPROVER_isgreaterequald(double f, double g);\n" + "int __CPROVER_islessf(float f, float g);\n" + "int __CPROVER_islessd(double f, double g);\n" + "int __CPROVER_islessequalf(float f, float g);\n" + "int __CPROVER_islessequald(double f, double g);\n" + "int __CPROVER_islessgreaterf(float f, float g);\n" + "int __CPROVER_islessgreaterd(double f, double g);\n" + "int __CPROVER_isunorderedf(float f, float g);\n" + "int __CPROVER_isunorderedd(double f, double g);\n" // absolute value "int __CPROVER_abs(int x);\n" @@ -211,7 +220,11 @@ void ansi_c_internal_additions(std::string &code) // arrays // NOLINTNEXTLINE(whitespace/line_length) "__CPROVER_bool __CPROVER_array_equal(const void *array1, const void *array2);\n" + // overwrite all of *dest (possibly using nondet values), even + // if *src is smaller "void __CPROVER_array_copy(const void *dest, const void *src);\n" + // replace at most size-of-*src bytes in *dest + "void __CPROVER_array_replace(const void *dest, const void *src);\n" "void __CPROVER_array_set(const void *dest, ...);\n" // k-induction @@ -242,6 +255,11 @@ void ansi_c_internal_additions(std::string &code) config.ansi_c.mode==configt::ansi_ct::flavourt::ARM) { code+=gcc_builtin_headers_generic; + code+=gcc_builtin_headers_math; + code+=gcc_builtin_headers_mem_string; + code+=gcc_builtin_headers_omp; + code+=gcc_builtin_headers_tm; + code+=gcc_builtin_headers_ubsan; code+=clang_builtin_headers; // there are many more, e.g., look at @@ -256,6 +274,8 @@ void ansi_c_internal_additions(std::string &code) code+=gcc_builtin_headers_ia32; code+=gcc_builtin_headers_ia32_2; + code+=gcc_builtin_headers_ia32_3; + code+=gcc_builtin_headers_ia32_4; } else if(config.ansi_c.arch=="arm64" || config.ansi_c.arch=="armel" || @@ -310,18 +330,6 @@ void ansi_c_internal_additions(std::string &code) ansi_c_architecture_strings(code); } -/*******************************************************************\ - -Function: architecture_strings - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ansi_c_architecture_strings(std::string &code) { // The following are CPROVER-specific. diff --git a/src/ansi-c/ansi_c_internal_additions.h b/src/ansi-c/ansi_c_internal_additions.h index 2b4a94f1d9b..a0977a35331 100644 --- a/src/ansi-c/ansi_c_internal_additions.h +++ b/src/ansi-c/ansi_c_internal_additions.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_ANSI_C_ANSI_C_INTERNAL_ADDITIONS_H #define CPROVER_ANSI_C_ANSI_C_INTERNAL_ADDITIONS_H @@ -15,7 +16,16 @@ void ansi_c_internal_additions(std::string &code); void ansi_c_architecture_strings(std::string &code); extern const char gcc_builtin_headers_generic[]; +extern const char gcc_builtin_headers_math[]; +extern const char gcc_builtin_headers_mem_string[]; +extern const char gcc_builtin_headers_omp[]; +extern const char gcc_builtin_headers_tm[]; +extern const char gcc_builtin_headers_ubsan[]; +extern const char clang_builtin_headers[]; extern const char gcc_builtin_headers_ia32[]; +extern const char gcc_builtin_headers_ia32_2[]; +extern const char gcc_builtin_headers_ia32_3[]; +extern const char gcc_builtin_headers_ia32_4[]; extern const char arm_builtin_headers[]; #endif // CPROVER_ANSI_C_ANSI_C_INTERNAL_ADDITIONS_H diff --git a/src/ansi-c/ansi_c_language.cpp b/src/ansi-c/ansi_c_language.cpp index bf2c1b46650..3a2f52f25fd 100644 --- a/src/ansi-c/ansi_c_language.cpp +++ b/src/ansi-c/ansi_c_language.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "ansi_c_language.h" + #include #include #include @@ -17,7 +19,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include "ansi_c_entry_point.h" -#include "ansi_c_language.h" #include "ansi_c_typecheck.h" #include "ansi_c_parser.h" #include "expr2c.h" @@ -26,52 +27,17 @@ Author: Daniel Kroening, kroening@kroening.com #include "ansi_c_internal_additions.h" #include "type2name.h" -/*******************************************************************\ - -Function: ansi_c_languaget::extensions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::set ansi_c_languaget::extensions() const { return { "c", "i" }; } -/*******************************************************************\ - -Function: ansi_c_languaget::modules_provided - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ansi_c_languaget::modules_provided(std::set &modules) { modules.insert(get_base_name(parse_path, true)); } -/*******************************************************************\ - -Function: ansi_c_languaget::preprocess - - Inputs: - - Outputs: - - Purpose: ANSI-C preprocessing - -\*******************************************************************/ - +/// ANSI-C preprocessing bool ansi_c_languaget::preprocess( std::istream &instream, const std::string &path, @@ -84,18 +50,6 @@ bool ansi_c_languaget::preprocess( return c_preprocess(path, outstream, get_message_handler()); } -/*******************************************************************\ - -Function: ansi_c_languaget::parse - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool ansi_c_languaget::parse( std::istream &instream, const std::string &path) @@ -148,18 +102,6 @@ bool ansi_c_languaget::parse( return result; } -/*******************************************************************\ - -Function: ansi_c_languaget::typecheck - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool ansi_c_languaget::typecheck( symbol_tablet &symbol_table, const std::string &module) @@ -183,18 +125,6 @@ bool ansi_c_languaget::typecheck( return false; } -/*******************************************************************\ - -Function: ansi_c_languaget::final - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool ansi_c_languaget::final( symbol_tablet &symbol_table, bool generate_start_function) @@ -208,52 +138,16 @@ bool ansi_c_languaget::final( return false; } -/*******************************************************************\ - -Function: ansi_c_languaget::show_parse - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ansi_c_languaget::show_parse(std::ostream &out) { parse_tree.output(out); } -/*******************************************************************\ - -Function: new_ansi_c_language - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - languaget *new_ansi_c_language() { return new ansi_c_languaget; } -/*******************************************************************\ - -Function: ansi_c_languaget::from_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool ansi_c_languaget::from_expr( const exprt &expr, std::string &code, @@ -263,18 +157,6 @@ bool ansi_c_languaget::from_expr( return false; } -/*******************************************************************\ - -Function: ansi_c_languaget::from_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool ansi_c_languaget::from_type( const typet &type, std::string &code, @@ -284,36 +166,12 @@ bool ansi_c_languaget::from_type( return false; } -/*******************************************************************\ - -Function: ansi_c_languaget::get_pretty_printer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::unique_ptr ansi_c_languaget::get_pretty_printer(const namespacet &ns) { return std::unique_ptr(new expr2ct(ns)); } -/*******************************************************************\ - -Function: ansi_c_languaget::type_to_name - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool ansi_c_languaget::type_to_name( const typet &type, std::string &name, @@ -323,18 +181,6 @@ bool ansi_c_languaget::type_to_name( return false; } -/*******************************************************************\ - -Function: ansi_c_languaget::to_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool ansi_c_languaget::to_expr( const std::string &code, const std::string &module, @@ -381,18 +227,6 @@ bool ansi_c_languaget::to_expr( return result; } -/*******************************************************************\ - -Function: ansi_c_languaget::~ansi_c_languaget - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - ansi_c_languaget::~ansi_c_languaget() { } diff --git a/src/ansi-c/ansi_c_language.h b/src/ansi-c/ansi_c_language.h index 25312253574..ba2aa0f8e32 100644 --- a/src/ansi-c/ansi_c_language.h +++ b/src/ansi-c/ansi_c_language.h @@ -6,18 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_ANSI_C_ANSI_C_LANGUAGE_H #define CPROVER_ANSI_C_ANSI_C_LANGUAGE_H -/*! \defgroup gr_ansi_c ANSI-C front-end */ - #include #include "ansi_c_parse_tree.h" -/*! \brief TO_BE_DOCUMENTED - \ingroup gr_ansi_c -*/ class ansi_c_languaget:public languaget { public: diff --git a/src/ansi-c/ansi_c_parse_tree.cpp b/src/ansi-c/ansi_c_parse_tree.cpp index 4f58d094563..f652c3b1e3a 100644 --- a/src/ansi-c/ansi_c_parse_tree.cpp +++ b/src/ansi-c/ansi_c_parse_tree.cpp @@ -6,56 +6,20 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "ansi_c_parse_tree.h" -/*******************************************************************\ - -Function: ansi_c_parse_treet::swap - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void ansi_c_parse_treet::swap(ansi_c_parse_treet &ansi_c_parse_tree) { ansi_c_parse_tree.items.swap(items); } -/*******************************************************************\ - -Function: ansi_c_parse_treet::clear - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ansi_c_parse_treet::clear() { items.clear(); } -/*******************************************************************\ - -Function: ansi_c_parse_treet::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ansi_c_parse_treet::output(std::ostream &out) const { for(const auto &item : items) diff --git a/src/ansi-c/ansi_c_parse_tree.h b/src/ansi-c/ansi_c_parse_tree.h index e32d5a6ca20..c346b5853fe 100644 --- a/src/ansi-c/ansi_c_parse_tree.h +++ b/src/ansi-c/ansi_c_parse_tree.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_ANSI_C_ANSI_C_PARSE_TREE_H #define CPROVER_ANSI_C_ANSI_C_PARSE_TREE_H diff --git a/src/ansi-c/ansi_c_parser.cpp b/src/ansi-c/ansi_c_parser.cpp index a32d31bac61..46d9f51d1b4 100644 --- a/src/ansi-c/ansi_c_parser.cpp +++ b/src/ansi-c/ansi_c_parser.cpp @@ -6,25 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "ansi_c_parser.h" + #include -#include "ansi_c_parser.h" #include "c_storage_spec.h" ansi_c_parsert ansi_c_parser; -/*******************************************************************\ - -Function: ansi_c_parsert::lookup - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - ansi_c_id_classt ansi_c_parsert::lookup( const irep_idt &base_name, irep_idt &identifier, // output @@ -59,29 +48,17 @@ ansi_c_id_classt ansi_c_parsert::lookup( { ansi_c_identifiert &i= current_scope().name_map[scope_name]; - i.id_class=ANSI_C_TAG; + i.id_class=ansi_c_id_classt::ANSI_C_TAG; i.prefixed_name=current_scope().prefix+id2string(scope_name); i.base_name=base_name; identifier=i.prefixed_name; - return ANSI_C_TAG; + return ansi_c_id_classt::ANSI_C_TAG; } identifier=base_name; - return ANSI_C_UNKNOWN; + return ansi_c_id_classt::ANSI_C_UNKNOWN; } -/*******************************************************************\ - -Function: ansi_c_parsert::add_tag_with_body - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ansi_c_parsert::add_tag_with_body(irept &tag) { const std::string scope_name= @@ -94,24 +71,12 @@ void ansi_c_parsert::add_tag_with_body(irept &tag) // re-defined in a deeper scope ansi_c_identifiert &identifier= current_scope().name_map[scope_name]; - identifier.id_class=ANSI_C_TAG; + identifier.id_class=ansi_c_id_classt::ANSI_C_TAG; identifier.prefixed_name=prefixed_name; tag.set(ID_identifier, prefixed_name); } } -/*******************************************************************\ - -Function: yyansi_cerror - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - extern char *yyansi_ctext; int yyansi_cerror(const std::string &error) @@ -120,18 +85,6 @@ int yyansi_cerror(const std::string &error) return 0; } -/*******************************************************************\ - -Function: ansi_c_parsert::add_declarator - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ansi_c_parsert::add_declarator( exprt &declaration, irept &declarator) @@ -180,8 +133,9 @@ void ansi_c_parsert::add_declarator( if(is_extern) force_root_scope=true; - ansi_c_id_classt id_class= - is_typedef?ANSI_C_TYPEDEF:ANSI_C_SYMBOL; + ansi_c_id_classt id_class=is_typedef? + ansi_c_id_classt::ANSI_C_TYPEDEF: + ansi_c_id_classt::ANSI_C_SYMBOL; scopet &scope= force_root_scope?root_scope():current_scope(); @@ -201,34 +155,22 @@ void ansi_c_parsert::add_declarator( ansi_c_declaration.declarators().push_back(new_declarator); } -/*******************************************************************\ - -Function: ansi_c_parsert::get_class - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - ansi_c_id_classt ansi_c_parsert::get_class(const typet &type) { if(type.id()==ID_typedef) - return ANSI_C_TYPEDEF; + return ansi_c_id_classt::ANSI_C_TYPEDEF; else if(type.id()==ID_struct || type.id()==ID_union || type.id()==ID_c_enum) - return ANSI_C_TAG; + return ansi_c_id_classt::ANSI_C_TAG; else if(type.id()==ID_merged_type) { forall_subtypes(it, type) - if(get_class(*it)==ANSI_C_TYPEDEF) - return ANSI_C_TYPEDEF; + if(get_class(*it)==ansi_c_id_classt::ANSI_C_TYPEDEF) + return ansi_c_id_classt::ANSI_C_TYPEDEF; } else if(type.has_subtype()) return get_class(type.subtype()); - return ANSI_C_SYMBOL; + return ansi_c_id_classt::ANSI_C_SYMBOL; } diff --git a/src/ansi-c/ansi_c_parser.h b/src/ansi-c/ansi_c_parser.h index 2b35b56f34a..b5dad0a515f 100644 --- a/src/ansi-c/ansi_c_parser.h +++ b/src/ansi-c/ansi_c_parser.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_ANSI_C_ANSI_C_PARSER_H #define CPROVER_ANSI_C_ANSI_C_PARSER_H @@ -28,7 +29,12 @@ class ansi_c_parsert:public parsert ansi_c_parse_treet parse_tree; ansi_c_parsert(): - cpp98(false), cpp11(false), + tag_following(false), + asm_block_following(false), + parenthesis_counter(0), + mode(modet::NONE), + cpp98(false), + cpp11(false), for_has_scope(false) { } @@ -50,7 +56,7 @@ class ansi_c_parsert:public parsert string_literal.clear(); pragma_pack.clear(); - // setup global scope + // set up global scope scopes.clear(); scopes.push_back(scopet()); } @@ -98,7 +104,7 @@ class ansi_c_parsert:public parsert return scopes.back(); } - typedef enum { TAG, MEMBER, PARAMETER, OTHER } decl_typet; + enum class decl_typet { TAG, MEMBER, PARAMETER, OTHER }; // convert a declarator and then add it to existing an declaration void add_declarator(exprt &declaration, irept &declarator); diff --git a/src/ansi-c/ansi_c_scope.cpp b/src/ansi-c/ansi_c_scope.cpp index 761fd23b19b..646a1d24ddd 100644 --- a/src/ansi-c/ansi_c_scope.cpp +++ b/src/ansi-c/ansi_c_scope.cpp @@ -6,21 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "ansi_c_scope.h" -/*******************************************************************\ - -Function: ansi_c_scopet::print - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void ansi_c_scopet::print(std::ostream &out) const { @@ -29,7 +17,7 @@ void ansi_c_scopet::print(std::ostream &out) const for(const auto &name : name_map) { out << " ID: " << name.first - << " CLASS: " << name.second.id_class + << " CLASS: " << static_cast(name.second.id_class) << "\n"; } } diff --git a/src/ansi-c/ansi_c_scope.h b/src/ansi-c/ansi_c_scope.h index 722774c01cc..0f9bc117729 100644 --- a/src/ansi-c/ansi_c_scope.h +++ b/src/ansi-c/ansi_c_scope.h @@ -6,13 +6,22 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_ANSI_C_ANSI_C_SCOPE_H #define CPROVER_ANSI_C_ANSI_C_SCOPE_H #include -typedef enum { ANSI_C_UNKNOWN, ANSI_C_SYMBOL, ANSI_C_TYPEDEF, - ANSI_C_TAG, ANSI_C_LOCAL_LABEL } ansi_c_id_classt; +enum class ansi_c_id_classt +{ + ANSI_C_UNKNOWN, + ANSI_C_SYMBOL, + ANSI_C_TYPEDEF, + ANSI_C_TAG, + ANSI_C_LOCAL_LABEL +}; + +std::ostream &operator<<(std::ostream &os, ansi_c_id_classt c); class ansi_c_identifiert { @@ -20,7 +29,7 @@ class ansi_c_identifiert ansi_c_id_classt id_class; irep_idt base_name, prefixed_name; - ansi_c_identifiert():id_class(ANSI_C_UNKNOWN) + ansi_c_identifiert():id_class(ansi_c_id_classt::ANSI_C_UNKNOWN) { } }; diff --git a/src/ansi-c/ansi_c_typecheck.cpp b/src/ansi-c/ansi_c_typecheck.cpp index 08da6bbae01..50bfe78dffb 100644 --- a/src/ansi-c/ansi_c_typecheck.cpp +++ b/src/ansi-c/ansi_c_typecheck.cpp @@ -6,19 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "ansi_c_typecheck.h" - -/*******************************************************************\ - -Function: ansi_c_typecheckt::typecheck - - Inputs: - - Outputs: - - Purpose: +/// \file +/// ANSI-C Language Type Checking -\*******************************************************************/ +#include "ansi_c_typecheck.h" void ansi_c_typecheckt::typecheck() { @@ -32,18 +23,6 @@ void ansi_c_typecheckt::typecheck() } } -/*******************************************************************\ - -Function: ansi_c_typecheck - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool ansi_c_typecheck( ansi_c_parse_treet &ansi_c_parse_tree, symbol_tablet &symbol_table, @@ -55,23 +34,14 @@ bool ansi_c_typecheck( return ansi_c_typecheck.typecheck_main(); } -/*******************************************************************\ - -Function: ansi_c_typecheck - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool ansi_c_typecheck( exprt &expr, message_handlert &message_handler, const namespacet &ns) { + const unsigned errors_before= + message_handler.get_message_count(messaget::M_ERROR); + symbol_tablet symbol_table; ansi_c_parse_treet ansi_c_parse_tree; @@ -99,5 +69,5 @@ bool ansi_c_typecheck( ansi_c_typecheck.error() << e << messaget::eom; } - return ansi_c_typecheck.get_error_found(); + return message_handler.get_message_count(messaget::M_ERROR)!=errors_before; } diff --git a/src/ansi-c/ansi_c_typecheck.h b/src/ansi-c/ansi_c_typecheck.h index aa6672d0d01..fdb9a32f2fe 100644 --- a/src/ansi-c/ansi_c_typecheck.h +++ b/src/ansi-c/ansi_c_typecheck.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// ANSI-C Language Type Checking + #ifndef CPROVER_ANSI_C_ANSI_C_TYPECHECK_H #define CPROVER_ANSI_C_ANSI_C_TYPECHECK_H diff --git a/src/ansi-c/c_misc.cpp b/src/ansi-c/c_misc.cpp index 94baea10fa2..5b1913bdf05 100644 --- a/src/ansi-c/c_misc.cpp +++ b/src/ansi-c/c_misc.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// ANSI-C Misc Utilities + +#include "c_misc.h" + #include #ifdef _WIN32 @@ -14,20 +19,6 @@ Author: Daniel Kroening, kroening@kroening.com #endif #endif -#include "c_misc.h" - -/*******************************************************************\ - -Function: MetaChar - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static void MetaChar(std::string &out, char c, bool inString) { switch(c) @@ -102,18 +93,6 @@ static void MetaChar(std::string &out, char c, bool inString) } #if 0 -/*******************************************************************\ - -Function: MetaChar - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static std::string MetaChar(char c) { std::string result; @@ -122,18 +101,6 @@ static std::string MetaChar(char c) } #endif -/*******************************************************************\ - -Function: MetaString - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string MetaString(const std::string &in) { std::string result; diff --git a/src/ansi-c/c_misc.h b/src/ansi-c/c_misc.h index 40f9d0db5b8..5af7eb4754c 100644 --- a/src/ansi-c/c_misc.h +++ b/src/ansi-c/c_misc.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// ANSI-C Misc Utilities + #ifndef CPROVER_ANSI_C_C_MISC_H #define CPROVER_ANSI_C_C_MISC_H diff --git a/src/ansi-c/c_nondet_symbol_factory.cpp b/src/ansi-c/c_nondet_symbol_factory.cpp index 9149d6f8786..53f21aa5ab5 100644 --- a/src/ansi-c/c_nondet_symbol_factory.cpp +++ b/src/ansi-c/c_nondet_symbol_factory.cpp @@ -6,10 +6,16 @@ Author: DiffBlue Limited. All rights reserved. \*******************************************************************/ +/// \file +/// C Nondet Symbol Factory + +#include "c_nondet_symbol_factory.h" + #include #include #include +#include #include #include #include @@ -20,30 +26,17 @@ Author: DiffBlue Limited. All rights reserved. #include -#include #include #include -#include "c_nondet_symbol_factory.h" - -/*******************************************************************\ - -Function: declare_new_tmp_symbol - - Inputs: - symbol_table - The symbol table to create the symbol in - loc - The location to assign to the symbol - type - The type of symbol to create - static_lifetime - Whether the symbol should have a static lifetime - prefix - The prefix to use for the symbol's basename - - Outputs: Returns a reference to the new symbol - - Purpose: Create a new temporary static symbol - -\*******************************************************************/ - +/// Create a new temporary static symbol +/// \param symbol_table: The symbol table to create the symbol in +/// \param loc: The location to assign to the symbol +/// \param type: The type of symbol to create +/// \param static_lifetime: Whether the symbol should have a static lifetime +/// \param prefix: The prefix to use for the symbol's basename +/// \return Returns a reference to the new symbol static const symbolt &c_new_tmp_symbol( symbol_tablet &symbol_table, const source_locationt &loc, @@ -58,19 +51,8 @@ static const symbolt &c_new_tmp_symbol( return tmp_symbol; } -/*******************************************************************\ - -Function: c_get_nondet_bool - - Inputs: - type - Desired type (C_bool or plain bool) - - Outputs: nondet expr of that type - - Purpose: - -\*******************************************************************/ - +/// \param type: Desired type (C_bool or plain bool) +/// \return nondet expr of that type static exprt c_get_nondet_bool(const typet &type) { // We force this to 0 and 1 and won't consider other values @@ -107,23 +89,14 @@ class symbol_factoryt void gen_nondet_init(code_blockt &assignments, const exprt &expr); }; -/*******************************************************************\ - -Function: symbol_factoryt::allocate_object - - Inputs: - assignments - The code block to add code to - target_expr - The expression which we are allocating a symbol for - allocate_type - The type to use for the symbol. If this doesn't match - target_expr then a cast will be used for the assignment - static_lifetime - Whether the symbol created should have static lifetime - - Outputs: Returns the address of the allocated symbol - - Purpose: Create a symbol for a pointer to point to - -\*******************************************************************/ - +/// Create a symbol for a pointer to point to +/// \param assignments: The code block to add code to +/// \param target_expr: The expression which we are allocating a symbol for +/// \param allocate_type: The type to use for the symbol. If this doesn't match +/// target_expr then a cast will be used for the assignment +/// \param static_lifetime: Whether the symbol created should have static +/// lifetime +/// \return Returns the address of the allocated symbol exprt symbol_factoryt::allocate_object( code_blockt &assignments, const exprt &target_expr, @@ -157,21 +130,11 @@ exprt symbol_factoryt::allocate_object( return aoe; } -/*******************************************************************\ - -Function: symbol_factoryt::gen_nondet_init - - Inputs: - assignments - The code block to add code to - expr - The expression which we are generating a non-determinate value for - - Outputs: - - Purpose: Creates a nondet for expr, including calling itself recursively to - make appropriate symbols to point to if expr is a pointer. - -\*******************************************************************/ - +/// Creates a nondet for expr, including calling itself recursively to make +/// appropriate symbols to point to if expr is a pointer. +/// \param assignments: The code block to add code to +/// \param expr: The expression which we are generating a non-determinate value +/// for void symbol_factoryt::gen_nondet_init( code_blockt &assignments, const exprt &expr) @@ -243,26 +206,16 @@ void symbol_factoryt::gen_nondet_init( } } -/*******************************************************************\ - -Function: c_nondet_symbol_factory - - Inputs: - init_code - The code block to add generated code to - symbol_table - The symbol table - base_name - The name to use for the symbol created - type - The type for the symbol created - loc - The location to assign to generated code - allow_null - Whether to allow a null value when type is a pointer - - Outputs: Returns the symbol_exprt for the symbol created - - Purpose: Creates a symbol and generates code so that it can vary - over all possible values for its type. For pointers this - involves allocating symbols which it can point to. - -\*******************************************************************/ - +/// Creates a symbol and generates code so that it can vary over all possible +/// values for its type. For pointers this involves allocating symbols which it +/// can point to. +/// \param init_code: The code block to add generated code to +/// \param symbol_table: The symbol table +/// \param base_name: The name to use for the symbol created +/// \param type: The type for the symbol created +/// \param loc: The location to assign to generated code +/// \param allow_null: Whether to allow a null value when type is a pointer +/// \return Returns the symbol_exprt for the symbol created exprt c_nondet_symbol_factory( code_blockt &init_code, symbol_tablet &symbol_table, diff --git a/src/ansi-c/c_nondet_symbol_factory.h b/src/ansi-c/c_nondet_symbol_factory.h index 8760de6ac55..8d375663e73 100644 --- a/src/ansi-c/c_nondet_symbol_factory.h +++ b/src/ansi-c/c_nondet_symbol_factory.h @@ -6,6 +6,9 @@ Author: DiffBlue Limited. All rights reserved. \*******************************************************************/ +/// \file +/// C Nondet Symbol Factory + #ifndef CPROVER_ANSI_C_C_NONDET_SYMBOL_FACTORY_H #define CPROVER_ANSI_C_C_NONDET_SYMBOL_FACTORY_H diff --git a/src/ansi-c/c_preprocess.cpp b/src/ansi-c/c_preprocess.cpp index 9582d6f3b00..927a928b187 100644 --- a/src/ansi-c/c_preprocess.cpp +++ b/src/ansi-c/c_preprocess.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "c_preprocess.h" + #include #include #include @@ -21,6 +23,7 @@ Author: Daniel Kroening, kroening@kroening.com #include +#include #include #include #include @@ -29,9 +32,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "c_types.h" -#include "c_preprocess.h" - #define GCC_DEFINES_16 \ " -D__INT_MAX__=32767"\ " -D__CHAR_BIT__=8"\ @@ -96,18 +96,7 @@ Author: Daniel Kroening, kroening@kroening.com " -D__INTPTR_TYPE__=\"long long int\""\ " -D__UINTPTR_TYPE__=\"long long unsigned int\"" -/*******************************************************************\ - -Function: type_max - - Inputs: - - Outputs: - - Purpose: produce a string with the maximum value of a given type - -\*******************************************************************/ - +/// produce a string with the maximum value of a given type static std::string type_max(const typet &src) { if(src.id()==ID_signedbv) @@ -120,18 +109,7 @@ static std::string type_max(const typet &src) assert(false); } -/*******************************************************************\ - -Function: shell_quote - - Inputs: - - Outputs: - - Purpose: quote a string for bash and CMD - -\*******************************************************************/ - +/// quote a string for bash and CMD static std::string shell_quote(const std::string &src) { #ifdef _WIN32 @@ -205,18 +183,6 @@ static std::string shell_quote(const std::string &src) #endif } -/*******************************************************************\ - -Function: error_parse_line - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static void error_parse_line( const std::string &line, bool warning_only, @@ -337,18 +303,6 @@ static void error_parse_line( m << error_msg << messaget::eom; } -/*******************************************************************\ - -Function: error_parse - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static void error_parse( std::istream &errors, bool warning_only, @@ -360,18 +314,7 @@ static void error_parse( error_parse_line(line, warning_only, message); } -/*******************************************************************\ - -Function: c_preprocess - - Inputs: - - Outputs: - - Purpose: ANSI-C preprocessing - -\*******************************************************************/ - +/// ANSI-C preprocessing bool c_preprocess( std::istream &instream, std::ostream &outstream, @@ -397,22 +340,11 @@ bool c_preprocess( return result; } -/*******************************************************************\ - -Function: is_dot_i_file - - Inputs: - - Outputs: - - Purpose: ANSI-C preprocessing - -\*******************************************************************/ - +/// ANSI-C preprocessing static bool is_dot_i_file(const std::string &path) { const char *ext=strrchr(path.c_str(), '.'); - if(ext==NULL) + if(ext==nullptr) return false; if(std::string(ext)==".i" || std::string(ext)==".ii") @@ -420,18 +352,7 @@ static bool is_dot_i_file(const std::string &path) return false; } -/*******************************************************************\ - -Function: c_preprocess - - Inputs: - - Outputs: - - Purpose: ANSI-C preprocessing - -\*******************************************************************/ - +/// ANSI-C preprocessing bool c_preprocess_codewarrior( const std::string &, std::ostream &, message_handlert &); bool c_preprocess_arm( @@ -480,18 +401,7 @@ bool c_preprocess( return true; } -/*******************************************************************\ - -Function: c_preprocess_visual_studio - - Inputs: - - Outputs: - - Purpose: ANSI-C preprocessing - -\*******************************************************************/ - +/// ANSI-C preprocessing bool c_preprocess_visual_studio( const std::string &file, std::ostream &outstream, @@ -598,18 +508,7 @@ bool c_preprocess_visual_studio( return false; } -/*******************************************************************\ - -Function: postprocess_codewarrior - - Inputs: - - Outputs: - - Purpose: post-processing specifically for CodeWarrior - -\*******************************************************************/ - +/// post-processing specifically for CodeWarrior void postprocess_codewarrior( std::istream &instream, std::ostream &outstream) @@ -645,18 +544,7 @@ void postprocess_codewarrior( } } -/*******************************************************************\ - -Function: c_preprocess_codewarrior - - Inputs: - - Outputs: - - Purpose: ANSI-C preprocessing - -\*******************************************************************/ - +/// ANSI-C preprocessing bool c_preprocess_codewarrior( const std::string &file, std::ostream &outstream, @@ -729,18 +617,7 @@ bool c_preprocess_codewarrior( return false; } -/*******************************************************************\ - -Function: c_preprocess_gcc_clang - - Inputs: - - Outputs: - - Purpose: ANSI-C preprocessing - -\*******************************************************************/ - +/// ANSI-C preprocessing bool c_preprocess_gcc_clang( const std::string &file, std::ostream &outstream, @@ -1012,7 +889,7 @@ bool c_preprocess_gcc_clang( FILE *stream=popen(command.c_str(), "r"); - if(stream!=NULL) + if(stream!=nullptr) { int ch; while((ch=fgetc(stream))!=EOF) @@ -1044,18 +921,7 @@ bool c_preprocess_gcc_clang( return false; } -/*******************************************************************\ - -Function: c_preprocess_arm - - Inputs: - - Outputs: - - Purpose: ANSI-C preprocessing - -\*******************************************************************/ - +/// ANSI-C preprocessing bool c_preprocess_arm( const std::string &file, std::ostream &outstream, @@ -1145,7 +1011,7 @@ bool c_preprocess_arm( FILE *stream=popen(command.c_str(), "r"); - if(stream!=NULL) + if(stream!=nullptr) { int ch; while((ch=fgetc(stream))!=EOF) @@ -1177,18 +1043,7 @@ bool c_preprocess_arm( return false; } -/*******************************************************************\ - -Function: c_preprocess_none - - Inputs: - - Outputs: - - Purpose: ANSI-C preprocessing - -\*******************************************************************/ - +/// ANSI-C preprocessing bool c_preprocess_none( const std::string &file, std::ostream &outstream, @@ -1223,18 +1078,7 @@ bool c_preprocess_none( return false; } -/*******************************************************************\ - -Function: test_c_preprocessor - - Inputs: - - Outputs: - - Purpose: tests ANSI-C preprocessing - -\*******************************************************************/ - +/// tests ANSI-C preprocessing const char c_test_program[]= "#include \n" "\n" diff --git a/src/ansi-c/c_preprocess.h b/src/ansi-c/c_preprocess.h index 2a50e0bfa36..bdf273d2775 100644 --- a/src/ansi-c/c_preprocess.h +++ b/src/ansi-c/c_preprocess.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_ANSI_C_C_PREPROCESS_H #define CPROVER_ANSI_C_C_PREPROCESS_H diff --git a/src/ansi-c/c_qualifiers.cpp b/src/ansi-c/c_qualifiers.cpp index 75ca8bf9c05..0802d144391 100644 --- a/src/ansi-c/c_qualifiers.cpp +++ b/src/ansi-c/c_qualifiers.cpp @@ -6,21 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "c_qualifiers.h" -/*******************************************************************\ - -Function: c_qualifierst::as_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include std::string c_qualifierst::as_string() const { @@ -50,18 +38,6 @@ std::string c_qualifierst::as_string() const return qualifiers; } -/*******************************************************************\ - -Function: c_qualifierst::read - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_qualifierst::read(const typet &src) { if(src.get_bool(ID_C_constant)) @@ -89,18 +65,6 @@ void c_qualifierst::read(const typet &src) is_noreturn=true; } -/*******************************************************************\ - -Function: c_qualifierst::write - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_qualifierst::write(typet &dest) const { if(is_constant) @@ -144,18 +108,6 @@ void c_qualifierst::write(typet &dest) const dest.remove(ID_C_noreturn); } -/*******************************************************************\ - -Function: c_qualifierst::clear - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_qualifierst::clear(typet &dest) { dest.remove(ID_C_constant); @@ -167,18 +119,7 @@ void c_qualifierst::clear(typet &dest) dest.remove(ID_C_noreturn); } -/*******************************************************************\ - -Function: operator << - - Inputs: - - Outputs: - - Purpose: pretty-print the qualifiers - -\*******************************************************************/ - +/// pretty-print the qualifiers std::ostream &operator << ( std::ostream &out, const c_qualifierst &c_qualifiers) diff --git a/src/ansi-c/c_qualifiers.h b/src/ansi-c/c_qualifiers.h index 45e5d01d782..2e9948e31e9 100644 --- a/src/ansi-c/c_qualifiers.h +++ b/src/ansi-c/c_qualifiers.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_ANSI_C_C_QUALIFIERS_H #define CPROVER_ANSI_C_C_QUALIFIERS_H diff --git a/src/ansi-c/c_sizeof.cpp b/src/ansi-c/c_sizeof.cpp index 85c91870208..fad6d00ce9f 100644 --- a/src/ansi-c/c_sizeof.cpp +++ b/src/ansi-c/c_sizeof.cpp @@ -6,26 +6,18 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Conversion of sizeof Expressions + +#include "c_sizeof.h" + #include #include #include #include +#include -#include "c_sizeof.h" #include "c_typecast.h" -#include "c_types.h" - -/*******************************************************************\ - -Function: c_sizeoft::sizeof_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ exprt c_sizeoft::sizeof_rec(const typet &type) { @@ -258,18 +250,6 @@ exprt c_sizeoft::sizeof_rec(const typet &type) return dest; } -/*******************************************************************\ - -Function: c_sizeoft::c_offsetof - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt c_sizeoft::c_offsetof( const struct_typet &type, const irep_idt &component_name) @@ -320,18 +300,6 @@ exprt c_sizeoft::c_offsetof( return nil_exprt(); } -/*******************************************************************\ - -Function: c_sizeof - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt c_sizeof(const typet &src, const namespacet &ns) { c_sizeoft c_sizeof_inst(ns); @@ -340,18 +308,6 @@ exprt c_sizeof(const typet &src, const namespacet &ns) return tmp; } -/*******************************************************************\ - -Function: c_offsetof - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt c_offsetof( const struct_typet &src, const irep_idt &component_name, diff --git a/src/ansi-c/c_sizeof.h b/src/ansi-c/c_sizeof.h index 40329726b75..de5421c0510 100644 --- a/src/ansi-c/c_sizeof.h +++ b/src/ansi-c/c_sizeof.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_ANSI_C_C_SIZEOF_H #define CPROVER_ANSI_C_C_SIZEOF_H diff --git a/src/ansi-c/c_storage_spec.cpp b/src/ansi-c/c_storage_spec.cpp index df4cdb2381c..5ed8314bd42 100644 --- a/src/ansi-c/c_storage_spec.cpp +++ b/src/ansi-c/c_storage_spec.cpp @@ -6,21 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "c_storage_spec.h" -/*******************************************************************\ - -Function: c_storage_spect::read - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void c_storage_spect::read(const typet &type) { diff --git a/src/ansi-c/c_storage_spec.h b/src/ansi-c/c_storage_spec.h index d735e578426..5b392fe4d05 100644 --- a/src/ansi-c/c_storage_spec.h +++ b/src/ansi-c/c_storage_spec.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_ANSI_C_C_STORAGE_SPEC_H #define CPROVER_ANSI_C_C_STORAGE_SPEC_H @@ -76,7 +77,13 @@ class c_storage_spect is_register |=other.is_register; is_inline |=other.is_inline; is_thread_local |=other.is_thread_local; - // attributes belong to the declarator, don't replace them + is_weak |=other.is_weak; + if(alias.empty()) + alias=other.alias; + if(asm_label.empty()) + asm_label=other.asm_label; + if(section.empty()) + section=other.section; return *this; } diff --git a/src/ansi-c/c_typecast.cpp b/src/ansi-c/c_typecast.cpp index 52070e29257..ce451e79f75 100644 --- a/src/ansi-c/c_typecast.cpp +++ b/src/ansi-c/c_typecast.cpp @@ -6,11 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "c_typecast.h" + #include #include #include +#include #include #include #include @@ -18,22 +21,8 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "c_typecast.h" -#include "c_types.h" #include "c_qualifiers.h" -/*******************************************************************\ - -Function: c_implicit_typecast - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool c_implicit_typecast( exprt &expr, const typet &dest_type, @@ -44,18 +33,6 @@ bool c_implicit_typecast( return !c_typecast.errors.empty(); } -/*******************************************************************\ - -Function: check_c_implicit_typecast - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool check_c_implicit_typecast( const typet &src_type, const typet &dest_type, @@ -68,18 +45,7 @@ bool check_c_implicit_typecast( return !c_typecast.errors.empty(); } -/*******************************************************************\ - -Function: c_implicit_typecast_arithmetic - - Inputs: - - Outputs: - - Purpose: perform arithmetic prompotions and conversions - -\*******************************************************************/ - +/// perform arithmetic prompotions and conversions bool c_implicit_typecast_arithmetic( exprt &expr1, exprt &expr2, const namespacet &ns) @@ -89,18 +55,6 @@ bool c_implicit_typecast_arithmetic( return !c_typecast.errors.empty(); } -/*******************************************************************\ - -Function: is_void_pointer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool is_void_pointer(const typet &type) { if(type.id()==ID_pointer) @@ -114,18 +68,6 @@ bool is_void_pointer(const typet &type) return false; } -/*******************************************************************\ - -Function: check_c_implicit_typecast - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool check_c_implicit_typecast( const typet &src_type, const typet &dest_type) @@ -308,18 +250,6 @@ bool check_c_implicit_typecast( return true; } -/*******************************************************************\ - -Function: c_typecastt::follow_with_qualifiers - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet c_typecastt::follow_with_qualifiers(const typet &src_type) { if(src_type.id()!=ID_symbol) @@ -344,18 +274,6 @@ typet c_typecastt::follow_with_qualifiers(const typet &src_type) return result_type; } -/*******************************************************************\ - -Function: c_typecastt::get_c_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - c_typecastt::c_typet c_typecastt::get_c_type( const typet &type) const { @@ -441,18 +359,6 @@ c_typecastt::c_typet c_typecastt::get_c_type( return OTHER; } -/*******************************************************************\ - -Function: c_typecastt::implicit_typecast_arithmetic - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecastt::implicit_typecast_arithmetic( exprt &expr, c_typet c_type) @@ -499,18 +405,6 @@ void c_typecastt::implicit_typecast_arithmetic( do_typecast(expr, new_type); } -/*******************************************************************\ - -Function: c_typecastt::implicit_typecast_arithmetic - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - c_typecastt::c_typet c_typecastt::minimum_promotion( const typet &type) const { @@ -544,36 +438,12 @@ c_typecastt::c_typet c_typecastt::minimum_promotion( return max_type; } -/*******************************************************************\ - -Function: c_typecastt::implicit_typecast_arithmetic - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecastt::implicit_typecast_arithmetic(exprt &expr) { c_typet c_type=minimum_promotion(expr.type()); implicit_typecast_arithmetic(expr, c_type); } -/*******************************************************************\ - -Function: c_typecastt::implicit_typecast - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecastt::implicit_typecast( exprt &expr, const typet &type) @@ -588,18 +458,6 @@ void c_typecastt::implicit_typecast( implicit_typecast_followed(expr, src_type, type_qual, dest_type); } -/*******************************************************************\ - -Function: c_typecastt::implicit_typecast_followed - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecastt::implicit_typecast_followed( exprt &expr, const typet &src_type, @@ -721,18 +579,6 @@ void c_typecastt::implicit_typecast_followed( do_typecast(expr, orig_dest_type); } -/*******************************************************************\ - -Function: c_typecastt::implicit_typecast_arithmetic - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecastt::implicit_typecast_arithmetic( exprt &expr1, exprt &expr2) @@ -847,18 +693,6 @@ void c_typecastt::implicit_typecast_arithmetic( #endif } -/*******************************************************************\ - -Function: c_typecastt::do_typecast - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecastt::do_typecast(exprt &expr, const typet &dest_type) { // special case: array -> pointer is actually @@ -881,7 +715,7 @@ void c_typecastt::do_typecast(exprt &expr, const typet &dest_type) if(src_type!=dest_type) { // C booleans are special; we produce the - // explicit comparision with zero. + // explicit comparison with zero. // Note that this requires ieee_float_notequal // in case of floating-point numbers. diff --git a/src/ansi-c/c_typecast.h b/src/ansi-c/c_typecast.h index cfc3eb79aa5..efd95f998b6 100644 --- a/src/ansi-c/c_typecast.h +++ b/src/ansi-c/c_typecast.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_ANSI_C_C_TYPECAST_H #define CPROVER_ANSI_C_C_TYPECAST_H @@ -14,7 +15,7 @@ Author: Daniel Kroening, kroening@kroening.com // try a type cast from expr.type() to type // -// false: typecast successfull, expr modified +// false: typecast successful, expr modified // true: typecast failed bool check_c_implicit_typecast( diff --git a/src/ansi-c/c_typecheck_argc_argv.cpp b/src/ansi-c/c_typecheck_argc_argv.cpp index a528a630042..879887db5b2 100644 --- a/src/ansi-c/c_typecheck_argc_argv.cpp +++ b/src/ansi-c/c_typecheck_argc_argv.cpp @@ -6,21 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// ANSI-C Conversion / Type Checking #include "c_typecheck_base.h" -/*******************************************************************\ - -Function: c_typecheck_baset::add_argc_argv - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void c_typecheck_baset::add_argc_argv(const symbolt &main_symbol) { diff --git a/src/ansi-c/c_typecheck_base.cpp b/src/ansi-c/c_typecheck_base.cpp index 8597eef3852..0d18016602d 100644 --- a/src/ansi-c/c_typecheck_base.cpp +++ b/src/ansi-c/c_typecheck_base.cpp @@ -6,61 +6,29 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// ANSI-C Conversion / Type Checking + +#include "c_typecheck_base.h" + #include #include #include -#include "c_typecheck_base.h" #include "expr2c.h" #include "type2name.h" #include "c_storage_spec.h" -/*******************************************************************\ - -Function: c_typecheck_baset::to_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string c_typecheck_baset::to_string(const exprt &expr) { return expr2c(expr, *this); } -/*******************************************************************\ - -Function: c_typecheck_baset::to_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string c_typecheck_baset::to_string(const typet &type) { return type2c(type, *this); } -/*******************************************************************\ - -Function: c_typecheck_baset::move_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::move_symbol(symbolt &symbol, symbolt *&new_symbol) { symbol.mode=mode; @@ -75,22 +43,8 @@ void c_typecheck_baset::move_symbol(symbolt &symbol, symbolt *&new_symbol) } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_symbol(symbolt &symbol) { - current_symbol_id=symbol.name; - bool is_function=symbol.type.id()==ID_code; const typet &final_type=follow(symbol.type); @@ -173,18 +127,6 @@ void c_typecheck_baset::typecheck_symbol(symbolt &symbol) } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_new_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_new_symbol(symbolt &symbol) { if(symbol.is_parameter) @@ -210,44 +152,11 @@ void c_typecheck_baset::typecheck_new_symbol(symbolt &symbol) } else { - if(symbol.type.id()==ID_array && - to_array_type(symbol.type).size().is_nil() && - !symbol.is_type) - { - // Insert a new type symbol for the array. - // We do this because we want a convenient way - // of adjusting the size of the type later on. - - type_symbolt new_symbol(symbol.type); - new_symbol.name=id2string(symbol.name)+"$type"; - new_symbol.base_name=id2string(symbol.base_name)+"$type"; - new_symbol.location=symbol.location; - new_symbol.mode=symbol.mode; - new_symbol.module=symbol.module; - - symbol.type=symbol_typet(new_symbol.name); - - symbolt *new_sp; - symbol_table.move(new_symbol, new_sp); - } - // check the initializer do_initializer(symbol); } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_redefinition_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_redefinition_type( symbolt &old_symbol, symbolt &new_symbol) @@ -255,7 +164,7 @@ void c_typecheck_baset::typecheck_redefinition_type( const typet &final_old=follow(old_symbol.type); const typet &final_new=follow(new_symbol.type); - // see if we had s.th. incomplete before + // see if we had something incomplete before if(final_old.id()==ID_incomplete_struct || final_old.id()==ID_incomplete_union || final_old.id()==ID_incomplete_c_enum) @@ -331,18 +240,6 @@ void c_typecheck_baset::typecheck_redefinition_type( } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_redefinition_non_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_redefinition_non_type( symbolt &old_symbol, symbolt &new_symbol) @@ -615,18 +512,6 @@ void c_typecheck_baset::typecheck_redefinition_non_type( // mismatch. } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_function_body - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_function_body(symbolt &symbol) { code_typet &code_type=to_code_type(symbol.type); @@ -653,7 +538,7 @@ void c_typecheck_baset::typecheck_function_body(symbolt &symbol) p_it++) { // may be anonymous - if(p_it->get_base_name()==irep_idt()) + if(p_it->get_base_name().empty()) { irep_idt base_name="#anon"+std::to_string(anon_counter++); p_it->set_base_name(base_name); @@ -697,18 +582,6 @@ void c_typecheck_baset::typecheck_function_body(symbolt &symbol) } } -/*******************************************************************\ - -Function: c_typecheck_baset::apply_asm_label - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::apply_asm_label( const irep_idt &asm_label, symbolt &symbol) @@ -777,18 +650,6 @@ void c_typecheck_baset::apply_asm_label( } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_declaration - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_declaration( ansi_c_declarationt &declaration) { @@ -840,6 +701,7 @@ void c_typecheck_baset::typecheck_declaration( symbolt symbol; declaration.to_symbol(*d_it, symbol); + current_symbol=symbol; // now check other half of type typecheck_type(symbol.type); diff --git a/src/ansi-c/c_typecheck_base.h b/src/ansi-c/c_typecheck_base.h index 68191f54fe9..ba6829bda05 100644 --- a/src/ansi-c/c_typecheck_base.h +++ b/src/ansi-c/c_typecheck_base.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// ANSI-C Language Type Checking + #ifndef CPROVER_ANSI_C_C_TYPECHECK_BASE_H #define CPROVER_ANSI_C_C_TYPECHECK_BASE_H @@ -32,7 +35,10 @@ class c_typecheck_baset: namespacet(_symbol_table), symbol_table(_symbol_table), module(_module), - mode("C") + mode(ID_C), + break_is_allowed(false), + continue_is_allowed(false), + case_is_allowed(false) { } @@ -45,7 +51,10 @@ class c_typecheck_baset: namespacet(_symbol_table1, _symbol_table2), symbol_table(_symbol_table1), module(_module), - mode("C") + mode(ID_C), + break_is_allowed(false), + continue_is_allowed(false), + case_is_allowed(false) { } @@ -58,7 +67,7 @@ class c_typecheck_baset: symbol_tablet &symbol_table; const irep_idt module; const irep_idt mode; - irep_idt current_symbol_id; + symbolt current_symbol; typedef std::unordered_map id_type_mapt; id_type_mapt parameter_map; @@ -86,10 +95,11 @@ class c_typecheck_baset: const typet &type, bool force_constant); - virtual void do_designated_initializer( + virtual exprt::operandst::const_iterator do_designated_initializer( exprt &result, designatort &designator, - const exprt &value, + const exprt &initializer_list, + exprt::operandst::const_iterator init_it, bool force_constant); designatort make_designator(const typet &type, const exprt &src); diff --git a/src/ansi-c/c_typecheck_code.cpp b/src/ansi-c/c_typecheck_code.cpp index dfbac98940c..9715fc2e4d3 100644 --- a/src/ansi-c/c_typecheck_code.cpp +++ b/src/ansi-c/c_typecheck_code.cpp @@ -6,41 +6,21 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include -#include +/// \file +/// C Language Type Checking -#include "ansi_c_declaration.h" #include "c_typecheck_base.h" -/*******************************************************************\ - -Function: c_typecheck_baset::start_typecheck_code - - Inputs: - - Outputs: - - Purpose: +#include +#include -\*******************************************************************/ +#include "ansi_c_declaration.h" void c_typecheck_baset::start_typecheck_code() { case_is_allowed=break_is_allowed=continue_is_allowed=false; } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_code - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_code(codet &code) { if(code.id()!=ID_code) @@ -152,18 +132,6 @@ void c_typecheck_baset::typecheck_code(codet &code) } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_asm - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_asm(codet &code) { const irep_idt flavor=to_code_asm(code).get_flavor(); @@ -197,18 +165,6 @@ void c_typecheck_baset::typecheck_asm(codet &code) } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_assign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_assign(codet &code) { if(code.operands().size()!=2) @@ -225,18 +181,6 @@ void c_typecheck_baset::typecheck_assign(codet &code) implicit_typecast(code.op1(), code.op0().type()); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_block - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_block(codet &code) { Forall_operands(it, code) @@ -276,18 +220,6 @@ void c_typecheck_baset::typecheck_block(codet &code) code.operands().swap(new_ops.operands()); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_break - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_break(codet &code) { if(!break_is_allowed) @@ -298,18 +230,6 @@ void c_typecheck_baset::typecheck_break(codet &code) } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_continue - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_continue(codet &code) { if(!continue_is_allowed) @@ -320,18 +240,6 @@ void c_typecheck_baset::typecheck_continue(codet &code) } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_decl - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_decl(codet &code) { // this comes with 1 operand, which is a declaration @@ -452,18 +360,6 @@ void c_typecheck_baset::typecheck_decl(codet &code) } } -/*******************************************************************\ - -Function: c_typecheck_baset::is_complete_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool c_typecheck_baset::is_complete_type(const typet &type) const { if(type.id()==ID_incomplete_struct || @@ -494,18 +390,6 @@ bool c_typecheck_baset::is_complete_type(const typet &type) const return true; } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expression - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expression(codet &code) { if(code.operands().size()!=1) @@ -520,18 +404,6 @@ void c_typecheck_baset::typecheck_expression(codet &code) typecheck_expr(op); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_for - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_for(codet &code) { if(code.operands().size()!=4) @@ -623,18 +495,6 @@ void c_typecheck_baset::typecheck_for(codet &code) typecheck_spec_expr(code, ID_C_spec_loop_invariant); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_label - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_label(code_labelt &code) { // record the label @@ -643,18 +503,6 @@ void c_typecheck_baset::typecheck_label(code_labelt &code) typecheck_code(code.code()); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_switch_case - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_switch_case(code_switch_caset &code) { if(code.operands().size()!=2) @@ -690,18 +538,6 @@ void c_typecheck_baset::typecheck_switch_case(code_switch_caset &code) } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_gcc_switch_case_range - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_gcc_switch_case_range(codet &code) { if(code.operands().size()!=3) @@ -727,54 +563,18 @@ void c_typecheck_baset::typecheck_gcc_switch_case_range(codet &code) implicit_typecast(code.op1(), switch_op_type); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_gcc_local_label - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_gcc_local_label(codet &code) { // these are just declarations, e.g., // __label__ here, there; } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_goto - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_goto(code_gotot &code) { // we record the label used labels_used[code.get_destination()]=code.source_location(); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_gcc_computed_goto - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_gcc_computed_goto(codet &code) { if(code.operands().size()!=1) @@ -800,18 +600,6 @@ void c_typecheck_baset::typecheck_gcc_computed_goto(codet &code) dest.type()=empty_typet(); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_ifthenelse - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_ifthenelse(code_ifthenelset &code) { if(code.operands().size()!=3) @@ -861,18 +649,6 @@ void c_typecheck_baset::typecheck_ifthenelse(code_ifthenelset &code) } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_start_thread - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_start_thread(codet &code) { if(code.operands().size()!=1) @@ -885,23 +661,13 @@ void c_typecheck_baset::typecheck_start_thread(codet &code) typecheck_code(to_code(code.op0())); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_return - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_return(codet &code) { if(code.operands().empty()) { - if(follow(return_type).id()!=ID_empty) + if(follow(return_type).id()!=ID_empty && + return_type.id()!=ID_constructor && + return_type.id()!=ID_destructor) { // gcc doesn't actually complain, it just warns! // We'll put a zero here, which is dubious. @@ -941,18 +707,6 @@ void c_typecheck_baset::typecheck_return(codet &code) } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_switch - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_switch(code_switcht &code) { if(code.operands().size()!=2) @@ -984,18 +738,6 @@ void c_typecheck_baset::typecheck_switch(code_switcht &code) switch_op_type=old_switch_op_type; } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_while - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_while(code_whilet &code) { if(code.operands().size()!=2) @@ -1031,18 +773,6 @@ void c_typecheck_baset::typecheck_while(code_whilet &code) typecheck_spec_expr(code, ID_C_spec_loop_invariant); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_dowhile - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_dowhile(code_dowhilet &code) { if(code.operands().size()!=2) @@ -1078,18 +808,6 @@ void c_typecheck_baset::typecheck_dowhile(code_dowhilet &code) typecheck_spec_expr(code, ID_C_spec_loop_invariant); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_spec_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_spec_expr( codet &code, const irep_idt &spec) diff --git a/src/ansi-c/c_typecheck_expr.cpp b/src/ansi-c/c_typecheck_expr.cpp index 5d4788e5145..fee4e8685d1 100644 --- a/src/ansi-c/c_typecheck_expr.cpp +++ b/src/ansi-c/c_typecheck_expr.cpp @@ -6,9 +6,15 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// ANSI-C Language Type Checking + +#include "c_typecheck_base.h" + #include #include +#include #include #include #include @@ -19,27 +25,13 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "c_types.h" #include "c_typecast.h" -#include "c_typecheck_base.h" #include "c_sizeof.h" #include "c_qualifiers.h" #include "string_constant.h" #include "anonymous_member.h" #include "padding.h" -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr(exprt &expr) { if(expr.id()==ID_already_typechecked) @@ -58,18 +50,6 @@ void c_typecheck_baset::typecheck_expr(exprt &expr) typecheck_expr_main(expr); } -/*******************************************************************\ - -Function: c_typecheck_baset::add_rounding_mode - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::add_rounding_mode(exprt &expr) { for(auto &op : expr.operands()) @@ -104,18 +84,6 @@ void c_typecheck_baset::add_rounding_mode(exprt &expr) } } -/*******************************************************************\ - -Function: c_typecheck_baset::gcc_types_compatible_p - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool c_typecheck_baset::gcc_types_compatible_p( const typet &type1, const typet &type2) @@ -198,18 +166,6 @@ bool c_typecheck_baset::gcc_types_compatible_p( return false; } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_main - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_main(exprt &expr) { if(expr.id()==ID_side_effect) @@ -395,7 +351,7 @@ void c_typecheck_baset::typecheck_expr_main(exprt &expr) { // This is C11. // The operand is already typechecked. Depending - // on it's type, we return one of the generic associatios. + // on its type, we return one of the generic associations. if(expr.operands().size()!=1) { @@ -459,6 +415,11 @@ void c_typecheck_baset::typecheck_expr_main(exprt &expr) expr.id()==ID_gcc_asm_clobbered_register) { } + else if(expr.id()==ID_lshr || expr.id()==ID_ashr || + expr.id()==ID_assign_lshr || expr.id()==ID_assign_ashr) + { + // already type checked + } else { err_location(expr); @@ -467,18 +428,6 @@ void c_typecheck_baset::typecheck_expr_main(exprt &expr) } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_comma - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_comma(exprt &expr) { if(expr.operands().size()!=2) @@ -495,18 +444,6 @@ void c_typecheck_baset::typecheck_expr_comma(exprt &expr) expr.set(ID_C_lvalue, true); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_builtin_va_arg - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_builtin_va_arg(exprt &expr) { // The first parameter is the va_list, and the second @@ -552,18 +489,6 @@ void c_typecheck_baset::typecheck_expr_builtin_va_arg(exprt &expr) symbol_table.move(symbol); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_cw_va_arg_typeof - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_cw_va_arg_typeof(exprt &expr) { // used in Code Warrior via @@ -581,18 +506,6 @@ void c_typecheck_baset::typecheck_expr_cw_va_arg_typeof(exprt &expr) expr.type()=signed_int_type(); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_builtin_offsetof - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_builtin_offsetof(exprt &expr) { // these need not be constant, due to array indices! @@ -754,18 +667,6 @@ void c_typecheck_baset::typecheck_expr_builtin_offsetof(exprt &expr) expr.swap(result); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_operands - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_operands(exprt &expr) { if(expr.id()==ID_side_effect && @@ -837,18 +738,6 @@ void c_typecheck_baset::typecheck_expr_operands(exprt &expr) } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_symbol(exprt &expr) { irep_idt identifier=to_symbol_expr(expr).get_identifier(); @@ -945,27 +834,14 @@ void c_typecheck_baset::typecheck_expr_symbol(exprt &expr) if(expr.type().id()==ID_code) // function designator { // special case: this is sugar for &f - exprt tmp(ID_address_of, pointer_type(expr.type())); + address_of_exprt tmp(expr, pointer_type(expr.type())); tmp.set("#implicit", true); tmp.add_source_location()=expr.source_location(); - tmp.move_to_operands(expr); - expr.swap(tmp); + expr=tmp; } } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_side_effect_statement_expression - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_side_effect_statement_expression( side_effect_exprt &expr) { @@ -1042,18 +918,6 @@ void c_typecheck_baset::typecheck_side_effect_statement_expression( expr.type()=typet(ID_empty); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_sizeof - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_sizeof(exprt &expr) { typet type; @@ -1116,18 +980,6 @@ void c_typecheck_baset::typecheck_expr_sizeof(exprt &expr) } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_alignof - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_alignof(exprt &expr) { typet argument_type; @@ -1150,18 +1002,6 @@ void c_typecheck_baset::typecheck_expr_alignof(exprt &expr) expr.swap(tmp); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_typecast - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_typecast(exprt &expr) { if(expr.operands().size()!=1) @@ -1318,8 +1158,8 @@ void c_typecheck_baset::typecheck_expr_typecast(exprt &expr) // an integer/float of the same size if((expr_type.id()==ID_signedbv || expr_type.id()==ID_unsignedbv) && - pointer_offset_size(expr_type, *this)== - pointer_offset_size(op_vector_type, *this)) + pointer_offset_bits(expr_type, *this)== + pointer_offset_bits(op_vector_type, *this)) { } else @@ -1354,35 +1194,11 @@ void c_typecheck_baset::typecheck_expr_typecast(exprt &expr) } } -/*******************************************************************\ - -Function: c_typecheck_baset::make_index_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::make_index_type(exprt &expr) { implicit_typecast(expr, index_type()); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_index - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_index(exprt &expr) { if(expr.operands().size()!=2) @@ -1443,18 +1259,6 @@ void c_typecheck_baset::typecheck_expr_index(exprt &expr) expr.type()=final_array_type.subtype(); } -/*******************************************************************\ - -Function: c_typecheck_baset::adjust_float_rel - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::adjust_float_rel(exprt &expr) { // equality and disequality on float is not mathematical equality! @@ -1469,18 +1273,6 @@ void c_typecheck_baset::adjust_float_rel(exprt &expr) } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_rel - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_rel( binary_relation_exprt &expr) { @@ -1587,18 +1379,6 @@ void c_typecheck_baset::typecheck_expr_rel( throw 0; } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_rel_vector - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_rel_vector( binary_relation_exprt &expr) { @@ -1625,18 +1405,6 @@ void c_typecheck_baset::typecheck_expr_rel_vector( expr.type()=vector_typet(signed_int_type(), to_vector_type(o_type0).size()); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_ptrmember - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_ptrmember(exprt &expr) { if(expr.operands().size()!=1) @@ -1672,18 +1440,6 @@ void c_typecheck_baset::typecheck_expr_ptrmember(exprt &expr) typecheck_expr_member(expr); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_member - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_member(exprt &expr) { if(expr.operands().size()!=1) @@ -1766,7 +1522,7 @@ void c_typecheck_baset::typecheck_expr_member(exprt &expr) // copy method identifier const irep_idt &identifier=component.get(ID_C_identifier); - if(identifier!=irep_idt()) + if(!identifier.empty()) expr.set(ID_C_identifier, identifier); const irep_idt &access=component.get_access(); @@ -1780,18 +1536,6 @@ void c_typecheck_baset::typecheck_expr_member(exprt &expr) } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_trinary - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_trinary(if_exprt &expr) { exprt::operandst &operands=expr.operands(); @@ -1885,18 +1629,6 @@ void c_typecheck_baset::typecheck_expr_trinary(if_exprt &expr) throw 0; } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_side_effect_gcc_conditional_expresssion - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_side_effect_gcc_conditional_expression( side_effect_exprt &expr) { @@ -1928,18 +1660,6 @@ void c_typecheck_baset::typecheck_side_effect_gcc_conditional_expression( expr.type()=if_expr.type(); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_address_of - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_address_of(exprt &expr) { if(expr.operands().size()!=1) @@ -2010,18 +1730,6 @@ void c_typecheck_baset::typecheck_expr_address_of(exprt &expr) expr.type()=pointer_type(op.type()); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_dereference - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_dereference(exprt &expr) { if(expr.operands().size()!=1) @@ -2065,42 +1773,17 @@ void c_typecheck_baset::typecheck_expr_dereference(exprt &expr) typecheck_expr_function_identifier(expr); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_function_identifier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_function_identifier(exprt &expr) { if(expr.type().id()==ID_code) { - exprt tmp(ID_address_of, pointer_type(expr.type())); + address_of_exprt tmp(expr, pointer_type(expr.type())); tmp.set(ID_C_implicit, true); tmp.add_source_location()=expr.source_location(); - tmp.move_to_operands(expr); - expr.swap(tmp); + expr=tmp; } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_side_effect - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_side_effect(side_effect_exprt &expr) { const irep_idt &statement=expr.get_statement(); @@ -2192,18 +1875,6 @@ void c_typecheck_baset::typecheck_expr_side_effect(side_effect_exprt &expr) } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_side_effect_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_side_effect_function_call( side_effect_expr_function_callt &expr) { @@ -2312,18 +1983,6 @@ void c_typecheck_baset::typecheck_side_effect_function_call( typecheck_function_call_arguments(expr); } -/*******************************************************************\ - -Function: c_typecheck_baset::do_special_functions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt c_typecheck_baset::do_special_functions( side_effect_expr_function_callt &expr) { @@ -2473,10 +2132,12 @@ exprt c_typecheck_baset::do_special_functions( throw 0; } - exprt pointer_offset_expr=exprt(ID_pointer_offset, expr.type()); - pointer_offset_expr.operands()=expr.arguments(); + exprt pointer_offset_expr=pointer_offset(expr.arguments().front()); pointer_offset_expr.add_source_location()=source_location; + if(expr.type()!=pointer_offset_expr.type()) + pointer_offset_expr.make_typecast(expr.type()); + return pointer_offset_expr; } else if(identifier==CPROVER_PREFIX "POINTER_OBJECT") @@ -2758,7 +2419,7 @@ exprt c_typecheck_baset::do_special_functions( exprt tmp; - // the followin means "don't know" + // the following means "don't know" if(arg1==0 || arg1==1) { tmp=from_integer(-1, size_type()); @@ -2904,7 +2565,7 @@ exprt c_typecheck_baset::do_special_functions( // http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Atomic-Builtins.html // adjust return type of function to match pointer subtype - if(expr.arguments().size()<1) + if(expr.arguments().empty()) { err_location(f_op); error() << "__sync_* primitives take as least one argument" << eom; @@ -2928,18 +2589,8 @@ exprt c_typecheck_baset::do_special_functions( return nil_exprt(); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_function_call_arguments - - Inputs: type-checked arguments, type-checked function - - Outputs: type-adjusted function arguments - - Purpose: - -\*******************************************************************/ - +/// \param type:checked arguments, type-checked function +/// \return type-adjusted function arguments void c_typecheck_baset::typecheck_function_call_arguments( side_effect_expr_function_callt &expr) { @@ -3022,35 +2673,11 @@ void c_typecheck_baset::typecheck_function_call_arguments( } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_constant - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_constant(exprt &expr) { // nothing to do } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_unary_arithmetic - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_unary_arithmetic(exprt &expr) { if(expr.operands().size()!=1) @@ -3090,18 +2717,6 @@ void c_typecheck_baset::typecheck_expr_unary_arithmetic(exprt &expr) throw 0; } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_unary_boolean - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_unary_boolean(exprt &expr) { if(expr.operands().size()!=1) @@ -3124,18 +2739,6 @@ void c_typecheck_baset::typecheck_expr_unary_boolean(exprt &expr) expr.type()=bool_typet(); } -/*******************************************************************\ - -Function: c_typecheck_baset::gcc_vector_types_compatible - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool c_typecheck_baset::gcc_vector_types_compatible( const vector_typet &type0, const vector_typet &type1) @@ -3151,7 +2754,7 @@ bool c_typecheck_baset::gcc_vector_types_compatible( if(s0!=s1) return false; - // comparse subtype + // compare subtype if((type0.subtype().id()==ID_signedbv || type0.subtype().id()==ID_unsignedbv) && (type1.subtype().id()==ID_signedbv || @@ -3163,18 +2766,6 @@ bool c_typecheck_baset::gcc_vector_types_compatible( return type0.subtype()==type1.subtype(); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_binary_arithmetic - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_binary_arithmetic(exprt &expr) { if(expr.operands().size()!=2) @@ -3276,18 +2867,6 @@ void c_typecheck_baset::typecheck_expr_binary_arithmetic(exprt &expr) throw 0; } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_shifts - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_shifts(shift_exprt &expr) { assert(expr.id()==ID_shl || expr.id()==ID_shr); @@ -3357,18 +2936,6 @@ void c_typecheck_baset::typecheck_expr_shifts(shift_exprt &expr) throw 0; } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_arithmetic_pointer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_arithmetic_pointer(const exprt &expr) { const typet &type=expr.type(); @@ -3387,18 +2954,6 @@ void c_typecheck_baset::typecheck_arithmetic_pointer(const exprt &expr) } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_pointer_arithmetic - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_pointer_arithmetic(exprt &expr) { assert(expr.operands().size()==2); @@ -3489,18 +3044,6 @@ void c_typecheck_baset::typecheck_expr_pointer_arithmetic(exprt &expr) throw 0; } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_expr_binary_boolean - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_expr_binary_boolean(exprt &expr) { if(expr.operands().size()!=2) @@ -3522,18 +3065,6 @@ void c_typecheck_baset::typecheck_expr_binary_boolean(exprt &expr) expr.type()=bool_typet(); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_side_effect_assignment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_side_effect_assignment( side_effect_exprt &expr) { @@ -3728,18 +3259,6 @@ void c_typecheck_baset::typecheck_side_effect_assignment( throw 0; } -/*******************************************************************\ - -Function: c_typecheck_baset::make_constant - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::make_constant(exprt &expr) { make_constant_rec(expr); @@ -3755,18 +3274,6 @@ void c_typecheck_baset::make_constant(exprt &expr) } } -/*******************************************************************\ - -Function: c_typecheck_baset::make_constant_index - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::make_constant_index(exprt &expr) { make_constant(expr); @@ -3782,18 +3289,6 @@ void c_typecheck_baset::make_constant_index(exprt &expr) } } -/*******************************************************************\ - -Function: c_typecheck_baset::make_constant_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::make_constant_rec(exprt &expr) { } diff --git a/src/ansi-c/c_typecheck_initializer.cpp b/src/ansi-c/c_typecheck_initializer.cpp index 79dabc9f0e9..1bc494c8d4a 100644 --- a/src/ansi-c/c_typecheck_initializer.cpp +++ b/src/ansi-c/c_typecheck_initializer.cpp @@ -6,8 +6,13 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// ANSI-C Conversion / Type Checking + +#include "c_typecheck_base.h" + #include -#include +#include #include #include #include @@ -16,23 +21,9 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "c_types.h" -#include "c_typecheck_base.h" #include "string_constant.h" #include "anonymous_member.h" -/*******************************************************************\ - -Function: c_typecheck_baset::do_initializer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::do_initializer( exprt &initializer, const typet &type, @@ -60,19 +51,7 @@ void c_typecheck_baset::do_initializer( initializer=result; } -/*******************************************************************\ - -Function: c_typecheck_baset::do_initializer_rec - - Inputs: - - Outputs: - - Purpose: initialize something of type `type' with given - value `value' - -\*******************************************************************/ - +/// initialize something of type `type' with given value `value' exprt c_typecheck_baset::do_initializer_rec( const exprt &value, const typet &type, @@ -230,18 +209,6 @@ exprt c_typecheck_baset::do_initializer_rec( return result; } -/*******************************************************************\ - -Function: c_typecheck_baset::do_initializer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::do_initializer(symbolt &symbol) { // this one doesn't need initialization @@ -285,25 +252,11 @@ void c_typecheck_baset::do_initializer(symbolt &symbol) } } -/*******************************************************************\ - -Function: c_typecheck_baset::designator_enter - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::designator_enter( const typet &type, designatort &designator) { - designatort::entryt entry; - entry.type=type; - entry.index=0; + designatort::entryt entry(type); const typet &full_type=follow(type); @@ -313,6 +266,8 @@ void c_typecheck_baset::designator_enter( entry.size=struct_type.components().size(); entry.subtype.make_nil(); + // only a top-level struct may end with a variable-length array + entry.vla_permitted=designator.empty(); for(struct_typet::componentst::const_iterator it=struct_type.components().begin(); @@ -340,7 +295,7 @@ void c_typecheck_baset::designator_enter( } else { - // The default is to unitialize using the first member of the + // The default is to initialize using the first member of the // union. entry.size=1; entry.subtype=union_type.components().front().type(); @@ -394,24 +349,18 @@ void c_typecheck_baset::designator_enter( designator.push_entry(entry); } -/*******************************************************************\ - -Function: c_typecheck_baset::do_designated_initializer - - Inputs: pre-initialized result, designator - - Outputs: sets result - - Purpose: - -\*******************************************************************/ - -void c_typecheck_baset::do_designated_initializer( +/// \param pre:initialized result, designator +/// \return sets result +exprt::operandst::const_iterator c_typecheck_baset::do_designated_initializer( exprt &result, designatort &designator, - const exprt &value, + const exprt &initializer_list, + exprt::operandst::const_iterator init_it, bool force_constant) { + // copy the value, we may need to adjust it + exprt value=*init_it; + assert(!designator.empty()); if(value.id()==ID_designated_initializer) @@ -425,8 +374,10 @@ void c_typecheck_baset::do_designated_initializer( assert(!designator.empty()); - return do_designated_initializer( - result, designator, value.op0(), force_constant); + // discard the return value + do_designated_initializer( + result, designator, value, value.operands().begin(), force_constant); + return ++init_it; } exprt *dest=&result; @@ -558,7 +509,7 @@ void c_typecheck_baset::do_designated_initializer( assert(full_type==follow(dest->type())); - return; // done + return ++init_it; // done } // union? The component in the zero initializer might @@ -592,7 +543,7 @@ void c_typecheck_baset::do_designated_initializer( if(value.id()==ID_initializer_list) { *dest=do_initializer_rec(value, type, force_constant); - return; // done + return ++init_it; // done } else if(value.id()==ID_string_constant) { @@ -604,7 +555,7 @@ void c_typecheck_baset::do_designated_initializer( follow(full_type.subtype()).id()==ID_unsignedbv)) { *dest=do_initializer_rec(value, type, force_constant); - return; // done + return ++init_it; // done } } else if(follow(value.type())==full_type) @@ -617,7 +568,7 @@ void c_typecheck_baset::do_designated_initializer( full_type.id()==ID_vector) { *dest=value; - return; // done + return ++init_it; // done } } @@ -627,36 +578,52 @@ void c_typecheck_baset::do_designated_initializer( full_type.id()==ID_vector); // we are initializing a compound type, and enter it! - // this may change the type, full_type might not be valid anymore + // this may change the type, full_type might not be valid any more const typet dest_type=full_type; + const bool vla_permitted=designator.back().vla_permitted; designator_enter(type, designator); + // GCC permits (though issuing a warning with -Wall) composite + // types built from flat initializer lists if(dest->operands().empty()) { - err_location(value); - error() << "cannot initialize type `" - << to_string(dest_type) << "' using value `" - << to_string(value) << "'" << eom; - throw 0; + warning().source_location=value.find_source_location(); + warning() << "initialisation of " << full_type.id() + << " requires initializer list, found " + << value.id() << " instead" << eom; + + // in case of a variable-length array consume all remaining + // initializer elements + if(vla_permitted && + dest_type.id()==ID_array && + (to_array_type(dest_type).size().is_zero() || + to_array_type(dest_type).size().is_nil())) + { + value.id(ID_initializer_list); + value.operands().clear(); + for( ; init_it!=initializer_list.operands().end(); ++init_it) + value.copy_to_operands(*init_it); + *dest=do_initializer_rec(value, dest_type, force_constant); + + return init_it; + } + else + { + err_location(value); + error() << "cannot initialize type `" + << to_string(dest_type) << "' using value `" + << to_string(value) << "'" << eom; + throw 0; + } } dest=&(dest->op0()); // we run into another loop iteration } -} - -/*******************************************************************\ - -Function: c_typecheck_baset::increment_designator - - Inputs: - Outputs: - - Purpose: - -\*******************************************************************/ + return ++init_it; +} void c_typecheck_baset::increment_designator(designatort &designator) { @@ -706,18 +673,6 @@ void c_typecheck_baset::increment_designator(designatort &designator) } } -/*******************************************************************\ - -Function: c_typecheck_baset::make_designator - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - designatort c_typecheck_baset::make_designator( const typet &src_type, const exprt &src) @@ -730,8 +685,7 @@ designatort c_typecheck_baset::make_designator( forall_operands(it, src) { const exprt &d_op=*it; - designatort::entryt entry; - entry.type=type; + designatort::entryt entry(type); const typet &full_type=follow(entry.type); if(full_type.id()==ID_array) @@ -865,18 +819,6 @@ designatort c_typecheck_baset::make_designator( return designator; } -/*******************************************************************\ - -Function: c_typecheck_baset::do_initializer_list - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt c_typecheck_baset::do_initializer_list( const exprt &value, const typet &type, @@ -947,10 +889,12 @@ exprt c_typecheck_baset::do_initializer_list( designator_enter(type, current_designator); - forall_operands(it, value) + const exprt::operandst &operands=value.operands(); + for(exprt::operandst::const_iterator it=operands.begin(); + it!=operands.end(); ) // no ++it { - do_designated_initializer( - result, current_designator, *it, force_constant); + it=do_designated_initializer( + result, current_designator, value, it, force_constant); // increase designator -- might go up increment_designator(current_designator); diff --git a/src/ansi-c/c_typecheck_type.cpp b/src/ansi-c/c_typecheck_type.cpp index ac3fe7f2928..5195e653364 100644 --- a/src/ansi-c/c_typecheck_type.cpp +++ b/src/ansi-c/c_typecheck_type.cpp @@ -6,16 +6,21 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// C++ Language Type Checking + +#include "c_typecheck_base.h" + #include +#include #include +#include #include #include #include #include -#include "c_typecheck_base.h" -#include "c_types.h" #include "c_sizeof.h" #include "c_qualifiers.h" #include "ansi_c_declaration.h" @@ -23,18 +28,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "type2name.h" #include "ansi_c_convert_type.h" -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_type(typet &type) { // we first convert, and then check @@ -109,7 +102,7 @@ void c_typecheck_baset::typecheck_type(typet &type) // get that mode irep_idt mode=type.get(ID_size); - // A list of all modes ist at + // A list of all modes is at // http://www.delorie.com/gnu/docs/gcc/gccint_53.html typecheck_type(type.subtype()); @@ -134,39 +127,74 @@ void c_typecheck_baset::typecheck_type(typet &type) typet result; if(mode=="__QI__") // 8 bits - result=is_signed?signed_char_type():unsigned_char_type(); + if(is_signed) + result=signed_char_type(); + else + result=unsigned_char_type(); else if(mode=="__byte__") // 8 bits - result=is_signed?signed_char_type():unsigned_char_type(); + if(is_signed) + result=signed_char_type(); + else + result=unsigned_char_type(); else if(mode=="__HI__") // 16 bits - result=is_signed?signed_short_int_type():unsigned_short_int_type(); + if(is_signed) + result=signed_short_int_type(); + else + result=unsigned_short_int_type(); else if(mode=="__SI__") // 32 bits - result=is_signed?signed_int_type():unsigned_int_type(); + if(is_signed) + result=signed_int_type(); + else + result=unsigned_int_type(); else if(mode=="__word__") // long int, we think - result=is_signed?signed_long_int_type():unsigned_long_int_type(); + if(is_signed) + result=signed_long_int_type(); + else + result=unsigned_long_int_type(); else if(mode=="__pointer__") // we think this is size_t/ssize_t - result=is_signed?signed_size_type():size_type(); + if(is_signed) + result=signed_size_type(); + else + result=size_type(); else if(mode=="__DI__") // 64 bits { if(config.ansi_c.long_int_width==64) - result=is_signed?signed_long_int_type():unsigned_long_int_type(); + if(is_signed) + result=signed_long_int_type(); + else + result=unsigned_long_int_type(); else { assert(config.ansi_c.long_long_int_width==64); - result= - is_signed?signed_long_long_int_type():unsigned_long_long_int_type(); + + if(is_signed) + result=signed_long_long_int_type(); + else + result=unsigned_long_long_int_type(); } } else if(mode=="__TI__") // 128 bits - result=is_signed?gcc_signed_int128_type():gcc_unsigned_int128_type(); + if(is_signed) + result=gcc_signed_int128_type(); + else + result=gcc_unsigned_int128_type(); else if(mode=="__V2SI__") // vector of 2 ints, deprecated by gcc - result= - vector_typet( - is_signed?signed_int_type():unsigned_int_type(), + if(is_signed) + result=vector_typet( + signed_int_type(), + from_integer(2, size_type())); + else + result=vector_typet( + unsigned_int_type(), from_integer(2, size_type())); else if(mode=="__V4SI__") // vector of 4 ints, deprecated by gcc - result= - vector_typet( - is_signed?signed_int_type():unsigned_int_type(), + if(is_signed) + result=vector_typet( + signed_int_type(), + from_integer(4, size_type())); + else + result=vector_typet( + unsigned_int_type(), from_integer(4, size_type())); else // give up, just use subtype result=type.subtype(); @@ -255,18 +283,6 @@ void c_typecheck_baset::typecheck_type(typet &type) } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_custom_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_custom_type(typet &type) { // they all have a width @@ -367,18 +383,6 @@ void c_typecheck_baset::typecheck_custom_type(typet &type) assert(false); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_code_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_code_type(code_typet &type) { // the return type is still 'subtype()' @@ -426,7 +430,7 @@ void c_typecheck_baset::typecheck_code_type(code_typet &type) irep_idt identifier=declaration.declarator().get_name(); // abstract or not? - if(identifier==irep_idt()) + if(identifier.empty()) { // abstract parameter.add_source_location()=declaration.type().source_location(); @@ -478,18 +482,6 @@ void c_typecheck_baset::typecheck_code_type(code_typet &type) } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_array_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_array_type(array_typet &type) { exprt &size=type.size(); @@ -560,9 +552,15 @@ void c_typecheck_baset::typecheck_array_type(array_typet &type) { // not a constant and not infinity - assert(current_symbol_id!=irep_idt()); + PRECONDITION(!current_symbol.name.empty()); - const symbolt &base_symbol=lookup(current_symbol_id); + if(current_symbol.is_static_lifetime) + { + error().source_location=current_symbol.location; + error() << "array size of static symbol `" + << current_symbol.base_name << "' is not constant" << eom; + throw 0; + } // Need to pull out! We insert new symbol. source_locationt source_location=size.find_source_location(); @@ -573,7 +571,7 @@ void c_typecheck_baset::typecheck_array_type(array_typet &type) do { suffix="$array_size"+std::to_string(count); - temp_identifier=id2string(base_symbol.name)+suffix; + temp_identifier=id2string(current_symbol.name)+suffix; count++; } while(symbol_table.symbols.find(temp_identifier)!= @@ -582,13 +580,13 @@ void c_typecheck_baset::typecheck_array_type(array_typet &type) // add the symbol to symbol table auxiliary_symbolt new_symbol; new_symbol.name=temp_identifier; - new_symbol.pretty_name=id2string(base_symbol.pretty_name)+suffix; - new_symbol.base_name=id2string(base_symbol.base_name)+suffix; + new_symbol.pretty_name=id2string(current_symbol.pretty_name)+suffix; + new_symbol.base_name=id2string(current_symbol.base_name)+suffix; new_symbol.type=size.type(); new_symbol.type.set(ID_C_constant, true); new_symbol.is_type=false; new_symbol.is_static_lifetime=false; - new_symbol.value.make_nil(); + new_symbol.value=size; new_symbol.location=source_location; symbol_table.add(new_symbol); @@ -616,18 +614,6 @@ void c_typecheck_baset::typecheck_array_type(array_typet &type) } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_vector_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_vector_type(vector_typet &type) { exprt &size=type.size(); @@ -709,18 +695,6 @@ void c_typecheck_baset::typecheck_vector_type(vector_typet &type) type.size()=from_integer(s, signed_size_type()); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_compound_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_compound_type(struct_union_typet &type) { // These get replaced by symbol types later. @@ -833,18 +807,6 @@ void c_typecheck_baset::typecheck_compound_type(struct_union_typet &type) original_qualifiers.write(type); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_compound_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_compound_body( struct_union_typet &type) { @@ -908,7 +870,7 @@ void c_typecheck_baset::typecheck_compound_body( // scan for anonymous members, and name them for(auto &member : components) { - if(member.get_name()!=irep_idt()) + if(!member.get_name().empty()) continue; member.set_name("$anon"+std::to_string(anon_member_counter++)); @@ -1021,18 +983,6 @@ void c_typecheck_baset::typecheck_compound_body( } } -/*******************************************************************\ - -Function: c_typecheck_baset::enum_constant_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet c_typecheck_baset::enum_constant_type( const mp_integer &min_value, const mp_integer &max_value) const @@ -1065,18 +1015,6 @@ typet c_typecheck_baset::enum_constant_type( } } -/*******************************************************************\ - -Function: c_typecheck_baset::enum_underlying_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet c_typecheck_baset::enum_underlying_type( const mp_integer &min_value, const mp_integer &max_value, @@ -1135,18 +1073,6 @@ typet c_typecheck_baset::enum_underlying_type( } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_c_enum_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_c_enum_type(typet &type) { // These come with the declarations @@ -1330,18 +1256,6 @@ void c_typecheck_baset::typecheck_c_enum_type(typet &type) type.set(ID_identifier, identifier); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_c_enum_tag_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_c_enum_tag_type(c_enum_tag_typet &type) { // It's just a tag. @@ -1401,18 +1315,6 @@ void c_typecheck_baset::typecheck_c_enum_tag_type(c_enum_tag_typet &type) type.set_identifier(identifier); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_c_bit_field_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_c_bit_field_type(c_bit_field_typet &type) { typecheck_type(type.subtype()); @@ -1493,18 +1395,6 @@ void c_typecheck_baset::typecheck_c_bit_field_type(c_bit_field_typet &type) } } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_typeof_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_typeof_type(typet &type) { // save location @@ -1542,18 +1432,6 @@ void c_typecheck_baset::typecheck_typeof_type(typet &type) c_qualifiers.write(type); } -/*******************************************************************\ - -Function: c_typecheck_baset::typecheck_symbol_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::typecheck_symbol_type(typet &type) { const irep_idt &identifier= @@ -1608,18 +1486,6 @@ void c_typecheck_baset::typecheck_symbol_type(typet &type) } } -/*******************************************************************\ - -Function: c_typecheck_baset::adjust_function_parameter - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::adjust_function_parameter(typet &type) const { if(type.id()==ID_array) @@ -1632,9 +1498,7 @@ void c_typecheck_baset::adjust_function_parameter(typet &type) const { // see ISO/IEC 9899:1999 page 199 clause 8, // may be hidden in typedef - pointer_typet tmp; - tmp.subtype()=type; - type.swap(tmp); + type=pointer_type(type); } else if(type.id()==ID_KnR) { diff --git a/src/ansi-c/c_typecheck_typecast.cpp b/src/ansi-c/c_typecheck_typecast.cpp index 5d1cfad1332..2ce03d83f18 100644 --- a/src/ansi-c/c_typecheck_typecast.cpp +++ b/src/ansi-c/c_typecheck_typecast.cpp @@ -6,21 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "c_typecast.h" #include "c_typecheck_base.h" -#include "c_types.h" - -/*******************************************************************\ - -Function: c_typecheck_baset::implicit_typecast - - Inputs: - - Outputs: - - Purpose: -\*******************************************************************/ +#include "c_typecast.h" void c_typecheck_baset::implicit_typecast( exprt &expr, @@ -62,18 +50,6 @@ void c_typecheck_baset::implicit_typecast( } } -/*******************************************************************\ - -Function: c_typecheck_baset::implicit_typecast_arithmetic - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::implicit_typecast_arithmetic( exprt &expr1, exprt &expr2) @@ -82,18 +58,6 @@ void c_typecheck_baset::implicit_typecast_arithmetic( c_typecast.implicit_typecast_arithmetic(expr1, expr2); } -/*******************************************************************\ - -Function: c_typecheck_baset::implicit_typecast_arithmetic - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void c_typecheck_baset::implicit_typecast_arithmetic(exprt &expr) { c_typecastt c_typecast(*this); diff --git a/src/ansi-c/c_types.cpp b/src/ansi-c/c_types.cpp deleted file mode 100644 index 6ba5ddaefb3..00000000000 --- a/src/ansi-c/c_types.cpp +++ /dev/null @@ -1,721 +0,0 @@ -/*******************************************************************\ - -Module: - -Author: Daniel Kroening, kroening@kroening.com - -\*******************************************************************/ - -#include -#include - -#include "c_types.h" - -/*******************************************************************\ - -Function: index_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet index_type() -{ - // same as signed size type - return signed_size_type(); -} - -/*******************************************************************\ - -Function: enum_constant_type - - Inputs: - - Outputs: - - Purpose: return type of enum constants - -\*******************************************************************/ - -typet enum_constant_type() -{ - // usually same as 'int', - // but might be unsigned, or shorter than 'int' - return signed_int_type(); -} - -/*******************************************************************\ - -Function: signed_int_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet signed_int_type() -{ - typet result=signedbv_typet(config.ansi_c.int_width); - result.set(ID_C_c_type, ID_signed_int); - return result; -} - -/*******************************************************************\ - -Function: signed_short_int_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet signed_short_int_type() -{ - typet result=signedbv_typet(config.ansi_c.short_int_width); - result.set(ID_C_c_type, ID_signed_short_int); - return result; -} - -/*******************************************************************\ - -Function: unsigned_int_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet unsigned_int_type() -{ - typet result=unsignedbv_typet(config.ansi_c.int_width); - result.set(ID_C_c_type, ID_unsigned_int); - return result; -} - -/*******************************************************************\ - -Function: unsigned_short_int_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet unsigned_short_int_type() -{ - typet result=unsignedbv_typet(config.ansi_c.short_int_width); - result.set(ID_C_c_type, ID_unsigned_short_int); - return result; -} - -/*******************************************************************\ - -Function: size_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet size_type() -{ - // The size type varies. This is unsigned int on some systems, - // and unsigned long int on others, - // and unsigned long long on say Windows 64. - - if(config.ansi_c.pointer_width==config.ansi_c.int_width) - return unsigned_int_type(); - else if(config.ansi_c.pointer_width==config.ansi_c.long_int_width) - return unsigned_long_int_type(); - else if(config.ansi_c.pointer_width==config.ansi_c.long_long_int_width) - return unsigned_long_long_int_type(); - else - assert(false); // aaah! -} - -/*******************************************************************\ - -Function: signed_size_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet signed_size_type() -{ - // we presume this is the same as pointer difference - return pointer_diff_type(); -} - -/*******************************************************************\ - -Function: signed_long_int_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet signed_long_int_type() -{ - typet result=signedbv_typet(config.ansi_c.long_int_width); - result.set(ID_C_c_type, ID_signed_long_int); - return result; -} - -/*******************************************************************\ - -Function: signed_long_long_int_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet signed_long_long_int_type() -{ - typet result=signedbv_typet(config.ansi_c.long_long_int_width); - result.set(ID_C_c_type, ID_signed_long_long_int); - return result; -} - -/*******************************************************************\ - -Function: unsigned_long_int_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet unsigned_long_int_type() -{ - typet result=unsignedbv_typet(config.ansi_c.long_int_width); - result.set(ID_C_c_type, ID_unsigned_long_int); - return result; -} - -/*******************************************************************\ - -Function: unsigned_long_long_int_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet unsigned_long_long_int_type() -{ - typet result=unsignedbv_typet(config.ansi_c.long_long_int_width); - result.set(ID_C_c_type, ID_unsigned_long_long_int); - return result; -} - -/*******************************************************************\ - -Function: c_bool_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet c_bool_type() -{ - typet result=c_bool_typet(config.ansi_c.bool_width); - return result; -} - -/*******************************************************************\ - -Function: char_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet char_type() -{ - typet result; - - // this can be signed or unsigned, depending on the architecture - - if(config.ansi_c.char_is_unsigned) - result=unsignedbv_typet(config.ansi_c.char_width); - else - result=signedbv_typet(config.ansi_c.char_width); - - // There are 3 char types, i.e., this one is - // different from either signed char or unsigned char! - - result.set(ID_C_c_type, ID_char); - - return result; -} - -/*******************************************************************\ - -Function: unsigned_char_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet unsigned_char_type() -{ - typet result=unsignedbv_typet(config.ansi_c.char_width); - - result.set(ID_C_c_type, ID_unsigned_char); - - return result; -} - -/*******************************************************************\ - -Function: signed_char_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet signed_char_type() -{ - typet result=signedbv_typet(config.ansi_c.char_width); - - result.set(ID_C_c_type, ID_signed_char); - - return result; -} - -/*******************************************************************\ - -Function: wchar_t_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet wchar_t_type() -{ - typet result; - - if(config.ansi_c.wchar_t_is_unsigned) - result=unsignedbv_typet(config.ansi_c.wchar_t_width); - else - result=signedbv_typet(config.ansi_c.wchar_t_width); - - result.set(ID_C_c_type, ID_wchar_t); - - return result; -} - -/*******************************************************************\ - -Function: char16_t_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet char16_t_type() -{ - typet result; - - // Types char16_t and char32_t denote distinct types with the same size, - // signedness, and alignment as uint_least16_t and uint_least32_t, - // respectively, in , called the underlying types. - result=unsignedbv_typet(16); - - result.set(ID_C_c_type, ID_char16_t); - - return result; -} - -/*******************************************************************\ - -Function: char32_t_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet char32_t_type() -{ - typet result; - - // Types char16_t and char32_t denote distinct types with the same size, - // signedness, and alignment as uint_least16_t and uint_least32_t, - // respectively, in , called the underlying types. - result=unsignedbv_typet(32); - - result.set(ID_C_c_type, ID_char32_t); - - return result; -} - -/*******************************************************************\ - -Function: float_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet float_type() -{ - typet result; - - if(config.ansi_c.use_fixed_for_float) - { - fixedbv_typet tmp; - tmp.set_width(config.ansi_c.single_width); - tmp.set_integer_bits(config.ansi_c.single_width/2); - result=tmp; - } - else - result=ieee_float_spect::single_precision().to_type(); - - result.set(ID_C_c_type, ID_float); - - return result; -} - -/*******************************************************************\ - -Function: double_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet double_type() -{ - typet result; - - if(config.ansi_c.use_fixed_for_float) - { - fixedbv_typet tmp; - tmp.set_width(config.ansi_c.double_width); - tmp.set_integer_bits(config.ansi_c.double_width/2); - result=tmp; - } - else - result=ieee_float_spect::double_precision().to_type(); - - result.set(ID_C_c_type, ID_double); - - return result; -} - -/*******************************************************************\ - -Function: long_double_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet long_double_type() -{ - typet result; - - if(config.ansi_c.use_fixed_for_float) - { - fixedbv_typet tmp; - tmp.set_width(config.ansi_c.long_double_width); - tmp.set_integer_bits(config.ansi_c.long_double_width/2); - result=tmp; - } - else - { - if(config.ansi_c.long_double_width==128) - result=ieee_float_spect::quadruple_precision().to_type(); - else if(config.ansi_c.long_double_width==64) - result=ieee_float_spect::double_precision().to_type(); - else if(config.ansi_c.long_double_width==80) - { - // x86 extended precision has 80 bits in total, and - // deviating from IEEE, does not use a hidden bit. - // We use the closest we have got, but the below isn't accurate. - result=ieee_float_spect(63, 15).to_type(); - } - else if(config.ansi_c.long_double_width==96) - { - result=ieee_float_spect(80, 15).to_type(); - // not quite right. The extra bits beyond 80 are usually padded. - } - else - assert(false); - } - - result.set(ID_C_c_type, ID_long_double); - - return result; -} - -/*******************************************************************\ - -Function: gcc_float128_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet gcc_float128_type() -{ - typet result; - - if(config.ansi_c.use_fixed_for_float) - { - fixedbv_typet tmp; - tmp.set_width(128); - tmp.set_integer_bits(128/2); - result=tmp; - } - else - { - result=ieee_float_spect::quadruple_precision().to_type(); - } - - // not same as long double! - result.set(ID_C_c_type, ID_gcc_float128); - - return result; -} - -/*******************************************************************\ - -Function: pointer_diff_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet pointer_diff_type() -{ - // The pointer-diff type varies. This is signed int on some systems, - // and signed long int on others, and signed long long on say Windows. - - if(config.ansi_c.pointer_width==config.ansi_c.int_width) - return signed_int_type(); - else if(config.ansi_c.pointer_width==config.ansi_c.long_int_width) - return signed_long_int_type(); - else if(config.ansi_c.pointer_width==config.ansi_c.long_long_int_width) - return signed_long_long_int_type(); - else - assert(false); // aaah! -} - -/*******************************************************************\ - -Function: pointer_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet pointer_type(const typet &subtype) -{ - return pointer_typet(subtype); -} - -/*******************************************************************\ - -Function: void_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet void_type() -{ - return empty_typet(); -} - -/*******************************************************************\ - -Function: gcc_unsigned_int128_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet gcc_unsigned_int128_type() -{ - typet result=unsignedbv_typet(128); - result.set(ID_C_c_type, ID_unsigned_int128); - return result; -} - -/*******************************************************************\ - -Function: gcc_signed_int128_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -typet gcc_signed_int128_type() -{ - typet result=signedbv_typet(128); - result.set(ID_C_c_type, ID_signed_int128); - return result; -} - -/*******************************************************************\ - -Function: c_type_as_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -std::string c_type_as_string(const irep_idt &c_type) -{ - if(c_type==ID_signed_int) - return "signed int"; - else if(c_type==ID_signed_short_int) - return "signed short int"; - else if(c_type==ID_unsigned_int) - return "unsigned int"; - else if(c_type==ID_unsigned_short_int) - return "unsigned short int"; - else if(c_type==ID_signed_long_int) - return "signed long int"; - else if(c_type==ID_signed_long_long_int) - return "signed long long int"; - else if(c_type==ID_unsigned_long_int) - return "unsigned long int"; - else if(c_type==ID_unsigned_long_long_int) - return "unsigned long long int"; - else if(c_type==ID_bool) - return "_Bool"; - else if(c_type==ID_char) - return "char"; - else if(c_type==ID_unsigned_char) - return "unsigned char"; - else if(c_type==ID_signed_char) - return "signed char"; - else if(c_type==ID_wchar_t) - return "wchar_t"; - else if(c_type==ID_char16_t) - return "char16_t"; - else if(c_type==ID_char32_t) - return "char32_t"; - else if(c_type==ID_float) - return "float"; - else if(c_type==ID_double) - return "double"; - else if(c_type==ID_long_double) - return "long double"; - else if(c_type==ID_gcc_float128) - return "__float128"; - else if(c_type==ID_unsigned_int128) - return "unsigned __int128"; - else if(c_type==ID_signed_int128) - return "signed __int128"; - else - return ""; -} diff --git a/src/ansi-c/c_types.h b/src/ansi-c/c_types.h deleted file mode 100644 index 6c571bd448b..00000000000 --- a/src/ansi-c/c_types.h +++ /dev/null @@ -1,47 +0,0 @@ -/*******************************************************************\ - -Module: - -Author: Daniel Kroening, kroening@kroening.com - -\*******************************************************************/ - -#ifndef CPROVER_ANSI_C_C_TYPES_H -#define CPROVER_ANSI_C_C_TYPES_H - -#include - -typet index_type(); -typet enum_constant_type(); -typet signed_int_type(); -typet unsigned_int_type(); -typet signed_long_int_type(); -typet signed_short_int_type(); -typet unsigned_short_int_type(); -typet signed_long_long_int_type(); -typet unsigned_long_int_type(); -typet unsigned_long_long_int_type(); -typet c_bool_type(); -typet char_type(); -typet unsigned_char_type(); -typet signed_char_type(); -typet wchar_t_type(); -typet char16_t_type(); -typet char32_t_type(); -typet float_type(); -typet double_type(); -typet long_double_type(); -typet gcc_float128_type(); -typet gcc_unsigned_int128_type(); -typet gcc_signed_int128_type(); -typet size_type(); -typet signed_size_type(); -typet pointer_diff_type(); -typet pointer_type(const typet &); -typet void_type(); - -// Turns an ID_C_c_type into a string, e.g., -// ID_signed_int gets "signed int". -std::string c_type_as_string(const irep_idt &); - -#endif // CPROVER_ANSI_C_C_TYPES_H diff --git a/src/ansi-c/clang_builtin_headers.h b/src/ansi-c/clang_builtin_headers.h index 9d266dda42e..742cba71dbf 100644 --- a/src/ansi-c/clang_builtin_headers.h +++ b/src/ansi-c/clang_builtin_headers.h @@ -1,3 +1,5 @@ typedef float __gcc_v4sf __attribute__ ((__vector_size__ (16))); __gcc_v4sf __builtin_shufflevector(__gcc_v4sf, __gcc_v4sf, ...); + +int __builtin_flt_rounds(void); diff --git a/src/ansi-c/cprover_library.cpp b/src/ansi-c/cprover_library.cpp index 382ec324636..f13e321d752 100644 --- a/src/ansi-c/cprover_library.cpp +++ b/src/ansi-c/cprover_library.cpp @@ -6,11 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "cprover_library.h" + #include #include -#include "cprover_library.h" #include "ansi_c_language.h" struct cprover_library_entryt @@ -21,18 +22,6 @@ struct cprover_library_entryt #include "cprover_library.inc" ; // NOLINT(whitespace/semicolon) -/*******************************************************************\ - -Function: get_cprover_library_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string get_cprover_library_text( const std::set &functions, const symbol_tablet &symbol_table) @@ -49,7 +38,7 @@ std::string get_cprover_library_text( std::size_t count=0; for(cprover_library_entryt *e=cprover_library; - e->function!=NULL; + e->function!=nullptr; e++) { irep_idt id=e->function; @@ -74,18 +63,6 @@ std::string get_cprover_library_text( return library_text.str(); } -/*******************************************************************\ - -Function: add_cprover_library - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void add_cprover_library( const std::set &functions, symbol_tablet &symbol_table, @@ -101,18 +78,6 @@ void add_cprover_library( add_library(library_text, symbol_table, message_handler); } -/*******************************************************************\ - -Function: add_library - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void add_library( const std::string &src, symbol_tablet &symbol_table, diff --git a/src/ansi-c/cprover_library.h b/src/ansi-c/cprover_library.h index 9b6012cbeef..6f36eb5abca 100644 --- a/src/ansi-c/cprover_library.h +++ b/src/ansi-c/cprover_library.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_ANSI_C_CPROVER_LIBRARY_H #define CPROVER_ANSI_C_CPROVER_LIBRARY_H diff --git a/src/ansi-c/designator.cpp b/src/ansi-c/designator.cpp index 88657e71407..d3902115a68 100644 --- a/src/ansi-c/designator.cpp +++ b/src/ansi-c/designator.cpp @@ -6,21 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// ANSI-C Language Type Checking #include "designator.h" -/*******************************************************************\ - -Function: designatort::print - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void designatort::print(std::ostream &out) const { diff --git a/src/ansi-c/designator.h b/src/ansi-c/designator.h index 019f622ef63..957bbbb6821 100644 --- a/src/ansi-c/designator.h +++ b/src/ansi-c/designator.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// ANSI-C Language Type Checking + #ifndef CPROVER_ANSI_C_DESIGNATOR_H #define CPROVER_ANSI_C_DESIGNATOR_H @@ -21,9 +24,11 @@ class designatort { size_t index; size_t size; + bool vla_permitted; typet type, subtype; - entryt():index(0), size(0) + explicit entryt(const typet &type): + index(0), size(0), vla_permitted(false), type(type) { } }; diff --git a/src/ansi-c/expr2c.cpp b/src/ansi-c/expr2c.cpp index abcd7e3bbb8..4db1985b07e 100644 --- a/src/ansi-c/expr2c.cpp +++ b/src/ansi-c/expr2c.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "expr2c.h" + #include #include #include @@ -20,6 +22,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include +#include #include #include #include @@ -36,8 +39,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "c_misc.h" #include "c_qualifiers.h" -#include "expr2c.h" -#include "c_types.h" #include "expr2c_class.h" /* @@ -51,18 +52,6 @@ Precedences are as follows. Higher values mean higher precedence. */ -/*******************************************************************\ - -Function: expr2ct::id_shorthand - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - irep_idt expr2ct::id_shorthand(const irep_idt &identifier) const { const symbolt *symbol; @@ -81,18 +70,6 @@ irep_idt expr2ct::id_shorthand(const irep_idt &identifier) const return sh; } -/*******************************************************************\ - -Function: clean_identifier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static std::string clean_identifier(const irep_idt &id) { std::string dest=id2string(id); @@ -115,18 +92,6 @@ static std::string clean_identifier(const irep_idt &id) return dest; } -/*******************************************************************\ - -Function: expr2ct::get_shorthands - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void expr2ct::get_shorthands(const exprt &expr) { find_symbols_sett symbols; @@ -190,36 +155,12 @@ void expr2ct::get_shorthands(const exprt &expr) } } -/*******************************************************************\ - -Function: expr2ct::convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert(const typet &src) { assert(next_pretty_printer && "Next pretty-printer should be set"); return convert_rec(src, c_qualifierst(), ""); } -/*******************************************************************\ - -Function: expr2ct::convert_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_rec( const typet &src, const c_qualifierst &qualifiers, @@ -618,6 +559,14 @@ std::string expr2ct::convert_rec( c_qualifierst ret_qualifiers; ret_qualifiers.read(code_type.return_type()); + // _Noreturn should go with the return type + if(new_qualifiers.is_noreturn) + { + ret_qualifiers.is_noreturn=true; + new_qualifiers.is_noreturn=false; + q=new_qualifiers.as_string(); + } + const typet &return_type=code_type.return_type(); // return type may be a function pointer or array @@ -688,21 +637,12 @@ std::string expr2ct::convert_rec( return next_pretty_printer->convert(src); } -/*******************************************************************\ - -Function: expr2ct::convert_struct_type - - Inputs: - src - the struct type being converted - qualifiers - any qualifiers on the type - declarator - the declarator on the type - - Outputs: Returns a type declaration for a struct, containing the - body of the struct and in that body the padding parameters. - - Purpose: To generate C-like string for defining the given struct - -\*******************************************************************/ +/// To generate C-like string for defining the given struct +/// \param src: the struct type being converted +/// \param qualifiers: any qualifiers on the type +/// \param declarator: the declarator on the type +/// \return Returns a type declaration for a struct, containing the body of the +/// struct and in that body the padding parameters. std::string expr2ct::convert_struct_type( const typet &src, const std::string &qualifiers_str, @@ -711,26 +651,16 @@ std::string expr2ct::convert_struct_type( return convert_struct_type(src, qualifiers_str, declarator_str, true, true); } -/*******************************************************************\ - -Function: expr2ct::convert_struct_type - - Inputs: - src - the struct type being converted - qualifiers - any qualifiers on the type - declarator - the declarator on the type - inc_struct_body - when generating the code, should we include - a complete definition of the struct - inc_padding_components - should the padding parameters be included - Note this only makes sense if inc_struct_body - - Outputs: Returns a type declaration for a struct, optionally containing the - body of the struct (and in that body, optionally the padding - parameters). - - Purpose: To generate C-like string for declaring (or defining) the given struct - -\*******************************************************************/ +/// To generate C-like string for declaring (or defining) the given struct +/// \param src: the struct type being converted +/// \param qualifiers: any qualifiers on the type +/// \param declarator: the declarator on the type +/// \param inc_struct_body: when generating the code, should we include a +/// complete definition of the struct +/// \param inc_padding_components: should the padding parameters be included +/// Note this only makes sense if inc_struct_body +/// \return Returns a type declaration for a struct, optionally containing the +/// body of the struct (and in that body, optionally the padding parameters). std::string expr2ct::convert_struct_type( const typet &src, const std::string &qualifiers, @@ -780,22 +710,12 @@ std::string expr2ct::convert_struct_type( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_array_type - - Inputs: - src - The array type to convert - qualifier - declarator_str - - Outputs: A C-like type declaration of an array - - Purpose: To generate a C-like type declaration of an array. Includes - the size of the array in the [] - -\*******************************************************************/ - +/// To generate a C-like type declaration of an array. Includes the size of the +/// array in the [] +/// \param src: The array type to convert +/// qualifier +/// declarator_str +/// \return A C-like type declaration of an array std::string expr2ct::convert_array_type( const typet &src, const c_qualifierst &qualifiers, @@ -804,24 +724,14 @@ std::string expr2ct::convert_array_type( return convert_array_type(src, qualifiers, declarator_str, true); } -/*******************************************************************\ - -Function: expr2ct::convert_array_type - - Inputs: - src - The array type to convert - qualifier - declarator_str - inc_size_if_possible - Should the generated string include - the size of the array (if it is known). - - Outputs: A C-like type declaration of an array - - Purpose: To generate a C-like type declaration of an array. Optionally - can include or exclude the size of the array in the [] - -\*******************************************************************/ - +/// To generate a C-like type declaration of an array. Optionally can include or +/// exclude the size of the array in the [] +/// \param src: The array type to convert +/// qualifier +/// declarator_str +/// \param inc_size_if_possible: Should the generated string include the size of +/// the array (if it is known). +/// \return A C-like type declaration of an array std::string expr2ct::convert_array_type( const typet &src, const c_qualifierst &qualifiers, @@ -842,18 +752,6 @@ std::string expr2ct::convert_array_type( src.subtype(), qualifiers, declarator_str+array_suffix); } -/*******************************************************************\ - -Function: expr2ct::convert_typecast - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_typecast( const typecast_exprt &src, unsigned &precedence) @@ -888,18 +786,6 @@ std::string expr2ct::convert_typecast( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_trinary - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_trinary( const exprt &src, const std::string &symbol1, @@ -951,18 +837,6 @@ std::string expr2ct::convert_trinary( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_quantifier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_quantifier( const exprt &src, const std::string &symbol, @@ -985,18 +859,6 @@ std::string expr2ct::convert_quantifier( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_with - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_with( const exprt &src, unsigned precedence) @@ -1065,18 +927,6 @@ std::string expr2ct::convert_with( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_update - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_update( const exprt &src, unsigned precedence) @@ -1121,18 +971,6 @@ std::string expr2ct::convert_update( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_cond - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_cond( const exprt &src, unsigned precedence) @@ -1167,18 +1005,6 @@ std::string expr2ct::convert_cond( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_binary - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_binary( const exprt &src, const std::string &symbol, @@ -1228,18 +1054,6 @@ std::string expr2ct::convert_binary( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_unary - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_unary( const exprt &src, const std::string &symbol, @@ -1263,18 +1077,6 @@ std::string expr2ct::convert_unary( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_pointer_object_has_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_pointer_object_has_type( const exprt &src, unsigned precedence) @@ -1295,18 +1097,6 @@ std::string expr2ct::convert_pointer_object_has_type( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_malloc - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_malloc( const exprt &src, unsigned &precedence) @@ -1333,18 +1123,6 @@ std::string expr2ct::convert_malloc( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_nondet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_nondet( const exprt &src, unsigned &precedence) @@ -1355,18 +1133,6 @@ std::string expr2ct::convert_nondet( return "NONDET("+convert(src.type())+")"; } -/*******************************************************************\ - -Function: expr2ct::convert_statement_expression - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_statement_expression( const exprt &src, unsigned &precedence) @@ -1378,18 +1144,6 @@ std::string expr2ct::convert_statement_expression( return "("+convert_code(to_code_block(to_code(src.op0())), 0)+")"; } -/*******************************************************************\ - -Function: expr2ct::convert_prob_coin - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_prob_coin( const exprt &src, unsigned &precedence) @@ -1400,18 +1154,6 @@ std::string expr2ct::convert_prob_coin( return convert_norep(src, precedence); } -/*******************************************************************\ - -Function: expr2ct::convert_literal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_literal( const exprt &src, unsigned &precedence) @@ -1419,18 +1161,6 @@ std::string expr2ct::convert_literal( return "L("+src.get_string(ID_literal)+")"; } -/*******************************************************************\ - -Function: expr2ct::convert_prob_uniform - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_prob_uniform( const exprt &src, unsigned &precedence) @@ -1441,18 +1171,6 @@ std::string expr2ct::convert_prob_uniform( return convert_norep(src, precedence); } -/*******************************************************************\ - -Function: expr2ct::convert_function - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_function( const exprt &src, const std::string &name, @@ -1477,18 +1195,6 @@ std::string expr2ct::convert_function( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_comma - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_comma( const exprt &src, unsigned precedence) @@ -1513,18 +1219,6 @@ std::string expr2ct::convert_comma( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_complex - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_complex( const exprt &src, unsigned precedence) @@ -1576,18 +1270,6 @@ std::string expr2ct::convert_complex( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_array_of - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_array_of( const exprt &src, unsigned precedence) @@ -1598,18 +1280,6 @@ std::string expr2ct::convert_array_of( return "ARRAY_OF("+convert(src.op0())+')'; } -/*******************************************************************\ - -Function: expr2ct::convert_byte_extract - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_byte_extract( const exprt &src, unsigned precedence) @@ -1635,18 +1305,6 @@ std::string expr2ct::convert_byte_extract( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_byte_update - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_byte_update( const exprt &src, unsigned precedence) @@ -1677,18 +1335,6 @@ std::string expr2ct::convert_byte_update( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_unary_post - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_unary_post( const exprt &src, const std::string &symbol, @@ -1711,18 +1357,6 @@ std::string expr2ct::convert_unary_post( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_index - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_index( const exprt &src, unsigned precedence) @@ -1747,18 +1381,6 @@ std::string expr2ct::convert_index( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_pointer_arithmetic - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_pointer_arithmetic( const exprt &src, unsigned &precedence) { @@ -1796,18 +1418,6 @@ std::string expr2ct::convert_pointer_arithmetic( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_pointer_difference - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_pointer_difference( const exprt &src, unsigned &precedence) { @@ -1845,18 +1455,6 @@ std::string expr2ct::convert_pointer_difference( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_member_designator - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_member_designator(const exprt &src) { unsigned precedence; @@ -1867,18 +1465,6 @@ std::string expr2ct::convert_member_designator(const exprt &src) return "."+src.get_string(ID_component_name); } -/*******************************************************************\ - -Function: expr2ct::convert_index_designator - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_index_designator(const exprt &src) { unsigned precedence; @@ -1889,18 +1475,6 @@ std::string expr2ct::convert_index_designator(const exprt &src) return "["+convert(src.op0())+"]"; } -/*******************************************************************\ - -Function: expr2ct::convert_member - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_member( const member_exprt &src, unsigned precedence) @@ -1977,18 +1551,6 @@ std::string expr2ct::convert_member( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_array_member_value - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_array_member_value( const exprt &src, unsigned precedence) @@ -1999,18 +1561,6 @@ std::string expr2ct::convert_array_member_value( return "[]="+convert(src.op0()); } -/*******************************************************************\ - -Function: expr2ct::convert_struct_member_value - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_struct_member_value( const exprt &src, unsigned precedence) @@ -2021,18 +1571,6 @@ std::string expr2ct::convert_struct_member_value( return "."+src.get_string(ID_name)+"="+convert(src.op0()); } -/*******************************************************************\ - -Function: expr2ct::convert_norep - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_norep( const exprt &src, unsigned &precedence) @@ -2044,18 +1582,6 @@ std::string expr2ct::convert_norep( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_symbol( const exprt &src, unsigned &precedence) @@ -2098,18 +1624,6 @@ std::string expr2ct::convert_symbol( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_nondet_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_nondet_symbol( const exprt &src, unsigned &precedence) @@ -2118,18 +1632,6 @@ std::string expr2ct::convert_nondet_symbol( return "nondet_symbol("+id+")"; } -/*******************************************************************\ - -Function: expr2ct::convert_predicate_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_predicate_symbol( const exprt &src, unsigned &precedence) @@ -2138,18 +1640,6 @@ std::string expr2ct::convert_predicate_symbol( return "ps("+id+")"; } -/*******************************************************************\ - -Function: expr2ct::convert_predicate_next_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_predicate_next_symbol( const exprt &src, unsigned &precedence) @@ -2158,18 +1648,6 @@ std::string expr2ct::convert_predicate_next_symbol( return "pns("+id+")"; } -/*******************************************************************\ - -Function: expr2ct::convert_predicate_passive_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_predicate_passive_symbol( const exprt &src, unsigned &precedence) @@ -2178,18 +1656,6 @@ std::string expr2ct::convert_predicate_passive_symbol( return "pps("+id+")"; } -/*******************************************************************\ - -Function: expr2ct::convert_quantified_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_quantified_symbol( const exprt &src, unsigned &precedence) @@ -2198,18 +1664,6 @@ std::string expr2ct::convert_quantified_symbol( return id; } -/*******************************************************************\ - -Function: expr2ct::convert_nondet_bool - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_nondet_bool( const exprt &src, unsigned &precedence) @@ -2217,18 +1671,6 @@ std::string expr2ct::convert_nondet_bool( return "nondet_bool()"; } -/*******************************************************************\ - -Function: expr2ct::convert_object_descriptor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_object_descriptor( const exprt &src, unsigned &precedence) @@ -2253,18 +1695,6 @@ std::string expr2ct::convert_object_descriptor( return result; } -/*******************************************************************\ - -Function: expr2ct::convert_constant - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_constant( const constant_exprt &src, unsigned &precedence) @@ -2405,10 +1835,12 @@ std::string expr2ct::convert_constant( if(dest!="" && isdigit(dest[dest.size()-1])) { + if(dest.find('.')==std::string::npos) + dest+=".0"; + + // ANSI-C: double is default; float/long-double require annotation if(src.type()==float_type()) dest+='f'; - else if(src.type()==double_type()) - dest+=""; // ANSI-C: double is default else if(src.type()==long_double_type()) dest+='l'; } @@ -2490,19 +1922,10 @@ std::string expr2ct::convert_constant( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_constant_bool - - Inputs: - boolean_value - The value of the constant bool expression - - Outputs: Returns a C-like representation of the boolean value, - e.g. TRUE or FALSE. - - Purpose: To get the C-like representation of a given boolean value. - -\*******************************************************************/ +/// To get the C-like representation of a given boolean value. +/// \param boolean_value: The value of the constant bool expression +/// \return Returns a C-like representation of the boolean value, e.g. TRUE or +/// FALSE. std::string expr2ct::convert_constant_bool(bool boolean_value) { // C doesn't really have these @@ -2512,18 +1935,6 @@ std::string expr2ct::convert_constant_bool(bool boolean_value) return "FALSE"; } -/*******************************************************************\ - -Function: expr2ct::convert_struct - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_struct( const exprt &src, unsigned &precedence) @@ -2531,23 +1942,13 @@ std::string expr2ct::convert_struct( return convert_struct(src, precedence, true); } -/*******************************************************************\ - -Function: expr2ct::convert_struct - - Inputs: - src - The struct declaration expression - precedence - include_padding_components - Should the generated C code - include the padding members added - to structs for GOTOs benifit - - Outputs: A string representation of the struct expression - - Purpose: To generate a C-like string representing a struct. Can optionally - include the padding parameters. - -\*******************************************************************/ +/// To generate a C-like string representing a struct. Can optionally include +/// the padding parameters. +/// \param src: The struct declaration expression +/// precedence +/// \param include_padding_components: Should the generated C code include the +/// padding members added to structs for GOTOs benefit +/// \return A string representation of the struct expression std::string expr2ct::convert_struct( const exprt &src, unsigned &precedence, @@ -2622,18 +2023,6 @@ std::string expr2ct::convert_struct( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_vector - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_vector( const exprt &src, unsigned &precedence) @@ -2681,18 +2070,6 @@ std::string expr2ct::convert_vector( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_union - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_union( const exprt &src, unsigned &precedence) @@ -2714,18 +2091,6 @@ std::string expr2ct::convert_union( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_array - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_array( const exprt &src, unsigned &precedence) @@ -2832,18 +2197,6 @@ std::string expr2ct::convert_array( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_array_list - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_array_list( const exprt &src, unsigned &precedence) @@ -2878,18 +2231,6 @@ std::string expr2ct::convert_array_list( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_initializer_list - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_initializer_list( const exprt &src, unsigned &precedence) @@ -2918,18 +2259,6 @@ std::string expr2ct::convert_initializer_list( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_designated_initializer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_designated_initializer( const exprt &src, unsigned &precedence) @@ -2948,18 +2277,6 @@ std::string expr2ct::convert_designated_initializer( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_function_application - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_function_application( const function_application_exprt &src, unsigned &precedence) @@ -2990,18 +2307,6 @@ std::string expr2ct::convert_function_application( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_side_effect_expr_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_side_effect_expr_function_call( const side_effect_expr_function_callt &src, unsigned &precedence) @@ -3032,18 +2337,6 @@ std::string expr2ct::convert_side_effect_expr_function_call( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_overflow - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_overflow( const exprt &src, unsigned &precedence) @@ -3075,35 +2368,11 @@ std::string expr2ct::convert_overflow( return dest; } -/*******************************************************************\ - -Function: expr2ct::indent_str - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::indent_str(unsigned indent) { return std::string(indent, ' '); } -/*******************************************************************\ - -Function: expr2ct::convert_code_asm - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_asm( const code_asmt &src, unsigned indent) @@ -3182,18 +2451,6 @@ std::string expr2ct::convert_code_asm( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_code_while - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_while( const code_whilet &src, unsigned indent) @@ -3220,18 +2477,6 @@ std::string expr2ct::convert_code_while( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_code_dowhile - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_dowhile( const code_dowhilet &src, unsigned indent) @@ -3261,18 +2506,6 @@ std::string expr2ct::convert_code_dowhile( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_code_ifthenelse - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_ifthenelse( const code_ifthenelset &src, unsigned indent) @@ -3310,18 +2543,6 @@ std::string expr2ct::convert_code_ifthenelse( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_code_return - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_return( const codet &src, unsigned indent) @@ -3344,18 +2565,6 @@ std::string expr2ct::convert_code_return( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_code_goto - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_goto( const codet &src, unsigned indent) @@ -3368,18 +2577,6 @@ std::string expr2ct::convert_code_goto( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_code_break - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_break( const codet &src, unsigned indent) @@ -3391,23 +2588,11 @@ std::string expr2ct::convert_code_break( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_code_switch - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_switch( const codet &src, unsigned indent) { - if(src.operands().size()<1) + if(src.operands().empty()) { unsigned precedence; return convert_norep(src, precedence); @@ -3446,18 +2631,6 @@ std::string expr2ct::convert_code_switch( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_code_continue - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_continue( const codet &src, unsigned indent) @@ -3469,18 +2642,6 @@ std::string expr2ct::convert_code_continue( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_code_decl - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_decl( const codet &src, unsigned indent) @@ -3497,7 +2658,7 @@ std::string expr2ct::convert_code_decl( std::string dest=indent_str(indent); - const symbolt *symbol=0; + const symbolt *symbol=nullptr; if(!ns.lookup(to_symbol_expr(src.op0()).get_identifier(), symbol)) { if(symbol->is_file_local && @@ -3518,20 +2679,8 @@ std::string expr2ct::convert_code_decl( dest+=';'; - return dest; -} - -/*******************************************************************\ - -Function: expr2ct::convert_code_dead - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ + return dest; +} std::string expr2ct::convert_code_dead( const codet &src, @@ -3547,18 +2696,6 @@ std::string expr2ct::convert_code_dead( return "dead "+convert(src.op0())+";"; } -/*******************************************************************\ - -Function: expr2ct::convert_code_for - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_for( const code_fort &src, unsigned indent) @@ -3596,18 +2733,6 @@ std::string expr2ct::convert_code_for( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_code_block - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_block( const code_blockt &src, unsigned indent) @@ -3631,18 +2756,6 @@ std::string expr2ct::convert_code_block( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_code_decl_block - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_decl_block( const codet &src, unsigned indent) @@ -3658,18 +2771,6 @@ std::string expr2ct::convert_code_decl_block( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_code_expression - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_expression( const codet &src, unsigned indent) @@ -3692,18 +2793,6 @@ std::string expr2ct::convert_code_expression( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_code - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code( const codet &src, unsigned indent) @@ -3818,6 +2907,9 @@ std::string expr2ct::convert_code( if(statement==ID_array_copy) return convert_code_array_copy(src, indent); + if(statement==ID_array_replace) + return convert_code_array_replace(src, indent); + if(statement=="set_may" || statement=="set_must") return @@ -3827,18 +2919,6 @@ std::string expr2ct::convert_code( return convert_norep(src, precedence); } -/*******************************************************************\ - -Function: expr2ct::convert_code_assign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_assign( const code_assignt &src, unsigned indent) @@ -3850,18 +2930,6 @@ std::string expr2ct::convert_code_assign( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_code_free - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_free( const codet &src, unsigned indent) @@ -3875,18 +2943,6 @@ std::string expr2ct::convert_code_free( return indent_str(indent)+"FREE("+convert(src.op0())+");"; } -/*******************************************************************\ - -Function: expr2ct::convert_code_init - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_init( const codet &src, unsigned indent) @@ -3896,18 +2952,6 @@ std::string expr2ct::convert_code_init( return indent_str(indent)+"INIT "+tmp+";"; } -/*******************************************************************\ - -Function: expr2ct::convert_code_lock - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_lock( const codet &src, unsigned indent) @@ -3921,18 +2965,6 @@ std::string expr2ct::convert_code_lock( return indent_str(indent)+"LOCK("+convert(src.op0())+");"; } -/*******************************************************************\ - -Function: expr2ct::convert_code_unlock - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_unlock( const codet &src, unsigned indent) @@ -3946,18 +2978,6 @@ std::string expr2ct::convert_code_unlock( return indent_str(indent)+"UNLOCK("+convert(src.op0())+");"; } -/*******************************************************************\ - -Function: expr2ct::convert_code_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_function_call( const code_function_callt &src, unsigned indent) @@ -4006,18 +3026,6 @@ std::string expr2ct::convert_code_function_call( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_code_printf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_printf( const codet &src, unsigned indent) @@ -4040,18 +3048,6 @@ std::string expr2ct::convert_code_printf( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_code_fence - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_fence( const codet &src, unsigned indent) @@ -4082,18 +3078,6 @@ std::string expr2ct::convert_code_fence( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_code_input - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_input( const codet &src, unsigned indent) @@ -4116,18 +3100,6 @@ std::string expr2ct::convert_code_input( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_code_output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_output( const codet &src, unsigned indent) @@ -4149,18 +3121,6 @@ std::string expr2ct::convert_code_output( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_code_array_set - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_array_set( const codet &src, unsigned indent) @@ -4183,18 +3143,6 @@ std::string expr2ct::convert_code_array_set( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_code_array_copy - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_array_copy( const codet &src, unsigned indent) @@ -4217,17 +3165,26 @@ std::string expr2ct::convert_code_array_copy( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_code_assert +std::string expr2ct::convert_code_array_replace( + const codet &src, + unsigned indent) +{ + std::string dest=indent_str(indent)+"ARRAY_REPLACE("; - Inputs: + forall_operands(it, src) + { + unsigned p; + std::string arg_str=convert_with_precedence(*it, p); - Outputs: + if(it!=src.operands().begin()) + dest+=", "; + dest+=arg_str; + } - Purpose: + dest+=");"; -\*******************************************************************/ + return dest; +} std::string expr2ct::convert_code_assert( const codet &src, @@ -4242,18 +3199,6 @@ std::string expr2ct::convert_code_assert( return indent_str(indent)+"assert("+convert(src.op0())+");"; } -/*******************************************************************\ - -Function: expr2ct::convert_code_assume - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_assume( const codet &src, unsigned indent) @@ -4267,18 +3212,6 @@ std::string expr2ct::convert_code_assume( return indent_str(indent)+"__CPROVER_assume("+convert(src.op0())+");"; } -/*******************************************************************\ - -Function: expr2ct::convert_code_label - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_label( const code_labelt &src, unsigned indent) @@ -4297,18 +3230,6 @@ std::string expr2ct::convert_code_label( return labels_string+tmp; } -/*******************************************************************\ - -Function: expr2ct::convert_code_switch_case - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code_switch_case( const code_switch_caset &src, unsigned indent) @@ -4339,35 +3260,11 @@ std::string expr2ct::convert_code_switch_case( return labels_string+tmp; } -/*******************************************************************\ - -Function: expr2ct::convert_code - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_code(const codet &src) { return convert_code(src, 0); } -/*******************************************************************\ - -Function: expr2ct::convert_Hoare - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_Hoare(const exprt &src) { unsigned precedence; @@ -4411,18 +3308,6 @@ std::string expr2ct::convert_Hoare(const exprt &src) return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_extractbit - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_extractbit( const exprt &src, unsigned precedence) @@ -4438,18 +3323,6 @@ std::string expr2ct::convert_extractbit( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_extractbits - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_extractbits( const exprt &src, unsigned precedence) @@ -4467,18 +3340,6 @@ std::string expr2ct::convert_extractbits( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert_sizeof - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_sizeof( const exprt &src, unsigned &precedence) @@ -4493,18 +3354,6 @@ std::string expr2ct::convert_sizeof( return dest; } -/*******************************************************************\ - -Function: expr2ct::convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert_with_precedence( const exprt &src, unsigned &precedence) @@ -4667,9 +3516,6 @@ std::string expr2ct::convert_with_precedence( else if(src.id()=="buffer_size") return convert_function(src, "BUFFER_SIZE", precedence=16); - else if(src.id()==ID_pointer_offset) - return convert_function(src, "POINTER_OFFSET", precedence=16); - else if(src.id()==ID_isnan) return convert_function(src, "isnan", precedence=16); @@ -4680,7 +3526,11 @@ std::string expr2ct::convert_with_precedence( return convert_function(src, "isinf", precedence=16); else if(src.id()==ID_bswap) - return convert_function(src, "bswap", precedence=16); + return convert_function( + src, + "__builtin_bswap"+ + integer2string(pointer_offset_bits(src.op0().type(), ns)), + precedence=16); else if(src.id()==ID_isnormal) return convert_function(src, "isnormal", precedence=16); @@ -5009,36 +3859,12 @@ std::string expr2ct::convert_with_precedence( return next_pretty_printer->convert(src); } -/*******************************************************************\ - -Function: expr2ct::convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2ct::convert(const exprt &src) { unsigned precedence; return convert_with_precedence(src, precedence); } -/*******************************************************************\ - -Function: expr2c - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2c(const exprt &expr, const namespacet &ns) { std::string code; @@ -5049,18 +3875,6 @@ std::string expr2c(const exprt &expr, const namespacet &ns) return expr2c.convert(expr); } -/*******************************************************************\ - -Function: type2c - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string type2c(const typet &type, const namespacet &ns) { expr2ct expr2c(ns); diff --git a/src/ansi-c/expr2c.h b/src/ansi-c/expr2c.h index 6a1b24aa221..2bbcad3832e 100644 --- a/src/ansi-c/expr2c.h +++ b/src/ansi-c/expr2c.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_ANSI_C_EXPR2C_H #define CPROVER_ANSI_C_EXPR2C_H diff --git a/src/ansi-c/expr2c_class.h b/src/ansi-c/expr2c_class.h index a1cab5ad2a4..7d02bdf4ee3 100644 --- a/src/ansi-c/expr2c_class.h +++ b/src/ansi-c/expr2c_class.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_ANSI_C_EXPR2C_CLASS_H #define CPROVER_ANSI_C_EXPR2C_CLASS_H @@ -206,6 +207,7 @@ class expr2ct:public pretty_printert std::string convert_code_output(const codet &src, unsigned indent); std::string convert_code_array_set(const codet &src, unsigned indent); std::string convert_code_array_copy(const codet &src, unsigned indent); + std::string convert_code_array_replace(const codet &src, unsigned indent); virtual std::string convert_with_precedence( const exprt &src, unsigned &precedence); diff --git a/src/ansi-c/file_converter.cpp b/src/ansi-c/file_converter.cpp index 1a3aecab1a3..ce0dbd9ea36 100644 --- a/src/ansi-c/file_converter.cpp +++ b/src/ansi-c/file_converter.cpp @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Convert file contents to C strings + #include #include @@ -37,6 +40,6 @@ int main() std::cout << ch; } - std::cout << "\\n\"" << std::endl; + std::cout << "\\n\"\n"; } } diff --git a/src/ansi-c/gcc_builtin_headers_generic.h b/src/ansi-c/gcc_builtin_headers_generic.h index ce0e94a8bd7..17d997b8deb 100644 --- a/src/ansi-c/gcc_builtin_headers_generic.h +++ b/src/ansi-c/gcc_builtin_headers_generic.h @@ -1,109 +1,70 @@ typedef void ** __builtin_va_list; typedef void ** __builtin_ms_va_list; -void __builtin_va_start(void *ap, ...); -void __builtin_va_end(void *ap); -void __builtin_va_copy(__builtin_va_list dest, __builtin_va_list src); -void __builtin_ms_va_start(void *ap, ...); +// stdarg +void* __builtin_apply_args(); void __builtin_ms_va_end(void *ap); -void *__builtin_va_arg_pack(); +void __builtin_ms_va_start(void *ap, ...); +void* __builtin_next_arg(); +int __builtin_va_arg_pack(); int __builtin_va_arg_pack_len(); -int __builtin_constant_p(); -int __builtin_abs(int); -int __builtin_finite(double); -int __builtin_finitef(float); -int __builtin_finitel(long double); -int __builtin_fpclassify(int, int, int, int, int, ...); -int __builtin_isfinite(); -int __builtin_isinf_sign(); -int __builtin_isnanl(long double); -int __builtin_isnormal(); -int __builtin_isgreater(); -int __builtin_isgreaterequal(); -int __builtin_isless(); -int __builtin_islessequal(); -int __builtin_islessgreater(); -int __builtin_isunordered(); -long int __builtin_labs(long); -long long int __builtin_llabs(long long int); -double __builtin_cos(double); -float __builtin_cosf(float); -double __builtin_fabs(double); -float __builtin_fabsf(float); -int __builtin_memcmp(const void *s1, const void *s2, __CPROVER_size_t n); -void *__builtin_memcpy(void *dest, const void *src, __CPROVER_size_t n); -void *__builtin___memcpy_chk(void *dest, const void *src, __CPROVER_size_t n, __CPROVER_size_t size); -char *__builtin___memmove_chk(void *dest, const void *src, __CPROVER_size_t n, __CPROVER_size_t size); -double __builtin_sin(double); -float __builtin_sinf(float); -double __builtin_sqrt(double); -float __builtin_sqrtf(float); -int __builtin_strcmp(const char *s1, const char *s2); -__CPROVER_size_t __builtin_strlen(const char *s); -int __builtin_strncmp(const char *s1, const char *s2, __CPROVER_size_t n); +void __builtin_va_copy(__builtin_va_list dest, __builtin_va_list src); +void __builtin_va_end(void *ap); +void __builtin_va_start(void *ap, ...); + +// stdlib +void __builtin__Exit(int); +void __builtin__exit(int); void __builtin_abort(); -void __builtin_prefetch(void *, ...); -int __builtin_printf(const char *fmt, ...); +int __builtin_execl(const char*, const char*, ...); +int __builtin_execle(const char*, const char*, ...); +int __builtin_execlp(const char*, const char*, ...); +int __builtin_execv(const char*, const char**); +int __builtin_execve(const char*, const char**, const char**); +int __builtin_execvp(const char*, const char**); +void __builtin_exit(int); + +// stdio +int __builtin___fprintf_chk(void*, int, const char*, ...); +int __builtin___printf_chk(int, const char*, ...); +int __builtin___snprintf_chk(char*, __CPROVER_size_t, int, __CPROVER_size_t, const char*, ...); +int __builtin___sprintf_chk(char*, int, __CPROVER_size_t, const char*, ...); +int __builtin___vfprintf_chk(void*, int, const char*, __builtin_va_list); +int __builtin___vprintf_chk(int, const char*, __builtin_va_list); +int __builtin___vsnprintf_chk (char *s, __CPROVER_size_t maxlen, int flag, __CPROVER_size_t os, const char *fmt, __builtin_va_list ap); +int __builtin___vsnprintf_chk(char*, __CPROVER_size_t, int, __CPROVER_size_t, const char*, __builtin_va_list); +int __builtin___vsprintf_chk(char*, int, __CPROVER_size_t, const char*, __builtin_va_list); +long __builtin_expect(long, long); int __builtin_fprintf(void *stream, const char *fmt, ...); +int __builtin_fprintf_unlocked(void*, const char*, ...); +int __builtin_fputc(int, void*); +int __builtin_fputc_unlocked(int, void*); +int __builtin_fputs(const char *s, void *stream); +int __builtin_fputs_unlocked(const char*, void*); int __builtin_fscanf(void *stream, const char *fmt, ...); +__CPROVER_size_t __builtin_fwrite(const void*, __CPROVER_size_t, __CPROVER_size_t, void*); +__CPROVER_size_t __builtin_fwrite_unlocked(const void*, __CPROVER_size_t, __CPROVER_size_t, void*); +int __builtin_printf(const char*, ...); +int __builtin_printf_unlocked(const char*, ...); +int __builtin_putc(int, void*); +int __builtin_putc_unlocked(int, void*); +int __builtin_putchar(int); +int __builtin_putchar_unlocked(int); +int __builtin_puts(const char*); +int __builtin_puts_unlocked(const char*); int __builtin_scanf(const char *str, const char *fmt, ...); -int __builtin_fputs(const char *s, void *stream); -int __builtin_vsnprintf(char * restrict str, __CPROVER_size_t size, const char * restrict format, __builtin_va_list ap); -long __builtin_expect(long, long); -void *__builtin_memset(void *s, int c, __CPROVER_size_t n); -void *__builtin___memset_chk(void *s, int c, __CPROVER_size_t n, __CPROVER_size_t size); -void *__builtin_memchr(const void *s, int c, __CPROVER_size_t n); -void *__builtin_memmove(void *s1, const void *s2, __CPROVER_size_t n); -void *__builtin_mempcpy(void *, const void *, __CPROVER_size_t); -void *__builtin___mempcpy_chk(void *dest, const void *src, __CPROVER_size_t n, __CPROVER_size_t size); -char *__builtin_strcat(char *dest, const char *src); -char *__builtin___strcat_chk(char *dest, const char *src, __CPROVER_size_t size); -char *__builtin_strcpy(char *dest, const char *src); -char *__builtin___strcpy_chk(char *dest, const char *src, __CPROVER_size_t size); -char *__builtin_strncpy(char *dest, const char *src, __CPROVER_size_t n); -char *__builtin___strncpy_chk(char *dest, const char *src, __CPROVER_size_t n, __CPROVER_size_t size); -char *__builtin_stpcpy(char *dest, const char *src); -char *__builtin___stpcpy(char *s1, const char *s2); -char *__builtin___stpncpy_chk(char *s1, const char *s2, __CPROVER_size_t n, __CPROVER_size_t size); -int __builtin___sprintf_chk(char *s, int flag, __CPROVER_size_t os, const char *fmt, ...); -int __builtin___snprintf_chk(char *s, __CPROVER_size_t maxlen, int flag, __CPROVER_size_t os, const char *fmt, ...); -int __builtin___vsprintf_chk(char *s, int flag, __CPROVER_size_t os, const char *fmt, __builtin_va_list ap); -int __builtin___vsnprintf_chk (char *s, __CPROVER_size_t maxlen, int flag, __CPROVER_size_t os, const char *fmt, __builtin_va_list ap); -void __builtin_exit(int status); -char *__builtin_strchr(const char *s, int c); -__CPROVER_size_t __builtin_strspn(const char *s, const char *accept); -__CPROVER_size_t __builtin_strcspn(const char *s, const char *reject); -char *__builtin_strstr(const char *a, const char *b); -char *__builtin_strpbrk(const char *s, const char *accept); -char *__builtin_strrchr(const char *s, int c); -char *__builtin_strncat(char *dest, const char *src, __CPROVER_size_t n); -char *__builtin___strncat_chk(char *dest, const char *src, __CPROVER_size_t n, __CPROVER_size_t size); -char *__builtin___stpcpy_chk(char *dest, const char *src, __CPROVER_size_t size); -void *__builtin_alloca(__CPROVER_size_t s); -int __builtin_ffs(int i); -char *__builtin_index(const char *s, int c); -char *__builtin_rindex(const char *s, int c); -int __builtin_bcmp(const void *s1, const void *s2, __CPROVER_size_t n); -void __builtin_bzero(void *s, __CPROVER_size_t n); -long double __builtin_sinl(long double x); -long double __builtin_cosl(long double x); -long double __builtin_sqrtl(long double x); -long double __builtin_fabsl(long double x); -int __builtin_popcount(unsigned int x); -int __builtin_popcountll(unsigned long long int x); -float __builtin_huge_valf(); -double __builtin_huge_val(); -float __builtin_inff(); -double __builtin_inf(); -float __builtin_nanf(const char *); -double __builtin_nan(const char *); -float __builtin_nansf(const char *); -double __builtin_nans(const char *); -long double __builtin_infl(); -__CPROVER_size_t __builtin_object_size(); -void *__builtin_return_address(unsigned level); -void *__builtin_extract_return_addr(void *); -int __builtin_choose_expr(_Bool, ...); +int __builtin_snprintf(char*, __CPROVER_size_t, const char*, ...); +int __builtin_sprintf(char*, const char*, ...); +int __builtin_sscanf(const char*, const char*, ...); +int __builtin_vfprintf(void*, const char*, __builtin_va_list); +int __builtin_vfscanf(void*, const char*, __builtin_va_list); +int __builtin_vprintf(const char*, __builtin_va_list); +int __builtin_vscanf(const char*, __builtin_va_list); +int __builtin_vsnprintf(char*, __CPROVER_size_t, const char*, __builtin_va_list); +int __builtin_vsprintf(char*, const char*, __builtin_va_list); +int __builtin_vsscanf(const char*, const char*, __builtin_va_list); + +// atomics int __sync_fetch_and_add(); int __sync_fetch_and_sub(); int __sync_fetch_and_or(); @@ -121,81 +82,37 @@ int __sync_val_compare_and_swap(); void __sync_synchronize(); int __sync_lock_test_and_set(); void __sync_lock_release(); -float __builtin_acosf(float); -long double __builtin_acosl(long double); -float __builtin_asinf(float); -long double __builtin_asinl(long double); -float __builtin_atanf(float); -long double __builtin_atanl(long double); -float __builtin_atan2f(float, float); -long double __builtin_atan2l(long double, long double); -float __builtin_ceilf(float); -long double __builtin_ceill(long double); -float __builtin_coshf(float); -long double __builtin_coshl(long double); -float __builtin_expf(float); -long double __builtin_expl(long double); -float __builtin_floorf(float); -long double __builtin_floorl(long double); -float __builtin_fmodf(float, float); -long double __builtin_fmodl(long double, long double); -float __builtin_frexpf(float, int*); -long double __builtin_frexpl(long double, int*); -float __builtin_ldexpf(float , int exp); -long double __builtin_ldexpl(long double, int); -float __builtin_logf(float); -long double __builtin_logl(long double); -float __builtin_log10f(float); -double __builtin_log10(double); -long double __builtin_log10l(long double); -float __builtin_log2f(float); -double __builtin_log2(double); -long double __builtin_log2l(float); -float __builtin_modff(float, float*); -long double __builtin_modfl(long double, long double*); -float __builtin_powf(float, float); -long double __builtin_powl(long double, long double); -double __builtin_powi(double, int); -float __builtin_powif(float, int); -long double __builtin_powil(long double, int); -float __builtin_sinhf(float); -long double __builtin_sinhl(long double); -float __builtin_tanf(float); -long double __builtin_tanl(long double); -float __builtin_tanhf(float); -long double __builtin_tanhl(long double); -int __builtin_parityl(unsigned long); -int __builtin_parityll(unsigned long long); -void __builtin_trap(void); -void __builtin___clear_cache(char *begin, char *end); -int __builtin_clz(unsigned int); -int __builtin_clzll(unsigned long long); -int __builtin_ctz(unsigned int); -int __builtin_ctzll(unsigned long long); -int __builtin_parity(unsigned int); -int __builtin_ffsl(unsigned long); -int __builtin_clzl(unsigned long); -int __builtin_ctzl(unsigned long); -short unsigned int __builtin_bswap16(short unsigned int); -long unsigned int __builtin_bswap32(long unsigned int); -long long unsigned int __builtin_bswap64(long long unsigned int); -int __builtin_classify_type(); -int __builtin_isinf(double); -int __builtin_isinff(float); -int __builtin_isinfl(long double); -int __builtin_isnan(double); -int __builtin_isnanf(float); -int __builtin_signbit(double); -int __builtin_signbitf(float); -int __builtin_signbitl(long double); +// other +int __builtin_choose_expr(_Bool, ...); +int __builtin_classify_type(); +int __builtin_constant_p(int); +void __builtin_trap(void); void __builtin_unreachable(void); +void* __builtin_dwarf_cfa(); +unsigned __builtin_dwarf_sp_column(); +int __builtin_eh_return_data_regno(int); +void __builtin_init_dwarf_reg___CPROVER_size_table(void*); +void __builtin_unwind_init(); + +const char* __builtin_FILE(); +const char* __builtin_FUNCTION(); +int __builtin_LINE(); + +void __builtin_longjmp(void*, int); +void __builtin_return(void*); +void* __builtin_saveregs(); +int __builtin_setjmp(void*); +void __builtin_update_setjmp_buf(void*); + + typedef int __gcc_m64 __attribute__ ((__vector_size__ (8), __may_alias__)); typedef char __gcc_v8qi __attribute__ ((__vector_size__ (8))); typedef char __gcc_v16qi __attribute__ ((__vector_size__ (16))); typedef char __gcc_v32qi __attribute__ ((__vector_size__ (32))); +typedef char __gcc_v64qi __attribute__ ((__vector_size__ (64))); typedef int __gcc_v2si __attribute__ ((__vector_size__ (8))); typedef int __gcc_v4si __attribute__ ((__vector_size__ (16))); typedef int __gcc_v8si __attribute__ ((__vector_size__ (32))); diff --git a/src/ansi-c/gcc_builtin_headers_ia32-2.h b/src/ansi-c/gcc_builtin_headers_ia32-2.h index 91f5eb01549..d5000ec19da 100644 --- a/src/ansi-c/gcc_builtin_headers_ia32-2.h +++ b/src/ansi-c/gcc_builtin_headers_ia32-2.h @@ -1,4 +1,4 @@ -void __builtin_ia32_emms(void); +void __builtin_ia32_emms(); __gcc_v2si __builtin_ia32_pmaddwd(__gcc_v4hi, __gcc_v4hi); __gcc_v2si __builtin_ia32_vec_init_v2si(int, int); __gcc_v4hi __builtin_ia32_vec_init_v4hi(short, short, short, short); @@ -8,15 +8,15 @@ __gcc_v8hi __builtin_ia32_paddusw128(__gcc_v8hi, __gcc_v8hi); __gcc_v8hi __builtin_ia32_psubusw128(__gcc_v8hi, __gcc_v8hi); void __builtin_ia32_ldmxcsr(unsigned); unsigned __builtin_ia32_stmxcsr(void); -__gcc_v8hi __builtin_ia32_paddsw128(__gcc_v8hi,__gcc_v8hi); -__gcc_v8hi __builtin_ia32_psubsw128(__gcc_v8hi,__gcc_v8hi); -__gcc_v16qi __builtin_ia32_paddsb128(__gcc_v16qi,__gcc_v16qi); -__gcc_v16qi __builtin_ia32_psubsb128(__gcc_v16qi,__gcc_v16qi); -__gcc_v16qi __builtin_ia32_paddusb128(__gcc_v16qi,__gcc_v16qi); -__gcc_v16qi __builtin_ia32_psubusb128(__gcc_v16qi,__gcc_v16qi); -__gcc_di __builtin_ia32_cvtss2si64(__gcc_v4sf); -__gcc_di __builtin_ia32_cvttss2si64(__gcc_v4sf); -__gcc_v4sf __builtin_ia32_cvtsi642ss(__gcc_v4sf, __gcc_di); +__gcc_v8hi __builtin_ia32_paddsw128(__gcc_v8hi, __gcc_v8hi); +__gcc_v8hi __builtin_ia32_psubsw128(__gcc_v8hi, __gcc_v8hi); +__gcc_v16qi __builtin_ia32_paddsb128(__gcc_v16qi, __gcc_v16qi); +__gcc_v16qi __builtin_ia32_psubsb128(__gcc_v16qi, __gcc_v16qi); +__gcc_v16qi __builtin_ia32_paddusb128(__gcc_v16qi, __gcc_v16qi); +__gcc_v16qi __builtin_ia32_psubusb128(__gcc_v16qi, __gcc_v16qi); +long long __builtin_ia32_cvtss2si64(__gcc_v4sf); +long long __builtin_ia32_cvttss2si64(__gcc_v4sf); +__gcc_v4sf __builtin_ia32_cvtsi642ss(__gcc_v4sf, long long); __gcc_v4hi __builtin_ia32_pshufw(__gcc_v4hi, int); short __builtin_ia32_vec_ext_v4hi(__gcc_v4hi, int); @@ -32,12 +32,12 @@ __gcc_v16qi __builtin_ia32_vec_set_v16qi(__gcc_v16qi, char, int); __gcc_v4si __builtin_ia32_vec_set_v4si(__gcc_v4si, int, int); __gcc_v2di __builtin_ia32_vec_set_v2di(__gcc_v2di, __gcc_di, int); -unsigned long long __builtin_ia32_rdtsc(void); +unsigned long long __builtin_ia32_rdtsc(); unsigned long long __builtin_ia32_rdtscp(unsigned*); void __builtin_ia32_fnstenv(void*); void __builtin_ia32_fldenv(const void*); -unsigned short __builtin_ia32_fnstsw(void); -void __builtin_ia32_fnclex(void); +unsigned short __builtin_ia32_fnstsw(); +void __builtin_ia32_fnclex(); void __builtin_ia32_fxsave(void*); void __builtin_ia32_fxrstor(void*); void __builtin_ia32_xsave(void*, long long); @@ -57,63 +57,63 @@ void __builtin_ia32_xsavec64(void*, long long); void __builtin_ia32_movntdq256(__gcc_v4di*, __gcc_v4di); void __builtin_ia32_movntpd256(double*, __gcc_v4df); void __builtin_ia32_movntps256(float*, __gcc_v8sf); -void __builtin_ia32_compressstoresf512_mask(__gcc_v16sf*, __gcc_v16sf, short); -void __builtin_ia32_compressstoresi512_mask(__gcc_v16si*, __gcc_v16si, short); -void __builtin_ia32_compressstoredf512_mask(__gcc_v8df*, __gcc_v8df, char); -void __builtin_ia32_compressstoredi512_mask(__gcc_v8di*, __gcc_v8di, char); -__gcc_v16sf __builtin_ia32_expandloadsf512_mask(const __gcc_v16sf*, __gcc_v16sf, short); -__gcc_v16sf __builtin_ia32_expandloadsf512_maskz(const __gcc_v16sf*, __gcc_v16sf, short); -__gcc_v16si __builtin_ia32_expandloadsi512_mask(const __gcc_v16si*, __gcc_v16si, short); -__gcc_v16si __builtin_ia32_expandloadsi512_maskz(const __gcc_v16si*, __gcc_v16si, short); -__gcc_v8df __builtin_ia32_expandloaddf512_mask(const __gcc_v8df*, __gcc_v8df, char); -__gcc_v8df __builtin_ia32_expandloaddf512_maskz(const __gcc_v8df*, __gcc_v8df, char); -__gcc_v8di __builtin_ia32_expandloaddi512_mask(const __gcc_v8di*, __gcc_v8di, char); -__gcc_v8di __builtin_ia32_expandloaddi512_maskz(const __gcc_v8di*, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_loaddqusi512_mask(const __gcc_v16si*, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_loaddqudi512_mask(const __gcc_v8di*, __gcc_v8di, char); -__gcc_v8df __builtin_ia32_loadupd512_mask(const __gcc_v8df*, __gcc_v8df, char); -__gcc_v16sf __builtin_ia32_loadups512_mask(const __gcc_v16sf*, __gcc_v16sf, short); -__gcc_v16sf __builtin_ia32_loadaps512_mask(const __gcc_v16sf*, __gcc_v16sf, short); -__gcc_v16si __builtin_ia32_movdqa32load512_mask(const __gcc_v16si*, __gcc_v16si, short); -__gcc_v8df __builtin_ia32_loadapd512_mask(const __gcc_v8df*, __gcc_v8df, char); -__gcc_v8di __builtin_ia32_movdqa64load512_mask(const __gcc_v8di*, __gcc_v8di, char); +void __builtin_ia32_compressstoresf512_mask(__gcc_v16sf*, __gcc_v16sf, unsigned short); +void __builtin_ia32_compressstoresi512_mask(__gcc_v16si*, __gcc_v16si, unsigned short); +void __builtin_ia32_compressstoredf512_mask(__gcc_v8df*, __gcc_v8df, unsigned char); +void __builtin_ia32_compressstoredi512_mask(__gcc_v8di*, __gcc_v8di, unsigned char); +__gcc_v16sf __builtin_ia32_expandloadsf512_mask(const __gcc_v16sf*, __gcc_v16sf, unsigned short); +__gcc_v16sf __builtin_ia32_expandloadsf512_maskz(const __gcc_v16sf*, __gcc_v16sf, unsigned short); +__gcc_v16si __builtin_ia32_expandloadsi512_mask(const __gcc_v16si*, __gcc_v16si, unsigned short); +__gcc_v16si __builtin_ia32_expandloadsi512_maskz(const __gcc_v16si*, __gcc_v16si, unsigned short); +__gcc_v8df __builtin_ia32_expandloaddf512_mask(const __gcc_v8df*, __gcc_v8df, unsigned char); +__gcc_v8df __builtin_ia32_expandloaddf512_maskz(const __gcc_v8df*, __gcc_v8df, unsigned char); +__gcc_v8di __builtin_ia32_expandloaddi512_mask(const __gcc_v8di*, __gcc_v8di, unsigned char); +__gcc_v8di __builtin_ia32_expandloaddi512_maskz(const __gcc_v8di*, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_loaddqusi512_mask(const int*, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_loaddqudi512_mask(const long long*, __gcc_v8di, unsigned char); +__gcc_v8df __builtin_ia32_loadupd512_mask(const double*, __gcc_v8df, unsigned char); +__gcc_v16sf __builtin_ia32_loadups512_mask(const float*, __gcc_v16sf, unsigned short); +__gcc_v16sf __builtin_ia32_loadaps512_mask(const __gcc_v16sf*, __gcc_v16sf, unsigned short); +__gcc_v16si __builtin_ia32_movdqa32load512_mask(const __gcc_v16si*, __gcc_v16si, unsigned short); +__gcc_v8df __builtin_ia32_loadapd512_mask(const __gcc_v8df*, __gcc_v8df, unsigned char); +__gcc_v8di __builtin_ia32_movdqa64load512_mask(const __gcc_v8di*, __gcc_v8di, unsigned char); void __builtin_ia32_movntps512(float*, __gcc_v16sf); void __builtin_ia32_movntpd512(double*, __gcc_v8df); void __builtin_ia32_movntdq512(__gcc_v8di*, __gcc_v8di); __gcc_v8di __builtin_ia32_movntdqa512(__gcc_v8di*); -void __builtin_ia32_storedqusi512_mask(__gcc_v16si*, __gcc_v16si, short); -void __builtin_ia32_storedqudi512_mask(__gcc_v8di*, __gcc_v8di, char); -void __builtin_ia32_storeupd512_mask(__gcc_v8df*, __gcc_v8df, char); -void __builtin_ia32_pmovusqd512mem_mask(__gcc_v8si*, __gcc_v8di, char); -void __builtin_ia32_pmovsqd512mem_mask(__gcc_v8si*, __gcc_v8di, char); -void __builtin_ia32_pmovqd512mem_mask(__gcc_v8si*, __gcc_v8di, char); -void __builtin_ia32_pmovusqw512mem_mask(__gcc_v8hi*, __gcc_v8di, char); -void __builtin_ia32_pmovsqw512mem_mask(__gcc_v8hi*, __gcc_v8di, char); -void __builtin_ia32_pmovqw512mem_mask(__gcc_v8hi*, __gcc_v8di, char); -void __builtin_ia32_pmovusdw512mem_mask(__gcc_v16hi*, __gcc_v16si, short); -void __builtin_ia32_pmovsdw512mem_mask(__gcc_v16hi*, __gcc_v16si, short); -void __builtin_ia32_pmovdw512mem_mask(__gcc_v16hi*, __gcc_v16si, short); -void __builtin_ia32_pmovqb512mem_mask(__gcc_v16qi*, __gcc_v8di, char); -void __builtin_ia32_pmovusqb512mem_mask(__gcc_v16qi*, __gcc_v8di, char); -void __builtin_ia32_pmovsqb512mem_mask(__gcc_v16qi*, __gcc_v8di, char); -void __builtin_ia32_pmovusdb512mem_mask(__gcc_v16qi*, __gcc_v16si, short); -void __builtin_ia32_pmovsdb512mem_mask(__gcc_v16qi*, __gcc_v16si, short); -void __builtin_ia32_pmovdb512mem_mask(__gcc_v16qi*, __gcc_v16si, short); -void __builtin_ia32_storeups512_mask(__gcc_v16sf*, __gcc_v16sf, short); -void __builtin_ia32_storeaps512_mask(__gcc_v16sf*, __gcc_v16sf, short); -void __builtin_ia32_movdqa32store512_mask(__gcc_v16si*, __gcc_v16si, short); -void __builtin_ia32_storeapd512_mask(__gcc_v8df*, __gcc_v8df, char); -void __builtin_ia32_movdqa64store512_mask(__gcc_v8di*, __gcc_v8di, char); +void __builtin_ia32_storedqusi512_mask(int*, __gcc_v16si, unsigned short); +void __builtin_ia32_storedqudi512_mask(long long*, __gcc_v8di, unsigned char); +void __builtin_ia32_storeupd512_mask(double*, __gcc_v8df, unsigned char); +void __builtin_ia32_pmovusqd512mem_mask(__gcc_v8si*, __gcc_v8di, unsigned char); +void __builtin_ia32_pmovsqd512mem_mask(__gcc_v8si*, __gcc_v8di, unsigned char); +void __builtin_ia32_pmovqd512mem_mask(__gcc_v8si*, __gcc_v8di, unsigned char); +void __builtin_ia32_pmovusqw512mem_mask(__gcc_v8hi*, __gcc_v8di, unsigned char); +void __builtin_ia32_pmovsqw512mem_mask(__gcc_v8hi*, __gcc_v8di, unsigned char); +void __builtin_ia32_pmovqw512mem_mask(__gcc_v8hi*, __gcc_v8di, unsigned char); +void __builtin_ia32_pmovusdw512mem_mask(__gcc_v16hi*, __gcc_v16si, unsigned short); +void __builtin_ia32_pmovsdw512mem_mask(__gcc_v16hi*, __gcc_v16si, unsigned short); +void __builtin_ia32_pmovdw512mem_mask(__gcc_v16hi*, __gcc_v16si, unsigned short); +void __builtin_ia32_pmovqb512mem_mask(__gcc_v16qi*, __gcc_v8di, unsigned char); +void __builtin_ia32_pmovusqb512mem_mask(__gcc_v16qi*, __gcc_v8di, unsigned char); +void __builtin_ia32_pmovsqb512mem_mask(__gcc_v16qi*, __gcc_v8di, unsigned char); +void __builtin_ia32_pmovusdb512mem_mask(__gcc_v16qi*, __gcc_v16si, unsigned short); +void __builtin_ia32_pmovsdb512mem_mask(__gcc_v16qi*, __gcc_v16si, unsigned short); +void __builtin_ia32_pmovdb512mem_mask(__gcc_v16qi*, __gcc_v16si, unsigned short); +void __builtin_ia32_storeups512_mask(float*, __gcc_v16sf, unsigned short); +void __builtin_ia32_storeaps512_mask(__gcc_v16sf*, __gcc_v16sf, unsigned short); +void __builtin_ia32_movdqa32store512_mask(__gcc_v16si*, __gcc_v16si, unsigned short); +void __builtin_ia32_storeapd512_mask(__gcc_v8df*, __gcc_v8df, unsigned char); +void __builtin_ia32_movdqa64store512_mask(__gcc_v8di*, __gcc_v8di, unsigned char); void __builtin_ia32_llwpcb(void*); -void* __builtin_ia32_slwpcb(void); +void* __builtin_ia32_slwpcb(); void __builtin_ia32_wrfsbase32(unsigned); void __builtin_ia32_wrfsbase64(unsigned long long); void __builtin_ia32_wrgsbase32(unsigned); void __builtin_ia32_wrgsbase64(unsigned long long); -unsigned __builtin_ia32_xbegin(void); -void __builtin_ia32_xend(void); +unsigned __builtin_ia32_xbegin(); +void __builtin_ia32_xend(); void __builtin_ia32_xabort(unsigned); -int __builtin_ia32_xtest(void); +int __builtin_ia32_xtest(); int __builtin_ia32_bsrsi(int); long long __builtin_ia32_bsrdi(long long); unsigned long long __builtin_ia32_rdpmc(int); @@ -121,7 +121,7 @@ unsigned char __builtin_ia32_rolqi(unsigned char, int); unsigned short __builtin_ia32_rolhi(unsigned short, int); unsigned char __builtin_ia32_rorqi(unsigned char, int); unsigned short __builtin_ia32_rorhi(unsigned short, int); -__gcc_v2si __builtin_ia32_pfrsqit1(__gcc_v2sf, __gcc_v2sf); +__gcc_v2sf __builtin_ia32_pfrsqit1(__gcc_v2sf, __gcc_v2sf); __gcc_v4sf __builtin_ia32_sqrtps_nr(__gcc_v4sf); __gcc_v4sf __builtin_ia32_rsqrtps_nr(__gcc_v4sf); __gcc_v4sf __builtin_ia32_copysignps(__gcc_v4sf, __gcc_v4sf); @@ -184,197 +184,197 @@ unsigned __builtin_ia32_pdep_si(unsigned, unsigned); unsigned long long __builtin_ia32_pdep_di(unsigned long long, unsigned long long); unsigned __builtin_ia32_pext_si(unsigned, unsigned); unsigned long long __builtin_ia32_pext_di(unsigned long long, unsigned long long); -__gcc_v16si __builtin_ia32_alignd512_mask(__gcc_v16si, __gcc_v16si, int, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_alignq512_mask(__gcc_v8di, __gcc_v8di, int, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_blendmd_512_mask(__gcc_v16si, __gcc_v16si, short); -__gcc_v8df __builtin_ia32_blendmpd_512_mask(__gcc_v8df, __gcc_v8df, char); -__gcc_v16sf __builtin_ia32_blendmps_512_mask(__gcc_v16sf, __gcc_v16sf, short); -__gcc_v8di __builtin_ia32_blendmq_512_mask(__gcc_v8di, __gcc_v8di, char); -__gcc_v16sf __builtin_ia32_broadcastf32x4_512(__gcc_v4sf, __gcc_v16sf, short); -__gcc_v8df __builtin_ia32_broadcastf64x4_512(__gcc_v4df, __gcc_v8df, char); -__gcc_v16si __builtin_ia32_broadcasti32x4_512(__gcc_v4si, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_broadcasti64x4_512(__gcc_v4di, __gcc_v8di, char); -__gcc_v8df __builtin_ia32_broadcastsd512(__gcc_v2df, __gcc_v8df, char); -__gcc_v16sf __builtin_ia32_broadcastss512(__gcc_v4sf, __gcc_v16sf, short); +__gcc_v16si __builtin_ia32_alignd512_mask(__gcc_v16si, __gcc_v16si, int, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_alignq512_mask(__gcc_v8di, __gcc_v8di, int, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_blendmd_512_mask(__gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8df __builtin_ia32_blendmpd_512_mask(__gcc_v8df, __gcc_v8df, unsigned char); +__gcc_v16sf __builtin_ia32_blendmps_512_mask(__gcc_v16sf, __gcc_v16sf, unsigned short); +__gcc_v8di __builtin_ia32_blendmq_512_mask(__gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v16sf __builtin_ia32_broadcastf32x4_512(__gcc_v4sf, __gcc_v16sf, unsigned short); +__gcc_v8df __builtin_ia32_broadcastf64x4_512(__gcc_v4df, __gcc_v8df, unsigned char); +__gcc_v16si __builtin_ia32_broadcasti32x4_512(__gcc_v4si, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_broadcasti64x4_512(__gcc_v4di, __gcc_v8di, unsigned char); +__gcc_v8df __builtin_ia32_broadcastsd512(__gcc_v2df, __gcc_v8df, unsigned char); +__gcc_v16sf __builtin_ia32_broadcastss512(__gcc_v4sf, __gcc_v16sf, unsigned short); short __builtin_ia32_cmpd512_mask(__gcc_v16si, __gcc_v16si, int, short); -char __builtin_ia32_cmpq512_mask(__gcc_v8di, __gcc_v8di, int, char); -__gcc_v8df __builtin_ia32_compressdf512_mask(__gcc_v8df, __gcc_v8df, char); -__gcc_v16sf __builtin_ia32_compresssf512_mask(__gcc_v16sf, __gcc_v16sf, short); -__gcc_v8df __builtin_ia32_cvtdq2pd512_mask(__gcc_v8si, __gcc_v8df, char); -__gcc_v16hi __builtin_ia32_vcvtps2ph512_mask(__gcc_v16sf, int, __gcc_v16hi, short); -__gcc_v8df __builtin_ia32_cvtudq2pd512_mask(__gcc_v8si, __gcc_v8df, char); +unsigned char __builtin_ia32_cmpq512_mask(__gcc_v8di, __gcc_v8di, int, unsigned char); +__gcc_v8df __builtin_ia32_compressdf512_mask(__gcc_v8df, __gcc_v8df, unsigned char); +__gcc_v16sf __builtin_ia32_compresssf512_mask(__gcc_v16sf, __gcc_v16sf, unsigned short); +__gcc_v8df __builtin_ia32_cvtdq2pd512_mask(__gcc_v8si, __gcc_v8df, unsigned char); +__gcc_v16hi __builtin_ia32_vcvtps2ph512_mask(__gcc_v16sf, int, __gcc_v16hi, unsigned short); +__gcc_v8df __builtin_ia32_cvtudq2pd512_mask(__gcc_v8si, __gcc_v8df, unsigned char); __gcc_v2df __builtin_ia32_cvtusi2sd32(__gcc_v2df, unsigned); -__gcc_v8df __builtin_ia32_expanddf512_mask(__gcc_v8df, __gcc_v8df, char); -__gcc_v8df __builtin_ia32_expanddf512_maskz(__gcc_v8df, __gcc_v8df, char); -__gcc_v16sf __builtin_ia32_expandsf512_mask(__gcc_v16sf, __gcc_v16sf, short); -__gcc_v16sf __builtin_ia32_expandsf512_maskz(__gcc_v16sf, __gcc_v16sf, short); -__gcc_v4sf __builtin_ia32_extractf32x4_mask(__gcc_v16sf, int, __gcc_v4sf, char); -__gcc_v4df __builtin_ia32_extractf64x4_mask(__gcc_v8df, int, __gcc_v4df, char); -__gcc_v4si __builtin_ia32_extracti32x4_mask(__gcc_v16si, int, __gcc_v4si, char); -__gcc_v4di __builtin_ia32_extracti64x4_mask(__gcc_v8di, int, __gcc_v4di, char); -__gcc_v16sf __builtin_ia32_insertf32x4_mask(__gcc_v16sf, __gcc_v4sf, int, __gcc_v16sf, short); -__gcc_v8df __builtin_ia32_insertf64x4_mask(__gcc_v8df, __gcc_v4df, int, __gcc_v8df, char); -__gcc_v16si __builtin_ia32_inserti32x4_mask(__gcc_v16si, __gcc_v4si, int, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_inserti64x4_mask(__gcc_v8di, __gcc_v4di, int, __gcc_v8di, char); -__gcc_v8df __builtin_ia32_movapd512_mask(__gcc_v8df, __gcc_v8df, char); -__gcc_v16sf __builtin_ia32_movaps512_mask(__gcc_v16sf, __gcc_v16sf, short); -__gcc_v8df __builtin_ia32_movddup512_mask(__gcc_v8df, __gcc_v8df, char); -__gcc_v16si __builtin_ia32_movdqa32_512_mask(__gcc_v16si, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_movdqa64_512_mask(__gcc_v8di, __gcc_v8di, char); -__gcc_v16sf __builtin_ia32_movshdup512_mask(__gcc_v16sf, __gcc_v16sf, short); -__gcc_v16sf __builtin_ia32_movsldup512_mask(__gcc_v16sf, __gcc_v16sf, short); -__gcc_v16si __builtin_ia32_pabsd512_mask(__gcc_v16si, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_pabsq512_mask(__gcc_v8di, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_paddd512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_paddq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_pandd512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, short); -__gcc_v16si __builtin_ia32_pandnd512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_pandnq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, char); -__gcc_v8di __builtin_ia32_pandq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_pbroadcastd512(__gcc_v4si, __gcc_v16si, short); -__gcc_v16si __builtin_ia32_pbroadcastd512_gpr_mask(int, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_broadcastmb512(char); -__gcc_v16si __builtin_ia32_broadcastmw512(short); -__gcc_v8di __builtin_ia32_pbroadcastq512(__gcc_v2di, __gcc_v8di, char); -__gcc_v8di __builtin_ia32_pbroadcastq512_gpr_mask(long long, __gcc_v8di, char); +__gcc_v8df __builtin_ia32_expanddf512_mask(__gcc_v8df, __gcc_v8df, unsigned char); +__gcc_v8df __builtin_ia32_expanddf512_maskz(__gcc_v8df, __gcc_v8df, unsigned char); +__gcc_v16sf __builtin_ia32_expandsf512_mask(__gcc_v16sf, __gcc_v16sf, unsigned short); +__gcc_v16sf __builtin_ia32_expandsf512_maskz(__gcc_v16sf, __gcc_v16sf, unsigned short); +__gcc_v4sf __builtin_ia32_extractf32x4_mask(__gcc_v16sf, int, __gcc_v4sf, unsigned char); +__gcc_v4df __builtin_ia32_extractf64x4_mask(__gcc_v8df, int, __gcc_v4df, unsigned char); +__gcc_v4si __builtin_ia32_extracti32x4_mask(__gcc_v16si, int, __gcc_v4si, unsigned char); +__gcc_v4di __builtin_ia32_extracti64x4_mask(__gcc_v8di, int, __gcc_v4di, unsigned char); +__gcc_v16sf __builtin_ia32_insertf32x4_mask(__gcc_v16sf, __gcc_v4sf, int, __gcc_v16sf, unsigned short); +__gcc_v8df __builtin_ia32_insertf64x4_mask(__gcc_v8df, __gcc_v4df, int, __gcc_v8df, unsigned char); +__gcc_v16si __builtin_ia32_inserti32x4_mask(__gcc_v16si, __gcc_v4si, int, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_inserti64x4_mask(__gcc_v8di, __gcc_v4di, int, __gcc_v8di, unsigned char); +__gcc_v8df __builtin_ia32_movapd512_mask(__gcc_v8df, __gcc_v8df, unsigned char); +__gcc_v16sf __builtin_ia32_movaps512_mask(__gcc_v16sf, __gcc_v16sf, unsigned short); +__gcc_v8df __builtin_ia32_movddup512_mask(__gcc_v8df, __gcc_v8df, unsigned char); +__gcc_v16si __builtin_ia32_movdqa32_512_mask(__gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_movdqa64_512_mask(__gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v16sf __builtin_ia32_movshdup512_mask(__gcc_v16sf, __gcc_v16sf, unsigned short); +__gcc_v16sf __builtin_ia32_movsldup512_mask(__gcc_v16sf, __gcc_v16sf, unsigned short); +__gcc_v16si __builtin_ia32_pabsd512_mask(__gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_pabsq512_mask(__gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_paddd512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_paddq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_pandd512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v16si __builtin_ia32_pandnd512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_pandnq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v8di __builtin_ia32_pandq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_pbroadcastd512(__gcc_v4si, __gcc_v16si, unsigned short); +__gcc_v16si __builtin_ia32_pbroadcastd512_gpr_mask(int, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_broadcastmb512(unsigned char); +__gcc_v16si __builtin_ia32_broadcastmw512(unsigned short); +__gcc_v8di __builtin_ia32_pbroadcastq512(__gcc_v2di, __gcc_v8di, unsigned char); +__gcc_v8di __builtin_ia32_pbroadcastq512_gpr_mask(long long, __gcc_v8di, unsigned char); __gcc_v8di __builtin_ia32_pbroadcastq512_mem_mask(long long, __gcc_v8di, char); -short __builtin_ia32_pcmpeqd512_mask(__gcc_v16si, __gcc_v16si, short); -char __builtin_ia32_pcmpeqq512_mask(__gcc_v8di, __gcc_v8di, char); -short __builtin_ia32_pcmpgtd512_mask(__gcc_v16si, __gcc_v16si, short); -char __builtin_ia32_pcmpgtq512_mask(__gcc_v8di, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_compresssi512_mask(__gcc_v16si, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_compressdi512_mask(__gcc_v8di, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_expandsi512_mask(__gcc_v16si, __gcc_v16si, short); -__gcc_v16si __builtin_ia32_expandsi512_maskz(__gcc_v16si, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_expanddi512_mask(__gcc_v8di, __gcc_v8di, char); -__gcc_v8di __builtin_ia32_expanddi512_maskz(__gcc_v8di, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_pmaxsd512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_pmaxsq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_pmaxud512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_pmaxuq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_pminsd512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_pminsq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_pminud512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_pminuq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, char); -__gcc_v16qi __builtin_ia32_pmovdb512_mask(__gcc_v16si, __gcc_v16qi, short); -__gcc_v16hi __builtin_ia32_pmovdw512_mask(__gcc_v16si, __gcc_v16hi, short); -__gcc_v16qi __builtin_ia32_pmovqb512_mask(__gcc_v8di, __gcc_v16qi, char); -__gcc_v8si __builtin_ia32_pmovqd512_mask(__gcc_v8di, __gcc_v8si, char); -__gcc_v8hi __builtin_ia32_pmovqw512_mask(__gcc_v8di, __gcc_v8hi, char); -__gcc_v16qi __builtin_ia32_pmovsdb512_mask(__gcc_v16si, __gcc_v16qi, short); -__gcc_v16hi __builtin_ia32_pmovsdw512_mask(__gcc_v16si, __gcc_v16hi, short); -__gcc_v16qi __builtin_ia32_pmovsqb512_mask(__gcc_v8di, __gcc_v16qi, char); -__gcc_v8si __builtin_ia32_pmovsqd512_mask(__gcc_v8di, __gcc_v8si, char); -__gcc_v8hi __builtin_ia32_pmovsqw512_mask(__gcc_v8di, __gcc_v8hi, char); -__gcc_v16si __builtin_ia32_pmovsxbd512_mask(__gcc_v16qi, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_pmovsxbq512_mask(__gcc_v16qi, __gcc_v8di, char); -__gcc_v8di __builtin_ia32_pmovsxdq512_mask(__gcc_v8si, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_pmovsxwd512_mask(__gcc_v16hi, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_pmovsxwq512_mask(__gcc_v8hi, __gcc_v8di, char); -__gcc_v16qi __builtin_ia32_pmovusdb512_mask(__gcc_v16si, __gcc_v16qi, short); -__gcc_v16hi __builtin_ia32_pmovusdw512_mask(__gcc_v16si, __gcc_v16hi, short); -__gcc_v16qi __builtin_ia32_pmovusqb512_mask(__gcc_v8di, __gcc_v16qi, char); -__gcc_v8si __builtin_ia32_pmovusqd512_mask(__gcc_v8di, __gcc_v8si, char); -__gcc_v8hi __builtin_ia32_pmovusqw512_mask(__gcc_v8di, __gcc_v8hi, char); -__gcc_v16si __builtin_ia32_pmovzxbd512_mask(__gcc_v16qi, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_pmovzxbq512_mask(__gcc_v16qi, __gcc_v8di, char); -__gcc_v8di __builtin_ia32_pmovzxdq512_mask(__gcc_v8si, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_pmovzxwd512_mask(__gcc_v16hi, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_pmovzxwq512_mask(__gcc_v8hi, __gcc_v8di, char); -__gcc_v8di __builtin_ia32_pmuldq512_mask(__gcc_v16si, __gcc_v16si, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_pmulld512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_pmuludq512_mask(__gcc_v16si, __gcc_v16si, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_pord512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_porq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_prold512_mask(__gcc_v16si, int, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_prolq512_mask(__gcc_v8di, int, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_prolvd512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_prolvq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_prord512_mask(__gcc_v16si, int, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_prorq512_mask(__gcc_v8di, int, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_prorvd512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_prorvq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_pshufd512_mask(__gcc_v16si, int, __gcc_v16si, short); +unsigned short __builtin_ia32_pcmpeqd512_mask(__gcc_v16si, __gcc_v16si, unsigned short); +unsigned char __builtin_ia32_pcmpeqq512_mask(__gcc_v8di, __gcc_v8di, unsigned char); +unsigned short __builtin_ia32_pcmpgtd512_mask(__gcc_v16si, __gcc_v16si, unsigned short); +unsigned char __builtin_ia32_pcmpgtq512_mask(__gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_compresssi512_mask(__gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_compressdi512_mask(__gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_expandsi512_mask(__gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v16si __builtin_ia32_expandsi512_maskz(__gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_expanddi512_mask(__gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v8di __builtin_ia32_expanddi512_maskz(__gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_pmaxsd512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_pmaxsq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_pmaxud512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_pmaxuq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_pminsd512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_pminsq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_pminud512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_pminuq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v16qi __builtin_ia32_pmovdb512_mask(__gcc_v16si, __gcc_v16qi, unsigned short); +__gcc_v16hi __builtin_ia32_pmovdw512_mask(__gcc_v16si, __gcc_v16hi, unsigned short); +__gcc_v16qi __builtin_ia32_pmovqb512_mask(__gcc_v8di, __gcc_v16qi, unsigned char); +__gcc_v8si __builtin_ia32_pmovqd512_mask(__gcc_v8di, __gcc_v8si, unsigned char); +__gcc_v8hi __builtin_ia32_pmovqw512_mask(__gcc_v8di, __gcc_v8hi, unsigned char); +__gcc_v16qi __builtin_ia32_pmovsdb512_mask(__gcc_v16si, __gcc_v16qi, unsigned short); +__gcc_v16hi __builtin_ia32_pmovsdw512_mask(__gcc_v16si, __gcc_v16hi, unsigned short); +__gcc_v16qi __builtin_ia32_pmovsqb512_mask(__gcc_v8di, __gcc_v16qi, unsigned char); +__gcc_v8si __builtin_ia32_pmovsqd512_mask(__gcc_v8di, __gcc_v8si, unsigned char); +__gcc_v8hi __builtin_ia32_pmovsqw512_mask(__gcc_v8di, __gcc_v8hi, unsigned char); +__gcc_v16si __builtin_ia32_pmovsxbd512_mask(__gcc_v16qi, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_pmovsxbq512_mask(__gcc_v16qi, __gcc_v8di, unsigned char); +__gcc_v8di __builtin_ia32_pmovsxdq512_mask(__gcc_v8si, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_pmovsxwd512_mask(__gcc_v16hi, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_pmovsxwq512_mask(__gcc_v8hi, __gcc_v8di, unsigned char); +__gcc_v16qi __builtin_ia32_pmovusdb512_mask(__gcc_v16si, __gcc_v16qi, unsigned short); +__gcc_v16hi __builtin_ia32_pmovusdw512_mask(__gcc_v16si, __gcc_v16hi, unsigned short); +__gcc_v16qi __builtin_ia32_pmovusqb512_mask(__gcc_v8di, __gcc_v16qi, unsigned char); +__gcc_v8si __builtin_ia32_pmovusqd512_mask(__gcc_v8di, __gcc_v8si, unsigned char); +__gcc_v8hi __builtin_ia32_pmovusqw512_mask(__gcc_v8di, __gcc_v8hi, unsigned char); +__gcc_v16si __builtin_ia32_pmovzxbd512_mask(__gcc_v16qi, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_pmovzxbq512_mask(__gcc_v16qi, __gcc_v8di, unsigned char); +__gcc_v8di __builtin_ia32_pmovzxdq512_mask(__gcc_v8si, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_pmovzxwd512_mask(__gcc_v16hi, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_pmovzxwq512_mask(__gcc_v8hi, __gcc_v8di, unsigned char); +__gcc_v8di __builtin_ia32_pmuldq512_mask(__gcc_v16si, __gcc_v16si, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_pmulld512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_pmuludq512_mask(__gcc_v16si, __gcc_v16si, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_pord512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_porq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_prold512_mask(__gcc_v16si, int, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_prolq512_mask(__gcc_v8di, int, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_prolvd512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_prolvq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_prord512_mask(__gcc_v16si, int, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_prorq512_mask(__gcc_v8di, int, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_prorvd512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_prorvq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_pshufd512_mask(__gcc_v16si, int, __gcc_v16si, unsigned short); __gcc_v16si __builtin_ia32_pslld512_mask(__gcc_v16si, __gcc_v4si, __gcc_v16si, short); __gcc_v16si __builtin_ia32_pslldi512_mask(__gcc_v16si, int, __gcc_v16si, short); __gcc_v8di __builtin_ia32_psllq512_mask(__gcc_v8di, __gcc_v2di, __gcc_v8di, char); __gcc_v8di __builtin_ia32_psllqi512_mask(__gcc_v8di, int, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_psllv16si_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_psllv8di_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, char); +__gcc_v16si __builtin_ia32_psllv16si_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_psllv8di_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); __gcc_v16si __builtin_ia32_psrad512_mask(__gcc_v16si, __gcc_v4si, __gcc_v16si, short); __gcc_v16si __builtin_ia32_psradi512_mask(__gcc_v16si, int, __gcc_v16si, short); __gcc_v8di __builtin_ia32_psraq512_mask(__gcc_v8di, __gcc_v2di, __gcc_v8di, char); __gcc_v8di __builtin_ia32_psraqi512_mask(__gcc_v8di, int, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_psrav16si_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_psrav8di_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, char); +__gcc_v16si __builtin_ia32_psrav16si_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_psrav8di_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); __gcc_v16si __builtin_ia32_psrld512_mask(__gcc_v16si, __gcc_v4si, __gcc_v16si, short); __gcc_v16si __builtin_ia32_psrldi512_mask(__gcc_v16si, int, __gcc_v16si, short); __gcc_v8di __builtin_ia32_psrlq512_mask(__gcc_v8di, __gcc_v2di, __gcc_v8di, char); __gcc_v8di __builtin_ia32_psrlqi512_mask(__gcc_v8di, int, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_psrlv16si_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_psrlv8di_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_psubd512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_psubq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, char); -short __builtin_ia32_ptestmd512(__gcc_v16si, __gcc_v16si, short); -char __builtin_ia32_ptestmq512(__gcc_v8di, __gcc_v8di, char); -short __builtin_ia32_ptestnmd512(__gcc_v16si, __gcc_v16si, short); -char __builtin_ia32_ptestnmq512(__gcc_v8di, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_punpckhdq512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_punpckhqdq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_punpckldq512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_punpcklqdq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_pxord512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_pxorq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, char); -__gcc_v8df __builtin_ia32_rcp14pd512_mask(__gcc_v8df, __gcc_v8df, char); -__gcc_v16sf __builtin_ia32_rcp14ps512_mask(__gcc_v16sf, __gcc_v16sf, short); +__gcc_v16si __builtin_ia32_psrlv16si_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_psrlv8di_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_psubd512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_psubq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); +unsigned short __builtin_ia32_ptestmd512(__gcc_v16si, __gcc_v16si, unsigned short); +unsigned char __builtin_ia32_ptestmq512(__gcc_v8di, __gcc_v8di, unsigned char); +unsigned short __builtin_ia32_ptestnmd512(__gcc_v16si, __gcc_v16si, unsigned short); +unsigned char __builtin_ia32_ptestnmq512(__gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_punpckhdq512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_punpckhqdq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_punpckldq512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_punpcklqdq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_pxord512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_pxorq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v8df __builtin_ia32_rcp14pd512_mask(__gcc_v8df, __gcc_v8df, unsigned char); +__gcc_v16sf __builtin_ia32_rcp14ps512_mask(__gcc_v16sf, __gcc_v16sf, unsigned short); __gcc_v2df __builtin_ia32_rcp14sd(__gcc_v2df, __gcc_v2df); __gcc_v4sf __builtin_ia32_rcp14ss(__gcc_v4sf, __gcc_v4sf); -__gcc_v8df __builtin_ia32_rsqrt14pd512_mask(__gcc_v8df, __gcc_v8df, char); -__gcc_v16sf __builtin_ia32_rsqrt14ps512_mask(__gcc_v16sf, __gcc_v16sf, short); +__gcc_v8df __builtin_ia32_rsqrt14pd512_mask(__gcc_v8df, __gcc_v8df, unsigned char); +__gcc_v16sf __builtin_ia32_rsqrt14ps512_mask(__gcc_v16sf, __gcc_v16sf, unsigned short); __gcc_v2df __builtin_ia32_rsqrt14sd(__gcc_v2df, __gcc_v2df); __gcc_v4sf __builtin_ia32_rsqrt14ss(__gcc_v4sf, __gcc_v4sf); -__gcc_v8df __builtin_ia32_shufpd512_mask(__gcc_v8df, __gcc_v8df, int, __gcc_v8df, char); -__gcc_v16sf __builtin_ia32_shufps512_mask(__gcc_v16sf, __gcc_v16sf, int, __gcc_v16sf, short); -__gcc_v16sf __builtin_ia32_shuf_f32x4_mask(__gcc_v16sf, __gcc_v16sf, int, __gcc_v16sf, short); -__gcc_v8df __builtin_ia32_shuf_f64x2_mask(__gcc_v8df, __gcc_v8df, int, __gcc_v8df, char); -__gcc_v16si __builtin_ia32_shuf_i32x4_mask(__gcc_v16si, __gcc_v16si, int, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_shuf_i64x2_mask(__gcc_v8di, __gcc_v8di, int, __gcc_v8di, char); +__gcc_v8df __builtin_ia32_shufpd512_mask(__gcc_v8df, __gcc_v8df, int, __gcc_v8df, unsigned char); +__gcc_v16sf __builtin_ia32_shufps512_mask(__gcc_v16sf, __gcc_v16sf, int, __gcc_v16sf, unsigned short); +__gcc_v16sf __builtin_ia32_shuf_f32x4_mask(__gcc_v16sf, __gcc_v16sf, int, __gcc_v16sf, unsigned short); +__gcc_v8df __builtin_ia32_shuf_f64x2_mask(__gcc_v8df, __gcc_v8df, int, __gcc_v8df, unsigned char); +__gcc_v16si __builtin_ia32_shuf_i32x4_mask(__gcc_v16si, __gcc_v16si, int, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_shuf_i64x2_mask(__gcc_v8di, __gcc_v8di, int, __gcc_v8di, unsigned char); short __builtin_ia32_ucmpd512_mask(__gcc_v16si, __gcc_v16si, int, short); -char __builtin_ia32_ucmpq512_mask(__gcc_v8di, __gcc_v8di, int, char); -__gcc_v8df __builtin_ia32_unpckhpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, char); -__gcc_v16sf __builtin_ia32_unpckhps512_mask(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, short); -__gcc_v8df __builtin_ia32_unpcklpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, char); -__gcc_v16sf __builtin_ia32_unpcklps512_mask(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, short); -__gcc_v16si __builtin_ia32_vplzcntd_512_mask(__gcc_v16si, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_vplzcntq_512_mask(__gcc_v8di, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_vpconflictsi_512_mask(__gcc_v16si, __gcc_v16si, short); -__gcc_v8di __builtin_ia32_vpconflictdi_512_mask(__gcc_v8di, __gcc_v8di, char); -__gcc_v8df __builtin_ia32_permdf512_mask(__gcc_v8df, int, __gcc_v8df, char); -__gcc_v8di __builtin_ia32_permdi512_mask(__gcc_v8di, int, __gcc_v8di, char); -__gcc_v16si __builtin_ia32_vpermi2vard512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, short); -__gcc_v8df __builtin_ia32_vpermi2varpd512_mask(__gcc_v8df, __gcc_v8di, __gcc_v8df, char); -__gcc_v16sf __builtin_ia32_vpermi2varps512_mask(__gcc_v16sf, __gcc_v16si, __gcc_v16sf, short); -__gcc_v8di __builtin_ia32_vpermi2varq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, char); -__gcc_v8df __builtin_ia32_vpermilpd512_mask(__gcc_v8df, int, __gcc_v8df, char); -__gcc_v16sf __builtin_ia32_vpermilps512_mask(__gcc_v16sf, int, __gcc_v16sf, short); -__gcc_v8df __builtin_ia32_vpermilvarpd512_mask(__gcc_v8df, __gcc_v8di, __gcc_v8df, char); -__gcc_v16sf __builtin_ia32_vpermilvarps512_mask(__gcc_v16sf, __gcc_v16si, __gcc_v16sf, short); -__gcc_v16si __builtin_ia32_vpermt2vard512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, short); -__gcc_v16si __builtin_ia32_vpermt2vard512_maskz(__gcc_v16si, __gcc_v16si, __gcc_v16si, short); -__gcc_v8df __builtin_ia32_vpermt2varpd512_mask(__gcc_v8di, __gcc_v8df, __gcc_v8df, char); -__gcc_v8df __builtin_ia32_vpermt2varpd512_maskz(__gcc_v8di, __gcc_v8df, __gcc_v8df, char); -__gcc_v16sf __builtin_ia32_vpermt2varps512_mask(__gcc_v16si, __gcc_v16sf, __gcc_v16sf, short); -__gcc_v16sf __builtin_ia32_vpermt2varps512_maskz(__gcc_v16si, __gcc_v16sf, __gcc_v16sf, short); -__gcc_v8di __builtin_ia32_vpermt2varq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, char); -__gcc_v8di __builtin_ia32_vpermt2varq512_maskz(__gcc_v8di, __gcc_v8di, __gcc_v8di, char); -__gcc_v8df __builtin_ia32_permvardf512_mask(__gcc_v8df, __gcc_v8di, __gcc_v8df, char); -__gcc_v8di __builtin_ia32_permvardi512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, char); -__gcc_v16sf __builtin_ia32_permvarsf512_mask(__gcc_v16sf, __gcc_v16si, __gcc_v16sf, short); -__gcc_v16si __builtin_ia32_permvarsi512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, short); -__gcc_v16si __builtin_ia32_pternlogd512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, int, short); -__gcc_v16si __builtin_ia32_pternlogd512_maskz(__gcc_v16si, __gcc_v16si, __gcc_v16si, int, short); -__gcc_v8di __builtin_ia32_pternlogq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, int, char); -__gcc_v8di __builtin_ia32_pternlogq512_maskz(__gcc_v8di, __gcc_v8di, __gcc_v8di, int, char); +unsigned char __builtin_ia32_ucmpq512_mask(__gcc_v8di, __gcc_v8di, int, unsigned char); +__gcc_v8df __builtin_ia32_unpckhpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, unsigned char); +__gcc_v16sf __builtin_ia32_unpckhps512_mask(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, unsigned short); +__gcc_v8df __builtin_ia32_unpcklpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, unsigned char); +__gcc_v16sf __builtin_ia32_unpcklps512_mask(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, unsigned short); +__gcc_v16si __builtin_ia32_vplzcntd_512_mask(__gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_vplzcntq_512_mask(__gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_vpconflictsi_512_mask(__gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_vpconflictdi_512_mask(__gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v8df __builtin_ia32_permdf512_mask(__gcc_v8df, int, __gcc_v8df, unsigned char); +__gcc_v8di __builtin_ia32_permdi512_mask(__gcc_v8di, int, __gcc_v8di, unsigned char); +__gcc_v16si __builtin_ia32_vpermi2vard512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8df __builtin_ia32_vpermi2varpd512_mask(__gcc_v8df, __gcc_v8di, __gcc_v8df, unsigned char); +__gcc_v16sf __builtin_ia32_vpermi2varps512_mask(__gcc_v16sf, __gcc_v16si, __gcc_v16sf, unsigned short); +__gcc_v8di __builtin_ia32_vpermi2varq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v8df __builtin_ia32_vpermilpd512_mask(__gcc_v8df, int, __gcc_v8df, unsigned char); +__gcc_v16sf __builtin_ia32_vpermilps512_mask(__gcc_v16sf, int, __gcc_v16sf, unsigned short); +__gcc_v8df __builtin_ia32_vpermilvarpd512_mask(__gcc_v8df, __gcc_v8di, __gcc_v8df, unsigned char); +__gcc_v16sf __builtin_ia32_vpermilvarps512_mask(__gcc_v16sf, __gcc_v16si, __gcc_v16sf, unsigned short); +__gcc_v16si __builtin_ia32_vpermt2vard512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v16si __builtin_ia32_vpermt2vard512_maskz(__gcc_v16si, __gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8df __builtin_ia32_vpermt2varpd512_mask(__gcc_v8di, __gcc_v8df, __gcc_v8df, unsigned char); +__gcc_v8df __builtin_ia32_vpermt2varpd512_maskz(__gcc_v8di, __gcc_v8df, __gcc_v8df, unsigned char); +__gcc_v16sf __builtin_ia32_vpermt2varps512_mask(__gcc_v16si, __gcc_v16sf, __gcc_v16sf, unsigned short); +__gcc_v16sf __builtin_ia32_vpermt2varps512_maskz(__gcc_v16si, __gcc_v16sf, __gcc_v16sf, unsigned short); +__gcc_v8di __builtin_ia32_vpermt2varq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v8di __builtin_ia32_vpermt2varq512_maskz(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v8df __builtin_ia32_permvardf512_mask(__gcc_v8df, __gcc_v8di, __gcc_v8df, unsigned char); +__gcc_v8di __builtin_ia32_permvardi512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v16sf __builtin_ia32_permvarsf512_mask(__gcc_v16sf, __gcc_v16si, __gcc_v16sf, unsigned short); +__gcc_v16si __builtin_ia32_permvarsi512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v16si __builtin_ia32_pternlogd512_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, int, unsigned short); +__gcc_v16si __builtin_ia32_pternlogd512_maskz(__gcc_v16si, __gcc_v16si, __gcc_v16si, int, unsigned short); +__gcc_v8di __builtin_ia32_pternlogq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, int, unsigned char); +__gcc_v8di __builtin_ia32_pternlogq512_maskz(__gcc_v8di, __gcc_v8di, __gcc_v8di, int, unsigned char); __gcc_v16sf __builtin_ia32_copysignps512(__gcc_v16sf, __gcc_v16sf); __gcc_v8df __builtin_ia32_copysignpd512(__gcc_v8df, __gcc_v8df); __gcc_v8df __builtin_ia32_sqrtpd512(__gcc_v8df); @@ -383,24 +383,24 @@ __gcc_v16sf __builtin_ia32_exp2ps(__gcc_v16sf); __gcc_v16si __builtin_ia32_roundpd_az_vec_pack_sfix512(__gcc_v8df, __gcc_v8df); __gcc_v16si __builtin_ia32_floorpd_vec_pack_sfix512(__gcc_v8df, __gcc_v8df, const int); __gcc_v16si __builtin_ia32_ceilpd_vec_pack_sfix512(__gcc_v8df, __gcc_v8df, const int); -short __builtin_ia32_kandhi(short, short); -short __builtin_ia32_kandnhi(short, short); -short __builtin_ia32_knothi(short); -short __builtin_ia32_korhi(short, short); -short __builtin_ia32_kortestchi(short, short); -short __builtin_ia32_kortestzhi(short, short); -short __builtin_ia32_kunpckhi(short, short); -short __builtin_ia32_kxnorhi(short, short); -short __builtin_ia32_kxorhi(short, short); +unsigned short __builtin_ia32_kandhi(unsigned short, unsigned short); +unsigned short __builtin_ia32_kandnhi(unsigned short, unsigned short); +unsigned short __builtin_ia32_knothi(unsigned short); +unsigned short __builtin_ia32_korhi(unsigned short, unsigned short); +unsigned short __builtin_ia32_kortestchi(unsigned short, unsigned short); +unsigned short __builtin_ia32_kortestzhi(unsigned short, unsigned short); +unsigned short __builtin_ia32_kunpckhi(unsigned short, unsigned short); +unsigned short __builtin_ia32_kxnorhi(unsigned short, unsigned short); +unsigned short __builtin_ia32_kxorhi(unsigned short, unsigned short); short __builtin_ia32_kmov16(short); -__gcc_v8df __builtin_ia32_addpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, char, int); +__gcc_v8df __builtin_ia32_addpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, unsigned char, int); __gcc_v16sf __builtin_ia32_addps512_mask(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, short, int); __gcc_v2df __builtin_ia32_addsd_round(__gcc_v2df, __gcc_v2df, int); __gcc_v4sf __builtin_ia32_addss_round(__gcc_v4sf, __gcc_v4sf, int); -char __builtin_ia32_cmppd512_mask(__gcc_v8df, __gcc_v8df, int, char, int); -short __builtin_ia32_cmpps512_mask(__gcc_v16sf, __gcc_v16sf, int, short, int); -char __builtin_ia32_cmpsd_mask(__gcc_v2df, __gcc_v2df, int, char, int); -char __builtin_ia32_cmpss_mask(__gcc_v4sf, __gcc_v4sf, int, char, int); +unsigned char __builtin_ia32_cmppd512_mask(__gcc_v8df, __gcc_v8df, int, unsigned char, int); +unsigned short __builtin_ia32_cmpps512_mask(__gcc_v16sf, __gcc_v16sf, int, unsigned short, int); +unsigned char __builtin_ia32_cmpsd_mask(__gcc_v2df, __gcc_v2df, int, unsigned char, int); +unsigned char __builtin_ia32_cmpss_mask(__gcc_v4sf, __gcc_v4sf, int, unsigned char, int); int __builtin_ia32_vcomisd(__gcc_v2df, __gcc_v2df, int, int); int __builtin_ia32_vcomiss(__gcc_v4sf, __gcc_v4sf, int, int); __gcc_v16sf __builtin_ia32_cvtdq2ps512_mask(__gcc_v16si, __gcc_v16sf, short, int); @@ -424,7 +424,7 @@ __gcc_v16sf __builtin_ia32_cvtudq2ps512_mask(__gcc_v16si, __gcc_v16sf, short, in __gcc_v2df __builtin_ia32_cvtusi2sd64(__gcc_v2df, unsigned long long, int); __gcc_v4sf __builtin_ia32_cvtusi2ss32(__gcc_v4sf, unsigned, int); __gcc_v4sf __builtin_ia32_cvtusi2ss64(__gcc_v4sf, unsigned long long, int); -__gcc_v8df __builtin_ia32_divpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, char, int); +__gcc_v8df __builtin_ia32_divpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, unsigned char, int); __gcc_v16sf __builtin_ia32_divps512_mask(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, short, int); __gcc_v2df __builtin_ia32_divsd_round(__gcc_v2df, __gcc_v2df, int); __gcc_v4sf __builtin_ia32_divss_round(__gcc_v4sf, __gcc_v4sf, int); @@ -444,15 +444,15 @@ __gcc_v8df __builtin_ia32_getmantpd512_mask(__gcc_v8df, int, __gcc_v8df, char, i __gcc_v16sf __builtin_ia32_getmantps512_mask(__gcc_v16sf, int, __gcc_v16sf, short, int); __gcc_v2df __builtin_ia32_getmantsd_round(__gcc_v2df, __gcc_v2df, int, int); __gcc_v4sf __builtin_ia32_getmantss_round(__gcc_v4sf, __gcc_v4sf, int, int); -__gcc_v8df __builtin_ia32_maxpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, char, int); +__gcc_v8df __builtin_ia32_maxpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, unsigned char, int); __gcc_v16sf __builtin_ia32_maxps512_mask(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, short, int); __gcc_v2df __builtin_ia32_maxsd_round(__gcc_v2df, __gcc_v2df, int); __gcc_v4sf __builtin_ia32_maxss_round(__gcc_v4sf, __gcc_v4sf, int); -__gcc_v8df __builtin_ia32_minpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, char, int); +__gcc_v8df __builtin_ia32_minpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, unsigned char, int); __gcc_v16sf __builtin_ia32_minps512_mask(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, short, int); __gcc_v2df __builtin_ia32_minsd_round(__gcc_v2df, __gcc_v2df, int); __gcc_v4sf __builtin_ia32_minss_round(__gcc_v4sf, __gcc_v4sf, int); -__gcc_v8df __builtin_ia32_mulpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, char, int); +__gcc_v8df __builtin_ia32_mulpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, unsigned char, int); __gcc_v16sf __builtin_ia32_mulps512_mask(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, short, int); __gcc_v2df __builtin_ia32_mulsd_round(__gcc_v2df, __gcc_v2df, int); __gcc_v4sf __builtin_ia32_mulss_round(__gcc_v4sf, __gcc_v4sf, int); @@ -460,7 +460,7 @@ __gcc_v8df __builtin_ia32_rndscalepd_mask(__gcc_v8df, int, __gcc_v8df, char, int __gcc_v16sf __builtin_ia32_rndscaleps_mask(__gcc_v16sf, int, __gcc_v16sf, short, int); __gcc_v2df __builtin_ia32_rndscalesd_round(__gcc_v2df, __gcc_v2df, int, int); __gcc_v4sf __builtin_ia32_rndscaless_round(__gcc_v4sf, __gcc_v4sf, int, int); -__gcc_v8df __builtin_ia32_scalefpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, char, int); +__gcc_v8df __builtin_ia32_scalefpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, unsigned char, int); __gcc_v16sf __builtin_ia32_scalefps512_mask(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, short, int); __gcc_v2df __builtin_ia32_scalefsd_round(__gcc_v2df, __gcc_v2df, int); __gcc_v4sf __builtin_ia32_scalefss_round(__gcc_v4sf, __gcc_v4sf, int); @@ -468,7 +468,7 @@ __gcc_v8df __builtin_ia32_sqrtpd512_mask(__gcc_v8df, __gcc_v8df, char, int); __gcc_v16sf __builtin_ia32_sqrtps512_mask(__gcc_v16sf, __gcc_v16sf, short, int); __gcc_v2df __builtin_ia32_sqrtsd_round(__gcc_v2df, __gcc_v2df, int); __gcc_v4sf __builtin_ia32_sqrtss_round(__gcc_v4sf, __gcc_v4sf, int); -__gcc_v8df __builtin_ia32_subpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, char, int); +__gcc_v8df __builtin_ia32_subpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, unsigned char, int); __gcc_v16sf __builtin_ia32_subps512_mask(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, short, int); __gcc_v2df __builtin_ia32_subsd_round(__gcc_v2df, __gcc_v2df, int); __gcc_v4sf __builtin_ia32_subss_round(__gcc_v4sf, __gcc_v4sf, int); @@ -494,9 +494,9 @@ __gcc_v4df __builtin_ia32_vfmaddpd256(__gcc_v4df, __gcc_v4df, __gcc_v4df); __gcc_v4sf __builtin_ia32_vfmaddps(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf); __gcc_v4sf __builtin_ia32_vfmaddss3(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf); __gcc_v8sf __builtin_ia32_vfmaddps256(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf); -__gcc_v8df __builtin_ia32_vfmaddpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, char, int); -__gcc_v8df __builtin_ia32_vfmaddpd512_mask3(__gcc_v8df, __gcc_v8df, __gcc_v8df, char, int); -__gcc_v8df __builtin_ia32_vfmaddpd512_maskz(__gcc_v8df, __gcc_v8df, __gcc_v8df, char, int); +__gcc_v8df __builtin_ia32_vfmaddpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, unsigned char, int); +__gcc_v8df __builtin_ia32_vfmaddpd512_mask3(__gcc_v8df, __gcc_v8df, __gcc_v8df, unsigned char, int); +__gcc_v8df __builtin_ia32_vfmaddpd512_maskz(__gcc_v8df, __gcc_v8df, __gcc_v8df, unsigned char, int); __gcc_v16sf __builtin_ia32_vfmaddps512_mask(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, short, int); __gcc_v16sf __builtin_ia32_vfmaddps512_mask3(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, short, int); __gcc_v16sf __builtin_ia32_vfmaddps512_maskz(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, short, int); @@ -506,20 +506,20 @@ __gcc_v2df __builtin_ia32_vfmaddsubpd(__gcc_v2df,__gcc_v2df, __gcc_v2df); __gcc_v4df __builtin_ia32_vfmaddsubpd256(__gcc_v4df, __gcc_v4df, __gcc_v4df); __gcc_v4sf __builtin_ia32_vfmaddsubps(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf); __gcc_v8sf __builtin_ia32_vfmaddsubps256(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf); -__gcc_v8df __builtin_ia32_vfmaddsubpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, char, int); -__gcc_v8df __builtin_ia32_vfmaddsubpd512_mask3(__gcc_v8df, __gcc_v8df, __gcc_v8df, char, int); -__gcc_v8df __builtin_ia32_vfmaddsubpd512_maskz(__gcc_v8df, __gcc_v8df, __gcc_v8df, char, int); +__gcc_v8df __builtin_ia32_vfmaddsubpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, unsigned char, int); +__gcc_v8df __builtin_ia32_vfmaddsubpd512_mask3(__gcc_v8df, __gcc_v8df, __gcc_v8df, unsigned char, int); +__gcc_v8df __builtin_ia32_vfmaddsubpd512_maskz(__gcc_v8df, __gcc_v8df, __gcc_v8df, unsigned char, int); __gcc_v16sf __builtin_ia32_vfmaddsubps512_mask(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, short, int); __gcc_v16sf __builtin_ia32_vfmaddsubps512_mask3(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, short, int); __gcc_v16sf __builtin_ia32_vfmaddsubps512_maskz(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, short, int); -__gcc_v8df __builtin_ia32_vfmsubaddpd512_mask3(__gcc_v8df, __gcc_v8df, __gcc_v8df, char, int); +__gcc_v8df __builtin_ia32_vfmsubaddpd512_mask3(__gcc_v8df, __gcc_v8df, __gcc_v8df, unsigned char, int); __gcc_v16sf __builtin_ia32_vfmsubaddps512_mask3(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, short, int); -__gcc_v8df __builtin_ia32_vfmsubpd512_mask3(__gcc_v8df, __gcc_v8df, __gcc_v8df, char, int); +__gcc_v8df __builtin_ia32_vfmsubpd512_mask3(__gcc_v8df, __gcc_v8df, __gcc_v8df, unsigned char, int); __gcc_v16sf __builtin_ia32_vfmsubps512_mask3(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, short, int); -__gcc_v8df __builtin_ia32_vfnmaddpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, char, int); +__gcc_v8df __builtin_ia32_vfnmaddpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, unsigned char, int); __gcc_v16sf __builtin_ia32_vfnmaddps512_mask(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, short, int); -__gcc_v8df __builtin_ia32_vfnmsubpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, char, int); -__gcc_v8df __builtin_ia32_vfnmsubpd512_mask3(__gcc_v8df, __gcc_v8df, __gcc_v8df, char, int); +__gcc_v8df __builtin_ia32_vfnmsubpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, unsigned char, int); +__gcc_v8df __builtin_ia32_vfnmsubpd512_mask3(__gcc_v8df, __gcc_v8df, __gcc_v8df, unsigned char, int); __gcc_v16sf __builtin_ia32_vfnmsubps512_mask(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, short, int); __gcc_v16sf __builtin_ia32_vfnmsubps512_mask3(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, short, int); __gcc_v8df __builtin_ia32_exp2pd_mask(__gcc_v8df, __gcc_v8df, char, int); diff --git a/src/ansi-c/gcc_builtin_headers_ia32-3.h b/src/ansi-c/gcc_builtin_headers_ia32-3.h new file mode 100644 index 00000000000..08aa6aee4c1 --- /dev/null +++ b/src/ansi-c/gcc_builtin_headers_ia32-3.h @@ -0,0 +1,666 @@ +__gcc_v32hi __builtin_ia32_loaddquhi512_mask(const short*, __gcc_v32hi, unsigned); +__gcc_v64qi __builtin_ia32_loaddquqi512_mask(const char*, __gcc_v64qi, unsigned long long); +void __builtin_ia32_storedquhi512_mask(short*, __gcc_v32hi, unsigned); +void __builtin_ia32_storedquqi512_mask(char*, __gcc_v64qi, unsigned long long); +__gcc_v16hi __builtin_ia32_loaddquhi256_mask(const short*, __gcc_v16hi, unsigned short); +__gcc_v8hi __builtin_ia32_loaddquhi128_mask(const short*, __gcc_v8hi, unsigned char); +__gcc_v32qi __builtin_ia32_loaddquqi256_mask(const char*, __gcc_v32qi, unsigned); +__gcc_v16qi __builtin_ia32_loaddquqi128_mask(const char*, __gcc_v16qi, unsigned short); +__gcc_v4di __builtin_ia32_movdqa64load256_mask(const __gcc_v4di*, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_movdqa64load128_mask(const __gcc_v2di*, __gcc_v2di, unsigned char); +__gcc_v8si __builtin_ia32_movdqa32load256_mask(const __gcc_v8si*, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_movdqa32load128_mask(const __gcc_v4si*, __gcc_v4si, unsigned char); +void __builtin_ia32_movdqa64store256_mask(__gcc_v4di*, __gcc_v4di, unsigned char); +void __builtin_ia32_movdqa64store128_mask(__gcc_v2di*, __gcc_v2di, unsigned char); +void __builtin_ia32_movdqa32store256_mask(__gcc_v8si*, __gcc_v8si, unsigned char); +void __builtin_ia32_movdqa32store128_mask(__gcc_v4si*, __gcc_v4si, unsigned char); +__gcc_v4df __builtin_ia32_loadapd256_mask(const __gcc_v4df*, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_loadapd128_mask(const __gcc_v2df*, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_loadaps256_mask(const __gcc_v8sf*, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_loadaps128_mask(const __gcc_v4sf*, __gcc_v4sf, unsigned char); +void __builtin_ia32_storeapd256_mask(__gcc_v4df*, __gcc_v4df, unsigned char); +void __builtin_ia32_storeapd128_mask(__gcc_v2df*, __gcc_v2df, unsigned char); +void __builtin_ia32_storeaps256_mask(__gcc_v8sf*, __gcc_v8sf, unsigned char); +void __builtin_ia32_storeaps128_mask(__gcc_v4sf*, __gcc_v4sf, unsigned char); +__gcc_v4df __builtin_ia32_loadupd256_mask(const double*, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_loadupd128_mask(const double*, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_loadups256_mask(const float*, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_loadups128_mask(const float*, __gcc_v4sf, unsigned char); +void __builtin_ia32_storeupd256_mask(double*, __gcc_v4df, unsigned char); +void __builtin_ia32_storeupd128_mask(double*, __gcc_v2df, unsigned char); +void __builtin_ia32_storeups256_mask(float*, __gcc_v8sf, unsigned char); +void __builtin_ia32_storeups128_mask(float*, __gcc_v4sf, unsigned char); +__gcc_v4di __builtin_ia32_loaddqudi256_mask(const long long*, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_loaddqudi128_mask(const long long*, __gcc_v2di, unsigned char); +__gcc_v8si __builtin_ia32_loaddqusi256_mask(const int*, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_loaddqusi128_mask(const int*, __gcc_v4si, unsigned char); +void __builtin_ia32_storedqudi256_mask(long long*, __gcc_v4di, unsigned char); +void __builtin_ia32_storedqudi128_mask(long long*, __gcc_v2di, unsigned char); +void __builtin_ia32_storedqusi256_mask(int*, __gcc_v8si, unsigned char); +void __builtin_ia32_storedqusi128_mask(int*, __gcc_v4si, unsigned char); +void __builtin_ia32_storedquhi256_mask(short*, __gcc_v16hi, unsigned short); +void __builtin_ia32_storedquhi128_mask(short*, __gcc_v8hi, unsigned char); +void __builtin_ia32_storedquqi256_mask(char*, __gcc_v32qi, unsigned); +void __builtin_ia32_storedquqi128_mask(char*, __gcc_v16qi, unsigned short); +void __builtin_ia32_compressstoredf256_mask(__gcc_v4df*, __gcc_v4df, unsigned char); +void __builtin_ia32_compressstoredf128_mask(__gcc_v2df*, __gcc_v2df, unsigned char); +void __builtin_ia32_compressstoresf256_mask(__gcc_v8sf*, __gcc_v8sf, unsigned char); +void __builtin_ia32_compressstoresf128_mask(__gcc_v4sf*, __gcc_v4sf, unsigned char); +void __builtin_ia32_compressstoredi256_mask(__gcc_v4di*, __gcc_v4di, unsigned char); +void __builtin_ia32_compressstoredi128_mask(__gcc_v2di*, __gcc_v2di, unsigned char); +void __builtin_ia32_compressstoresi256_mask(__gcc_v8si*, __gcc_v8si, unsigned char); +void __builtin_ia32_compressstoresi128_mask(__gcc_v4si*, __gcc_v4si, unsigned char); +__gcc_v4df __builtin_ia32_expandloaddf256_mask(const __gcc_v4df*, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_expandloaddf128_mask(const __gcc_v2df*, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_expandloadsf256_mask(const __gcc_v8sf*, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_expandloadsf128_mask(const __gcc_v4sf*, __gcc_v4sf, unsigned char); +__gcc_v4di __builtin_ia32_expandloaddi256_mask(const __gcc_v4di*, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_expandloaddi128_mask(const __gcc_v2di*, __gcc_v2di, unsigned char); +__gcc_v8si __builtin_ia32_expandloadsi256_mask(const __gcc_v8si*, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_expandloadsi128_mask(const __gcc_v4si*, __gcc_v4si, unsigned char); +__gcc_v4df __builtin_ia32_expandloaddf256_maskz(const __gcc_v4df*, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_expandloaddf128_maskz(const __gcc_v2df*, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_expandloadsf256_maskz(const __gcc_v8sf*, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_expandloadsf128_maskz(const __gcc_v4sf*, __gcc_v4sf, unsigned char); +__gcc_v4di __builtin_ia32_expandloaddi256_maskz(const __gcc_v4di*, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_expandloaddi128_maskz(const __gcc_v2di*, __gcc_v2di, unsigned char); +__gcc_v8si __builtin_ia32_expandloadsi256_maskz(const __gcc_v8si*, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_expandloadsi128_maskz(const __gcc_v4si*, __gcc_v4si, unsigned char); +void __builtin_ia32_pmovqd256mem_mask(__gcc_v4si*, __gcc_v4di, unsigned char); +void __builtin_ia32_pmovqd128mem_mask(__gcc_v4si*, __gcc_v2di, unsigned char); +void __builtin_ia32_pmovsqd256mem_mask(__gcc_v4si*, __gcc_v4di, unsigned char); +void __builtin_ia32_pmovsqd128mem_mask(__gcc_v4si*, __gcc_v2di, unsigned char); +void __builtin_ia32_pmovusqd256mem_mask(__gcc_v4si*, __gcc_v4di, unsigned char); +void __builtin_ia32_pmovusqd128mem_mask(__gcc_v4si*, __gcc_v2di, unsigned char); +void __builtin_ia32_pmovqw256mem_mask(__gcc_v8hi*, __gcc_v4di, unsigned char); +void __builtin_ia32_pmovqw128mem_mask(__gcc_v8hi*, __gcc_v2di, unsigned char); +void __builtin_ia32_pmovsqw256mem_mask(__gcc_v8hi*, __gcc_v4di, unsigned char); +void __builtin_ia32_pmovsqw128mem_mask(__gcc_v8hi*, __gcc_v2di, unsigned char); +void __builtin_ia32_pmovusqw256mem_mask(__gcc_v8hi*, __gcc_v4di, unsigned char); +void __builtin_ia32_pmovusqw128mem_mask(__gcc_v8hi*, __gcc_v2di, unsigned char); +void __builtin_ia32_pmovqb256mem_mask(__gcc_v16qi*, __gcc_v4di, unsigned char); +void __builtin_ia32_pmovqb128mem_mask(__gcc_v16qi*, __gcc_v2di, unsigned char); +void __builtin_ia32_pmovsqb256mem_mask(__gcc_v16qi*, __gcc_v4di, unsigned char); +void __builtin_ia32_pmovsqb128mem_mask(__gcc_v16qi*, __gcc_v2di, unsigned char); +void __builtin_ia32_pmovusqb256mem_mask(__gcc_v16qi*, __gcc_v4di, unsigned char); +void __builtin_ia32_pmovusqb128mem_mask(__gcc_v16qi*, __gcc_v2di, unsigned char); +void __builtin_ia32_pmovdb256mem_mask(__gcc_v16qi*, __gcc_v8si, unsigned char); +void __builtin_ia32_pmovdb128mem_mask(__gcc_v16qi*, __gcc_v4si, unsigned char); +void __builtin_ia32_pmovsdb256mem_mask(__gcc_v16qi*, __gcc_v8si, unsigned char); +void __builtin_ia32_pmovsdb128mem_mask(__gcc_v16qi*, __gcc_v4si, unsigned char); +void __builtin_ia32_pmovusdb256mem_mask(__gcc_v16qi*, __gcc_v8si, unsigned char); +void __builtin_ia32_pmovusdb128mem_mask(__gcc_v16qi*, __gcc_v4si, unsigned char); +void __builtin_ia32_pmovdw256mem_mask(__gcc_v8hi*, __gcc_v8si, unsigned char); +void __builtin_ia32_pmovdw128mem_mask(__gcc_v8hi*, __gcc_v4si, unsigned char); +void __builtin_ia32_pmovsdw256mem_mask(__gcc_v8hi*, __gcc_v8si, unsigned char); +void __builtin_ia32_pmovsdw128mem_mask(__gcc_v8hi*, __gcc_v4si, unsigned char); +void __builtin_ia32_pmovusdw256mem_mask(__gcc_v8hi*, __gcc_v8si, unsigned char); +void __builtin_ia32_pmovusdw128mem_mask(__gcc_v8hi*, __gcc_v4si, unsigned char); +unsigned __builtin_ia32_rdpkru(); +void __builtin_ia32_wrpkru(unsigned); +__gcc_v8si __builtin_ia32_vec_pack_sfix256 (__gcc_v4df, __gcc_v4df); +unsigned short __builtin_ia32_lzcnt_u16(unsigned short); +unsigned short __builtin_ia32_tzcnt_u16(unsigned short); +unsigned __builtin_ia32_tzcnt_u32(unsigned); +unsigned long long __builtin_ia32_tzcnt_u64(unsigned long long); +__gcc_v16si __builtin_ia32_si512_256si(__gcc_v8si); +__gcc_v16sf __builtin_ia32_ps512_256ps(__gcc_v8sf); +__gcc_v8df __builtin_ia32_pd512_256pd(__gcc_v4df); +__gcc_v16si __builtin_ia32_si512_si(__gcc_v4si); +__gcc_v16sf __builtin_ia32_ps512_ps(__gcc_v4sf); +__gcc_v8df __builtin_ia32_pd512_pd(__gcc_v2df); +__gcc_v16si __builtin_ia32_cvtps2dq512(__gcc_v16sf); +__gcc_v16si __builtin_ia32_vec_pack_sfix512(__gcc_v8df, __gcc_v8df); +__gcc_v16si __builtin_ia32_roundps_az_sfix512(__gcc_v16sf); +unsigned short __builtin_ia32_kshiftlihi(unsigned short, unsigned char); +unsigned __builtin_ia32_kshiftlisi(unsigned, unsigned char); +unsigned long long __builtin_ia32_kshiftlidi(unsigned long long, unsigned char); +unsigned short __builtin_ia32_kshiftrihi(unsigned short, unsigned char); +unsigned __builtin_ia32_kshiftrisi(unsigned, unsigned char); +unsigned long long __builtin_ia32_kshiftridi(unsigned long long, unsigned char); +unsigned char __builtin_ia32_kandqi(unsigned char, unsigned char); +unsigned __builtin_ia32_kandsi(unsigned, unsigned); +unsigned long long __builtin_ia32_kanddi(unsigned long long, unsigned long long); +unsigned char __builtin_ia32_kandnqi(unsigned char, unsigned char); +unsigned __builtin_ia32_kandnsi(unsigned, unsigned); +unsigned long long __builtin_ia32_kandndi(unsigned long long, unsigned long long); +unsigned char __builtin_ia32_knotqi(unsigned char); +unsigned __builtin_ia32_knotsi(unsigned); +unsigned long long __builtin_ia32_knotdi(unsigned long long); +unsigned char __builtin_ia32_korqi(unsigned char, unsigned char); +unsigned __builtin_ia32_korsi(unsigned, unsigned); +unsigned long long __builtin_ia32_kordi(unsigned long long, unsigned long long); +unsigned char __builtin_ia32_ktestcqi(unsigned char, unsigned char); +unsigned char __builtin_ia32_ktestzqi(unsigned char, unsigned char); +unsigned short __builtin_ia32_ktestchi(unsigned short, unsigned short); +unsigned short __builtin_ia32_ktestzhi(unsigned short, unsigned short); +unsigned __builtin_ia32_ktestcsi(unsigned, unsigned); +unsigned __builtin_ia32_ktestzsi(unsigned, unsigned); +unsigned long long __builtin_ia32_ktestcdi(unsigned long long, unsigned long long); +unsigned long long __builtin_ia32_ktestzdi(unsigned long long, unsigned long long); +unsigned char __builtin_ia32_kortestcqi(unsigned char, unsigned char); +unsigned char __builtin_ia32_kortestzqi(unsigned char, unsigned char); +unsigned __builtin_ia32_kortestcsi(unsigned, unsigned); +unsigned __builtin_ia32_kortestzsi(unsigned, unsigned); +unsigned long long __builtin_ia32_kortestcdi(unsigned long long, unsigned long long); +unsigned long long __builtin_ia32_kortestzdi(unsigned long long, unsigned long long); +unsigned char __builtin_ia32_kxnorqi(unsigned char, unsigned char); +unsigned __builtin_ia32_kxnorsi(unsigned, unsigned); +unsigned long long __builtin_ia32_kxnordi(unsigned long long, unsigned long long); +unsigned char __builtin_ia32_kxorqi(unsigned char, unsigned char); +unsigned __builtin_ia32_kxorsi(unsigned, unsigned); +unsigned long long __builtin_ia32_kxordi(unsigned long long, unsigned long long); +unsigned char __builtin_ia32_kmovb(unsigned char); +unsigned short __builtin_ia32_kmovw(unsigned short); +unsigned __builtin_ia32_kmovd(unsigned); +unsigned long long __builtin_ia32_kmovq(unsigned long long); +unsigned char __builtin_ia32_kaddqi(unsigned char, unsigned char); +unsigned short __builtin_ia32_kaddhi(unsigned short, unsigned short); +unsigned __builtin_ia32_kaddsi(unsigned, unsigned); +unsigned long long __builtin_ia32_kadddi(unsigned long long, unsigned long long); +__gcc_v4di __builtin_ia32_movdqa64_256_mask(__gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_movdqa64_128_mask(__gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v8si __builtin_ia32_movdqa32_256_mask(__gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_movdqa32_128_mask(__gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v4df __builtin_ia32_movapd256_mask(__gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_movapd128_mask(__gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_movaps256_mask(__gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_movaps128_mask(__gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v16hi __builtin_ia32_movdquhi256_mask(__gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v8hi __builtin_ia32_movdquhi128_mask(__gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v32qi __builtin_ia32_movdquqi256_mask(__gcc_v32qi, __gcc_v32qi, unsigned); +__gcc_v16qi __builtin_ia32_movdquqi128_mask(__gcc_v16qi, __gcc_v16qi, unsigned short); +__gcc_v4sf __builtin_ia32_minps_mask(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v4sf __builtin_ia32_maxps_mask(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v2df __builtin_ia32_minpd_mask(__gcc_v2df, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v2df __builtin_ia32_maxpd_mask(__gcc_v2df, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v4df __builtin_ia32_maxpd256_mask(__gcc_v4df, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v8sf __builtin_ia32_maxps256_mask(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4df __builtin_ia32_minpd256_mask(__gcc_v4df, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v8sf __builtin_ia32_minps256_mask(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_mulps_mask(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v4sf __builtin_ia32_divps_mask(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v2df __builtin_ia32_mulpd_mask(__gcc_v2df, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v2df __builtin_ia32_divpd_mask(__gcc_v2df, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v4df __builtin_ia32_divpd256_mask(__gcc_v4df, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v8sf __builtin_ia32_divps256_mask(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4df __builtin_ia32_mulpd256_mask(__gcc_v4df, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v8sf __builtin_ia32_mulps256_mask(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v2df __builtin_ia32_addpd128_mask(__gcc_v2df, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v4df __builtin_ia32_addpd256_mask(__gcc_v4df, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v4sf __builtin_ia32_addps128_mask(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v8sf __builtin_ia32_addps256_mask(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v2df __builtin_ia32_subpd128_mask(__gcc_v2df, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v4df __builtin_ia32_subpd256_mask(__gcc_v4df, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v4sf __builtin_ia32_subps128_mask(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v8sf __builtin_ia32_subps256_mask(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4df __builtin_ia32_xorpd256_mask(__gcc_v4df, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_xorpd128_mask(__gcc_v2df, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_xorps256_mask(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_xorps128_mask(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v4df __builtin_ia32_orpd256_mask(__gcc_v4df, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_orpd128_mask(__gcc_v2df, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_orps256_mask(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_orps128_mask(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v8sf __builtin_ia32_broadcastf32x2_256_mask(__gcc_v4sf, __gcc_v8sf, unsigned char); +__gcc_v8si __builtin_ia32_broadcasti32x2_256_mask(__gcc_v4si, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_broadcasti32x2_128_mask(__gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v4df __builtin_ia32_broadcastf64x2_256_mask(__gcc_v2df, __gcc_v4df, unsigned char); +__gcc_v4di __builtin_ia32_broadcasti64x2_256_mask(__gcc_v2di, __gcc_v4di, unsigned char); +__gcc_v8sf __builtin_ia32_broadcastf32x4_256_mask(__gcc_v4sf, __gcc_v8sf, unsigned char); +__gcc_v8si __builtin_ia32_broadcasti32x4_256_mask(__gcc_v4si, __gcc_v8si, unsigned char); +__gcc_v4sf __builtin_ia32_extractf32x4_256_mask(__gcc_v8sf, int, __gcc_v4sf, unsigned char); +__gcc_v4si __builtin_ia32_extracti32x4_256_mask(__gcc_v8si, int, __gcc_v4si, unsigned char); +__gcc_v16hi __builtin_ia32_dbpsadbw256_mask(__gcc_v32qi, __gcc_v32qi, int, __gcc_v16hi, unsigned short); +__gcc_v8hi __builtin_ia32_dbpsadbw128_mask(__gcc_v16qi, __gcc_v16qi, int, __gcc_v8hi, unsigned char); +__gcc_v4di __builtin_ia32_cvttpd2qq256_mask(__gcc_v4df, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_cvttpd2qq128_mask(__gcc_v2df, __gcc_v2di, unsigned char); +__gcc_v4di __builtin_ia32_cvttpd2uqq256_mask(__gcc_v4df, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_cvttpd2uqq128_mask(__gcc_v2df, __gcc_v2di, unsigned char); +__gcc_v4di __builtin_ia32_cvtpd2qq256_mask(__gcc_v4df, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_cvtpd2qq128_mask(__gcc_v2df, __gcc_v2di, unsigned char); +__gcc_v4di __builtin_ia32_cvtpd2uqq256_mask(__gcc_v4df, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_cvtpd2uqq128_mask(__gcc_v2df, __gcc_v2di, unsigned char); +__gcc_v4si __builtin_ia32_cvtpd2udq256_mask(__gcc_v4df, __gcc_v4si, unsigned char); +__gcc_v4si __builtin_ia32_cvtpd2udq128_mask(__gcc_v2df, __gcc_v4si, unsigned char); +__gcc_v4di __builtin_ia32_cvttps2qq256_mask(__gcc_v4sf, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_cvttps2qq128_mask(__gcc_v4sf, __gcc_v2di, unsigned char); +__gcc_v4di __builtin_ia32_cvttps2uqq256_mask(__gcc_v4sf, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_cvttps2uqq128_mask(__gcc_v4sf, __gcc_v2di, unsigned char); +__gcc_v8si __builtin_ia32_cvttps2dq256_mask(__gcc_v8sf, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_cvttps2dq128_mask(__gcc_v4sf, __gcc_v4si, unsigned char); +__gcc_v8si __builtin_ia32_cvttps2udq256_mask(__gcc_v8sf, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_cvttps2udq128_mask(__gcc_v4sf, __gcc_v4si, unsigned char); +__gcc_v4si __builtin_ia32_cvttpd2dq256_mask(__gcc_v4df, __gcc_v4si, unsigned char); +__gcc_v4si __builtin_ia32_cvttpd2dq128_mask(__gcc_v2df, __gcc_v4si, unsigned char); +__gcc_v4si __builtin_ia32_cvttpd2udq256_mask(__gcc_v4df, __gcc_v4si, unsigned char); +__gcc_v4si __builtin_ia32_cvttpd2udq128_mask(__gcc_v2df, __gcc_v4si, unsigned char); +__gcc_v4si __builtin_ia32_cvtpd2dq256_mask(__gcc_v4df, __gcc_v4si, unsigned char); +__gcc_v4si __builtin_ia32_cvtpd2dq128_mask(__gcc_v2df, __gcc_v4si, unsigned char); +__gcc_v4df __builtin_ia32_cvtdq2pd256_mask(__gcc_v4si, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_cvtdq2pd128_mask(__gcc_v4si, __gcc_v2df, unsigned char); +__gcc_v4df __builtin_ia32_cvtudq2pd256_mask(__gcc_v4si, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_cvtudq2pd128_mask(__gcc_v4si, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_cvtdq2ps256_mask(__gcc_v8si, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_cvtdq2ps128_mask(__gcc_v4si, __gcc_v4sf, unsigned char); +__gcc_v8sf __builtin_ia32_cvtudq2ps256_mask(__gcc_v8si, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_cvtudq2ps128_mask(__gcc_v4si, __gcc_v4sf, unsigned char); +__gcc_v4df __builtin_ia32_cvtps2pd256_mask(__gcc_v4sf, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_cvtps2pd128_mask(__gcc_v4sf, __gcc_v2df, unsigned char); +__gcc_v32qi __builtin_ia32_pbroadcastb256_mask(__gcc_v16qi, __gcc_v32qi, unsigned); +__gcc_v32qi __builtin_ia32_pbroadcastb256_gpr_mask(char, __gcc_v32qi, unsigned); +__gcc_v16qi __builtin_ia32_pbroadcastb128_mask(__gcc_v16qi, __gcc_v16qi, unsigned short); +__gcc_v16qi __builtin_ia32_pbroadcastb128_gpr_mask(char, __gcc_v16qi, unsigned short); +__gcc_v16hi __builtin_ia32_pbroadcastw256_mask(__gcc_v8hi, __gcc_v16hi, unsigned short); +__gcc_v16hi __builtin_ia32_pbroadcastw256_gpr_mask(short, __gcc_v16hi, unsigned short); +__gcc_v8hi __builtin_ia32_pbroadcastw128_mask(__gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v8hi __builtin_ia32_pbroadcastw128_gpr_mask(short, __gcc_v8hi, unsigned char); +__gcc_v8si __builtin_ia32_pbroadcastd256_mask(__gcc_v4si, __gcc_v8si, unsigned char); +__gcc_v8si __builtin_ia32_pbroadcastd256_gpr_mask(int, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_pbroadcastd128_mask(__gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v4si __builtin_ia32_pbroadcastd128_gpr_mask(int, __gcc_v4si, unsigned char); +__gcc_v4di __builtin_ia32_pbroadcastq256_mask(__gcc_v2di, __gcc_v4di, unsigned char); +__gcc_v4di __builtin_ia32_pbroadcastq256_gpr_mask(long long, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_pbroadcastq128_mask(__gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v2di __builtin_ia32_pbroadcastq128_gpr_mask(long long, __gcc_v2di, unsigned char); +__gcc_v8sf __builtin_ia32_broadcastss256_mask(__gcc_v4sf, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_broadcastss128_mask(__gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v4df __builtin_ia32_broadcastsd256_mask(__gcc_v2df, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_extractf64x2_256_mask(__gcc_v4df, int, __gcc_v2df, unsigned char); +__gcc_v2di __builtin_ia32_extracti64x2_256_mask(__gcc_v4di, int, __gcc_v2di, unsigned char); +__gcc_v8sf __builtin_ia32_insertf32x4_256_mask(__gcc_v8sf, __gcc_v4sf, int, __gcc_v8sf, unsigned char); +__gcc_v8si __builtin_ia32_inserti32x4_256_mask(__gcc_v8si, __gcc_v4si, int, __gcc_v8si, unsigned char); +__gcc_v16hi __builtin_ia32_pmovsxbw256_mask(__gcc_v16qi, __gcc_v16hi, unsigned short); +__gcc_v8hi __builtin_ia32_pmovsxbw128_mask(__gcc_v16qi, __gcc_v8hi, unsigned char); +__gcc_v8si __builtin_ia32_pmovsxbd256_mask(__gcc_v16qi, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_pmovsxbd128_mask(__gcc_v16qi, __gcc_v4si, unsigned char); +__gcc_v4di __builtin_ia32_pmovsxbq256_mask(__gcc_v16qi, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_pmovsxbq128_mask(__gcc_v16qi, __gcc_v2di, unsigned char); +__gcc_v8si __builtin_ia32_pmovsxwd256_mask(__gcc_v8hi, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_pmovsxwd128_mask(__gcc_v8hi, __gcc_v4si, unsigned char); +__gcc_v4di __builtin_ia32_pmovsxwq256_mask(__gcc_v8hi, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_pmovsxwq128_mask(__gcc_v8hi, __gcc_v2di, unsigned char); +__gcc_v4di __builtin_ia32_pmovsxdq256_mask(__gcc_v4si, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_pmovsxdq128_mask(__gcc_v4si, __gcc_v2di, unsigned char); +__gcc_v16hi __builtin_ia32_pmovzxbw256_mask(__gcc_v16qi, __gcc_v16hi, unsigned short); +__gcc_v8hi __builtin_ia32_pmovzxbw128_mask(__gcc_v16qi, __gcc_v8hi, unsigned char); +__gcc_v8si __builtin_ia32_pmovzxbd256_mask(__gcc_v16qi, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_pmovzxbd128_mask(__gcc_v16qi, __gcc_v4si, unsigned char); +__gcc_v4di __builtin_ia32_pmovzxbq256_mask(__gcc_v16qi, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_pmovzxbq128_mask(__gcc_v16qi, __gcc_v2di, unsigned char); +__gcc_v8si __builtin_ia32_pmovzxwd256_mask(__gcc_v8hi, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_pmovzxwd128_mask(__gcc_v8hi, __gcc_v4si, unsigned char); +__gcc_v4di __builtin_ia32_pmovzxwq256_mask(__gcc_v8hi, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_pmovzxwq128_mask(__gcc_v8hi, __gcc_v2di, unsigned char); +__gcc_v4di __builtin_ia32_pmovzxdq256_mask(__gcc_v4si, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_pmovzxdq128_mask(__gcc_v4si, __gcc_v2di, unsigned char); +__gcc_v4df __builtin_ia32_reducepd256_mask(__gcc_v4df, int, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_reducepd128_mask(__gcc_v2df, int, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_reduceps256_mask(__gcc_v8sf, int, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_reduceps128_mask(__gcc_v4sf, int, __gcc_v4sf, unsigned char); +__gcc_v2df __builtin_ia32_reducesd(__gcc_v2df, __gcc_v2df, int); +__gcc_v4sf __builtin_ia32_reducess(__gcc_v4sf, __gcc_v4sf, int); +__gcc_v16hi __builtin_ia32_permvarhi256_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v8hi __builtin_ia32_permvarhi128_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v16hi __builtin_ia32_vpermt2varhi256_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v16hi __builtin_ia32_vpermt2varhi256_maskz(__gcc_v16hi, __gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v8hi __builtin_ia32_vpermt2varhi128_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v8hi __builtin_ia32_vpermt2varhi128_maskz(__gcc_v8hi, __gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v16hi __builtin_ia32_vpermi2varhi256_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v8hi __builtin_ia32_vpermi2varhi128_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v4df __builtin_ia32_rcp14pd256_mask(__gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_rcp14pd128_mask(__gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_rcp14ps256_mask(__gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_rcp14ps128_mask(__gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v4df __builtin_ia32_rsqrt14pd256_mask(__gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_rsqrt14pd128_mask(__gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_rsqrt14ps256_mask(__gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_rsqrt14ps128_mask(__gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v4df __builtin_ia32_sqrtpd256_mask(__gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_sqrtpd128_mask(__gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_sqrtps256_mask(__gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_sqrtps128_mask(__gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v16qi __builtin_ia32_paddb128_mask(__gcc_v16qi, __gcc_v16qi, __gcc_v16qi, unsigned short); +__gcc_v8hi __builtin_ia32_paddw128_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v4si __builtin_ia32_paddd128_mask(__gcc_v4si, __gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v2di __builtin_ia32_paddq128_mask(__gcc_v2di, __gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v16qi __builtin_ia32_psubb128_mask(__gcc_v16qi, __gcc_v16qi, __gcc_v16qi, unsigned short); +__gcc_v8hi __builtin_ia32_psubw128_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v4si __builtin_ia32_psubd128_mask(__gcc_v4si, __gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v2di __builtin_ia32_psubq128_mask(__gcc_v2di, __gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v16qi __builtin_ia32_paddsb128_mask(__gcc_v16qi, __gcc_v16qi, __gcc_v16qi, unsigned short); +__gcc_v8hi __builtin_ia32_paddsw128_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v16qi __builtin_ia32_psubsb128_mask(__gcc_v16qi, __gcc_v16qi, __gcc_v16qi, unsigned short); +__gcc_v8hi __builtin_ia32_psubsw128_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v16qi __builtin_ia32_paddusb128_mask(__gcc_v16qi, __gcc_v16qi, __gcc_v16qi, unsigned short); +__gcc_v8hi __builtin_ia32_paddusw128_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v16qi __builtin_ia32_psubusb128_mask(__gcc_v16qi, __gcc_v16qi, __gcc_v16qi, unsigned short); +__gcc_v8hi __builtin_ia32_psubusw128_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v32qi __builtin_ia32_paddb256_mask(__gcc_v32qi, __gcc_v32qi, __gcc_v32qi, unsigned); +__gcc_v16hi __builtin_ia32_paddw256_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v8si __builtin_ia32_paddd256_mask(__gcc_v8si, __gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v4di __builtin_ia32_paddq256_mask(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v32qi __builtin_ia32_paddsb256_mask(__gcc_v32qi, __gcc_v32qi, __gcc_v32qi, unsigned); +__gcc_v16hi __builtin_ia32_paddsw256_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v32qi __builtin_ia32_paddusb256_mask(__gcc_v32qi, __gcc_v32qi, __gcc_v32qi, unsigned); +__gcc_v16hi __builtin_ia32_paddusw256_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v32qi __builtin_ia32_psubb256_mask(__gcc_v32qi, __gcc_v32qi, __gcc_v32qi, unsigned); +__gcc_v16hi __builtin_ia32_psubw256_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v8si __builtin_ia32_psubd256_mask(__gcc_v8si, __gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v4di __builtin_ia32_psubq256_mask(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v32qi __builtin_ia32_psubsb256_mask(__gcc_v32qi, __gcc_v32qi, __gcc_v32qi, unsigned); +__gcc_v16hi __builtin_ia32_psubsw256_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v32qi __builtin_ia32_psubusb256_mask(__gcc_v32qi, __gcc_v32qi, __gcc_v32qi, unsigned); +__gcc_v16hi __builtin_ia32_psubusw256_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v4df __builtin_ia32_shuf_f64x2_256_mask(__gcc_v4df, __gcc_v4df, int, __gcc_v4df, unsigned char); +__gcc_v4di __builtin_ia32_shuf_i64x2_256_mask(__gcc_v4di, __gcc_v4di, int, __gcc_v4di, unsigned char); +__gcc_v8si __builtin_ia32_shuf_i32x4_256_mask(__gcc_v8si, __gcc_v8si, int, __gcc_v8si, unsigned char); +__gcc_v8sf __builtin_ia32_shuf_f32x4_256_mask(__gcc_v8sf, __gcc_v8sf, int, __gcc_v8sf, unsigned char); +__gcc_v16qi __builtin_ia32_pmovwb128_mask(__gcc_v8hi, __gcc_v16qi, unsigned char); +__gcc_v16qi __builtin_ia32_pmovwb256_mask(__gcc_v16hi, __gcc_v16qi, unsigned short); +__gcc_v16qi __builtin_ia32_pmovswb128_mask(__gcc_v8hi, __gcc_v16qi, unsigned char); +__gcc_v16qi __builtin_ia32_pmovswb256_mask(__gcc_v16hi, __gcc_v16qi, unsigned short); +__gcc_v16qi __builtin_ia32_pmovuswb128_mask(__gcc_v8hi, __gcc_v16qi, unsigned char); +__gcc_v16qi __builtin_ia32_pmovuswb256_mask(__gcc_v16hi, __gcc_v16qi, unsigned short); +__gcc_v16qi __builtin_ia32_pmovdb128_mask(__gcc_v4si, __gcc_v16qi, unsigned char); +__gcc_v16qi __builtin_ia32_pmovdb256_mask(__gcc_v8si, __gcc_v16qi, unsigned char); +__gcc_v16qi __builtin_ia32_pmovsdb128_mask(__gcc_v4si, __gcc_v16qi, unsigned char); +__gcc_v16qi __builtin_ia32_pmovsdb256_mask(__gcc_v8si, __gcc_v16qi, unsigned char); +__gcc_v16qi __builtin_ia32_pmovusdb128_mask(__gcc_v4si, __gcc_v16qi, unsigned char); +__gcc_v16qi __builtin_ia32_pmovusdb256_mask(__gcc_v8si, __gcc_v16qi, unsigned char); +__gcc_v8hi __builtin_ia32_pmovdw128_mask(__gcc_v4si, __gcc_v8hi, unsigned char); +__gcc_v8hi __builtin_ia32_pmovdw256_mask(__gcc_v8si, __gcc_v8hi, unsigned char); +__gcc_v8hi __builtin_ia32_pmovsdw128_mask(__gcc_v4si, __gcc_v8hi, unsigned char); +__gcc_v8hi __builtin_ia32_pmovsdw256_mask(__gcc_v8si, __gcc_v8hi, unsigned char); +__gcc_v8hi __builtin_ia32_pmovusdw128_mask(__gcc_v4si, __gcc_v8hi, unsigned char); +__gcc_v8hi __builtin_ia32_pmovusdw256_mask(__gcc_v8si, __gcc_v8hi, unsigned char); +__gcc_v16qi __builtin_ia32_pmovqb128_mask(__gcc_v2di, __gcc_v16qi, unsigned char); +__gcc_v16qi __builtin_ia32_pmovqb256_mask(__gcc_v4di, __gcc_v16qi, unsigned char); +__gcc_v16qi __builtin_ia32_pmovsqb128_mask(__gcc_v2di, __gcc_v16qi, unsigned char); +__gcc_v16qi __builtin_ia32_pmovsqb256_mask(__gcc_v4di, __gcc_v16qi, unsigned char); +__gcc_v16qi __builtin_ia32_pmovusqb128_mask(__gcc_v2di, __gcc_v16qi, unsigned char); +__gcc_v16qi __builtin_ia32_pmovusqb256_mask(__gcc_v4di, __gcc_v16qi, unsigned char); +__gcc_v8hi __builtin_ia32_pmovqw128_mask(__gcc_v2di, __gcc_v8hi, unsigned char); +__gcc_v8hi __builtin_ia32_pmovqw256_mask(__gcc_v4di, __gcc_v8hi, unsigned char); +__gcc_v8hi __builtin_ia32_pmovsqw128_mask(__gcc_v2di, __gcc_v8hi, unsigned char); +__gcc_v8hi __builtin_ia32_pmovsqw256_mask(__gcc_v4di, __gcc_v8hi, unsigned char); +__gcc_v8hi __builtin_ia32_pmovusqw128_mask(__gcc_v2di, __gcc_v8hi, unsigned char); +__gcc_v8hi __builtin_ia32_pmovusqw256_mask(__gcc_v4di, __gcc_v8hi, unsigned char); +__gcc_v4si __builtin_ia32_pmovqd128_mask(__gcc_v2di, __gcc_v4si, unsigned char); +__gcc_v4si __builtin_ia32_pmovqd256_mask(__gcc_v4di, __gcc_v4si, unsigned char); +__gcc_v4si __builtin_ia32_pmovsqd128_mask(__gcc_v2di, __gcc_v4si, unsigned char); +__gcc_v4si __builtin_ia32_pmovsqd256_mask(__gcc_v4di, __gcc_v4si, unsigned char); +__gcc_v4si __builtin_ia32_pmovusqd128_mask(__gcc_v2di, __gcc_v4si, unsigned char); +__gcc_v4si __builtin_ia32_pmovusqd256_mask(__gcc_v4di, __gcc_v4si, unsigned char); +__gcc_v4df __builtin_ia32_rangepd256_mask(__gcc_v4df, __gcc_v4df, int, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_rangepd128_mask(__gcc_v2df, __gcc_v2df, int, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_rangeps256_mask(__gcc_v8sf, __gcc_v8sf, int, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_rangeps128_mask(__gcc_v4sf, __gcc_v4sf, int, __gcc_v4sf, unsigned char); +__gcc_v8sf __builtin_ia32_getexpps256_mask(__gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4df __builtin_ia32_getexppd256_mask(__gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v4sf __builtin_ia32_getexpps128_mask(__gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v2df __builtin_ia32_getexppd128_mask(__gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v4df __builtin_ia32_fixupimmpd256_mask(__gcc_v4df, __gcc_v4df, __gcc_v4di, int, unsigned char); +__gcc_v4df __builtin_ia32_fixupimmpd256_maskz(__gcc_v4df, __gcc_v4df, __gcc_v4di, int, unsigned char); +__gcc_v8sf __builtin_ia32_fixupimmps256_mask(__gcc_v8sf, __gcc_v8sf, __gcc_v8si, int, unsigned char); +__gcc_v8sf __builtin_ia32_fixupimmps256_maskz(__gcc_v8sf, __gcc_v8sf, __gcc_v8si, int, unsigned char); +__gcc_v2df __builtin_ia32_fixupimmpd128_mask(__gcc_v2df, __gcc_v2df, __gcc_v2di, int, unsigned char); +__gcc_v2df __builtin_ia32_fixupimmpd128_maskz(__gcc_v2df, __gcc_v2df, __gcc_v2di, int, unsigned char); +__gcc_v4sf __builtin_ia32_fixupimmps128_mask(__gcc_v4sf, __gcc_v4sf, __gcc_v4si, int, unsigned char); +__gcc_v4sf __builtin_ia32_fixupimmps128_maskz(__gcc_v4sf, __gcc_v4sf, __gcc_v4si, int, unsigned char); +__gcc_v4di __builtin_ia32_pabsq256_mask(__gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_pabsq128_mask(__gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v8si __builtin_ia32_pabsd256_mask(__gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_pabsd128_mask(__gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v16hi __builtin_ia32_pmulhrsw256_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v8hi __builtin_ia32_pmulhrsw128_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v8hi __builtin_ia32_pmulhuw128_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v16hi __builtin_ia32_pmulhuw256_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v16hi __builtin_ia32_pmulhw256_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v8hi __builtin_ia32_pmulhw128_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v16hi __builtin_ia32_pmullw256_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v8hi __builtin_ia32_pmullw128_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v4di __builtin_ia32_pmullq256_mask(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_pmullq128_mask(__gcc_v2di, __gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v4df __builtin_ia32_andpd256_mask(__gcc_v4df, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_andpd128_mask(__gcc_v2df, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_andps256_mask(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_andps128_mask(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v4df __builtin_ia32_andnpd256_mask(__gcc_v4df, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_andnpd128_mask(__gcc_v2df, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_andnps256_mask(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_andnps128_mask(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v8si __builtin_ia32_pandd256_mask(__gcc_v8si, __gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_pandd128_mask(__gcc_v4si, __gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v4di __builtin_ia32_pandq256_mask(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_pandq128_mask(__gcc_v2di, __gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v8si __builtin_ia32_pandnd256_mask(__gcc_v8si, __gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_pandnd128_mask(__gcc_v4si, __gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v4di __builtin_ia32_pandnq256_mask(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_pandnq128_mask(__gcc_v2di, __gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v8si __builtin_ia32_pord256_mask(__gcc_v8si, __gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_pord128_mask(__gcc_v4si, __gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v4di __builtin_ia32_porq256_mask(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_porq128_mask(__gcc_v2di, __gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v8si __builtin_ia32_pxord256_mask(__gcc_v8si, __gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_pxord128_mask(__gcc_v4si, __gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v4di __builtin_ia32_pxorq256_mask(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_pxorq128_mask(__gcc_v2di, __gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v32qi __builtin_ia32_packsswb256_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v32qi, unsigned); +__gcc_v16qi __builtin_ia32_packsswb128_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v16qi, unsigned short); +__gcc_v32qi __builtin_ia32_packuswb256_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v32qi, unsigned); +__gcc_v16qi __builtin_ia32_packuswb128_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v16qi, unsigned short); +__gcc_v8sf __builtin_ia32_rndscaleps_256_mask(__gcc_v8sf, int, __gcc_v8sf, unsigned char); +__gcc_v4df __builtin_ia32_rndscalepd_256_mask(__gcc_v4df, int, __gcc_v4df, unsigned char); +__gcc_v4sf __builtin_ia32_rndscaleps_128_mask(__gcc_v4sf, int, __gcc_v4sf, unsigned char); +__gcc_v2df __builtin_ia32_rndscalepd_128_mask(__gcc_v2df, int, __gcc_v2df, unsigned char); +__gcc_v4di __builtin_ia32_pternlogq256_mask(__gcc_v4di, __gcc_v4di, __gcc_v4di, int, unsigned char); +__gcc_v4di __builtin_ia32_pternlogq256_maskz(__gcc_v4di, __gcc_v4di, __gcc_v4di, int, unsigned char); +__gcc_v8si __builtin_ia32_pternlogd256_mask(__gcc_v8si, __gcc_v8si, __gcc_v8si, int, unsigned char); +__gcc_v8si __builtin_ia32_pternlogd256_maskz(__gcc_v8si, __gcc_v8si, __gcc_v8si, int, unsigned char); +__gcc_v2di __builtin_ia32_pternlogq128_mask(__gcc_v2di, __gcc_v2di, __gcc_v2di, int, unsigned char); +__gcc_v2di __builtin_ia32_pternlogq128_maskz(__gcc_v2di, __gcc_v2di, __gcc_v2di, int, unsigned char); +__gcc_v4si __builtin_ia32_pternlogd128_mask(__gcc_v4si, __gcc_v4si, __gcc_v4si, int, unsigned char); +__gcc_v4si __builtin_ia32_pternlogd128_maskz(__gcc_v4si, __gcc_v4si, __gcc_v4si, int, unsigned char); +__gcc_v4df __builtin_ia32_scalefpd256_mask(__gcc_v4df, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v8sf __builtin_ia32_scalefps256_mask(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v2df __builtin_ia32_scalefpd128_mask(__gcc_v2df, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v4sf __builtin_ia32_scalefps128_mask(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v4df __builtin_ia32_vfmaddpd256_mask(__gcc_v4df, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v4df __builtin_ia32_vfmaddpd256_mask3(__gcc_v4df, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v4df __builtin_ia32_vfmaddpd256_maskz(__gcc_v4df, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_vfmaddpd128_mask(__gcc_v2df, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v2df __builtin_ia32_vfmaddpd128_mask3(__gcc_v2df, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v2df __builtin_ia32_vfmaddpd128_maskz(__gcc_v2df, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_vfmaddps256_mask(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v8sf __builtin_ia32_vfmaddps256_mask3(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v8sf __builtin_ia32_vfmaddps256_maskz(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_vfmaddps128_mask(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v4sf __builtin_ia32_vfmaddps128_mask3(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v4sf __builtin_ia32_vfmaddps128_maskz(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v4df __builtin_ia32_vfmsubpd256_mask3(__gcc_v4df, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_vfmsubpd128_mask3(__gcc_v2df, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_vfmsubps256_mask3(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_vfmsubps128_mask3(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v4df __builtin_ia32_vfnmaddpd256_mask(__gcc_v4df, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_vfnmaddpd128_mask(__gcc_v2df, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_vfnmaddps256_mask(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_vfnmaddps128_mask(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v4df __builtin_ia32_vfnmsubpd256_mask(__gcc_v4df, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v4df __builtin_ia32_vfnmsubpd256_mask3(__gcc_v4df, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_vfnmsubpd128_mask(__gcc_v2df, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v2df __builtin_ia32_vfnmsubpd128_mask3(__gcc_v2df, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_vfnmsubps256_mask(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v8sf __builtin_ia32_vfnmsubps256_mask3(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_vfnmsubps128_mask(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v4sf __builtin_ia32_vfnmsubps128_mask3(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v4df __builtin_ia32_vfmaddsubpd256_mask(__gcc_v4df, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v4df __builtin_ia32_vfmaddsubpd256_mask3(__gcc_v4df, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v4df __builtin_ia32_vfmaddsubpd256_maskz(__gcc_v4df, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_vfmaddsubpd128_mask(__gcc_v2df, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v2df __builtin_ia32_vfmaddsubpd128_mask3(__gcc_v2df, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v2df __builtin_ia32_vfmaddsubpd128_maskz(__gcc_v2df, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_vfmaddsubps256_mask(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v8sf __builtin_ia32_vfmaddsubps256_mask3(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v8sf __builtin_ia32_vfmaddsubps256_maskz(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_vfmaddsubps128_mask(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v4sf __builtin_ia32_vfmaddsubps128_mask3(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v4sf __builtin_ia32_vfmaddsubps128_maskz(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v4df __builtin_ia32_vfmsubaddpd256_mask3(__gcc_v4df, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_vfmsubaddpd128_mask3(__gcc_v2df, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_vfmsubaddps256_mask3(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_vfmsubaddps128_mask3(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v4df __builtin_ia32_insertf64x2_256_mask(__gcc_v4df, __gcc_v2df, int, __gcc_v4df, unsigned char); +__gcc_v4di __builtin_ia32_inserti64x2_256_mask(__gcc_v4di, __gcc_v2di, int, __gcc_v4di, unsigned char); +__gcc_v16hi __builtin_ia32_psrav16hi_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v8hi __builtin_ia32_psrav8hi_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v16hi __builtin_ia32_pmaddubsw256_mask(__gcc_v32qi, __gcc_v32qi, __gcc_v16hi, unsigned short); +__gcc_v8hi __builtin_ia32_pmaddubsw128_mask(__gcc_v16qi, __gcc_v16qi, __gcc_v8hi, unsigned char); +__gcc_v8si __builtin_ia32_pmaddwd256_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_pmaddwd128_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v4si, unsigned char); +__gcc_v16hi __builtin_ia32_psrlv16hi_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v8hi __builtin_ia32_psrlv8hi_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v8si __builtin_ia32_cvtps2dq256_mask(__gcc_v8sf, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_cvtps2dq128_mask(__gcc_v4sf, __gcc_v4si, unsigned char); +__gcc_v8si __builtin_ia32_cvtps2udq256_mask(__gcc_v8sf, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_cvtps2udq128_mask(__gcc_v4sf, __gcc_v4si, unsigned char); +__gcc_v4di __builtin_ia32_cvtps2qq256_mask(__gcc_v4sf, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_cvtps2qq128_mask(__gcc_v4sf, __gcc_v2di, unsigned char); +__gcc_v4di __builtin_ia32_cvtps2uqq256_mask(__gcc_v4sf, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_cvtps2uqq128_mask(__gcc_v4sf, __gcc_v2di, unsigned char); +__gcc_v8sf __builtin_ia32_getmantps256_mask(__gcc_v8sf, int, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_getmantps128_mask(__gcc_v4sf, int, __gcc_v4sf, unsigned char); +__gcc_v4df __builtin_ia32_getmantpd256_mask(__gcc_v4df, int, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_getmantpd128_mask(__gcc_v2df, int, __gcc_v2df, unsigned char); +__gcc_v4df __builtin_ia32_movddup256_mask(__gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_movddup128_mask(__gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_movshdup256_mask(__gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_movshdup128_mask(__gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v8sf __builtin_ia32_movsldup256_mask(__gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_movsldup128_mask(__gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v4sf __builtin_ia32_cvtqq2ps256_mask(__gcc_v4di, __gcc_v4sf, unsigned char); +__gcc_v4sf __builtin_ia32_cvtqq2ps128_mask(__gcc_v2di, __gcc_v4sf, unsigned char); +__gcc_v4sf __builtin_ia32_cvtuqq2ps256_mask(__gcc_v4di, __gcc_v4sf, unsigned char); +__gcc_v4sf __builtin_ia32_cvtuqq2ps128_mask(__gcc_v2di, __gcc_v4sf, unsigned char); +__gcc_v4df __builtin_ia32_cvtqq2pd256_mask(__gcc_v4di, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_cvtqq2pd128_mask(__gcc_v2di, __gcc_v2df, unsigned char); +__gcc_v4df __builtin_ia32_cvtuqq2pd256_mask(__gcc_v4di, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_cvtuqq2pd128_mask(__gcc_v2di, __gcc_v2df, unsigned char); +__gcc_v4di __builtin_ia32_vpermt2varq256_mask(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v4di __builtin_ia32_vpermt2varq256_maskz(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v8si __builtin_ia32_vpermt2vard256_mask(__gcc_v8si, __gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v8si __builtin_ia32_vpermt2vard256_maskz(__gcc_v8si, __gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v4di __builtin_ia32_vpermi2varq256_mask(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v8si __builtin_ia32_vpermi2vard256_mask(__gcc_v8si, __gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v4df __builtin_ia32_vpermt2varpd256_mask(__gcc_v4di, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v4df __builtin_ia32_vpermt2varpd256_maskz(__gcc_v4di, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v8sf __builtin_ia32_vpermt2varps256_mask(__gcc_v8si, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v8sf __builtin_ia32_vpermt2varps256_maskz(__gcc_v8si, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4df __builtin_ia32_vpermi2varpd256_mask(__gcc_v4df, __gcc_v4di, __gcc_v4df, unsigned char); +__gcc_v8sf __builtin_ia32_vpermi2varps256_mask(__gcc_v8sf, __gcc_v8si, __gcc_v8sf, unsigned char); +__gcc_v2di __builtin_ia32_vpermt2varq128_mask(__gcc_v2di, __gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v2di __builtin_ia32_vpermt2varq128_maskz(__gcc_v2di, __gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v4si __builtin_ia32_vpermt2vard128_mask(__gcc_v4si, __gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v4si __builtin_ia32_vpermt2vard128_maskz(__gcc_v4si, __gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v2di __builtin_ia32_vpermi2varq128_mask(__gcc_v2di, __gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v4si __builtin_ia32_vpermi2vard128_mask(__gcc_v4si, __gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v2df __builtin_ia32_vpermt2varpd128_mask(__gcc_v2di, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v2df __builtin_ia32_vpermt2varpd128_maskz(__gcc_v2di, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v4sf __builtin_ia32_vpermt2varps128_mask(__gcc_v4si, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v4sf __builtin_ia32_vpermt2varps128_maskz(__gcc_v4si, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v2df __builtin_ia32_vpermi2varpd128_mask(__gcc_v2df, __gcc_v2di, __gcc_v2df, unsigned char); +__gcc_v4sf __builtin_ia32_vpermi2varps128_mask(__gcc_v4sf, __gcc_v4si, __gcc_v4sf, unsigned char); +__gcc_v32qi __builtin_ia32_pshufb256_mask(__gcc_v32qi, __gcc_v32qi, __gcc_v32qi, unsigned); +__gcc_v16qi __builtin_ia32_pshufb128_mask(__gcc_v16qi, __gcc_v16qi, __gcc_v16qi, unsigned short); +__gcc_v16hi __builtin_ia32_pshufhw256_mask(__gcc_v16hi, int, __gcc_v16hi, unsigned short); +__gcc_v8hi __builtin_ia32_pshufhw128_mask(__gcc_v8hi, int, __gcc_v8hi, unsigned char); +__gcc_v16hi __builtin_ia32_pshuflw256_mask(__gcc_v16hi, int, __gcc_v16hi, unsigned short); +__gcc_v8hi __builtin_ia32_pshuflw128_mask(__gcc_v8hi, int, __gcc_v8hi, unsigned char); +__gcc_v8si __builtin_ia32_pshufd256_mask(__gcc_v8si, int, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_pshufd128_mask(__gcc_v4si, int, __gcc_v4si, unsigned char); +__gcc_v4df __builtin_ia32_shufpd256_mask(__gcc_v4df, __gcc_v4df, int, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_shufpd128_mask(__gcc_v2df, __gcc_v2df, int, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_shufps256_mask(__gcc_v8sf, __gcc_v8sf, int, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_shufps128_mask(__gcc_v4sf, __gcc_v4sf, int, __gcc_v4sf, unsigned char); +__gcc_v4di __builtin_ia32_prolvq256_mask(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_prolvq128_mask(__gcc_v2di, __gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v4di __builtin_ia32_prolq256_mask(__gcc_v4di, int, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_prolq128_mask(__gcc_v2di, int, __gcc_v2di, unsigned char); +__gcc_v4di __builtin_ia32_prorvq256_mask(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_prorvq128_mask(__gcc_v2di, __gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v4di __builtin_ia32_prorq256_mask(__gcc_v4di, int, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_prorq128_mask(__gcc_v2di, int, __gcc_v2di, unsigned char); +__gcc_v2di __builtin_ia32_psravq128_mask(__gcc_v2di, __gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v4di __builtin_ia32_psravq256_mask(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v4di __builtin_ia32_psllv4di_mask(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_psllv2di_mask(__gcc_v2di, __gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v8si __builtin_ia32_psllv8si_mask(__gcc_v8si, __gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_psllv4si_mask(__gcc_v4si, __gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v8si __builtin_ia32_psrav8si_mask(__gcc_v8si, __gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_psrav4si_mask(__gcc_v4si, __gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v4di __builtin_ia32_psrlv4di_mask(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_psrlv2di_mask(__gcc_v2di, __gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v8si __builtin_ia32_psrlv8si_mask(__gcc_v8si, __gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_psrlv4si_mask(__gcc_v4si, __gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v8si __builtin_ia32_prorvd256_mask(__gcc_v8si, __gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v8si __builtin_ia32_prolvd256_mask(__gcc_v8si, __gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v8si __builtin_ia32_prord256_mask(__gcc_v8si, int, __gcc_v8si, unsigned char); +__gcc_v8si __builtin_ia32_prold256_mask(__gcc_v8si, int, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_prorvd128_mask(__gcc_v4si, __gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v4si __builtin_ia32_prolvd128_mask(__gcc_v4si, __gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v4si __builtin_ia32_prord128_mask(__gcc_v4si, int, __gcc_v4si, unsigned char); +__gcc_v4si __builtin_ia32_prold128_mask(__gcc_v4si, int, __gcc_v4si, unsigned char); +char __builtin_ia32_fpclasspd256_mask(__gcc_v4df, int, unsigned char); +char __builtin_ia32_fpclasspd128_mask(__gcc_v2df, int, unsigned char); +char __builtin_ia32_fpclasssd(__gcc_v2df, int); +char __builtin_ia32_fpclassps256_mask(__gcc_v8sf, int, unsigned char); +char __builtin_ia32_fpclassps128_mask(__gcc_v4sf, int, unsigned char); +char __builtin_ia32_fpclassss(__gcc_v4sf, int); +unsigned short __builtin_ia32_cvtb2mask128(__gcc_v16qi); +unsigned __builtin_ia32_cvtb2mask256(__gcc_v32qi); +unsigned char __builtin_ia32_cvtw2mask128(__gcc_v8hi); +unsigned short __builtin_ia32_cvtw2mask256(__gcc_v16hi); +unsigned char __builtin_ia32_cvtd2mask128(__gcc_v4si); +unsigned char __builtin_ia32_cvtd2mask256(__gcc_v8si); +unsigned char __builtin_ia32_cvtq2mask128(__gcc_v2di); +unsigned char __builtin_ia32_cvtq2mask256(__gcc_v4di); +__gcc_v16qi __builtin_ia32_cvtmask2b128(unsigned short); +__gcc_v32qi __builtin_ia32_cvtmask2b256(unsigned); +__gcc_v8hi __builtin_ia32_cvtmask2w128(unsigned char); +__gcc_v16hi __builtin_ia32_cvtmask2w256(unsigned short); +__gcc_v4si __builtin_ia32_cvtmask2d128(unsigned char); +__gcc_v8si __builtin_ia32_cvtmask2d256(unsigned char); +__gcc_v2di __builtin_ia32_cvtmask2q128(unsigned char); +__gcc_v4di __builtin_ia32_cvtmask2q256(unsigned char); +unsigned short __builtin_ia32_pcmpeqb128_mask(__gcc_v16qi, __gcc_v16qi, unsigned short); +unsigned __builtin_ia32_pcmpeqb256_mask(__gcc_v32qi, __gcc_v32qi, unsigned); +unsigned char __builtin_ia32_pcmpeqw128_mask(__gcc_v8hi, __gcc_v8hi, unsigned char); +unsigned short __builtin_ia32_pcmpeqw256_mask(__gcc_v16hi, __gcc_v16hi, unsigned short); +unsigned char __builtin_ia32_pcmpeqd128_mask(__gcc_v4si, __gcc_v4si, unsigned char); +unsigned char __builtin_ia32_pcmpeqd256_mask(__gcc_v8si, __gcc_v8si, unsigned char); +unsigned char __builtin_ia32_pcmpeqq128_mask(__gcc_v2di, __gcc_v2di, unsigned char); +unsigned char __builtin_ia32_pcmpeqq256_mask(__gcc_v4di, __gcc_v4di, unsigned char); +unsigned short __builtin_ia32_pcmpgtb128_mask(__gcc_v16qi, __gcc_v16qi, unsigned short); +unsigned __builtin_ia32_pcmpgtb256_mask(__gcc_v32qi, __gcc_v32qi, unsigned); +unsigned char __builtin_ia32_pcmpgtw128_mask(__gcc_v8hi, __gcc_v8hi, unsigned char); +unsigned short __builtin_ia32_pcmpgtw256_mask(__gcc_v16hi, __gcc_v16hi, unsigned short); +unsigned char __builtin_ia32_pcmpgtd128_mask(__gcc_v4si, __gcc_v4si, unsigned char); +unsigned char __builtin_ia32_pcmpgtd256_mask(__gcc_v8si, __gcc_v8si, unsigned char); +unsigned char __builtin_ia32_pcmpgtq128_mask(__gcc_v2di, __gcc_v2di, unsigned char); +unsigned char __builtin_ia32_pcmpgtq256_mask(__gcc_v4di, __gcc_v4di, unsigned char); +unsigned short __builtin_ia32_ptestmb128(__gcc_v16qi, __gcc_v16qi, unsigned short); +unsigned __builtin_ia32_ptestmb256(__gcc_v32qi, __gcc_v32qi, unsigned); +unsigned char __builtin_ia32_ptestmw128(__gcc_v8hi, __gcc_v8hi, unsigned char); +unsigned short __builtin_ia32_ptestmw256(__gcc_v16hi, __gcc_v16hi, unsigned short); +unsigned char __builtin_ia32_ptestmd128(__gcc_v4si, __gcc_v4si, unsigned char); +unsigned char __builtin_ia32_ptestmd256(__gcc_v8si, __gcc_v8si, unsigned char); +unsigned char __builtin_ia32_ptestmq128(__gcc_v2di, __gcc_v2di, unsigned char); +unsigned char __builtin_ia32_ptestmq256(__gcc_v4di, __gcc_v4di, unsigned char); +unsigned short __builtin_ia32_ptestnmb128(__gcc_v16qi, __gcc_v16qi, unsigned short); +unsigned __builtin_ia32_ptestnmb256(__gcc_v32qi, __gcc_v32qi, unsigned); +unsigned char __builtin_ia32_ptestnmw128(__gcc_v8hi, __gcc_v8hi, unsigned char); +unsigned short __builtin_ia32_ptestnmw256(__gcc_v16hi, __gcc_v16hi, unsigned short); +unsigned char __builtin_ia32_ptestnmd128(__gcc_v4si, __gcc_v4si, unsigned char); +unsigned char __builtin_ia32_ptestnmd256(__gcc_v8si, __gcc_v8si, unsigned char); +unsigned char __builtin_ia32_ptestnmq128(__gcc_v2di, __gcc_v2di, unsigned char); +unsigned char __builtin_ia32_ptestnmq256(__gcc_v4di, __gcc_v4di, unsigned char); diff --git a/src/ansi-c/gcc_builtin_headers_ia32-4.h b/src/ansi-c/gcc_builtin_headers_ia32-4.h new file mode 100644 index 00000000000..5acd1ab952a --- /dev/null +++ b/src/ansi-c/gcc_builtin_headers_ia32-4.h @@ -0,0 +1,341 @@ +__gcc_v2di __builtin_ia32_broadcastmb128(unsigned char); +__gcc_v4di __builtin_ia32_broadcastmb256(unsigned char); +__gcc_v4si __builtin_ia32_broadcastmw128(unsigned short); +__gcc_v8si __builtin_ia32_broadcastmw256(unsigned short); +__gcc_v4df __builtin_ia32_compressdf256_mask(__gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_compressdf128_mask(__gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_compresssf256_mask(__gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_compresssf128_mask(__gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v4di __builtin_ia32_compressdi256_mask(__gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_compressdi128_mask(__gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v8si __builtin_ia32_compresssi256_mask(__gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_compresssi128_mask(__gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v4df __builtin_ia32_expanddf256_mask(__gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_expanddf128_mask(__gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_expandsf256_mask(__gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_expandsf128_mask(__gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v4di __builtin_ia32_expanddi256_mask(__gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_expanddi128_mask(__gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v8si __builtin_ia32_expandsi256_mask(__gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_expandsi128_mask(__gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v4df __builtin_ia32_expanddf256_maskz(__gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_expanddf128_maskz(__gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_expandsf256_maskz(__gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_expandsf128_maskz(__gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v4di __builtin_ia32_expanddi256_maskz(__gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_expanddi128_maskz(__gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v8si __builtin_ia32_expandsi256_maskz(__gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_expandsi128_maskz(__gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v8si __builtin_ia32_pmaxsd256_mask(__gcc_v8si, __gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v8si __builtin_ia32_pminsd256_mask(__gcc_v8si, __gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v8si __builtin_ia32_pmaxud256_mask(__gcc_v8si, __gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v8si __builtin_ia32_pminud256_mask(__gcc_v8si, __gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_pmaxsd128_mask(__gcc_v4si, __gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v4si __builtin_ia32_pminsd128_mask(__gcc_v4si, __gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v4si __builtin_ia32_pmaxud128_mask(__gcc_v4si, __gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v4si __builtin_ia32_pminud128_mask(__gcc_v4si, __gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v4di __builtin_ia32_pmaxsq256_mask(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v4di __builtin_ia32_pminsq256_mask(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v4di __builtin_ia32_pmaxuq256_mask(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v4di __builtin_ia32_pminuq256_mask(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_pmaxsq128_mask(__gcc_v2di, __gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v2di __builtin_ia32_pminsq128_mask(__gcc_v2di, __gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v2di __builtin_ia32_pmaxuq128_mask(__gcc_v2di, __gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v2di __builtin_ia32_pminuq128_mask(__gcc_v2di, __gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v32qi __builtin_ia32_pminsb256_mask(__gcc_v32qi, __gcc_v32qi, __gcc_v32qi, unsigned); +__gcc_v32qi __builtin_ia32_pminub256_mask(__gcc_v32qi, __gcc_v32qi, __gcc_v32qi, unsigned); +__gcc_v32qi __builtin_ia32_pmaxsb256_mask(__gcc_v32qi, __gcc_v32qi, __gcc_v32qi, unsigned); +__gcc_v32qi __builtin_ia32_pmaxub256_mask(__gcc_v32qi, __gcc_v32qi, __gcc_v32qi, unsigned); +__gcc_v16qi __builtin_ia32_pminsb128_mask(__gcc_v16qi, __gcc_v16qi, __gcc_v16qi, unsigned short); +__gcc_v16qi __builtin_ia32_pminub128_mask(__gcc_v16qi, __gcc_v16qi, __gcc_v16qi, unsigned short); +__gcc_v16qi __builtin_ia32_pmaxsb128_mask(__gcc_v16qi, __gcc_v16qi, __gcc_v16qi, unsigned short); +__gcc_v16qi __builtin_ia32_pmaxub128_mask(__gcc_v16qi, __gcc_v16qi, __gcc_v16qi, unsigned short); +__gcc_v16hi __builtin_ia32_pminsw256_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v16hi __builtin_ia32_pminuw256_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v16hi __builtin_ia32_pmaxsw256_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v16hi __builtin_ia32_pmaxuw256_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v8hi __builtin_ia32_pminsw128_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v8hi __builtin_ia32_pminuw128_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v8hi __builtin_ia32_pmaxsw128_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v8hi __builtin_ia32_pmaxuw128_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v4di __builtin_ia32_vpconflictdi_256_mask(__gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v8si __builtin_ia32_vpconflictsi_256_mask(__gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v4di __builtin_ia32_vplzcntq_256_mask(__gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v8si __builtin_ia32_vplzcntd_256_mask(__gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v4df __builtin_ia32_unpckhpd256_mask(__gcc_v4df, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_unpckhpd128_mask(__gcc_v2df, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_unpckhps256_mask(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v4sf __builtin_ia32_unpckhps128_mask(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v4df __builtin_ia32_unpcklpd256_mask(__gcc_v4df, __gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v2df __builtin_ia32_unpcklpd128_mask(__gcc_v2df, __gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_unpcklps256_mask(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v2di __builtin_ia32_vpconflictdi_128_mask(__gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v4si __builtin_ia32_vpconflictsi_128_mask(__gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v2di __builtin_ia32_vplzcntq_128_mask(__gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v4si __builtin_ia32_vplzcntd_128_mask(__gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v4sf __builtin_ia32_unpcklps128_mask(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v8si __builtin_ia32_alignd256_mask(__gcc_v8si, __gcc_v8si, int, __gcc_v8si, unsigned char); +__gcc_v4di __builtin_ia32_alignq256_mask(__gcc_v4di, __gcc_v4di, int, __gcc_v4di, unsigned char); +__gcc_v4si __builtin_ia32_alignd128_mask(__gcc_v4si, __gcc_v4si, int, __gcc_v4si, unsigned char); +__gcc_v2di __builtin_ia32_alignq128_mask(__gcc_v2di, __gcc_v2di, int, __gcc_v2di, unsigned char); +__gcc_v8hi __builtin_ia32_vcvtps2ph256_mask(__gcc_v8sf, int, __gcc_v8hi, unsigned char); +__gcc_v8hi __builtin_ia32_vcvtps2ph_mask(__gcc_v4sf, int, __gcc_v8hi, unsigned char); +__gcc_v4sf __builtin_ia32_vcvtph2ps_mask(__gcc_v8hi, __gcc_v4sf, unsigned char); +__gcc_v8sf __builtin_ia32_vcvtph2ps256_mask(__gcc_v8hi, __gcc_v8sf, unsigned char); +__gcc_v4si __builtin_ia32_punpckhdq128_mask(__gcc_v4si, __gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v8si __builtin_ia32_punpckhdq256_mask(__gcc_v8si, __gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v2di __builtin_ia32_punpckhqdq128_mask(__gcc_v2di, __gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v4di __builtin_ia32_punpckhqdq256_mask(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v4si __builtin_ia32_punpckldq128_mask(__gcc_v4si, __gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v8si __builtin_ia32_punpckldq256_mask(__gcc_v8si, __gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v2di __builtin_ia32_punpcklqdq128_mask(__gcc_v2di, __gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v4di __builtin_ia32_punpcklqdq256_mask(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v16qi __builtin_ia32_punpckhbw128_mask(__gcc_v16qi, __gcc_v16qi, __gcc_v16qi, unsigned short); +__gcc_v32qi __builtin_ia32_punpckhbw256_mask(__gcc_v32qi, __gcc_v32qi, __gcc_v32qi, unsigned); +__gcc_v8hi __builtin_ia32_punpckhwd128_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v16hi __builtin_ia32_punpckhwd256_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v16qi __builtin_ia32_punpcklbw128_mask(__gcc_v16qi, __gcc_v16qi, __gcc_v16qi, unsigned short); +__gcc_v32qi __builtin_ia32_punpcklbw256_mask(__gcc_v32qi, __gcc_v32qi, __gcc_v32qi, unsigned); +__gcc_v8hi __builtin_ia32_punpcklwd128_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v16hi __builtin_ia32_punpcklwd256_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v16hi __builtin_ia32_psllv16hi_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v8hi __builtin_ia32_psllv8hi_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v16hi __builtin_ia32_packssdw256_mask(__gcc_v8si, __gcc_v8si, __gcc_v16hi, unsigned short); +__gcc_v8hi __builtin_ia32_packssdw128_mask(__gcc_v4si, __gcc_v4si, __gcc_v8hi, unsigned char); +__gcc_v16hi __builtin_ia32_packusdw256_mask(__gcc_v8si, __gcc_v8si, __gcc_v16hi, unsigned short); +__gcc_v8hi __builtin_ia32_packusdw128_mask(__gcc_v4si, __gcc_v4si, __gcc_v8hi, unsigned char); +__gcc_v32qi __builtin_ia32_pavgb256_mask(__gcc_v32qi, __gcc_v32qi, __gcc_v32qi, unsigned); +__gcc_v16hi __builtin_ia32_pavgw256_mask(__gcc_v16hi, __gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v16qi __builtin_ia32_pavgb128_mask(__gcc_v16qi, __gcc_v16qi, __gcc_v16qi, unsigned short); +__gcc_v8hi __builtin_ia32_pavgw128_mask(__gcc_v8hi, __gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v8sf __builtin_ia32_permvarsf256_mask(__gcc_v8sf, __gcc_v8si, __gcc_v8sf, unsigned char); +__gcc_v4df __builtin_ia32_permvardf256_mask(__gcc_v4df, __gcc_v4di, __gcc_v4df, unsigned char); +__gcc_v4df __builtin_ia32_permdf256_mask(__gcc_v4df, int, __gcc_v4df, unsigned char); +__gcc_v32qi __builtin_ia32_pabsb256_mask(__gcc_v32qi, __gcc_v32qi, unsigned); +__gcc_v16qi __builtin_ia32_pabsb128_mask(__gcc_v16qi, __gcc_v16qi, unsigned short); +__gcc_v16hi __builtin_ia32_pabsw256_mask(__gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v8hi __builtin_ia32_pabsw128_mask(__gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v2df __builtin_ia32_vpermilvarpd_mask(__gcc_v2df, __gcc_v2di, __gcc_v2df, unsigned char); +__gcc_v4sf __builtin_ia32_vpermilvarps_mask(__gcc_v4sf, __gcc_v4si, __gcc_v4sf, unsigned char); +__gcc_v4df __builtin_ia32_vpermilvarpd256_mask(__gcc_v4df, __gcc_v4di, __gcc_v4df, unsigned char); +__gcc_v8sf __builtin_ia32_vpermilvarps256_mask(__gcc_v8sf, __gcc_v8si, __gcc_v8sf, unsigned char); +__gcc_v2df __builtin_ia32_vpermilpd_mask(__gcc_v2df, int, __gcc_v2df, unsigned char); +__gcc_v4sf __builtin_ia32_vpermilps_mask(__gcc_v4sf, int, __gcc_v4sf, unsigned char); +__gcc_v4df __builtin_ia32_vpermilpd256_mask(__gcc_v4df, int, __gcc_v4df, unsigned char); +__gcc_v8sf __builtin_ia32_vpermilps256_mask(__gcc_v8sf, int, __gcc_v8sf, unsigned char); +__gcc_v4di __builtin_ia32_blendmq_256_mask(__gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v8si __builtin_ia32_blendmd_256_mask(__gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v4df __builtin_ia32_blendmpd_256_mask(__gcc_v4df, __gcc_v4df, unsigned char); +__gcc_v8sf __builtin_ia32_blendmps_256_mask(__gcc_v8sf, __gcc_v8sf, unsigned char); +__gcc_v2di __builtin_ia32_blendmq_128_mask(__gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v4si __builtin_ia32_blendmd_128_mask(__gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v2df __builtin_ia32_blendmpd_128_mask(__gcc_v2df, __gcc_v2df, unsigned char); +__gcc_v4sf __builtin_ia32_blendmps_128_mask(__gcc_v4sf, __gcc_v4sf, unsigned char); +__gcc_v16hi __builtin_ia32_blendmw_256_mask(__gcc_v16hi, __gcc_v16hi, unsigned short); +__gcc_v32qi __builtin_ia32_blendmb_256_mask(__gcc_v32qi, __gcc_v32qi, unsigned); +__gcc_v8hi __builtin_ia32_blendmw_128_mask(__gcc_v8hi, __gcc_v8hi, unsigned char); +__gcc_v16qi __builtin_ia32_blendmb_128_mask(__gcc_v16qi, __gcc_v16qi, unsigned short); +__gcc_v8si __builtin_ia32_pmulld256_mask(__gcc_v8si, __gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v4si __builtin_ia32_pmulld128_mask(__gcc_v4si, __gcc_v4si, __gcc_v4si, unsigned char); +__gcc_v4di __builtin_ia32_pmuludq256_mask(__gcc_v8si, __gcc_v8si, __gcc_v4di, unsigned char); +__gcc_v4di __builtin_ia32_pmuldq256_mask(__gcc_v8si, __gcc_v8si, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_pmuldq128_mask(__gcc_v4si, __gcc_v4si, __gcc_v2di, unsigned char); +__gcc_v2di __builtin_ia32_pmuludq128_mask(__gcc_v4si, __gcc_v4si, __gcc_v2di, unsigned char); +__gcc_v4sf __builtin_ia32_cvtpd2ps256_mask(__gcc_v4df, __gcc_v4sf, unsigned char); +__gcc_v4sf __builtin_ia32_cvtpd2ps_mask(__gcc_v2df, __gcc_v4sf, unsigned char); +__gcc_v8si __builtin_ia32_permvarsi256_mask(__gcc_v8si, __gcc_v8si, __gcc_v8si, unsigned char); +__gcc_v4di __builtin_ia32_permvardi256_mask(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v4di __builtin_ia32_permdi256_mask(__gcc_v4di, int, __gcc_v4di, unsigned char); +unsigned char __builtin_ia32_cmpq256_mask(__gcc_v4di, __gcc_v4di, int, unsigned char); +unsigned char __builtin_ia32_cmpd256_mask(__gcc_v8si, __gcc_v8si, int, unsigned char); +unsigned char __builtin_ia32_ucmpq256_mask(__gcc_v4di, __gcc_v4di, int, unsigned char); +unsigned char __builtin_ia32_ucmpd256_mask(__gcc_v8si, __gcc_v8si, int, unsigned char); +unsigned __builtin_ia32_cmpb256_mask(__gcc_v32qi, __gcc_v32qi, int, unsigned); +unsigned short __builtin_ia32_cmpw256_mask(__gcc_v16hi, __gcc_v16hi, int, unsigned short); +unsigned __builtin_ia32_ucmpb256_mask(__gcc_v32qi, __gcc_v32qi, int, unsigned); +unsigned short __builtin_ia32_ucmpw256_mask(__gcc_v16hi, __gcc_v16hi, int, unsigned short); +char __builtin_ia32_cmppd256_mask(__gcc_v4df, __gcc_v4df, int, unsigned char); +char __builtin_ia32_cmpps256_mask(__gcc_v8sf, __gcc_v8sf, int, unsigned char); +unsigned char __builtin_ia32_cmpq128_mask(__gcc_v2di, __gcc_v2di, int, unsigned char); +unsigned char __builtin_ia32_cmpd128_mask(__gcc_v4si, __gcc_v4si, int, unsigned char); +unsigned char __builtin_ia32_ucmpq128_mask(__gcc_v2di, __gcc_v2di, int, unsigned char); +unsigned char __builtin_ia32_ucmpd128_mask(__gcc_v4si, __gcc_v4si, int, unsigned char); +unsigned short __builtin_ia32_cmpb128_mask(__gcc_v16qi, __gcc_v16qi, int, unsigned short); +unsigned char __builtin_ia32_cmpw128_mask(__gcc_v8hi, __gcc_v8hi, int, unsigned char); +unsigned short __builtin_ia32_ucmpb128_mask(__gcc_v16qi, __gcc_v16qi, int, unsigned short); +unsigned char __builtin_ia32_ucmpw128_mask(__gcc_v8hi, __gcc_v8hi, int, unsigned char); +unsigned char __builtin_ia32_cmppd128_mask(__gcc_v2df, __gcc_v2df, int, unsigned char); +unsigned char __builtin_ia32_cmpps128_mask(__gcc_v4sf, __gcc_v4sf, int, unsigned char); +__gcc_v16sf __builtin_ia32_broadcastf32x2_512_mask(__gcc_v4sf, __gcc_v16sf, unsigned short); +__gcc_v16si __builtin_ia32_broadcasti32x2_512_mask(__gcc_v4si, __gcc_v16si, unsigned short); +__gcc_v8df __builtin_ia32_broadcastf64x2_512_mask(__gcc_v2df, __gcc_v8df, unsigned char); +__gcc_v8di __builtin_ia32_broadcasti64x2_512_mask(__gcc_v2di, __gcc_v8di, unsigned char); +__gcc_v16sf __builtin_ia32_broadcastf32x8_512_mask(__gcc_v8sf, __gcc_v16sf, unsigned short); +__gcc_v16si __builtin_ia32_broadcasti32x8_512_mask(__gcc_v8si, __gcc_v16si, unsigned short); +__gcc_v2df __builtin_ia32_extractf64x2_512_mask(__gcc_v8df, int, __gcc_v2df, unsigned char); +__gcc_v8sf __builtin_ia32_extractf32x8_mask(__gcc_v16sf, int, __gcc_v8sf, unsigned char); +__gcc_v2di __builtin_ia32_extracti64x2_512_mask(__gcc_v8di, int, __gcc_v2di, unsigned char); +__gcc_v8si __builtin_ia32_extracti32x8_mask(__gcc_v16si, int, __gcc_v8si, unsigned char); +__gcc_v8df __builtin_ia32_reducepd512_mask(__gcc_v8df, int, __gcc_v8df, unsigned char); +__gcc_v16sf __builtin_ia32_reduceps512_mask(__gcc_v16sf, int, __gcc_v16sf, unsigned short); +__gcc_v8di __builtin_ia32_pmullq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v8df __builtin_ia32_xorpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, unsigned char); +__gcc_v16sf __builtin_ia32_xorps512_mask(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, unsigned short); +__gcc_v8df __builtin_ia32_orpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, unsigned char); +__gcc_v16sf __builtin_ia32_orps512_mask(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, unsigned short); +__gcc_v8df __builtin_ia32_andpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, unsigned char); +__gcc_v16sf __builtin_ia32_andps512_mask(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, unsigned short); +__gcc_v8df __builtin_ia32_andnpd512_mask(__gcc_v8df, __gcc_v8df, __gcc_v8df, unsigned char); +__gcc_v16sf __builtin_ia32_andnps512_mask(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, unsigned short); +__gcc_v16sf __builtin_ia32_insertf32x8_mask(__gcc_v16sf, __gcc_v8sf, int, __gcc_v16sf, unsigned short); +__gcc_v16si __builtin_ia32_inserti32x8_mask(__gcc_v16si, __gcc_v8si, int, __gcc_v16si, unsigned short); +__gcc_v8df __builtin_ia32_insertf64x2_512_mask(__gcc_v8df, __gcc_v2df, int, __gcc_v8df, unsigned char); +__gcc_v8di __builtin_ia32_inserti64x2_512_mask(__gcc_v8di, __gcc_v2di, int, __gcc_v8di, unsigned char); +char __builtin_ia32_fpclasspd512_mask(__gcc_v8df, int, unsigned char); +short __builtin_ia32_fpclassps512_mask(__gcc_v16sf, int, unsigned short); +unsigned short __builtin_ia32_cvtd2mask512(__gcc_v16si); +unsigned char __builtin_ia32_cvtq2mask512(__gcc_v8di); +__gcc_v16si __builtin_ia32_cvtmask2d512(unsigned short); +__gcc_v8di __builtin_ia32_cvtmask2q512(unsigned char); +unsigned __builtin_ia32_kunpcksi(unsigned, unsigned); +unsigned long long __builtin_ia32_kunpckdi(unsigned long long, unsigned long long); +__gcc_v32hi __builtin_ia32_packusdw512_mask(__gcc_v16si, __gcc_v16si, __gcc_v32hi, unsigned); +__gcc_v32hi __builtin_ia32_packssdw512_mask(__gcc_v16si, __gcc_v16si, __gcc_v32hi, unsigned); +__gcc_v32hi __builtin_ia32_movdquhi512_mask(__gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v64qi __builtin_ia32_movdquqi512_mask(__gcc_v64qi, __gcc_v64qi, unsigned long long); +__gcc_v8di __builtin_ia32_psadbw512(__gcc_v64qi, __gcc_v64qi); +__gcc_v32hi __builtin_ia32_dbpsadbw512_mask(__gcc_v64qi, __gcc_v64qi, int, __gcc_v32hi, unsigned); +__gcc_v64qi __builtin_ia32_pbroadcastb512_mask(__gcc_v16qi, __gcc_v64qi, unsigned long long); +__gcc_v64qi __builtin_ia32_pbroadcastb512_gpr_mask(char, __gcc_v64qi, unsigned long long); +__gcc_v32hi __builtin_ia32_pbroadcastw512_mask(__gcc_v8hi, __gcc_v32hi, unsigned); +__gcc_v32hi __builtin_ia32_pbroadcastw512_gpr_mask(short, __gcc_v32hi, unsigned); +__gcc_v32hi __builtin_ia32_pmovsxbw512_mask(__gcc_v32qi, __gcc_v32hi, unsigned); +__gcc_v32hi __builtin_ia32_pmovzxbw512_mask(__gcc_v32qi, __gcc_v32hi, unsigned); +__gcc_v32hi __builtin_ia32_permvarhi512_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v32hi __builtin_ia32_vpermt2varhi512_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v32hi __builtin_ia32_vpermt2varhi512_maskz(__gcc_v32hi, __gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v32hi __builtin_ia32_vpermi2varhi512_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v64qi __builtin_ia32_pavgb512_mask(__gcc_v64qi, __gcc_v64qi, __gcc_v64qi, unsigned long long); +__gcc_v32hi __builtin_ia32_pavgw512_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v64qi __builtin_ia32_paddb512_mask(__gcc_v64qi, __gcc_v64qi, __gcc_v64qi, unsigned long long); +__gcc_v64qi __builtin_ia32_psubb512_mask(__gcc_v64qi, __gcc_v64qi, __gcc_v64qi, unsigned long long); +__gcc_v64qi __builtin_ia32_psubsb512_mask(__gcc_v64qi, __gcc_v64qi, __gcc_v64qi, unsigned long long); +__gcc_v64qi __builtin_ia32_paddsb512_mask(__gcc_v64qi, __gcc_v64qi, __gcc_v64qi, unsigned long long); +__gcc_v64qi __builtin_ia32_psubusb512_mask(__gcc_v64qi, __gcc_v64qi, __gcc_v64qi, unsigned long long); +__gcc_v64qi __builtin_ia32_paddusb512_mask(__gcc_v64qi, __gcc_v64qi, __gcc_v64qi, unsigned long long); +__gcc_v32hi __builtin_ia32_psubw512_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v32hi __builtin_ia32_paddw512_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v32hi __builtin_ia32_psubsw512_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v32hi __builtin_ia32_paddsw512_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v32hi __builtin_ia32_psubusw512_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v32hi __builtin_ia32_paddusw512_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v32hi __builtin_ia32_pmaxuw512_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v32hi __builtin_ia32_pmaxsw512_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v32hi __builtin_ia32_pminuw512_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v32hi __builtin_ia32_pminsw512_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v64qi __builtin_ia32_pmaxub512_mask(__gcc_v64qi, __gcc_v64qi, __gcc_v64qi, unsigned long long); +__gcc_v64qi __builtin_ia32_pmaxsb512_mask(__gcc_v64qi, __gcc_v64qi, __gcc_v64qi, unsigned long long); +__gcc_v64qi __builtin_ia32_pminub512_mask(__gcc_v64qi, __gcc_v64qi, __gcc_v64qi, unsigned long long); +__gcc_v64qi __builtin_ia32_pminsb512_mask(__gcc_v64qi, __gcc_v64qi, __gcc_v64qi, unsigned long long); +__gcc_v32qi __builtin_ia32_pmovwb512_mask(__gcc_v32hi, __gcc_v32qi, unsigned); +__gcc_v32qi __builtin_ia32_pmovswb512_mask(__gcc_v32hi, __gcc_v32qi, unsigned); +__gcc_v32qi __builtin_ia32_pmovuswb512_mask(__gcc_v32hi, __gcc_v32qi, unsigned); +__gcc_v32hi __builtin_ia32_pmulhrsw512_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v32hi __builtin_ia32_pmulhuw512_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v32hi __builtin_ia32_pmulhw512_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v32hi __builtin_ia32_pmullw512_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v64qi __builtin_ia32_packsswb512_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v64qi, unsigned long long); +__gcc_v64qi __builtin_ia32_packuswb512_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v64qi, unsigned long long); +__gcc_v32hi __builtin_ia32_psrav32hi_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v32hi __builtin_ia32_pmaddubsw512_mask(__gcc_v64qi, __gcc_v64qi, __gcc_v32hi, unsigned); +__gcc_v16si __builtin_ia32_pmaddwd512_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v16si, unsigned short); +__gcc_v32hi __builtin_ia32_psrlv32hi_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v64qi __builtin_ia32_punpckhbw512_mask(__gcc_v64qi, __gcc_v64qi, __gcc_v64qi, unsigned long long); +__gcc_v32hi __builtin_ia32_punpckhwd512_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v64qi __builtin_ia32_punpcklbw512_mask(__gcc_v64qi, __gcc_v64qi, __gcc_v64qi, unsigned long long); +__gcc_v32hi __builtin_ia32_punpcklwd512_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v64qi __builtin_ia32_pshufb512_mask(__gcc_v64qi, __gcc_v64qi, __gcc_v64qi, unsigned long long); +__gcc_v32hi __builtin_ia32_pshufhw512_mask(__gcc_v32hi, int, __gcc_v32hi, unsigned); +__gcc_v32hi __builtin_ia32_pshuflw512_mask(__gcc_v32hi, int, __gcc_v32hi, unsigned); +unsigned long long __builtin_ia32_cvtb2mask512(__gcc_v64qi); +unsigned __builtin_ia32_cvtw2mask512(__gcc_v32hi); +__gcc_v64qi __builtin_ia32_cvtmask2b512(unsigned long long); +__gcc_v32hi __builtin_ia32_cvtmask2w512(unsigned); +unsigned long long __builtin_ia32_pcmpeqb512_mask(__gcc_v64qi, __gcc_v64qi, unsigned long long); +unsigned __builtin_ia32_pcmpeqw512_mask(__gcc_v32hi, __gcc_v32hi, unsigned); +unsigned long long __builtin_ia32_pcmpgtb512_mask(__gcc_v64qi, __gcc_v64qi, unsigned long long); +unsigned __builtin_ia32_pcmpgtw512_mask(__gcc_v32hi, __gcc_v32hi, unsigned); +unsigned long long __builtin_ia32_ptestmb512(__gcc_v64qi, __gcc_v64qi, unsigned long long); +unsigned __builtin_ia32_ptestmw512(__gcc_v32hi, __gcc_v32hi, unsigned); +unsigned long long __builtin_ia32_ptestnmb512(__gcc_v64qi, __gcc_v64qi, unsigned long long); +unsigned __builtin_ia32_ptestnmw512(__gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v32hi __builtin_ia32_psllv32hi_mask(__gcc_v32hi, __gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v64qi __builtin_ia32_pabsb512_mask(__gcc_v64qi, __gcc_v64qi, unsigned long long); +__gcc_v32hi __builtin_ia32_pabsw512_mask(__gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v32hi __builtin_ia32_blendmw_512_mask(__gcc_v32hi, __gcc_v32hi, unsigned); +__gcc_v64qi __builtin_ia32_blendmb_512_mask(__gcc_v64qi, __gcc_v64qi, unsigned long long); +unsigned long long __builtin_ia32_cmpb512_mask(__gcc_v64qi, __gcc_v64qi, int, unsigned long long); +unsigned __builtin_ia32_cmpw512_mask(__gcc_v32hi, __gcc_v32hi, int, unsigned); +unsigned long long __builtin_ia32_ucmpb512_mask(__gcc_v64qi, __gcc_v64qi, int, unsigned long long); +unsigned __builtin_ia32_ucmpw512_mask(__gcc_v32hi, __gcc_v32hi, int, unsigned); +__gcc_v8di __builtin_ia32_vpmadd52luq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v8di __builtin_ia32_vpmadd52luq512_maskz(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v8di __builtin_ia32_vpmadd52huq512_mask(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v8di __builtin_ia32_vpmadd52huq512_maskz(__gcc_v8di, __gcc_v8di, __gcc_v8di, unsigned char); +__gcc_v4di __builtin_ia32_vpmadd52luq256_mask(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v4di __builtin_ia32_vpmadd52luq256_maskz(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v4di __builtin_ia32_vpmadd52huq256_mask(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v4di __builtin_ia32_vpmadd52huq256_maskz(__gcc_v4di, __gcc_v4di, __gcc_v4di, unsigned char); +__gcc_v2di __builtin_ia32_vpmadd52luq128_mask(__gcc_v2di, __gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v2di __builtin_ia32_vpmadd52luq128_maskz(__gcc_v2di, __gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v2di __builtin_ia32_vpmadd52huq128_mask(__gcc_v2di, __gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v2di __builtin_ia32_vpmadd52huq128_maskz(__gcc_v2di, __gcc_v2di, __gcc_v2di, unsigned char); +__gcc_v64qi __builtin_ia32_vpmultishiftqb512_mask(__gcc_v64qi, __gcc_v64qi, __gcc_v64qi, unsigned long long); +__gcc_v32qi __builtin_ia32_vpmultishiftqb256_mask(__gcc_v32qi, __gcc_v32qi, __gcc_v32qi, unsigned); +__gcc_v16qi __builtin_ia32_vpmultishiftqb128_mask(__gcc_v16qi, __gcc_v16qi, __gcc_v16qi, unsigned short); +__gcc_v64qi __builtin_ia32_permvarqi512_mask(__gcc_v64qi, __gcc_v64qi, __gcc_v64qi, unsigned long long); +__gcc_v64qi __builtin_ia32_vpermt2varqi512_mask(__gcc_v64qi, __gcc_v64qi, __gcc_v64qi, unsigned long long); +__gcc_v64qi __builtin_ia32_vpermt2varqi512_maskz(__gcc_v64qi, __gcc_v64qi, __gcc_v64qi, unsigned long long); +__gcc_v64qi __builtin_ia32_vpermi2varqi512_mask(__gcc_v64qi, __gcc_v64qi, __gcc_v64qi, unsigned long long); +__gcc_v32qi __builtin_ia32_permvarqi256_mask(__gcc_v32qi, __gcc_v32qi, __gcc_v32qi, unsigned); +__gcc_v16qi __builtin_ia32_permvarqi128_mask(__gcc_v16qi, __gcc_v16qi, __gcc_v16qi, unsigned short); +__gcc_v32qi __builtin_ia32_vpermt2varqi256_mask(__gcc_v32qi, __gcc_v32qi, __gcc_v32qi, unsigned); +__gcc_v32qi __builtin_ia32_vpermt2varqi256_maskz(__gcc_v32qi, __gcc_v32qi, __gcc_v32qi, unsigned); +__gcc_v16qi __builtin_ia32_vpermt2varqi128_mask(__gcc_v16qi, __gcc_v16qi, __gcc_v16qi, unsigned short); +__gcc_v16qi __builtin_ia32_vpermt2varqi128_maskz(__gcc_v16qi, __gcc_v16qi, __gcc_v16qi, unsigned short); +__gcc_v32qi __builtin_ia32_vpermi2varqi256_mask(__gcc_v32qi, __gcc_v32qi, __gcc_v32qi, unsigned); +__gcc_v16qi __builtin_ia32_vpermi2varqi128_mask(__gcc_v16qi, __gcc_v16qi, __gcc_v16qi, unsigned short); +__gcc_v2df __builtin_ia32_rangesd128_round(__gcc_v2df, __gcc_v2df, int, int); +__gcc_v4sf __builtin_ia32_rangess128_round(__gcc_v4sf, __gcc_v4sf, int, int); +__gcc_v8di __builtin_ia32_cvtpd2qq512_mask(__gcc_v8df, __gcc_v8di, char, int); +__gcc_v8di __builtin_ia32_cvtps2qq512_mask(__gcc_v8sf, __gcc_v8di, char, int); +__gcc_v8di __builtin_ia32_cvtpd2uqq512_mask(__gcc_v8df, __gcc_v8di, char, int); +__gcc_v8di __builtin_ia32_cvtps2uqq512_mask(__gcc_v8sf, __gcc_v8di, char, int); +__gcc_v8sf __builtin_ia32_cvtqq2ps512_mask(__gcc_v8di, __gcc_v8sf, char, int); +__gcc_v8sf __builtin_ia32_cvtuqq2ps512_mask(__gcc_v8di, __gcc_v8sf, char, int); +__gcc_v8df __builtin_ia32_cvtqq2pd512_mask(__gcc_v8di, __gcc_v8df, char, int); +__gcc_v8df __builtin_ia32_cvtuqq2pd512_mask(__gcc_v8di, __gcc_v8df, char, int); +__gcc_v8di __builtin_ia32_cvttps2qq512_mask(__gcc_v8sf, __gcc_v8di, char, int); +__gcc_v8di __builtin_ia32_cvttps2uqq512_mask(__gcc_v8sf, __gcc_v8di, char, int); +__gcc_v8di __builtin_ia32_cvttpd2qq512_mask(__gcc_v8df, __gcc_v8di, char, int); +__gcc_v8di __builtin_ia32_cvttpd2uqq512_mask(__gcc_v8df, __gcc_v8di, char, int); +__gcc_v16sf __builtin_ia32_rangeps512_mask(__gcc_v16sf, __gcc_v16sf, int, __gcc_v16sf, short, int); +__gcc_v8df __builtin_ia32_rangepd512_mask(__gcc_v8df, __gcc_v8df, int, __gcc_v8df, char, int); +__gcc_v16sf __builtin_ia32_4fmaddps_mask(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, __gcc_v16sf, __gcc_v16sf, const __gcc_v4sf*, __gcc_v16sf, unsigned short); +__gcc_v16sf __builtin_ia32_4fmaddps(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, __gcc_v16sf, __gcc_v16sf, const __gcc_v4sf*); +__gcc_v4sf __builtin_ia32_4fmaddss(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, __gcc_v4sf, __gcc_v4sf, const __gcc_v4sf*); +__gcc_v4sf __builtin_ia32_4fmaddss_mask(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, __gcc_v4sf, __gcc_v4sf, const __gcc_v4sf*, __gcc_v4sf, unsigned char); +__gcc_v16sf __builtin_ia32_4fnmaddps_mask(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, __gcc_v16sf, __gcc_v16sf, const __gcc_v4sf*, __gcc_v16sf, unsigned short); +__gcc_v16sf __builtin_ia32_4fnmaddps(__gcc_v16sf, __gcc_v16sf, __gcc_v16sf, __gcc_v16sf, __gcc_v16sf, const __gcc_v4sf*); +__gcc_v4sf __builtin_ia32_4fnmaddss(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, __gcc_v4sf, __gcc_v4sf, const __gcc_v4sf*); +__gcc_v4sf __builtin_ia32_4fnmaddss_mask(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf, __gcc_v4sf, __gcc_v4sf, const __gcc_v4sf*, __gcc_v4sf, unsigned char); +__gcc_v16si __builtin_ia32_vp4dpwssd(__gcc_v16si, __gcc_v16si, __gcc_v16si, __gcc_v16si, __gcc_v16si, const __gcc_v4si*); +__gcc_v16si __builtin_ia32_vp4dpwssd_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, __gcc_v16si, __gcc_v16si, const __gcc_v4si*, __gcc_v16si, unsigned short); +__gcc_v16si __builtin_ia32_vp4dpwssds(__gcc_v16si, __gcc_v16si, __gcc_v16si, __gcc_v16si, __gcc_v16si, const __gcc_v4si*); +__gcc_v16si __builtin_ia32_vp4dpwssds_mask(__gcc_v16si, __gcc_v16si, __gcc_v16si, __gcc_v16si, __gcc_v16si, const __gcc_v4si*, __gcc_v16si, unsigned short); +__gcc_v16si __builtin_ia32_vpopcountd_v16si(__gcc_v16si); +__gcc_v16si __builtin_ia32_vpopcountd_v16si_mask(__gcc_v16si, __gcc_v16si, unsigned short); +__gcc_v8di __builtin_ia32_vpopcountq_v8di(__gcc_v8di); +__gcc_v8di __builtin_ia32_vpopcountq_v8di_mask(__gcc_v8di, __gcc_v8di, unsigned char); +unsigned __builtin_ia32_rdpid(); +unsigned long __builtin_ia32_sizeof(void); diff --git a/src/ansi-c/gcc_builtin_headers_ia32.h b/src/ansi-c/gcc_builtin_headers_ia32.h index 90ffac22ba1..9be09f54701 100644 --- a/src/ansi-c/gcc_builtin_headers_ia32.h +++ b/src/ansi-c/gcc_builtin_headers_ia32.h @@ -3,7 +3,7 @@ __float128 __builtin_fabsq(__float128); __float128 __builtin_copysignq(__float128, __float128); -void __builtin_ia32_pause(void); +void __builtin_ia32_pause(); __float128 __builtin_infq(void); __float128 __builtin_huge_valq(void); __gcc_v8qi __builtin_ia32_paddb(__gcc_v8qi, __gcc_v8qi); @@ -74,18 +74,18 @@ __gcc_v4hi __builtin_ia32_pminsw(__gcc_v4hi, __gcc_v4hi); int __builtin_ia32_pextrw(__gcc_v4hi, int); __gcc_v4hi __builtin_ia32_pinsrw(__gcc_v4hi, int, int); int __builtin_ia32_pmovmskb(__gcc_v8qi); -void __builtin_ia32_maskmovq(__gcc_v8qi, __gcc_v8qi, char *); +void __builtin_ia32_maskmovq(__gcc_v8qi, __gcc_v8qi, char*); // clang uses the following: -// void __builtin_ia32_movntq(__gcc_v1di *, __gcc_v1di); -// -// GCC uses this: -// void __builtin_ia32_movntq(__gcc_di *, __gcc_di); -// -// So, we use: -void __builtin_ia32_movntq(void *, ...); +// void __builtin_ia32_movntq(__gcc_v1di*, __gcc_v1di); + // + // GCC uses this: +// void __builtin_ia32_movntq(__gcc_di*, __gcc_di); + // + // So, we use: +void __builtin_ia32_movntq(void*, ...); -void __builtin_ia32_sfence(void); +void __builtin_ia32_sfence(); int __builtin_ia32_comieq(__gcc_v4sf, __gcc_v4sf); int __builtin_ia32_comineq(__gcc_v4sf, __gcc_v4sf); int __builtin_ia32_comilt(__gcc_v4sf, __gcc_v4sf); @@ -152,35 +152,35 @@ __gcc_v4sf __builtin_ia32_rcpss(__gcc_v4sf); __gcc_v4sf __builtin_ia32_rsqrtss(__gcc_v4sf); __gcc_v4sf __builtin_ia32_sqrtss(__gcc_v4sf); __gcc_v4sf __builtin_ia32_shufps(__gcc_v4sf, __gcc_v4sf, int); -void __builtin_ia32_movntps(float *, __gcc_v4sf); +void __builtin_ia32_movntps(float*, __gcc_v4sf); int __builtin_ia32_movmskps(__gcc_v4sf); -__gcc_v4sf __builtin_ia32_loadaps(float *); -void __builtin_ia32_storeaps(float *, __gcc_v4sf); -__gcc_v4sf __builtin_ia32_loadups(float *); -void __builtin_ia32_storeups(float *, __gcc_v4sf); -__gcc_v4sf __builtin_ia32_loadsss(float *); -void __builtin_ia32_storess(float *, __gcc_v4sf); +__gcc_v4sf __builtin_ia32_loadaps(float*); +void __builtin_ia32_storeaps(float*, __gcc_v4sf); +__gcc_v4sf __builtin_ia32_loadups(const float*); +void __builtin_ia32_storeups(float*, __gcc_v4sf); +__gcc_v4sf __builtin_ia32_loadsss(float*); +void __builtin_ia32_storess(float*, __gcc_v4sf); // clang uses these: -// __gcc_v4sf __builtin_ia32_loadhps(__gcc_v4sf, const __gcc_v2si *); -// __gcc_v4sf __builtin_ia32_loadlps(__gcc_v4sf, const __gcc_v2si *); -// void __builtin_ia32_storehps(__gcc_v2si *, __gcc_v4sf); -// void __builtin_ia32_storelps(__gcc_v2si *, __gcc_v4sf); +// __gcc_v4sf __builtin_ia32_loadhps(__gcc_v4sf, const __gcc_v2si*); +// __gcc_v4sf __builtin_ia32_loadlps(__gcc_v4sf, const __gcc_v2si*); +// void __builtin_ia32_storehps(__gcc_v2si*, __gcc_v4sf); +// void __builtin_ia32_storelps(__gcc_v2si*, __gcc_v4sf); // // but GCC uses: -// __gcc_v4sf __builtin_ia32_loadhps(__gcc_v4sf, const __gcc_v2sf *); -// __gcc_v4sf __builtin_ia32_loadlps(__gcc_v4sf, const __gcc_v2sf *); -// void __builtin_ia32_storehps(__gcc_v2sf *, __gcc_v4sf); -// void __builtin_ia32_storelps(__gcc_v2sf *, __gcc_v4sf); +// __gcc_v4sf __builtin_ia32_loadhps(__gcc_v4sf, const __gcc_v2sf*); +// __gcc_v4sf __builtin_ia32_loadlps(__gcc_v4sf, const __gcc_v2sf*); +// void __builtin_ia32_storehps(__gcc_v2sf*, __gcc_v4sf); +// void __builtin_ia32_storelps(__gcc_v2sf*, __gcc_v4sf); // // So we use: -__gcc_v4sf __builtin_ia32_loadhps(__gcc_v4sf, const void *); -__gcc_v4sf __builtin_ia32_loadlps(__gcc_v4sf, const void *); -void __builtin_ia32_storehps(void *, __gcc_v4sf); -void __builtin_ia32_storelps(void *, __gcc_v4sf); +__gcc_v4sf __builtin_ia32_loadhps(__gcc_v4sf, const void*); +__gcc_v4sf __builtin_ia32_loadlps(__gcc_v4sf, const void*); +void __builtin_ia32_storehps(void*, __gcc_v4sf); +void __builtin_ia32_storelps(void*, __gcc_v4sf); -__gcc_v4si __builtin_ia32_loadlv4si(const __gcc_v2si *); -void __builtin_ia32_storelv4si(__gcc_v2si *, __gcc_v4si); +__gcc_v4si __builtin_ia32_loadlv4si(const __gcc_v2si*); +void __builtin_ia32_storelv4si(__gcc_v2si*, __gcc_v4si); __gcc_v4si __builtin_ia32_movqv4si(__gcc_v4si); int __builtin_ia32_comisdeq(__gcc_v2df, __gcc_v2df); @@ -274,17 +274,17 @@ __gcc_v16qi __builtin_ia32_packsswb128(__gcc_v8hi, __gcc_v8hi); __gcc_v8hi __builtin_ia32_packssdw128(__gcc_v4si, __gcc_v4si); __gcc_v16qi __builtin_ia32_packuswb128(__gcc_v8hi, __gcc_v8hi); __gcc_v8hi __builtin_ia32_pmulhuw128(__gcc_v8hi, __gcc_v8hi); -void __builtin_ia32_maskmovdqu(__gcc_v16qi, __gcc_v16qi, char *); -__gcc_v2df __builtin_ia32_loadupd(double *); -void __builtin_ia32_storeupd(double *, __gcc_v2df); -__gcc_v2df __builtin_ia32_loadhpd(__gcc_v2df, double const *); -__gcc_v2df __builtin_ia32_loadlpd(__gcc_v2df, double const *); +void __builtin_ia32_maskmovdqu(__gcc_v16qi, __gcc_v16qi, char*); +__gcc_v2df __builtin_ia32_loadupd(const double*); +void __builtin_ia32_storeupd(double*, __gcc_v2df); +__gcc_v2df __builtin_ia32_loadhpd(__gcc_v2df, const double*); +__gcc_v2df __builtin_ia32_loadlpd(__gcc_v2df, const double*); int __builtin_ia32_movmskpd(__gcc_v2df); int __builtin_ia32_pmovmskb128(__gcc_v16qi); -void __builtin_ia32_movnti(int *, int); -void __builtin_ia32_movnti64(__gcc_di *, __gcc_di); -void __builtin_ia32_movntpd(double *, __gcc_v2df); -void __builtin_ia32_movntdq(__gcc_v2di *, __gcc_v2di); +void __builtin_ia32_movnti(int*, int); +void __builtin_ia32_movnti64(long long*, long long); +void __builtin_ia32_movntpd(double*, __gcc_v2df); +void __builtin_ia32_movntdq(__gcc_v2di*, __gcc_v2di); __gcc_v4si __builtin_ia32_pshufd(__gcc_v4si, int); __gcc_v8hi __builtin_ia32_pshuflw(__gcc_v8hi, int); __gcc_v8hi __builtin_ia32_pshufhw(__gcc_v8hi, int); @@ -302,20 +302,20 @@ __gcc_v2si __builtin_ia32_cvttpd2pi(__gcc_v2df); __gcc_v2df __builtin_ia32_cvtpi2pd(__gcc_v2si); int __builtin_ia32_cvtsd2si(__gcc_v2df); int __builtin_ia32_cvttsd2si(__gcc_v2df); -__gcc_di __builtin_ia32_cvtsd2si64(__gcc_v2df); -__gcc_di __builtin_ia32_cvttsd2si64(__gcc_v2df); +long long __builtin_ia32_cvtsd2si64(__gcc_v2df); +long long __builtin_ia32_cvttsd2si64(__gcc_v2df); __gcc_v4si __builtin_ia32_cvtps2dq(__gcc_v4sf); __gcc_v2df __builtin_ia32_cvtps2pd(__gcc_v4sf); __gcc_v4si __builtin_ia32_cvttps2dq(__gcc_v4sf); __gcc_v2df __builtin_ia32_cvtsi2sd(__gcc_v2df, int); -__gcc_v2df __builtin_ia32_cvtsi642sd(__gcc_v2df, __gcc_di); +__gcc_v2df __builtin_ia32_cvtsi642sd(__gcc_v2df, long long); __gcc_v4sf __builtin_ia32_cvtsd2ss(__gcc_v4sf, __gcc_v2df); __gcc_v2df __builtin_ia32_cvtss2sd(__gcc_v2df, __gcc_v4sf); -void __builtin_ia32_clflush(const void *); -void __builtin_ia32_lfence(void); +void __builtin_ia32_clflush(const void*); +void __builtin_ia32_lfence(); void __builtin_ia32_mfence(void); -__gcc_v16qi __builtin_ia32_loaddqu(const char *); -void __builtin_ia32_storedqu(char *, __gcc_v16qi); +__gcc_v16qi __builtin_ia32_loaddqu(const char*); +void __builtin_ia32_storedqu(char*, __gcc_v16qi); __gcc_v1di __builtin_ia32_pmuludq(__gcc_v2si, __gcc_v2si); __gcc_v2di __builtin_ia32_pmuludq128(__gcc_v4si, __gcc_v4si); __gcc_v8hi __builtin_ia32_psllw128(__gcc_v8hi, __gcc_v8hi); @@ -344,13 +344,13 @@ __gcc_v2df __builtin_ia32_haddpd(__gcc_v2df, __gcc_v2df); __gcc_v4sf __builtin_ia32_haddps(__gcc_v4sf, __gcc_v4sf); __gcc_v2df __builtin_ia32_hsubpd(__gcc_v2df, __gcc_v2df); __gcc_v4sf __builtin_ia32_hsubps(__gcc_v4sf, __gcc_v4sf); -__gcc_v16qi __builtin_ia32_lddqu(char const *); -void __builtin_ia32_monitor(void *, unsigned int, unsigned int); +__gcc_v16qi __builtin_ia32_lddqu(const char*); +void __builtin_ia32_monitor(void*, unsigned int, unsigned int); __gcc_v2df __builtin_ia32_movddup(__gcc_v2df); __gcc_v4sf __builtin_ia32_movshdup(__gcc_v4sf); __gcc_v4sf __builtin_ia32_movsldup(__gcc_v4sf); void __builtin_ia32_mwait(unsigned int, unsigned int); -__gcc_v2df __builtin_ia32_loadddup(double const *); +__gcc_v2df __builtin_ia32_loadddup(double const*); __gcc_v2si __builtin_ia32_phaddd(__gcc_v2si, __gcc_v2si); __gcc_v4hi __builtin_ia32_phaddw(__gcc_v4hi, __gcc_v4hi); __gcc_v4hi __builtin_ia32_phaddsw(__gcc_v4hi, __gcc_v4hi); @@ -383,18 +383,18 @@ __gcc_v2di __builtin_ia32_palignr128(__gcc_v2di, __gcc_v2di, int); __gcc_v16qi __builtin_ia32_pabsb128(__gcc_v16qi); __gcc_v4si __builtin_ia32_pabsd128(__gcc_v4si); __gcc_v8hi __builtin_ia32_pabsw128(__gcc_v8hi); -__gcc_v2df __builtin_ia32_blendpd(__gcc_v2df, __gcc_v2df, const int); -__gcc_v4sf __builtin_ia32_blendps(__gcc_v4sf, __gcc_v4sf, const int); +__gcc_v2df __builtin_ia32_blendpd(__gcc_v2df, __gcc_v2df, int); +__gcc_v4sf __builtin_ia32_blendps(__gcc_v4sf, __gcc_v4sf, int); __gcc_v2df __builtin_ia32_blendvpd(__gcc_v2df, __gcc_v2df, __gcc_v2df); __gcc_v4sf __builtin_ia32_blendvps(__gcc_v4sf, __gcc_v4sf, __gcc_v4sf); -__gcc_v2df __builtin_ia32_dppd(__gcc_v2df, __gcc_v2df, const int); -__gcc_v4sf __builtin_ia32_dpps(__gcc_v4sf, __gcc_v4sf, const int); -__gcc_v4sf __builtin_ia32_insertps128(__gcc_v4sf, __gcc_v4sf, const int); -__gcc_v2di __builtin_ia32_movntdqa(__gcc_v2di *); -__gcc_v16qi __builtin_ia32_mpsadbw128(__gcc_v16qi, __gcc_v16qi, const int); +__gcc_v2df __builtin_ia32_dppd(__gcc_v2df, __gcc_v2df, int); +__gcc_v4sf __builtin_ia32_dpps(__gcc_v4sf, __gcc_v4sf, int); +__gcc_v4sf __builtin_ia32_insertps128(__gcc_v4sf, __gcc_v4sf, int); +__gcc_v2di __builtin_ia32_movntdqa(__gcc_v2di*); +__gcc_v16qi __builtin_ia32_mpsadbw128(__gcc_v16qi, __gcc_v16qi, int); __gcc_v8hi __builtin_ia32_packusdw128(__gcc_v4si, __gcc_v4si); __gcc_v16qi __builtin_ia32_pblendvb128(__gcc_v16qi, __gcc_v16qi, __gcc_v16qi); -__gcc_v8hi __builtin_ia32_pblendw128(__gcc_v8hi, __gcc_v8hi, const int); +__gcc_v8hi __builtin_ia32_pblendw128(__gcc_v8hi, __gcc_v8hi, int); __gcc_v2di __builtin_ia32_pcmpeqq(__gcc_v2di, __gcc_v2di); __gcc_v8hi __builtin_ia32_phminposuw128(__gcc_v8hi); __gcc_v16qi __builtin_ia32_pmaxsb128(__gcc_v16qi, __gcc_v16qi); @@ -422,10 +422,10 @@ __gcc_v4si __builtin_ia32_pmulld128(__gcc_v4si, __gcc_v4si); int __builtin_ia32_ptestc128(__gcc_v2di, __gcc_v2di); int __builtin_ia32_ptestnzc128(__gcc_v2di, __gcc_v2di); int __builtin_ia32_ptestz128(__gcc_v2di, __gcc_v2di); -__gcc_v2df __builtin_ia32_roundpd(__gcc_v2df, const int); -__gcc_v4sf __builtin_ia32_roundps(__gcc_v4sf, const int); -__gcc_v2df __builtin_ia32_roundsd(__gcc_v2df, __gcc_v2df, const int); -__gcc_v4sf __builtin_ia32_roundss(__gcc_v4sf, __gcc_v4sf, const int); +__gcc_v2df __builtin_ia32_roundpd(__gcc_v2df, int); +__gcc_v4sf __builtin_ia32_roundps(__gcc_v4sf, int); +__gcc_v2df __builtin_ia32_roundsd(__gcc_v2df, __gcc_v2df, int); +__gcc_v4sf __builtin_ia32_roundss(__gcc_v4sf, __gcc_v4sf, int); int __builtin_ia32_vec_ext___gcc_v16qi(__gcc_v16qi, const int); float __builtin_ia32_vec_ext___gcc_v4sf(__gcc_v4sf, const int); int __builtin_ia32_vec_ext___gcc_v4si(__gcc_v4si, const int); @@ -445,31 +445,31 @@ int __builtin_ia32_pcmpistrio128(__gcc_v16qi, __gcc_v16qi, const int); int __builtin_ia32_pcmpistris128(__gcc_v16qi, __gcc_v16qi, const int); int __builtin_ia32_pcmpistriz128(__gcc_v16qi, __gcc_v16qi, const int); __gcc_v2di __builtin_ia32_pcmpgtq(__gcc_v2di, __gcc_v2di); -unsigned int __builtin_ia32_crc32qi(unsigned int, unsigned char); -unsigned int __builtin_ia32_crc32hi(unsigned int, unsigned short); -unsigned int __builtin_ia32_crc32si(unsigned int, unsigned int); +unsigned __builtin_ia32_crc32qi(unsigned, unsigned char); +unsigned __builtin_ia32_crc32hi(unsigned, unsigned short); +unsigned __builtin_ia32_crc32si(unsigned, unsigned); unsigned long long __builtin_ia32_crc32di(unsigned long long, unsigned long long); int __builtin_popcount(unsigned int); int __builtin_popcountl(unsigned long); int __builtin_popcountll(unsigned long long); -__gcc_v4df __builtin_ia32_addpd256(__gcc_v4df,__gcc_v4df); -__gcc_v8sf __builtin_ia32_addps256(__gcc_v8sf,__gcc_v8sf); -__gcc_v4df __builtin_ia32_addsubpd256(__gcc_v4df,__gcc_v4df); -__gcc_v8sf __builtin_ia32_addsubps256(__gcc_v8sf,__gcc_v8sf); -__gcc_v4df __builtin_ia32_andnpd256(__gcc_v4df,__gcc_v4df); -__gcc_v8sf __builtin_ia32_andnps256(__gcc_v8sf,__gcc_v8sf); -__gcc_v4df __builtin_ia32_andpd256(__gcc_v4df,__gcc_v4df); -__gcc_v8sf __builtin_ia32_andps256(__gcc_v8sf,__gcc_v8sf); -__gcc_v4df __builtin_ia32_blendpd256(__gcc_v4df,__gcc_v4df,int); -__gcc_v8sf __builtin_ia32_blendps256(__gcc_v8sf,__gcc_v8sf,int); -__gcc_v4df __builtin_ia32_blendvpd256(__gcc_v4df,__gcc_v4df,__gcc_v4df); -__gcc_v8sf __builtin_ia32_blendvps256(__gcc_v8sf,__gcc_v8sf,__gcc_v8sf); -__gcc_v2df __builtin_ia32_cmppd(__gcc_v2df,__gcc_v2df,int); -__gcc_v4df __builtin_ia32_cmppd256(__gcc_v4df,__gcc_v4df,int); -__gcc_v4sf __builtin_ia32_cmpps(__gcc_v4sf,__gcc_v4sf,int); -__gcc_v8sf __builtin_ia32_cmpps256(__gcc_v8sf,__gcc_v8sf,int); -__gcc_v2df __builtin_ia32_cmpsd(__gcc_v2df,__gcc_v2df,int); -__gcc_v4sf __builtin_ia32_cmpss(__gcc_v4sf,__gcc_v4sf,int); +__gcc_v4df __builtin_ia32_addpd256(__gcc_v4df, __gcc_v4df); +__gcc_v8sf __builtin_ia32_addps256(__gcc_v8sf, __gcc_v8sf); +__gcc_v4df __builtin_ia32_addsubpd256(__gcc_v4df, __gcc_v4df); +__gcc_v8sf __builtin_ia32_addsubps256(__gcc_v8sf, __gcc_v8sf); +__gcc_v4df __builtin_ia32_andnpd256(__gcc_v4df, __gcc_v4df); +__gcc_v8sf __builtin_ia32_andnps256(__gcc_v8sf, __gcc_v8sf); +__gcc_v4df __builtin_ia32_andpd256(__gcc_v4df, __gcc_v4df); +__gcc_v8sf __builtin_ia32_andps256(__gcc_v8sf, __gcc_v8sf); +__gcc_v4df __builtin_ia32_blendpd256(__gcc_v4df, __gcc_v4df, int); +__gcc_v8sf __builtin_ia32_blendps256(__gcc_v8sf, __gcc_v8sf, int); +__gcc_v4df __builtin_ia32_blendvpd256(__gcc_v4df, __gcc_v4df, __gcc_v4df); +__gcc_v8sf __builtin_ia32_blendvps256(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf); +__gcc_v2df __builtin_ia32_cmppd(__gcc_v2df, __gcc_v2df, int); +__gcc_v4df __builtin_ia32_cmppd256(__gcc_v4df, __gcc_v4df, int); +__gcc_v4sf __builtin_ia32_cmpps(__gcc_v4sf, __gcc_v4sf, int); +__gcc_v8sf __builtin_ia32_cmpps256(__gcc_v8sf, __gcc_v8sf, int); +__gcc_v2df __builtin_ia32_cmpsd(__gcc_v2df, __gcc_v2df, int); +__gcc_v4sf __builtin_ia32_cmpss(__gcc_v4sf, __gcc_v4sf, int); __gcc_v4df __builtin_ia32_cvtdq2pd256(__gcc_v4si); __gcc_v8sf __builtin_ia32_cvtdq2ps256(__gcc_v8si); __gcc_v4si __builtin_ia32_cvtpd2dq256(__gcc_v4df); @@ -478,38 +478,38 @@ __gcc_v8si __builtin_ia32_cvtps2dq256(__gcc_v8sf); __gcc_v4df __builtin_ia32_cvtps2pd256(__gcc_v4sf); __gcc_v4si __builtin_ia32_cvttpd2dq256(__gcc_v4df); __gcc_v8si __builtin_ia32_cvttps2dq256(__gcc_v8sf); -__gcc_v4df __builtin_ia32_divpd256(__gcc_v4df,__gcc_v4df); -__gcc_v8sf __builtin_ia32_divps256(__gcc_v8sf,__gcc_v8sf); -__gcc_v8sf __builtin_ia32_dpps256(__gcc_v8sf,__gcc_v8sf,int); -__gcc_v4df __builtin_ia32_haddpd256(__gcc_v4df,__gcc_v4df); -__gcc_v8sf __builtin_ia32_haddps256(__gcc_v8sf,__gcc_v8sf); -__gcc_v4df __builtin_ia32_hsubpd256(__gcc_v4df,__gcc_v4df); -__gcc_v8sf __builtin_ia32_hsubps256(__gcc_v8sf,__gcc_v8sf); -__gcc_v32qi __builtin_ia32_lddqu256(const char *); -__gcc_v32qi __builtin_ia32_loaddqu256(const char *); -__gcc_v4df __builtin_ia32_loadupd256(const double *); -__gcc_v8sf __builtin_ia32_loadups256(const float *); -__gcc_v2df __builtin_ia32_maskloadpd(const __gcc_v2df *,__gcc_v2df); -__gcc_v4df __builtin_ia32_maskloadpd256(const __gcc_v4df *,__gcc_v4df); -__gcc_v4sf __builtin_ia32_maskloadps(const __gcc_v4sf *,__gcc_v4sf); -__gcc_v8sf __builtin_ia32_maskloadps256(const __gcc_v8sf *,__gcc_v8sf); -void __builtin_ia32_maskstorepd(__gcc_v2df *,__gcc_v2df,__gcc_v2df); -void __builtin_ia32_maskstorepd256(__gcc_v4df *,__gcc_v4df,__gcc_v4df); -void __builtin_ia32_maskstoreps(__gcc_v4sf *,__gcc_v4sf,__gcc_v4sf); -void __builtin_ia32_maskstoreps256(__gcc_v8sf *,__gcc_v8sf,__gcc_v8sf); -__gcc_v4df __builtin_ia32_maxpd256(__gcc_v4df,__gcc_v4df); -__gcc_v8sf __builtin_ia32_maxps256(__gcc_v8sf,__gcc_v8sf); -__gcc_v4df __builtin_ia32_minpd256(__gcc_v4df,__gcc_v4df); -__gcc_v8sf __builtin_ia32_minps256(__gcc_v8sf,__gcc_v8sf); +__gcc_v4df __builtin_ia32_divpd256(__gcc_v4df, __gcc_v4df); +__gcc_v8sf __builtin_ia32_divps256(__gcc_v8sf, __gcc_v8sf); +__gcc_v8sf __builtin_ia32_dpps256(__gcc_v8sf, __gcc_v8sf, int); +__gcc_v4df __builtin_ia32_haddpd256(__gcc_v4df, __gcc_v4df); +__gcc_v8sf __builtin_ia32_haddps256(__gcc_v8sf, __gcc_v8sf); +__gcc_v4df __builtin_ia32_hsubpd256(__gcc_v4df, __gcc_v4df); +__gcc_v8sf __builtin_ia32_hsubps256(__gcc_v8sf, __gcc_v8sf); +__gcc_v32qi __builtin_ia32_lddqu256(const char*); +__gcc_v32qi __builtin_ia32_loaddqu256(const char*); +__gcc_v4df __builtin_ia32_loadupd256(const double*); +__gcc_v8sf __builtin_ia32_loadups256(const float*); +__gcc_v2df __builtin_ia32_maskloadpd(const __gcc_v2df*, __gcc_v2di); +__gcc_v4df __builtin_ia32_maskloadpd256(const __gcc_v4df*, __gcc_v4di); +__gcc_v4sf __builtin_ia32_maskloadps(const __gcc_v4sf*, __gcc_v4si); +__gcc_v8sf __builtin_ia32_maskloadps256(const __gcc_v8sf*, __gcc_v8si); +void __builtin_ia32_maskstorepd(__gcc_v2df*, __gcc_v2di, __gcc_v2df); +void __builtin_ia32_maskstorepd256(__gcc_v4df*, __gcc_v4di, __gcc_v4df); +void __builtin_ia32_maskstoreps(__gcc_v4sf*, __gcc_v4si, __gcc_v4sf); +void __builtin_ia32_maskstoreps256(__gcc_v8sf*, __gcc_v8si, __gcc_v8sf); +__gcc_v4df __builtin_ia32_maxpd256(__gcc_v4df, __gcc_v4df); +__gcc_v8sf __builtin_ia32_maxps256(__gcc_v8sf, __gcc_v8sf); +__gcc_v4df __builtin_ia32_minpd256(__gcc_v4df, __gcc_v4df); +__gcc_v8sf __builtin_ia32_minps256(__gcc_v8sf, __gcc_v8sf); __gcc_v4df __builtin_ia32_movddup256(__gcc_v4df); int __builtin_ia32_movmskpd256(__gcc_v4df); int __builtin_ia32_movmskps256(__gcc_v8sf); __gcc_v8sf __builtin_ia32_movshdup256(__gcc_v8sf); __gcc_v8sf __builtin_ia32_movsldup256(__gcc_v8sf); -__gcc_v4df __builtin_ia32_mulpd256(__gcc_v4df,__gcc_v4df); -__gcc_v8sf __builtin_ia32_mulps256(__gcc_v8sf,__gcc_v8sf); -__gcc_v4df __builtin_ia32_orpd256(__gcc_v4df,__gcc_v4df); -__gcc_v8sf __builtin_ia32_orps256(__gcc_v8sf,__gcc_v8sf); +__gcc_v4df __builtin_ia32_mulpd256(__gcc_v4df, __gcc_v4df); +__gcc_v8sf __builtin_ia32_mulps256(__gcc_v8sf, __gcc_v8sf); +__gcc_v4df __builtin_ia32_orpd256(__gcc_v4df, __gcc_v4df); +__gcc_v8sf __builtin_ia32_orps256(__gcc_v8sf, __gcc_v8sf); __gcc_v2df __builtin_ia32_pd_pd256(__gcc_v4df); __gcc_v4df __builtin_ia32_pd256_pd(__gcc_v2df); __gcc_v4sf __builtin_ia32_ps_ps256(__gcc_v8sf); @@ -518,52 +518,52 @@ int __builtin_ia32_ptestc256(__gcc_v4di,__gcc_v4di,...); int __builtin_ia32_ptestnzc256(__gcc_v4di,__gcc_v4di,...); int __builtin_ia32_ptestz256(__gcc_v4di,__gcc_v4di,...); __gcc_v8sf __builtin_ia32_rcpps256(__gcc_v8sf); -__gcc_v4df __builtin_ia32_roundpd256(__gcc_v4df,int); -__gcc_v8sf __builtin_ia32_roundps256(__gcc_v8sf,int); +__gcc_v4df __builtin_ia32_roundpd256(__gcc_v4df, int); +__gcc_v8sf __builtin_ia32_roundps256(__gcc_v8sf, int); __gcc_v8sf __builtin_ia32_rsqrtps_nr256(__gcc_v8sf); __gcc_v8sf __builtin_ia32_rsqrtps256(__gcc_v8sf); -__gcc_v4df __builtin_ia32_shufpd256(__gcc_v4df,__gcc_v4df,int); -__gcc_v8sf __builtin_ia32_shufps256(__gcc_v8sf,__gcc_v8sf,int); +__gcc_v4df __builtin_ia32_shufpd256(__gcc_v4df, __gcc_v4df, int); +__gcc_v8sf __builtin_ia32_shufps256(__gcc_v8sf, __gcc_v8sf, int); __gcc_v4si __builtin_ia32_si_si256(__gcc_v8si); __gcc_v8si __builtin_ia32_si256_si(__gcc_v4si); __gcc_v4df __builtin_ia32_sqrtpd256(__gcc_v4df); __gcc_v8sf __builtin_ia32_sqrtps_nr256(__gcc_v8sf); __gcc_v8sf __builtin_ia32_sqrtps256(__gcc_v8sf); -void __builtin_ia32_storedqu256(char *,__gcc_v32qi); -void __builtin_ia32_storeupd256(double *,__gcc_v4df); -void __builtin_ia32_storeups256(float *,__gcc_v8sf); -__gcc_v4df __builtin_ia32_subpd256(__gcc_v4df,__gcc_v4df); -__gcc_v8sf __builtin_ia32_subps256(__gcc_v8sf,__gcc_v8sf); -__gcc_v4df __builtin_ia32_unpckhpd256(__gcc_v4df,__gcc_v4df); -__gcc_v8sf __builtin_ia32_unpckhps256(__gcc_v8sf,__gcc_v8sf); -__gcc_v4df __builtin_ia32_unpcklpd256(__gcc_v4df,__gcc_v4df); -__gcc_v8sf __builtin_ia32_unpcklps256(__gcc_v8sf,__gcc_v8sf); -__gcc_v4df __builtin_ia32_vbroadcastf128_pd256(const __gcc_v2df *); -__gcc_v8sf __builtin_ia32_vbroadcastf128_ps256(const __gcc_v4sf *); -__gcc_v4df __builtin_ia32_vbroadcastsd256(const double *); -__gcc_v4sf __builtin_ia32_vbroadcastss(const float *); -__gcc_v8sf __builtin_ia32_vbroadcastss256(const float *); -__gcc_v2df __builtin_ia32_vextractf128_pd256(__gcc_v4df,int); -__gcc_v4sf __builtin_ia32_vextractf128_ps256(__gcc_v8sf,int); -__gcc_v4si __builtin_ia32_vextractf128_si256(__gcc_v8si,int); -__gcc_v4df __builtin_ia32_vinsertf128_pd256(__gcc_v4df,__gcc_v2df,int); -__gcc_v8sf __builtin_ia32_vinsertf128_ps256(__gcc_v8sf,__gcc_v4sf,int); -__gcc_v8si __builtin_ia32_vinsertf128_si256(__gcc_v8si,__gcc_v4si,int); -__gcc_v4df __builtin_ia32_vperm2f128_pd256(__gcc_v4df,__gcc_v4df,int); -__gcc_v8sf __builtin_ia32_vperm2f128_ps256(__gcc_v8sf,__gcc_v8sf,int); -__gcc_v8si __builtin_ia32_vperm2f128_si256(__gcc_v8si,__gcc_v8si,int); +void __builtin_ia32_storedqu256(char*, __gcc_v32qi); +void __builtin_ia32_storeupd256(double*, __gcc_v4df); +void __builtin_ia32_storeups256(float*, __gcc_v8sf); +__gcc_v4df __builtin_ia32_subpd256(__gcc_v4df, __gcc_v4df); +__gcc_v8sf __builtin_ia32_subps256(__gcc_v8sf, __gcc_v8sf); +__gcc_v4df __builtin_ia32_unpckhpd256(__gcc_v4df, __gcc_v4df); +__gcc_v8sf __builtin_ia32_unpckhps256(__gcc_v8sf, __gcc_v8sf); +__gcc_v4df __builtin_ia32_unpcklpd256(__gcc_v4df, __gcc_v4df); +__gcc_v8sf __builtin_ia32_unpcklps256(__gcc_v8sf, __gcc_v8sf); +__gcc_v4df __builtin_ia32_vbroadcastf128_pd256(const __gcc_v2df*); +__gcc_v8sf __builtin_ia32_vbroadcastf128_ps256(const __gcc_v4sf*); +__gcc_v4df __builtin_ia32_vbroadcastsd256(const double*); +__gcc_v4sf __builtin_ia32_vbroadcastss(const float*); +__gcc_v8sf __builtin_ia32_vbroadcastss256(const float*); +__gcc_v2df __builtin_ia32_vextractf128_pd256(__gcc_v4df, int); +__gcc_v4sf __builtin_ia32_vextractf128_ps256(__gcc_v8sf, int); +__gcc_v4si __builtin_ia32_vextractf128_si256(__gcc_v8si, int); +__gcc_v4df __builtin_ia32_vinsertf128_pd256(__gcc_v4df, __gcc_v2df, int); +__gcc_v8sf __builtin_ia32_vinsertf128_ps256(__gcc_v8sf, __gcc_v4sf, int); +__gcc_v8si __builtin_ia32_vinsertf128_si256(__gcc_v8si, __gcc_v4si, int); +__gcc_v4df __builtin_ia32_vperm2f128_pd256(__gcc_v4df, __gcc_v4df, int); +__gcc_v8sf __builtin_ia32_vperm2f128_ps256(__gcc_v8sf, __gcc_v8sf, int); +__gcc_v8si __builtin_ia32_vperm2f128_si256(__gcc_v8si, __gcc_v8si, int); __gcc_v2df __builtin_ia32_vpermil2pd(__gcc_v2df,__gcc_v2df,__gcc_v2di,int); __gcc_v4df __builtin_ia32_vpermil2pd256(__gcc_v4df,__gcc_v4df,__gcc_v4di,int); __gcc_v4sf __builtin_ia32_vpermil2ps(__gcc_v4sf,__gcc_v4sf,__gcc_v4si,int); __gcc_v8sf __builtin_ia32_vpermil2ps256(__gcc_v8sf,__gcc_v8sf,__gcc_v8si,int); -__gcc_v2df __builtin_ia32_vpermilpd(__gcc_v2df,int); -__gcc_v4df __builtin_ia32_vpermilpd256(__gcc_v4df,int); -__gcc_v4sf __builtin_ia32_vpermilps(__gcc_v4sf,int); -__gcc_v8sf __builtin_ia32_vpermilps256(__gcc_v8sf,int); -__gcc_v2df __builtin_ia32_vpermilvarpd(__gcc_v2df,__gcc_v2di); -__gcc_v4df __builtin_ia32_vpermilvarpd256(__gcc_v4df,__gcc_v4di); -__gcc_v4sf __builtin_ia32_vpermilvarps(__gcc_v4sf,__gcc_v4si); -__gcc_v8sf __builtin_ia32_vpermilvarps256(__gcc_v8sf,__gcc_v8si); +__gcc_v2df __builtin_ia32_vpermilpd(__gcc_v2df, int); +__gcc_v4df __builtin_ia32_vpermilpd256(__gcc_v4df, int); +__gcc_v4sf __builtin_ia32_vpermilps(__gcc_v4sf, int); +__gcc_v8sf __builtin_ia32_vpermilps256(__gcc_v8sf, int); +__gcc_v2df __builtin_ia32_vpermilvarpd(__gcc_v2df, __gcc_v2di); +__gcc_v4df __builtin_ia32_vpermilvarpd256(__gcc_v4df, __gcc_v4di); +__gcc_v4sf __builtin_ia32_vpermilvarps(__gcc_v4sf, __gcc_v4si); +__gcc_v8sf __builtin_ia32_vpermilvarps256(__gcc_v8sf, __gcc_v8si); int __builtin_ia32_vtestcpd(__gcc_v2df,__gcc_v2df,...); int __builtin_ia32_vtestcpd256(__gcc_v4df,__gcc_v4df,...); int __builtin_ia32_vtestcps(__gcc_v4sf,__gcc_v4sf,...); @@ -576,61 +576,61 @@ int __builtin_ia32_vtestzpd(__gcc_v2df,__gcc_v2df,...); int __builtin_ia32_vtestzpd256(__gcc_v4df,__gcc_v4df,...); int __builtin_ia32_vtestzps(__gcc_v4sf,__gcc_v4sf,...); int __builtin_ia32_vtestzps256(__gcc_v8sf,__gcc_v8sf,...); -void __builtin_ia32_vzeroall(void); -void __builtin_ia32_vzeroupper(void); -__gcc_v4df __builtin_ia32_xorpd256(__gcc_v4df,__gcc_v4df); -__gcc_v8sf __builtin_ia32_xorps256(__gcc_v8sf,__gcc_v8sf); -__gcc_v32qi __builtin_ia32_mpsadbw256(__gcc_v32qi,__gcc_v32qi,int); +void __builtin_ia32_vzeroall(); +void __builtin_ia32_vzeroupper(); +__gcc_v4df __builtin_ia32_xorpd256(__gcc_v4df, __gcc_v4df); +__gcc_v8sf __builtin_ia32_xorps256(__gcc_v8sf, __gcc_v8sf); +__gcc_v32qi __builtin_ia32_mpsadbw256(__gcc_v32qi, __gcc_v32qi, int); __gcc_v32qi __builtin_ia32_pabsb256(__gcc_v32qi); __gcc_v16hi __builtin_ia32_pabsw256(__gcc_v16hi); __gcc_v8si __builtin_ia32_pabsd256(__gcc_v8si); -__gcc_v16hi __builtin_ia32_packssdw256(__gcc_v8si,__gcc_v8si); -__gcc_v32qi __builtin_ia32_packsswb256(__gcc_v16hi,__gcc_v16hi); -__gcc_v16hi __builtin_ia32_packusdw256(__gcc_v8si,__gcc_v8si); -__gcc_v32qi __builtin_ia32_packuswb256(__gcc_v16hi,__gcc_v16hi); -__gcc_v32qi __builtin_ia32_paddb256(__gcc_v32qi,__gcc_v32qi); -__gcc_v16hi __builtin_ia32_paddw256(__gcc_v16hi,__gcc_v16hi); -__gcc_v8si __builtin_ia32_paddd256(__gcc_v8si,__gcc_v8si); -__gcc_v4di __builtin_ia32_paddq256(__gcc_v4di,__gcc_v4di); -__gcc_v32qi __builtin_ia32_paddsb256(__gcc_v32qi,__gcc_v32qi); -__gcc_v16hi __builtin_ia32_paddsw256(__gcc_v16hi,__gcc_v16hi); -__gcc_v32qi __builtin_ia32_paddusb256(__gcc_v32qi,__gcc_v32qi); -__gcc_v16hi __builtin_ia32_paddusw256(__gcc_v16hi,__gcc_v16hi); +__gcc_v16hi __builtin_ia32_packssdw256(__gcc_v8si, __gcc_v8si); +__gcc_v32qi __builtin_ia32_packsswb256(__gcc_v16hi, __gcc_v16hi); +__gcc_v16hi __builtin_ia32_packusdw256(__gcc_v8si, __gcc_v8si); +__gcc_v32qi __builtin_ia32_packuswb256(__gcc_v16hi, __gcc_v16hi); +__gcc_v32qi __builtin_ia32_paddb256(__gcc_v32qi, __gcc_v32qi); +__gcc_v16hi __builtin_ia32_paddw256(__gcc_v16hi, __gcc_v16hi); +__gcc_v8si __builtin_ia32_paddd256(__gcc_v8si, __gcc_v8si); +__gcc_v4di __builtin_ia32_paddq256(__gcc_v4di, __gcc_v4di); +__gcc_v32qi __builtin_ia32_paddsb256(__gcc_v32qi, __gcc_v32qi); +__gcc_v16hi __builtin_ia32_paddsw256(__gcc_v16hi, __gcc_v16hi); +__gcc_v32qi __builtin_ia32_paddusb256(__gcc_v32qi, __gcc_v32qi); +__gcc_v16hi __builtin_ia32_paddusw256(__gcc_v16hi, __gcc_v16hi); __gcc_v4di __builtin_ia32_palignr256(__gcc_v4di,__gcc_v4di,int); -__gcc_v4di __builtin_ia32_andsi256(__gcc_v4di,__gcc_v4di); -__gcc_v4di __builtin_ia32_andnotsi256(__gcc_v4di,__gcc_v4di); -__gcc_v32qi __builtin_ia32_pavgb256(__gcc_v32qi,__gcc_v32qi); -__gcc_v16hi __builtin_ia32_pavgw256(__gcc_v16hi,__gcc_v16hi); -__gcc_v32qi __builtin_ia32_pblendvb256(__gcc_v32qi,__gcc_v32qi,__gcc_v32qi); -__gcc_v16hi __builtin_ia32_pblendw256(__gcc_v16hi,__gcc_v16hi,int); -__gcc_v32qi __builtin_ia32_pcmpeqb256(__gcc_v32qi,__gcc_v32qi); -__gcc_v16hi __builtin_ia32_pcmpeqw256(__gcc_v16hi,__gcc_v16hi); -__gcc_v8si __builtin_ia32_pcmpeqd256(__gcc_v8si,__gcc_v8si); -__gcc_v4di __builtin_ia32_pcmpeqq256(__gcc_v4di,__gcc_v4di); -__gcc_v32qi __builtin_ia32_pcmpgtb256(__gcc_v32qi,__gcc_v32qi); -__gcc_v16hi __builtin_ia32_pcmpgtw256(__gcc_v16hi,__gcc_v16hi); -__gcc_v8si __builtin_ia32_pcmpgtd256(__gcc_v8si,__gcc_v8si); -__gcc_v4di __builtin_ia32_pcmpgtq256(__gcc_v4di,__gcc_v4di); -__gcc_v16hi __builtin_ia32_phaddw256(__gcc_v16hi,__gcc_v16hi); -__gcc_v8si __builtin_ia32_phaddd256(__gcc_v8si,__gcc_v8si); -__gcc_v16hi __builtin_ia32_phaddsw256(__gcc_v16hi,__gcc_v16hi); -__gcc_v16hi __builtin_ia32_phsubw256(__gcc_v16hi,__gcc_v16hi); -__gcc_v8si __builtin_ia32_phsubd256(__gcc_v8si,__gcc_v8si); -__gcc_v16hi __builtin_ia32_phsubsw256(__gcc_v16hi,__gcc_v16hi); -__gcc_v32qi __builtin_ia32_pmaddubsw256(__gcc_v32qi,__gcc_v32qi); -__gcc_v16hi __builtin_ia32_pmaddwd256(__gcc_v16hi,__gcc_v16hi); -__gcc_v32qi __builtin_ia32_pmaxsb256(__gcc_v32qi,__gcc_v32qi); -__gcc_v16hi __builtin_ia32_pmaxsw256(__gcc_v16hi,__gcc_v16hi); -__gcc_v8si __builtin_ia32_pmaxsd256(__gcc_v8si,__gcc_v8si); -__gcc_v32qi __builtin_ia32_pmaxub256(__gcc_v32qi,__gcc_v32qi); -__gcc_v16hi __builtin_ia32_pmaxuw256(__gcc_v16hi,__gcc_v16hi); -__gcc_v8si __builtin_ia32_pmaxud256(__gcc_v8si,__gcc_v8si); -__gcc_v32qi __builtin_ia32_pminsb256(__gcc_v32qi,__gcc_v32qi); -__gcc_v16hi __builtin_ia32_pminsw256(__gcc_v16hi,__gcc_v16hi); -__gcc_v8si __builtin_ia32_pminsd256(__gcc_v8si,__gcc_v8si); -__gcc_v32qi __builtin_ia32_pminub256(__gcc_v32qi,__gcc_v32qi); -__gcc_v16hi __builtin_ia32_pminuw256(__gcc_v16hi,__gcc_v16hi); -__gcc_v8si __builtin_ia32_pminud256(__gcc_v8si,__gcc_v8si); +__gcc_v4di __builtin_ia32_andsi256(__gcc_v4di, __gcc_v4di); +__gcc_v4di __builtin_ia32_andnotsi256(__gcc_v4di, __gcc_v4di); +__gcc_v32qi __builtin_ia32_pavgb256(__gcc_v32qi, __gcc_v32qi); +__gcc_v16hi __builtin_ia32_pavgw256(__gcc_v16hi, __gcc_v16hi); +__gcc_v32qi __builtin_ia32_pblendvb256(__gcc_v32qi, __gcc_v32qi, __gcc_v32qi); +__gcc_v16hi __builtin_ia32_pblendw256(__gcc_v16hi, __gcc_v16hi, int); +__gcc_v32qi __builtin_ia32_pcmpeqb256(__gcc_v32qi, __gcc_v32qi); +__gcc_v16hi __builtin_ia32_pcmpeqw256(__gcc_v16hi, __gcc_v16hi); +__gcc_v8si __builtin_ia32_pcmpeqd256(__gcc_v8si, __gcc_v8si); +__gcc_v4di __builtin_ia32_pcmpeqq256(__gcc_v4di, __gcc_v4di); +__gcc_v32qi __builtin_ia32_pcmpgtb256(__gcc_v32qi, __gcc_v32qi); +__gcc_v16hi __builtin_ia32_pcmpgtw256(__gcc_v16hi, __gcc_v16hi); +__gcc_v8si __builtin_ia32_pcmpgtd256(__gcc_v8si, __gcc_v8si); +__gcc_v4di __builtin_ia32_pcmpgtq256(__gcc_v4di, __gcc_v4di); +__gcc_v16hi __builtin_ia32_phaddw256(__gcc_v16hi, __gcc_v16hi); +__gcc_v8si __builtin_ia32_phaddd256(__gcc_v8si, __gcc_v8si); +__gcc_v16hi __builtin_ia32_phaddsw256(__gcc_v16hi, __gcc_v16hi); +__gcc_v16hi __builtin_ia32_phsubw256(__gcc_v16hi, __gcc_v16hi); +__gcc_v8si __builtin_ia32_phsubd256(__gcc_v8si, __gcc_v8si); +__gcc_v16hi __builtin_ia32_phsubsw256(__gcc_v16hi, __gcc_v16hi); +__gcc_v16hi __builtin_ia32_pmaddubsw256(__gcc_v32qi, __gcc_v32qi); +__gcc_v8si __builtin_ia32_pmaddwd256(__gcc_v16hi, __gcc_v16hi); +__gcc_v32qi __builtin_ia32_pmaxsb256(__gcc_v32qi, __gcc_v32qi); +__gcc_v16hi __builtin_ia32_pmaxsw256(__gcc_v16hi, __gcc_v16hi); +__gcc_v8si __builtin_ia32_pmaxsd256(__gcc_v8si, __gcc_v8si); +__gcc_v32qi __builtin_ia32_pmaxub256(__gcc_v32qi, __gcc_v32qi); +__gcc_v16hi __builtin_ia32_pmaxuw256(__gcc_v16hi, __gcc_v16hi); +__gcc_v8si __builtin_ia32_pmaxud256(__gcc_v8si, __gcc_v8si); +__gcc_v32qi __builtin_ia32_pminsb256(__gcc_v32qi, __gcc_v32qi); +__gcc_v16hi __builtin_ia32_pminsw256(__gcc_v16hi, __gcc_v16hi); +__gcc_v8si __builtin_ia32_pminsd256(__gcc_v8si, __gcc_v8si); +__gcc_v32qi __builtin_ia32_pminub256(__gcc_v32qi, __gcc_v32qi); +__gcc_v16hi __builtin_ia32_pminuw256(__gcc_v16hi, __gcc_v16hi); +__gcc_v8si __builtin_ia32_pminud256(__gcc_v8si, __gcc_v8si); int __builtin_ia32_pmovmskb256(__gcc_v32qi); __gcc_v16hi __builtin_ia32_pmovsxbw256(__gcc_v16qi); __gcc_v8si __builtin_ia32_pmovsxbd256(__gcc_v16qi); @@ -644,22 +644,22 @@ __gcc_v4di __builtin_ia32_pmovzxbq256(__gcc_v16qi); __gcc_v8si __builtin_ia32_pmovzxwd256(__gcc_v8hi); __gcc_v4di __builtin_ia32_pmovzxwq256(__gcc_v8hi); __gcc_v4di __builtin_ia32_pmovzxdq256(__gcc_v4si); -__gcc_v4di __builtin_ia32_pmuldq256(__gcc_v8si,__gcc_v8si); +__gcc_v4di __builtin_ia32_pmuldq256(__gcc_v8si, __gcc_v8si); __gcc_v16hi __builtin_ia32_pmulhrsw256(__gcc_v16hi, __gcc_v16hi); -__gcc_v16hi __builtin_ia32_pmulhuw256(__gcc_v16hi,__gcc_v16hi); -__gcc_v16hi __builtin_ia32_pmulhw256(__gcc_v16hi,__gcc_v16hi); -__gcc_v16hi __builtin_ia32_pmullw256(__gcc_v16hi,__gcc_v16hi); -__gcc_v8si __builtin_ia32_pmulld256(__gcc_v8si,__gcc_v8si); -__gcc_v4di __builtin_ia32_pmuludq256(__gcc_v8si,__gcc_v8si); -__gcc_v4di __builtin_ia32_por256(__gcc_v4di,__gcc_v4di); -__gcc_v16hi __builtin_ia32_psadbw256(__gcc_v32qi,__gcc_v32qi); -__gcc_v32qi __builtin_ia32_pshufb256(__gcc_v32qi,__gcc_v32qi); -__gcc_v8si __builtin_ia32_pshufd256(__gcc_v8si,int); -__gcc_v16hi __builtin_ia32_pshufhw256(__gcc_v16hi,int); -__gcc_v16hi __builtin_ia32_pshuflw256(__gcc_v16hi,int); -__gcc_v32qi __builtin_ia32_psignb256(__gcc_v32qi,__gcc_v32qi); -__gcc_v16hi __builtin_ia32_psignw256(__gcc_v16hi,__gcc_v16hi); -__gcc_v8si __builtin_ia32_psignd256(__gcc_v8si,__gcc_v8si); +__gcc_v16hi __builtin_ia32_pmulhuw256(__gcc_v16hi, __gcc_v16hi); +__gcc_v16hi __builtin_ia32_pmulhw256(__gcc_v16hi, __gcc_v16hi); +__gcc_v16hi __builtin_ia32_pmullw256(__gcc_v16hi, __gcc_v16hi); +__gcc_v8si __builtin_ia32_pmulld256(__gcc_v8si, __gcc_v8si); +__gcc_v4di __builtin_ia32_pmuludq256(__gcc_v8si, __gcc_v8si); +__gcc_v4di __builtin_ia32_por256(__gcc_v4di, __gcc_v4di); +__gcc_v16hi __builtin_ia32_psadbw256(__gcc_v32qi, __gcc_v32qi); +__gcc_v32qi __builtin_ia32_pshufb256(__gcc_v32qi, __gcc_v32qi); +__gcc_v8si __builtin_ia32_pshufd256(__gcc_v8si, int); +__gcc_v16hi __builtin_ia32_pshufhw256(__gcc_v16hi, int); +__gcc_v16hi __builtin_ia32_pshuflw256(__gcc_v16hi, int); +__gcc_v32qi __builtin_ia32_psignb256(__gcc_v32qi, __gcc_v32qi); +__gcc_v16hi __builtin_ia32_psignw256(__gcc_v16hi, __gcc_v16hi); +__gcc_v8si __builtin_ia32_psignd256(__gcc_v8si, __gcc_v8si); __gcc_v4di __builtin_ia32_pslldqi256(__gcc_v4di,int); __gcc_v16hi __builtin_ia32_psllwi256(__gcc_v16hi,int); __gcc_v16hi __builtin_ia32_psllw256(__gcc_v16hi,__gcc_v8hi); @@ -678,30 +678,30 @@ __gcc_v8si __builtin_ia32_psrldi256(__gcc_v8si,int); __gcc_v8si __builtin_ia32_psrld256(__gcc_v8si,__gcc_v4si); __gcc_v4di __builtin_ia32_psrlqi256(__gcc_v4di,int); __gcc_v4di __builtin_ia32_psrlq256(__gcc_v4di,__gcc_v2di); -__gcc_v32qi __builtin_ia32_psubb256(__gcc_v32qi,__gcc_v32qi); -__gcc_v32hi __builtin_ia32_psubw256(__gcc_v16hi,__gcc_v16hi); -__gcc_v8si __builtin_ia32_psubd256(__gcc_v8si,__gcc_v8si); -__gcc_v4di __builtin_ia32_psubq256(__gcc_v4di,__gcc_v4di); -__gcc_v32qi __builtin_ia32_psubsb256(__gcc_v32qi,__gcc_v32qi); -__gcc_v16hi __builtin_ia32_psubsw256(__gcc_v16hi,__gcc_v16hi); -__gcc_v32qi __builtin_ia32_psubusb256(__gcc_v32qi,__gcc_v32qi); -__gcc_v16hi __builtin_ia32_psubusw256(__gcc_v16hi,__gcc_v16hi); -__gcc_v32qi __builtin_ia32_punpckhbw256(__gcc_v32qi,__gcc_v32qi); -__gcc_v16hi __builtin_ia32_punpckhwd256(__gcc_v16hi,__gcc_v16hi); -__gcc_v8si __builtin_ia32_punpckhdq256(__gcc_v8si,__gcc_v8si); -__gcc_v4di __builtin_ia32_punpckhqdq256(__gcc_v4di,__gcc_v4di); -__gcc_v32qi __builtin_ia32_punpcklbw256(__gcc_v32qi,__gcc_v32qi); -__gcc_v16hi __builtin_ia32_punpcklwd256(__gcc_v16hi,__gcc_v16hi); -__gcc_v8si __builtin_ia32_punpckldq256(__gcc_v8si,__gcc_v8si); -__gcc_v4di __builtin_ia32_punpcklqdq256(__gcc_v4di,__gcc_v4di); -__gcc_v4di __builtin_ia32_pxor256(__gcc_v4di,__gcc_v4di); -__gcc_v4di __builtin_ia32_movntdqa256(__gcc_v4di *); +__gcc_v32qi __builtin_ia32_psubb256(__gcc_v32qi, __gcc_v32qi); +__gcc_v16hi __builtin_ia32_psubw256(__gcc_v16hi, __gcc_v16hi); +__gcc_v8si __builtin_ia32_psubd256(__gcc_v8si, __gcc_v8si); +__gcc_v4di __builtin_ia32_psubq256(__gcc_v4di, __gcc_v4di); +__gcc_v32qi __builtin_ia32_psubsb256(__gcc_v32qi, __gcc_v32qi); +__gcc_v16hi __builtin_ia32_psubsw256(__gcc_v16hi, __gcc_v16hi); +__gcc_v32qi __builtin_ia32_psubusb256(__gcc_v32qi, __gcc_v32qi); +__gcc_v16hi __builtin_ia32_psubusw256(__gcc_v16hi, __gcc_v16hi); +__gcc_v32qi __builtin_ia32_punpckhbw256(__gcc_v32qi, __gcc_v32qi); +__gcc_v16hi __builtin_ia32_punpckhwd256(__gcc_v16hi, __gcc_v16hi); +__gcc_v8si __builtin_ia32_punpckhdq256(__gcc_v8si, __gcc_v8si); +__gcc_v4di __builtin_ia32_punpckhqdq256(__gcc_v4di, __gcc_v4di); +__gcc_v32qi __builtin_ia32_punpcklbw256(__gcc_v32qi, __gcc_v32qi); +__gcc_v16hi __builtin_ia32_punpcklwd256(__gcc_v16hi, __gcc_v16hi); +__gcc_v8si __builtin_ia32_punpckldq256(__gcc_v8si, __gcc_v8si); +__gcc_v4di __builtin_ia32_punpcklqdq256(__gcc_v4di, __gcc_v4di); +__gcc_v4di __builtin_ia32_pxor256(__gcc_v4di, __gcc_v4di); +__gcc_v4di __builtin_ia32_movntdqa256(__gcc_v4di*); __gcc_v4sf __builtin_ia32_vbroadcastss_ps(__gcc_v4sf); __gcc_v8sf __builtin_ia32_vbroadcastss_ps256(__gcc_v4sf); __gcc_v4df __builtin_ia32_vbroadcastsd_pd256(__gcc_v2df); __gcc_v4di __builtin_ia32_vbroadcastsi256(__gcc_v2di); -__gcc_v4si __builtin_ia32_pblendd128(__gcc_v4si,__gcc_v4si,int); -__gcc_v8si __builtin_ia32_pblendd256(__gcc_v8si,__gcc_v8si,int); +__gcc_v4si __builtin_ia32_pblendd128(__gcc_v4si, __gcc_v4si, int); +__gcc_v8si __builtin_ia32_pblendd256(__gcc_v8si, __gcc_v8si, int); __gcc_v32qi __builtin_ia32_pbroadcastb256(__gcc_v16qi); __gcc_v16hi __builtin_ia32_pbroadcastw256(__gcc_v8hi); __gcc_v8si __builtin_ia32_pbroadcastd256(__gcc_v4si); @@ -710,21 +710,21 @@ __gcc_v16qi __builtin_ia32_pbroadcastb128(__gcc_v16qi); __gcc_v8hi __builtin_ia32_pbroadcastw128(__gcc_v8hi); __gcc_v4si __builtin_ia32_pbroadcastd128(__gcc_v4si); __gcc_v2di __builtin_ia32_pbroadcastq128(__gcc_v2di); -__gcc_v8si __builtin_ia32_permvarsi256(__gcc_v8si,__gcc_v8si); -__gcc_v4df __builtin_ia32_permdf256(__gcc_v4df,int); -__gcc_v8sf __builtin_ia32_permvarsf256(__gcc_v8sf,__gcc_v8sf); -__gcc_v4di __builtin_ia32_permdi256(__gcc_v4di,int); -__gcc_v4di __builtin_ia32_permti256(__gcc_v4di,__gcc_v4di,int); -__gcc_v4di __builtin_ia32_extract128i256(__gcc_v4di,int); -__gcc_v4di __builtin_ia32_insert128i256(__gcc_v4di,__gcc_v2di,int); -__gcc_v8si __builtin_ia32_maskloadd256(const __gcc_v8si *,__gcc_v8si); -__gcc_v4di __builtin_ia32_maskloadq256(const __gcc_v4di *,__gcc_v4di); -__gcc_v4si __builtin_ia32_maskloadd(const __gcc_v4si *,__gcc_v4si); -__gcc_v2di __builtin_ia32_maskloadq(const __gcc_v2di *,__gcc_v2di); -void __builtin_ia32_maskstored256(__gcc_v8si *,__gcc_v8si,__gcc_v8si); -void __builtin_ia32_maskstoreq256(__gcc_v4di *,__gcc_v4di,__gcc_v4di); -void __builtin_ia32_maskstored(__gcc_v4si *,__gcc_v4si,__gcc_v4si); -void __builtin_ia32_maskstoreq(__gcc_v2di *,__gcc_v2di,__gcc_v2di); +__gcc_v8si __builtin_ia32_permvarsi256(__gcc_v8si, __gcc_v8si); +__gcc_v4df __builtin_ia32_permdf256(__gcc_v4df, int); +__gcc_v8sf __builtin_ia32_permvarsf256(__gcc_v8sf, __gcc_v8si); +__gcc_v4di __builtin_ia32_permdi256(__gcc_v4di, int); +__gcc_v4di __builtin_ia32_permti256(__gcc_v4di, __gcc_v4di, int); +__gcc_v2di __builtin_ia32_extract128i256(__gcc_v4di, int); +__gcc_v4di __builtin_ia32_insert128i256(__gcc_v4di, __gcc_v2di, int); +__gcc_v8si __builtin_ia32_maskloadd256(const __gcc_v8si*, __gcc_v8si); +__gcc_v4di __builtin_ia32_maskloadq256(const __gcc_v4di*, __gcc_v4di); +__gcc_v4si __builtin_ia32_maskloadd(const __gcc_v4si*, __gcc_v4si); +__gcc_v2di __builtin_ia32_maskloadq(const __gcc_v2di*, __gcc_v2di); +void __builtin_ia32_maskstored256(__gcc_v8si*, __gcc_v8si, __gcc_v8si); +void __builtin_ia32_maskstoreq256(__gcc_v4di*, __gcc_v4di, __gcc_v4di); +void __builtin_ia32_maskstored(__gcc_v4si*, __gcc_v4si, __gcc_v4si); +void __builtin_ia32_maskstoreq(__gcc_v2di*, __gcc_v2di, __gcc_v2di); __gcc_v8si __builtin_ia32_psll__gcc_v8si(__gcc_v8si,__gcc_v8si); __gcc_v4si __builtin_ia32_psll__gcc_v4si(__gcc_v4si,__gcc_v4si); __gcc_v4di __builtin_ia32_psll__gcc_v4di(__gcc_v4di,__gcc_v4di); @@ -735,22 +735,22 @@ __gcc_v8si __builtin_ia32_psrl__gcc_v8si(__gcc_v8si,__gcc_v8si); __gcc_v4si __builtin_ia32_psrl__gcc_v4si(__gcc_v4si,__gcc_v4si); __gcc_v4di __builtin_ia32_psrl__gcc_v4di(__gcc_v4di,__gcc_v4di); __gcc_v2di __builtin_ia32_psrl__gcc_v2di(__gcc_v2di,__gcc_v2di); -__gcc_v2df __builtin_ia32_gathersi__gcc_v2df(__gcc_v2df, const double *,__gcc_v4si,__gcc_v2df,int); -__gcc_v4df __builtin_ia32_gathersi__gcc_v4df(__gcc_v4df, const double *,__gcc_v4si,__gcc_v4df,int); -__gcc_v2df __builtin_ia32_gatherdi__gcc_v2df(__gcc_v2df, const double *,__gcc_v2di,__gcc_v2df,int); -__gcc_v4df __builtin_ia32_gatherdi__gcc_v4df(__gcc_v4df, const double *,__gcc_v4di,__gcc_v4df,int); -__gcc_v4sf __builtin_ia32_gathersi__gcc_v4sf(__gcc_v4sf, const float *,__gcc_v4si,__gcc_v4sf,int); -__gcc_v8sf __builtin_ia32_gathersi__gcc_v8sf(__gcc_v8sf, const float *,__gcc_v8si,__gcc_v8sf,int); -__gcc_v4sf __builtin_ia32_gatherdi__gcc_v4sf(__gcc_v4sf, const float *,__gcc_v2di,__gcc_v4sf,int); -__gcc_v4sf __builtin_ia32_gatherdi__gcc_v4sf256(__gcc_v4sf, const float *,__gcc_v4di,__gcc_v4sf,int); -__gcc_v2di __builtin_ia32_gathersi__gcc_v2di(__gcc_v2di, const long long int *,__gcc_v4si,__gcc_v2di,int); -__gcc_v4di __builtin_ia32_gathersi__gcc_v4di(__gcc_v4di, const long long int *,__gcc_v4si,__gcc_v4di,int); -__gcc_v2di __builtin_ia32_gatherdi__gcc_v2di(__gcc_v2di, const long long int *,__gcc_v2di,__gcc_v2di,int); -__gcc_v4di __builtin_ia32_gatherdi__gcc_v4di(__gcc_v4di, const long long int *,__gcc_v4di,__gcc_v4di,int); -__gcc_v4si __builtin_ia32_gathersi__gcc_v4si(__gcc_v4si, const int *,__gcc_v4si,__gcc_v4si,int); -__gcc_v8si __builtin_ia32_gathersi__gcc_v8si(__gcc_v8si, const int *,__gcc_v8si,__gcc_v8si,int); -__gcc_v4si __builtin_ia32_gatherdi__gcc_v4si(__gcc_v4si, const int *,__gcc_v2di,__gcc_v4si,int); -__gcc_v4si __builtin_ia32_gatherdi__gcc_v4si256(__gcc_v4si, const int *,__gcc_v4di,__gcc_v4si,int); +__gcc_v2df __builtin_ia32_gathersi__gcc_v2df(__gcc_v2df, const double*,__gcc_v4si,__gcc_v2df,int); +__gcc_v4df __builtin_ia32_gathersi__gcc_v4df(__gcc_v4df, const double*,__gcc_v4si,__gcc_v4df,int); +__gcc_v2df __builtin_ia32_gatherdi__gcc_v2df(__gcc_v2df, const double*,__gcc_v2di,__gcc_v2df,int); +__gcc_v4df __builtin_ia32_gatherdi__gcc_v4df(__gcc_v4df, const double*,__gcc_v4di,__gcc_v4df,int); +__gcc_v4sf __builtin_ia32_gathersi__gcc_v4sf(__gcc_v4sf, const float*,__gcc_v4si,__gcc_v4sf,int); +__gcc_v8sf __builtin_ia32_gathersi__gcc_v8sf(__gcc_v8sf, const float*,__gcc_v8si,__gcc_v8sf,int); +__gcc_v4sf __builtin_ia32_gatherdi__gcc_v4sf(__gcc_v4sf, const float*,__gcc_v2di,__gcc_v4sf,int); +__gcc_v4sf __builtin_ia32_gatherdi__gcc_v4sf256(__gcc_v4sf, const float*,__gcc_v4di,__gcc_v4sf,int); +__gcc_v2di __builtin_ia32_gathersi__gcc_v2di(__gcc_v2di, const long long int*,__gcc_v4si,__gcc_v2di,int); +__gcc_v4di __builtin_ia32_gathersi__gcc_v4di(__gcc_v4di, const long long int*,__gcc_v4si,__gcc_v4di,int); +__gcc_v2di __builtin_ia32_gatherdi__gcc_v2di(__gcc_v2di, const long long int*,__gcc_v2di,__gcc_v2di,int); +__gcc_v4di __builtin_ia32_gatherdi__gcc_v4di(__gcc_v4di, const long long int*,__gcc_v4di,__gcc_v4di,int); +__gcc_v4si __builtin_ia32_gathersi__gcc_v4si(__gcc_v4si, const int*,__gcc_v4si,__gcc_v4si,int); +__gcc_v8si __builtin_ia32_gathersi__gcc_v8si(__gcc_v8si, const int*,__gcc_v8si,__gcc_v8si,int); +__gcc_v4si __builtin_ia32_gatherdi__gcc_v4si(__gcc_v4si, const int*,__gcc_v2di,__gcc_v4si,int); +__gcc_v4si __builtin_ia32_gatherdi__gcc_v4si256(__gcc_v4si, const int*,__gcc_v4di,__gcc_v4si,int); __gcc_v2di __builtin_ia32_aesenc128(__gcc_v2di, __gcc_v2di); __gcc_v2di __builtin_ia32_aesenclast128(__gcc_v2di, __gcc_v2di); __gcc_v2di __builtin_ia32_aesdec128(__gcc_v2di, __gcc_v2di); @@ -758,23 +758,23 @@ __gcc_v2di __builtin_ia32_aesdeclast128(__gcc_v2di, __gcc_v2di); __gcc_v2di __builtin_ia32_aeskeygenassist128(__gcc_v2di, const int); __gcc_v2di __builtin_ia32_aesimc128(__gcc_v2di); __gcc_v2di __builtin_ia32_pclmulqdq128(__gcc_v2di, __gcc_v2di, const int); -unsigned int __builtin_ia32_rdfsbase32(void); -unsigned long long __builtin_ia32_rdfsbase64(void); -unsigned int __builtin_ia32_rdgsbase32(void); -unsigned long long __builtin_ia32_rdgsbase64(void); +unsigned __builtin_ia32_rdfsbase32(); +unsigned long long __builtin_ia32_rdfsbase64(); +unsigned __builtin_ia32_rdgsbase32(); +unsigned long long __builtin_ia32_rdgsbase64(); void _writefsbase_u32(unsigned int); void _writefsbase_u64(unsigned long long); void _writegsbase_u32(unsigned int); void _writegsbase_u64(unsigned long long); -unsigned int __builtin_ia32_rdrand16_step(unsigned short *); -unsigned int __builtin_ia32_rdrand32_step(unsigned int *); -unsigned int __builtin_ia32_rdrand64_step(unsigned long long *); -void __builtin_ia32_movntsd(double *, __gcc_v2df); -void __builtin_ia32_movntss(float *, __gcc_v4sf); +unsigned int __builtin_ia32_rdrand16_step(unsigned short*); +unsigned int __builtin_ia32_rdrand32_step(unsigned int*); +unsigned int __builtin_ia32_rdrand64_step(unsigned long long*); +void __builtin_ia32_movntsd(double*, __gcc_v2df); +void __builtin_ia32_movntss(float*, __gcc_v4sf); __gcc_v2di __builtin_ia32_extrq (__gcc_v2di, __gcc_v16qi); -__gcc_v2di __builtin_ia32_extrqi(__gcc_v2di, const unsigned int, const unsigned int); +__gcc_v2di __builtin_ia32_extrqi(__gcc_v2di, unsigned, unsigned); __gcc_v2di __builtin_ia32_insertq(__gcc_v2di, __gcc_v2di); -__gcc_v2di __builtin_ia32_insertqi(__gcc_v2di, __gcc_v2di, const unsigned int, const unsigned int); +__gcc_v2di __builtin_ia32_insertqi(__gcc_v2di, __gcc_v2di, unsigned, unsigned); __gcc_v2df __builtin_ia32_vfrczpd(__gcc_v2df); __gcc_v4sf __builtin_ia32_vfrczps(__gcc_v4sf); __gcc_v2df __builtin_ia32_vfrczsd(__gcc_v2df); @@ -931,19 +931,19 @@ __gcc_v4df __builtin_ia32_fmaddsubpd256(__gcc_v4df, __gcc_v4df, __gcc_v4df); __gcc_v8sf __builtin_ia32_fmaddsubps256(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf); __gcc_v4df __builtin_ia32_fmsubaddpd256(__gcc_v4df, __gcc_v4df, __gcc_v4df); __gcc_v8sf __builtin_ia32_fmsubaddps256(__gcc_v8sf, __gcc_v8sf, __gcc_v8sf); -void __builtin_ia32_llwpcb16(void *); -void __builtin_ia32_llwpcb32(void *); -void __builtin_ia32_llwpcb64(void *); -//void * __builtin_ia32_llwpcb16(void); -//void * __builtin_ia32_llwpcb32(void); -//void * __builtin_ia32_llwpcb64(void); +void __builtin_ia32_llwpcb16(void*); +void __builtin_ia32_llwpcb32(void*); +void __builtin_ia32_llwpcb64(void*); +//void* __builtin_ia32_llwpcb16(void); +//void* __builtin_ia32_llwpcb32(void); +//void* __builtin_ia32_llwpcb64(void); void __builtin_ia32_lwpval16(unsigned short, unsigned int, unsigned short); -void __builtin_ia32_lwpval32(unsigned int, unsigned int, unsigned int); -void __builtin_ia32_lwpval64(unsigned __int64, unsigned int, unsigned int); +void __builtin_ia32_lwpval32(unsigned, unsigned, unsigned); +void __builtin_ia32_lwpval64(unsigned long long, unsigned, unsigned); unsigned char __builtin_ia32_lwpins16(unsigned short, unsigned int, unsigned short); -unsigned char __builtin_ia32_lwpins32(unsigned int, unsigned int, unsigned int); -unsigned char __builtin_ia32_lwpins64(unsigned __int64, unsigned int, unsigned int); -unsigned int __builtin_ia32_bextr_u32(unsigned int, unsigned int); +unsigned char __builtin_ia32_lwpins32(unsigned, unsigned, unsigned); +unsigned char __builtin_ia32_lwpins64(unsigned long long, unsigned, unsigned); +unsigned __builtin_ia32_bextr_u32(unsigned, unsigned); unsigned long long __builtin_ia32_bextr_u64(unsigned long long, unsigned long long); unsigned int _bzhi_u32(unsigned int, unsigned int); unsigned int _pdep_u32(unsigned int, unsigned int); @@ -952,11 +952,11 @@ unsigned long long _bzhi_u64(unsigned long long, unsigned long long); unsigned long long _pdep_u64(unsigned long long, unsigned long long); unsigned long long _pext_u64(unsigned long long, unsigned long long); unsigned short __builtin_ia32_lzcnt_16(unsigned short); -unsigned int __builtin_ia32_lzcnt_u32(unsigned int); +unsigned __builtin_ia32_lzcnt_u32(unsigned); unsigned long long __builtin_ia32_lzcnt_u64(unsigned long long); -unsigned int __builtin_ia32_bextri_u32(unsigned int, const unsigned int); -unsigned long long __builtin_ia32_bextri_u64(unsigned long long, const unsigned long long); -void __builtin_ia32_femms(void); +unsigned __builtin_ia32_bextri_u32(unsigned, unsigned); +unsigned long long __builtin_ia32_bextri_u64(unsigned long long, unsigned long long); +void __builtin_ia32_femms(); __gcc_v8qi __builtin_ia32_pavgusb(__gcc_v8qi, __gcc_v8qi); __gcc_v2si __builtin_ia32_pf2id(__gcc_v2sf); __gcc_v2sf __builtin_ia32_pfacc(__gcc_v2sf, __gcc_v2sf); diff --git a/src/ansi-c/gcc_builtin_headers_math.h b/src/ansi-c/gcc_builtin_headers_math.h new file mode 100644 index 00000000000..9ab9d4992ff --- /dev/null +++ b/src/ansi-c/gcc_builtin_headers_math.h @@ -0,0 +1,379 @@ +int __builtin_abs(int); +double __builtin_acos(double); +float __builtin_acosf(float); +double __builtin_acosh(double); +float __builtin_acoshf(float); +long double __builtin_acoshl(long double); +long double __builtin_acosl(long double); +_Bool __builtin_add_overflow(); +_Bool __builtin_add_overflow_p(); +double __builtin_asin(double); +float __builtin_asinf(float); +double __builtin_asinh(double); +float __builtin_asinhf(float); +long double __builtin_asinhl(long double); +long double __builtin_asinl(long double); +double __builtin_atan(double); +double __builtin_atan2(double, double); +float __builtin_atan2f(float, float); +long double __builtin_atan2l(long double, long double); +float __builtin_atanf(float); +double __builtin_atanh(double); +float __builtin_atanhf(float); +long double __builtin_atanhl(long double); +long double __builtin_atanl(long double); +double __builtin_cabs(double _Complex); +float __builtin_cabsf(float _Complex); +long double __builtin_cabsl(long double _Complex); +double _Complex __builtin_cacos(double _Complex); +float _Complex __builtin_cacosf(float _Complex); +double _Complex __builtin_cacosh(double _Complex); +float _Complex __builtin_cacoshf(float _Complex); +long double _Complex __builtin_cacoshl(long double _Complex); +long double _Complex __builtin_cacosl(long double _Complex); +double __builtin_carg(double _Complex); +float __builtin_cargf(float _Complex); +long double __builtin_cargl(long double _Complex); +double _Complex __builtin_casin(double _Complex); +float _Complex __builtin_casinf(float _Complex); +double _Complex __builtin_casinh(double _Complex); +float _Complex __builtin_casinhf(float _Complex); +long double _Complex __builtin_casinhl(long double _Complex); +long double _Complex __builtin_casinl(long double _Complex); +double _Complex __builtin_catan(double _Complex); +float _Complex __builtin_catanf(float _Complex); +double _Complex __builtin_catanh(double _Complex); +float _Complex __builtin_catanhf(float _Complex); +long double _Complex __builtin_catanhl(long double _Complex); +long double _Complex __builtin_catanl(long double _Complex); +double __builtin_cbrt(double); +float __builtin_cbrtf(float); +long double __builtin_cbrtl(long double); +double _Complex __builtin_ccos(double _Complex); +float _Complex __builtin_ccosf(float _Complex); +double _Complex __builtin_ccosh(double _Complex); +float _Complex __builtin_ccoshf(float _Complex); +long double _Complex __builtin_ccoshl(long double _Complex); +long double _Complex __builtin_ccosl(long double _Complex); +double __builtin_ceil(double); +float __builtin_ceilf(float); +long double __builtin_ceill(long double); +double _Complex __builtin_cexp(double _Complex); +float _Complex __builtin_cexpf(float _Complex); +double _Complex __builtin_cexpi(double); +float _Complex __builtin_cexpif(float); +long double _Complex __builtin_cexpil(long double); +long double _Complex __builtin_cexpl(long double _Complex); +double __builtin_cimag(double _Complex); +float __builtin_cimagf(float _Complex); +long double __builtin_cimagl(long double _Complex); +double _Complex __builtin_clog(double _Complex); +double _Complex __builtin_clog10(double _Complex); +float _Complex __builtin_clog10f(float _Complex); +long double _Complex __builtin_clog10l(long double _Complex); +float _Complex __builtin_clogf(float _Complex); +long double _Complex __builtin_clogl(long double _Complex); +double _Complex __builtin_conj(double _Complex); +float _Complex __builtin_conjf(float _Complex); +long double _Complex __builtin_conjl(long double _Complex); +double __builtin_copysign(double, double); +float __builtin_copysignf(float, float); +long double __builtin_copysignl(long double, long double); +double __builtin_cos(double); +float __builtin_cosf(float); +double __builtin_cosh(double); +float __builtin_coshf(float); +long double __builtin_coshl(long double); +long double __builtin_cosl(long double); +double _Complex __builtin_cpow(double _Complex, double _Complex); +float _Complex __builtin_cpowf(float _Complex, float _Complex); +long double _Complex __builtin_cpowl(long double _Complex, long double _Complex); +double _Complex __builtin_cproj(double _Complex); +float _Complex __builtin_cprojf(float _Complex); +long double _Complex __builtin_cprojl(long double _Complex); +double __builtin_creal(double _Complex); +float __builtin_crealf(float _Complex); +long double __builtin_creall(long double _Complex); +double _Complex __builtin_csin(double _Complex); +float _Complex __builtin_csinf(float _Complex); +double _Complex __builtin_csinh(double _Complex); +float _Complex __builtin_csinhf(float _Complex); +long double _Complex __builtin_csinhl(long double _Complex); +long double _Complex __builtin_csinl(long double _Complex); +double _Complex __builtin_csqrt(double _Complex); +float _Complex __builtin_csqrtf(float _Complex); +long double _Complex __builtin_csqrtl(long double _Complex); +double _Complex __builtin_ctan(double _Complex); +float _Complex __builtin_ctanf(float _Complex); +double _Complex __builtin_ctanh(double _Complex); +float _Complex __builtin_ctanhf(float _Complex); +long double _Complex __builtin_ctanhl(long double _Complex); +long double _Complex __builtin_ctanl(long double _Complex); +int __builtin_ctz(unsigned); +int __builtin_ctzl(unsigned long); +int __builtin_ctzll(unsigned long long); +double __builtin_drem(double, double); +float __builtin_dremf(float, float); +long double __builtin_dreml(long double, long double); +double __builtin_erf(double); +double __builtin_erfc(double); +float __builtin_erfcf(float); +long double __builtin_erfcl(long double); +float __builtin_erff(float); +long double __builtin_erfl(long double); +double __builtin_exp(double); +double __builtin_exp10(double); +float __builtin_exp10f(float); +long double __builtin_exp10l(long double); +double __builtin_exp2(double); +float __builtin_exp2f(float); +long double __builtin_exp2l(long double); +float __builtin_expf(float); +long double __builtin_expl(long double); +double __builtin_expm1(double); +float __builtin_expm1f(float); +long double __builtin_expm1l(long double); +double __builtin_fabs(double); +float __builtin_fabsf(float); +long double __builtin_fabsl(long double); +double __builtin_fdim(double, double); +float __builtin_fdimf(float, float); +long double __builtin_fdiml(long double, long double); +int __builtin_finite(double); +int __builtin_finitef(float); +int __builtin_finitel(long double); +double __builtin_floor(double); +float __builtin_floorf(float); +long double __builtin_floorl(long double); +double __builtin_fma(double, double, double); +float __builtin_fmaf(float, float, float); +long double __builtin_fmal(long double, long double, long double); +double __builtin_fmax(double, double); +float __builtin_fmaxf(float, float); +long double __builtin_fmaxl(long double, long double); +double __builtin_fmin(double, double); +float __builtin_fminf(float, float); +long double __builtin_fminl(long double, long double); +double __builtin_fmod(double, double); +float __builtin_fmodf(float, float); +long double __builtin_fmodl(long double, long double); +int __builtin_fpclassify(int, int, int, int, int, ...); +double __builtin_frexp(double, int*); +float __builtin_frexpf(float, int*); +long double __builtin_frexpl(long double, int*); +double __builtin_gamma(double); +double __builtin_gamma_r(double, int*); +float __builtin_gammaf(float); +float __builtin_gammaf_r(float, int*); +long double __builtin_gammal(long double); +long double __builtin_gammal_r(long double, int*); +double __builtin_huge_val(); +float __builtin_huge_valf(); +long double __builtin_huge_vall(); +double __builtin_hypot(double, double); +float __builtin_hypotf(float, float); +long double __builtin_hypotl(long double, long double); +int __builtin_iceil(double); +int __builtin_iceilf(float); +int __builtin_iceill(long double); +int __builtin_ifloor(double); +int __builtin_ifloorf(float); +int __builtin_ifloorl(long double); +int __builtin_ilogb(double); +int __builtin_ilogbf(float); +int __builtin_ilogbl(long double); +double __builtin_inf(); +float __builtin_inff(); +long double __builtin_infl(); +int __builtin_irint(double); +int __builtin_irintf(float); +int __builtin_irintl(long double); +int __builtin_iround(double); +int __builtin_iroundf(float); +int __builtin_iroundl(long double); +int __builtin_isfinite(); +int __builtin_isgreater(); +int __builtin_isgreaterequal(); +int __builtin_isinf(double); +int __builtin_isinf_sign(); +int __builtin_isinff(float); +int __builtin_isinfl(long double); +int __builtin_isless(); +int __builtin_islessequal(); +int __builtin_islessgreater(); +int __builtin_isnan(double); +int __builtin_isnanf(float); +int __builtin_isnanl(long double); +int __builtin_isnormal(); +int __builtin_isunordered(); +double __builtin_j0(double); +float __builtin_j0f(float); +long double __builtin_j0l(long double); +double __builtin_j1(double); +float __builtin_j1f(float); +long double __builtin_j1l(long double); +double __builtin_jn(int, double); +float __builtin_jnf(int, float); +long double __builtin_jnl(int, long double); +long __builtin_labs(long); +long __builtin_lceil(double); +long __builtin_lceilf(float); +long __builtin_lceill(long double); +double __builtin_ldexp(double, int); +float __builtin_ldexpf(float, int); +long double __builtin_ldexpl(long double, int); +long __builtin_lfloor(double); +long __builtin_lfloorf(float); +long __builtin_lfloorl(long double); +double __builtin_lgamma(double); +double __builtin_lgamma_r(double, int*); +float __builtin_lgammaf(float); +float __builtin_lgammaf_r(float, int*); +long double __builtin_lgammal(long double); +long double __builtin_lgammal_r(long double, int*); +long long __builtin_llabs(long long); +long long __builtin_llceil(double); +long long __builtin_llceilf(float); +long long __builtin_llceill(long double); +long long __builtin_llfloor(double); +long long __builtin_llfloorf(float); +long long __builtin_llfloorl(long double); +long long __builtin_llrint(double); +long long __builtin_llrintf(float); +long long __builtin_llrintl(long double); +long long __builtin_llround(double); +long long __builtin_llroundf(float); +long long __builtin_llroundl(long double); +double __builtin_log(double); +double __builtin_log10(double); +float __builtin_log10f(float); +long double __builtin_log10l(long double); +double __builtin_log1p(double); +float __builtin_log1pf(float); +long double __builtin_log1pl(long double); +double __builtin_log2(double); +float __builtin_log2f(float); +long double __builtin_log2l(long double); +double __builtin_logb(double); +float __builtin_logbf(float); +long double __builtin_logbl(long double); +float __builtin_logf(float); +long double __builtin_logl(long double); +long __builtin_lrint(double); +long __builtin_lrintf(float); +long __builtin_lrintl(long double); +long __builtin_lround(double); +long __builtin_lroundf(float); +long __builtin_lroundl(long double); +double __builtin_modf(double, double*); +float __builtin_modff(float, float*); +long double __builtin_modfl(long double, long double*); +_Bool __builtin_mul_overflow(); +_Bool __builtin_mul_overflow_p(); +double __builtin_nan(const char*); +float __builtin_nanf(const char*); +long double __builtin_nanl(const char*); +double __builtin_nans(const char*); +float __builtin_nansf(const char*); +long double __builtin_nansl(const char*); +double __builtin_nearbyint(double); +float __builtin_nearbyintf(float); +long double __builtin_nearbyintl(long double); +double __builtin_nextafter(double, double); +float __builtin_nextafterf(float, float); +long double __builtin_nextafterl(long double, long double); +double __builtin_nexttoward(double, long double); +float __builtin_nexttowardf(float, long double); +long double __builtin_nexttowardl(long double, long double); +int __builtin_parity(unsigned); +int __builtin_parityl(unsigned long); +int __builtin_parityll(unsigned long long); +double __builtin_pow(double, double); +double __builtin_pow10(double); +float __builtin_pow10f(float); +long double __builtin_pow10l(long double); +float __builtin_powf(float, float); +double __builtin_powi(double, int); +float __builtin_powif(float, int); +long double __builtin_powil(long double, int); +long double __builtin_powl(long double, long double); +double __builtin_remainder(double, double); +float __builtin_remainderf(float, float); +long double __builtin_remainderl(long double, long double); +double __builtin_remquo(double, double, int*); +float __builtin_remquof(float, float, int*); +long double __builtin_remquol(long double, long double, int*); +double __builtin_rint(double); +float __builtin_rintf(float); +long double __builtin_rintl(long double); +double __builtin_round(double); +float __builtin_roundf(float); +long double __builtin_roundl(long double); +_Bool __builtin_sadd_overflow(int, int, int*); +_Bool __builtin_saddl_overflow(long, long, long*); +_Bool __builtin_saddll_overflow(long long, long long, long long*); +double __builtin_scalb(double, double); +float __builtin_scalbf(float, float); +long double __builtin_scalbl(long double, long double); +double __builtin_scalbln(double, long); +float __builtin_scalblnf(float, long); +long double __builtin_scalblnl(long double, long); +double __builtin_scalbn(double, int); +float __builtin_scalbnf(float, int); +long double __builtin_scalbnl(long double, int); +int __builtin_signbit(double); +int __builtin_signbitf(float); +int __builtin_signbitl(long double); +double __builtin_significand(double); +float __builtin_significandf(float); +long double __builtin_significandl(long double); +double __builtin_sin(double); +void __builtin_sincos(double, double*, double*); +void __builtin_sincosf(float, float*, float*); +void __builtin_sincosl(long double, long double*, long double*); +float __builtin_sinf(float); +double __builtin_sinh(double); +float __builtin_sinhf(float); +long double __builtin_sinhl(long double); +long double __builtin_sinl(long double); +_Bool __builtin_smul_overflow(int, int, int*); +_Bool __builtin_smull_overflow(long, long, long*); +_Bool __builtin_smulll_overflow(long long, long long, long long*); +double __builtin_sqrt(double); +float __builtin_sqrtf(float); +long double __builtin_sqrtl(long double); +_Bool __builtin_ssub_overflow(int, int, int*); +_Bool __builtin_ssubl_overflow(long, long, long*); +_Bool __builtin_ssubll_overflow(long long, long long, long long*); +_Bool __builtin_sub_overflow(); +_Bool __builtin_sub_overflow_p(); +double __builtin_tan(double); +float __builtin_tanf(float); +double __builtin_tanh(double); +float __builtin_tanhf(float); +long double __builtin_tanhl(long double); +long double __builtin_tanl(long double); +double __builtin_tgamma(double); +float __builtin_tgammaf(float); +long double __builtin_tgammal(long double); +double __builtin_trunc(double); +float __builtin_truncf(float); +long double __builtin_truncl(long double); +_Bool __builtin_uadd_overflow(unsigned, unsigned, unsigned*); +_Bool __builtin_uaddl_overflow(unsigned long, unsigned long, unsigned long*); +_Bool __builtin_uaddll_overflow(unsigned long long, unsigned long long, unsigned long long*); +_Bool __builtin_umul_overflow(unsigned, unsigned, unsigned*); +_Bool __builtin_umull_overflow(unsigned long, unsigned long, unsigned long*); +_Bool __builtin_umulll_overflow(unsigned long long, unsigned long long, unsigned long long*); +_Bool __builtin_usub_overflow(unsigned, unsigned, unsigned*); +_Bool __builtin_usubl_overflow(unsigned long, unsigned long, unsigned long*); +_Bool __builtin_usubll_overflow(unsigned long long, unsigned long long, unsigned long long*); +double __builtin_y0(double); +float __builtin_y0f(float); +long double __builtin_y0l(long double); +double __builtin_y1(double); +float __builtin_y1f(float); +long double __builtin_y1l(long double); +double __builtin_yn(int, double); +float __builtin_ynf(int, float); +long double __builtin_ynl(int, long double); diff --git a/src/ansi-c/gcc_builtin_headers_mem_string.h b/src/ansi-c/gcc_builtin_headers_mem_string.h new file mode 100644 index 00000000000..dca5af04300 --- /dev/null +++ b/src/ansi-c/gcc_builtin_headers_mem_string.h @@ -0,0 +1,118 @@ +void __builtin___bnd_chk_ptr_bounds(const void*, __CPROVER_size_t); +void __builtin___bnd_chk_ptr_lbounds(const void*); +void __builtin___bnd_chk_ptr_ubounds(const void*); +void* __builtin___bnd_copy_ptr_bounds(const void*, const void*); +const void* __builtin___bnd_get_ptr_lbound(const void*); +const void* __builtin___bnd_get_ptr_ubound(const void*); +void* __builtin___bnd_init_ptr_bounds(const void*); +void* __builtin___bnd_narrow_ptr_bounds(const void*, const void*, __CPROVER_size_t); +void* __builtin___bnd_null_ptr_bounds(const void*); +void* __builtin___bnd_set_ptr_bounds(const void*, __CPROVER_size_t); +void __builtin___bnd_store_ptr_bounds(void**, const void*); +const void* __builtin___chkp_bndldx(const void*, const void*); +void __builtin___clear_cache(void*, void*); +void* __builtin___memcpy_chk(void*, const void*, __CPROVER_size_t, __CPROVER_size_t); +void* __builtin___memmove_chk(void*, const void*, __CPROVER_size_t, __CPROVER_size_t); +void* __builtin___mempcpy_chk(void*, const void*, __CPROVER_size_t, __CPROVER_size_t); +void* __builtin___memset_chk(void*, int, __CPROVER_size_t, __CPROVER_size_t); +char* __builtin___stpcpy(char *s1, const char *s2); +char* __builtin___stpcpy_chk(char*, const char*, __CPROVER_size_t); +char* __builtin___stpncpy_chk(char*, const char*, __CPROVER_size_t, __CPROVER_size_t); +char* __builtin___strcat_chk(char*, const char*, __CPROVER_size_t); +char* __builtin___strcpy_chk(char*, const char*, __CPROVER_size_t); +char* __builtin___strncat_chk(char*, const char*, __CPROVER_size_t, __CPROVER_size_t); +char* __builtin___strncpy_chk(char*, const char*, __CPROVER_size_t, __CPROVER_size_t); +void* __builtin_aggregate_incoming_address(); +void* __builtin_aligned_alloc(__CPROVER_size_t, __CPROVER_size_t); +void* __builtin_alloca(__CPROVER_size_t); +void* __builtin_assume_aligned(const void*, __CPROVER_size_t, ...); +int __builtin_bcmp(const void*, const void*, __CPROVER_size_t); +void __builtin_bcopy(const void*, void*, __CPROVER_size_t); +short unsigned int __builtin_bswap16(short unsigned int); +unsigned int __builtin_bswap32(unsigned int); +long long unsigned int __builtin_bswap64(long long unsigned int); +void __builtin_bzero(void*, __CPROVER_size_t); +void* __builtin_calloc(__CPROVER_size_t, __CPROVER_size_t); +void* __builtin_chkp_memcpy_nobnd(void*, const void*, __CPROVER_size_t); +void* __builtin_chkp_memcpy_nobnd_nochk(void*, const void*, __CPROVER_size_t); +void* __builtin_chkp_memcpy_nochk(void*, const void*, __CPROVER_size_t); +void* __builtin_chkp_memmove_nobnd(void*, const void*, __CPROVER_size_t); +void* __builtin_chkp_memmove_nobnd_nochk(void*, const void*, __CPROVER_size_t); +void* __builtin_chkp_memmove_nochk(void*, const void*, __CPROVER_size_t); +void* __builtin_chkp_mempcpy_nobnd(void*, const void*, __CPROVER_size_t); +void* __builtin_chkp_mempcpy_nobnd_nochk(void*, const void*, __CPROVER_size_t); +void* __builtin_chkp_mempcpy_nochk(void*, const void*, __CPROVER_size_t); +void* __builtin_chkp_memset_nobnd(void*, int, __CPROVER_size_t); +void* __builtin_chkp_memset_nobnd_nochk(void*, int, __CPROVER_size_t); +void* __builtin_chkp_memset_nochk(void*, int, __CPROVER_size_t); +int __builtin_clrsb(int); +int __builtin_clrsbl(long); +int __builtin_clrsbll(long long); +int __builtin_clz(unsigned); +int __builtin_clzl(unsigned long); +int __builtin_clzll(unsigned long long); +int __builtin_ctz(unsigned); +int __builtin_ctzl(unsigned long); +int __builtin_ctzll(unsigned long long); +char* __builtin_dcgettext(const char*, const char*, int); +char* __builtin_dgettext(const char*, const char*); +void* __builtin_extract_return_addr(void*); +int __builtin_ffs(int); +int __builtin_ffsl(long); +int __builtin_ffsll(long long); +void* __builtin_frame_address(unsigned); +void __builtin_free(void*); +void* __builtin_frob_return_addr(void*); +char* __builtin_gettext(const char*); +char* __builtin_index(const char*, int); +int __builtin_isalnum(int); +int __builtin_isalpha(int); +int __builtin_isascii(int); +int __builtin_isblank(int); +int __builtin_iscntrl(int); +int __builtin_isdigit(int); +int __builtin_isgraph(int); +int __builtin_islower(int); +int __builtin_isprint(int); +int __builtin_ispunct(int); +int __builtin_isspace(int); +int __builtin_isupper(int); +int __builtin_isxdigit(int); +void* __builtin_malloc(__CPROVER_size_t); +void* __builtin_memchr(const void*, int, __CPROVER_size_t); +int __builtin_memcmp(const void*, const void*, __CPROVER_size_t); +void* __builtin_memcpy(void*, const void*, __CPROVER_size_t); +void* __builtin_memmove(void*, const void*, __CPROVER_size_t); +void* __builtin_mempcpy(void*, const void*, __CPROVER_size_t); +void* __builtin_memset(void*, int, __CPROVER_size_t); +__CPROVER_size_t __builtin_object_size(const void*, int); +int __builtin_popcount(unsigned); +int __builtin_popcountll(unsigned long long int x); +int __builtin_posix_memalign(void**, __CPROVER_size_t, __CPROVER_size_t); +void __builtin_prefetch(const void*, ...); +void* __builtin_realloc(void*, __CPROVER_size_t); +void* __builtin_return_address(unsigned); +char* __builtin_rindex(const char*, int); +char* __builtin_stpcpy(char*, const char*); +char* __builtin_stpncpy(char*, const char*, __CPROVER_size_t); +int __builtin_strcasecmp(const char*, const char*); +char* __builtin_strcat(char*, const char*); +char* __builtin_strchr(const char*, int); +int __builtin_strcmp(const char*, const char*); +char* __builtin_strcpy(char*, const char*); +__CPROVER_size_t __builtin_strcspn(const char*, const char*); +char* __builtin_strdup(const char*); +__CPROVER_size_t __builtin_strftime(char*, __CPROVER_size_t, const char*, const struct tm*); +__CPROVER_size_t __builtin_strlen(const char*); +int __builtin_strncasecmp(const char*, const char*, __CPROVER_size_t); +char* __builtin_strncat(char*, const char*, __CPROVER_size_t); +int __builtin_strncmp(const char*, const char*, __CPROVER_size_t); +char* __builtin_strncpy(char*, const char*, __CPROVER_size_t); +char* __builtin_strndup(const char*, __CPROVER_size_t); +char* __builtin_strpbrk(const char*, const char*); +char* __builtin_strrchr(const char*, int); +__CPROVER_size_t __builtin_strspn(const char*, const char*); +char* __builtin_strstr(const char*, const char*); +int __builtin_toascii(int); +int __builtin_tolower(int); +int __builtin_toupper(int); diff --git a/src/ansi-c/gcc_builtin_headers_omp.h b/src/ansi-c/gcc_builtin_headers_omp.h new file mode 100644 index 00000000000..6b7b28957b0 --- /dev/null +++ b/src/ansi-c/gcc_builtin_headers_omp.h @@ -0,0 +1,90 @@ +int __builtin_omp_get_thread_num(); +int __builtin_omp_get_num_threads(); +int __builtin_omp_get_team_num(); +int __builtin_omp_get_num_teams(); +void __builtin_GOMP_atomic_start(); +void __builtin_GOMP_atomic_end(); +void __builtin_GOMP_barrier(); +_Bool __builtin_GOMP_barrier_cancel(); +void __builtin_GOMP_taskwait(); +void __builtin_GOMP_taskyield(); +void __builtin_GOMP_taskgroup_start(); +void __builtin_GOMP_taskgroup_end(); +_Bool __builtin_GOMP_cancel(int, _Bool); +_Bool __builtin_GOMP_cancellation_point(int); +void __builtin_GOMP_critical_start(); +void __builtin_GOMP_critical_end(); +void __builtin_GOMP_critical_name_start(void**); +void __builtin_GOMP_critical_name_end(void**); +_Bool __builtin_GOMP_loop_static_start(long, long, long, long, long*, long*); +_Bool __builtin_GOMP_loop_dynamic_start(long, long, long, long, long*, long*); +_Bool __builtin_GOMP_loop_guided_start(long, long, long, long, long*, long*); +_Bool __builtin_GOMP_loop_runtime_start(long, long, long, long*, long*); +_Bool __builtin_GOMP_loop_nonmonotonic_dynamic_start(long, long, long, long, long*, long*); +_Bool __builtin_GOMP_loop_nonmonotonic_guided_start(long, long, long, long, long*, long*); +_Bool __builtin_GOMP_loop_ordered_static_start(long, long, long, long, long*, long*); +_Bool __builtin_GOMP_loop_ordered_dynamic_start(long, long, long, long, long*, long*); +_Bool __builtin_GOMP_loop_ordered_guided_start(long, long, long, long, long*, long*); +_Bool __builtin_GOMP_loop_ordered_runtime_start(long, long, long, long*, long*); +_Bool __builtin_GOMP_loop_doacross_static_start(unsigned, long*, long, long*, long*); +_Bool __builtin_GOMP_loop_doacross_dynamic_start(unsigned, long*, long, long*, long*); +_Bool __builtin_GOMP_loop_doacross_guided_start(unsigned, long*, long, long*, long*); +_Bool __builtin_GOMP_loop_doacross_runtime_start(unsigned, long*, long*, long*); +_Bool __builtin_GOMP_loop_static_next(long*, long*); +_Bool __builtin_GOMP_loop_dynamic_next(long*, long*); +_Bool __builtin_GOMP_loop_guided_next(long*, long*); +_Bool __builtin_GOMP_loop_runtime_next(long*, long*); +_Bool __builtin_GOMP_loop_nonmonotonic_dynamic_next(long*, long*); +_Bool __builtin_GOMP_loop_nonmonotonic_guided_next(long*, long*); +_Bool __builtin_GOMP_loop_ordered_static_next(long*, long*); +_Bool __builtin_GOMP_loop_ordered_dynamic_next(long*, long*); +_Bool __builtin_GOMP_loop_ordered_guided_next(long*, long*); +_Bool __builtin_GOMP_loop_ordered_runtime_next(long*, long*); +_Bool __builtin_GOMP_loop_ull_static_start(_Bool, unsigned long long, unsigned long long, unsigned long long, unsigned long long, unsigned long long*, unsigned long long*); +_Bool __builtin_GOMP_loop_ull_dynamic_start(_Bool, unsigned long long, unsigned long long, unsigned long long, unsigned long long, unsigned long long*, unsigned long long*); +_Bool __builtin_GOMP_loop_ull_guided_start(_Bool, unsigned long long, unsigned long long, unsigned long long, unsigned long long, unsigned long long*, unsigned long long*); +_Bool __builtin_GOMP_loop_ull_runtime_start(_Bool, unsigned long long, unsigned long long, unsigned long long, unsigned long long*, unsigned long long*); +_Bool __builtin_GOMP_loop_ull_nonmonotonic_dynamic_start(_Bool, unsigned long long, unsigned long long, unsigned long long, unsigned long long, unsigned long long*, unsigned long long*); +_Bool __builtin_GOMP_loop_ull_nonmonotonic_guided_start(_Bool, unsigned long long, unsigned long long, unsigned long long, unsigned long long, unsigned long long*, unsigned long long*); +_Bool __builtin_GOMP_loop_ull_ordered_static_start(_Bool, unsigned long long, unsigned long long, unsigned long long, unsigned long long, unsigned long long*, unsigned long long*); +_Bool __builtin_GOMP_loop_ull_ordered_dynamic_start(_Bool, unsigned long long, unsigned long long, unsigned long long, unsigned long long, unsigned long long*, unsigned long long*); +_Bool __builtin_GOMP_loop_ull_ordered_guided_start(_Bool, unsigned long long, unsigned long long, unsigned long long, unsigned long long, unsigned long long*, unsigned long long*); +_Bool __builtin_GOMP_loop_ull_ordered_runtime_start(_Bool, unsigned long long, unsigned long long, unsigned long long, unsigned long long*, unsigned long long*); +_Bool __builtin_GOMP_loop_ull_doacross_static_start(unsigned, unsigned long long*, unsigned long long, unsigned long long*, unsigned long long*); +_Bool __builtin_GOMP_loop_ull_doacross_dynamic_start(unsigned, unsigned long long*, unsigned long long, unsigned long long*, unsigned long long*); +_Bool __builtin_GOMP_loop_ull_doacross_guided_start(unsigned, unsigned long long*, unsigned long long, unsigned long long*, unsigned long long*); +_Bool __builtin_GOMP_loop_ull_doacross_runtime_start(unsigned, unsigned long long*, unsigned long long*, unsigned long long*); +_Bool __builtin_GOMP_loop_ull_static_next(unsigned long long*, unsigned long long*); +_Bool __builtin_GOMP_loop_ull_dynamic_next(unsigned long long*, unsigned long long*); +_Bool __builtin_GOMP_loop_ull_guided_next(unsigned long long*, unsigned long long*); +_Bool __builtin_GOMP_loop_ull_runtime_next(unsigned long long*, unsigned long long*); +_Bool __builtin_GOMP_loop_ull_nonmonotonic_dynamic_next(unsigned long long*, unsigned long long*); +_Bool __builtin_GOMP_loop_ull_nonmonotonic_guided_next(unsigned long long*, unsigned long long*); +_Bool __builtin_GOMP_loop_ull_ordered_static_next(unsigned long long*, unsigned long long*); +_Bool __builtin_GOMP_loop_ull_ordered_dynamic_next(unsigned long long*, unsigned long long*); +_Bool __builtin_GOMP_loop_ull_ordered_guided_next(unsigned long long*, unsigned long long*); +_Bool __builtin_GOMP_loop_ull_ordered_runtime_next(unsigned long long*, unsigned long long*); +void __builtin_GOMP_loop_end(); +_Bool __builtin_GOMP_loop_end_cancel(); +void __builtin_GOMP_loop_end_nowait(); +void __builtin_GOMP_ordered_start(); +void __builtin_GOMP_ordered_end(); +void __builtin_GOMP_doacross_post(void*); +void __builtin_GOMP_doacross_wait(long, ...); +void __builtin_GOMP_doacross_ull_post(void*); +void __builtin_GOMP_doacross_ull_wait(unsigned long long, ...); +unsigned __builtin_GOMP_sections_start(unsigned); +unsigned __builtin_GOMP_sections_next(); +void __builtin_GOMP_sections_end(); +_Bool __builtin_GOMP_sections_end_cancel(); +void __builtin_GOMP_sections_end_nowait(); +_Bool __builtin_GOMP_single_start(); +void* __builtin_GOMP_single_copy_start(); +void __builtin_GOMP_single_copy_end(void*); +void __builtin_GOMP_offload_register_ver(int, void*, int, void*); +void __builtin_GOMP_offload_unregister_ver(int, void*, int, void*); +void __builtin_GOMP_target_data_ext(int, __CPROVER_size_t, void*, void*, void*); +void __builtin_GOMP_target_end_data(); +void __builtin_GOMP_target_update_ext(int, __CPROVER_size_t, void*, void*, void*, unsigned, void*); +void __builtin_GOMP_target_enter_exit_data(int, __CPROVER_size_t, void*, void*, void*, unsigned, void*); +void __builtin_GOMP_teams(unsigned, unsigned); diff --git a/src/ansi-c/gcc_builtin_headers_tm.h b/src/ansi-c/gcc_builtin_headers_tm.h new file mode 100644 index 00000000000..bee9771f29a --- /dev/null +++ b/src/ansi-c/gcc_builtin_headers_tm.h @@ -0,0 +1,44 @@ +unsigned __builtin__ITM_beginTransaction(unsigned, ...); +void __builtin__ITM_commitTransaction(); +void __builtin__ITM_commitTransactionEH(void*); +void __builtin__ITM_abortTransaction(int); +void __builtin__ITM_changeTransactionMode(int); +void __builtin__ITM_memcpyRtWt(void*, const void*, __CPROVER_size_t); +void __builtin__ITM_memcpyRnWt(void*, const void*, __CPROVER_size_t); +void __builtin__ITM_memcpyRtWn(void*, const void*, __CPROVER_size_t); +void __builtin__ITM_memmoveRtWt(void*, const void*, __CPROVER_size_t); +void __builtin__ITM_memsetW(void*, int, __CPROVER_size_t); +void* __builtin__ITM_malloc(__CPROVER_size_t); +void* __builtin__ITM_calloc(__CPROVER_size_t, __CPROVER_size_t); +void __builtin__ITM_LB(volatile void*, __CPROVER_size_t); +void* __builtin__ITM_getTMCloneOrIrrevocable(void*); +void* __builtin__ITM_getTMCloneSafe(void*); +void __builtin__ITM_free(void*); +void __builtin__ITM_LU1(volatile void*); +void __builtin__ITM_LU2(volatile void*); +void __builtin__ITM_LU4(volatile void*); +void __builtin__ITM_LU8(volatile void*); +void __builtin__ITM_LF(volatile void*); +void __builtin__ITM_LD(volatile void*); +void __builtin__ITM_LE(volatile void*); +void __builtin__ITM_WF(volatile void*, float); +void __builtin__ITM_WaRF(volatile void*, float); +void __builtin__ITM_WaWF(volatile void*, float); +void __builtin__ITM_WD(volatile void*, double); +void __builtin__ITM_WaRD(volatile void*, double); +void __builtin__ITM_WaWD(volatile void*, double); +void __builtin__ITM_WE(volatile void*, long double); +void __builtin__ITM_WaRE(volatile void*, long double); +void __builtin__ITM_WaWE(volatile void*, long double); +float __builtin__ITM_RF(volatile void*); +float __builtin__ITM_RaRF(volatile void*); +float __builtin__ITM_RaWF(volatile void*); +float __builtin__ITM_RfWF(volatile void*); +double __builtin__ITM_RD(double*); +double __builtin__ITM_RaRD(double*); +double __builtin__ITM_RaWD(double*); +double __builtin__ITM_RfWD(double*); +long double __builtin__ITM_RE(volatile void*); +long double __builtin__ITM_RaRE(volatile void*); +long double __builtin__ITM_RaWE(volatile void*); +long double __builtin__ITM_RfWE(volatile void*); diff --git a/src/ansi-c/gcc_builtin_headers_ubsan.h b/src/ansi-c/gcc_builtin_headers_ubsan.h new file mode 100644 index 00000000000..4536f2b1d08 --- /dev/null +++ b/src/ansi-c/gcc_builtin_headers_ubsan.h @@ -0,0 +1,92 @@ +void __builtin___asan_init(); +void __builtin___asan_version_mismatch_check_v8(); +void __builtin___asan_report_load1(void*); +void __builtin___asan_report_load2(void*); +void __builtin___asan_report_load4(void*); +void __builtin___asan_report_load8(void*); +void __builtin___asan_report_load16(void*); +void __builtin___asan_report_store1(void*); +void __builtin___asan_report_store2(void*); +void __builtin___asan_report_store4(void*); +void __builtin___asan_report_store8(void*); +void __builtin___asan_report_store16(void*); +void __builtin___asan_report_load1_noabort(void*); +void __builtin___asan_report_load2_noabort(void*); +void __builtin___asan_report_load4_noabort(void*); +void __builtin___asan_report_load8_noabort(void*); +void __builtin___asan_report_load16_noabort(void*); +void __builtin___asan_report_store1_noabort(void*); +void __builtin___asan_report_store2_noabort(void*); +void __builtin___asan_report_store4_noabort(void*); +void __builtin___asan_report_store8_noabort(void*); +void __builtin___asan_report_store16_noabort(void*); +void __builtin___asan_load1(void*); +void __builtin___asan_load2(void*); +void __builtin___asan_load4(void*); +void __builtin___asan_load8(void*); +void __builtin___asan_load16(void*); +void __builtin___asan_store1(void*); +void __builtin___asan_store2(void*); +void __builtin___asan_store4(void*); +void __builtin___asan_store8(void*); +void __builtin___asan_store16(void*); +void __builtin___asan_load1_noabort(void*); +void __builtin___asan_load2_noabort(void*); +void __builtin___asan_load4_noabort(void*); +void __builtin___asan_load8_noabort(void*); +void __builtin___asan_load16_noabort(void*); +void __builtin___asan_store1_noabort(void*); +void __builtin___asan_store2_noabort(void*); +void __builtin___asan_store4_noabort(void*); +void __builtin___asan_store8_noabort(void*); +void __builtin___asan_store16_noabort(void*); +void __builtin___asan_handle_no_return(); +void __builtin___asan_before_dynamic_init(const void*); +void __builtin___asan_after_dynamic_init(); +void __builtin___tsan_init(); +void __builtin___tsan_func_entry(void*); +void __builtin___tsan_func_exit(void*); +void __builtin___tsan_vptr_update(void*, void*); +void __builtin___tsan_read1(void*); +void __builtin___tsan_read2(void*); +void __builtin___tsan_read4(void*); +void __builtin___tsan_read8(void*); +void __builtin___tsan_read16(void*); +void __builtin___tsan_write1(void*); +void __builtin___tsan_write2(void*); +void __builtin___tsan_write4(void*); +void __builtin___tsan_write8(void*); +void __builtin___tsan_write16(void*); +void __builtin___tsan_atomic_thread_fence(int); +void __builtin___tsan_atomic_signal_fence(int); +void __builtin___ubsan_handle_divrem_overflow(void*, void*, void*); +void __builtin___ubsan_handle_shift_out_of_bounds(void*, void*, void*); +void __builtin___ubsan_handle_builtin_unreachable(void*); +void __builtin___ubsan_handle_missing_return(void*); +void __builtin___ubsan_handle_vla_bound_not_positive(void*, void*); +void __builtin___ubsan_handle_type_mismatch(void*, void*); +void __builtin___ubsan_handle_add_overflow(void*, void*, void*); +void __builtin___ubsan_handle_sub_overflow(void*, void*, void*); +void __builtin___ubsan_handle_mul_overflow(void*, void*, void*); +void __builtin___ubsan_handle_negate_overflow(void*, void*); +void __builtin___ubsan_handle_load_invalid_value(void*, void*); +void __builtin___ubsan_handle_divrem_overflow_abort(void*, void*, void*); +void __builtin___ubsan_handle_shift_out_of_bounds_abort(void*, void*, void*); +void __builtin___ubsan_handle_vla_bound_not_positive_abort(void*, void*); +void __builtin___ubsan_handle_type_mismatch_abort(void*, void*); +void __builtin___ubsan_handle_add_overflow_abort(void*, void*, void*); +void __builtin___ubsan_handle_sub_overflow_abort(void*, void*, void*); +void __builtin___ubsan_handle_mul_overflow_abort(void*, void*, void*); +void __builtin___ubsan_handle_negate_overflow_abort(void*, void*); +void __builtin___ubsan_handle_load_invalid_value_abort(void*, void*); +void __builtin___ubsan_handle_float_cast_overflow(void*, void*); +void __builtin___ubsan_handle_float_cast_overflow_abort(void*, void*); +void __builtin___ubsan_handle_out_of_bounds(void*, void*); +void __builtin___ubsan_handle_out_of_bounds_abort(void*, void*); +void __builtin___ubsan_handle_nonnull_arg(void*); +void __builtin___ubsan_handle_nonnull_arg_abort(void*); +void __builtin___ubsan_handle_nonnull_return(void*); +void __builtin___ubsan_handle_nonnull_return_abort(void*); +void __builtin___ubsan_handle_dynamic_type_cache_miss(void*, void*, void*); +void __builtin___ubsan_handle_dynamic_type_cache_miss_abort(void*, void*, void*); +void __builtin___sanitizer_cov_trace_pc(); diff --git a/src/ansi-c/get-gcc-builtins.sh b/src/ansi-c/get-gcc-builtins.sh index dd02b98c99d..fd06b79945d 100755 --- a/src/ansi-c/get-gcc-builtins.sh +++ b/src/ansi-c/get-gcc-builtins.sh @@ -10,10 +10,11 @@ fi builtin_defs=" \ builtin-types.def builtins.def sync-builtins.def \ omp-builtins.def gtm-builtins.def cilk-builtins.def cilkplus.def \ - sanitizer.def chkp-builtins.def hsa-builtins.def" + sanitizer.def chkp-builtins.def hsa-builtins.def brig-builtins.def \ + config/i386/i386-builtin.def config/i386/i386-builtin-types.def" for f in $builtin_defs ; do - [ ! -s $f ] || continue + [ ! -s `basename $f` ] || continue echo Downloading http://gcc.gnu.org/svn/gcc/trunk/gcc/$f svn export http://gcc.gnu.org/svn/gcc/trunk/gcc/$f > /dev/null done @@ -25,6 +26,31 @@ cat > gcc-builtins.h < #include +typedef char __gcc_v8qi __attribute__ ((__vector_size__ (8))); +typedef char __gcc_v16qi __attribute__ ((__vector_size__ (16))); +typedef char __gcc_v32qi __attribute__ ((__vector_size__ (32))); +typedef char __gcc_v64qi __attribute__ ((__vector_size__ (64))); +typedef int __gcc_v2si __attribute__ ((__vector_size__ (8))); +typedef int __gcc_v4si __attribute__ ((__vector_size__ (16))); +typedef int __gcc_v8si __attribute__ ((__vector_size__ (32))); +typedef int __gcc_v16si __attribute__ ((__vector_size__ (64))); +typedef short __gcc_v4hi __attribute__ ((__vector_size__ (8))); +typedef short __gcc_v8hi __attribute__ ((__vector_size__ (16))); +typedef short __gcc_v16hi __attribute__ ((__vector_size__ (32))); +typedef short __gcc_v32hi __attribute__ ((__vector_size__ (64))); +typedef float __gcc_v2sf __attribute__ ((__vector_size__ (8))); +typedef float __gcc_v4sf __attribute__ ((__vector_size__ (16))); +typedef float __gcc_v8sf __attribute__ ((__vector_size__ (32))); +typedef float __gcc_v16sf __attribute__ ((__vector_size__ (64))); +typedef double __gcc_v2df __attribute__ ((__vector_size__ (16))); +typedef double __gcc_v4df __attribute__ ((__vector_size__ (32))); +typedef double __gcc_v8df __attribute__ ((__vector_size__ (64))); +typedef long long __gcc_v1di __attribute__ ((__vector_size__ (8))); +typedef long long __gcc_v2di __attribute__ ((__vector_size__ (16))); +typedef long long __gcc_v4di __attribute__ ((__vector_size__ (32))); +typedef long long __gcc_v8di __attribute__ ((__vector_size__ (64))); +typedef unsigned long long __gcc_di; + EOF cat > builtins.h < builtins.h < i386-builtin-types-expanded.def + +grep -v '^DEF_FUNCTION_TYPE[[:space:]]' i386-builtin-types.def | \ + grep '^DEF_P' | \ + sed '/^DEF_POINTER_TYPE[^,]*, [^,]*, [^,]*$/ s/_TYPE/_TYPE_CONST/' \ + >> i386-builtin-types-expanded.def + +cat i386-builtin-types.def | \ + sed '/^DEF_FUNCTION_TYPE[[:space:]]/! s/.*//' | \ + sed 's/^DEF_FUNCTION_TYPE[[:space:]]*(\([^,]*\))/\1_FTYPE_VOID/' | \ + sed 's/^DEF_FUNCTION_TYPE[[:space:]]*(\([^,]*\), \(.*\))/\1_FTYPE_\2/' | \ + sed 's/, /_/g' > i386-type-names.def +cat i386-builtin-types.def | tr -c -d ',\n' | awk '{ print length }' | \ + paste - i386-type-names.def i386-builtin-types.def | grep -v '#' | \ + sed 's/^\([0-9]\)[[:space:]]*\([^[:space:]]*\)[[:space:]]*DEF_FUNCTION_TYPE[[:space:]]*(/DEF_FUNCTION_TYPE_\1(\2, /' | \ + grep ^DEF_FUNCTION_TYPE >> i386-builtin-types-expanded.def + +gcc -E builtins.h | sed 's/^NEXTDEF/#define/' | \ + cat - builtins.def i386-builtin.def | \ gcc -E -P - | \ sed 's/MANGLE("__builtin_" "\(.*\)")/__builtin_\1/' | \ + sed 's/MANGLEi386("__builtin_\(.*\)")/__builtin_\1/' | \ + sed 's/^(int) //' | \ sed '/^;$/d' >> gcc-builtins.h -rm $builtin_defs builtins.h +for f in $builtin_defs builtins.h i386-builtin-types-expanded.def i386-type-names.def ; do + rm `basename $f` +done + +sed_is_gnu_sed=0 +if sed --version >/dev/null 2>&1 ; then + # GNU sed + sed_is_gnu_sed=1 +fi # for some we don't know how to handle them - removing symbols should be safe remove_line() { local pattern="$1" - if sed --version >/dev/null 2>&1 ; then - # GNU sed + if [ $sed_is_gnu_sed -eq 1 ] ; then sed -i "/$pattern/d" gcc-builtins.h else sed -i '' "/$pattern/d" gcc-builtins.h @@ -152,9 +226,50 @@ remove_line BT_FN remove_line lang_hooks.types.type_for_mode remove_line __float remove_line pointer_bounds_type_node +remove_line BT_LAST +remove_line BDESC_END +remove_line error_mark_node +remove_line '^0(' +remove_line 'CC.mode(' +remove_line FTYPE +remove_line MULTI_ARG + +ifs=$IFS +IFS=' +' + +while read line ; do + if [ $sed_is_gnu_sed -eq 1 ] ; then + line=`echo "$line" | sed 's/\\([^\.]\)/_Complex\1/g'` + else + line=`echo "$line" | sed 's/[[:<:]]size_t/__CPROVER_size_t/g'` + line=`echo "$line" | sed 's/[[:<:]]complex[[:>:]]\([^\.]\)/_Complex\1/g'` + fi + + if grep -q -F "$line" gcc_builtin_headers_*.h ; then + continue + fi + + bi=`echo "$line" | cut -f1 -d'(' | sed 's/.* //'` + + if [[ $bi =~ __builtin_ia32 ]] ; then + if grep -wq $bi gcc_builtin_headers_ia32*.h ; then + if [ $sed_is_gnu_sed -eq 1 ] ; then + sed -i "/^[^/].*$bi(/ s/.*/$line/" gcc_builtin_headers_ia32*.h + else + sed -i '' "/^[^/].*$bi(/ s/.*/$line/" gcc_builtin_headers_ia32*.h + fi + continue + fi + fi + + echo "$line" >> _gcc-builtins.h +done < gcc-builtins.h +mv _gcc-builtins.h gcc-builtins.h cat gcc-builtins.h | sed 's/__builtin/XX__builtin/' | \ - gcc -c -fno-builtin -x c - -o gcc-builtins.o + gcc -D__CPROVER_size_t=size_t -c -fno-builtin -x c - -o gcc-builtins.o rm gcc-builtins.o echo "Successfully built gcc-builtins.h" diff --git a/src/ansi-c/library/converter.cpp b/src/ansi-c/library/converter.cpp index e114c5c2409..391511cdcd7 100644 --- a/src/ansi-c/library/converter.cpp +++ b/src/ansi-c/library/converter.cpp @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #include #include @@ -57,7 +58,7 @@ int main() std::cout << ch; } - std::cout << "\\n\"" << std::endl; + std::cout << "\\n\"\n"; } } diff --git a/src/ansi-c/library/cprover.h b/src/ansi-c/library/cprover.h index 42c92b7ed7a..251bb828b6f 100644 --- a/src/ansi-c/library/cprover.h +++ b/src/ansi-c/library/cprover.h @@ -1,3 +1,14 @@ +/*******************************************************************\ + +Module: + +Author: Daniel Kroening, kroening@kroening.com + +\*******************************************************************/ + +#ifndef CPROVER_ANSI_C_LIBRARY_CPROVER_H +#define CPROVER_ANSI_C_LIBRARY_CPROVER_H + typedef __typeof__(sizeof(int)) __CPROVER_size_t; void *__CPROVER_malloc(__CPROVER_size_t size); extern const void *__CPROVER_deallocated; @@ -41,11 +52,13 @@ void CBMC_trace(int lvl, const char *event, ...); #endif // pointers -//unsigned __CPROVER_POINTER_OBJECT(const void *p); +unsigned __CPROVER_POINTER_OBJECT(const void *p); signed __CPROVER_POINTER_OFFSET(const void *p); __CPROVER_bool __CPROVER_DYNAMIC_OBJECT(const void *p); #if 0 extern unsigned char __CPROVER_memory[__CPROVER_constant_infinity_uint]; +void __CPROVER_allocated_memory( + __CPROVER_size_t address, __CPROVER_size_t extent); // this is ANSI-C extern __CPROVER_thread_local const char __func__[__CPROVER_constant_infinity_uint]; @@ -79,6 +92,7 @@ double __CPROVER_inf(void); float __CPROVER_inff(void); long double __CPROVER_infl(void); //extern int __CPROVER_thread_local __CPROVER_rounding_mode; +int __CPROVER_isgreaterd(double f, double g); // absolute value int __CPROVER_abs(int); @@ -91,7 +105,8 @@ float __CPROVER_fabsf(float); // arrays //__CPROVER_bool __CPROVER_array_equal(const void *array1, const void *array2); void __CPROVER_array_copy(const void *dest, const void *src); -//void __CPROVER_array_set(const void *dest, ...); +void __CPROVER_array_set(const void *dest, ...); +void __CPROVER_array_replace(const void *dest, const void *src); #if 0 // k-induction @@ -130,3 +145,5 @@ __CPROVER_bool __CPROVER_get_may(const void *, const char *); #define __CPROVER_danger_max_solution_size 1 #define __CPROVER_danger_number_of_vars 1 #define __CPROVER_danger_number_of_consts 1 + +#endif // CPROVER_ANSI_C_LIBRARY_CPROVER_H diff --git a/src/ansi-c/library/float.c b/src/ansi-c/library/float.c index ef82057ab44..204ad8d9627 100644 --- a/src/ansi-c/library/float.c +++ b/src/ansi-c/library/float.c @@ -67,3 +67,19 @@ inline int _isnan(double x) { return __CPROVER_isnand(x); } + +/* FUNCTION: __builtin_flt_rounds */ + +extern int __CPROVER_rounding_mode; + +inline int __builtin_flt_rounds(void) +{ + // This is a clang builtin for FLT_ROUNDS + // The magic numbers are C99 and different from the + // x86 encoding that CPROVER uses. + return __CPROVER_rounding_mode==0?1: // to nearest + __CPROVER_rounding_mode==1?3: // downward + __CPROVER_rounding_mode==2?2: // upward + __CPROVER_rounding_mode==3?0: // to zero + -1; +} diff --git a/src/ansi-c/library/getopt.c b/src/ansi-c/library/getopt.c index d3eedda9814..458f9d2e414 100644 --- a/src/ansi-c/library/getopt.c +++ b/src/ansi-c/library/getopt.c @@ -3,22 +3,67 @@ extern char *optarg; extern int optind; +#ifndef __CPROVER_STRING_H_INCLUDED +#include +#define __CPROVER_STRING_H_INCLUDED +#endif + inline int getopt(int argc, char * const argv[], const char *optstring) { __CPROVER_HIDE:; - int result_index; - __CPROVER_assume(result_index>=0); - (void)*optstring; - if(optind>=argc) + int result=-1; + + if(optind==0) + optind=1; + + if(optind>=argc || argv[optind][0]!='-') return -1; - __CPROVER_assume(result_index=optind); + + size_t result_index; + __CPROVER_assume( + result_index g; } + +/* FUNCTION: __CPROVER_isgreaterd */ + +int __CPROVER_isgreaterd(double f, double g) { return f > g; } + +/* FUNCTION: __CPROVER_isgreaterequalf */ + +int __CPROVER_isgreaterequalf(float f, float g) { return f >= g; } + +/* FUNCTION: __CPROVER_isgreaterequald */ + +int __CPROVER_isgreaterequald(double f, double g) { return f >= g; } + +/* FUNCTION: __CPROVER_islessf */ + +int __CPROVER_islessf(float f, float g) { return f < g;} + +/* FUNCTION: __CPROVER_islessd */ + +int __CPROVER_islessd(double f, double g) { return f < g;} + +/* FUNCTION: __CPROVER_islessequalf */ + +int __CPROVER_islessequalf(float f, float g) { return f <= g; } + +/* FUNCTION: __CPROVER_islessequald */ + +int __CPROVER_islessequald(double f, double g) { return f <= g; } + +/* FUNCTION: __CPROVER_islessgreaterf */ + +int __CPROVER_islessgreaterf(float f, float g) { return (f < g) || (f > g); } + +/* FUNCTION: __CPROVER_islessgreaterd */ + +int __CPROVER_islessgreaterd(double f, double g) { return (f < g) || (f > g); } + +/* FUNCTION: __CPROVER_isunorderedf */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +int __CPROVER_isunorderedf(float f, float g) { return isnanf(f) || isnanf(g); } + +/* FUNCTION: __CPROVER_isunorderedd */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +int __CPROVER_isunorderedd(double f, double g) { return isnan(f) || isnan(g); } + + /* FUNCTION: isfinite */ +#undef isfinite + int isfinite(double d) { return __CPROVER_isfinited(d); } /* FUNCTION: __finite */ @@ -40,6 +101,8 @@ int __finitel(long double ld) { return __CPROVER_isfiniteld(ld); } /* FUNCTION: isinf */ +#undef isinf + inline int isinf(double d) { return __CPROVER_isinfd(d); } /* FUNCTION: __isinf */ @@ -64,6 +127,8 @@ inline int __isinfl(long double ld) { return __CPROVER_isinfld(ld); } /* FUNCTION: isnan */ +#undef isnan + inline int isnan(double d) { return __CPROVER_isnand(d); } /* FUNCTION: __isnan */ @@ -88,6 +153,8 @@ inline int __isnanl(long double ld) { return __CPROVER_isnanld(ld); } /* FUNCTION: isnormal */ +#undef isnormal + inline int isnormal(double d) { return __CPROVER_isnormald(d); } /* FUNCTION: __isnormalf */ @@ -152,6 +219,8 @@ inline int _fdsign(float f) { return __CPROVER_signf(f); } /* FUNCTION: signbit */ +#undef signbit + inline int signbit(double d) { return __CPROVER_signd(d); } /* FUNCTION: __signbitd */ @@ -423,10 +492,70 @@ float __builtin_nanf(const char *str) { // the 'str' argument is not yet used __CPROVER_hide:; + (void)*str; + return 0.0f/0.0f; +} + + +/* ISO 9899:2011 + * The call nan("n-char-sequence") is equivalent to + * strtod("NAN(n-char-sequence)", (char**) NULL); the call nan("") is + * equivalent to strtod("NAN()", (char**) NULL). If tagp does not + * point to an n-char sequence or an empty string, the call is + * equivalent to strtod("NAN", (char**) NULL). Calls to nanf and nanl + * are equivalent to the corresponding calls to strtof and strtold. + * + * The nan functions return a quiet NaN, if available, with content + * indicated through tagp. If the implementation does not support + * quiet NaNs, the functions return zero. + */ + +/* FUNCTION: nan */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +double nan(const char *str) { + // the 'str' argument is not yet used + __CPROVER_hide:; + (void)*str; + return 0.0/0.0; +} + +/* FUNCTION: nanf */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +float nanf(const char *str) { + // the 'str' argument is not yet used + __CPROVER_hide:; + (void)*str; + return 0.0f/0.0f; +} + +/* FUNCTION: nanl */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +long double nanl(const char *str) { + // the 'str' argument is not yet used + __CPROVER_hide:; (void)*str; return 0.0/0.0; } + + + + /* FUNCTION: nextUpf */ #ifndef __CPROVER_LIMITS_H_INCLUDED @@ -575,6 +704,7 @@ __CPROVER_hide:; --m.bv; return m.f; } + } @@ -608,8 +738,6 @@ __CPROVER_hide:; float nextUpf(float f); -extern int __CPROVER_rounding_mode; - float sqrtf(float f) { __CPROVER_hide:; @@ -645,7 +773,7 @@ float sqrtf(float f) __CPROVER_assume(f < upperSquare); // Select between them to work out which to return - switch(__CPROVER_rounding_mode) + switch(fegetround()) { case FE_TONEAREST : return (f - lowerSquare < upperSquare - f) ? lower : upper; break; @@ -720,7 +848,7 @@ double sqrt(double d) __CPROVER_assume(lowerSquare <= d); __CPROVER_assume(d < upperSquare); - switch(__CPROVER_rounding_mode) + switch(fegetround()) { case FE_TONEAREST: return (d - lowerSquare < upperSquare - d) ? lower : upper; break; @@ -789,7 +917,7 @@ long double sqrtl(long double d) __CPROVER_assume(lowerSquare <= d); __CPROVER_assume(d < upperSquare); - switch(__CPROVER_rounding_mode) + switch(fegetround()) { case FE_TONEAREST: return (d - lowerSquare < upperSquare - d) ? lower : upper; break; @@ -816,3 +944,1381 @@ long double sqrtl(long double d) return root; } } + + +/* ISO 9899:2011 + * The fmax functions determine the maximum numeric value of their + * arguments. 242) + * + * 242) NaN arguments are treated as missing data: if one argument is + * a NaN and the other numeric, then the fmax functions choose the + * numeric value. See F.10.9.2. + * + * - If just one argument is a NaN, the fmax functions return the other + * argument (if both arguments are NaNs, the functions return a NaN). + * - The returned value is exact and is independent of the current + * rounding direction mode. + * - The body of the fmax function might be 374) + * { return (isgreaterequal(x, y) || isnan(y)) ? x : y; } + * + * 374) Ideally, fmax would be sensitive to the sign of zero, for + * example fmax(-0.0, +0.0) would return +0; however, implementation + * in software might be impractical. + */ + +/* FUNCTION: fmax */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +// TODO : Should call a __CPROVER_function so that it can be converted to SMT-LIB +double fmax(double f, double g) { return ((f >= g) || isnan(g)) ? f : g; } + +/* FUNCTION : fmaxf */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +// TODO : Should call a __CPROVER_function so that it can be converted to SMT-LIB +float fmaxf(float f, float g) { return ((f >= g) || isnan(g)) ? f : g; } + + +/* FUNCTION : fmaxl */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +// TODO : Should call a __CPROVER_function so that it can be converted to SMT-LIB +long double fmaxl(long double f, long double g) { return ((f >= g) || isnan(g)) ? f : g; } + + +/* ISO 9899:2011 + * The fmin functions determine the minimum numeric value of their + * arguments.243) + * + * 243) The fmin functions are analogous to the fmax functions in + * their treatment of NaNs. + * + * - The fmin functions are analogous to the fmax functions (see F.10.9.2). + * - The returned value is exact and is independent of the current + * rounding direction mode. + */ + +/* FUNCTION: fmin */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +// TODO : Should call a __CPROVER_function so that it can be converted to SMT-LIB +double fmin(double f, double g) { return ((f <= g) || isnan(g)) ? f : g; } + +/* FUNCTION: fminf */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +// TODO : Should call a __CPROVER_function so that it can be converted to SMT-LIB +float fminf(float f, float g) { return ((f <= g) || isnan(g)) ? f : g; } + +/* FUNCTION: fminl */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +// TODO : Should call a __CPROVER_function so that it can be converted to SMT-LIB +long double fminl(long double f, long double g) { return ((f <= g) || isnan(g)) ? f : g; } + + +/* ISO 9899:2011 + * The fdim functions determine the positive difference between their + * arguments: + * x - y if x > y + * +0 if x <= y + * A range error may occur. + */ + +/* FUNCTION: fdim */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +double fdim(double f, double g) { return ((f > g) ? f - g : +0.0); } + + +/* FUNCTION: fdimf */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +float fdimf(float f, float g) { return ((f > g) ? f - g : +0.0f); } + + +/* FUNCTION: fdiml */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +long double fdiml(long double f, long double g) { return ((f > g) ? f - g : +0.0); } + + + +/* FUNCTION: __sort_of_CPROVER_round_to_integral */ +// TODO : Should be a real __CPROVER function to convert to SMT-LIB + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +double __sort_of_CPROVER_round_to_integral (int rounding_mode, double d) +{ + double magicConst = 0x1.0p+52; + double return_value; + int saved_rounding_mode = fegetround(); + fesetround(rounding_mode); + + if (fabs(d) >= magicConst || d == 0.0) + { + return_value = d; + } + else + { + if (!signbit(d)) { + double tmp = d + magicConst; + return_value = tmp - magicConst; + } else { + double tmp = d - magicConst; + return_value = tmp + magicConst; + } + } + + fesetround(saved_rounding_mode); + return return_value; +} + +/* FUNCTION: __sort_of_CPROVER_round_to_integralf */ +// TODO : Should be a real __CPROVER function to convert to SMT-LIB + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +float __sort_of_CPROVER_round_to_integralf (int rounding_mode, float d) +{ + float magicConst = 0x1.0p+23f; // 23 is significant + float return_value; + int saved_rounding_mode = fegetround(); + fesetround(rounding_mode); + + if (fabsf(d) >= magicConst || d == 0.0) + { + return_value = d; + } + else + { + if (!signbit(d)) { + float tmp = d + magicConst; + return_value = tmp - magicConst; + } else { + float tmp = d - magicConst; + return_value = tmp + magicConst; + } + } + + fesetround(saved_rounding_mode); + return return_value; +} + + +/* FUNCTION: __sort_of_CPROVER_round_to_integrall */ +// TODO : Should be a real __CPROVER function to convert to SMT-LIB + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +long double __sort_of_CPROVER_round_to_integrall (int rounding_mode, long double d) +{ + long double magicConst = 0x1.0p+64; + long double return_value; + int saved_rounding_mode = fegetround(); + fesetround(rounding_mode); + + if (fabsl(d) >= magicConst || d == 0.0) + { + return_value = d; + } + else + { + if (!signbit(d)) { + long double tmp = d + magicConst; + return_value = tmp - magicConst; + } else { + long double tmp = d - magicConst; + return_value = tmp + magicConst; + } + } + + fesetround(saved_rounding_mode); + return return_value; +} + +/* ISO 9899:2011 + * + * The ceil functions compute the smallest integer value not less than + * x. + */ + +/* FUNCTION: ceil */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +double __sort_of_CPROVER_round_to_integral (int rounding_mode, double d); + +double ceil(double x) +{ + return __sort_of_CPROVER_round_to_integral(FE_UPWARD, x); +} + +/* FUNCTION: ceilf */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +float __sort_of_CPROVER_round_to_integralf (int rounding_mode, float d); + +float ceilf(float x) +{ + return __sort_of_CPROVER_round_to_integralf(FE_UPWARD, x); +} + + +/* FUNCTION: ceill */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +long double __sort_of_CPROVER_round_to_integrall (int rounding_mode, long double d); + +long double ceill(long double x) +{ + return __sort_of_CPROVER_round_to_integrall(FE_UPWARD, x); +} + + +/* ISO 9899:2011 + * + * The floor functions compute the largest integer value not greater than x. + */ + +/* FUNCTION: floor */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +double __sort_of_CPROVER_round_to_integral (int rounding_mode, double d); + +double floor(double x) +{ + return __sort_of_CPROVER_round_to_integral(FE_DOWNWARD, x); +} + +/* FUNCTION: floorf */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +float __sort_of_CPROVER_round_to_integralf (int rounding_mode, float d); + +float floorf(float x) +{ + return __sort_of_CPROVER_round_to_integralf(FE_DOWNWARD, x); +} + + +/* FUNCTION: floorl */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +long double __sort_of_CPROVER_round_to_integrall (int rounding_mode, long double d); + +long double floorl(long double x) +{ + return __sort_of_CPROVER_round_to_integrall(FE_DOWNWARD, x); +} + + +/* ISO 9899:2011 + * + * The trunc functions round their argument to the integer value, in + * floating format, nearest to but no larger in magnitude than the argument. + */ + +/* FUNCTION: trunc */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +double __sort_of_CPROVER_round_to_integral (int rounding_mode, double d); + +double trunc(double x) +{ + return __sort_of_CPROVER_round_to_integral(FE_TOWARDZERO, x); +} + +/* FUNCTION: truncf */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +float __sort_of_CPROVER_round_to_integralf (int rounding_mode, float d); + +float truncf(float x) +{ + return __sort_of_CPROVER_round_to_integralf(FE_TOWARDZERO, x); +} + + +/* FUNCTION: truncl */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +long double __sort_of_CPROVER_round_to_integrall (int rounding_mode, long double d); + +long double truncl(long double x) +{ + return __sort_of_CPROVER_round_to_integrall(FE_TOWARDZERO, x); +} + + +/* ISO 9899:2011 + * + * The round functions round their argument to the integer value, in + * floating format, nearest to but no larger in magnitude than the argument. + */ + +/* FUNCTION: round */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +double __sort_of_CPROVER_round_to_integral (int rounding_mode, double d); + +double round(double x) +{ + // Tempting but RNE not RNA + // return __sort_of_CPROVER_round_to_integral(FE_TONEAREST, x); + + int saved_rounding_mode = fegetround(); + fesetround(FE_TOWARDZERO); + + double xp; + if (x > 0.0) { + xp = x + 0.5; + } else if (x < 0.0) { + xp = x - 0.5; + } else { + xp = x; + } + + fesetround(saved_rounding_mode); + + return __sort_of_CPROVER_round_to_integral(FE_TOWARDZERO, xp); +} + +/* FUNCTION: roundf */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +float __sort_of_CPROVER_round_to_integralf (int rounding_mode, float d); + +float roundf(float x) +{ + // Tempting but RNE not RNA + // return __sort_of_CPROVER_round_to_integralf(FE_TONEAREST, x); + + int saved_rounding_mode = fegetround(); + fesetround(FE_TOWARDZERO); + + float xp; + if (x > 0.0f) { + xp = x + 0.5f; + } else if (x < 0.0f) { + xp = x - 0.5f; + } else { + xp = x; + } + + fesetround(saved_rounding_mode); + + return __sort_of_CPROVER_round_to_integralf(FE_TOWARDZERO, xp); +} + + +/* FUNCTION: roundl */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +long double __sort_of_CPROVER_round_to_integrall (int rounding_mode, long double d); + +long double roundl(long double x) +{ + // Tempting but RNE not RNA + // return __sort_of_CPROVER_round_to_integrall(FE_TONEAREST, x); + + int saved_rounding_mode = fegetround(); + fesetround(FE_TOWARDZERO); + + long double xp; + if (x > 0.0) { + xp = x + 0.5; + } else if (x < 0.0) { + xp = x - 0.5; + } else { + xp = x; + } + + fesetround(saved_rounding_mode); + + return __sort_of_CPROVER_round_to_integrall(FE_TOWARDZERO, xp); +} + + + +/* ISO 9899:2011 + * + * The nearbyint functions round their argument to an integer value in + * floating-point format, using the current rounding direction and + * without raising the inexact floating-point exception. + */ + +/* FUNCTION: nearbyint */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +double __sort_of_CPROVER_round_to_integral (int rounding_mode, double d); + +double nearbyint(double x) +{ + return __sort_of_CPROVER_round_to_integral(fegetround(), x); +} + +/* FUNCTION: nearbyintf */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +float __sort_of_CPROVER_round_to_integralf (int rounding_mode, float d); + +float nearbyintf(float x) +{ + return __sort_of_CPROVER_round_to_integralf(fegetround(), x); +} + + +/* FUNCTION: nearbyintl */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +long double __sort_of_CPROVER_round_to_integrall (int rounding_mode, long double d); + +long double nearbyintl(long double x) +{ + return __sort_of_CPROVER_round_to_integrall(fegetround(), x); +} + + + +/* ISO 9899:2011 + * + * The rint functions differ from the nearbyint functions (7.12.9.3) + * only in that the rint functions may raise the inexact + * floating-point exception if the result differs in value from the argument. + */ + +/* FUNCTION: rint */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +double __sort_of_CPROVER_round_to_integral (int rounding_mode, double d); + +double rint(double x) +{ + return __sort_of_CPROVER_round_to_integral(fegetround(), x); +} + +/* FUNCTION: rintf */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +float __sort_of_CPROVER_round_to_integralf (int rounding_mode, float d); + +float rintf(float x) +{ + return __sort_of_CPROVER_round_to_integralf(fegetround(), x); +} + +/* FUNCTION: rintl */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +long double __sort_of_CPROVER_round_to_integrall (int rounding_mode, long double d); + +long double rintl(long double x) +{ + return __sort_of_CPROVER_round_to_integrall(fegetround(), x); +} + + + +/* ISO 9899:2011 + * + * The lrint and llrint functions round their argument to the nearest + * integer value, rounding according to the current rounding + * direction. If the rounded value is outside the range of the return + * type, the numeric result is unspecified and a domain error or range + * error may occur. + */ + +/* FUNCTION: lrint */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +double __sort_of_CPROVER_round_to_integral (int rounding_mode, double d); + +long int lrint(double x) +{ + // TODO : should be an all-in-one __CPROVER function to allow + // conversion to SMT + double rti = __sort_of_CPROVER_round_to_integral(fegetround(), x); + return (long int)rti; +} + +/* FUNCTION: lrintf */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +float __sort_of_CPROVER_round_to_integralf (int rounding_mode, float d); + +long int lrintf(float x) +{ + // TODO : should be an all-in-one __CPROVER function to allow + // conversion to SMT + float rti = __sort_of_CPROVER_round_to_integralf(fegetround(), x); + return (long int)rti; +} + + +/* FUNCTION: lrintl */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +long double __sort_of_CPROVER_round_to_integrall (int rounding_mode, long double d); + +long int lrintl(long double x) +{ + // TODO : should be an all-in-one __CPROVER function to allow + // conversion to SMT + long double rti = __sort_of_CPROVER_round_to_integrall(fegetround(), x); + return (long int)rti; +} + + +/* FUNCTION: llrint */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +double __sort_of_CPROVER_round_to_integral (int rounding_mode, double d); + +long long int llrint(double x) +{ + // TODO : should be an all-in-one __CPROVER function to allow + // conversion to SMT + double rti = __sort_of_CPROVER_round_to_integral(fegetround(), x); + return (long long int)rti; +} + +/* FUNCTION: llrintf */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +float __sort_of_CPROVER_round_to_integralf (int rounding_mode, float d); + +long long int llrintf(float x) +{ + // TODO : should be an all-in-one __CPROVER function to allow + // conversion to SMT + float rti = __sort_of_CPROVER_round_to_integralf(fegetround(), x); + return (long long int)rti; +} + + +/* FUNCTION: llrintl */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +long double __sort_of_CPROVER_round_to_integrall (int rounding_mode, long double d); + +long long int llrintl(long double x) +{ + // TODO : should be an all-in-one __CPROVER function to allow + // conversion to SMT + long double rti = __sort_of_CPROVER_round_to_integrall(fegetround(), x); + return (long long int)rti; +} + + +/* ISO 9899:2011 + * + * The lround and llround functions round their argument to the + * nearest integer value, rounding halfway cases away from zero, + * regardless of the current rounding direction. If the rounded value + * is outside the range of the return type, the numeric result is + * unspecified and a domain error or range error may occur. + */ + +/* FUNCTION: lround */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +double __sort_of_CPROVER_round_to_integral (int rounding_mode, double d); + +long int lround(double x) +{ + // TODO : should be an all-in-one __CPROVER function to allow + // conversion to SMT, plus should use RNA + + int saved_rounding_mode = fegetround(); + fesetround(FE_TOWARDZERO); + + double xp; + if (x > 0.0) { + xp = x + 0.5; + } else if (x < 0.0) { + xp = x - 0.5; + } else { + xp = x; + } + + fesetround(saved_rounding_mode); + + double rti = __sort_of_CPROVER_round_to_integral(FE_TOWARDZERO, xp); + return (long int)rti; +} + +/* FUNCTION: lroundf */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +float __sort_of_CPROVER_round_to_integralf (int rounding_mode, float d); + +long int lroundf(float x) +{ + // TODO : should be an all-in-one __CPROVER function to allow + // conversion to SMT, plus should use RNA + int saved_rounding_mode = fegetround(); + fesetround(FE_TOWARDZERO); + + float xp; + if (x > 0.0f) { + xp = x + 0.5f; + } else if (x < 0.0f) { + xp = x - 0.5f; + } else { + xp = x; + } + + fesetround(saved_rounding_mode); + + float rti = __sort_of_CPROVER_round_to_integralf(FE_TOWARDZERO, xp); + return (long int)rti; +} + + +/* FUNCTION: lroundl */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +long double __sort_of_CPROVER_round_to_integrall (int rounding_mode, long double d); + +long int lroundl(long double x) +{ + int saved_rounding_mode = fegetround(); + fesetround(FE_TOWARDZERO); + + // TODO : should be an all-in-one __CPROVER function to allow + // conversion to SMT, plus should use RNA + long double xp; + if (x > 0.0) { + xp = x + 0.5; + } else if (x < 0.0) { + xp = x - 0.5; + } else { + xp = x; + } + + fesetround(saved_rounding_mode); + + long double rti = __sort_of_CPROVER_round_to_integrall(FE_TOWARDZERO, xp); + return (long int)rti; +} + + +/* FUNCTION: llround */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +double __sort_of_CPROVER_round_to_integral (int rounding_mode, double d); + +long long int llround(double x) +{ + // TODO : should be an all-in-one __CPROVER function to allow + // conversion to SMT, plus should use RNA + int saved_rounding_mode = fegetround(); + fesetround(FE_TOWARDZERO); + + double xp; + if (x > 0.0) { + xp = x + 0.5; + } else if (x < 0.0) { + xp = x - 0.5; + } else { + xp = x; + } + + fesetround(saved_rounding_mode); + + double rti = __sort_of_CPROVER_round_to_integral(FE_TOWARDZERO, xp); + return (long long int)rti; +} + +/* FUNCTION: llroundf */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +float __sort_of_CPROVER_round_to_integralf (int rounding_mode, float d); + +long long int llroundf(float x) +{ + // TODO : should be an all-in-one __CPROVER function to allow + // conversion to SMT, plus should use RNA + int saved_rounding_mode = fegetround(); + fesetround(FE_TOWARDZERO); + + float xp; + if (x > 0.0f) { + xp = x + 0.5f; + } else if (x < 0.0f) { + xp = x - 0.5f; + } else { + xp = x; + } + + fesetround(saved_rounding_mode); + + float rti = __sort_of_CPROVER_round_to_integralf(FE_TOWARDZERO, xp); + return (long long int)rti; +} + + +/* FUNCTION: llroundl */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +long double __sort_of_CPROVER_round_to_integrall (int rounding_mode, long double d); + +long long int llroundl(long double x) +{ + // TODO : should be an all-in-one __CPROVER function to allow + // conversion to SMT, plus should use RNA + int saved_rounding_mode = fegetround(); + fesetround(FE_TOWARDZERO); + + long double xp; + if (x > 0.0) { + xp = x + 0.5; + } else if (x < 0.0) { + xp = x - 0.5; + } else { + xp = x; + } + + fesetround(saved_rounding_mode); + + long double rti = __sort_of_CPROVER_round_to_integrall(FE_TOWARDZERO, xp); + return (long long int)rti; +} + + +/* ISO 9899:2011 + * + * The modf functions break the argument value into integral and + * fractional parts, each of which has the same type and sign as the + * argument. They store the integral part (in floating-point format) + * in the object pointed to by iptr. + */ + +/* FUNCTION: modf */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +double __sort_of_CPROVER_round_to_integral (int rounding_mode, double d); + +double modf(double x, double *iptr) +{ + *iptr = __sort_of_CPROVER_round_to_integral(FE_TOWARDZERO, x); + return (x - *iptr); +} + +/* FUNCTION: modff */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +float __sort_of_CPROVER_round_to_integralf (int rounding_mode, float d); + + float modff(float x, float *iptr) +{ + *iptr = __sort_of_CPROVER_round_to_integralf(FE_TOWARDZERO, x); + return (x - *iptr); +} + + +/* FUNCTION: modfl */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +long double __sort_of_CPROVER_round_to_integrall (int rounding_mode, long double d); + + long double modfl(long double x, long double *iptr) +{ + *iptr = __sort_of_CPROVER_round_to_integralf(FE_TOWARDZERO, x); + return (x - *iptr); +} + + + +/* FUNCTION: __sort_of_CPROVER_remainder */ +// TODO : Should be a real __CPROVER function to convert to SMT-LIB +double __sort_of_CPROVER_round_to_integral (int rounding_mode, double d); + +double __sort_of_CPROVER_remainder (int rounding_mode, double x, double y) +{ + if (x == 0.0 || __CPROVER_isinfd(y)) + return x; + + // Extended precision helps... a bit... + long double div = x/y; + long double n = __sort_of_CPROVER_round_to_integral(rounding_mode,div); + long double res = (-y * n) + x; // TODO : FMA would be an improvement + return res; +} + +/* FUNCTION: __sort_of_CPROVER_remainderf */ +// TODO : Should be a real __CPROVER function to convert to SMT-LIB + +float __sort_of_CPROVER_round_to_integralf (int rounding_mode, float d); + +float __sort_of_CPROVER_remainderf (int rounding_mode, float x, float y) +{ + if (x == 0.0f || __CPROVER_isinff(y)) + return x; + + // Extended precision helps... a bit... + long double div = x/y; + long double n = __sort_of_CPROVER_round_to_integral(rounding_mode,div); + long double res = (-y * n) + x; // TODO : FMA would be an improvement + return res; +} + +/* FUNCTION: __sort_of_CPROVER_remainderl */ +// TODO : Should be a real __CPROVER function to convert to SMT-LIB + +long double __sort_of_CPROVER_round_to_integrall (int rounding_mode, long double d); + +long double __sort_of_CPROVER_remainderl (int rounding_mode, long double x, long double y) +{ + if (x == 0.0 || __CPROVER_isinfld(y)) + return x; + + // Extended precision helps... a bit... + long double div = x/y; + long double n = __sort_of_CPROVER_round_to_integral(rounding_mode,div); + long double res = (-y * n) + x; // TODO : FMA would be an improvement + return res; +} + + + +/* ISO 9899:2011 + * + * The fmod functions return the value x - ny, for some + * integer n such that, if y is nonzero, the result has the same sign + * as x and magnitude less than the magnitude of y. If y is zero, + * whether a domain error occurs or the fmod functions return zero is + * implementation-defined. + */ + +/* FUNCTION: fmod */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +double __sort_of_CPROVER_remainder (int rounding_mode, double x, double y); + +double fmod(double x, double y) { return __sort_of_CPROVER_remainder(FE_TOWARDZERO, x, y); } + + +/* FUNCTION: fmodf */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +float __sort_of_CPROVER_remainderf (int rounding_mode, float x, float y); + +float fmodf(float x, float y) { return __sort_of_CPROVER_remainderf(FE_TOWARDZERO, x, y); } + + +/* FUNCTION: fmodl */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +long double __sort_of_CPROVER_remainderl (int rounding_mode, long double x, long double y); + +long double fmodl(long double x, long double y) { return __sort_of_CPROVER_remainderl(FE_TOWARDZERO, x, y); } + + + +/* ISO 9899:2011 + * + * The remainder functions compute the remainder x REM y required by + * IEC 60559.239) + * + * 239) "When y != 0, the remainder r = x REM y is defined regardless + * of the rounding mode by the mathematical relation r = x - n + * y, where n is the integer nearest the exact value of x/y; + * whenever | n - x/y | = 1/2, then n is even. If r = 0, its + * sign shall be that of x." This definition is applicable for + * all implementations. + */ + +/* FUNCTION: remainder */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +double __sort_of_CPROVER_remainder (int rounding_mode, double x, double y); + +double remainder(double x, double y) { return __sort_of_CPROVER_remainder(FE_TONEAREST, x, y); } + + +/* FUNCTION: remainderf */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +float __sort_of_CPROVER_remainderf (int rounding_mode, float x, float y); + +float remainderf(float x, float y) { return __sort_of_CPROVER_remainderf(FE_TONEAREST, x, y); } + + +/* FUNCTION: remainderl */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +#ifndef __CPROVER_FENV_H_INCLUDED +#include +#define __CPROVER_FENV_H_INCLUDED +#endif + +long double __sort_of_CPROVER_remainderl (int rounding_mode, long double x, long double y); + +long double remainderl(long double x, long double y) { return __sort_of_CPROVER_remainderl(FE_TONEAREST, x, y); } + + + + +/* ISO 9899:2011 + * The copysign functions produce a value with the magnitude of x and + * the sign of y. They produce a NaN (with the sign of y) if x is a + * NaN. On implementations that represent a signed zero but do not + * treat negative zero consistently in arithmetic operations, the + * copysign functions regard the sign of zero as positive. + */ + +/* FUNCTION: copysign */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +double fabs (double d); + +double copysign(double x, double y) +{ + double abs = fabs(x); + return (signbit(y)) ? -abs : abs; +} + +/* FUNCTION: copysignf */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +float fabsf (float d); + +float copysignf(float x, float y) +{ + float abs = fabs(x); + return (signbit(y)) ? -abs : abs; +} + +/* FUNCTION: copysignl */ + +#ifndef __CPROVER_MATH_H_INCLUDED +#include +#define __CPROVER_MATH_H_INCLUDED +#endif + +long double fabsl (long double d); + +long double copysignl(long double x, long double y) +{ + long double abs = fabs(x); + return (signbit(y)) ? -abs : abs; +} + + + diff --git a/src/ansi-c/library/stdio.c b/src/ansi-c/library/stdio.c index 5a9ab1e9d57..0472908d744 100644 --- a/src/ansi-c/library/stdio.c +++ b/src/ansi-c/library/stdio.c @@ -65,7 +65,14 @@ inline FILE *fopen(const char *filename, const char *mode) FILE *fopen_result; _Bool fopen_error; + + #if !defined(__linux__) || defined(__GLIBC__) fopen_result=fopen_error?NULL:malloc(sizeof(FILE)); + #else + // libraries need to expose the definition of FILE; this is the + // case for musl + fopen_result=fopen_error?NULL:malloc(sizeof(int)); + #endif #ifdef __CPROVER_CUSTOM_BITVECTOR_ANALYSIS __CPROVER_set_must(fopen_result, "open"); @@ -99,6 +106,11 @@ inline FILE* freopen(const char *filename, const char *mode, FILE *f) #define __CPROVER_STDIO_H_INCLUDED #endif +#ifndef __CPROVER_STDLIB_H_INCLUDED +#include +#define __CPROVER_STDLIB_H_INCLUDED +#endif + inline int fclose(FILE *stream) { __CPROVER_HIDE:; @@ -135,11 +147,48 @@ inline FILE *fdopen(int handle, const char *mode) "fdopen zero-termination of 2nd argument"); #endif + #if !defined(__linux__) || defined(__GLIBC__) FILE *f=malloc(sizeof(FILE)); + #else + // libraries need to expose the definition of FILE; this is the + // case for musl + FILE *f=malloc(sizeof(int)); + #endif return f; } +/* FUNCTION: _fdopen */ + +// This is for Apple + +#ifndef __CPROVER_STDIO_H_INCLUDED +#include +#define __CPROVER_STDIO_H_INCLUDED +#endif + +#ifndef __CPROVER_STDLIB_H_INCLUDED +#include +#define __CPROVER_STDLIB_H_INCLUDED +#endif + +#ifdef __APPLE__ +inline FILE *_fdopen(int handle, const char *mode) +{ + __CPROVER_HIDE:; + (void)handle; + (void)*mode; + #ifdef __CPROVER_STRING_ABSTRACTION + __CPROVER_assert(__CPROVER_is_zero_string(mode), + "fdopen zero-termination of 2nd argument"); + #endif + + FILE *f=malloc(sizeof(FILE)); + + return f; +} +#endif + /* FUNCTION: fgets */ #ifndef __CPROVER_STDIO_H_INCLUDED @@ -147,7 +196,7 @@ inline FILE *fdopen(int handle, const char *mode) #define __CPROVER_STDIO_H_INCLUDED #endif -inline char *fgets(char *str, int size, FILE *stream) +char *fgets(char *str, int size, FILE *stream) { __CPROVER_HIDE:; __CPROVER_bool error; @@ -169,6 +218,16 @@ inline char *fgets(char *str, int size, FILE *stream) __CPROVER_is_zero_string(str)=!error; __CPROVER_zero_string_length(str)=resulting_size; } + #else + if(size>0) + { + int str_length; + __CPROVER_assume(str_length>=0 && str_length +#define __CPROVER_STDIO_H_INCLUDED +#endif + +#ifndef __CPROVER_STDARG_H_INCLUDED +#include +#define __CPROVER_STDARG_H_INCLUDED +#endif + +#ifndef __CPROVER_STDLIB_H_INCLUDED +#include +#define __CPROVER_STDLIB_H_INCLUDED +#endif + +inline int vasprintf(char **ptr, const char *fmt, va_list ap) +{ + (void)*fmt; + (void)ap; + + int result_buffer_size; + if(result_buffer_size<=0) + return -1; + + *ptr=malloc(result_buffer_size); + for(int i=0; i1) + __CPROVER_array_set(res, 0); + else if(nmemb==1) + for(__CPROVER_size_t i=0; i=(const char *)src+n) + char src_n[n]; + __CPROVER_array_copy(src_n, (char*)src); + __CPROVER_array_replace((char*)dest, src_n); + #endif + return dest; +} + +/* FUNCTION: __builtin___memmove_chk */ + +#ifndef __CPROVER_STRING_H_INCLUDED +#include +#define __CPROVER_STRING_H_INCLUDED +#endif + +#undef memmove + +void *__builtin___memmove_chk(void *dest, const void *src, size_t n, __CPROVER_size_t size) +{ + __CPROVER_HIDE:; + #ifdef __CPROVER_STRING_ABSTRACTION + __CPROVER_assert(__CPROVER_buffer_size(src)>=n, "memmove buffer overflow"); + __CPROVER_assert(__CPROVER_buffer_size(dest)==size, "builtin object size"); + // dst = src (with overlap allowed) + if(__CPROVER_is_zero_string(src) && + n > __CPROVER_zero_string_length(src)) { - for(__CPROVER_size_t i=0; i0; i--) ((char *)dest)[i-1]=((const char *)src)[i-1]; - } + __CPROVER_is_zero_string(dest)=0; + #else + (void)size; + char src_n[n]; + __CPROVER_array_copy(src_n, (char*)src); + __CPROVER_array_replace((char*)dest, src_n); #endif return dest; } diff --git a/src/ansi-c/library/unistd.c b/src/ansi-c/library/unistd.c index b9c632fcb77..00af7246882 100644 --- a/src/ansi-c/library/unistd.c +++ b/src/ansi-c/library/unistd.c @@ -198,14 +198,19 @@ ssize_t read(int fildes, void *buf, size_t nbyte) if((fildes>=0 && fildes<=2) || fildes < __CPROVER_pipe_offset) { ssize_t nread; - size_t i; __CPROVER_assume(0<=nread && (size_t)nread<=nbyte); +#if 0 + size_t i; for(i=0; i #include +#include #include -#include "../c_types.h" - #include "unescape_string.h" -#include "convert_character_literal.h" - -/*******************************************************************\ - -Function: convert_character_literal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ exprt convert_character_literal( const std::string &src, diff --git a/src/ansi-c/literals/convert_character_literal.h b/src/ansi-c/literals/convert_character_literal.h index 4c497db73cd..797457a3970 100644 --- a/src/ansi-c/literals/convert_character_literal.h +++ b/src/ansi-c/literals/convert_character_literal.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// C++ Language Conversion + #ifndef CPROVER_ANSI_C_LITERALS_CONVERT_CHARACTER_LITERAL_H #define CPROVER_ANSI_C_LITERALS_CONVERT_CHARACTER_LITERAL_H diff --git a/src/ansi-c/literals/convert_float_literal.cpp b/src/ansi-c/literals/convert_float_literal.cpp index 7e72f6e6f53..8838a2e3492 100644 --- a/src/ansi-c/literals/convert_float_literal.cpp +++ b/src/ansi-c/literals/convert_float_literal.cpp @@ -6,30 +6,22 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// C++ Language Conversion + +#include "convert_float_literal.h" + #include #include +#include #include #include #include #include #include -#include "../c_types.h" #include "parse_float.h" -#include "convert_float_literal.h" - -/*******************************************************************\ - -Function: convert_float_literal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ exprt convert_float_literal(const std::string &src) { @@ -56,7 +48,7 @@ exprt convert_float_literal(const std::string &src) // In ANSI-C, float literals are double by default, // unless marked with 'f'. // All of these can be complex as well. - // This can be overriden with + // This can be overridden with // config.ansi_c.single_precision_constant. if(is_float) diff --git a/src/ansi-c/literals/convert_float_literal.h b/src/ansi-c/literals/convert_float_literal.h index 4c76abbd312..5aa627ace8c 100644 --- a/src/ansi-c/literals/convert_float_literal.h +++ b/src/ansi-c/literals/convert_float_literal.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// C Language Conversion + #ifndef CPROVER_ANSI_C_LITERALS_CONVERT_FLOAT_LITERAL_H #define CPROVER_ANSI_C_LITERALS_CONVERT_FLOAT_LITERAL_H diff --git a/src/ansi-c/literals/convert_integer_literal.cpp b/src/ansi-c/literals/convert_integer_literal.cpp index d7c832dee31..7123f2dddd8 100644 --- a/src/ansi-c/literals/convert_integer_literal.cpp +++ b/src/ansi-c/literals/convert_integer_literal.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// C++ Language Conversion + +#include "convert_integer_literal.h" + #include #include @@ -15,20 +20,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "convert_integer_literal.h" - -/*******************************************************************\ - -Function: convert_integer_literal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt convert_integer_literal(const std::string &src) { bool is_unsigned=false, is_imaginary=false; diff --git a/src/ansi-c/literals/convert_integer_literal.h b/src/ansi-c/literals/convert_integer_literal.h index 5ce3847fdb6..27c231d3790 100644 --- a/src/ansi-c/literals/convert_integer_literal.h +++ b/src/ansi-c/literals/convert_integer_literal.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// C++ Language Conversion + #ifndef CPROVER_ANSI_C_LITERALS_CONVERT_INTEGER_LITERAL_H #define CPROVER_ANSI_C_LITERALS_CONVERT_INTEGER_LITERAL_H diff --git a/src/ansi-c/literals/convert_string_literal.cpp b/src/ansi-c/literals/convert_string_literal.cpp index 4176581afe2..7167bdd8175 100644 --- a/src/ansi-c/literals/convert_string_literal.cpp +++ b/src/ansi-c/literals/convert_string_literal.cpp @@ -6,28 +6,20 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// C/C++ Language Conversion + +#include "convert_string_literal.h" + #include #include +#include #include #include "../string_constant.h" -#include "../c_types.h" #include "unescape_string.h" -#include "convert_string_literal.h" - -/*******************************************************************\ - -Function: convert_one_string_literal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ std::basic_string convert_one_string_literal( const std::string &src) @@ -47,7 +39,7 @@ std::basic_string convert_one_string_literal( // pad into wide string value.resize(utf8_value.size()); - for(unsigned i=0; i convert_one_string_literal( assert(src[0]=='"'); assert(src[src.size()-1]=='"'); - std::basic_string value= - unescape_wide_string(std::string(src, 1, src.size()-2)); - - // turn into utf-8 - std::string utf8_value=utf32_to_utf8(value); + std::string char_value= + unescape_string(std::string(src, 1, src.size()-2)); // pad into wide string - value.resize(utf8_value.size()); - for(unsigned i=0; i value; + value.resize(char_value.size()); + for(std::size_t i=0; i tmp_value= - convert_one_string_literal(tmp_src); - value.append(tmp_value); - i=j; - } + for(++j; j tmp_value= + convert_one_string_literal(tmp_src); + value.append(tmp_value); + i=j; } if(wide!=0) @@ -161,7 +136,7 @@ exprt convert_string_literal(const std::string &src) result.type().set(ID_size, from_integer(value.size(), index_type())); result.operands().resize(value.size()); - for(unsigned i=0; i255. // gcc issues a warning in this case. diff --git a/src/ansi-c/literals/convert_string_literal.h b/src/ansi-c/literals/convert_string_literal.h index f634a1dfb1f..16b7e5e5929 100644 --- a/src/ansi-c/literals/convert_string_literal.h +++ b/src/ansi-c/literals/convert_string_literal.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// C/C++ Language Conversion + #ifndef CPROVER_ANSI_C_LITERALS_CONVERT_STRING_LITERAL_H #define CPROVER_ANSI_C_LITERALS_CONVERT_STRING_LITERAL_H diff --git a/src/ansi-c/literals/parse_float.cpp b/src/ansi-c/literals/parse_float.cpp index 674e986e35a..d6b85acecbb 100644 --- a/src/ansi-c/literals/parse_float.cpp +++ b/src/ansi-c/literals/parse_float.cpp @@ -6,21 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Conversion of Expressions #include "parse_float.h" -/*******************************************************************\ - -Function: convert_ct::parse_float - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void parse_float( const std::string &src, diff --git a/src/ansi-c/literals/parse_float.h b/src/ansi-c/literals/parse_float.h index 7edb55a08b7..b750c0cd77b 100644 --- a/src/ansi-c/literals/parse_float.h +++ b/src/ansi-c/literals/parse_float.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// ANSI-C Conversion / Type Checking + #ifndef CPROVER_ANSI_C_LITERALS_PARSE_FLOAT_H #define CPROVER_ANSI_C_LITERALS_PARSE_FLOAT_H diff --git a/src/ansi-c/literals/unescape_string.cpp b/src/ansi-c/literals/unescape_string.cpp index 6ecfadc703d..ab633795dec 100644 --- a/src/ansi-c/literals/unescape_string.cpp +++ b/src/ansi-c/literals/unescape_string.cpp @@ -6,159 +6,49 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include -#include -#include +/// \file +/// ANSI-C Language Conversion #include "unescape_string.h" -/*******************************************************************\ - -Function: unescape_string - - Inputs: - - Outputs: - - Purpose: +#include +#include -\*******************************************************************/ +#include -std::string unescape_string(const std::string &src) +static void append_universal_char( + unsigned int value, + std::string &dest) { - std::string dest; - dest.reserve(src.size()); - - for(unsigned i=0; i value_str(1, value); - // go back - i--; + // turn into utf-8 + std::string utf8_value=utf32_to_utf8(value_str); - ch=octal_to_unsigned(octal.c_str(), octal.size()); - dest+=ch; - } - else - { - // Unknown escape sequence. - // Both GCC and CL turn \% into %. - dest.push_back(ch); - } - } - } - else - dest+=ch; - } - - return dest; + dest.append(utf8_value); } -/*******************************************************************\ - -Function: unescape_wide_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +static void append_universal_char( + unsigned int value, + std::basic_string &dest) +{ + dest.push_back(value); +} -std::basic_string unescape_wide_string( - const std::string &src) +template +std::basic_string unescape_string_templ(const std::string &src) { - std::basic_string dest; + std::basic_string dest; dest.reserve(src.size()); // about that long, but may be shorter for(unsigned i=0; i unescape_wide_string( { std::string hex; - unsigned count=(ch=='u')?4:8; - hex.reserve(count); + const unsigned digits=(ch=='u')?4:8; + hex.reserve(digits); - for(; count!=0 && i unescape_wide_string( { std::string hex; + while(i unescape_wide_string( // go back i--; - unsigned int result; - sscanf(hex.c_str(), "%x", &result); - ch=result; + ch=hex_to_unsigned(hex.c_str(), hex.size()); } + // if T isn't sufficiently wide to hold unsigned values + // the following might truncate; but then + // universal characters in non-wide strings don't + // really work; gcc just issues a warning. dest.push_back(ch); break; @@ -236,9 +130,7 @@ std::basic_string unescape_wide_string( // go back i--; - unsigned int result; - sscanf(octal.c_str(), "%o", &result); - ch=result; + ch=octal_to_unsigned(octal.c_str(), octal.size()); dest.push_back(ch); } else @@ -256,17 +148,16 @@ std::basic_string unescape_wide_string( return dest; } -/*******************************************************************\ - -Function: hex_to_unsigned - - Inputs: - - Outputs: - - Purpose: +std::string unescape_string(const std::string &src) +{ + return unescape_string_templ(src); +} -\*******************************************************************/ +std::basic_string unescape_wide_string( + const std::string &src) +{ + return unescape_string_templ(src); +} unsigned hex_to_unsigned(const char *hex, std::size_t digits) { @@ -290,18 +181,6 @@ unsigned hex_to_unsigned(const char *hex, std::size_t digits) return value; } -/*******************************************************************\ - -Function: octal_to_unsigned - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - unsigned octal_to_unsigned(const char *octal, std::size_t digits) { unsigned value=0; diff --git a/src/ansi-c/literals/unescape_string.h b/src/ansi-c/literals/unescape_string.h index 9d672cde19c..be6f1a18093 100644 --- a/src/ansi-c/literals/unescape_string.h +++ b/src/ansi-c/literals/unescape_string.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// ANSI-C Language Conversion + #ifndef CPROVER_ANSI_C_LITERALS_UNESCAPE_STRING_H #define CPROVER_ANSI_C_LITERALS_UNESCAPE_STRING_H diff --git a/src/ansi-c/module.md b/src/ansi-c/module.md new file mode 100644 index 00000000000..db72087f4d3 --- /dev/null +++ b/src/ansi-c/module.md @@ -0,0 +1,114 @@ +\ingroup module_hidden +\defgroup module_ansi-c ANSI-C Language Front-end + +\author Kareem Khazem + +\section preprocessing Preprocessing & Parsing + +In the \ref ansi-c and \ref java_bytecode directories + +**Key classes:** +* \ref languaget and its subclasses +* ansi_c_parse_treet + +\dot +digraph G { + node [shape=box]; + rankdir="LR"; + 1 [shape=none, label=""]; + 2 [label="preprocessing & parsing"]; + 3 [shape=none, label=""]; + 1 -> 2 [label="Command line options, file names"]; + 2 -> 3 [label="Parse tree"]; +} +\enddot + + + +--- +\section type-checking Type-checking + +In the \ref ansi-c and \ref java_bytecode directories. + +**Key classes:** +* \ref languaget and its subclasses +* \ref irept +* \ref irep_idt +* \ref symbolt +* symbol_tablet + +\dot +digraph G { + node [shape=box]; + rankdir="LR"; + 1 [shape=none, label=""]; + 2 [label="type checking"]; + 3 [shape=none, label=""]; + 1 -> 2 [label="Parse tree"]; + 2 -> 3 [label="Symbol table"]; +} +\enddot + +This stage generates a symbol table, mapping identifiers to symbols; +\ref symbolt "symbols" are tuples of (value, type, location, flags). + +This is a good point to introduce the \ref irept ("internal +representation") class---the base type of many of CBMC's hierarchical +data structures. In particular, \ref exprt "expressions", +\ref typet "types" and \ref codet "statements" are all subtypes of +\ref irept. +An irep is a tree of ireps. A subtlety is that an irep is actually the +root of _three_ (possibly empty) trees, i.e. it has three disjoint sets +of children: \ref irept::get_sub() returns a list of children, and +\ref irept::get_named_sub() and \ref irept::get_comments() each return an +association from names to children. **Most clients never use these +functions directly**, as subtypes of irept generally provide more +descriptive functions. For example, the operands of an +\ref exprt "expression" (\ref exprt::op0() "op0", op1 etc) are +really that expression's children; the +\ref code_assignt::lhs() "left-hand" and right-hand side of an +\ref code_assignt "assignment" are the children of that assignment. +The \ref irept::pretty() function provides a descriptive string +representation of an irep. + +\ref irep_idt "irep_idts" ("identifiers") are strings that use sharing +to improve memory consumption. A common pattern is a map from irep_idts +to ireps. A goto-program contains a single symbol table (with a single +scope), meaning that the names of identifiers in the target program are +lightly mangled in order to make them globally unique. If there is an +identifier `foo` in the target program, the `name` field of `foo`'s +\ref symbolt "symbol" in the goto-program will be +* `foo` if it is global; +* bar\::foo if it is a parameter to a function `bar()`; +* bar\::3\::foo if it is a local variable in a function + `bar()`, where `3` is a counter that is incremented every time a + newly-scoped `foo` is encountered in that function. + +The use of *sharing* to save memory is a pervasive design decision in +the implementation of ireps and identifiers. Sharing makes equality +comparisons fast (as there is no need to traverse entire trees), and +this is especially important given the large number of map lookups +throughout the codebase. More importantly, the use of sharing saves vast +amounts of memory, as there is plenty of duplication within the +goto-program data structures. For example, every statement, and every +sub-expression of a statement, contains a \ref source_locationt +that indicates the source file and location that it came from. Every +symbol in every expression has a field indicating its type and location; +etc. Although each of these are constructed as separate objects, the +values that they eventually point to are shared throughout the codebase, +decreasing memory consumption dramatically. + +The Type Checking stage turns a parse tree into a +\ref symbol_tablet "symbol table". In this context, the 'symbols' +consist of code statements as well as what might more traditionally be +called symbols. Thus, for example: +* The statement `int foo = 11;` is converted into a symbol whose type is + integer_typet and value is the \ref constant_exprt + "constant expression" `11`; that symbol is stored in the symbol table + using the mangled name of `foo` as the key; +* The function definition `void foo(){ int x = 11; bar(); }` is + converted into a symbol whose type is \ref code_typet (not to be + confused with \ref typet or \ref codet!); the code_typet contains the + parameter and return types of the function. The value of the symbol is + the function's body (a \ref codet), and the symbol is stored in the + symbol table with `foo` as the key. diff --git a/src/ansi-c/padding.cpp b/src/ansi-c/padding.cpp index 16391ee33a7..e7219fd615a 100644 --- a/src/ansi-c/padding.cpp +++ b/src/ansi-c/padding.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// C++ Language Type Checking + +#include "padding.h" + #include #include @@ -13,20 +18,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "padding.h" - -/*******************************************************************\ - -Function: alignment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - mp_integer alignment(const typet &type, const namespacet &ns) { // we need to consider a number of different cases: @@ -114,18 +105,6 @@ mp_integer alignment(const typet &type, const namespacet &ns) return result; } -/*******************************************************************\ - -Function: add_padding - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void add_padding(struct_typet &type, const namespacet &ns) { struct_typet::componentst &components=type.components(); @@ -322,23 +301,14 @@ void add_padding(struct_typet &type, const namespacet &ns) } } -/*******************************************************************\ - -Function: add_padding - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void add_padding(union_typet &type, const namespacet &ns) { mp_integer max_alignment=alignment(type, ns)*8; mp_integer size_bits=pointer_offset_bits(type, ns); + if(size_bits<0) + throw "type of unknown size:\n"+type.pretty(); + union_typet::componentst &components=type.components(); // Is the union packed? diff --git a/src/ansi-c/padding.h b/src/ansi-c/padding.h index 18634a61559..27fb6fda099 100644 --- a/src/ansi-c/padding.h +++ b/src/ansi-c/padding.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// ANSI-C Language Type Checking + #ifndef CPROVER_ANSI_C_PADDING_H #define CPROVER_ANSI_C_PADDING_H diff --git a/src/ansi-c/parser.y b/src/ansi-c/parser.y index b93bcae9b48..bddccced310 100644 --- a/src/ansi-c/parser.y +++ b/src/ansi-c/parser.y @@ -22,6 +22,8 @@ extern char *yyansi_ctext; #include "parser_static.inc" +#include "literals/convert_integer_literal.h" + #include "ansi_c_y.tab.h" // statements have right recursion, deep nesting of statements thus @@ -265,7 +267,8 @@ identifier: irep_idt value=stack($2).get(ID_value); stack($$).set(ID_C_base_name, value); stack($$).set(ID_identifier, value); - stack($$).set(ID_C_id_class, ANSI_C_SYMBOL); + stack($$).set( + ID_C_id_class, static_cast(ansi_c_id_classt::ANSI_C_SYMBOL)); } ; @@ -424,6 +427,17 @@ offsetof_member_designator: mto($2, $3); mto($$, $2); } + | offsetof_member_designator TOK_ARROW member_name + { + $$=$1; + set($2, ID_index); + exprt tmp=convert_integer_literal("0"); + stack($2).move_to_operands(tmp); + mto($$, $2); + set($2, ID_member); + stack($2).set(ID_component_name, stack($3).get(ID_C_base_name)); + mto($$, $2); + } ; quantifier_expression: @@ -1531,7 +1545,7 @@ gcc_attribute_list: gcc_attribute | gcc_attribute_list ',' gcc_attribute { - $$=merge($1, $2); + $$=merge($1, $3); } ; @@ -2387,7 +2401,7 @@ gcc_local_label_statement: irep_idt base_name=it->get(ID_identifier); irep_idt id="label-"+id2string(base_name); ansi_c_parsert::identifiert &i=PARSER.current_scope().name_map[id]; - i.id_class=ANSI_C_LOCAL_LABEL; + i.id_class=ansi_c_id_classt::ANSI_C_LOCAL_LABEL; i.prefixed_name=PARSER.current_scope().prefix+id2string(id); i.base_name=base_name; } diff --git a/src/ansi-c/parser_static.inc b/src/ansi-c/parser_static.inc index eb91ce52983..e0c8385998d 100644 --- a/src/ansi-c/parser_static.inc +++ b/src/ansi-c/parser_static.inc @@ -1,10 +1,9 @@ +#include #include #include #include #include -#include "c_types.h" - #define YYSTYPE unsigned #define YYSTYPE_IS_TRIVIAL 1 @@ -100,8 +99,8 @@ Function: merge_types static void merge_types(irept &dest, irept &src) { #if 0 - std::cout << "D: " << dest.pretty() << std::endl; - std::cout << "S: " << src.pretty() << std::endl; + std::cout << "D: " << dest.pretty() << '\n'; + std::cout << "S: " << src.pretty() << '\n'; #endif if(src.is_nil()) @@ -183,8 +182,8 @@ static void make_subtype(typet &dest, typet &src) // find spot in 'dest' where to insert 'src' #if 0 - std::cout << "D: " << dest.pretty() << std::endl; - std::cout << "S: " << src.pretty() << std::endl; + std::cout << "D: " << dest.pretty() << '\n'; + std::cout << "S: " << src.pretty() << '\n'; #endif assert(src.id()==ID_array || @@ -364,7 +363,7 @@ static void create_function_scope(const YYSTYPE d) irep_idt base_name=param_decl.declarator().get_base_name(); ansi_c_identifiert &identifier= PARSER.current_scope().name_map[base_name]; - identifier.id_class=ANSI_C_SYMBOL; + identifier.id_class=ansi_c_id_classt::ANSI_C_SYMBOL; identifier.base_name=base_name; identifier.prefixed_name=param_decl.declarator().get_name(); } diff --git a/src/ansi-c/preprocessor_line.cpp b/src/ansi-c/preprocessor_line.cpp index a9b651fc3f7..b43b1fc4bb4 100644 --- a/src/ansi-c/preprocessor_line.cpp +++ b/src/ansi-c/preprocessor_line.cpp @@ -6,25 +6,17 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// ANSI-C Language Conversion + +#include "preprocessor_line.h" + #include #include #include #include "literals/unescape_string.h" -#include "preprocessor_line.h" - -/*******************************************************************\ - -Function: preprocessor_line - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ void preprocessor_line( const char *text, diff --git a/src/ansi-c/preprocessor_line.h b/src/ansi-c/preprocessor_line.h index 5222fdd83d9..bd18aa636fe 100644 --- a/src/ansi-c/preprocessor_line.h +++ b/src/ansi-c/preprocessor_line.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// ANSI-C Language Conversion + #ifndef CPROVER_ANSI_C_PREPROCESSOR_LINE_H #define CPROVER_ANSI_C_PREPROCESSOR_LINE_H diff --git a/src/ansi-c/printf_formatter.cpp b/src/ansi-c/printf_formatter.cpp index 59e3dbcc20f..1cbbf879546 100644 --- a/src/ansi-c/printf_formatter.cpp +++ b/src/ansi-c/printf_formatter.cpp @@ -6,27 +6,18 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// printf Formatting + +#include "printf_formatter.h" + #include #include +#include #include #include -#include "c_types.h" -#include "printf_formatter.h" - -/*******************************************************************\ - -Function: printf_formattert::make_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const exprt printf_formattert::make_type( const exprt &src, const typet &dest) { @@ -38,18 +29,6 @@ const exprt printf_formattert::make_type( return tmp; } -/*******************************************************************\ - -Function: printf_formattert::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void printf_formattert::operator()( const std::string &_format, const std::list &_operands) @@ -58,18 +37,6 @@ void printf_formattert::operator()( operands=_operands; } -/*******************************************************************\ - -Function: printf_formattert::print() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void printf_formattert::print(std::ostream &out) { format_pos=0; @@ -85,18 +52,6 @@ void printf_formattert::print(std::ostream &out) } } -/*******************************************************************\ - -Function: printf_formattert::as_string() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string printf_formattert::as_string() { std::ostringstream stream; @@ -104,18 +59,6 @@ std::string printf_formattert::as_string() return stream.str(); } -/*******************************************************************\ - -Function: printf_formattert::process_format - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void printf_formattert::process_format(std::ostream &out) { exprt tmp; @@ -159,8 +102,18 @@ void printf_formattert::process_format(std::ostream &out) out << ch; break; + case 'e': + case 'E': + format_constant.style=format_spect::stylet::SCIENTIFIC; + if(next_operand==operands.end()) + break; + out << format_constant( + make_type(*(next_operand++), double_type())); + break; + case 'f': case 'F': + format_constant.style=format_spect::stylet::DECIMAL; if(next_operand==operands.end()) break; out << format_constant( @@ -169,6 +122,7 @@ void printf_formattert::process_format(std::ostream &out) case 'g': case 'G': + format_constant.style=format_spect::stylet::AUTOMATIC; if(format_constant.precision==0) format_constant.precision=1; if(next_operand==operands.end()) @@ -225,18 +179,6 @@ void printf_formattert::process_format(std::ostream &out) } } -/*******************************************************************\ - -Function: printf_formattert::process_char - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void printf_formattert::process_char(std::ostream &out) { char ch=next(); diff --git a/src/ansi-c/printf_formatter.h b/src/ansi-c/printf_formatter.h index 4048af9a6a4..0e48ac60e2a 100644 --- a/src/ansi-c/printf_formatter.h +++ b/src/ansi-c/printf_formatter.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// printf Formatting + #ifndef CPROVER_ANSI_C_PRINTF_FORMATTER_H #define CPROVER_ANSI_C_PRINTF_FORMATTER_H @@ -22,7 +25,9 @@ class printf_formattert void print(std::ostream &out); std::string as_string(); - explicit printf_formattert(const namespacet &_ns):ns(_ns) + explicit printf_formattert(const namespacet &_ns): + ns(_ns), + format_pos(0) { } diff --git a/src/ansi-c/scanner.l b/src/ansi-c/scanner.l index bc4ef1c042b..7a97b0a7b89 100644 --- a/src/ansi-c/scanner.l +++ b/src/ansi-c/scanner.l @@ -21,7 +21,6 @@ static int isatty(int) { return 0; } #include -#include "c_types.h" #include "preprocessor_line.h" #include "string_constant.h" @@ -96,9 +95,9 @@ int make_identifier() stack(yyansi_clval).id(ID_symbol); stack(yyansi_clval).set(ID_C_base_name, base_name); stack(yyansi_clval).set(ID_identifier, identifier); - stack(yyansi_clval).set(ID_C_id_class, result); + stack(yyansi_clval).set(ID_C_id_class, static_cast(result)); - if(result==ANSI_C_TYPEDEF) + if(result==ansi_c_id_classt::ANSI_C_TYPEDEF) return TOK_TYPEDEFNAME; else return TOK_IDENTIFIER; diff --git a/src/ansi-c/string_constant.cpp b/src/ansi-c/string_constant.cpp index 6576a99ea5b..3c083e4c32e 100644 --- a/src/ansi-c/string_constant.cpp +++ b/src/ansi-c/string_constant.cpp @@ -6,23 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include -#include - #include "string_constant.h" -#include "c_types.h" - -/*******************************************************************\ - -Function: string_constantt::string_constantt - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include +#include string_constantt::string_constantt(): exprt(ID_string_constant) @@ -30,36 +18,12 @@ string_constantt::string_constantt(): set_value(irep_idt()); } -/*******************************************************************\ - -Function: string_constantt::string_constantt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - string_constantt::string_constantt(const irep_idt &_value): exprt(ID_string_constant) { set_value(_value); } -/*******************************************************************\ - -Function: string_constantt::set_value - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_constantt::set_value(const irep_idt &value) { exprt size_expr=from_integer(value.size()+1, index_type()); @@ -67,18 +31,7 @@ void string_constantt::set_value(const irep_idt &value) set(ID_value, value); } -/*******************************************************************\ - -Function: string_constantt:to_array_expr - - Inputs: - - Outputs: - - Purpose: convert string into array constant - -\*******************************************************************/ - +/// convert string into array constant array_exprt string_constantt::to_array_expr() const { const std::string &str=get_string(ID_value); @@ -119,18 +72,8 @@ array_exprt string_constantt::to_array_expr() const return dest; } -/*******************************************************************\ - -Function: string_constantt:from_array_expr - - Inputs: - - Outputs: true on error - - Purpose: convert array constant into string - -\*******************************************************************/ - +/// convert array constant into string +/// \return true on error bool string_constantt::from_array_expr(const array_exprt &src) { id(ID_string_constant); diff --git a/src/ansi-c/string_constant.h b/src/ansi-c/string_constant.h index 40ef0a94366..d991d6409c1 100644 --- a/src/ansi-c/string_constant.h +++ b/src/ansi-c/string_constant.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_ANSI_C_STRING_CONSTANT_H #define CPROVER_ANSI_C_STRING_CONSTANT_H diff --git a/src/ansi-c/type2name.cpp b/src/ansi-c/type2name.cpp index fdcf6b0a276..edc5c51f87b 100644 --- a/src/ansi-c/type2name.cpp +++ b/src/ansi-c/type2name.cpp @@ -6,14 +6,17 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// Type Naming for C + +#include "type2name.h" + #include #include #include #include #include -#include "type2name.h" - typedef std::unordered_map, irep_id_hash> symbol_numbert; @@ -22,18 +25,6 @@ static std::string type2name( const namespacet &ns, symbol_numbert &symbol_number); -/*******************************************************************\ - -Function: type2name_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static std::string type2name_symbol( const typet &type, const namespacet &ns, @@ -90,18 +81,6 @@ static std::string type2name_symbol( return result; } -/*******************************************************************\ - -Function: type2name - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static bool parent_is_sym_check=false; static std::string type2name( const typet &type, @@ -131,7 +110,7 @@ static std::string type2name( if(!type.source_location().get_function().empty()) result+='l'; - if(type.id()==irep_idt()) + if(type.id().empty()) throw "empty type encountered"; else if(type.id()==ID_empty) result+='V'; @@ -278,18 +257,6 @@ static std::string type2name( return result; } -/*******************************************************************\ - -Function: type2name - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string type2name(const typet &type, const namespacet &ns) { parent_is_sym_check=true; @@ -297,18 +264,6 @@ std::string type2name(const typet &type, const namespacet &ns) return type2name(type, ns, symbol_number); } -/*******************************************************************\ - -Function: type2name - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string type2name(const typet &type) { symbol_tablet symbol_table; diff --git a/src/ansi-c/type2name.h b/src/ansi-c/type2name.h index b7299617e7f..e86b4f8b400 100644 --- a/src/ansi-c/type2name.h +++ b/src/ansi-c/type2name.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// Type Naming for C + #ifndef CPROVER_ANSI_C_TYPE2NAME_H #define CPROVER_ANSI_C_TYPE2NAME_H @@ -13,6 +16,8 @@ Author: Daniel Kroening, kroening@cs.cmu.edu #include +class namespacet; + std::string type2name(const typet &type); std::string type2name(const typet &type, const namespacet &ns); diff --git a/src/assembler/assembler_parser.cpp b/src/assembler/assembler_parser.cpp index 59367857340..1ad30f95680 100644 --- a/src/assembler/assembler_parser.cpp +++ b/src/assembler/assembler_parser.cpp @@ -6,23 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "assembler_parser.h" -assembler_parsert assembler_parser; - -/*******************************************************************\ - -Function: yyassemblererror - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +assembler_parsert assembler_parser; extern char *yyassemblertext; diff --git a/src/assembler/assembler_parser.h b/src/assembler/assembler_parser.h index 7745ec21ed6..4d3a160da25 100644 --- a/src/assembler/assembler_parser.h +++ b/src/assembler/assembler_parser.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_ASSEMBLER_ASSEMBLER_PARSER_H #define CPROVER_ASSEMBLER_ASSEMBLER_PARSER_H diff --git a/src/cbmc/Makefile b/src/cbmc/Makefile index a2a96057200..836dcc91594 100644 --- a/src/cbmc/Makefile +++ b/src/cbmc/Makefile @@ -17,6 +17,7 @@ SRC = all_properties.cpp \ OBJ += ../ansi-c/ansi-c$(LIBEXT) \ ../cpp/cpp$(LIBEXT) \ + ../java_bytecode/java_bytecode$(LIBEXT) \ ../linking/linking$(LIBEXT) \ ../big-int/big-int$(LIBEXT) \ ../goto-programs/goto-programs$(LIBEXT) \ @@ -59,26 +60,11 @@ ifneq ($(wildcard ../bv_refinement/Makefile),) CP_CXXFLAGS += -DHAVE_BV_REFINEMENT endif -ifneq ($(wildcard ../java_bytecode/Makefile),) - OBJ += ../java_bytecode/java_bytecode$(LIBEXT) - CP_CXXFLAGS += -DHAVE_JAVA_BYTECODE -endif - ifneq ($(wildcard ../jsil/Makefile),) OBJ += ../jsil/jsil$(LIBEXT) CP_CXXFLAGS += -DHAVE_JSIL endif -ifneq ($(wildcard ../specc/Makefile),) - OBJ += ../specc/specc$(LIBEXT) - CP_CXXFLAGS += -DHAVE_SPECC -endif - -ifneq ($(wildcard ../php/Makefile),) - OBJ += ../php/php$(LIBEXT) - CP_CXXFLAGS += -DHAVE_PHP -endif - ############################################################################### cbmc$(EXEEXT): $(OBJ) diff --git a/src/cbmc/all_properties.cpp b/src/cbmc/all_properties.cpp index 590b7696201..f91fd5c52c3 100644 --- a/src/cbmc/all_properties.cpp +++ b/src/cbmc/all_properties.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symbolic Execution of ANSI-C + +#include "all_properties_class.h" + #include #include @@ -21,20 +26,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "bv_cbmc.h" -#include "all_properties_class.h" - -/*******************************************************************\ - -Function: bmc_all_propertiest::goal_covered - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bmc_all_propertiest::goal_covered(const cover_goalst::goalt &) { for(auto &g : goal_map) @@ -61,18 +52,6 @@ void bmc_all_propertiest::goal_covered(const cover_goalst::goalt &) } } -/*******************************************************************\ - -Function: bmc_all_propertiest::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - safety_checkert::resultt bmc_all_propertiest::operator()() { status() << "Passing problem to " << solver.decision_procedure_text() << eom; @@ -140,7 +119,7 @@ safety_checkert::resultt bmc_all_propertiest::operator()() decision_proceduret::resultt result=cover_goals(); - if(result==decision_proceduret::D_ERROR) + if(result==decision_proceduret::resultt::D_ERROR) { error=true; for(auto &g : goal_map) @@ -166,7 +145,7 @@ safety_checkert::resultt bmc_all_propertiest::operator()() report(cover_goals); if(error) - return safety_checkert::ERROR; + return safety_checkert::resultt::ERROR; bool safe=(cover_goals.number_covered()==0); @@ -175,26 +154,14 @@ safety_checkert::resultt bmc_all_propertiest::operator()() else bmc.report_failure(); // legacy, might go away - return safe?safety_checkert::SAFE:safety_checkert::UNSAFE; + return safe?safety_checkert::resultt::SAFE:safety_checkert::resultt::UNSAFE; } -/*******************************************************************\ - -Function: bmc_all_propertiest::report() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bmc_all_propertiest::report(const cover_goalst &cover_goals) { switch(bmc.ui) { - case ui_message_handlert::PLAIN: + case ui_message_handlert::uit::PLAIN: { status() << "\n** Results:" << eom; @@ -222,7 +189,7 @@ void bmc_all_propertiest::report(const cover_goalst &cover_goals) } break; - case ui_message_handlert::XML_UI: + case ui_message_handlert::uit::XML_UI: { for(const auto &g : goal_map) { @@ -238,7 +205,7 @@ void bmc_all_propertiest::report(const cover_goalst &cover_goals) break; } - case ui_message_handlert::JSON_UI: + case ui_message_handlert::uit::JSON_UI: { json_objectt json_result; json_arrayt &result_array=json_result["result"].make_array(); @@ -263,18 +230,6 @@ void bmc_all_propertiest::report(const cover_goalst &cover_goals) } } -/*******************************************************************\ - -Function: bmct::all_properties - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - safety_checkert::resultt bmct::all_properties( const goto_functionst &goto_functions, prop_convt &solver) diff --git a/src/cbmc/all_properties_class.h b/src/cbmc/all_properties_class.h index 1f3fc27960a..89c4614cc12 100644 --- a/src/cbmc/all_properties_class.h +++ b/src/cbmc/all_properties_class.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symbolic Execution of ANSI-C + #ifndef CPROVER_CBMC_ALL_PROPERTIES_CLASS_H #define CPROVER_CBMC_ALL_PROPERTIES_CLASS_H @@ -13,18 +16,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "bmc.h" -/*******************************************************************\ - - Class: bmc_all_propertiest - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - class bmc_all_propertiest: public cover_goalst::observert, public messaget diff --git a/src/cbmc/bmc.cpp b/src/cbmc/bmc.cpp index f1e005a46a1..4f55b1a7315 100644 --- a/src/cbmc/bmc.cpp +++ b/src/cbmc/bmc.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symbolic Execution of ANSI-C + +#include "bmc.h" + #include #include #include @@ -19,11 +24,8 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include -#include - #include #include #include @@ -37,37 +39,12 @@ Author: Daniel Kroening, kroening@kroening.com #include "counterexample_beautification.h" #include "fault_localization.h" -#include "bmc.h" - -/*******************************************************************\ - -Function: bmct::do_unwind_module - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ void bmct::do_unwind_module() { // this is a hook for hw-cbmc } -/*******************************************************************\ - -Function: bmct::error_trace - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bmct::error_trace() { status() << "Building error trace" << eom; @@ -77,12 +54,12 @@ void bmct::error_trace() switch(ui) { - case ui_message_handlert::PLAIN: + case ui_message_handlert::uit::PLAIN: std::cout << "\n" << "Counterexample:" << "\n"; show_goto_trace(std::cout, ns, goto_trace); break; - case ui_message_handlert::XML_UI: + case ui_message_handlert::uit::XML_UI: { xmlt xml; convert(ns, goto_trace, xml); @@ -90,7 +67,7 @@ void bmct::error_trace() } break; - case ui_message_handlert::JSON_UI: + case ui_message_handlert::uit::JSON_UI: { json_objectt json_result; json_arrayt &result_array=json_result["results"].make_array(); @@ -109,18 +86,7 @@ void bmct::error_trace() } } -/*******************************************************************\ - -Function: bmct::output_graphml - - Inputs: - - Outputs: - - Purpose: outputs witnesses in graphml format - -\*******************************************************************/ - +/// outputs witnesses in graphml format void bmct::output_graphml( resultt result, const goto_functionst &goto_functions) @@ -130,9 +96,9 @@ void bmct::output_graphml( return; graphml_witnesst graphml_witness(ns); - if(result==UNSAFE) + if(result==resultt::UNSAFE) graphml_witness(safety_checkert::error_trace); - else if(result==SAFE) + else if(result==resultt::SAFE) graphml_witness(equation); else return; @@ -146,18 +112,6 @@ void bmct::output_graphml( } } -/*******************************************************************\ - -Function: bmct::do_conversion - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bmct::do_conversion() { // convert HDL (hook for hw-cbmc) @@ -178,18 +132,6 @@ void bmct::do_conversion() } } -/*******************************************************************\ - -Function: bmct::run_decision_procedure - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - decision_proceduret::resultt bmct::run_decision_procedure(prop_convt &prop_conv) { @@ -217,28 +159,16 @@ bmct::run_decision_procedure(prop_convt &prop_conv) return dec_result; } -/*******************************************************************\ - -Function: bmct::report_success - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bmct::report_success() { result() << "VERIFICATION SUCCESSFUL" << eom; switch(ui) { - case ui_message_handlert::PLAIN: + case ui_message_handlert::uit::PLAIN: break; - case ui_message_handlert::XML_UI: + case ui_message_handlert::uit::XML_UI: { xmlt xml("cprover-status"); xml.data="SUCCESS"; @@ -247,7 +177,7 @@ void bmct::report_success() } break; - case ui_message_handlert::JSON_UI: + case ui_message_handlert::uit::JSON_UI: { json_objectt json_result; json_result["cProverStatus"]=json_stringt("success"); @@ -257,28 +187,16 @@ void bmct::report_success() } } -/*******************************************************************\ - -Function: bmct::report_failure - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bmct::report_failure() { result() << "VERIFICATION FAILED" << eom; switch(ui) { - case ui_message_handlert::PLAIN: + case ui_message_handlert::uit::PLAIN: break; - case ui_message_handlert::XML_UI: + case ui_message_handlert::uit::XML_UI: { xmlt xml("cprover-status"); xml.data="FAILURE"; @@ -287,7 +205,7 @@ void bmct::report_failure() } break; - case ui_message_handlert::JSON_UI: + case ui_message_handlert::uit::JSON_UI: { json_objectt json_result; json_result["cProverStatus"]=json_stringt("failure"); @@ -297,24 +215,10 @@ void bmct::report_failure() } } -/*******************************************************************\ - -Function: bmct::show_program - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bmct::show_program() { unsigned count=1; - languagest languages(ns, new_ansi_c_language()); - std::cout << "\n" << "Program constraints:" << "\n"; for(const auto &step : equation.SSA_steps) @@ -324,13 +228,14 @@ void bmct::show_program() if(step.is_assignment()) { - std::string string_value; - languages.from_expr(step.cond_expr, string_value); + std::string string_value= + from_expr(ns, "", step.cond_expr); std::cout << "(" << count << ") " << string_value << "\n"; if(!step.guard.is_true()) { - languages.from_expr(step.guard, string_value); + std::string string_value= + from_expr(ns, "", step.guard); std::cout << std::string(std::to_string(count).size()+3, ' '); std::cout << "guard: " << string_value << "\n"; } @@ -339,14 +244,15 @@ void bmct::show_program() } else if(step.is_assert()) { - std::string string_value; - languages.from_expr(step.cond_expr, string_value); + std::string string_value= + from_expr(ns, "", step.cond_expr); std::cout << "(" << count << ") ASSERT(" << string_value <<") " << "\n"; if(!step.guard.is_true()) { - languages.from_expr(step.guard, string_value); + std::string string_value= + from_expr(ns, "", step.guard); std::cout << std::string(std::to_string(count).size()+3, ' '); std::cout << "guard: " << string_value << "\n"; } @@ -355,14 +261,15 @@ void bmct::show_program() } else if(step.is_assume()) { - std::string string_value; - languages.from_expr(step.cond_expr, string_value); + std::string string_value= + from_expr(ns, "", step.cond_expr); std::cout << "(" << count << ") ASSUME(" << string_value <<") " << "\n"; if(!step.guard.is_true()) { - languages.from_expr(step.guard, string_value); + std::string string_value= + from_expr(ns, "", step.guard); std::cout << std::string(std::to_string(count).size()+3, ' '); std::cout << "guard: " << string_value << "\n"; } @@ -371,8 +278,8 @@ void bmct::show_program() } else if(step.is_constraint()) { - std::string string_value; - languages.from_expr(step.cond_expr, string_value); + std::string string_value= + from_expr(ns, "", step.cond_expr); std::cout << "(" << count << ") CONSTRAINT(" << string_value <<") " << "\n"; @@ -380,15 +287,16 @@ void bmct::show_program() } else if(step.is_shared_read() || step.is_shared_write()) { - std::string string_value; - languages.from_expr(step.ssa_lhs, string_value); + std::string string_value= + from_expr(ns, "", step.ssa_lhs); std::cout << "(" << count << ") SHARED_" << (step.is_shared_write()?"WRITE":"READ") << "(" << string_value <<")\n"; if(!step.guard.is_true()) { - languages.from_expr(step.guard, string_value); + std::string string_value= + from_expr(ns, "", step.guard); std::cout << std::string(std::to_string(count).size()+3, ' '); std::cout << "guard: " << string_value << "\n"; } @@ -398,18 +306,6 @@ void bmct::show_program() } } -/*******************************************************************\ - -Function: bmct::run - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - safety_checkert::resultt bmct::run( const goto_functionst &goto_functions) { @@ -426,7 +322,7 @@ safety_checkert::resultt bmct::run( { error() << "Invalid memory model " << mm << " -- use one of sc, tso, pso" << eom; - return safety_checkert::ERROR; + return safety_checkert::resultt::ERROR; } symex.set_message_handler(get_message_handler()); @@ -464,7 +360,7 @@ safety_checkert::resultt bmct::run( message.error().source_location=symex.last_source_location; message.error() << error_str << messaget::eom; - return safety_checkert::ERROR; + return safety_checkert::resultt::ERROR; } catch(const char *error_str) @@ -473,13 +369,13 @@ safety_checkert::resultt bmct::run( message.error().source_location=symex.last_source_location; message.error() << error_str << messaget::eom; - return safety_checkert::ERROR; + return safety_checkert::resultt::ERROR; } catch(std::bad_alloc) { error() << "Out of memory" << eom; - return safety_checkert::ERROR; + return safety_checkert::resultt::ERROR; } statistics() << "size of program expression: " @@ -534,13 +430,13 @@ safety_checkert::resultt bmct::run( symex.output_coverage_report(goto_functions, cov_out)) { error() << "Failed to write symex coverage report" << eom; - return safety_checkert::ERROR; + return safety_checkert::resultt::ERROR; } if(options.get_bool_option("show-vcc")) { show_vcc(); - return safety_checkert::SAFE; // to indicate non-error + return safety_checkert::resultt::SAFE; // to indicate non-error } if(!options.get_list_option("cover").empty()) @@ -548,7 +444,7 @@ safety_checkert::resultt bmct::run( const optionst::value_listt criteria= options.get_list_option("cover"); return cover(goto_functions, criteria)? - safety_checkert::ERROR:safety_checkert::SAFE; + safety_checkert::resultt::ERROR:safety_checkert::resultt::SAFE; } if(options.get_option("localize-faults")!="") @@ -563,14 +459,14 @@ safety_checkert::resultt bmct::run( symex.remaining_vccs==0) { report_success(); - output_graphml(SAFE, goto_functions); - return safety_checkert::SAFE; + output_graphml(resultt::SAFE, goto_functions); + return safety_checkert::resultt::SAFE; } if(options.get_bool_option("program-only")) { show_program(); - return safety_checkert::SAFE; + return safety_checkert::resultt::SAFE; } return decide(goto_functions, prop_conv); @@ -579,34 +475,22 @@ safety_checkert::resultt bmct::run( catch(std::string &error_str) { error() << error_str << eom; - return safety_checkert::ERROR; + return safety_checkert::resultt::ERROR; } catch(const char *error_str) { error() << error_str << eom; - return safety_checkert::ERROR; + return safety_checkert::resultt::ERROR; } catch(std::bad_alloc) { error() << "Out of memory" << eom; - return safety_checkert::ERROR; + return safety_checkert::resultt::ERROR; } } -/*******************************************************************\ - -Function: bmct::decide - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - safety_checkert::resultt bmct::decide( const goto_functionst &goto_functions, prop_convt &prop_conv) @@ -619,30 +503,18 @@ safety_checkert::resultt bmct::decide( return all_properties(goto_functions, prop_conv); } -/*******************************************************************\ - -Function: bmct::stop_on_fail - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - safety_checkert::resultt bmct::stop_on_fail( const goto_functionst &goto_functions, prop_convt &prop_conv) { switch(run_decision_procedure(prop_conv)) { - case decision_proceduret::D_UNSATISFIABLE: + case decision_proceduret::resultt::D_UNSATISFIABLE: report_success(); - output_graphml(SAFE, goto_functions); - return SAFE; + output_graphml(resultt::SAFE, goto_functions); + return resultt::SAFE; - case decision_proceduret::D_SATISFIABLE: + case decision_proceduret::resultt::D_SATISFIABLE: if(options.get_bool_option("trace")) { if(options.get_bool_option("beautify")) @@ -650,35 +522,23 @@ safety_checkert::resultt bmct::stop_on_fail( dynamic_cast(prop_conv), equation, ns); error_trace(); - output_graphml(UNSAFE, goto_functions); + output_graphml(resultt::UNSAFE, goto_functions); } report_failure(); - return UNSAFE; + return resultt::UNSAFE; default: if(options.get_bool_option("dimacs") || options.get_option("outfile")!="") - return SAFE; + return resultt::SAFE; error() << "decision procedure failed" << eom; - return ERROR; + return resultt::ERROR; } } -/*******************************************************************\ - -Function: bmct::setup_unwind - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bmct::setup_unwind() { const std::string &set=options.get_option("unwindset"); diff --git a/src/cbmc/bmc.h b/src/cbmc/bmc.h index b81b2d94c38..e05a4de62f6 100644 --- a/src/cbmc/bmc.h +++ b/src/cbmc/bmc.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Bounded Model Checking for ANSI-C + HDL + #ifndef CPROVER_CBMC_BMC_H #define CPROVER_CBMC_BMC_H @@ -40,7 +43,7 @@ class bmct:public safety_checkert equation(ns), symex(ns, new_symbol_table, equation), prop_conv(_prop_conv), - ui(ui_message_handlert::PLAIN) + ui(ui_message_handlert::uit::PLAIN) { symex.constant_propagation=options.get_bool_option("propagation"); symex.record_coverage= diff --git a/src/cbmc/bmc_cover.cpp b/src/cbmc/bmc_cover.cpp index 5fb282778f5..8485988b4a2 100644 --- a/src/cbmc/bmc_cover.cpp +++ b/src/cbmc/bmc_cover.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Test-Suite Generation with BMC + +#include "bmc.h" + #include #include @@ -21,21 +26,8 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "bmc.h" #include "bv_cbmc.h" -/*******************************************************************\ - - Class: bmc_covert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - class bmc_covert: public cover_goalst::observert, public messaget @@ -77,7 +69,7 @@ class bmc_covert: std::string description; source_locationt source_location; - // if satisified, we compute a goto_trace + // if satisfied, we compute a goto_trace bool satisfied; goalt( @@ -149,18 +141,6 @@ class bmc_covert: bmct &bmc; }; -/*******************************************************************\ - -Function: bmc_covert::satisfying_assignment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bmc_covert::satisfying_assignment() { tests.push_back(testt()); @@ -210,18 +190,6 @@ void bmc_covert::satisfying_assignment() #endif } -/*******************************************************************\ - -Function: bmc_covert::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool bmc_covert::operator()() { status() << "Passing problem to " << solver.decision_procedure_text() << eom; @@ -309,7 +277,7 @@ bool bmc_covert::operator()() switch(bmc.ui) { - case ui_message_handlert::PLAIN: + case ui_message_handlert::uit::PLAIN: { status() << "\n** coverage results:" << eom; @@ -334,7 +302,7 @@ bool bmc_covert::operator()() break; } - case ui_message_handlert::XML_UI: + case ui_message_handlert::uit::XML_UI: { for(const auto &goal_pair : goal_map) { @@ -386,7 +354,7 @@ bool bmc_covert::operator()() break; } - case ui_message_handlert::JSON_UI: + case ui_message_handlert::uit::JSON_UI: { json_objectt json_result; json_arrayt &goals_array=json_result["goals"].make_array(); @@ -452,7 +420,7 @@ bool bmc_covert::operator()() << (cover_goals.iterations()==1?"":"s") << eom; - if(bmc.ui==ui_message_handlert::PLAIN) + if(bmc.ui==ui_message_handlert::uit::PLAIN) { std::cout << "Test suite:" << '\n'; @@ -463,18 +431,7 @@ bool bmc_covert::operator()() return false; } -/*******************************************************************\ - -Function: bmct::cover - - Inputs: - - Outputs: - - Purpose: Try to cover all goals - -\*******************************************************************/ - +/// Try to cover all goals bool bmct::cover( const goto_functionst &goto_functions, const optionst::value_listt &criteria) diff --git a/src/cbmc/bv_cbmc.cpp b/src/cbmc/bv_cbmc.cpp index 830507c0099..e1652695796 100644 --- a/src/cbmc/bv_cbmc.cpp +++ b/src/cbmc/bv_cbmc.cpp @@ -6,22 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include -#include - #include "bv_cbmc.h" -/*******************************************************************\ - -Function: bv_cbmct::convert_waitfor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include bvt bv_cbmct::convert_waitfor(const exprt &expr) { @@ -144,18 +132,6 @@ bvt bv_cbmct::convert_waitfor(const exprt &expr) return convert_bitvector(new_cycle); } -/*******************************************************************\ - -Function: bv_cbmct::convert_waitfor_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt bv_cbmct::convert_waitfor_symbol(const exprt &expr) { if(expr.operands().size()!=1) @@ -179,18 +155,6 @@ bvt bv_cbmct::convert_waitfor_symbol(const exprt &expr) return convert_bitvector(result); } -/*******************************************************************\ - -Function: bv_cbmct::convert_bitvector - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt bv_cbmct::convert_bitvector(const exprt &expr) { if(expr.id()=="waitfor") diff --git a/src/cbmc/bv_cbmc.h b/src/cbmc/bv_cbmc.h index 9f7cc8630f4..a55805ffbe7 100644 --- a/src/cbmc/bv_cbmc.h +++ b/src/cbmc/bv_cbmc.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_CBMC_BV_CBMC_H #define CPROVER_CBMC_BV_CBMC_H diff --git a/src/cbmc/cbmc_dimacs.cpp b/src/cbmc/cbmc_dimacs.cpp index 4df2dfbbed9..fc28153edc0 100644 --- a/src/cbmc/cbmc_dimacs.cpp +++ b/src/cbmc/cbmc_dimacs.cpp @@ -6,24 +6,15 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include -#include - -#include +/// \file +/// Writing DIMACS Files #include "cbmc_dimacs.h" -/*******************************************************************\ - -Function: cbmc_dimacst::write_dimacs - - Inputs: - - Outputs: - - Purpose: +#include +#include -\*******************************************************************/ +#include bool cbmc_dimacst::write_dimacs(const std::string &filename) { @@ -41,18 +32,6 @@ bool cbmc_dimacst::write_dimacs(const std::string &filename) return write_dimacs(out); } -/*******************************************************************\ - -Function: cbmc_dimacst::write_dimacs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool cbmc_dimacst::write_dimacs(std::ostream &out) { dynamic_cast(prop).write_dimacs_cnf(out); diff --git a/src/cbmc/cbmc_dimacs.h b/src/cbmc/cbmc_dimacs.h index e8ccda5155a..444a99e73f4 100644 --- a/src/cbmc/cbmc_dimacs.h +++ b/src/cbmc/cbmc_dimacs.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Writing DIMACS Files + #ifndef CPROVER_CBMC_CBMC_DIMACS_H #define CPROVER_CBMC_CBMC_DIMACS_H diff --git a/src/cbmc/cbmc_languages.cpp b/src/cbmc/cbmc_languages.cpp index a18d0344833..06b919b9cc4 100644 --- a/src/cbmc/cbmc_languages.cpp +++ b/src/cbmc/cbmc_languages.cpp @@ -6,49 +6,26 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Language Registration + +#include "cbmc_parse_options.h" + #include #include #include - -#ifdef HAVE_SPECC -#include -#endif - -#ifdef HAVE_JAVA_BYTECODE #include -#endif #ifdef HAVE_JSIL #include #endif -#include "cbmc_parse_options.h" - -/*******************************************************************\ - -Function: cbmc_parse_optionst::register_languages - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cbmc_parse_optionst::register_languages() { register_language(new_ansi_c_language); register_language(new_cpp_language); - - #ifdef HAVE_SPECC - register_language(new_specc_language); - #endif - - #ifdef HAVE_JAVA_BYTECODE register_language(new_java_bytecode_language); - #endif #ifdef HAVE_JSIL register_language(new_jsil_language); diff --git a/src/cbmc/cbmc_main.cpp b/src/cbmc/cbmc_main.cpp index d09ecc4772e..3a35c6bb197 100644 --- a/src/cbmc/cbmc_main.cpp +++ b/src/cbmc/cbmc_main.cpp @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// CBMC Main Module + /* CBMC @@ -14,26 +17,14 @@ Author: Daniel Kroening, kroening@kroening.com */ +#include "cbmc_parse_options.h" + #include #ifdef IREP_HASH_STATS #include #endif -#include "cbmc_parse_options.h" - -/*******************************************************************\ - -Function: main / wmain - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - #ifdef IREP_HASH_STATS extern unsigned long long irep_hash_cnt; extern unsigned long long irep_cmp_cnt; @@ -53,9 +44,9 @@ int main(int argc, const char **argv) int res=parse_options.main(); #ifdef IREP_HASH_STATS - std::cout << "IREP_HASH_CNT=" << irep_hash_cnt << std::endl; - std::cout << "IREP_CMP_CNT=" << irep_cmp_cnt << std::endl; - std::cout << "IREP_CMP_NE_CNT=" << irep_cmp_ne_cnt << std::endl; + std::cout << "IREP_HASH_CNT=" << irep_hash_cnt << '\n'; + std::cout << "IREP_CMP_CNT=" << irep_cmp_cnt << '\n'; + std::cout << "IREP_CMP_NE_CNT=" << irep_cmp_ne_cnt << '\n'; #endif return res; diff --git a/src/cbmc/cbmc_parse_options.cpp b/src/cbmc/cbmc_parse_options.cpp index 250097558c5..0e12193ce38 100644 --- a/src/cbmc/cbmc_parse_options.cpp +++ b/src/cbmc/cbmc_parse_options.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// CBMC Command Line Option Processing + +#include "cbmc_parse_options.h" + #include #include // exit() #include @@ -16,6 +21,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include +#include #include #include @@ -31,6 +37,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include +#include #include #include #include @@ -54,23 +61,10 @@ Author: Daniel Kroening, kroening@kroening.com #include #include "cbmc_solvers.h" -#include "cbmc_parse_options.h" #include "bmc.h" #include "version.h" #include "xml_interface.h" -/*******************************************************************\ - -Function: cbmc_parse_optionst::cbmc_parse_optionst - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - cbmc_parse_optionst::cbmc_parse_optionst(int argc, const char **argv): parse_options_baset(CBMC_OPTIONS, argc, argv), xml_interfacet(cmdline), @@ -79,18 +73,6 @@ cbmc_parse_optionst::cbmc_parse_optionst(int argc, const char **argv): { } -/*******************************************************************\ - -Function: cbmc_parse_optionst::cbmc_parse_optionst - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - ::cbmc_parse_optionst::cbmc_parse_optionst( int argc, const char **argv, @@ -102,18 +84,6 @@ ::cbmc_parse_optionst::cbmc_parse_optionst( { } -/*******************************************************************\ - -Function: cbmc_parse_optionst::eval_verbosity - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cbmc_parse_optionst::eval_verbosity() { // this is our default verbosity @@ -129,18 +99,6 @@ void cbmc_parse_optionst::eval_verbosity() ui_message_handler.set_verbosity(v); } -/*******************************************************************\ - -Function: cbmc_parse_optionst::get_command_line_options - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cbmc_parse_optionst::get_command_line_options(optionst &options) { overlay_map omap; @@ -445,23 +403,12 @@ void cbmc_parse_optionst::get_command_line_options(optionst &options) cmdline.get_value("symex-coverage-report")); } -/*******************************************************************\ - -Function: cbmc_parse_optionst::doit - - Inputs: - - Outputs: - - Purpose: invoke main modules - -\*******************************************************************/ - +/// invoke main modules int cbmc_parse_optionst::doit() { if(cmdline.isset("version")) { - std::cout << CBMC_VERSION << std::endl; + std::cout << CBMC_VERSION << '\n'; return 0; // should contemplate EX_OK from sysexits.h } @@ -506,35 +453,14 @@ int cbmc_parse_optionst::doit() goto_functionst goto_functions; - // get solver - cbmc_solverst cbmc_solvers(options, symbol_table, ui_message_handler); - cbmc_solvers.set_ui(get_ui()); - - std::unique_ptr cbmc_solver; - - try - { - cbmc_solver=cbmc_solvers.get_solver(); - } - - catch(const char *error_msg) - { - error() << error_msg << eom; - return 1; // should contemplate EX_SOFTWARE from sysexits.h - } - - prop_convt &prop_conv=cbmc_solver->prop_conv(); - - bmct bmc(options, symbol_table, ui_message_handler, prop_conv); + expr_listt bmc_constraints; int get_goto_program_ret= - get_goto_program(options, bmc, goto_functions); + get_goto_program(options, bmc_constraints, goto_functions); if(get_goto_program_ret!=-1) return get_goto_program_ret; - label_properties(goto_functions); - if(cmdline.isset("show-claims") || // will go away cmdline.isset("show-properties")) // use this one { @@ -551,21 +477,30 @@ int cbmc_parse_optionst::doit() if(options.get_bool_option("java-unwind-enum-static")) remove_static_init_loops(symbol_table, goto_functions, options); - // do actual BMC - return do_bmc(bmc, goto_functions); -} + // get solver + cbmc_solverst cbmc_solvers(options, symbol_table, ui_message_handler); + cbmc_solvers.set_ui(get_ui()); -/*******************************************************************\ + std::unique_ptr cbmc_solver; -Function: cbmc_parse_optionst::set_properties + try + { + cbmc_solver=cbmc_solvers.get_solver(); + } - Inputs: + catch(const char *error_msg) + { + error() << error_msg << eom; + return 1; // should contemplate EX_SOFTWARE from sysexits.h + } - Outputs: + prop_convt &prop_conv=cbmc_solver->prop_conv(); - Purpose: + bmct bmc(options, symbol_table, ui_message_handler, prop_conv); -\*******************************************************************/ + // do actual BMC + return do_bmc(bmc, goto_functions); +} bool cbmc_parse_optionst::set_properties(goto_functionst &goto_functions) { @@ -598,21 +533,9 @@ bool cbmc_parse_optionst::set_properties(goto_functionst &goto_functions) return false; } -/*******************************************************************\ - -Function: cbmc_parse_optionst::get_goto_program - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - int cbmc_parse_optionst::get_goto_program( const optionst &options, - bmct &bmc, // for get_modules + expr_listt &bmc_constraints, // for get_modules goto_functionst &goto_functions) { if(cmdline.args.empty()) @@ -649,7 +572,7 @@ int cbmc_parse_optionst::get_goto_program( languaget *language=get_language_from_filename(filename); - if(language==NULL) + if(language==nullptr) { error() << "failed to figure out type of file `" << filename << "'" << eom; @@ -658,7 +581,7 @@ int cbmc_parse_optionst::get_goto_program( language->set_message_handler(get_message_handler()); - status("Parsing", filename); + status() << "Parsing " << filename << eom; if(language->parse(infile, filename)) { @@ -694,7 +617,7 @@ int cbmc_parse_optionst::get_goto_program( return 6; if(typecheck()) return 6; - int get_modules_ret=get_modules(bmc); + int get_modules_ret=get_modules(bmc_constraints); if(get_modules_ret!=-1) return get_modules_ret; if(binaries.empty() && final()) @@ -776,18 +699,6 @@ int cbmc_parse_optionst::get_goto_program( return -1; // no error, continue } -/*******************************************************************\ - -Function: cbmc_parse_optionst::preprocessing - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cbmc_parse_optionst::preprocessing() { try @@ -810,7 +721,7 @@ void cbmc_parse_optionst::preprocessing() languaget *ptr=get_language_from_filename(filename); - if(ptr==NULL) + if(ptr==nullptr) { error() << "failed to figure out type of file" << eom; return; @@ -844,18 +755,6 @@ void cbmc_parse_optionst::preprocessing() } } -/*******************************************************************\ - -Function: cbmc_parse_optionst::process_goto_program - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool cbmc_parse_optionst::process_goto_program( const optionst &options, goto_functionst &goto_functions) @@ -889,6 +788,8 @@ bool cbmc_parse_optionst::process_goto_program( // Similar removal of RTTI inspection: remove_instanceof(symbol_table, goto_functions); + mm_io(symbol_table, goto_functions); + // do partial inlining status() << "Partial Inlining" << eom; goto_partial_inline(goto_functions, ns, ui_message_handler); @@ -903,13 +804,6 @@ bool cbmc_parse_optionst::process_goto_program( status() << "Generic Property Instrumentation" << eom; goto_check(ns, options, goto_functions); - // full slice? - if(cmdline.isset("full-slice")) - { - status() << "Performing a full slice" << eom; - full_slicer(goto_functions, ns); - } - // checks don't know about adjusted float expressions adjust_float_expressions(goto_functions, ns); @@ -959,6 +853,23 @@ bool cbmc_parse_optionst::process_goto_program( return true; } + // label the assertions + // This must be done after adding assertions and + // before using the argument of the "property" option. + // Do not re-label after using the property slicer because + // this would cause the property identifiers to change. + label_properties(goto_functions); + + // full slice? + if(cmdline.isset("full-slice")) + { + status() << "Performing a full slice" << eom; + if(cmdline.isset("property")) + property_slicer(goto_functions, ns, cmdline.get_values("property")); + else + full_slicer(goto_functions, ns); + } + // remove skips remove_skip(goto_functions); goto_functions.update(); @@ -990,18 +901,7 @@ bool cbmc_parse_optionst::process_goto_program( return false; } -/*******************************************************************\ - -Function: cbmc_parse_optionst::do_bmc - - Inputs: - - Outputs: - - Purpose: invoke main modules - -\*******************************************************************/ - +/// invoke main modules int cbmc_parse_optionst::do_bmc( bmct &bmc, const goto_functionst &goto_functions) @@ -1013,13 +913,13 @@ int cbmc_parse_optionst::do_bmc( // do actual BMC switch(bmc.run(goto_functions)) { - case safety_checkert::SAFE: + case safety_checkert::resultt::SAFE: result=0; break; - case safety_checkert::UNSAFE: + case safety_checkert::resultt::UNSAFE: result=10; break; - case safety_checkert::ERROR: + case safety_checkert::resultt::ERROR: result=6; break; } @@ -1032,23 +932,12 @@ int cbmc_parse_optionst::do_bmc( return result; } -/*******************************************************************\ - -Function: cbmc_parse_optionst::help - - Inputs: - - Outputs: - - Purpose: display command line help - -\*******************************************************************/ - +/// display command line help void cbmc_parse_optionst::help() { std::cout << "\n" - "* * CBMC " CBMC_VERSION " - Copyright (C) 2001-2016 "; + "* * CBMC " CBMC_VERSION " - Copyright (C) 2001-2017 "; std::cout << "(" << (sizeof(void *)*8) << "-bit version)"; diff --git a/src/cbmc/cbmc_parse_options.h b/src/cbmc/cbmc_parse_options.h index db987d3c304..4d8e6753476 100644 --- a/src/cbmc/cbmc_parse_options.h +++ b/src/cbmc/cbmc_parse_options.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// CBMC Command Line Option Processing + #ifndef CPROVER_CBMC_CBMC_PARSE_OPTIONS_H #define CPROVER_CBMC_CBMC_PARSE_OPTIONS_H @@ -82,11 +85,14 @@ class cbmc_parse_optionst: virtual void register_languages(); virtual void get_command_line_options(optionst &options); - virtual int do_bmc(bmct &bmc, const goto_functionst &goto_functions); + + virtual int do_bmc( + bmct &bmc, + const goto_functionst &goto_functions); virtual int get_goto_program( const optionst &options, - bmct &bmc, + expr_listt &bmc_constraints, goto_functionst &goto_functions); virtual bool process_goto_program( @@ -97,8 +103,8 @@ class cbmc_parse_optionst: void eval_verbosity(); - // get any additional stuff before finalizing - virtual int get_modules(bmct &bmc) + // get any additional stuff before finalizing the goto program + virtual int get_modules(expr_listt &bmc_constraints) { return -1; // continue } diff --git a/src/cbmc/cbmc_solvers.cpp b/src/cbmc/cbmc_solvers.cpp index ccd660dc586..d3198249558 100644 --- a/src/cbmc/cbmc_solvers.cpp +++ b/src/cbmc/cbmc_solvers.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Solvers for VCs Generated by Symbolic Execution of ANSI-C + +#include "cbmc_solvers.h" + #include #include #include @@ -20,100 +25,68 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "cbmc_solvers.h" #include "bv_cbmc.h" #include "cbmc_dimacs.h" #include "counterexample_beautification.h" #include "version.h" -/*******************************************************************\ - -Function: cbmc_solverst::get_smt1_solver_type - - Inputs: None - - Outputs: An smt1_dect::solvert giving the solver to use. - - Purpose: Uses the options to pick an SMT 1.2 solver - -\*******************************************************************/ - +/// Uses the options to pick an SMT 1.2 solver +/// \return An smt1_dect::solvert giving the solver to use. smt1_dect::solvert cbmc_solverst::get_smt1_solver_type() const { assert(options.get_bool_option("smt1")); - smt1_dect::solvert s=smt1_dect::GENERIC; + smt1_dect::solvert s=smt1_dect::solvert::GENERIC; if(options.get_bool_option("boolector")) - s=smt1_dect::BOOLECTOR; + s=smt1_dect::solvert::BOOLECTOR; else if(options.get_bool_option("mathsat")) - s=smt1_dect::MATHSAT; + s=smt1_dect::solvert::MATHSAT; else if(options.get_bool_option("cvc3")) - s=smt1_dect::CVC3; + s=smt1_dect::solvert::CVC3; else if(options.get_bool_option("cvc4")) - s=smt1_dect::CVC4; + s=smt1_dect::solvert::CVC4; else if(options.get_bool_option("opensmt")) - s=smt1_dect::OPENSMT; + s=smt1_dect::solvert::OPENSMT; else if(options.get_bool_option("yices")) - s=smt1_dect::YICES; + s=smt1_dect::solvert::YICES; else if(options.get_bool_option("z3")) - s=smt1_dect::Z3; + s=smt1_dect::solvert::Z3; else if(options.get_bool_option("generic")) - s=smt1_dect::GENERIC; + s=smt1_dect::solvert::GENERIC; return s; } -/*******************************************************************\ - -Function: cbmc_solverst::get_smt2_solver_type - - Inputs: None - - Outputs: An smt2_dect::solvert giving the solver to use. - - Purpose: Uses the options to pick an SMT 2.0 solver - -\*******************************************************************/ - +/// Uses the options to pick an SMT 2.0 solver +/// \return An smt2_dect::solvert giving the solver to use. smt2_dect::solvert cbmc_solverst::get_smt2_solver_type() const { assert(options.get_bool_option("smt2")); - smt2_dect::solvert s=smt2_dect::GENERIC; + smt2_dect::solvert s=smt2_dect::solvert::GENERIC; if(options.get_bool_option("boolector")) - s=smt2_dect::BOOLECTOR; + s=smt2_dect::solvert::BOOLECTOR; else if(options.get_bool_option("mathsat")) - s=smt2_dect::MATHSAT; + s=smt2_dect::solvert::MATHSAT; else if(options.get_bool_option("cvc3")) - s=smt2_dect::CVC3; + s=smt2_dect::solvert::CVC3; else if(options.get_bool_option("cvc4")) - s=smt2_dect::CVC4; + s=smt2_dect::solvert::CVC4; else if(options.get_bool_option("opensmt")) - s=smt2_dect::OPENSMT; + s=smt2_dect::solvert::OPENSMT; else if(options.get_bool_option("yices")) - s=smt2_dect::YICES; + s=smt2_dect::solvert::YICES; else if(options.get_bool_option("z3")) - s=smt2_dect::Z3; + s=smt2_dect::solvert::Z3; else if(options.get_bool_option("generic")) - s=smt2_dect::GENERIC; + s=smt2_dect::solvert::GENERIC; return s; } -/*******************************************************************\ - -Function: cbmc_solverst::get_default - - Inputs: - - Outputs: - - Purpose: Get the default decision procedure - -\*******************************************************************/ - +/// Get the default decision procedure cbmc_solverst::solvert* cbmc_solverst::get_default() { solvert *solver=new solvert; @@ -134,27 +107,15 @@ cbmc_solverst::solvert* cbmc_solverst::get_default() bv_cbmct *bv_cbmc=new bv_cbmct(ns, solver->prop()); if(options.get_option("arrays-uf")=="never") - bv_cbmc->unbounded_array=bv_cbmct::U_NONE; + bv_cbmc->unbounded_array=bv_cbmct::unbounded_arrayt::U_NONE; else if(options.get_option("arrays-uf")=="always") - bv_cbmc->unbounded_array=bv_cbmct::U_ALL; + bv_cbmc->unbounded_array=bv_cbmct::unbounded_arrayt::U_ALL; solver->set_prop_conv(bv_cbmc); return solver; } -/*******************************************************************\ - -Function: cbmc_solverst::get_dimacs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - cbmc_solverst::solvert* cbmc_solverst::get_dimacs() { no_beautification(); @@ -168,18 +129,6 @@ cbmc_solverst::solvert* cbmc_solverst::get_dimacs() return new solvert(new cbmc_dimacst(ns, *prop, filename), prop); } -/*******************************************************************\ - -Function: cbmc_solverst::get_bv_refinement - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - cbmc_solverst::solvert* cbmc_solverst::get_bv_refinement() { propt *prop; @@ -211,18 +160,6 @@ cbmc_solverst::solvert* cbmc_solverst::get_bv_refinement() return new solvert(bv_refinement, prop); } -/*******************************************************************\ - -Function: cbmc_solverst::get_smt1 - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - cbmc_solverst::solvert* cbmc_solverst::get_smt1(smt1_dect::solvert solver) { no_beautification(); @@ -232,7 +169,7 @@ cbmc_solverst::solvert* cbmc_solverst::get_smt1(smt1_dect::solvert solver) if(filename=="") { - if(solver==smt1_dect::GENERIC) + if(solver==smt1_dect::solvert::GENERIC) { error() << "please use --outfile" << eom; throw 0; @@ -292,18 +229,6 @@ cbmc_solverst::solvert* cbmc_solverst::get_smt1(smt1_dect::solvert solver) } } -/*******************************************************************\ - -Function: cbmc_solverst::get_smt2 - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - cbmc_solverst::solvert* cbmc_solverst::get_smt2(smt2_dect::solvert solver) { no_beautification(); @@ -312,7 +237,7 @@ cbmc_solverst::solvert* cbmc_solverst::get_smt2(smt2_dect::solvert solver) if(filename=="") { - if(solver==smt2_dect::GENERIC) + if(solver==smt2_dect::solvert::GENERIC) { error() << "please use --outfile" << eom; throw 0; @@ -381,18 +306,6 @@ cbmc_solverst::solvert* cbmc_solverst::get_smt2(smt2_dect::solvert solver) } } -/*******************************************************************\ - -Function: cbmc_solverst::no_beautification - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cbmc_solverst::no_beautification() { if(options.get_bool_option("beautify")) @@ -402,18 +315,6 @@ void cbmc_solverst::no_beautification() } } -/*******************************************************************\ - -Function: cbmc_solverst::no_incremental_check - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cbmc_solverst::no_incremental_check() { if(options.get_bool_option("all-properties") || diff --git a/src/cbmc/cbmc_solvers.h b/src/cbmc/cbmc_solvers.h index 42d47fcaed3..1af31cdc03c 100644 --- a/src/cbmc/cbmc_solvers.h +++ b/src/cbmc/cbmc_solvers.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Bounded Model Checking for ANSI-C + HDL + #ifndef CPROVER_CBMC_CBMC_SOLVERS_H #define CPROVER_CBMC_CBMC_SOLVERS_H @@ -27,12 +30,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "bv_cbmc.h" -/*******************************************************************\ - -Solver factory - -\*******************************************************************/ - class cbmc_solverst:public messaget { public: @@ -43,7 +40,8 @@ class cbmc_solverst:public messaget messaget(_message_handler), options(_options), symbol_table(_symbol_table), - ns(_symbol_table) + ns(_symbol_table), + ui(ui_message_handlert::uit::PLAIN) { } diff --git a/src/cbmc/counterexample_beautification.cpp b/src/cbmc/counterexample_beautification.cpp index c0e5d1ba230..3cee2da664b 100644 --- a/src/cbmc/counterexample_beautification.cpp +++ b/src/cbmc/counterexample_beautification.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Counterexample Beautification using Incremental SAT + +#include "counterexample_beautification.h" + #include #include #include @@ -14,20 +19,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "counterexample_beautification.h" - -/*******************************************************************\ - -Function: counterexample_beautificationt::get_minimization_list - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void counterexample_beautificationt::get_minimization_list( prop_convt &prop_conv, const symex_target_equationt &equation, @@ -40,7 +31,7 @@ void counterexample_beautificationt::get_minimization_list( it!=equation.SSA_steps.end(); it++) { if(it->is_assignment() && - it->assignment_type==symex_targett::STATE) + it->assignment_type==symex_targett::assignment_typet::STATE) { if(!prop_conv.l_get(it->guard_literal).is_false()) { @@ -68,18 +59,6 @@ void counterexample_beautificationt::get_minimization_list( } } -/*******************************************************************\ - -Function: counterexample_beautificationt::get_failed_property - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - symex_target_equationt::SSA_stepst::const_iterator counterexample_beautificationt::get_failed_property( const prop_convt &prop_conv, @@ -99,18 +78,6 @@ counterexample_beautificationt::get_failed_property( return equation.SSA_steps.end(); } -/*******************************************************************\ - -Function: counterexample_beautificationt::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void counterexample_beautificationt::operator()( bv_cbmct &bv_cbmc, const symex_target_equationt &equation, @@ -136,7 +103,7 @@ void counterexample_beautificationt::operator()( it!=equation.SSA_steps.end(); it++) { if(it->is_assignment() && - it->assignment_type!=symex_targett::HIDDEN) + it->assignment_type!=symex_targett::assignment_typet::HIDDEN) { if(!it->guard_literal.is_constant()) guard_count[it->guard_literal]++; diff --git a/src/cbmc/counterexample_beautification.h b/src/cbmc/counterexample_beautification.h index d4f9c35bc88..10bb96f4597 100644 --- a/src/cbmc/counterexample_beautification.h +++ b/src/cbmc/counterexample_beautification.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Counterexample Beautification + #ifndef CPROVER_CBMC_COUNTEREXAMPLE_BEAUTIFICATION_H #define CPROVER_CBMC_COUNTEREXAMPLE_BEAUTIFICATION_H diff --git a/src/cbmc/fault_localization.cpp b/src/cbmc/fault_localization.cpp index 9fa6651c1c8..414c30e5e9a 100644 --- a/src/cbmc/fault_localization.cpp +++ b/src/cbmc/fault_localization.cpp @@ -6,6 +6,11 @@ Author: Peter Schrammel \*******************************************************************/ +/// \file +/// Fault Localization + +#include "fault_localization.h" + #include #include #include @@ -18,21 +23,8 @@ Author: Peter Schrammel #include -#include "fault_localization.h" #include "counterexample_beautification.h" -/*******************************************************************\ - -Function: fault_localizationt::freeze_guards - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void fault_localizationt::freeze_guards() { for(const auto &step : bmc.equation.SSA_steps) @@ -45,18 +37,6 @@ void fault_localizationt::freeze_guards() } } -/*******************************************************************\ - -Function: fault_localizationt::collect_guards - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void fault_localizationt::collect_guards(lpointst &lpoints) { for(symex_target_equationt::SSA_stepst::const_iterator @@ -64,7 +44,7 @@ void fault_localizationt::collect_guards(lpointst &lpoints) it!=bmc.equation.SSA_steps.end(); it++) { if(it->is_assignment() && - it->assignment_type==symex_targett::STATE && + it->assignment_type==symex_targett::assignment_typet::STATE && !it->ignore) { if(!it->guard_literal.is_constant()) @@ -80,18 +60,6 @@ void fault_localizationt::collect_guards(lpointst &lpoints) } } -/*******************************************************************\ - -Function: fault_localizationt::get_failed_property - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - symex_target_equationt::SSA_stepst::const_iterator fault_localizationt::get_failed_property() { @@ -107,18 +75,6 @@ fault_localizationt::get_failed_property() return bmc.equation.SSA_steps.end(); } -/*******************************************************************\ - -Function: fault_localizationt::check - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool fault_localizationt::check(const lpointst &lpoints, const lpoints_valuet &value) { @@ -139,24 +95,12 @@ bool fault_localizationt::check(const lpointst &lpoints, bmc.prop_conv.set_assumptions(assumptions); - if(bmc.prop_conv()==decision_proceduret::D_SATISFIABLE) + if(bmc.prop_conv()==decision_proceduret::resultt::D_SATISFIABLE) return false; return true; } -/*******************************************************************\ - -Function: fault_localizationt::update_scores - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void fault_localizationt::update_scores(lpointst &lpoints, const lpoints_valuet &value) { @@ -174,18 +118,6 @@ void fault_localizationt::update_scores(lpointst &lpoints, } } -/*******************************************************************\ - -Function: fault_localizationt::localize_linear - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void fault_localizationt::localize_linear(lpointst &lpoints) { lpoints_valuet v; @@ -204,18 +136,6 @@ void fault_localizationt::localize_linear(lpointst &lpoints) } } -/*******************************************************************\ - -Function: fault_localizationt::run - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void fault_localizationt::run(irep_idt goal_id) { // find failed property @@ -243,18 +163,6 @@ void fault_localizationt::run(irep_idt goal_id) bmc.prop_conv.set_assumptions(assumptions); } -/*******************************************************************\ - -Function: fault_localizationt::report() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void fault_localizationt::report(irep_idt goal_id) { if(goal_id==ID_nil) @@ -284,18 +192,6 @@ void fault_localizationt::report(irep_idt goal_id) << eom; } -/*******************************************************************\ - -Function: fault_localizationt::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - safety_checkert::resultt fault_localizationt::operator()() { if(options.get_bool_option("stop-on-fail")) @@ -304,18 +200,6 @@ safety_checkert::resultt fault_localizationt::operator()() return bmc_all_propertiest::operator()(); } -/*******************************************************************\ - -Function: fault_localizationt::run_decision_procedure - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - decision_proceduret::resultt fault_localizationt::run_decision_procedure(prop_convt &prop_conv) { @@ -346,27 +230,15 @@ fault_localizationt::run_decision_procedure(prop_convt &prop_conv) return dec_result; } -/*******************************************************************\ - -Function: fault_localizationt::stop_on_fail - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - safety_checkert::resultt fault_localizationt::stop_on_fail() { switch(run_decision_procedure(bmc.prop_conv)) { - case decision_proceduret::D_UNSATISFIABLE: + case decision_proceduret::resultt::D_UNSATISFIABLE: bmc.report_success(); - return safety_checkert::SAFE; + return safety_checkert::resultt::SAFE; - case decision_proceduret::D_SATISFIABLE: + case decision_proceduret::resultt::D_SATISFIABLE: if(options.get_bool_option("trace")) { if(options.get_bool_option("beautify")) @@ -382,27 +254,15 @@ safety_checkert::resultt fault_localizationt::stop_on_fail() report(ID_nil); bmc.report_failure(); - return safety_checkert::UNSAFE; + return safety_checkert::resultt::UNSAFE; default: error() << "decision procedure failed" << eom; - return safety_checkert::ERROR; + return safety_checkert::resultt::ERROR; } } -/*******************************************************************\ - -Function: fault_localizationt::goal_covered - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void fault_localizationt::goal_covered( const cover_goalst::goalt &) { @@ -434,18 +294,6 @@ void fault_localizationt::goal_covered( } } -/*******************************************************************\ - -Function: fault_localizationt::report - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void fault_localizationt::report( const cover_goalst &cover_goals) { @@ -453,7 +301,7 @@ void fault_localizationt::report( switch(bmc.ui) { - case ui_message_handlert::PLAIN: + case ui_message_handlert::uit::PLAIN: if(cover_goals.number_covered()>0) { status() << "\n** Most likely fault location:" << eom; @@ -465,9 +313,9 @@ void fault_localizationt::report( } } break; - case ui_message_handlert::XML_UI: + case ui_message_handlert::uit::XML_UI: break; - case ui_message_handlert::JSON_UI: + case ui_message_handlert::uit::JSON_UI: break; } } diff --git a/src/cbmc/fault_localization.h b/src/cbmc/fault_localization.h index 552095b7cd3..0c3ec090153 100644 --- a/src/cbmc/fault_localization.h +++ b/src/cbmc/fault_localization.h @@ -6,6 +6,9 @@ Author: Peter Schrammel \*******************************************************************/ +/// \file +/// Fault Localization + #ifndef CPROVER_CBMC_FAULT_LOCALIZATION_H #define CPROVER_CBMC_FAULT_LOCALIZATION_H diff --git a/src/cbmc/module.md b/src/cbmc/module.md new file mode 100644 index 00000000000..d2dcb75b4b3 --- /dev/null +++ b/src/cbmc/module.md @@ -0,0 +1,47 @@ +\ingroup module_hidden +\defgroup module_cbmc CBMC tour + +\author Kareem Khazem + +CBMC takes C code or a goto-binary as input and tries to emit traces of +executions that lead to crashes or undefined behaviour. The diagram +below shows the intermediate steps in this process. + + +\dot +digraph G { + + rankdir="TB"; + node [shape=box, fontcolor=blue]; + + subgraph top { + rank=same; + 1 -> 2 -> 3 -> 4; + } + + subgraph bottom { + rank=same; + 5 -> 6 -> 7 -> 8 -> 9; + } + + /* shift bottom subgraph over */ + 9 -> 1 [color=white]; + + 4 -> 5; + + 1 [label="command line\nparsing" URL="\ref cbmc_parse_optionst"]; + 2 [label="preprocessing,\nparsing" URL="\ref preprocessing"]; + 3 [label="language\ntype-checking" URL="\ref type-checking"]; + 4 [label="goto\nconversion" URL="\ref goto-conversion"]; + 5 [label="instrumentation" URL="\ref instrumentation"]; + 6 [label="symbolic\nexecution" URL="\ref symbolic-execution"]; + 7 [label="SAT/SMT\nencoding" URL="\ref sat-smt-encoding"]; + 8 [label="decision\nprocedure" URL="\ref decision-procedure"]; + 9 [label="counter example\nproduction" URL="\ref counter-example-production"]; +} +\enddot + +The \ref cprover-manual "CProver Manual" describes CBMC from a user +perspective. Each node in the diagram above links to the appropriate +class or module documentation, describing that particular stage in the +CBMC pipeline. diff --git a/src/cbmc/show_vcc.cpp b/src/cbmc/show_vcc.cpp index 46e7603662f..067b22461c3 100644 --- a/src/cbmc/show_vcc.cpp +++ b/src/cbmc/show_vcc.cpp @@ -6,38 +6,24 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symbolic Execution of ANSI-C + +#include "bmc.h" + #include #include #include -#include #include -#include - #include #include -#include "bmc.h" - -/*******************************************************************\ - -Function: bmct::show_vcc_plain - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bmct::show_vcc_plain(std::ostream &out) { out << "\n" << "VERIFICATION CONDITIONS:" << "\n" << "\n"; - languagest languages(ns, new_ansi_c_language()); - bool has_threads=equation.has_threads(); for(symex_target_equationt::SSA_stepst::iterator @@ -66,8 +52,8 @@ void bmct::show_vcc_plain(std::ostream &out) { if(!p_it->ignore) { - std::string string_value; - languages.from_expr(p_it->cond_expr, string_value); + std::string string_value= + from_expr(ns, "", p_it->cond_expr); out << "{-" << count << "} " << string_value << "\n"; #if 0 @@ -82,34 +68,20 @@ void bmct::show_vcc_plain(std::ostream &out) out << "|--------------------------" << "\n"; - std::string string_value; - languages.from_expr(s_it->cond_expr, string_value); + std::string string_value= + from_expr(ns, "", s_it->cond_expr); out << "{" << 1 << "} " << string_value << "\n"; out << "\n"; } } -/*******************************************************************\ - -Function: bmct::show_vcc_json - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bmct::show_vcc_json(std::ostream &out) { json_objectt json_result; json_arrayt &json_vccs=json_result["vccs"].make_array(); - languagest languages(ns, new_ansi_c_language()); - bool has_threads=equation.has_threads(); for(symex_target_equationt::SSA_stepst::iterator @@ -146,32 +118,20 @@ void bmct::show_vcc_json(std::ostream &out) p_it->is_constraint()) && !p_it->ignore) { - std::string string_value; - languages.from_expr(p_it->cond_expr, string_value); + std::string string_value= + from_expr(ns, "", p_it->cond_expr); json_constraints.push_back(json_stringt(string_value)); } } - std::string string_value; - languages.from_expr(s_it->cond_expr, string_value); + std::string string_value= + from_expr(ns, "", s_it->cond_expr); object["expression"]=json_stringt(string_value); } out << ",\n" << json_result; } -/*******************************************************************\ - -Function: bmct::show_vcc - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bmct::show_vcc() { const std::string &filename=options.get_option("outfile"); @@ -190,15 +150,15 @@ void bmct::show_vcc() switch(ui) { - case ui_message_handlert::XML_UI: + case ui_message_handlert::uit::XML_UI: error() << "XML UI not supported" << eom; return; - case ui_message_handlert::JSON_UI: + case ui_message_handlert::uit::JSON_UI: show_vcc_json(out); break; - case ui_message_handlert::PLAIN: + case ui_message_handlert::uit::PLAIN: show_vcc_plain(out); break; } diff --git a/src/cbmc/symex_bmc.cpp b/src/cbmc/symex_bmc.cpp index 5ae65275ef6..1212e0405d8 100644 --- a/src/cbmc/symex_bmc.cpp +++ b/src/cbmc/symex_bmc.cpp @@ -6,24 +6,15 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - -#include -#include +/// \file +/// Bounded Model Checking for ANSI-C #include "symex_bmc.h" -/*******************************************************************\ - -Function: symex_bmct::symex_bmct - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include +#include symex_bmct::symex_bmct( const namespacet &_ns, @@ -31,23 +22,13 @@ symex_bmct::symex_bmct( symex_targett &_target): goto_symext(_ns, _new_symbol_table, _target), record_coverage(false), + max_unwind(0), max_unwind_is_set(false), symex_coverage(_ns) { } -/*******************************************************************\ - -Function: symex_bmct::symex_step - - Inputs: - - Outputs: - - Purpose: show progress - -\*******************************************************************/ - +/// show progress void symex_bmct::symex_step( const goto_functionst &goto_functions, statet &state) @@ -65,6 +46,7 @@ void symex_bmct::symex_step( } const goto_programt::const_targett cur_pc=state.source.pc; + const guardt cur_guard=state.guard; if(!state.guard.is_false() && state.source.pc->is_assume() && @@ -84,30 +66,25 @@ void symex_bmct::symex_step( goto_symext::symex_step(goto_functions, state); if(record_coverage && - // is the instruction being executed - !state.guard.is_false() && // avoid an invalid iterator in state.source.pc (!cur_pc->is_end_function() || - cur_pc->function!=goto_functions.entry_point()) && - // ignore transition to next instruction when goto points elsewhere - (!cur_pc->is_goto() || - cur_pc->get_target()==state.source.pc || - !cur_pc->guard.is_true())) - symex_coverage.covered(cur_pc, state.source.pc); + cur_pc->function!=goto_functions.entry_point())) + { + // forward goto will effectively be covered via phi function, + // which does not invoke symex_step; as symex_step is called + // before merge_gotos, also state.guard will be false (we have + // taken an impossible transition); thus we synthesize a + // transition from the goto instruction to its target to make + // sure the goto is considered covered + if(cur_pc->is_goto() && + cur_pc->get_target()!=state.source.pc && + cur_pc->guard.is_true()) + symex_coverage.covered(cur_pc, cur_pc->get_target()); + else if(!state.guard.is_false()) + symex_coverage.covered(cur_pc, state.source.pc); + } } -/*******************************************************************\ - -Function: symex_bmct::merge_goto - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_bmct::merge_goto( const statet::goto_statet &goto_state, statet &state) @@ -127,18 +104,6 @@ void symex_bmct::merge_goto( symex_coverage.covered(prev_pc, state.source.pc); } -/*******************************************************************\ - -Function: symex_bmct::get_unwind - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool symex_bmct::get_unwind( const symex_targett::sourcet &source, unsigned unwind) @@ -180,18 +145,6 @@ bool symex_bmct::get_unwind( return abort; } -/*******************************************************************\ - -Function: symex_bmct::get_unwind_recursion - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool symex_bmct::get_unwind_recursion( const irep_idt &id, const unsigned thread_nr, @@ -237,18 +190,6 @@ bool symex_bmct::get_unwind_recursion( return abort; } -/*******************************************************************\ - -Function: symex_bmct::no_body - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_bmct::no_body(const irep_idt &identifier) { if(body_warnings.insert(identifier).second) diff --git a/src/cbmc/symex_bmc.h b/src/cbmc/symex_bmc.h index 8b2df348f3b..b8d23a52719 100644 --- a/src/cbmc/symex_bmc.h +++ b/src/cbmc/symex_bmc.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Bounded Model Checking for ANSI-C + #ifndef CPROVER_CBMC_SYMEX_BMC_H #define CPROVER_CBMC_SYMEX_BMC_H diff --git a/src/cbmc/symex_coverage.cpp b/src/cbmc/symex_coverage.cpp index 812df4de062..f9ac9cc207d 100644 --- a/src/cbmc/symex_coverage.cpp +++ b/src/cbmc/symex_coverage.cpp @@ -8,6 +8,11 @@ Date: March 2016 \*******************************************************************/ +/// \file +/// Record and print code coverage of symbolic execution + +#include "symex_coverage.h" + #include #include #include @@ -21,8 +26,6 @@ Date: March 2016 #include #include -#include "symex_coverage.h" - class coverage_recordt { public: @@ -91,18 +94,6 @@ class goto_program_coverage_recordt:public coverage_recordt coverage_lines_mapt &dest); }; -/*******************************************************************\ - -Function: rate - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static std::string rate( std::size_t covered, std::size_t total, @@ -129,17 +120,16 @@ static std::string rate( return oss.str(); } -/*******************************************************************\ - -Function: goto_program_coverage_recordt::goto_program_coverage_recordt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +static std::string rate_detailed( + std::size_t covered, + std::size_t total, + bool per_cent=false) +{ + std::ostringstream oss; + oss << rate(covered, total, per_cent) + << " (" << covered << '/' << total << ')'; + return oss.str(); +} goto_program_coverage_recordt::goto_program_coverage_recordt( const namespacet &ns, @@ -187,7 +177,7 @@ goto_program_coverage_recordt::goto_program_coverage_recordt( from_type(ns, gf_it->first, sig_type)); xml.set_attribute("line-rate", - rate(lines_covered, lines_total)); + rate_detailed(lines_covered, lines_total)); xml.set_attribute("branch-rate", rate(branches_covered, branches_total)); @@ -219,26 +209,13 @@ goto_program_coverage_recordt::goto_program_coverage_recordt( condition.set_attribute("coverage", rate(taken, 2, true)); } - std::ostringstream oss; - oss << rate(total_taken, number*2, true) - << " (" << total_taken << '/' << number*2 << ')'; - line.set_attribute("condition-coverage", oss.str()); + line.set_attribute( + "condition-coverage", + rate_detailed(total_taken, number*2, true)); } } } -/*******************************************************************\ - -Function: goto_program_coverage_recordt::compute_coverage_lines - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_program_coverage_recordt::compute_coverage_lines( const goto_programt &goto_program, const irep_idt &file_name, @@ -279,9 +256,9 @@ void goto_program_coverage_recordt::compute_coverage_lines( { if(!(c_entry->second.size()==1 || is_branch)) { - std::cerr << it->location_number << std::endl; + std::cerr << it->location_number << '\n'; for(const auto &cov : c_entry->second) - std::cerr << cov.second.succ->location_number << std::endl; + std::cerr << cov.second.succ->location_number << '\n'; } assert(c_entry->second.size()==1 || is_branch); @@ -292,7 +269,8 @@ void goto_program_coverage_recordt::compute_coverage_lines( if(entry.first->second.hits==0) ++lines_covered; - entry.first->second.hits+=cov.second.num_executions; + if(cov.second.num_executions>entry.first->second.hits) + entry.first->second.hits=cov.second.num_executions; if(is_branch) { @@ -321,18 +299,6 @@ void goto_program_coverage_recordt::compute_coverage_lines( } } -/*******************************************************************\ - -Function: symex_coveraget::compute_overall_coverage - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_coveraget::compute_overall_coverage( const goto_functionst &goto_functions, coverage_recordt &dest) const @@ -409,18 +375,6 @@ void symex_coveraget::compute_overall_coverage( } } -/*******************************************************************\ - -Function: symex_coveraget::build_cobertura - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_coveraget::build_cobertura( const goto_functionst &goto_functions, xmlt &xml_coverage) const @@ -462,18 +416,6 @@ void symex_coveraget::build_cobertura( package.set_attribute("complexity", "0.0"); } -/*******************************************************************\ - -Function: symex_coveraget::output_report - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool symex_coveraget::output_report( const goto_functionst &goto_functions, std::ostream &os) const @@ -489,18 +431,6 @@ bool symex_coveraget::output_report( return !os.good(); } -/*******************************************************************\ - -Function: symex_coveraget::output_report - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool symex_coveraget::generate_report( const goto_functionst &goto_functions, const std::string &path) const diff --git a/src/cbmc/symex_coverage.h b/src/cbmc/symex_coverage.h index c173bc65ad7..b7556b1087b 100644 --- a/src/cbmc/symex_coverage.h +++ b/src/cbmc/symex_coverage.h @@ -8,6 +8,9 @@ Date: March 2016 \*******************************************************************/ +/// \file +/// Record and print code coverage of symbolic execution + #ifndef CPROVER_CBMC_SYMEX_COVERAGE_H #define CPROVER_CBMC_SYMEX_COVERAGE_H diff --git a/src/cbmc/version.h b/src/cbmc/version.h index 017ded44272..58bdccf0018 100644 --- a/src/cbmc/version.h +++ b/src/cbmc/version.h @@ -1,6 +1,6 @@ #ifndef CPROVER_CBMC_VERSION_H #define CPROVER_CBMC_VERSION_H -#define CBMC_VERSION "5.7" +#define CBMC_VERSION "5.8" #endif // CPROVER_CBMC_VERSION_H diff --git a/src/cbmc/xml_interface.cpp b/src/cbmc/xml_interface.cpp index d94fa7bf034..09856b69bff 100644 --- a/src/cbmc/xml_interface.cpp +++ b/src/cbmc/xml_interface.cpp @@ -6,26 +6,18 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - -#include - -#include +/// \file +/// XML Interface #include "xml_interface.h" -/*******************************************************************\ - -Function: xml_interfacet::get_xml_options - - Inputs: - - Outputs: +#include - Purpose: XML User Interface +#include -\*******************************************************************/ +#include +/// XML User Interface void xml_interfacet::get_xml_options(cmdlinet &cmdline) { if(cmdline.isset("xml-interface")) @@ -41,18 +33,7 @@ void xml_interfacet::get_xml_options(cmdlinet &cmdline) } } -/*******************************************************************\ - -Function: xml_interfacet::get_xml_options - - Inputs: - - Outputs: - - Purpose: XML User Interface - -\*******************************************************************/ - +/// XML User Interface void xml_interfacet::get_xml_options( const xmlt &xml, cmdlinet &cmdline) diff --git a/src/cbmc/xml_interface.h b/src/cbmc/xml_interface.h index 0cf038083db..945be7624bb 100644 --- a/src/cbmc/xml_interface.h +++ b/src/cbmc/xml_interface.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// XML Interface + #ifndef CPROVER_CBMC_XML_INTERFACE_H #define CPROVER_CBMC_XML_INTERFACE_H diff --git a/src/clobber/clobber_main.cpp b/src/clobber/clobber_main.cpp index 8255f068c92..e63a9d63e49 100644 --- a/src/clobber/clobber_main.cpp +++ b/src/clobber/clobber_main.cpp @@ -6,21 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Symex Main Module #include "clobber_parse_options.h" -/*******************************************************************\ - -Function: main - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include #ifdef _MSC_VER int wmain(int argc, const wchar_t **argv_wide) diff --git a/src/clobber/clobber_parse_options.cpp b/src/clobber/clobber_parse_options.cpp index 803ab9db5b1..8c2b2dc1f50 100644 --- a/src/clobber/clobber_parse_options.cpp +++ b/src/clobber/clobber_parse_options.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symex Command Line Options Processing + +#include "clobber_parse_options.h" + #include #include #include @@ -34,21 +39,8 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "clobber_parse_options.h" // #include "clobber_instrumenter.h" -/*******************************************************************\ - -Function: clobber_parse_optionst::clobber_parse_optionst - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - clobber_parse_optionst::clobber_parse_optionst(int argc, const char **argv): parse_options_baset(CLOBBER_OPTIONS, argc, argv), language_uit(cmdline, ui_message_handler), @@ -56,18 +48,6 @@ clobber_parse_optionst::clobber_parse_optionst(int argc, const char **argv): { } -/*******************************************************************\ - -Function: clobber_parse_optionst::eval_verbosity - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void clobber_parse_optionst::eval_verbosity() { // this is our default verbosity @@ -85,18 +65,6 @@ void clobber_parse_optionst::eval_verbosity() ui_message_handler.set_verbosity(v); } -/*******************************************************************\ - -Function: clobber_parse_optionst::get_command_line_options - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void clobber_parse_optionst::get_command_line_options(optionst &options) { if(config.set(cmdline)) @@ -131,23 +99,12 @@ void clobber_parse_optionst::get_command_line_options(optionst &options) options.set_option("error-label", cmdline.get_value("error-label")); } -/*******************************************************************\ - -Function: clobber_parse_optionst::doit - - Inputs: - - Outputs: - - Purpose: invoke main modules - -\*******************************************************************/ - +/// invoke main modules int clobber_parse_optionst::doit() { if(cmdline.isset("version")) { - std::cout << CBMC_VERSION << std::endl; + std::cout << CBMC_VERSION << '\n'; return 0; } @@ -190,7 +147,7 @@ int clobber_parse_optionst::doit() if(!out) throw std::string("failed to create file simulator.c"); - dump_c(goto_functions, true, ns, out); + dump_c(goto_functions, true, false, ns, out); status() << "instrumentation complete; compile and execute simulator.c" << eom; @@ -224,18 +181,6 @@ int clobber_parse_optionst::doit() #endif } -/*******************************************************************\ - -Function: clobber_parse_optionst::set_properties - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool clobber_parse_optionst::set_properties(goto_functionst &goto_functions) { if(cmdline.isset("property")) @@ -244,23 +189,11 @@ bool clobber_parse_optionst::set_properties(goto_functionst &goto_functions) return false; } -/*******************************************************************\ - -Function: clobber_parse_optionst::get_goto_program - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool clobber_parse_optionst::get_goto_program( const optionst &options, goto_functionst &goto_functions) { - if(cmdline.args.size()==0) + if(cmdline.args.empty()) { error() << "Please provide a program to verify" << eom; return true; @@ -317,7 +250,7 @@ bool clobber_parse_optionst::get_goto_program( languaget *language=get_language_from_filename(filename); - if(language==NULL) + if(language==nullptr) { error() << "failed to figure out type of file `" << filename << "'" << eom; @@ -326,7 +259,7 @@ bool clobber_parse_optionst::get_goto_program( language->set_message_handler(get_message_handler()); - status("Parsing", filename); + status() << "Parsing " << filename << eom; if(language->parse(infile, filename)) { @@ -378,18 +311,6 @@ bool clobber_parse_optionst::get_goto_program( return false; } -/*******************************************************************\ - -Function: clobber_parse_optionst::process_goto_program - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool clobber_parse_optionst::process_goto_program( const optionst &options, goto_functionst &goto_functions) @@ -435,18 +356,6 @@ bool clobber_parse_optionst::process_goto_program( return false; } -/*******************************************************************\ - -Function: clobber_parse_optionst::report_properties - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - #if 0 void clobber_parse_optionst::report_properties( const path_searcht::property_mapt &property_map) @@ -506,33 +415,21 @@ void clobber_parse_optionst::report_properties( } #endif -/*******************************************************************\ - -Function: clobber_parse_optionst::report_success - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void clobber_parse_optionst::report_success() { result() << "VERIFICATION SUCCESSFUL" << eom; switch(get_ui()) { - case ui_message_handlert::PLAIN: + case ui_message_handlert::uit::PLAIN: break; - case ui_message_handlert::XML_UI: + case ui_message_handlert::uit::XML_UI: { xmlt xml("cprover-status"); xml.data="SUCCESS"; std::cout << xml; - std::cout << std::endl; + std::cout << '\n'; } break; @@ -541,18 +438,6 @@ void clobber_parse_optionst::report_success() } } -/*******************************************************************\ - -Function: clobber_parse_optionst::show_counterexample - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void clobber_parse_optionst::show_counterexample( const goto_tracet &error_trace) { @@ -560,16 +445,16 @@ void clobber_parse_optionst::show_counterexample( switch(get_ui()) { - case ui_message_handlert::PLAIN: - std::cout << std::endl << "Counterexample:" << std::endl; + case ui_message_handlert::uit::PLAIN: + std::cout << "\nCounterexample:\n"; show_goto_trace(std::cout, ns, error_trace); break; - case ui_message_handlert::XML_UI: + case ui_message_handlert::uit::XML_UI: { xmlt xml; convert(ns, error_trace, xml); - std::cout << xml << std::endl; + std::cout << xml << '\n'; } break; @@ -578,33 +463,21 @@ void clobber_parse_optionst::show_counterexample( } } -/*******************************************************************\ - -Function: clobber_parse_optionst::report_failure - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void clobber_parse_optionst::report_failure() { result() << "VERIFICATION FAILED" << eom; switch(get_ui()) { - case ui_message_handlert::PLAIN: + case ui_message_handlert::uit::PLAIN: break; - case ui_message_handlert::XML_UI: + case ui_message_handlert::uit::XML_UI: { xmlt xml("cprover-status"); xml.data="FAILURE"; std::cout << xml; - std::cout << std::endl; + std::cout << '\n'; } break; @@ -613,18 +486,7 @@ void clobber_parse_optionst::report_failure() } } -/*******************************************************************\ - -Function: clobber_parse_optionst::help - - Inputs: - - Outputs: - - Purpose: display command line help - -\*******************************************************************/ - +/// display command line help void clobber_parse_optionst::help() { std::cout << diff --git a/src/clobber/clobber_parse_options.h b/src/clobber/clobber_parse_options.h index ffd897c9155..89faff353f0 100644 --- a/src/clobber/clobber_parse_options.h +++ b/src/clobber/clobber_parse_options.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Command Line Parsing + #ifndef CPROVER_CLOBBER_CLOBBER_PARSE_OPTIONS_H #define CPROVER_CLOBBER_CLOBBER_PARSE_OPTIONS_H diff --git a/src/common b/src/common index 87feed97124..d410f999a36 100644 --- a/src/common +++ b/src/common @@ -33,14 +33,17 @@ else EXEEXT = endif CFLAGS ?= -Wall -O2 - CXXFLAGS ?= -Wall -O2 CP_CFLAGS = -MMD -MP + CXXFLAGS ?= -Wall -O2 ifeq ($(filter-out OSX OSX_Universal,$(BUILD_ENV_)),) CP_CXXFLAGS = -MMD -MP -mmacosx-version-min=10.9 -std=c++11 -stdlib=libc++ LINKFLAGS += -mmacosx-version-min=10.9 -stdlib=libc++ LINKNATIVE += -mmacosx-version-min=10.9 -stdlib=libc++ else CP_CXXFLAGS = -MMD -MP -std=c++11 +endif +ifeq ($(filter -O%,$(CXXFLAGS)),) + CP_CXXFLAGS += -O2 endif #LINKFLAGS = -static ifeq ($(filter-out OSX OSX_Universal,$(BUILD_ENV_)),) diff --git a/src/cpp/cpp_constructor.cpp b/src/cpp/cpp_constructor.cpp index 3c5b34762dd..9be6e8c3f01 100644 --- a/src/cpp/cpp_constructor.cpp +++ b/src/cpp/cpp_constructor.cpp @@ -6,26 +6,21 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include -#include - -#include +/// \file +/// C++ Language Type Checking #include "cpp_typecheck.h" -#include "cpp_util.h" - -/*******************************************************************\ - -Function: cpp_typecheckt::cpp_constructor - Inputs: non-typchecked object, non-typechecked operands - - Outputs: typechecked code +#include +#include - Purpose: +#include -\*******************************************************************/ +#include "cpp_util.h" +/// \param object: non-typechecked object +/// \param operands: non-typechecked operands +/// \return typechecked code codet cpp_typecheckt::cpp_constructor( const source_locationt &source_location, const exprt &object, @@ -47,8 +42,8 @@ codet cpp_typecheckt::cpp_constructor( // We allow only one operand and it must be tagged with '#array_ini'. // Note that the operand is an array that is used for copy-initialization. // In the general case, a program is not allow to use this form of - // construct. This way of initializing an array is used internaly only. - // The purpose of the tag #arra_ini is to rule out ill-formed + // construct. This way of initializing an array is used internally only. + // The purpose of the tag #array_ini is to rule out ill-formed // programs. if(!operands.empty() && !operands.front().get_bool("#array_ini")) @@ -294,10 +289,7 @@ codet cpp_typecheckt::cpp_constructor( assert(tmp_this.id()==ID_address_of && tmp_this.op0().id()=="new_object"); - exprt address_of(ID_address_of, typet(ID_pointer)); - address_of.type().subtype()=object_tc.type(); - address_of.copy_to_operands(object_tc); - tmp_this.swap(address_of); + tmp_this=address_of_exprt(object_tc); if(block.operands().empty()) return to_code(initializer); @@ -315,18 +307,6 @@ codet cpp_typecheckt::cpp_constructor( return nil; } -/*******************************************************************\ - -Function: cpp_typecheckt::new_temporary - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::new_temporary( const source_locationt &source_location, const typet &type, @@ -359,18 +339,6 @@ void cpp_typecheckt::new_temporary( temporary.swap(tmp_object_expr); } -/*******************************************************************\ - -Function: cpp_typecheckt::new_temporary - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::new_temporary( const source_locationt &source_location, const typet &type, diff --git a/src/cpp/cpp_convert_type.cpp b/src/cpp/cpp_convert_type.cpp index 0f106b19575..b98845964e0 100644 --- a/src/cpp/cpp_convert_type.cpp +++ b/src/cpp/cpp_convert_type.cpp @@ -6,15 +6,19 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Conversion + +#include "cpp_convert_type.h" + #include #include #include #include -#include +#include -#include "cpp_convert_type.h" #include "cpp_declaration.h" #include "cpp_name.h" @@ -42,18 +46,6 @@ class cpp_convert_typet void read_template(const typet &type); }; -/*******************************************************************\ - -Function: cpp_convert_typet::read - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_convert_typet::read(const typet &type) { unsigned_cnt=signed_cnt=char_cnt=int_cnt=short_cnt= @@ -66,29 +58,17 @@ void cpp_convert_typet::read(const typet &type) other.clear(); #if 0 - std::cout << "cpp_convert_typet::read: " << type.pretty() << std::endl; + std::cout << "cpp_convert_typet::read: " << type.pretty() << '\n'; #endif read_rec(type); } -/*******************************************************************\ - -Function: cpp_convert_typet::read_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_convert_typet::read_rec(const typet &type) { #if 0 std::cout << "cpp_convert_typet::read_rec: " - << type.pretty() << std::endl; + << type.pretty() << '\n'; #endif if(type.id()==ID_merged_type) @@ -185,18 +165,6 @@ void cpp_convert_typet::read_rec(const typet &type) } } -/*******************************************************************\ - -Function: cpp_covnert_typet::read_template - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_convert_typet::read_template(const typet &type) { other.push_back(type); @@ -225,18 +193,6 @@ void cpp_convert_typet::read_template(const typet &type) } } -/*******************************************************************\ - -Function: cpp_convert_typet::read_function_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_convert_typet::read_function_type(const typet &type) { other.push_back(type); @@ -295,8 +251,8 @@ void cpp_convert_typet::read_function_type(const typet &type) // see if it's an array type if(final_type.id()==ID_array) { - final_type.id(ID_pointer); - final_type.remove(ID_size); + // turn into pointer type + final_type=pointer_type(final_type.subtype()); } code_typet::parametert new_parameter(final_type); @@ -338,18 +294,6 @@ void cpp_convert_typet::read_function_type(const typet &type) parameters.get_sub().clear(); } -/*******************************************************************\ - -Function: cpp_convert_typet::write - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_convert_typet::write(typet &type) { type.clear(); @@ -600,18 +544,6 @@ void cpp_convert_typet::write(typet &type) type.set(ID_C_volatile, true); } -/*******************************************************************\ - -Function: cpp_convert_plain_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_convert_plain_type(typet &type) { if(type.id()==ID_cpp_name || diff --git a/src/cpp/cpp_convert_type.h b/src/cpp/cpp_convert_type.h index 9c690287fae..590ce6e98a6 100644 --- a/src/cpp/cpp_convert_type.h +++ b/src/cpp/cpp_convert_type.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Conversion + #ifndef CPROVER_CPP_CPP_CONVERT_TYPE_H #define CPROVER_CPP_CPP_CONVERT_TYPE_H diff --git a/src/cpp/cpp_declaration.cpp b/src/cpp/cpp_declaration.cpp index 1a06fbaa36d..a01afe82aa3 100644 --- a/src/cpp/cpp_declaration.cpp +++ b/src/cpp/cpp_declaration.cpp @@ -6,21 +6,12 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include +/// \file +/// C++ Language Type Checking #include "cpp_declaration.h" -/*******************************************************************\ - -Function: cpp_declarationt::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void cpp_declarationt::output(std::ostream &out) const { @@ -38,18 +29,6 @@ void cpp_declarationt::output(std::ostream &out) const } } -/*******************************************************************\ - -Function: cpp_declarationt::name_anon_struct_union - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_declarationt::name_anon_struct_union(typet &dest) { // We name any anon struct/unions according to the first diff --git a/src/cpp/cpp_declaration.h b/src/cpp/cpp_declaration.h index 271f7c5ee44..17cf872d226 100644 --- a/src/cpp/cpp_declaration.h +++ b/src/cpp/cpp_declaration.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + #ifndef CPROVER_CPP_CPP_DECLARATION_H #define CPROVER_CPP_CPP_DECLARATION_H diff --git a/src/cpp/cpp_declarator.cpp b/src/cpp/cpp_declarator.cpp index 063003b696c..1b9df60f2d3 100644 --- a/src/cpp/cpp_declarator.cpp +++ b/src/cpp/cpp_declarator.cpp @@ -6,22 +6,13 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include -#include +/// \file +/// C++ Language Type Checking #include "cpp_declarator.h" -/*******************************************************************\ - -Function: cpp_declaratort::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include void cpp_declaratort::output(std::ostream &out) const { @@ -32,18 +23,6 @@ void cpp_declaratort::output(std::ostream &out) const out << " method_qualifier: " << method_qualifier().pretty() << "\n"; } -/*******************************************************************\ - -Function: cpp_declaratort::merge_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet cpp_declaratort::merge_type(const typet &declaration_type) const { typet dest_type=type(); @@ -70,7 +49,7 @@ typet cpp_declaratort::merge_type(const typet &declaration_type) const } else { - assert(t.id()!=irep_idt()); + assert(!t.id().empty()); p=&t.subtype(); } } diff --git a/src/cpp/cpp_declarator.h b/src/cpp/cpp_declarator.h index 3a08f17180a..7f316506f56 100644 --- a/src/cpp/cpp_declarator.h +++ b/src/cpp/cpp_declarator.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + #ifndef CPROVER_CPP_CPP_DECLARATOR_H #define CPROVER_CPP_CPP_DECLARATOR_H diff --git a/src/cpp/cpp_declarator_converter.cpp b/src/cpp/cpp_declarator_converter.cpp index 83f5f1c1b38..9d7ee9b3121 100644 --- a/src/cpp/cpp_declarator_converter.cpp +++ b/src/cpp/cpp_declarator_converter.cpp @@ -6,27 +6,19 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + +#include "cpp_declarator_converter.h" + #include #include -#include +#include #include "cpp_type2name.h" -#include "cpp_declarator_converter.h" #include "cpp_typecheck.h" -/*******************************************************************\ - -Function: cpp_declarator_convertert::cpp_declarator_convertert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - cpp_declarator_convertert::cpp_declarator_convertert( class cpp_typecheckt &_cpp_typecheck): is_typedef(false), @@ -34,22 +26,11 @@ cpp_declarator_convertert::cpp_declarator_convertert( is_template_parameter(false), is_friend(false), linkage_spec(_cpp_typecheck.current_linkage_spec), - cpp_typecheck(_cpp_typecheck) + cpp_typecheck(_cpp_typecheck), + is_code(false) { } -/*******************************************************************\ - -Function: cpp_declarator_convertert::convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - symbolt &cpp_declarator_convertert::convert( const typet &declaration_type, const cpp_storage_spect &storage_spec, @@ -100,7 +81,7 @@ symbolt &cpp_declarator_convertert::convert( get_final_identifier(); // first see if it is a member - if(scope->id_class==cpp_idt::CLASS && !is_friend) + if(scope->id_class==cpp_idt::id_classt::CLASS && !is_friend) { // it's a member! it must be declared already @@ -160,7 +141,7 @@ symbolt &cpp_declarator_convertert::convert( exprt symbol_expr= cpp_typecheck.resolve( name, - cpp_typecheck_resolvet::TYPE, + cpp_typecheck_resolvet::wantt::TYPE, cpp_typecheck_fargst()); if(symbol_expr.id()!=ID_type || @@ -238,13 +219,13 @@ symbolt &cpp_declarator_convertert::convert( cpp_scopet::id_sett id_set; scope->lookup_identifier( - symbol.name, cpp_idt::TEMPLATE_PARAMETER, id_set); + symbol.name, cpp_idt::id_classt::TEMPLATE_PARAMETER, id_set); if(id_set.empty()) { cpp_idt &identifier= cpp_typecheck.cpp_scopes.put_into_scope(symbol, *scope); - identifier.id_class=cpp_idt::TEMPLATE_PARAMETER; + identifier.id_class=cpp_idt::id_classt::TEMPLATE_PARAMETER; } } @@ -252,18 +233,6 @@ symbolt &cpp_declarator_convertert::convert( } } -/*******************************************************************\ - -Function: cpp_declarator_convertert::combine_types - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_declarator_convertert::combine_types( const source_locationt &source_location, const typet &decl_type, @@ -346,18 +315,6 @@ void cpp_declarator_convertert::combine_types( throw 0; } -/*******************************************************************\ - -Function: cpp_declarator_convertert::enforce_rules - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_declarator_convertert::enforce_rules(const symbolt &symbol) { // enforce rules for operator overloading @@ -367,18 +324,6 @@ void cpp_declarator_convertert::enforce_rules(const symbolt &symbol) main_function_rules(symbol); } -/*******************************************************************\ - -Function: cpp_declarator_convertert::handle_initializer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_declarator_convertert::handle_initializer( symbolt &symbol, cpp_declaratort &declarator) @@ -431,18 +376,6 @@ void cpp_declarator_convertert::handle_initializer( } } -/*******************************************************************\ - -Function: cpp_declarator_convertert::get_final_identifier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_declarator_convertert::get_final_identifier() { std::string identifier=id2string(base_name); @@ -489,18 +422,6 @@ void cpp_declarator_convertert::get_final_identifier() identifier; } -/*******************************************************************\ - -Function: cpp_declarator_convertert::convert_new_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - symbolt &cpp_declarator_convertert::convert_new_symbol( const cpp_storage_spect &storage_spec, const cpp_member_spect &member_spec, @@ -618,13 +539,13 @@ symbolt &cpp_declarator_convertert::convert_new_symbol( cpp_typecheck.cpp_scopes.put_into_scope(*new_symbol, *scope, is_friend); if(is_template) - identifier.id_class=cpp_idt::TEMPLATE; + identifier.id_class=cpp_idt::id_classt::TEMPLATE; else if(is_template_parameter) - identifier.id_class=cpp_idt::TEMPLATE_PARAMETER; + identifier.id_class=cpp_idt::id_classt::TEMPLATE_PARAMETER; else if(is_typedef) - identifier.id_class=cpp_idt::TYPEDEF; + identifier.id_class=cpp_idt::id_classt::TYPEDEF; else - identifier.id_class=cpp_idt::SYMBOL; + identifier.id_class=cpp_idt::id_classt::SYMBOL; // do the value if(!new_symbol->is_type) @@ -641,18 +562,6 @@ symbolt &cpp_declarator_convertert::convert_new_symbol( return *new_symbol; } -/*******************************************************************\ - -Function: cpp_declarator_convertert::get_pretty_name - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - irep_idt cpp_declarator_convertert::get_pretty_name() { if(is_code) @@ -680,35 +589,11 @@ irep_idt cpp_declarator_convertert::get_pretty_name() return scope->prefix+id2string(base_name); } -/*******************************************************************\ - -Function: cpp_declarator_convertert::operator_overloading_rules - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_declarator_convertert::operator_overloading_rules( const symbolt &symbol) { } -/*******************************************************************\ - -Function: cpp_declarator_convertert::main_function_rules - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_declarator_convertert::main_function_rules( const symbolt &symbol) { diff --git a/src/cpp/cpp_declarator_converter.h b/src/cpp/cpp_declarator_converter.h index 850549a69d5..54399c6b62e 100644 --- a/src/cpp/cpp_declarator_converter.h +++ b/src/cpp/cpp_declarator_converter.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + #ifndef CPROVER_CPP_CPP_DECLARATOR_CONVERTER_H #define CPROVER_CPP_CPP_DECLARATOR_CONVERTER_H diff --git a/src/cpp/cpp_destructor.cpp b/src/cpp/cpp_destructor.cpp index 75479a0ee85..6a35398475c 100644 --- a/src/cpp/cpp_destructor.cpp +++ b/src/cpp/cpp_destructor.cpp @@ -6,24 +6,16 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include - -#include +/// \file +/// C++ Language Type Checking #include "cpp_typecheck.h" -/*******************************************************************\ - -Function: cpp_typecheckt::cpp_destructor - - Inputs: - - Outputs: typechecked code - - Purpose: +#include -\*******************************************************************/ +#include +/// \return typechecked code codet cpp_typecheckt::cpp_destructor( const source_locationt &source_location, const typet &type, @@ -150,10 +142,7 @@ codet cpp_typecheckt::cpp_destructor( assert(tmp_this.id()==ID_address_of && tmp_this.op0().id()=="new_object"); - exprt address_of(ID_address_of, typet(ID_pointer)); - address_of.type().subtype()=object.type(); - address_of.copy_to_operands(object); - tmp_this.swap(address_of); + tmp_this=address_of_exprt(object, pointer_type(object.type())); new_code.swap(initializer); } diff --git a/src/cpp/cpp_enum_type.cpp b/src/cpp/cpp_enum_type.cpp index ba4bc6ecbae..d9a8d2e1efe 100644 --- a/src/cpp/cpp_enum_type.cpp +++ b/src/cpp/cpp_enum_type.cpp @@ -6,38 +6,17 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include +/// \file +/// C++ Language Type Checking #include "cpp_enum_type.h" -/*******************************************************************\ - -Function: cpp_enum_typet::cpp_enum_typet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include cpp_enum_typet::cpp_enum_typet():typet(ID_c_enum) { } -/*******************************************************************\ - -Function: cpp_enum_typet::generate_anon_tag - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - irep_idt cpp_enum_typet::generate_anon_tag() const { // This will only clash with anon enums that would have diff --git a/src/cpp/cpp_enum_type.h b/src/cpp/cpp_enum_type.h index 23edd61900e..97dc50df769 100644 --- a/src/cpp/cpp_enum_type.h +++ b/src/cpp/cpp_enum_type.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + #ifndef CPROVER_CPP_CPP_ENUM_TYPE_H #define CPROVER_CPP_CPP_ENUM_TYPE_H diff --git a/src/cpp/cpp_exception_id.cpp b/src/cpp/cpp_exception_id.cpp index e64fa67e0df..18649696f53 100644 --- a/src/cpp/cpp_exception_id.cpp +++ b/src/cpp/cpp_exception_id.cpp @@ -6,20 +6,12 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include "cpp_exception_id.h" - -/*******************************************************************\ - -Function: cpp_exception_list_rec - - Inputs: - - Outputs: - - Purpose: turns a type into a list of relevant exception IDs +/// \file +/// C++ Language Type Checking -\*******************************************************************/ +#include "cpp_exception_id.h" +/// turns a type into a list of relevant exception IDs void cpp_exception_list_rec( const typet &src, const namespacet &ns, @@ -67,7 +59,7 @@ void cpp_exception_list_rec( // grab C/C++ type irep_idt c_type=src.get(ID_C_c_type); - if(c_type!=irep_idt()) + if(!c_type.empty()) { dest.push_back(id2string(c_type)+suffix); return; @@ -75,18 +67,7 @@ void cpp_exception_list_rec( } } -/*******************************************************************\ - -Function: cpp_exception_list - - Inputs: - - Outputs: - - Purpose: turns a type into a list of relevant exception IDs - -\*******************************************************************/ - +/// turns a type into a list of relevant exception IDs irept cpp_exception_list( const typet &src, const namespacet &ns) @@ -103,18 +84,7 @@ irept cpp_exception_list( return result; } -/*******************************************************************\ - -Function: cpp_exception_id - - Inputs: - - Outputs: - - Purpose: turns a type into an exception ID - -\*******************************************************************/ - +/// turns a type into an exception ID irep_idt cpp_exception_id( const typet &src, const namespacet &ns) diff --git a/src/cpp/cpp_exception_id.h b/src/cpp/cpp_exception_id.h index 38b675c76fb..c652169aa50 100644 --- a/src/cpp/cpp_exception_id.h +++ b/src/cpp/cpp_exception_id.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + #ifndef CPROVER_CPP_CPP_EXCEPTION_ID_H #define CPROVER_CPP_CPP_EXCEPTION_ID_H diff --git a/src/cpp/cpp_id.cpp b/src/cpp/cpp_id.cpp index 1357c646fe6..edcc139ce4f 100644 --- a/src/cpp/cpp_id.cpp +++ b/src/cpp/cpp_id.cpp @@ -6,22 +6,14 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include +/// \file +/// C++ Language Type Checking #include "cpp_id.h" -#include "cpp_scope.h" - -/*******************************************************************\ - -Function: cpp_idt::cpp_idt - - Inputs: - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include "cpp_scope.h" cpp_idt::cpp_idt(): is_member(false), @@ -29,25 +21,13 @@ cpp_idt::cpp_idt(): is_static_member(false), is_scope(false), is_constructor(false), - id_class(UNKNOWN), + id_class(id_classt::UNKNOWN), this_expr(static_cast(get_nil_irep())), compound_counter(0), - parent(NULL) + parent(nullptr) { } -/*******************************************************************\ - -Function: cpp_idt::print - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_idt::print(std::ostream &out, unsigned indent) const { print_fields(out, indent); @@ -59,41 +39,29 @@ void cpp_idt::print(std::ostream &out, unsigned indent) const it++) it->second.print(out, indent+2); - out << std::endl; + out << '\n'; } } -/*******************************************************************\ - -Function: cpp_idt::print_fields - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_idt::print_fields(std::ostream &out, unsigned indent) const { for(unsigned i=0; i #include +#include #include class cpp_scopet; @@ -26,12 +30,20 @@ class cpp_idt public: cpp_idt(); - typedef enum + enum class id_classt { - UNKNOWN, SYMBOL, TYPEDEF, CLASS, ENUM, TEMPLATE, - TEMPLATE_PARAMETER, NAMESPACE, BLOCK_SCOPE, - TEMPLATE_SCOPE, ROOT_SCOPE - } id_classt; + UNKNOWN, + SYMBOL, + TYPEDEF, + CLASS, + ENUM, + TEMPLATE, + TEMPLATE_PARAMETER, + NAMESPACE, + BLOCK_SCOPE, + TEMPLATE_SCOPE, + ROOT_SCOPE, + }; bool is_member, is_method, is_static_member, is_scope, is_constructor; @@ -40,22 +52,22 @@ class cpp_idt bool is_class() const { - return id_class==CLASS; + return id_class==id_classt::CLASS; } bool is_enum() const { - return id_class==ENUM; + return id_class==id_classt::ENUM; } bool is_namespace() const { - return id_class==NAMESPACE; + return id_class==id_classt::NAMESPACE; } bool is_typedef() const { - return id_class==TYPEDEF; + return id_class==id_classt::TYPEDEF; } irep_idt identifier, base_name; @@ -70,7 +82,7 @@ class cpp_idt cpp_idt &get_parent() const { - assert(parent!=NULL); + PRECONDITION(parent!=nullptr); return *parent; } diff --git a/src/cpp/cpp_instantiate_template.cpp b/src/cpp/cpp_instantiate_template.cpp index 0a6b9d5c129..fe0b3e28ac2 100644 --- a/src/cpp/cpp_instantiate_template.cpp +++ b/src/cpp/cpp_instantiate_template.cpp @@ -6,25 +6,18 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include -#include - -#include +/// \file +/// C++ Language Type Checking -#include "cpp_type2name.h" #include "cpp_typecheck.h" -/*******************************************************************\ - -Function: cpp_typecheckt::template_suffix - - Inputs: - - Outputs: +#include +#include +#include - Purpose: +#include -\*******************************************************************/ +#include "cpp_type2name.h" std::string cpp_typecheckt::template_suffix( const cpp_template_args_tct &template_args) @@ -88,18 +81,6 @@ std::string cpp_typecheckt::template_suffix( return result; } -/*******************************************************************\ - -Function: cpp_typecheckt::show_instantiation_stack - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::show_instantiation_stack(std::ostream &out) { for(instantiation_stackt::const_iterator @@ -121,22 +102,10 @@ void cpp_typecheckt::show_instantiation_stack(std::ostream &out) out << to_string(*a_it); } - out << "> at " << s_it->source_location << std::endl; + out << "> at " << s_it->source_location << '\n'; } } -/*******************************************************************\ - -Function: cpp_typecheckt::class_template_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const symbolt &cpp_typecheckt::class_template_symbol( const source_locationt &source_location, const symbolt &template_symbol, @@ -162,7 +131,8 @@ const symbolt &cpp_typecheckt::class_template_symbol( cpp_scopet *template_scope= static_cast(cpp_scopes.id_map[template_symbol.name]); - assert(template_scope!=NULL); + INVARIANT_STRUCTURED( + template_scope!=nullptr, nullptr_exceptiont, "template_scope is null"); irep_idt identifier= id2string(template_scope->prefix)+ @@ -201,29 +171,18 @@ const symbolt &cpp_typecheckt::class_template_symbol( // put into template scope cpp_idt &id=cpp_scopes.put_into_scope(*s_ptr, *template_scope); - id.id_class=cpp_idt::CLASS; + id.id_class=cpp_idt::id_classt::CLASS; id.is_scope=true; id.prefix=template_scope->prefix+ id2string(s_ptr->base_name)+ id2string(suffix)+"::"; id.class_identifier=s_ptr->name; - id.id_class=cpp_idt::CLASS; + id.id_class=cpp_idt::id_classt::CLASS; return *s_ptr; } -/*******************************************************************\ - -Function: cpp_typecheckt::elaborate_class_template - - Inputs: - - Outputs: - - Purpose: elaborate class template instances - -\*******************************************************************/ - +/// elaborate class template instances void cpp_typecheckt::elaborate_class_template( const typet &type) { @@ -248,21 +207,10 @@ void cpp_typecheckt::elaborate_class_template( } } -/*******************************************************************\ - -Function: cpp_typecheckt::instantiate_template - - Inputs: location of the instantiation, - the identifier of the template symbol, - typechecked template arguments, - an (optional) specialization - - Outputs: - - Purpose: - -\*******************************************************************/ - +/// \par parameters: location of the instantiation, +/// the identifier of the template symbol, +/// typechecked template arguments, +/// an (optional) specialization #define MAX_DEPTH 50 const symbolt &cpp_typecheckt::instantiate_template( @@ -286,8 +234,8 @@ const symbolt &cpp_typecheckt::instantiate_template( instantiation_stack.back().full_template_args=full_template_args; #if 0 - std::cout << "L: " << source_location << std::endl; - std::cout << "I: " << template_symbol.name << std::endl; + std::cout << "L: " << source_location << '\n'; + std::cout << "I: " << template_symbol.name << '\n'; #endif cpp_save_scopet cpp_saved_scope(cpp_scopes); @@ -310,7 +258,7 @@ const symbolt &cpp_typecheckt::instantiate_template( else std::cout << to_string(*it); } - std::cout << ">" << std::endl; + std::cout << ">\n"; #endif // do we have arguments? @@ -330,7 +278,7 @@ const symbolt &cpp_typecheckt::instantiate_template( cpp_scopet *template_scope= static_cast(cpp_scopes.id_map[template_symbol.name]); - if(template_scope==NULL) + if(template_scope==nullptr) { error().source_location=source_location; error() << "identifier: " << template_symbol.name << '\n' @@ -338,7 +286,8 @@ const symbolt &cpp_typecheckt::instantiate_template( throw 0; } - assert(template_scope!=NULL); + INVARIANT_STRUCTURED( + template_scope!=nullptr, nullptr_exceptiont, "template_scope is null"); // produce new declaration cpp_declarationt new_decl=to_cpp_declaration(template_symbol.type); @@ -387,16 +336,16 @@ const symbolt &cpp_typecheckt::instantiate_template( if(id_set.size()==1) { - // It has already been instantianted! + // It has already been instantiated! const cpp_idt &cpp_id = **id_set.begin(); - assert(cpp_id.id_class == cpp_idt::CLASS || - cpp_id.id_class == cpp_idt::SYMBOL); + assert(cpp_id.id_class == cpp_idt::id_classt::CLASS || + cpp_id.id_class == cpp_idt::id_classt::SYMBOL); const symbolt &symb=lookup(cpp_id.identifier); // continue if the type is incomplete only - if(cpp_id.id_class==cpp_idt::CLASS && + if(cpp_id.id_class==cpp_idt::id_classt::CLASS && symb.type.id()==ID_struct) return symb; else if(symb.value.is_not_nil()) @@ -410,7 +359,7 @@ const symbolt &cpp_typecheckt::instantiate_template( // set up a scope as subscope of the template scope cpp_scopet &sub_scope= cpp_scopes.current_scope().new_scope(subscope_name); - sub_scope.id_class=cpp_idt::TEMPLATE_SCOPE; + sub_scope.id_class=cpp_idt::id_classt::TEMPLATE_SCOPE; sub_scope.prefix=template_scope->get_parent().prefix; sub_scope.suffix=suffix; sub_scope.add_using_scope(template_scope->get_parent()); @@ -429,7 +378,7 @@ const symbolt &cpp_typecheckt::instantiate_template( } #if 0 - std::cout << "MAP:" << std::endl; + std::cout << "MAP:\n"; template_map.print(std::cout); #endif @@ -540,7 +489,7 @@ const symbolt &cpp_typecheckt::instantiate_template( bool is_static=new_decl.storage_spec().is_static(); irep_idt access = new_decl.get(ID_C_access); - assert(access != irep_idt()); + assert(!access.empty()); assert(symb.type.id()==ID_struct); typecheck_compound_declarator( diff --git a/src/cpp/cpp_internal_additions.cpp b/src/cpp/cpp_internal_additions.cpp index dfeabc2739e..78384905a83 100644 --- a/src/cpp/cpp_internal_additions.cpp +++ b/src/cpp/cpp_internal_additions.cpp @@ -6,26 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "cpp_internal_additions.h" + #include #include #include -#include "cpp_internal_additions.h" - -/*******************************************************************\ - -Function: c2cpp - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string c2cpp(const std::string &s) { std::string result; @@ -49,18 +37,6 @@ std::string c2cpp(const std::string &s) return result; } -/*******************************************************************\ - -Function: cpp_interal_additions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_internal_additions(std::ostream &out) { out << "# 1 \"\"" << '\n'; @@ -136,11 +112,20 @@ void cpp_internal_additions(std::ostream &out) { out << "extern \"C\" {" << '\n'; out << c2cpp(gcc_builtin_headers_generic); + out << c2cpp(gcc_builtin_headers_math); + out << c2cpp(gcc_builtin_headers_mem_string); + out << c2cpp(gcc_builtin_headers_omp); + out << c2cpp(gcc_builtin_headers_tm); + out << c2cpp(gcc_builtin_headers_ubsan); + out << c2cpp(clang_builtin_headers); if(config.ansi_c.mode==configt::ansi_ct::flavourt::APPLE) out << "typedef double __float128;\n"; // clang doesn't do __float128 out << c2cpp(gcc_builtin_headers_ia32); + out << c2cpp(gcc_builtin_headers_ia32_2); + out << c2cpp(gcc_builtin_headers_ia32_3); + out << c2cpp(gcc_builtin_headers_ia32_4); out << "}" << '\n'; } diff --git a/src/cpp/cpp_internal_additions.h b/src/cpp/cpp_internal_additions.h index 54a2189e877..c2b0fd46024 100644 --- a/src/cpp/cpp_internal_additions.h +++ b/src/cpp/cpp_internal_additions.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_CPP_CPP_INTERNAL_ADDITIONS_H #define CPROVER_CPP_CPP_INTERNAL_ADDITIONS_H diff --git a/src/cpp/cpp_is_pod.cpp b/src/cpp/cpp_is_pod.cpp index 2b5c895611e..5cd698fd718 100644 --- a/src/cpp/cpp_is_pod.cpp +++ b/src/cpp/cpp_is_pod.cpp @@ -6,40 +6,10 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include "cpp_typecheck.h" - -/*******************************************************************\ - -Function: cpp_typecheckt::cpp_is_pod - - Inputs: - - Outputs: +/// \file +/// C++ Language Type Checking - Standard: - "Arithmetic types (3.9.1), enumeration types, pointer types, and - pointer to member types (3.9.2), and cvqualified versions of - these types (3.9.3) are collectively called scalar types. Scalar - types, POD-struct types, POD-union types (clause 9), arrays of - such types and cv-qualified versions of these types (3.9.3) are - collectively called POD types." - - "A POD-struct is an aggregate class that has no non-static data - members of type non-POD-struct, non-POD-union (or array of such - types) or reference, and has no user-defined copy assignment - operator and no user-defined destructor. Similarly, a POD-union - is an aggregate union that has no non-static data members of type - non-POD-struct, non-POD-union (or array of such types) or reference, - and has no userdefined copy assignment operator and no user-defined - destructor. A POD class is a class that is either a POD-struct or - a POD-union." - - "An aggregate is an array or a class (clause 9) with no - user-declared constructors (12.1), no private or protected - non-static data members (clause 11), no base classes (clause 10), - and no virtual functions (10.3)." - -\*******************************************************************/ +#include "cpp_typecheck.h" bool cpp_typecheckt::cpp_is_pod(const typet &type) const { diff --git a/src/cpp/cpp_item.h b/src/cpp/cpp_item.h index f3f32674278..75b7c3e120c 100644 --- a/src/cpp/cpp_item.h +++ b/src/cpp/cpp_item.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + #ifndef CPROVER_CPP_CPP_ITEM_H #define CPROVER_CPP_CPP_ITEM_H diff --git a/src/cpp/cpp_language.cpp b/src/cpp/cpp_language.cpp index e558f478665..cc84b5fb489 100644 --- a/src/cpp/cpp_language.cpp +++ b/src/cpp/cpp_language.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Module + +#include "cpp_language.h" + #include #include #include @@ -20,25 +25,12 @@ Author: Daniel Kroening, kroening@cs.cmu.edu #include #include "cpp_internal_additions.h" -#include "cpp_language.h" #include "expr2cpp.h" #include "expr2cpp_class.h" #include "cpp_parser.h" #include "cpp_typecheck.h" #include "cpp_type2name.h" -/*******************************************************************\ - -Function: cpp_languaget::extensions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::set cpp_languaget::extensions() const { std::set s; @@ -57,35 +49,12 @@ std::set cpp_languaget::extensions() const return s; } -/*******************************************************************\ - -Function: cpp_languaget::modules_provided - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_languaget::modules_provided(std::set &modules) { modules.insert(get_base_name(parse_path, true)); } -/*******************************************************************\ - -Function: cpp_languaget::preprocess - - Inputs: - - Outputs: - - Purpose: ANSI-C preprocessing - -\*******************************************************************/ - +/// ANSI-C preprocessing bool cpp_languaget::preprocess( std::istream &instream, const std::string &path, @@ -97,7 +66,7 @@ bool cpp_languaget::preprocess( // check extension const char *ext=strrchr(path.c_str(), '.'); - if(ext!=NULL && std::string(ext)==".ipp") + if(ext!=nullptr && std::string(ext)==".ipp") { std::ifstream infile(path); @@ -112,18 +81,6 @@ bool cpp_languaget::preprocess( return c_preprocess(path, outstream, get_message_handler()); } -/*******************************************************************\ - -Function: cpp_languaget::parse - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool cpp_languaget::parse( std::istream &instream, const std::string &path) @@ -162,18 +119,6 @@ bool cpp_languaget::parse( return result; } -/*******************************************************************\ - -Function: cpp_languaget::typecheck - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool cpp_languaget::typecheck( symbol_tablet &symbol_table, const std::string &module) @@ -190,18 +135,6 @@ bool cpp_languaget::typecheck( return linking(symbol_table, new_symbol_table, get_message_handler()); } -/*******************************************************************\ - -Function: cpp_languaget::final - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool cpp_languaget::final( symbol_tablet &symbol_table, bool generate_start_function) @@ -215,18 +148,6 @@ bool cpp_languaget::final( return false; } -/*******************************************************************\ - -Function: cpp_languaget::show_parse - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_languaget::show_parse(std::ostream &out) { for(cpp_parse_treet::itemst::const_iterator it= @@ -236,18 +157,6 @@ void cpp_languaget::show_parse(std::ostream &out) show_parse(out, *it); } -/*******************************************************************\ - -Function: cpp_languaget::show_parse - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_languaget::show_parse( std::ostream &out, const cpp_itemt &item) @@ -258,7 +167,7 @@ void cpp_languaget::show_parse( item.get_linkage_spec(); out << "LINKAGE " << linkage_spec.linkage().get("value") - << ":" << std::endl; + << ":\n"; for(cpp_linkage_spect::itemst::const_iterator it=linkage_spec.items().begin(); @@ -266,7 +175,7 @@ void cpp_languaget::show_parse( it++) show_parse(out, *it); - out << std::endl; + out << '\n'; } else if(item.is_namespace_spec()) { @@ -274,7 +183,7 @@ void cpp_languaget::show_parse( item.get_namespace_spec(); out << "NAMESPACE " << namespace_spec.get_namespace() - << ":" << std::endl; + << ":\n"; for(cpp_namespace_spect::itemst::const_iterator it=namespace_spec.items().begin(); @@ -282,7 +191,7 @@ void cpp_languaget::show_parse( it++) show_parse(out, *it); - out << std::endl; + out << '\n'; } else if(item.is_using()) { @@ -291,46 +200,22 @@ void cpp_languaget::show_parse( out << "USING "; if(cpp_using.get_namespace()) out << "NAMESPACE "; - out << cpp_using.name().pretty() << std::endl; - out << std::endl; + out << cpp_using.name().pretty() << '\n'; + out << '\n'; } else if(item.is_declaration()) { item.get_declaration().output(out); } else - out << "UNKNOWN: " << item.pretty() << std::endl; + out << "UNKNOWN: " << item.pretty() << '\n'; } -/*******************************************************************\ - -Function: new_cpp_language - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - languaget *new_cpp_language() { return new cpp_languaget; } -/*******************************************************************\ - -Function: cpp_languaget::from_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool cpp_languaget::from_expr( const exprt &expr, std::string &code, @@ -340,18 +225,6 @@ bool cpp_languaget::from_expr( return false; } -/*******************************************************************\ - -Function: cpp_languaget::from_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool cpp_languaget::from_type( const typet &type, std::string &code, @@ -361,36 +234,12 @@ bool cpp_languaget::from_type( return false; } -/*******************************************************************\ - -Function: cpp_languaget::get_pretty_printer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::unique_ptr cpp_languaget::get_pretty_printer(const namespacet &ns) { return std::unique_ptr(new expr2cppt(ns)); } -/*******************************************************************\ - -Function: cpp_languaget::type_to_name - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool cpp_languaget::type_to_name( const typet &type, std::string &name, @@ -400,18 +249,6 @@ bool cpp_languaget::type_to_name( return false; } -/*******************************************************************\ - -Function: cpp_languaget::to_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool cpp_languaget::to_expr( const std::string &code, const std::string &module, @@ -450,18 +287,6 @@ bool cpp_languaget::to_expr( return result; } -/*******************************************************************\ - -Function: cpp_languaget::~cpp_languaget - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - cpp_languaget::~cpp_languaget() { } diff --git a/src/cpp/cpp_language.h b/src/cpp/cpp_language.h index b818d64f4d6..7e050271300 100644 --- a/src/cpp/cpp_language.h +++ b/src/cpp/cpp_language.h @@ -6,18 +6,16 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Module + #ifndef CPROVER_CPP_CPP_LANGUAGE_H #define CPROVER_CPP_CPP_LANGUAGE_H -/*! \defgroup gr_cpp C++ front-end */ - #include #include "cpp_parse_tree.h" -/*! \brief TO_BE_DOCUMENTED - \ingroup gr_cpp -*/ class cpp_languaget:public languaget { public: diff --git a/src/cpp/cpp_linkage_spec.h b/src/cpp/cpp_linkage_spec.h index 67cf2c93b63..d7b6002ea60 100644 --- a/src/cpp/cpp_linkage_spec.h +++ b/src/cpp/cpp_linkage_spec.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + #ifndef CPROVER_CPP_CPP_LINKAGE_SPEC_H #define CPROVER_CPP_CPP_LINKAGE_SPEC_H diff --git a/src/cpp/cpp_member_spec.h b/src/cpp/cpp_member_spec.h index 714b84b684b..76097e1b14c 100644 --- a/src/cpp/cpp_member_spec.h +++ b/src/cpp/cpp_member_spec.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ + #ifndef CPROVER_CPP_CPP_MEMBER_SPEC_H #define CPROVER_CPP_CPP_MEMBER_SPEC_H diff --git a/src/cpp/cpp_name.cpp b/src/cpp/cpp_name.cpp index ae73ba3cbca..1206ade0a71 100644 --- a/src/cpp/cpp_name.cpp +++ b/src/cpp/cpp_name.cpp @@ -6,22 +6,13 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include -#include +/// \file +/// C++ Language Type Checking #include "cpp_name.h" -/*******************************************************************\ - -Function: cpp_namet::get_base_name - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include irep_idt cpp_namet::get_base_name() const { @@ -49,18 +40,6 @@ irep_idt cpp_namet::get_base_name() const return irep_idt(); } -/*******************************************************************\ - -Function: cpp_namet::convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - #if 0 void cpp_namet::convert( std::string &identifier, @@ -77,7 +56,7 @@ void cpp_namet::convert( else if(id==ID_template_args) { std::stringstream ss; - ss << location() << std::endl; + ss << location() << '\n'; ss << "no template arguments allowed here"; throw ss.str(); } @@ -94,18 +73,6 @@ void cpp_namet::convert( } #endif -/*******************************************************************\ - -Function: cpp_namet::convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string cpp_namet::to_string() const { std::string str; diff --git a/src/cpp/cpp_name.h b/src/cpp/cpp_name.h index 9f1f635e26a..a27374c5524 100644 --- a/src/cpp/cpp_name.h +++ b/src/cpp/cpp_name.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ + #ifndef CPROVER_CPP_CPP_NAME_H #define CPROVER_CPP_CPP_NAME_H diff --git a/src/cpp/cpp_namespace_spec.cpp b/src/cpp/cpp_namespace_spec.cpp index d7e8adb5eda..2254f2b7d34 100644 --- a/src/cpp/cpp_namespace_spec.cpp +++ b/src/cpp/cpp_namespace_spec.cpp @@ -6,22 +6,14 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include +/// \file +/// C++ Language Type Checking #include "cpp_namespace_spec.h" -#include "cpp_item.h" - -/*******************************************************************\ - -Function: cpp_namespace_spect::output - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include "cpp_item.h" void cpp_namespace_spect::output(std::ostream &out) const { diff --git a/src/cpp/cpp_namespace_spec.h b/src/cpp/cpp_namespace_spec.h index 84aa6314086..ed96d1dd338 100644 --- a/src/cpp/cpp_namespace_spec.h +++ b/src/cpp/cpp_namespace_spec.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + #ifndef CPROVER_CPP_CPP_NAMESPACE_SPEC_H #define CPROVER_CPP_CPP_NAMESPACE_SPEC_H diff --git a/src/cpp/cpp_parse_tree.cpp b/src/cpp/cpp_parse_tree.cpp index 33614a83f53..9027c9ed3b0 100644 --- a/src/cpp/cpp_parse_tree.cpp +++ b/src/cpp/cpp_parse_tree.cpp @@ -6,37 +6,16 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include "cpp_parse_tree.h" - -/*******************************************************************\ - -Function: cpp_parse_treet::swap - - Inputs: +/// \file +/// C++ Parser - Outputs: - - Purpose: - -\*******************************************************************/ +#include "cpp_parse_tree.h" void cpp_parse_treet::swap(cpp_parse_treet &cpp_parse_tree) { cpp_parse_tree.items.swap(items); } -/*******************************************************************\ - -Function: cpp_parse_treet::clear - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_parse_treet::clear() { items.clear(); diff --git a/src/cpp/cpp_parse_tree.h b/src/cpp/cpp_parse_tree.h index 9d620864247..afcd706fcef 100644 --- a/src/cpp/cpp_parse_tree.h +++ b/src/cpp/cpp_parse_tree.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Parser + #ifndef CPROVER_CPP_CPP_PARSE_TREE_H #define CPROVER_CPP_CPP_PARSE_TREE_H diff --git a/src/cpp/cpp_parser.cpp b/src/cpp/cpp_parser.cpp index b72c6be6d5e..eae4728bbc4 100644 --- a/src/cpp/cpp_parser.cpp +++ b/src/cpp/cpp_parser.cpp @@ -6,23 +6,14 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include +/// \file +/// C++ Parser #include "cpp_parser.h" -cpp_parsert cpp_parser; - -/*******************************************************************\ - -Function: cpp_parsert::parse - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +cpp_parsert cpp_parser; bool cpp_parse(); diff --git a/src/cpp/cpp_parser.h b/src/cpp/cpp_parser.h index f2db8e6c2f7..1a167f71f24 100644 --- a/src/cpp/cpp_parser.h +++ b/src/cpp/cpp_parser.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Parser + #ifndef CPROVER_CPP_CPP_PARSER_H #define CPROVER_CPP_CPP_PARSER_H diff --git a/src/cpp/cpp_scope.cpp b/src/cpp/cpp_scope.cpp index 35b52479419..c3849384d67 100644 --- a/src/cpp/cpp_scope.cpp +++ b/src/cpp/cpp_scope.cpp @@ -6,20 +6,12 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include "cpp_typecheck.h" -#include "cpp_scope.h" - -/*******************************************************************\ - -Function: cpp_scopet::operator << - - Inputs: - - Outputs: +/// \file +/// C++ Language Type Checking - Purpose: +#include "cpp_scope.h" -\*******************************************************************/ +#include "cpp_typecheck.h" std::ostream &operator << (std::ostream &out, cpp_scopet::lookup_kindt kind) { @@ -34,18 +26,6 @@ std::ostream &operator << (std::ostream &out, cpp_scopet::lookup_kindt kind) return out; } -/*******************************************************************\ - -Function: cpp_scopet::lookup - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_scopet::lookup( const irep_idt &base_name, lookup_kindt kind, @@ -109,18 +89,6 @@ void cpp_scopet::lookup( get_parent().lookup(base_name, kind, id_set); } -/*******************************************************************\ - -Function: cpp_scopet::lookup - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_scopet::lookup( const irep_idt &base_name, lookup_kindt kind, @@ -131,11 +99,11 @@ void cpp_scopet::lookup( // are looking for templates! #if 0 - std::cout << "B: " << base_name << std::endl; - std::cout << "K: " << kind << std::endl; - std::cout << "I: " << id_class << std::endl; + std::cout << "B: " << base_name << '\n'; + std::cout << "K: " << kind << '\n'; + std::cout << "I: " << id_class << '\n'; std::cout << "THIS: " << this->base_name << " " << this->id_class - << " " << this->identifier << std::endl; + << " " << this->identifier << '\n'; #endif cpp_id_mapt::iterator @@ -175,7 +143,7 @@ void cpp_scopet::lookup( } if(!id_set.empty() && - id_class!=TEMPLATE) return; // done, upwards scopes are hidden + id_class!=id_classt::TEMPLATE) return; // done, upwards scopes are hidden // secondary scopes for(scope_listt::iterator @@ -194,25 +162,13 @@ void cpp_scopet::lookup( return; // done if(!id_set.empty() && - id_class!=TEMPLATE) return; // done, upwards scopes are hidden + id_class!=id_classt::TEMPLATE) return; // done, upwards scopes are hidden // ask parent, recursive call if(!is_root_scope()) get_parent().lookup(base_name, kind, id_class, id_set); } -/*******************************************************************\ - -Function: cpp_scopet::lookup_identifier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_scopet::lookup_identifier( const irep_idt &identifier, cpp_idt::id_classt id_class, @@ -241,18 +197,6 @@ void cpp_scopet::lookup_identifier( #endif } -/*******************************************************************\ - -Function: cpp_scopet::new_scope - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - cpp_scopet &cpp_scopet::new_scope(const irep_idt &new_scope_name) { cpp_idt &id=insert(new_scope_name); @@ -265,18 +209,6 @@ cpp_scopet &cpp_scopet::new_scope(const irep_idt &new_scope_name) } -/*******************************************************************\ - -Function: cpp_scopet::contains - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool cpp_scopet::contains(const irep_idt &base_name) { id_sett id_set; diff --git a/src/cpp/cpp_scope.h b/src/cpp/cpp_scope.h index 07cded727fa..690318edb43 100644 --- a/src/cpp/cpp_scope.h +++ b/src/cpp/cpp_scope.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + #ifndef CPROVER_CPP_CPP_SCOPE_H #define CPROVER_CPP_CPP_SCOPE_H @@ -69,18 +72,18 @@ class cpp_scopet:public cpp_idt bool is_root_scope() const { - return id_class==ROOT_SCOPE; + return id_class==id_classt::ROOT_SCOPE; } bool is_global_scope() const { - return id_class==ROOT_SCOPE || - id_class==NAMESPACE; + return id_class==id_classt::ROOT_SCOPE || + id_class==id_classt::NAMESPACE; } bool is_template_scope() const { - return id_class==TEMPLATE_SCOPE; + return id_class==id_classt::TEMPLATE_SCOPE; } cpp_scopet &get_parent() const @@ -118,7 +121,7 @@ class cpp_root_scopet:public cpp_scopet public: cpp_root_scopet() { - id_class=ROOT_SCOPE; + id_class=id_classt::ROOT_SCOPE; identifier="::"; } }; diff --git a/src/cpp/cpp_scopes.cpp b/src/cpp/cpp_scopes.cpp index 51923be1929..71a6b1edfbf 100644 --- a/src/cpp/cpp_scopes.cpp +++ b/src/cpp/cpp_scopes.cpp @@ -6,41 +6,19 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include - +/// \file +/// C++ Language Type Checking #include "cpp_scopes.h" -/*******************************************************************\ - -Function: cpp_scopest::new_block_scope - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include cpp_scopet &cpp_scopest::new_block_scope() { unsigned prefix=++current_scope().compound_counter; - return new_scope(std::to_string(prefix), cpp_idt::BLOCK_SCOPE); + return new_scope(std::to_string(prefix), cpp_idt::id_classt::BLOCK_SCOPE); } -/*******************************************************************\ - -Function: cpp_scopest::put_into_scope - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - cpp_idt &cpp_scopest::put_into_scope( const symbolt &symbol, cpp_scopet &scope, @@ -57,7 +35,7 @@ cpp_idt &cpp_scopest::put_into_scope( { irep_idt block_base_name(std::string("$block:")+symbol.base_name.c_str()); cpp_idt &id = scope.insert(block_base_name); - id.id_class=cpp_idt::BLOCK_SCOPE; + id.id_class=cpp_idt::id_classt::BLOCK_SCOPE; id.identifier=symbol.name; id.is_scope=true; id.prefix = id2string(scope.prefix) + id2string(symbol.base_name) + "::"; @@ -74,7 +52,7 @@ cpp_idt &cpp_scopest::put_into_scope( cpp_idt &id=current_scope().insert(symbol.base_name); id.identifier=symbol.name; - id.id_class = cpp_idt::SYMBOL; + id.id_class = cpp_idt::id_classt::SYMBOL; if(id_map.find(symbol.name)==id_map.end()) id_map[symbol.name]=&id; return id; @@ -83,24 +61,14 @@ cpp_idt &cpp_scopest::put_into_scope( { cpp_idt &id=scope.insert(symbol.base_name); id.identifier=symbol.name; - id.id_class = cpp_idt::SYMBOL; + id.id_class = cpp_idt::id_classt::SYMBOL; if(id_map.find(symbol.name)==id_map.end()) id_map[symbol.name]=&id; return id; } } -/*******************************************************************\ - -Function: cpp_scopest::print_current - - Inputs: - - Outputs: - Purpose: - -\*******************************************************************/ - +/// \return Purpose: void cpp_scopest::print_current(std::ostream &out) const { const cpp_scopet *scope=current_scope_ptr; diff --git a/src/cpp/cpp_scopes.h b/src/cpp/cpp_scopes.h index e2034a436f7..ca392497c7d 100644 --- a/src/cpp/cpp_scopes.h +++ b/src/cpp/cpp_scopes.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + #ifndef CPROVER_CPP_CPP_SCOPES_H #define CPROVER_CPP_CPP_SCOPES_H @@ -46,7 +49,7 @@ class cpp_scopest cpp_scopet &new_namespace(const irep_idt &new_scope_name) { - return new_scope(new_scope_name, cpp_idt::NAMESPACE); + return new_scope(new_scope_name, cpp_idt::id_classt::NAMESPACE); } cpp_scopet &new_block_scope(); diff --git a/src/cpp/cpp_static_assert.h b/src/cpp/cpp_static_assert.h index 64b3d5bcf6a..be784ca51f1 100644 --- a/src/cpp/cpp_static_assert.h +++ b/src/cpp/cpp_static_assert.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + #ifndef CPROVER_CPP_CPP_STATIC_ASSERT_H #define CPROVER_CPP_CPP_STATIC_ASSERT_H diff --git a/src/cpp/cpp_storage_spec.h b/src/cpp/cpp_storage_spec.h index a2f438fe766..74c11bc1ef0 100644 --- a/src/cpp/cpp_storage_spec.h +++ b/src/cpp/cpp_storage_spec.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ + #ifndef CPROVER_CPP_CPP_STORAGE_SPEC_H #define CPROVER_CPP_CPP_STORAGE_SPEC_H diff --git a/src/cpp/cpp_template_args.h b/src/cpp/cpp_template_args.h index 5fa708879a8..47ceca5f003 100644 --- a/src/cpp/cpp_template_args.h +++ b/src/cpp/cpp_template_args.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + #ifndef CPROVER_CPP_CPP_TEMPLATE_ARGS_H #define CPROVER_CPP_CPP_TEMPLATE_ARGS_H diff --git a/src/cpp/cpp_template_parameter.h b/src/cpp/cpp_template_parameter.h index af5527a10c4..2d9a49bc215 100644 --- a/src/cpp/cpp_template_parameter.h +++ b/src/cpp/cpp_template_parameter.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ + #ifndef CPROVER_CPP_CPP_TEMPLATE_PARAMETER_H #define CPROVER_CPP_CPP_TEMPLATE_PARAMETER_H diff --git a/src/cpp/cpp_template_type.h b/src/cpp/cpp_template_type.h index 2ebb5ac34e0..57e9d257e1d 100644 --- a/src/cpp/cpp_template_type.h +++ b/src/cpp/cpp_template_type.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ + #ifndef CPROVER_CPP_CPP_TEMPLATE_TYPE_H #define CPROVER_CPP_CPP_TEMPLATE_TYPE_H diff --git a/src/cpp/cpp_token.h b/src/cpp/cpp_token.h index a022cf92df2..800ac372353 100644 --- a/src/cpp/cpp_token.h +++ b/src/cpp/cpp_token.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Parser: Token + #ifndef CPROVER_CPP_CPP_TOKEN_H #define CPROVER_CPP_CPP_TOKEN_H diff --git a/src/cpp/cpp_token_buffer.cpp b/src/cpp/cpp_token_buffer.cpp index 9dcd75526e6..472a4333cfd 100644 --- a/src/cpp/cpp_token_buffer.cpp +++ b/src/cpp/cpp_token_buffer.cpp @@ -6,24 +6,15 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include - -#include -#include +/// \file +/// C++ Parser: Token Buffer #include "cpp_token_buffer.h" -/*******************************************************************\ - -Function: cpp_token_buffert::LookAhead - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include +#include int cpp_token_buffert::LookAhead(unsigned offset) { @@ -37,18 +28,6 @@ int cpp_token_buffert::LookAhead(unsigned offset) return token_vector[offset]->kind; } -/*******************************************************************\ - -Function: cpp_token_buffert::get_token - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - int cpp_token_buffert::get_token(cpp_tokent &token) { assert(current_pos<=token_vector.size()); @@ -63,18 +42,6 @@ int cpp_token_buffert::get_token(cpp_tokent &token) return token.kind; } -/*******************************************************************\ - -Function: cpp_token_buffert::get_token - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - int cpp_token_buffert::get_token() { assert(current_pos<=token_vector.size()); @@ -89,18 +56,6 @@ int cpp_token_buffert::get_token() return kind; } -/*******************************************************************\ - -Function: cpp_token_buffert::LookAhead - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - int cpp_token_buffert::LookAhead(unsigned offset, cpp_tokent &token) { assert(current_pos<=token_vector.size()); @@ -115,18 +70,6 @@ int cpp_token_buffert::LookAhead(unsigned offset, cpp_tokent &token) return token.kind; } -/*******************************************************************\ - -Function: cpp_token_buffert::read_token - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - int yyansi_clex(); extern char *yyansi_ctext; @@ -147,60 +90,24 @@ void cpp_token_buffert::read_token() tokens.back().filename=ansi_c_parser.get_file(); } - // std::cout << "TOKEN: " << kind << " " << tokens.back().text << std::endl; + // std::cout << "TOKEN: " << kind << " " << tokens.back().text << '\n'; tokens.back().kind=kind; - // std::cout << "II: " << token_vector.back()->kind << std::endl; - // std::cout << "I2: " << token_vector.size() << std::endl; + // std::cout << "II: " << token_vector.back()->kind << '\n'; + // std::cout << "I2: " << token_vector.size() << '\n'; } -/*******************************************************************\ - -Function: cpp_token_buffert::Save - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - cpp_token_buffert::post cpp_token_buffert::Save() { return current_pos; } -/*******************************************************************\ - -Function: cpp_token_buffert::Restore - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_token_buffert::Restore(post pos) { current_pos=pos; } -/*******************************************************************\ - -Function: cpp_token_buffert::Replace - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_token_buffert::Replace(const cpp_tokent &token) { assert(current_pos<=token_vector.size()); @@ -211,18 +118,6 @@ void cpp_token_buffert::Replace(const cpp_tokent &token) *token_vector[current_pos]=token; } -/*******************************************************************\ - -Function: cpp_token_buffert::Replace - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_token_buffert::Insert(const cpp_tokent &token) { assert(current_pos<=token_vector.size()); diff --git a/src/cpp/cpp_token_buffer.h b/src/cpp/cpp_token_buffer.h index e4e90422853..859945787bd 100644 --- a/src/cpp/cpp_token_buffer.h +++ b/src/cpp/cpp_token_buffer.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Parser: Token Buffer + #ifndef CPROVER_CPP_CPP_TOKEN_BUFFER_H #define CPROVER_CPP_CPP_TOKEN_BUFFER_H diff --git a/src/cpp/cpp_type2name.cpp b/src/cpp/cpp_type2name.cpp index 98842b8b41a..f40af724134 100644 --- a/src/cpp/cpp_type2name.cpp +++ b/src/cpp/cpp_type2name.cpp @@ -6,24 +6,15 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include - -#include -#include +/// \file +/// C++ Language Module #include "cpp_type2name.h" -/*******************************************************************\ - -Function: do_prefix - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include +#include static std::string do_prefix(const std::string &s) { @@ -34,18 +25,6 @@ static std::string do_prefix(const std::string &s) return s; } -/*******************************************************************\ - -Function: irep2name - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static void irep2name(const irept &irep, std::string &result) { result=""; @@ -109,18 +88,6 @@ static void irep2name(const irept &irep, std::string &result) result+=')'; } -/*******************************************************************\ - -Function: cpp_type2name - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string cpp_type2name(const typet &type) { std::string result; @@ -152,7 +119,7 @@ std::string cpp_type2name(const typet &type) // we try to use #c_type const irep_idt c_type=type.get(ID_C_c_type); - if(c_type!=irep_idt()) + if(!c_type.empty()) result+=id2string(c_type); else if(type.id()==ID_unsignedbv) result+="unsigned_int"; @@ -164,7 +131,7 @@ std::string cpp_type2name(const typet &type) // we try to use #c_type const irep_idt c_type=type.get(ID_C_c_type); - if(c_type!=irep_idt()) + if(!c_type.empty()) result+=id2string(c_type); else result+="double"; @@ -203,18 +170,6 @@ std::string cpp_type2name(const typet &type) return result; } -/*******************************************************************\ - -Function: cpp_expr2name - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string cpp_expr2name(const exprt &expr) { std::string tmp; diff --git a/src/cpp/cpp_type2name.h b/src/cpp/cpp_type2name.h index ffb2a99eef6..1f5015c076a 100644 --- a/src/cpp/cpp_type2name.h +++ b/src/cpp/cpp_type2name.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Module + #ifndef CPROVER_CPP_CPP_TYPE2NAME_H #define CPROVER_CPP_CPP_TYPE2NAME_H @@ -13,6 +16,8 @@ Author: Daniel Kroening, kroening@cs.cmu.edu #include +class exprt; + std::string cpp_type2name(const typet &type); std::string cpp_expr2name(const exprt &expr); diff --git a/src/cpp/cpp_typecast.h b/src/cpp/cpp_typecast.h index 34eaf8fd48a..6cfc7905cdb 100644 --- a/src/cpp/cpp_typecast.h +++ b/src/cpp/cpp_typecast.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ + #ifndef CPROVER_CPP_CPP_TYPECAST_H #define CPROVER_CPP_CPP_TYPECAST_H diff --git a/src/cpp/cpp_typecheck.cpp b/src/cpp/cpp_typecheck.cpp index fe8a9f063d7..e87efb885fb 100644 --- a/src/cpp/cpp_typecheck.cpp +++ b/src/cpp/cpp_typecheck.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + +#include "cpp_typecheck.h" + #include #include @@ -15,23 +20,10 @@ Author: Daniel Kroening, kroening@cs.cmu.edu #include #include -#include "cpp_typecheck.h" #include "expr2cpp.h" #include "cpp_convert_type.h" #include "cpp_declarator.h" -/*******************************************************************\ - -Function: cpp_typecheckt::convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::convert(cpp_itemt &item) { if(item.is_declaration()) @@ -52,18 +44,7 @@ void cpp_typecheckt::convert(cpp_itemt &item) } } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck - - Inputs: - - Outputs: - - Purpose: typechecking main method - -\*******************************************************************/ - +/// typechecking main method void cpp_typecheckt::typecheck() { // default linkage is "automatic" @@ -79,18 +60,6 @@ void cpp_typecheckt::typecheck() clean_up(); } -/*******************************************************************\ - -Function: cpp_typecheckt::this_struct_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const struct_typet &cpp_typecheckt::this_struct_type() { const exprt &this_expr= @@ -104,52 +73,16 @@ const struct_typet &cpp_typecheckt::this_struct_type() return to_struct_type(t); } -/*******************************************************************\ - -Function: cpp_typecheckt::to_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string cpp_typecheckt::to_string(const exprt &expr) { return expr2cpp(expr, *this); } -/*******************************************************************\ - -Function: cpp_typecheckt::to_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string cpp_typecheckt::to_string(const typet &type) { return type2cpp(type, *this); } -/*******************************************************************\ - -Function: cpp_typecheck - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool cpp_typecheck( cpp_parse_treet &cpp_parse_tree, symbol_tablet &symbol_table, @@ -161,23 +94,14 @@ bool cpp_typecheck( return cpp_typecheck.typecheck_main(); } -/*******************************************************************\ - -Function: cpp_typecheck - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool cpp_typecheck( exprt &expr, message_handlert &message_handler, const namespacet &ns) { + const unsigned errors_before= + message_handler.get_message_count(messaget::M_ERROR); + symbol_tablet symbol_table; cpp_parse_treet cpp_parse_tree; @@ -204,34 +128,23 @@ bool cpp_typecheck( cpp_typecheck.error() << e << messaget::eom; } - return cpp_typecheck.get_error_found(); + return message_handler.get_message_count(messaget::M_ERROR)!=errors_before; } -/*******************************************************************\ - -Function: cpp_typecheckt::static_and_dynamic_initialization - - Inputs: - - Outputs: - - Purpose: Initialization of static objects: - - "Objects with static storage duration (3.7.1) shall be zero-initialized - (8.5) before any other initialization takes place. Zero-initialization - and initialization with a constant expression are collectively called - static initialization; all other initialization is dynamic - initialization. Objects of POD types (3.9) with static storage duration - initialized with constant expressions (5.19) shall be initialized before - any dynamic initialization takes place. Objects with static storage - duration defined in namespace scope in the same translation unit and - dynamically initialized shall be initialized in the order in which their - definition appears in the translation unit. [Note: 8.5.1 describes the - order in which aggregate members are initialized. The initialization - of local static objects is described in 6.7. ]" - -\*******************************************************************/ - +/// Initialization of static objects: +/// +/// "Objects with static storage duration (3.7.1) shall be zero-initialized +/// (8.5) before any other initialization takes place. Zero-initialization +/// and initialization with a constant expression are collectively called +/// static initialization; all other initialization is dynamic +/// initialization. Objects of POD types (3.9) with static storage duration +/// initialized with constant expressions (5.19) shall be initialized before +/// any dynamic initialization takes place. Objects with static storage +/// duration defined in namespace scope in the same translation unit and +/// dynamically initialized shall be initialized in the order in which their +/// definition appears in the translation unit. [Note: 8.5.1 describes the +/// order in which aggregate members are initialized. The initialization +/// of local static objects is described in 6.7. ]" void cpp_typecheckt::static_and_dynamic_initialization() { code_blockt init_block; // Dynamic Initialization Block @@ -302,18 +215,6 @@ void cpp_typecheckt::static_and_dynamic_initialization() disable_access_control=false; } -/*******************************************************************\ - -Function: cpp_typecheckt::do_not_typechecked - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::do_not_typechecked() { bool cont; @@ -363,18 +264,6 @@ void cpp_typecheckt::do_not_typechecked() } } -/*******************************************************************\ - -Function: cpp_typecheckt::clean_up - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::clean_up() { symbol_tablet::symbolst::iterator it=symbol_table.symbols.begin(); diff --git a/src/cpp/cpp_typecheck.h b/src/cpp/cpp_typecheck.h index 55955cd0334..5c0a6afe285 100644 --- a/src/cpp/cpp_typecheck.h +++ b/src/cpp/cpp_typecheck.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + #ifndef CPROVER_CPP_CPP_TYPECHECK_H #define CPROVER_CPP_CPP_TYPECHECK_H diff --git a/src/cpp/cpp_typecheck_bases.cpp b/src/cpp/cpp_typecheck_bases.cpp index 5bcb06e55e3..c076d1e131b 100644 --- a/src/cpp/cpp_typecheck_bases.cpp +++ b/src/cpp/cpp_typecheck_bases.cpp @@ -6,21 +6,12 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include +/// \file +/// C++ Language Type Checking #include "cpp_typecheck.h" -/*******************************************************************\ - -Function: cpp_typecheckt::typcheck_compound_bases - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void cpp_typecheckt::typecheck_compound_bases(struct_typet &type) { @@ -40,7 +31,7 @@ void cpp_typecheckt::typecheck_compound_bases(struct_typet &type) exprt base_symbol_expr= resolve( name, - cpp_typecheck_resolvet::TYPE, + cpp_typecheck_resolvet::wantt::TYPE, cpp_typecheck_fargst()); if(base_symbol_expr.id()!=ID_type) @@ -80,7 +71,7 @@ void cpp_typecheckt::typecheck_compound_bases(struct_typet &type) bool virtual_base = base_it->get_bool(ID_virtual); irep_idt class_access = base_it->get(ID_protection); - if(class_access==irep_idt()) + if(class_access.empty()) class_access = default_class_access; base_symbol_expr.id(ID_base); @@ -126,18 +117,6 @@ void cpp_typecheckt::typecheck_compound_bases(struct_typet &type) } } -/*******************************************************************\ - -Function: cpp_typecheckt::add_base_components - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::add_base_components( const struct_typet &from, const irep_idt &access, diff --git a/src/cpp/cpp_typecheck_code.cpp b/src/cpp/cpp_typecheck_code.cpp index 3d86c0f5f5d..4613918ce8f 100644 --- a/src/cpp/cpp_typecheck_code.cpp +++ b/src/cpp/cpp_typecheck_code.cpp @@ -6,27 +6,19 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include +/// \file +/// C++ Language Type Checking #include "cpp_typecheck.h" + +#include + #include "cpp_convert_type.h" #include "cpp_declarator_converter.h" #include "cpp_template_type.h" #include "cpp_util.h" #include "cpp_exception_id.h" -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_code - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_code(codet &code) { const irep_idt &statement=code.get_statement(); @@ -45,22 +37,14 @@ void cpp_typecheckt::typecheck_code(codet &code) statement==ID_msc_if_not_exists) { } + else if(statement==ID_decl_block) + { + // type checked already + } else c_typecheck_baset::typecheck_code(code); } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_try_catch - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_try_catch(codet &code) { codet::operandst &operands=code.operands(); @@ -127,18 +111,6 @@ void cpp_typecheckt::typecheck_try_catch(codet &code) } } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_ifthenelse - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_ifthenelse(code_ifthenelset &code) { // In addition to the C syntax, C++ also allows a declaration @@ -153,18 +125,6 @@ void cpp_typecheckt::typecheck_ifthenelse(code_ifthenelset &code) c_typecheck_baset::typecheck_ifthenelse(code); } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_while - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_while(code_whilet &code) { // In addition to the C syntax, C++ also allows a declaration @@ -179,18 +139,6 @@ void cpp_typecheckt::typecheck_while(code_whilet &code) c_typecheck_baset::typecheck_while(code); } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_switch - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_switch(code_switcht &code) { // In addition to the C syntax, C++ also allows a declaration @@ -222,18 +170,6 @@ void cpp_typecheckt::typecheck_switch(code_switcht &code) c_typecheck_baset::typecheck_switch(code); } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_member_initializer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_member_initializer(codet &code) { const cpp_namet &member= @@ -256,7 +192,7 @@ void cpp_typecheckt::typecheck_member_initializer(codet &code) // Plus, this should happen in class scope, not the scope of // the constructor because of the constructor arguments. exprt symbol_expr= - resolve(member, cpp_typecheck_resolvet::VAR, fargs); + resolve(member, cpp_typecheck_resolvet::wantt::VAR, fargs); if(symbol_expr.type().id()==ID_code) { @@ -340,7 +276,7 @@ void cpp_typecheckt::typecheck_member_initializer(codet &code) cpp_save_scopet cpp_saved_scope(cpp_scopes); cpp_scopes.go_to( *(cpp_scopes.id_map[cpp_scopes.current_scope().class_identifier])); - symbol_expr=resolve(member, cpp_typecheck_resolvet::VAR, fargs); + symbol_expr=resolve(member, cpp_typecheck_resolvet::wantt::VAR, fargs); } if(symbol_expr.id() == ID_dereference && @@ -413,18 +349,6 @@ void cpp_typecheckt::typecheck_member_initializer(codet &code) } } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_decl - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_decl(codet &code) { if(code.operands().size()!=1) @@ -518,18 +442,6 @@ void cpp_typecheckt::typecheck_decl(codet &code) code.swap(new_code); } -/*******************************************************************\ - -Function: cpp_typecheck_codet::typecheck_block - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_block(codet &code) { cpp_save_scopet saved_scope(cpp_scopes); @@ -538,18 +450,6 @@ void cpp_typecheckt::typecheck_block(codet &code) c_typecheck_baset::typecheck_block(code); } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_assign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_assign(codet &code) { if(code.operands().size()!=2) @@ -560,7 +460,7 @@ void cpp_typecheckt::typecheck_assign(codet &code) throw 0; } - // turn into a sideeffect + // turn into a side effect side_effect_exprt expr(code.get(ID_statement)); expr.operands() = code.operands(); typecheck_expr(expr); diff --git a/src/cpp/cpp_typecheck_compound_type.cpp b/src/cpp/cpp_typecheck_compound_type.cpp index e1ece6d8be9..c0715fd03f4 100644 --- a/src/cpp/cpp_typecheck_compound_type.cpp +++ b/src/cpp/cpp_typecheck_compound_type.cpp @@ -6,32 +6,25 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + +#include "cpp_typecheck.h" + #include #include #include #include +#include #include #include "cpp_type2name.h" #include "cpp_declarator_converter.h" -#include "cpp_typecheck.h" #include "cpp_convert_type.h" #include "cpp_name.h" -/*******************************************************************\ - -Function: cpp_typecheckt::has_const - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - bool cpp_typecheckt::has_const(const typet &type) { if(type.id()==ID_const) @@ -48,18 +41,6 @@ bool cpp_typecheckt::has_const(const typet &type) return false; } -/*******************************************************************\ - -Function: cpp_typecheckt::has_volatile - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - bool cpp_typecheckt::has_volatile(const typet &type) { if(type.id()==ID_volatile) @@ -76,18 +57,6 @@ bool cpp_typecheckt::has_volatile(const typet &type) return false; } -/*******************************************************************\ - -Function: cpp_typecheckt::tag_scope - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - cpp_scopet &cpp_typecheckt::tag_scope( const irep_idt &base_name, bool has_body, @@ -127,18 +96,6 @@ cpp_scopet &cpp_typecheckt::tag_scope( return cpp_scopes.get_global_scope(); } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_compound_type - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_compound_type( struct_union_typet &type) { @@ -153,7 +110,7 @@ void cpp_typecheckt::typecheck_compound_type( // get the tag name bool has_tag=type.find(ID_tag).is_not_nil(); irep_idt base_name; - cpp_scopet *dest_scope=NULL; + cpp_scopet *dest_scope=nullptr; bool has_body=type.find(ID_body).is_not_nil(); bool tag_only_declaration=type.get_bool(ID_C_tag_only_declaration); @@ -193,7 +150,7 @@ void cpp_typecheckt::typecheck_compound_type( } // The identifier 'tag-X' matches what the C front-end does! - // The hypen is deliberate to avoid collisions with other + // The hyphen is deliberate to avoid collisions with other // identifiers. const irep_idt symbol_name= dest_scope->prefix+ @@ -269,13 +226,13 @@ void cpp_typecheckt::typecheck_compound_type( // put into dest_scope cpp_idt &id=cpp_scopes.put_into_scope(*new_symbol, *dest_scope); - id.id_class=cpp_idt::CLASS; + id.id_class=cpp_idt::id_classt::CLASS; id.is_scope=true; id.prefix=cpp_scopes.current_scope().prefix+ id2string(new_symbol->base_name)+ cpp_scopes.current_scope().suffix+"::"; id.class_identifier=new_symbol->name; - id.id_class=cpp_idt::CLASS; + id.id_class=cpp_idt::id_classt::CLASS; if(has_body) typecheck_compound_body(*new_symbol); @@ -294,18 +251,6 @@ void cpp_typecheckt::typecheck_compound_type( type.swap(symbol_type); } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_compound_declarator - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_compound_declarator( const symbolt &symbol, const cpp_declarationt &declaration, @@ -523,7 +468,7 @@ void cpp_typecheckt::typecheck_compound_declarator( { is_virtual=true; const code_typet &code_type=to_code_type(comp.type()); - assert(code_type.parameters().size()>0); + assert(!code_type.parameters().empty()); const typet &pointer_type=code_type.parameters()[0].type(); assert(pointer_type.id()==ID_pointer); virtual_bases.insert(pointer_type.subtype().get(ID_identifier)); @@ -601,7 +546,7 @@ void cpp_typecheckt::typecheck_compound_declarator( // add a virtual-table pointer struct_typet::componentt compo; - compo.type()=pointer_typet(symbol_typet(vt_name)); + compo.type()=pointer_type(symbol_typet(vt_name)); compo.set_name(id2string(symbol.name) +"::@vtable_pointer"); compo.set(ID_base_name, "@vtable_pointer"); compo.set( @@ -623,7 +568,7 @@ void cpp_typecheckt::typecheck_compound_declarator( // add an entry to the virtual table struct_typet::componentt vt_entry; - vt_entry.type()=pointer_typet(component.type()); + vt_entry.type()=pointer_type(component.type()); vt_entry.set_name(id2string(vtit->first)+"::"+virtual_name); vt_entry.set(ID_base_name, virtual_name); vt_entry.set(ID_pretty_name, virtual_name); @@ -659,7 +604,7 @@ void cpp_typecheckt::typecheck_compound_declarator( { irep_idt base_name=arg.get_base_name(); - if(base_name==irep_idt()) + if(base_name.empty()) base_name="arg"+std::to_string(i++); symbolt arg_symb; @@ -804,18 +749,7 @@ void cpp_typecheckt::typecheck_compound_declarator( components.push_back(component); } -/*******************************************************************\ - -Function: cpp_typecheckt::check_fixed_size_array - -Inputs: - -Outputs: - -Purpose: check that an array has fixed size - -\*******************************************************************/ - +/// check that an array has fixed size void cpp_typecheckt::check_fixed_size_array(typet &type) { if(type.id()==ID_array) @@ -830,18 +764,6 @@ void cpp_typecheckt::check_fixed_size_array(typet &type) } } -/*******************************************************************\ - -Function: cpp_typecheckt::put_compound_into_scope - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::put_compound_into_scope( const struct_union_typet::componentt &compound) { @@ -849,14 +771,16 @@ void cpp_typecheckt::put_compound_into_scope( const irep_idt &name=compound.get_name(); // nothing to do if no base_name (e.g., an anonymous bitfield) - if(base_name==irep_idt()) + if(base_name.empty()) return; if(compound.type().id()==ID_code) { // put the symbol into scope cpp_idt &id=cpp_scopes.current_scope().insert(base_name); - id.id_class=compound.get_bool("is_type")?cpp_idt::TYPEDEF:cpp_idt::SYMBOL; + id.id_class=compound.get_bool("is_type")? + cpp_idt::id_classt::TYPEDEF: + cpp_idt::id_classt::SYMBOL; id.identifier=name; id.class_identifier=cpp_scopes.current_scope().identifier; id.is_member=true; @@ -870,7 +794,7 @@ void cpp_typecheckt::put_compound_into_scope( cpp_scopes.current_scope().insert( irep_idt(std::string("$block:") + base_name.c_str())); - id_block.id_class=cpp_idt::BLOCK_SCOPE; + id_block.id_class=cpp_idt::id_classt::BLOCK_SCOPE; id_block.identifier=name; id_block.class_identifier=cpp_scopes.current_scope().identifier; id_block.is_method=true; @@ -905,7 +829,9 @@ void cpp_typecheckt::put_compound_into_scope( // put into the scope cpp_idt &id=cpp_scopes.current_scope().insert(base_name); - id.id_class=compound.get_bool(ID_is_type)?cpp_idt::TYPEDEF:cpp_idt::SYMBOL; + id.id_class=compound.get_bool(ID_is_type)? + cpp_idt::id_classt::TYPEDEF: + cpp_idt::id_classt::SYMBOL; id.identifier=name; id.class_identifier=cpp_scopes.current_scope().identifier; id.is_member=true; @@ -914,18 +840,6 @@ void cpp_typecheckt::put_compound_into_scope( } } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_friend_declaration - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_friend_declaration( symbolt &symbol, cpp_declarationt &declaration) @@ -936,9 +850,12 @@ void cpp_typecheckt::typecheck_friend_declaration( if(declaration.is_template()) { return; // TODO + +#if 0 error().source_location=declaration.type().source_location(); error() << "friend template not supported" << eom; throw 0; +#endif } // we distinguish these whether there is a declarator @@ -1010,18 +927,6 @@ void cpp_typecheckt::typecheck_friend_declaration( } } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_compound_body - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_compound_body(symbolt &symbol) { cpp_save_scopet saved_scope(cpp_scopes); @@ -1083,7 +988,7 @@ void cpp_typecheckt::typecheck_compound_body(symbolt &symbol) continue; } - if(declaration.type().id()==irep_idt()) // empty? + if(declaration.type().id().empty()) continue; bool is_typedef=declaration.is_typedef(); @@ -1179,7 +1084,7 @@ void cpp_typecheckt::typecheck_compound_body(symbolt &symbol) ID_public, false, false, false); } - // setup virtual tables before doing the constructors + // set up virtual tables before doing the constructors if(symbol.type.id()==ID_struct) do_virtual_table(symbol); @@ -1304,18 +1209,6 @@ void cpp_typecheckt::typecheck_compound_body(symbolt &symbol) symbol.type.remove(ID_body); } -/*******************************************************************\ - -Function: cpp_typecheckt::move_member_initializers - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::move_member_initializers( irept &initializers, const typet &type, @@ -1358,18 +1251,6 @@ void cpp_typecheckt::move_member_initializers( } } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_member_function - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_member_function( const irep_idt &compound_identifier, struct_typet::componentt &component, @@ -1383,7 +1264,7 @@ void cpp_typecheckt::typecheck_member_function( if(component.get_bool(ID_is_static)) { - if(method_qualifier.id()!=irep_idt()) + if(!method_qualifier.id().empty()) { error().source_location=component.source_location(); error() << "method is static -- no qualifiers allowed" << eom; @@ -1452,18 +1333,6 @@ void cpp_typecheckt::typecheck_member_function( add_method_body(new_symbol); } -/*******************************************************************\ - -Function: cpp_typecheckt::add_this_to_method_type - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::add_this_to_method_type( const irep_idt &compound_symbol, typet &type, @@ -1488,21 +1357,9 @@ void cpp_typecheckt::add_this_to_method_type( if(has_volatile(method_qualifier)) subtype.set(ID_C_volatile, true); - parameter.type()=pointer_typet(subtype); + parameter.type()=pointer_type(subtype); } -/*******************************************************************\ - -Function: cpp_typecheckt::add_anonymous_members_to_scope - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::add_anonymous_members_to_scope( const symbolt &struct_union_symbol) { @@ -1530,7 +1387,7 @@ void cpp_typecheckt::add_anonymous_members_to_scope( if(comp.get_anonymous()) { const symbolt &symbol=lookup(comp.type().get(ID_identifier)); - // recrusive call + // recursive call add_anonymous_members_to_scope(symbol); } else @@ -1545,7 +1402,7 @@ void cpp_typecheckt::add_anonymous_members_to_scope( } cpp_idt &id=cpp_scopes.current_scope().insert(base_name); - id.id_class=cpp_idt::SYMBOL; + id.id_class=cpp_idt::id_classt::SYMBOL; id.identifier=comp.get_name(); id.class_identifier=struct_union_symbol.name; id.is_member=true; @@ -1553,18 +1410,6 @@ void cpp_typecheckt::add_anonymous_members_to_scope( } } -/*******************************************************************\ - -Function: cpp_typecheckt::convert_anon_struct_union_member - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::convert_anon_struct_union_member( const cpp_declarationt &declaration, const irep_idt &access, @@ -1616,18 +1461,6 @@ void cpp_typecheckt::convert_anon_struct_union_member( struct_union_symbol.type.set("#unnamed_object", base_name); } -/*******************************************************************\ - -Function: cpp_typecheckt::get_component - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - bool cpp_typecheckt::get_component( const source_locationt &source_location, const exprt &object, @@ -1670,8 +1503,7 @@ bool cpp_typecheckt::get_component( error().source_location=source_location; str << "error: member `" << component_name << "' is not accessible (" << component.get(ID_access) << ")"; - str << std::endl - << "struct name: " << final_type.get(ID_name); + str << "\nstruct name: " << final_type.get(ID_name); throw 0; #endif } @@ -1728,18 +1560,6 @@ bool cpp_typecheckt::get_component( return false; // component not found } -/*******************************************************************\ - -Function: cpp_typecheckt::check_component_access - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - bool cpp_typecheckt::check_component_access( const struct_union_typet::componentt &component, const struct_union_typet &struct_union_type) @@ -1806,18 +1626,6 @@ bool cpp_typecheckt::check_component_access( return true; // not ok } -/*******************************************************************\ - -Function: cpp_typecheckt::get_bases - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::get_bases( const struct_typet &type, std::set &set_bases) const @@ -1837,18 +1645,6 @@ void cpp_typecheckt::get_bases( } } -/*******************************************************************\ - -Function: cpp_typecheckt::get_virtual_bases - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::get_virtual_bases( const struct_typet &type, std::list &vbases) const @@ -1873,18 +1669,6 @@ void cpp_typecheckt::get_virtual_bases( } } -/*******************************************************************\ - -Function: cpp_typecheckt::subtype_typecast - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - bool cpp_typecheckt::subtype_typecast( const struct_typet &from, const struct_typet &to) const @@ -1899,18 +1683,6 @@ bool cpp_typecheckt::subtype_typecast( return bases.find(to.get(ID_name))!=bases.end(); } -/*******************************************************************\ - -Function: cpp_typecheckt::make_ptr_subtypecast - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::make_ptr_typecast( exprt &expr, const typet &dest_type) diff --git a/src/cpp/cpp_typecheck_constructor.cpp b/src/cpp/cpp_typecheck_constructor.cpp index 01cc9ca7123..cfc645c5cb2 100644 --- a/src/cpp/cpp_typecheck_constructor.cpp +++ b/src/cpp/cpp_typecheck_constructor.cpp @@ -6,28 +6,22 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + +#include "cpp_typecheck.h" + #include #include #include -#include +#include -#include "cpp_typecheck.h" #include "cpp_util.h" -/*******************************************************************\ - -Function: copy_parent - - Inputs: parent_base_name: base name of typechecked parent - block: non-typechecked block - - Outputs: generate code to copy the parent - - Purpose: - -\*******************************************************************/ - +/// \param parent_base_name: base name of typechecked parent +/// \param block: non-typechecked block +/// \return generate code to copy the parent static void copy_parent( const source_locationt &source_location, const irep_idt &parent_base_name, @@ -66,19 +60,9 @@ static void copy_parent( op1.add_source_location()=source_location; } -/*******************************************************************\ - -Function: copy_member - - Inputs: member_base_name: name of a member - block: non-typechecked block - - Outputs: generate code to copy the member - - Purpose: - -\*******************************************************************/ - +/// \param member_base_name: name of a member +/// \param block: non-typechecked block +/// \return generate code to copy the member static void copy_member( const source_locationt &source_location, const irep_idt &member_base_name, @@ -120,20 +104,10 @@ static void copy_member( op1.add_source_location()=source_location; } -/*******************************************************************\ - -Function: copy_array - - Inputs: member_base_name: name of array member - index: index to copy - block: non-typechecked block - - Outputs: generate code to copy the member - - Purpose: - -\*******************************************************************/ - +/// \param member_base_name: name of array member +/// \param index: index to copy +/// \param block: non-typechecked block +/// \return generate code to copy the member static void copy_array( const source_locationt &source_location, const irep_idt &member_base_name, @@ -182,18 +156,7 @@ static void copy_array( op1.add_source_location()=source_location; } -/*******************************************************************\ - -Function: cpp_typecheckt::default_ctor - - Inputs: - - Outputs: - - Purpose: Generate code for implicit default constructors - -\*******************************************************************/ - +/// Generate code for implicit default constructors void cpp_typecheckt::default_ctor( const source_locationt &source_location, const irep_idt &base_name, @@ -222,18 +185,7 @@ void cpp_typecheckt::default_ctor( ctor.add_source_location()=source_location; } -/*******************************************************************\ - -Function: cpp_typecheckt::default_cpctor - - Inputs: - - Outputs: - - Purpose: Generate code for implicit default copy constructor - -\*******************************************************************/ - +/// Generate code for implicit default copy constructor void cpp_typecheckt::default_cpctor( const symbolt &symbol, cpp_declarationt &cpctor) const @@ -402,19 +354,7 @@ void cpp_typecheckt::default_cpctor( } } -/*******************************************************************\ - -Function: cpp_typecheckt::default_assignop - - Inputs: - - Outputs: - - Purpose: Generate declarartion of the implicit default assignment - operator - -\*******************************************************************/ - +/// Generate declaration of the implicit default assignment operator void cpp_typecheckt::default_assignop( const symbolt &symbol, cpp_declarationt &cpctor) @@ -488,18 +428,7 @@ void cpp_typecheckt::default_assignop( args_decl_declor.value().make_nil(); } -/*******************************************************************\ - -Function: cpp_typecheckt::default_assignop_value - - Inputs: - - Outputs: - - Purpose: Generate code for the implicit default assignment operator - -\*******************************************************************/ - +/// Generate code for the implicit default assignment operator void cpp_typecheckt::default_assignop_value( const symbolt &symbol, cpp_declaratort &declarator) @@ -553,7 +482,7 @@ void cpp_typecheckt::default_assignop_value( if(size_expr.id()==ID_infinity) { // error().source_location=object); - // err << "cannot copy array of infinite size" << std::endl; + // err << "cannot copy array of infinite size\n"; // throw 0; continue; } @@ -580,24 +509,13 @@ void cpp_typecheckt::default_assignop_value( ret_code.type()=code_typet(); } -/*******************************************************************\ - -Function: check_member_initializers - - Inputs: bases: the parents of the class - components: the components of the class - initializers: the constructor initializers - - Outputs: If an invalid initializer is found, then - the method outputs an error message and - throws a 0 exception. - - Purpose: Check a constructor initialization-list. - An initalizer has to be a data member declared - in this class or a direct-parent constructor. - -\*******************************************************************/ - +/// Check a constructor initialization-list. An initializer has to be a data +/// member declared in this class or a direct-parent constructor. +/// \param bases: the parents of the class +/// \param components: the components of the class +/// \param initializers: the constructor initializers +/// \return If an invalid initializer is found, then the method outputs an error +/// message and throws a 0 exception. void cpp_typecheckt::check_member_initializers( const irept &bases, const struct_typet::componentst &components, @@ -726,23 +644,14 @@ void cpp_typecheckt::check_member_initializers( } } -/*******************************************************************\ - -Function: full_member_initialization - - Inputs: struct_union_type: the class/struct/union - initializers: the constructor initializers - - Outputs: initializers is updated. - - Purpose: Build the full initialization list of the constructor. - First, all the direct-parent constructors are called. - Second, all the non-pod data members are initialized. - - Note: The initialization order follows the decalration order. - -\*******************************************************************/ - +/// Build the full initialization list of the constructor. First, all the +/// direct-parent constructors are called. Second, all the non-pod data members +/// are initialized. +/// +/// Note: The initialization order follows the declaration order. +/// \param struct_union_type: the class/struct/union +/// \param initializers: the constructor initializers +/// \return initializers is updated. void cpp_typecheckt::full_member_initialization( const struct_union_typet &struct_union_type, irept &initializers) @@ -801,7 +710,7 @@ void cpp_typecheckt::full_member_initialization( const irept &bases=struct_union_type.find(ID_bases); - // Subsequenlty, we need to call the non-POD parent constructors + // Subsequently, we need to call the non-POD parent constructors forall_irep(parent_it, bases.get_sub()) { assert(parent_it->id()==ID_base); @@ -1006,23 +915,8 @@ void cpp_typecheckt::full_member_initialization( initializers.swap(final_initializers); } -/*******************************************************************\ - -Function: find_cpctor - - Inputs: typechecked compound symbol - - Outputs: return true if a copy constructor is found - - Note: - "A non-template constructor for class X is a copy constructor - if its first parameter is of type X&, const X&, volatile X& - or const volatile X&, and either there are no other parameters - or else all other parameters have default arguments (8.3.6).106) - [Example: X::X(const X&) and X::X(X&, int=1) are copy constructors." - -\*******************************************************************/ - +/// \par parameters: typechecked compound symbol +/// \return return true if a copy constructor is found bool cpp_typecheckt::find_cpctor(const symbolt &symbol) const { const struct_typet &struct_type=to_struct_type(symbol.type); @@ -1080,18 +974,6 @@ bool cpp_typecheckt::find_cpctor(const symbolt &symbol) const return false; } -/*******************************************************************\ - -Function: cpp_typecheckt::find_assignop - - Inputs: - - Outputs: - - Note: - -\*******************************************************************/ - bool cpp_typecheckt::find_assignop(const symbolt &symbol) const { const struct_typet &struct_type=to_struct_type(symbol.type); diff --git a/src/cpp/cpp_typecheck_conversions.cpp b/src/cpp/cpp_typecheck_conversions.cpp index 16d8e519741..f2c5d04f36f 100644 --- a/src/cpp/cpp_typecheck_conversions.cpp +++ b/src/cpp/cpp_typecheck_conversions.cpp @@ -6,6 +6,11 @@ Module: C++ Language Type Checking \*******************************************************************/ +/// \file +/// C++ Language Type Checking + +#include "cpp_typecheck.h" + #include #include @@ -15,39 +20,28 @@ Module: C++ Language Type Checking #include #include -#include - -#include "cpp_typecheck.h" - -/*******************************************************************\ - -Function: standard_conversion_lvalue_to_rvalue - - Inputs: A typechecked lvalue expression - - Outputs: True iff the lvalue-to-rvalue conversion is possible. - 'new_type' contains the result of the conversion. - - Purpose: Lvalue-to-rvalue conversion - - An lvalue (3.10) of a non-function, non-array type T can be - converted to an rvalue. If T is an incomplete type, a program - that necessitates this conversion is ill-formed. If the object - to which the lvalue refers is not an object of type T and is - not an object of a type derived from T, or if the object is - uninitialized, a program that necessitates this conversion has - undefined behavior. If T is a non-class type, the type of the - rvalue is the cv-unqualified version of T. Otherwise, the type of - the rvalue is T. - - The value contained in the object indicated by the lvalue - is the rvalue result. When an lvalue-to-rvalue conversion - occurs within the operand of sizeof (5.3.3) the value contained - in the referenced object is not accessed, since that operator - does not evaluate its operand. - -\*******************************************************************/ - +#include + +/// Lvalue-to-rvalue conversion +/// +/// An lvalue (3.10) of a non-function, non-array type T can be +/// converted to an rvalue. If T is an incomplete type, a program +/// that necessitates this conversion is ill-formed. If the object +/// to which the lvalue refers is not an object of type T and is +/// not an object of a type derived from T, or if the object is +/// uninitialized, a program that necessitates this conversion has +/// undefined behavior. If T is a non-class type, the type of the +/// rvalue is the cv-unqualified version of T. Otherwise, the type of +/// the rvalue is T. +/// +/// The value contained in the object indicated by the lvalue +/// is the rvalue result. When an lvalue-to-rvalue conversion +/// occurs within the operand of sizeof (5.3.3) the value contained +/// in the referenced object is not accessed, since that operator +/// does not evaluate its operand. +/// \par parameters: A typechecked lvalue expression +/// \return True iff the lvalue-to-rvalue conversion is possible. 'new_type' +/// contains the result of the conversion. bool cpp_typecheckt::standard_conversion_lvalue_to_rvalue( const exprt &expr, exprt &new_expr) const @@ -65,91 +59,54 @@ bool cpp_typecheckt::standard_conversion_lvalue_to_rvalue( return true; } -/*******************************************************************\ - -Function: standard_conversion_array_to_pointer - - Inputs: An array expression - - Outputs: True iff the array-to-pointer conversion is possible. - The result of the conversion is stored in 'new_expr'. - - Purpose: Array-to-pointer conversion - - An lvalue or rvalue of type "array of N T" or "array of unknown - bound of T" can be converted to an rvalue of type "pointer to T." - The result is a pointer to the first element of the array. - -\*******************************************************************/ - +/// Array-to-pointer conversion +/// +/// An lvalue or rvalue of type "array of N T" or "array of unknown +/// bound of T" can be converted to an rvalue of type "pointer to T." +/// The result is a pointer to the first element of the array. +/// \par parameters: An array expression +/// \return True iff the array-to-pointer conversion is possible. The result of +/// the conversion is stored in 'new_expr'. bool cpp_typecheckt::standard_conversion_array_to_pointer( const exprt &expr, exprt &new_expr) const { assert(expr.type().id()==ID_array); - exprt index(ID_index, expr.type().subtype()); - index.copy_to_operands(expr, from_integer(0, index_type())); - index.set(ID_C_lvalue, true); + index_exprt index( + expr, + from_integer(0, index_type())); - pointer_typet pointer; - pointer.subtype()=expr.type().subtype(); + index.set(ID_C_lvalue, true); - new_expr=exprt(ID_address_of, pointer); - new_expr.move_to_operands(index); + new_expr=address_of_exprt(index); return true; } -/*******************************************************************\ - -Function: standard_conversion_function_to_pointer - - Inputs: A function expression - - Outputs: True iff the array-to-pointer conversion is possible. - The result of the conversion is stored in 'new_expr'. - - - Purpose: Function-to-pointer conversion - - An lvalue of function type T can be converted to an rvalue of type - "pointer to T." The result is a pointer to the function.50) - -\*******************************************************************/ - +/// Function-to-pointer conversion +/// +/// An lvalue of function type T can be converted to an rvalue of type +/// "pointer to T." The result is a pointer to the function.50) +/// \par parameters: A function expression +/// \return True iff the array-to-pointer conversion is possible. The result of +/// the conversion is stored in 'new_expr'. bool cpp_typecheckt::standard_conversion_function_to_pointer( const exprt &expr, exprt &new_expr) const { - const code_typet &func_type=to_code_type(expr.type()); - if(!expr.get_bool(ID_C_lvalue)) return false; - pointer_typet pointer; - pointer.subtype()=func_type; - - new_expr=exprt(ID_address_of); - new_expr.copy_to_operands(expr); - new_expr.type()=pointer; + new_expr=address_of_exprt(expr); return true; } -/*******************************************************************\ - -Function: standard_conversion_qualification - - Inputs: A typechecked expression 'expr', a destination - type 'type' - - Outputs: True iff the qualification conversion is possible. - The result of the conversion is stored in 'new_expr'. - - Purpose: Qualification conversion - -\*******************************************************************/ - +/// Qualification conversion +/// \par parameters: A typechecked expression 'expr', a destination +/// type 'type' +/// \return True iff the qualification conversion is possible. The result of the +/// conversion is stored in 'new_expr'. bool cpp_typecheckt::standard_conversion_qualification( const exprt &expr, const typet &type, @@ -203,40 +160,31 @@ bool cpp_typecheckt::standard_conversion_qualification( return false; } -/*******************************************************************\ - -Function: standard_conversion_integral_promotion - - Inputs: A typechecked expression 'expr' - - Outputs: True iff the integral pormotion is possible. - The result of the conversion is stored in 'new_expr'. - - Purpose: Integral-promotion conversion - - An rvalue of type char, signed char, unsigned char, short int, - or unsigned short int can be converted to an rvalue of type int - if int can represent all the values of the source type; otherwise, - the source rvalue can be converted to an rvalue of type unsigned int. - - An rvalue of type wchar_t (3.9.1) or an enumeration type (7.2) can - be converted to an rvalue of the first of the following types that - can represent all the values of its underlying type: int, unsigned int, - long, or unsigned long. - - An rvalue for an integral bit-field (9.6) can be converted - to an rvalue of type int if int can represent all the values of the - bit-field; otherwise, it can be converted to unsigned int if - unsigned int can represent all the values of the bit-field. - If the bit-field is larger yet, no integral promotion applies to - it. If the bit-field has an enumerated type, it is treated as - any other value of that type for promotion purposes. - - An rvalue of type bool can be converted to an rvalue of type int, - with false becoming zero and true becoming one. - -\*******************************************************************/ - +/// Integral-promotion conversion +/// +/// An rvalue of type char, signed char, unsigned char, short int, +/// or unsigned short int can be converted to an rvalue of type int +/// if int can represent all the values of the source type; otherwise, +/// the source rvalue can be converted to an rvalue of type unsigned int. +/// +/// An rvalue of type wchar_t (3.9.1) or an enumeration type (7.2) can +/// be converted to an rvalue of the first of the following types that +/// can represent all the values of its underlying type: int, unsigned int, +/// long, or unsigned long. +/// +/// An rvalue for an integral bit-field (9.6) can be converted +/// to an rvalue of type int if int can represent all the values of the +/// bit-field; otherwise, it can be converted to unsigned int if +/// unsigned int can represent all the values of the bit-field. +/// If the bit-field is larger yet, no integral promotion applies to +/// it. If the bit-field has an enumerated type, it is treated as +/// any other value of that type for promotion purposes. +/// +/// An rvalue of type bool can be converted to an rvalue of type int, +/// with false becoming zero and true becoming one. +/// \par parameters: A typechecked expression 'expr' +/// \return True iff the integral promotion is possible. The result of the +/// conversion is stored in 'new_expr'. bool cpp_typecheckt::standard_conversion_integral_promotion( const exprt &expr, exprt &new_expr) const @@ -282,22 +230,13 @@ bool cpp_typecheckt::standard_conversion_integral_promotion( return false; } -/*******************************************************************\ - -Function: standard_conversion_floating_point_promotion - - Inputs: A typechecked expression 'expr' - - Outputs: True iff the integral promotion is possible. - The result of the conversion is stored in 'new_expr'. - - Purpose: Floating-point-promotion conversion - - An rvalue of type float can be converted to an rvalue of type - double. The value is unchanged. - -\*******************************************************************/ - +/// Floating-point-promotion conversion +/// +/// An rvalue of type float can be converted to an rvalue of type +/// double. The value is unchanged. +/// \par parameters: A typechecked expression 'expr' +/// \return True iff the integral promotion is possible. The result of the +/// conversion is stored in 'new_expr'. bool cpp_typecheckt::standard_conversion_floating_point_promotion( const exprt &expr, exprt &new_expr) const @@ -325,43 +264,34 @@ bool cpp_typecheckt::standard_conversion_floating_point_promotion( return true; } -/*******************************************************************\ - -Function: standard_conversion_integral_conversion - - Inputs: A typechecked expression 'expr', a destination - type 'type' - - Outputs: True iff the integral pormotion is possible. - The result of the conversion is stored in 'new_expr'. - - Purpose: Integral conversion - - An rvalue of type char, signed char, unsigned char, short int, - An rvalue of an integer type can be converted to an rvalue of - another integer type. An rvalue of an enumeration type can be - converted to an rvalue of an integer type. - - If the destination type is unsigned, the resulting value is the - least unsigned integer congruent to the source integer (modulo - 2n where n is the number of bits used to represent the unsigned - type). [Note: In a two's complement representation, this - conversion is conceptual and there is no change in the bit - pattern (if there is no truncation). ] - - If the destination type is signed, the value is unchanged if it - can be represented in the destination type (and bit-field width); - otherwise, the value is implementation-defined. - - If the destination type is bool, see 4.12. If the source type is - bool, the value false is converted to zero and the value true is - converted to one. - - The conversions allowed as integral promotions are excluded from - the set of integral conversions. - -\*******************************************************************/ - +/// Integral conversion +/// +/// An rvalue of type char, signed char, unsigned char, short int, +/// An rvalue of an integer type can be converted to an rvalue of +/// another integer type. An rvalue of an enumeration type can be +/// converted to an rvalue of an integer type. +/// +/// If the destination type is unsigned, the resulting value is the +/// least unsigned integer congruent to the source integer (modulo +/// 2n where n is the number of bits used to represent the unsigned +/// type). [Note: In a two's complement representation, this +/// conversion is conceptual and there is no change in the bit +/// pattern (if there is no truncation). ] +/// +/// If the destination type is signed, the value is unchanged if it +/// can be represented in the destination type (and bit-field width); +/// otherwise, the value is implementation-defined. +/// +/// If the destination type is bool, see 4.12. If the source type is +/// bool, the value false is converted to zero and the value true is +/// converted to one. +/// +/// The conversions allowed as integral promotions are excluded from +/// the set of integral conversions. +/// \par parameters: A typechecked expression 'expr', a destination +/// type 'type' +/// \return True iff the integral promotion is possible. The result of the +/// conversion is stored in 'new_expr'. bool cpp_typecheckt::standard_conversion_integral_conversion( const exprt &expr, const typet &type, @@ -389,34 +319,25 @@ bool cpp_typecheckt::standard_conversion_integral_conversion( return true; } -/*******************************************************************\ - -Function: standard_conversion_floating_integral_conversion - - Inputs: A typechecked expression 'expr' - - Outputs: True iff the conversion is possible. - The result of the conversion is stored in 'new_expr'. - - Purpose: Floating-integral conversion - - An rvalue of a floating point type can be converted to an rvalue - of an integer type. The conversion truncates; that is, the - fractional part is discarded. The behavior is undefined if the - truncated value cannot be represented in the destination type. - [Note: If the destination type is bool, see 4.12. ] - - An rvalue of an integer type or of an enumeration type can be - converted to an rvalue of a floating point type. The result is - exact if possible. Otherwise, it is an implementation-defined - choice of either the next lower or higher representable value. - [Note: loss of precision occurs if the integral value cannot be - represented exactly as a value of the floating type. ] If the - source type is bool, the value false is converted to zero and the - value true is converted to one. - -\*******************************************************************/ - +/// Floating-integral conversion +/// +/// An rvalue of a floating point type can be converted to an rvalue +/// of an integer type. The conversion truncates; that is, the +/// fractional part is discarded. The behavior is undefined if the +/// truncated value cannot be represented in the destination type. +/// [Note: If the destination type is bool, see 4.12. ] +/// +/// An rvalue of an integer type or of an enumeration type can be +/// converted to an rvalue of a floating point type. The result is +/// exact if possible. Otherwise, it is an implementation-defined +/// choice of either the next lower or higher representable value. +/// [Note: loss of precision occurs if the integral value cannot be +/// represented exactly as a value of the floating type. ] If the +/// source type is bool, the value false is converted to zero and the +/// value true is converted to one. +/// \par parameters: A typechecked expression 'expr' +/// \return True iff the conversion is possible. The result of the conversion is +/// stored in 'new_expr'. bool cpp_typecheckt::standard_conversion_floating_integral_conversion( const exprt &expr, const typet &type, @@ -453,31 +374,22 @@ bool cpp_typecheckt::standard_conversion_floating_integral_conversion( } -/*******************************************************************\ - -Function: standard_conversion_floating_point_conversion - - Inputs: A typechecked expression 'expr', a destination - type 'type' - - Outputs: True iff the floating-point conversion is possible. - The result of the conversion is stored in 'new_expr'. - - Purpose: Floating-point conversion - - An rvalue of floating point type can be converted to an rvalue - of another floating point type. If the source value can be exactly - represented in the destination type, the result of the conversion - is that exact representation. If the source value is between two - adjacent destination values, the result of the conversion is an - implementation-defined choice of either of those values. Otherwise, - the behavior is undefined. - - The conversions allowed as floating point promotions are excluded - from the set of floating point conversions. - -\*******************************************************************/ - +/// Floating-point conversion +/// +/// An rvalue of floating point type can be converted to an rvalue +/// of another floating point type. If the source value can be exactly +/// represented in the destination type, the result of the conversion +/// is that exact representation. If the source value is between two +/// adjacent destination values, the result of the conversion is an +/// implementation-defined choice of either of those values. Otherwise, +/// the behavior is undefined. +/// +/// The conversions allowed as floating point promotions are excluded +/// from the set of floating point conversions. +/// \par parameters: A typechecked expression 'expr', a destination +/// type 'type' +/// \return True iff the floating-point conversion is possible. The result of +/// the conversion is stored in 'new_expr'. bool cpp_typecheckt::standard_conversion_floating_point_conversion( const exprt &expr, const typet &type, @@ -504,47 +416,38 @@ bool cpp_typecheckt::standard_conversion_floating_point_conversion( return true; } -/*******************************************************************\ - -Function: standard_conversion_pointer - - Inputs: A typechecked expression 'expr', a destination - type 'type' - - Outputs: True iff the pointer conversion is possible. - The result of the conversion is stored in 'new_expr'. - - Purpose: Pointer conversion - - A null pointer constant is an integral constant expression - (5.19) rvalue of integer type that evaluates to zero. A null - pointer constant can be converted to a pointer type; the result - is the null pointer value of that type and is distinguishable - from every other value of pointer to object or pointer to - function type. Two null pointer values of the same type shall - compare equal. The conversion of a null pointer constant to a - pointer to cv-qualified type is a single conversion, and not the - sequence of a pointer conversion followed by a qualification - conversion (4.4). - - An rvalue of type "pointer to cv T," where T is an object type, - can be converted to an rvalue of type "pointer to cv void." The - result of converting a "pointer to cv T" to a "pointer to cv - void" points to the start of the storage location where the - object of type T resides, as if the object is a most derived - object (1.8) of type T (that is, not a base class subobject). - - An rvalue of type "pointer to cv D," where D is a class type, - can be converted to an rvalue of type "pointer to cv B," where - B is a base class (clause 10) of D. If B is an inaccessible - (clause 11) or ambiguous (10.2) base class of D, a program that - necessitates this conversion is ill-formed. The result of the - conversion is a pointer to the base class sub-object of the - derived class object. The null pointer value is converted to - the null pointer value of the destination type. - -\*******************************************************************/ - +/// Pointer conversion +/// +/// A null pointer constant is an integral constant expression +/// (5.19) rvalue of integer type that evaluates to zero. A null +/// pointer constant can be converted to a pointer type; the result +/// is the null pointer value of that type and is distinguishable +/// from every other value of pointer to object or pointer to +/// function type. Two null pointer values of the same type shall +/// compare equal. The conversion of a null pointer constant to a +/// pointer to cv-qualified type is a single conversion, and not the +/// sequence of a pointer conversion followed by a qualification +/// conversion (4.4). +/// +/// An rvalue of type "pointer to cv T," where T is an object type, +/// can be converted to an rvalue of type "pointer to cv void." The +/// result of converting a "pointer to cv T" to a "pointer to cv +/// void" points to the start of the storage location where the +/// object of type T resides, as if the object is a most derived +/// object (1.8) of type T (that is, not a base class subobject). +/// +/// An rvalue of type "pointer to cv D," where D is a class type, +/// can be converted to an rvalue of type "pointer to cv B," where +/// B is a base class (clause 10) of D. If B is an inaccessible +/// (clause 11) or ambiguous (10.2) base class of D, a program that +/// necessitates this conversion is ill-formed. The result of the +/// conversion is a pointer to the base class sub-object of the +/// derived class object. The null pointer value is converted to +/// the null pointer value of the destination type. +/// \par parameters: A typechecked expression 'expr', a destination +/// type 'type' +/// \return True iff the pointer conversion is possible. The result of the +/// conversion is stored in 'new_expr'. bool cpp_typecheckt::standard_conversion_pointer( const exprt &expr, const typet &type, @@ -611,46 +514,36 @@ bool cpp_typecheckt::standard_conversion_pointer( return false; } -/*******************************************************************\ - -Function: standard_conversion_pointer_to_member - - Inputs: A typechecked expression 'expr', a destination - type 'type' - - Outputs: True iff the pointer-to-member conversion is possible. - The result of the conversion is stored in 'new_expr'. - - - Purpose: Pointer-to-member conversion - - A null pointer constant (4.10) can be converted to a pointer to - member type; the result is the null member pointer value of that - type and is distinguishable from any pointer to member not created - from a null pointer constant. Two null member pointer values of - the same type shall compare equal. The conversion of a null pointer - constant to a pointer to member of cv-qualified type is a single - conversion, and not the sequence of a pointer to member conversion - followed by a qualification conversion (4.4). - - An rvalue of type "pointer to member of B of type cv T," where B - is a class type, can be converted to an rvalue of type "pointer - to member of D of type cv T," where D is a derived class - (clause 10) of B. If B is an inaccessible (clause 11), ambiguous - (10.2) or virtual (10.1) base class of D, a program that - necessitates this conversion is ill-formed. The result of the - conversion refers to the same member as the pointer to member - before the conversion took place, but it refers to the base class - member as if it were a member of the derived class. The result - refers to the member in D"s instance of B. Since the result has - type "pointer to member of D of type cv T," it can be dereferenced - with a D object. The result is the same as if the pointer to - member of B were dereferenced with the B sub-object of D. The null - member pointer value is converted to the null member pointer value - of the destination type.52) - -\*******************************************************************/ - +/// Pointer-to-member conversion +/// +/// A null pointer constant (4.10) can be converted to a pointer to +/// member type; the result is the null member pointer value of that +/// type and is distinguishable from any pointer to member not created +/// from a null pointer constant. Two null member pointer values of +/// the same type shall compare equal. The conversion of a null pointer +/// constant to a pointer to member of cv-qualified type is a single +/// conversion, and not the sequence of a pointer to member conversion +/// followed by a qualification conversion (4.4). +/// +/// An rvalue of type "pointer to member of B of type cv T," where B +/// is a class type, can be converted to an rvalue of type "pointer +/// to member of D of type cv T," where D is a derived class +/// (clause 10) of B. If B is an inaccessible (clause 11), ambiguous +/// (10.2) or virtual (10.1) base class of D, a program that +/// necessitates this conversion is ill-formed. The result of the +/// conversion refers to the same member as the pointer to member +/// before the conversion took place, but it refers to the base class +/// member as if it were a member of the derived class. The result +/// refers to the member in D"s instance of B. Since the result has +/// type "pointer to member of D of type cv T," it can be dereferenced +/// with a D object. The result is the same as if the pointer to +/// member of B were dereferenced with the B sub-object of D. The null +/// member pointer value is converted to the null member pointer value +/// of the destination type.52) +/// \par parameters: A typechecked expression 'expr', a destination +/// type 'type' +/// \return True iff the pointer-to-member conversion is possible. The result of +/// the conversion is stored in 'new_expr'. bool cpp_typecheckt::standard_conversion_pointer_to_member( const exprt &expr, const typet &type, @@ -672,13 +565,13 @@ bool cpp_typecheckt::standard_conversion_pointer_to_member( expr.type().subtype().id()==ID_code) { code_typet code1=to_code_type(expr.type().subtype()); - assert(code1.parameters().size()>0); + assert(!code1.parameters().empty()); code_typet::parametert this1=code1.parameters()[0]; assert(this1.get(ID_C_base_name)==ID_this); code1.parameters().erase(code1.parameters().begin()); code_typet code2=to_code_type(type.subtype()); - assert(code2.parameters().size()>0); + assert(!code2.parameters().empty()); code_typet::parametert this2=code2.parameters()[0]; assert(this2.get(ID_C_base_name)==ID_this); code2.parameters().erase(code2.parameters().begin()); @@ -724,25 +617,15 @@ bool cpp_typecheckt::standard_conversion_pointer_to_member( return false; } -/*******************************************************************\ - -Function: standard_conversion_boolean - - Inputs: A typechecked expression 'expr' - - Outputs: True iff the boolean conversion is possible. - The result of the conversion is stored in 'new_expr'. - - - Purpose: Boolean conversion - - An rvalue of arithmetic, enumeration, pointer, or pointer to - member type can be converted to an rvalue of type bool. - A zero value, null pointer value, or null member pointer value is - converted to false; any other value is converted to true. - -\*******************************************************************/ - +/// Boolean conversion +/// +/// An rvalue of arithmetic, enumeration, pointer, or pointer to +/// member type can be converted to an rvalue of type bool. +/// A zero value, null pointer value, or null member pointer value is +/// converted to false; any other value is converted to true. +/// \par parameters: A typechecked expression 'expr' +/// \return True iff the boolean conversion is possible. The result of the +/// conversion is stored in 'new_expr'. bool cpp_typecheckt::standard_conversion_boolean( const exprt &expr, exprt &new_expr) const { @@ -766,37 +649,26 @@ bool cpp_typecheckt::standard_conversion_boolean( return true; } -/*******************************************************************\ - -Function: standard_conversion_sequence - - Inputs: A typechecked expression 'expr', a destination - type 'type'. - - Outputs: True iff a standard conversion sequence exists. - The result of the conversion is stored in 'new_expr'. - The reference 'rank' is incremented. - - - Purpose: Standard Conversion Sequence - - A standard conversion sequence is a sequence of standard conversions - in the following order: - - * Zero or one conversion from the following set: lvalue-to-rvalue - conversion, array-to-pointer conversion, and function-to-pointer - conversion. - - * Zero or one conversion from the following set: integral - promotions, floating point promotion, integral conversions, - floating point conversions, floating-integral conversions, - pointer conversions, pointer to member conversions, and boolean - conversions. - - * Zero or one qualification conversion. - -\*******************************************************************/ - +/// Standard Conversion Sequence +/// +/// A standard conversion sequence is a sequence of standard conversions +/// in the following order: +/// +/// * Zero or one conversion from the following set: lvalue-to-rvalue +/// conversion, array-to-pointer conversion, and function-to-pointer +/// conversion. +/// +/// * Zero or one conversion from the following set: integral +/// promotions, floating point promotion, integral conversions, +/// floating point conversions, floating-integral conversions, +/// pointer conversions, pointer to member conversions, and boolean +/// conversions. +/// +/// * Zero or one qualification conversion. +/// \par parameters: A typechecked expression 'expr', a destination +/// type 'type'. +/// \return True iff a standard conversion sequence exists. The result of the +/// conversion is stored in 'new_expr'. The reference 'rank' is incremented. bool cpp_typecheckt::standard_conversion_sequence( const exprt &expr, const typet &type, @@ -962,20 +834,11 @@ bool cpp_typecheckt::standard_conversion_sequence( return true; } -/*******************************************************************\ - -Function: user_defined_conversion_sequence - - Inputs: A typechecked expression 'expr', a destination - type 'type'. - - Outputs: True iff a user-defined conversion sequence exists. - The result of the conversion is stored in 'new_expr'. - - Purpose: User-defined conversion sequence - -\*******************************************************************/ - +/// User-defined conversion sequence +/// \par parameters: A typechecked expression 'expr', a destination +/// type 'type'. +/// \return True iff a user-defined conversion sequence exists. The result of +/// the conversion is stored in 'new_expr'. bool cpp_typecheckt::user_defined_conversion_sequence( const exprt &expr, const typet &type, @@ -1015,16 +878,13 @@ bool cpp_typecheckt::user_defined_conversion_sequence( if(subtype_typecast(from_struct, to_struct)) { - exprt address(ID_address_of, pointer_typet()); - address.copy_to_operands(expr); - address.type().subtype()=expr.type(); + exprt address=address_of_exprt(expr); // simplify address if(expr.id()==ID_dereference) address=expr.op0(); - pointer_typet ptr_sub; - ptr_sub.subtype()=type; + pointer_typet ptr_sub=pointer_type(type); c_qualifierst qual_from; qual_from.read(expr.type()); qual_from.write(ptr_sub.subtype()); @@ -1147,62 +1007,60 @@ bool cpp_typecheckt::user_defined_conversion_sequence( } else if(from_struct.is_not_nil() && arg1_struct.is_not_nil()) { - // try derived-to-base conversion - exprt expr_pfrom(ID_address_of, pointer_typet()); - expr_pfrom.type().subtype()=expr.type(); - expr_pfrom.copy_to_operands(expr); - - pointer_typet pto; - pto.subtype()=arg1_type; - - exprt expr_ptmp; - tmp_rank=0; - if(standard_conversion_sequence( - expr_pfrom, pto, expr_ptmp, tmp_rank)) + // try derived-to-base conversion + address_of_exprt expr_pfrom(expr, pointer_type(expr.type())); + pointer_typet pto=pointer_type(arg1_type); + + exprt expr_ptmp; + tmp_rank=0; + if(standard_conversion_sequence( + expr_pfrom, pto, expr_ptmp, tmp_rank)) + { + // check if it's ambiguous + if(found) + return false; + found=true; + + rank+=tmp_rank; + + // create temporary object + exprt expr_deref= + exprt(ID_dereference, expr_ptmp.type().subtype()); + expr_deref.set(ID_C_lvalue, true); + expr_deref.copy_to_operands(expr_ptmp); + expr_deref.add_source_location()=expr.source_location(); + + exprt new_object("new_object", type); + new_object.set(ID_C_lvalue, true); + new_object.type().set(ID_C_constant, false); + + exprt func_symb=cpp_symbol_expr(lookup(component.get(ID_name))); + func_symb.type()=comp_type; { - // check if it's ambiguous - if(found) - return false; - found=true; - - rank+=tmp_rank; - - // create temporary object - exprt expr_deref= - exprt(ID_dereference, expr_ptmp.type().subtype()); - expr_deref.set(ID_C_lvalue, true); - expr_deref.copy_to_operands(expr_ptmp); - expr_deref.add_source_location()=expr.source_location(); - - exprt new_object("new_object", type); - new_object.set(ID_C_lvalue, true); - new_object.type().set(ID_C_constant, false); - - exprt func_symb=cpp_symbol_expr(lookup(component.get(ID_name))); - func_symb.type()=comp_type; - { - exprt tmp("already_typechecked"); - tmp.copy_to_operands(func_symb); - func_symb.swap(func_symb); - } - - side_effect_expr_function_callt ctor_expr; - ctor_expr.add_source_location()=expr.source_location(); - ctor_expr.function().swap(func_symb); - ctor_expr.arguments().push_back(expr_deref); - typecheck_side_effect_function_call(ctor_expr); - - new_expr.swap(ctor_expr); - - assert(new_expr.get(ID_statement)==ID_temporary_object); - - if(to.get_bool(ID_C_constant)) - new_expr.type().set(ID_C_constant, true); + exprt tmp("already_typechecked"); + tmp.copy_to_operands(func_symb); + func_symb.swap(func_symb); } + + side_effect_expr_function_callt ctor_expr; + ctor_expr.add_source_location()=expr.source_location(); + ctor_expr.function().swap(func_symb); + ctor_expr.arguments().push_back(expr_deref); + typecheck_side_effect_function_call(ctor_expr); + + new_expr.swap(ctor_expr); + + INVARIANT( + new_expr.get(ID_statement)==ID_temporary_object, + "statement ID"); + + if(to.get_bool(ID_C_constant)) + new_expr.type().set(ID_C_constant, true); } } - if(found) - return true; + } + if(found) + return true; } } @@ -1282,20 +1140,10 @@ bool cpp_typecheckt::user_defined_conversion_sequence( return new_expr.is_not_nil(); } -/*******************************************************************\ - -Function: reference_related - - Inputs: A typechecked expression 'expr', - a reference 'type'. - - Outputs: True iff an the reference 'type' is reference-related - to 'expr'. - - Purpose: Reference-related - -\*******************************************************************/ - +/// Reference-related +/// \par parameters: A typechecked expression 'expr', +/// a reference 'type'. +/// \return True iff an the reference 'type' is reference-related to 'expr'. bool cpp_typecheckt::reference_related( const exprt &expr, const typet &type) const @@ -1329,20 +1177,10 @@ bool cpp_typecheckt::reference_related( return false; } -/*******************************************************************\ - -Function: reference_compatible - - Inputs: A typechecked expression 'expr', a - reference 'type'. - - Outputs: True iff an the reference 'type' is reference-compatible - to 'expr'. - - Purpose: Reference-compatible - -\*******************************************************************/ - +/// Reference-compatible +/// \par parameters: A typechecked expression 'expr', a +/// reference 'type'. +/// \return True iff an the reference 'type' is reference-compatible to 'expr'. bool cpp_typecheckt::reference_compatible( const exprt &expr, const typet &type, @@ -1372,50 +1210,40 @@ bool cpp_typecheckt::reference_compatible( return false; } -/*******************************************************************\ - -Function: reference_binding - - Inputs: A typechecked expression 'expr', a - reference 'type'. - - Outputs: True iff an the reference can be bound to the expression. - The result of the conversion is stored in 'new_expr'. - - - Purpose: Reference binding - - When a parameter of reference type binds directly (8.5.3) to an - argument expression, the implicit conversion sequence is the - identity conversion, unless the argument expression has a type - that is a derived class of the parameter type, in which case the - implicit conversion sequence is a derived-to-base Conversion - (13.3.3.1). - - If the parameter binds directly to the result of applying a - conversion function to the argument expression, the implicit - conversion sequence is a user-defined conversion sequence - (13.3.3.1.2), with the second standard conversion sequence - either an identity conversion or, if the conversion function - returns an entity of a type that is a derived class of the - parameter type, a derived-to-base Conversion. - - When a parameter of reference type is not bound directly to - an argument expression, the conversion sequence is the one - required to convert the argument expression to the underlying - type of the reference according to 13.3.3.1. Conceptually, this - conversion sequence corresponds to copy-initializing a temporary - of the underlying type with the argument expression. Any - difference in top-level cv-qualification is subsumed by the - initialization itself and does not constitute a conversion. - - A standard conversion sequence cannot be formed if it requires - binding a reference to non-const to an rvalue (except when - binding an implicit object parameter; see the special rules - for that case in 13.3.1). - -\*******************************************************************/ - +/// Reference binding +/// +/// When a parameter of reference type binds directly (8.5.3) to an +/// argument expression, the implicit conversion sequence is the +/// identity conversion, unless the argument expression has a type +/// that is a derived class of the parameter type, in which case the +/// implicit conversion sequence is a derived-to-base Conversion +/// (13.3.3.1). +/// +/// If the parameter binds directly to the result of applying a +/// conversion function to the argument expression, the implicit +/// conversion sequence is a user-defined conversion sequence +/// (13.3.3.1.2), with the second standard conversion sequence +/// either an identity conversion or, if the conversion function +/// returns an entity of a type that is a derived class of the +/// parameter type, a derived-to-base Conversion. +/// +/// When a parameter of reference type is not bound directly to +/// an argument expression, the conversion sequence is the one +/// required to convert the argument expression to the underlying +/// type of the reference according to 13.3.3.1. Conceptually, this +/// conversion sequence corresponds to copy-initializing a temporary +/// of the underlying type with the argument expression. Any +/// difference in top-level cv-qualification is subsumed by the +/// initialization itself and does not constitute a conversion. +/// +/// A standard conversion sequence cannot be formed if it requires +/// binding a reference to non-const to an rvalue (except when +/// binding an implicit object parameter; see the special rules +/// for that case in 13.3.1). +/// \par parameters: A typechecked expression 'expr', a +/// reference 'type'. +/// \return True iff an the reference can be bound to the expression. The result +/// of the conversion is stored in 'new_expr'. bool cpp_typecheckt::reference_binding( exprt expr, const typet &type, @@ -1455,9 +1283,8 @@ bool cpp_typecheckt::reference_binding( address_of_exprt tmp; tmp.add_source_location()=expr.source_location(); tmp.object()=expr; - tmp.type()=pointer_typet(); + tmp.type()=pointer_type(tmp.op0().type()); tmp.type().set(ID_C_reference, true); - tmp.type().subtype()=tmp.op0().type(); new_expr.swap(tmp); } @@ -1569,7 +1396,7 @@ bool cpp_typecheckt::reference_binding( type.subtype().get_bool(ID_C_volatile)) return false; - // TODO: hanlde the case for implicit parameters + // TODO: handle the case for implicit parameters if(!type.subtype().get_bool(ID_C_constant) && !expr.get_bool(ID_C_lvalue)) return false; @@ -1585,10 +1412,9 @@ bool cpp_typecheckt::reference_binding( if(user_defined_conversion_sequence(arg_expr, type.subtype(), new_expr, rank)) { address_of_exprt tmp; - tmp.type()=pointer_typet(); + tmp.type()=pointer_type(new_expr.type()); tmp.object()=new_expr; tmp.type().set(ID_C_reference, true); - tmp.type().subtype()= new_expr.type(); tmp.add_source_location()=new_expr.source_location(); new_expr.swap(tmp); return true; @@ -1607,33 +1433,23 @@ bool cpp_typecheckt::reference_binding( new_expr.swap(tmp); } - exprt tmp(ID_address_of, pointer_typet()); - tmp.copy_to_operands(new_expr); + address_of_exprt tmp(new_expr, pointer_type(new_expr.type())); tmp.type().set(ID_C_reference, true); - tmp.type().subtype()= new_expr.type(); tmp.add_source_location()=new_expr.source_location(); - new_expr.swap(tmp); + + new_expr=tmp; return true; } return false; } -/*******************************************************************\ - -Function: implicit_conversion_sequence - - Inputs: A typechecked expression 'expr', a destination - type 'type'. - - Outputs: True iff an implicit conversion sequence exists. - The result of the conversion is stored in 'new_expr'. - The rank of the sequence is stored in 'rank' - - Purpose: implicit conversion sequence - -\*******************************************************************/ - +/// implicit conversion sequence +/// \par parameters: A typechecked expression 'expr', a destination +/// type 'type'. +/// \return True iff an implicit conversion sequence exists. The result of the +/// conversion is stored in 'new_expr'. The rank of the sequence is stored in +/// 'rank' bool cpp_typecheckt::implicit_conversion_sequence( const exprt &expr, const typet &type, @@ -1671,20 +1487,11 @@ bool cpp_typecheckt::implicit_conversion_sequence( return true; } -/*******************************************************************\ - -Function: implicit_conversion_sequence - - Inputs: A typechecked expression 'expr', a destination - type 'type'. - - Outputs: True iff an implicit conversion sequence exists. - The result of the conversion is stored in 'new_expr'. - - Purpose: implicit conversion sequence - -\*******************************************************************/ - +/// implicit conversion sequence +/// \par parameters: A typechecked expression 'expr', a destination +/// type 'type'. +/// \return True iff an implicit conversion sequence exists. The result of the +/// conversion is stored in 'new_expr'. bool cpp_typecheckt::implicit_conversion_sequence( const exprt &expr, const typet &type, @@ -1694,22 +1501,11 @@ bool cpp_typecheckt::implicit_conversion_sequence( return implicit_conversion_sequence(expr, type, new_expr, rank); } -/*******************************************************************\ - -Function: implicit_conversion_sequence - - Inputs: A typechecked expression 'expr', a destination - type 'type'. - - Outputs: True iff an implicit conversion sequence exists. - The rank of the sequence is stored in 'rank' - - - Purpose: implicit conversion sequence - - -\*******************************************************************/ - +/// implicit conversion sequence +/// \par parameters: A typechecked expression 'expr', a destination +/// type 'type'. +/// \return True iff an implicit conversion sequence exists. The rank of the +/// sequence is stored in 'rank' bool cpp_typecheckt::implicit_conversion_sequence( const exprt &expr, const typet &type, @@ -1719,18 +1515,6 @@ bool cpp_typecheckt::implicit_conversion_sequence( return implicit_conversion_sequence(expr, type, new_expr, rank); } -/*******************************************************************\ - -Function: cpp_typecheck_baset::implicit_typecast - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::implicit_typecast(exprt &expr, const typet &type) { exprt e=expr; @@ -1743,68 +1527,55 @@ void cpp_typecheckt::implicit_typecast(exprt &expr, const typet &type) << to_string(e.type()) << "' to `" << to_string(type) << "'" << eom; #if 0 - str << "\n " << follow(e.type()).pretty() << std::endl; - str << "\n " << type.pretty() << std::endl; + str << "\n " << follow(e.type()).pretty() << '\n'; + str << "\n " << type.pretty() << '\n'; #endif throw 0; } } -/*******************************************************************\ - -Function: cpp_typecheck_baset::reference_initializer - - Inputs: - - Outputs: - - Purpose: - - A reference to type "cv1 T1" is initialized by an expression of - type "cv2 T2" as follows: - - - If the initializer expression - - is an lvalue (but is not a bit-field), and "cv1 T1" is - reference-compatible with "cv2 T2," or - - has a class type (i.e., T2 is a class type) and can be - implicitly converted to an lvalue of type "cv3 T3," where - "cv1 T1" is reference-compatible with "cv3 T3" 92) (this - conversion is selected by enumerating the applicable conversion - functions (13.3.1.6) and choosing the best one through overload - resolution (13.3)), - - then the reference is bound directly to the initializer - expression lvalue in the first case, and the reference is - bound to the lvalue result of the conversion in the second - case. In these cases the reference is said to bind directly - to the initializer expression. - - - Otherwise, the reference shall be to a non-volatile const type - - If the initializer expression is an rvalue, with T2 a class - type, and "cv1 T1" is reference-compatible with "cv2 T2," the - reference is bound in one of the following ways (the choice is - implementation-defined): - - - The reference is bound to the object represented by the - rvalue (see 3.10) or to a sub-object within that object. - - - A temporary of type "cv1 T2" [sic] is created, and a - constructor is called to copy the entire rvalue object into - the temporary. The reference is bound to the temporary or - to a sub-object within the temporary. - - The constructor that would be used to make the copy shall be - callable whether or not the copy is actually done. - - Otherwise, a temporary of type "cv1 T1" is created and - initialized from the initializer expression using the rules for - a non-reference copy initialization (8.5). The reference is then - bound to the temporary. If T1 is reference-related to T2, cv1 - must be the same cv-qualification as, or greater cvqualification - than, cv2; otherwise, the program is ill-formed. - -\*******************************************************************/ - +/// A reference to type "cv1 T1" is initialized by an expression of +/// type "cv2 T2" as follows: +/// +/// - If the initializer expression +/// - is an lvalue (but is not a bit-field), and "cv1 T1" is +/// reference-compatible with "cv2 T2," or +/// - has a class type (i.e., T2 is a class type) and can be +/// implicitly converted to an lvalue of type "cv3 T3," where +/// "cv1 T1" is reference-compatible with "cv3 T3" 92) (this +/// conversion is selected by enumerating the applicable conversion +/// functions (13.3.1.6) and choosing the best one through overload +/// resolution (13.3)), +/// +/// then the reference is bound directly to the initializer +/// expression lvalue in the first case, and the reference is +/// bound to the lvalue result of the conversion in the second +/// case. In these cases the reference is said to bind directly +/// to the initializer expression. +/// +/// - Otherwise, the reference shall be to a non-volatile const type +/// - If the initializer expression is an rvalue, with T2 a class +/// type, and "cv1 T1" is reference-compatible with "cv2 T2," the +/// reference is bound in one of the following ways (the choice is +/// implementation-defined): +/// +/// - The reference is bound to the object represented by the +/// rvalue (see 3.10) or to a sub-object within that object. +/// +/// - A temporary of type "cv1 T2" [sic] is created, and a +/// constructor is called to copy the entire rvalue object into +/// the temporary. The reference is bound to the temporary or +/// to a sub-object within the temporary. +/// +/// The constructor that would be used to make the copy shall be +/// callable whether or not the copy is actually done. +/// +/// Otherwise, a temporary of type "cv1 T1" is created and +/// initialized from the initializer expression using the rules for +/// a non-reference copy initialization (8.5). The reference is then +/// bound to the temporary. If T1 is reference-related to T2, cv1 +/// must be the same cv-qualification as, or greater cvqualification +/// than, cv2; otherwise, the program is ill-formed. void cpp_typecheckt::reference_initializer( exprt &expr, const typet &type) @@ -1825,19 +1596,6 @@ void cpp_typecheckt::reference_initializer( throw 0; } -/*******************************************************************\ - -Function: cpp_typecheckt::cast_away_constness - - Inputs: - - Outputs: - - Purpose: - - -\*******************************************************************/ - bool cpp_typecheckt::cast_away_constness( const typet &t1, const typet &t2) const @@ -1901,18 +1659,6 @@ bool cpp_typecheckt::cast_away_constness( return !standard_conversion_qualification(e1, snt2.back(), e2); } -/*******************************************************************\ - -Function: cpp_typecheckt::const_typecast - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool cpp_typecheckt::const_typecast( const exprt &expr, const typet &type, @@ -1952,10 +1698,9 @@ bool cpp_typecheckt::const_typecast( if(new_expr.type()!=type.subtype()) return false; - exprt address_of(ID_address_of, type); - address_of.copy_to_operands(expr); + exprt address_of=address_of_exprt(expr, to_pointer_type(type)); add_implicit_dereference(address_of); - new_expr.swap(address_of); + new_expr=address_of; return true; } else if(type.id()==ID_pointer) @@ -1972,18 +1717,6 @@ bool cpp_typecheckt::const_typecast( return false; } -/*******************************************************************\ - -Function: cpp_typecheckt::dynamic_typecast - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool cpp_typecheckt::dynamic_typecast( const exprt &expr, const typet &type, @@ -2036,18 +1769,6 @@ bool cpp_typecheckt::dynamic_typecast( return static_typecast(e, type, new_expr); } -/*******************************************************************\ - -Function: cpp_typecheckt::reinterpret_typecastcast - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool cpp_typecheckt::reinterpret_typecast( const exprt &expr, const typet &type, @@ -2141,9 +1862,7 @@ bool cpp_typecheckt::reinterpret_typecast( if(is_reference(type) && e.get_bool(ID_C_lvalue)) { - exprt tmp(ID_address_of, pointer_typet()); - tmp.type().subtype()=e.type(); - tmp.copy_to_operands(e); + exprt tmp=address_of_exprt(e); tmp.make_typecast(type); new_expr.swap(tmp); return true; @@ -2152,18 +1871,6 @@ bool cpp_typecheckt::reinterpret_typecast( return false; } -/*******************************************************************\ - -Function: cpp_typecheckt::static_typecast - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool cpp_typecheckt::static_typecast( const exprt &expr, // source expression const typet &type, // destination type @@ -2219,10 +1926,8 @@ bool cpp_typecheckt::static_typecast( return true; } - exprt address_of(ID_address_of, pointer_typet()); - address_of.type().subtype()=e.type(); - address_of.copy_to_operands(e); - make_ptr_typecast(address_of , type); + exprt address_of=address_of_exprt(e); + make_ptr_typecast(address_of, type); new_expr.swap(address_of); return true; } diff --git a/src/cpp/cpp_typecheck_declaration.cpp b/src/cpp/cpp_typecheck_declaration.cpp index fd846d90c0d..c91c8d979cf 100644 --- a/src/cpp/cpp_typecheck_declaration.cpp +++ b/src/cpp/cpp_typecheck_declaration.cpp @@ -6,20 +6,12 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \********************************************************************/ -#include "cpp_typecheck.h" -#include "cpp_declarator_converter.h" - -/*******************************************************************\ - -Function: cpp_typecheckt::convert - - Inputs: +/// \file +/// C++ Language Type Checking - Outputs: - - Purpose: +#include "cpp_typecheck.h" -\*******************************************************************/ +#include "cpp_declarator_converter.h" void cpp_typecheckt::convert(cpp_declarationt &declaration) { @@ -44,18 +36,6 @@ void cpp_typecheckt::convert(cpp_declarationt &declaration) method_bodies.swap(old_method_bodies); } -/*******************************************************************\ - -Function: cpp_typecheckt::convert_anonymous_union - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::convert_anonymous_union( cpp_declarationt &declaration, codet &code) @@ -118,7 +98,7 @@ void cpp_typecheckt::convert_anonymous_union( } cpp_idt &id=cpp_scopes.current_scope().insert(base_name); - id.id_class = cpp_idt::SYMBOL; + id.id_class = cpp_idt::id_classt::SYMBOL; id.identifier=it->get(ID_name); id.class_identifier=union_symbol.name; id.is_member=true; @@ -130,18 +110,6 @@ void cpp_typecheckt::convert_anonymous_union( code.swap(new_code); } -/*******************************************************************\ - -Function: cpp_typecheckt::convert_non_template_declaration - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::convert_non_template_declaration( cpp_declarationt &declaration) { diff --git a/src/cpp/cpp_typecheck_destructor.cpp b/src/cpp/cpp_typecheck_destructor.cpp index 4b1be9ceeb4..b8038d5c01f 100644 --- a/src/cpp/cpp_typecheck_destructor.cpp +++ b/src/cpp/cpp_typecheck_destructor.cpp @@ -6,19 +6,10 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include "cpp_typecheck.h" - -/*******************************************************************\ - -Function: cpp_typecheckt::find_dtor - - Inputs: - - Outputs: - - Note: +/// \file +/// C++ Language Type Checking -\*******************************************************************/ +#include "cpp_typecheck.h" bool cpp_typecheckt::find_dtor(const symbolt &symbol) const { @@ -34,20 +25,7 @@ bool cpp_typecheckt::find_dtor(const symbolt &symbol) const return false; } -/*******************************************************************\ - -Function: default_dtor - - Inputs: - - Outputs: - - Purpose: - - Note: - -\*******************************************************************/ - +/// Note: void cpp_typecheckt::default_dtor( const symbolt &symbol, cpp_declarationt &dtor) @@ -77,20 +55,9 @@ void cpp_typecheckt::default_dtor( dtor.move_to_operands(decl); } -/*******************************************************************\ - -Function: cpp_typecheckt::dtor - - Inputs: - - Outputs: - - Purpose: produces destructor code for a class object - - Note: - -\*******************************************************************/ - +/// produces destructor code for a class object +/// +/// Note: codet cpp_typecheckt::dtor(const symbolt &symbol) { assert(symbol.type.id()==ID_struct || diff --git a/src/cpp/cpp_typecheck_enum_type.cpp b/src/cpp/cpp_typecheck_enum_type.cpp index 2e1bcf67172..74a18107622 100644 --- a/src/cpp/cpp_typecheck_enum_type.cpp +++ b/src/cpp/cpp_typecheck_enum_type.cpp @@ -6,25 +6,17 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - -#include -#include +/// \file +/// C++ Language Type Checking #include "cpp_typecheck.h" -#include "cpp_enum_type.h" - -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_enum_body - - Inputs: - Outputs: +#include - Purpose: +#include +#include -\*******************************************************************/ +#include "cpp_enum_type.h" void cpp_typecheckt::typecheck_enum_body(symbolt &enum_symbol) { @@ -83,24 +75,12 @@ void cpp_typecheckt::typecheck_enum_body(symbolt &enum_symbol) cpp_idt &scope_identifier= cpp_scopes.put_into_scope(*new_symbol); - scope_identifier.id_class=cpp_idt::SYMBOL; + scope_identifier.id_class=cpp_idt::id_classt::SYMBOL; ++i; } } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_enum_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_enum_type(typet &type) { // first save qualifiers @@ -212,7 +192,7 @@ void cpp_typecheckt::typecheck_enum_type(typet &type) cpp_idt &scope_identifier= cpp_scopes.put_into_scope(*new_symbol, dest_scope); - scope_identifier.id_class=cpp_idt::CLASS; + scope_identifier.id_class=cpp_idt::id_classt::CLASS; typecheck_enum_body(*new_symbol); } diff --git a/src/cpp/cpp_typecheck_expr.cpp b/src/cpp/cpp_typecheck_expr.cpp index 51b43cde996..88b26461482 100644 --- a/src/cpp/cpp_typecheck_expr.cpp +++ b/src/cpp/cpp_typecheck_expr.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + +#include "cpp_typecheck.h" + #include #include @@ -15,30 +20,17 @@ Author: Daniel Kroening, kroening@cs.cmu.edu #include #include -#include +#include #include #include #include #include "cpp_type2name.h" -#include "cpp_typecheck.h" #include "cpp_convert_type.h" #include "cpp_exception_id.h" #include "expr2cpp.h" -/*******************************************************************\ - -Function: cpp_typecheckt::find_parent - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - bool cpp_typecheckt::find_parent( const symbolt &symb, const irep_idt &base_name, @@ -56,18 +48,7 @@ bool cpp_typecheckt::find_parent( return false; } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_expr_main - -Inputs: - -Outputs: - -Purpose: Called after the operands are done - -\*******************************************************************/ - +/// Called after the operands are done void cpp_typecheckt::typecheck_expr_main(exprt &expr) { if(expr.id()==ID_cpp_name) @@ -89,22 +70,22 @@ void cpp_typecheckt::typecheck_expr_main(exprt &expr) else if(expr.is_nil()) { #if 0 - std::cerr << "cpp_typecheckt::typecheck_expr_main got nil" << std::endl; + std::cerr << "cpp_typecheckt::typecheck_expr_main got nil\n"; #endif abort(); } else if(expr.id()==ID_code) { #if 0 - std::cerr << "cpp_typecheckt::typecheck_expr_main got code" << std::endl; + std::cerr << "cpp_typecheckt::typecheck_expr_main got code\n"; #endif abort(); } else if(expr.id()==ID_symbol) { #if 0 - std::cout << "E: " << expr.pretty() << std::endl; - std::cerr << "cpp_typecheckt::typecheck_expr_main got symbol" << std::endl; + std::cout << "E: " << expr.pretty() << '\n'; + std::cerr << "cpp_typecheckt::typecheck_expr_main got symbol\n"; abort(); #endif } @@ -156,18 +137,6 @@ void cpp_typecheckt::typecheck_expr_main(exprt &expr) c_typecheck_baset::typecheck_expr_main(expr); } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_expr_trinary - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_expr_trinary(if_exprt &expr) { assert(expr.operands().size()==3); @@ -329,18 +298,6 @@ void cpp_typecheckt::typecheck_expr_trinary(if_exprt &expr) return; } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_expr_member - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_expr_member(exprt &expr) { typecheck_expr_member( @@ -348,18 +305,6 @@ void cpp_typecheckt::typecheck_expr_member(exprt &expr) cpp_typecheck_fargst()); } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_expr_sizeof - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_expr_sizeof(exprt &expr) { // We need to overload, "sizeof-expression" can be mis-parsed @@ -379,7 +324,7 @@ void cpp_typecheckt::typecheck_expr_sizeof(exprt &expr) exprt symbol_expr=resolve( to_cpp_name(static_cast(type)), - cpp_typecheck_resolvet::BOTH, + cpp_typecheck_resolvet::wantt::BOTH, fargs); if(symbol_expr.id()!=ID_type) @@ -398,7 +343,7 @@ void cpp_typecheckt::typecheck_expr_sizeof(exprt &expr) exprt symbol_expr=resolve( to_cpp_name(static_cast(type.subtype())), - cpp_typecheck_resolvet::BOTH, + cpp_typecheck_resolvet::wantt::BOTH, fargs); if(symbol_expr.id()!=ID_type) @@ -415,35 +360,11 @@ void cpp_typecheckt::typecheck_expr_sizeof(exprt &expr) c_typecheck_baset::typecheck_expr_sizeof(expr); } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_expr_ptrmember - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_expr_ptrmember(exprt &expr) { typecheck_expr_ptrmember(expr, cpp_typecheck_fargst()); } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_function_expr - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_function_expr( exprt &expr, const cpp_typecheck_fargst &fargs) @@ -500,18 +421,6 @@ void cpp_typecheckt::typecheck_function_expr( typecheck_expr(expr); } -/*******************************************************************\ - -Function: cpp_typecheckt::overloadable - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - bool cpp_typecheckt::overloadable(const exprt &expr) { // at least one argument must have class or enumerated type @@ -532,18 +441,6 @@ bool cpp_typecheckt::overloadable(const exprt &expr) return false; } -/*******************************************************************\ - -Function: cpp_typecheckt::operator_is_overloaded - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - struct operator_entryt { const irep_idt id; @@ -574,7 +471,7 @@ struct operator_entryt { ID_notequal, "!=" }, { ID_dereference, "*" }, { ID_ptrmember, "->" }, - { irep_idt(), NULL } + { irep_idt(), nullptr } }; bool cpp_typecheckt::operator_is_overloaded(exprt &expr) @@ -608,7 +505,7 @@ bool cpp_typecheckt::operator_is_overloaded(exprt &expr) cpp_name.get_sub().back().set(ID_identifier, op_name); cpp_name.get_sub().back().add(ID_C_source_location)=expr.source_location(); - // See if the struct decalares the cast operator as a member + // See if the struct declares the cast operator as a member bool found_in_struct=false; assert(!expr.operands().empty()); typet t0(follow(expr.op0().type())); @@ -675,7 +572,7 @@ bool cpp_typecheckt::operator_is_overloaded(exprt &expr) } for(const operator_entryt *e=operators; - e->id!=irep_idt(); + !e->id.empty(); e++) if(expr.id()==e->id) { @@ -725,7 +622,7 @@ bool cpp_typecheckt::operator_is_overloaded(exprt &expr) // should really be a qualified search exprt resolve_result=resolve( - cpp_name, cpp_typecheck_resolvet::VAR, fargs, false); + cpp_name, cpp_typecheck_resolvet::wantt::VAR, fargs, false); if(resolve_result.is_not_nil()) { @@ -767,7 +664,7 @@ bool cpp_typecheckt::operator_is_overloaded(exprt &expr) fargs.in_use=true; exprt resolve_result=resolve( - cpp_name, cpp_typecheck_resolvet::VAR, fargs, false); + cpp_name, cpp_typecheck_resolvet::wantt::VAR, fargs, false); if(resolve_result.is_not_nil()) { @@ -802,18 +699,6 @@ bool cpp_typecheckt::operator_is_overloaded(exprt &expr) return false; } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_expr_address_of - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_expr_address_of(exprt &expr) { if(expr.operands().size()!=1) @@ -837,9 +722,7 @@ void cpp_typecheckt::typecheck_expr_address_of(exprt &expr) // we take the address of the method. assert(expr.op0().id()==ID_member); exprt symb=cpp_symbol_expr(lookup(expr.op0().get(ID_component_name))); - exprt address(ID_address_of, typet(ID_pointer)); - address.copy_to_operands(symb); - address.type().subtype()=symb.type(); + address_of_exprt address(symb, pointer_type(symb.type())); address.set(ID_C_implicit, true); expr.op0().swap(address); } @@ -872,21 +755,9 @@ void cpp_typecheckt::typecheck_expr_address_of(exprt &expr) const bool is_ref=is_reference(expr.type()); c_typecheck_baset::typecheck_expr_address_of(expr); if(is_ref) - expr.type()=reference_typet(expr.type().subtype()); + expr.type()=reference_type(expr.type().subtype()); } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_expr_throw - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_expr_throw(exprt &expr) { // these are of type void @@ -913,18 +784,6 @@ void cpp_typecheckt::typecheck_expr_throw(exprt &expr) } } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_expr_new - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_expr_new(exprt &expr) { // next, find out if we do an array @@ -949,8 +808,8 @@ void cpp_typecheckt::typecheck_expr_new(exprt &expr) expr.set(ID_size, to_array_type(expr.type()).size()); // new actually returns a pointer, not an array - pointer_typet ptr_type; - ptr_type.subtype()=expr.type().subtype(); + pointer_typet ptr_type= + pointer_type(expr.type().subtype()); expr.type().swap(ptr_type); } else @@ -960,8 +819,7 @@ void cpp_typecheckt::typecheck_expr_new(exprt &expr) expr.set(ID_statement, ID_cpp_new); - pointer_typet ptr_type; - ptr_type.subtype().swap(expr.type()); + pointer_typet ptr_type=pointer_type(expr.type()); expr.type().swap(ptr_type); } @@ -1002,18 +860,6 @@ void cpp_typecheckt::typecheck_expr_new(exprt &expr) sizeof_expr.add("#c_sizeof_type")=expr.type().subtype(); } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_expr_explicit_typecast - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - static exprt collect_comma_expression(const exprt &src) { exprt result; @@ -1063,7 +909,7 @@ void cpp_typecheckt::typecheck_expr_explicit_typecast(exprt &expr) exprt symbol_expr=resolve( to_cpp_name(static_cast(expr.type())), - cpp_typecheck_resolvet::TYPE, + cpp_typecheck_resolvet::wantt::TYPE, fargs, false); // fail silently @@ -1116,18 +962,6 @@ void cpp_typecheckt::typecheck_expr_explicit_typecast(exprt &expr) } } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_expr_explicit_constructor_call - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_expr_explicit_constructor_call(exprt &expr) { typecheck_type(expr.type()); @@ -1150,18 +984,6 @@ void cpp_typecheckt::typecheck_expr_explicit_constructor_call(exprt &expr) } } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_expr_this - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_expr_this(exprt &expr) { if(cpp_scopes.current_scope().class_identifier.empty()) @@ -1181,18 +1003,6 @@ void cpp_typecheckt::typecheck_expr_this(exprt &expr) expr.add_source_location()=source_location; } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_expr_delete - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_expr_delete(exprt &expr) { if(expr.operands().size()!=1) @@ -1250,39 +1060,15 @@ void cpp_typecheckt::typecheck_expr_delete(exprt &expr) expr.set(ID_destructor, destructor_code); } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_expr_typecast - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_expr_typecast(exprt &expr) { // should not be called #if 0 - std::cout << "E: " << expr.pretty() << std::endl; + std::cout << "E: " << expr.pretty() << '\n'; assert(0); #endif } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_expr_member - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_expr_member( exprt &expr, const cpp_typecheck_fargst &fargs) @@ -1356,7 +1142,7 @@ void cpp_typecheckt::typecheck_expr_member( exprt symbol_expr=resolve( component_cpp_name, - cpp_typecheck_resolvet::VAR, + cpp_typecheck_resolvet::wantt::VAR, new_fargs); if(symbol_expr.id()==ID_dereference) @@ -1464,18 +1250,6 @@ void cpp_typecheckt::typecheck_expr_member( } } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_expr_ptrmember - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_expr_ptrmember( exprt &expr, const cpp_typecheck_fargst &fargs) @@ -1514,18 +1288,6 @@ void cpp_typecheckt::typecheck_expr_ptrmember( typecheck_expr_member(expr, fargs); } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_cast_expr - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_cast_expr(exprt &expr) { side_effect_expr_function_callt e = @@ -1635,18 +1397,6 @@ void cpp_typecheckt::typecheck_cast_expr(exprt &expr) expr.swap(new_expr); } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_expr_cpp_name - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_expr_cpp_name( exprt &expr, const cpp_typecheck_fargst &fargs) @@ -1679,7 +1429,7 @@ void cpp_typecheckt::typecheck_expr_cpp_name( // http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Atomic-Builtins.html // adjust return type of function to match pointer subtype - if(fargs.operands.size()<1) + if(fargs.operands.empty()) { error().source_location=source_location; error() << "__sync_* primitives take as least one argument" @@ -2097,7 +1847,7 @@ void cpp_typecheckt::typecheck_expr_cpp_name( exprt symbol_expr= resolve( to_cpp_name(expr), - cpp_typecheck_resolvet::VAR, + cpp_typecheck_resolvet::wantt::VAR, fargs); // we want VAR @@ -2147,18 +1897,6 @@ void cpp_typecheckt::typecheck_expr_cpp_name( add_implicit_dereference(expr); } -/*******************************************************************\ - -Function: cpp_typecheckt::add_implicit_dereference - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::add_implicit_dereference(exprt &expr) { if(is_reference(expr.type())) @@ -2173,18 +1911,6 @@ void cpp_typecheckt::add_implicit_dereference(exprt &expr) } } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_side_effect_function_call - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_side_effect_function_call( side_effect_expr_function_callt &expr) { @@ -2247,7 +1973,7 @@ void cpp_typecheckt::typecheck_side_effect_function_call( else { error().source_location=expr.source_location(); - error() << "zero or one argument excpected" << eom; + error() << "zero or one argument expected" << eom; throw 0; } @@ -2291,7 +2017,7 @@ void cpp_typecheckt::typecheck_side_effect_function_call( assert(bound.type().id()==ID_pointer); expr.arguments().insert(expr.arguments().begin(), bound); - // we don't need the object anymore + // we don't need the object any more expr.function().type().remove("#bound"); } @@ -2372,7 +2098,7 @@ void cpp_typecheckt::typecheck_side_effect_function_call( vtentry_member.swap(tmp); } - // Typcheck the expresssion as if it was not virtual + // Typecheck the expression as if it was not virtual // (add the this pointer) expr.type()= @@ -2526,11 +2252,9 @@ void cpp_typecheckt::typecheck_side_effect_function_call( if(operand.type().id()!=ID_pointer && operand.type()==argument.type().subtype()) { - exprt tmp(ID_address_of, typet(ID_pointer)); - tmp.type().subtype()=operand.type(); + address_of_exprt tmp(operand, pointer_type(operand.type())); tmp.add_source_location()=operand.source_location(); - tmp.move_to_operands(operand); - operand.swap(tmp); + operand=tmp; } } } @@ -2549,18 +2273,8 @@ void cpp_typecheckt::typecheck_side_effect_function_call( expr.swap(tmp); } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_function_call_arguments - - Inputs: type-checked arguments, type-checked function - - Outputs: type-adjusted function arguments - -Purpose: - -\*******************************************************************/ - +/// \param type:checked arguments, type-checked function +/// \return type-adjusted function arguments void cpp_typecheckt::typecheck_function_call_arguments( side_effect_expr_function_callt &expr) { @@ -2614,18 +2328,6 @@ void cpp_typecheckt::typecheck_function_call_arguments( c_typecheck_baset::typecheck_function_call_arguments(expr); } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_expr_side_effect - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_expr_side_effect( side_effect_exprt &expr) { @@ -2660,18 +2362,6 @@ void cpp_typecheckt::typecheck_expr_side_effect( c_typecheck_baset::typecheck_expr_side_effect(expr); } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_method_application - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_method_application( side_effect_expr_function_callt &expr) { @@ -2732,18 +2422,6 @@ void cpp_typecheckt::typecheck_method_application( } } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_side_effect_assignment - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_side_effect_assignment(side_effect_exprt &expr) { if(expr.operands().size()!=2) @@ -2831,18 +2509,6 @@ void cpp_typecheckt::typecheck_side_effect_assignment(side_effect_exprt &expr) expr=new_expr; } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_side_effect_inc_dec - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_side_effect_inc_dec( side_effect_exprt &expr) { @@ -2919,18 +2585,6 @@ void cpp_typecheckt::typecheck_side_effect_inc_dec( expr.swap(new_expr); } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_expr_dereference - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_expr_dereference(exprt &expr) { if(expr.operands().size()!=1) @@ -2955,18 +2609,6 @@ void cpp_typecheckt::typecheck_expr_dereference(exprt &expr) c_typecheck_baset::typecheck_expr_dereference(expr); } -/*******************************************************************\ - -Function: cpp_typecheckt::convert_pmop - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::convert_pmop(exprt &expr) { assert(expr.id()=="pointer-to-member"); @@ -3024,10 +2666,7 @@ void cpp_typecheckt::convert_pmop(exprt &expr) else { assert(expr.op0().get_bool(ID_C_lvalue)); - exprt address_of(ID_address_of, typet(ID_pointer)); - address_of.copy_to_operands(expr.op0()); - address_of.type().subtype()=address_of.op0().type(); - expr.op0().swap(address_of); + expr.op0()=address_of_exprt(expr.op0()); } } @@ -3037,18 +2676,6 @@ void cpp_typecheckt::convert_pmop(exprt &expr) return; } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_expr_function_identifier - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_expr_function_identifier(exprt &expr) { if(expr.id()==ID_symbol) @@ -3068,18 +2695,6 @@ void cpp_typecheckt::typecheck_expr_function_identifier(exprt &expr) c_typecheck_baset::typecheck_expr_function_identifier(expr); } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_expr - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_expr(exprt &expr) { bool override_constantness= @@ -3102,18 +2717,6 @@ void cpp_typecheckt::typecheck_expr(exprt &expr) expr.type().set(ID_C_constant, false); } -/*******************************************************************\ - -Function: cpp_typecheckt::explict_typecast_ambiguity - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::explicit_typecast_ambiguity(exprt &expr) { // There is an ambiguity in the C++ grammar as follows: @@ -3141,7 +2744,7 @@ void cpp_typecheckt::explicit_typecast_ambiguity(exprt &expr) exprt resolve_result= resolve( to_cpp_name(expr.type()), - cpp_typecheck_resolvet::BOTH, + cpp_typecheck_resolvet::wantt::BOTH, cpp_typecheck_fargst()); if(resolve_result.id()!=ID_type) @@ -3169,18 +2772,6 @@ void cpp_typecheckt::explicit_typecast_ambiguity(exprt &expr) } } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_expr_binary_arithmetic - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_expr_binary_arithmetic(exprt &expr) { if(expr.operands().size()!=2) @@ -3197,35 +2788,11 @@ void cpp_typecheckt::typecheck_expr_binary_arithmetic(exprt &expr) c_typecheck_baset::typecheck_expr_binary_arithmetic(expr); } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_expr_index - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_expr_index(exprt &expr) { c_typecheck_baset::typecheck_expr_index(expr); } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_expr_comma - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_expr_comma(exprt &expr) { if(expr.operands().size()!=2) @@ -3243,18 +2810,6 @@ void cpp_typecheckt::typecheck_expr_comma(exprt &expr) c_typecheck_baset::typecheck_expr_comma(expr); } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_expr_rel - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_expr_rel(binary_relation_exprt &expr) { c_typecheck_baset::typecheck_expr_rel(expr); diff --git a/src/cpp/cpp_typecheck_fargs.cpp b/src/cpp/cpp_typecheck_fargs.cpp index 592c538fc2c..6f6f905c327 100644 --- a/src/cpp/cpp_typecheck_fargs.cpp +++ b/src/cpp/cpp_typecheck_fargs.cpp @@ -6,27 +6,19 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + +#include "cpp_typecheck_fargs.h" + #include #include #include -#include "cpp_typecheck_fargs.h" #include "cpp_typecheck.h" -/*******************************************************************\ - -Function: cpp_typecheck_fargst::has_class_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool cpp_typecheck_fargst::has_class_type() const { for(exprt::operandst::const_iterator it=operands.begin(); @@ -40,18 +32,6 @@ bool cpp_typecheck_fargst::has_class_type() const return false; } -/*******************************************************************\ - -Function: cpp_typecheck_fargst::build - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheck_fargst::build( const side_effect_expr_function_callt &function_call) { @@ -64,18 +44,6 @@ void cpp_typecheck_fargst::build( operands.push_back(function_call.op1().operands()[i]); } -/*******************************************************************\ - -Function: cpp_typecheck_fargst::exact_match - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool cpp_typecheck_fargst::match( const code_typet &code_type, unsigned &distance, @@ -129,7 +97,7 @@ bool cpp_typecheck_fargst::match( #if 0 // unclear, todo if(is_reference(operand.type())) - std::cout << "O: " << operand.pretty() << std::endl; + std::cout << "O: " << operand.pretty() << '\n'; assert(!is_reference(operand.type())); #endif @@ -148,7 +116,7 @@ bool cpp_typecheck_fargst::match( #if 0 std::cout << "C: " << cpp_typecheck.to_string(operand.type()) << " -> " << cpp_typecheck.to_string(parameter.type()) - << std::endl; + << '\n'; #endif // can we do the standard conversion sequence? @@ -158,13 +126,13 @@ bool cpp_typecheck_fargst::match( // ok distance+=rank; #if 0 - std::cout << "OK " << rank << std::endl; + std::cout << "OK " << rank << '\n'; #endif } else { #if 0 - std::cout << "NOT OK" << std::endl; + std::cout << "NOT OK\n"; #endif return false; // no conversion possible } diff --git a/src/cpp/cpp_typecheck_fargs.h b/src/cpp/cpp_typecheck_fargs.h index 370cc10ed65..fac18356d7f 100644 --- a/src/cpp/cpp_typecheck_fargs.h +++ b/src/cpp/cpp_typecheck_fargs.h @@ -6,12 +6,16 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + #ifndef CPROVER_CPP_CPP_TYPECHECK_FARGS_H #define CPROVER_CPP_CPP_TYPECHECK_FARGS_H #include class cpp_typecheckt; +class code_typet; class cpp_typecheck_fargst // for function overloading { diff --git a/src/cpp/cpp_typecheck_function.cpp b/src/cpp/cpp_typecheck_function.cpp index a55bbf41d6b..06739870df6 100644 --- a/src/cpp/cpp_typecheck_function.cpp +++ b/src/cpp/cpp_typecheck_function.cpp @@ -6,25 +6,17 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + +#include "cpp_typecheck.h" + #include #include "cpp_template_type.h" -#include "cpp_typecheck.h" #include "cpp_type2name.h" #include "cpp_util.h" -/*******************************************************************\ - -Function: cpp_typecheckt::convert_parameter - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::convert_parameter( const irep_idt &mode, code_typet::parametert ¶meter) @@ -69,18 +61,6 @@ void cpp_typecheckt::convert_parameter( cpp_scopes.put_into_scope(*new_symbol); } -/*******************************************************************\ - -Function: cpp_typecheckt::convert_parameters - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::convert_parameters( const irep_idt &mode, code_typet &function_type) @@ -95,18 +75,6 @@ void cpp_typecheckt::convert_parameters( convert_parameter(mode, *it); } -/*******************************************************************\ - -Function: cpp_typecheckt::convert_function - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::convert_function(symbolt &symbol) { code_typet &function_type= @@ -171,18 +139,7 @@ void cpp_typecheckt::convert_function(symbolt &symbol) return_type = old_return_type; } -/*******************************************************************\ - -Function: cpp_typecheckt::function_identifier - - Inputs: - - Outputs: - - Purpose: for function overloading - -\*******************************************************************/ - +/// for function overloading irep_idt cpp_typecheckt::function_identifier(const typet &type) { const code_typet &function_type= diff --git a/src/cpp/cpp_typecheck_initializer.cpp b/src/cpp/cpp_typecheck_initializer.cpp index ef19cba6050..e492a170cbf 100644 --- a/src/cpp/cpp_typecheck_initializer.cpp +++ b/src/cpp/cpp_typecheck_initializer.cpp @@ -6,28 +6,21 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + +#include "cpp_typecheck.h" + #include #include #include -#include +#include #include -#include "cpp_typecheck.h" #include "cpp_util.h" -/*******************************************************************\ - -Function: cpp_typecheckt::convert_initializer - - Inputs: - - Outputs: - - Purpose: Initialize an object with a value - -\*******************************************************************/ - +/// Initialize an object with a value void cpp_typecheckt::convert_initializer(symbolt &symbol) { // this is needed for template arguments that are types @@ -110,7 +103,7 @@ void cpp_typecheckt::convert_initializer(symbolt &symbol) exprt resolved_expr=resolve( to_cpp_name(static_cast(symbol.value.op0())), - cpp_typecheck_resolvet::BOTH, fargs); + cpp_typecheck_resolvet::wantt::BOTH, fargs); assert(symbol.type.subtype() == resolved_expr.type()); @@ -179,18 +172,6 @@ void cpp_typecheckt::convert_initializer(symbolt &symbol) } } -/*******************************************************************\ - -Function: cpp_typecheckt::zero_initializer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::zero_initializer( const exprt &object, const typet &type, diff --git a/src/cpp/cpp_typecheck_linkage_spec.cpp b/src/cpp/cpp_typecheck_linkage_spec.cpp index 39ebc12db29..a21a5913979 100644 --- a/src/cpp/cpp_typecheck_linkage_spec.cpp +++ b/src/cpp/cpp_typecheck_linkage_spec.cpp @@ -6,19 +6,10 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include "cpp_typecheck.h" - -/*******************************************************************\ - -Function: cpp_typecheckt::convert - - Inputs: +/// \file +/// C++ Language Type Checking - Outputs: - - Purpose: - -\*******************************************************************/ +#include "cpp_typecheck.h" void cpp_typecheckt::convert(cpp_linkage_spect &linkage_spec) { diff --git a/src/cpp/cpp_typecheck_method_bodies.cpp b/src/cpp/cpp_typecheck_method_bodies.cpp index 0b16bebd8d8..5e134f79558 100644 --- a/src/cpp/cpp_typecheck_method_bodies.cpp +++ b/src/cpp/cpp_typecheck_method_bodies.cpp @@ -6,21 +6,11 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking #include "cpp_typecheck.h" -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_method_bodies - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_method_bodies( method_bodiest &bodies) { diff --git a/src/cpp/cpp_typecheck_namespace.cpp b/src/cpp/cpp_typecheck_namespace.cpp index 81fea3a3eae..c3ae770ad90 100644 --- a/src/cpp/cpp_typecheck_namespace.cpp +++ b/src/cpp/cpp_typecheck_namespace.cpp @@ -6,21 +6,12 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include +/// \file +/// C++ Language Type Checking #include "cpp_typecheck.h" -/*******************************************************************\ - -Function: cpp_typecheckt::convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void cpp_typecheckt::convert(cpp_namespace_spect &namespace_spec) { diff --git a/src/cpp/cpp_typecheck_resolve.cpp b/src/cpp/cpp_typecheck_resolve.cpp index 47628c9f3f7..0b49853f5fd 100644 --- a/src/cpp/cpp_typecheck_resolve.cpp +++ b/src/cpp/cpp_typecheck_resolve.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + +#include "cpp_typecheck_resolve.h" + #include #include @@ -14,46 +19,22 @@ Author: Daniel Kroening, kroening@cs.cmu.edu #include #include -#include +#include #include #include #include "cpp_typecheck.h" -#include "cpp_typecheck_resolve.h" #include "cpp_template_type.h" #include "cpp_type2name.h" #include "cpp_util.h" #include "cpp_convert_type.h" -/*******************************************************************\ - -Function: cpp_typecheck_resolvet::cpp_typecheck_resolvet - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - cpp_typecheck_resolvet::cpp_typecheck_resolvet(cpp_typecheckt &_cpp_typecheck): - cpp_typecheck(_cpp_typecheck) + cpp_typecheck(_cpp_typecheck), + original_scope(nullptr) // set in resolve_scope() { } -/*******************************************************************\ - -Function: cpp_typecheck_resolvet::convert_identifiers - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheck_resolvet::convert_identifiers( const cpp_scopest::id_sett &id_set, const wantt want, @@ -78,18 +59,6 @@ void cpp_typecheck_resolvet::convert_identifiers( } } -/*******************************************************************\ - -Function: cpp_typecheck_resolvet::apply_template_args - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheck_resolvet::apply_template_args( resolve_identifierst &identifiers, const cpp_template_args_non_tct &template_args, @@ -116,18 +85,7 @@ void cpp_typecheck_resolvet::apply_template_args( } } -/*******************************************************************\ - -Function: cpp_typecheck_resolvet::guess_function_template_args - -Inputs: - -Outputs: - -Purpose: guess arguments of function templates - -\*******************************************************************/ - +/// guess arguments of function templates void cpp_typecheck_resolvet::guess_function_template_args( resolve_identifierst &identifiers, const cpp_typecheck_fargst &fargs) @@ -179,18 +137,6 @@ void cpp_typecheck_resolvet::guess_function_template_args( } } -/*******************************************************************\ - -Function: cpp_typecheck_resolvet::remove_templates - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheck_resolvet::remove_templates( resolve_identifierst &identifiers) { @@ -207,18 +153,6 @@ void cpp_typecheck_resolvet::remove_templates( } } -/*******************************************************************\ - -Function: cpp_typecheck_resolvet::remove_duplicates - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheck_resolvet::remove_duplicates( resolve_identifierst &identifiers) { @@ -253,18 +187,6 @@ void cpp_typecheck_resolvet::remove_duplicates( } } -/*******************************************************************\ - -Function: cpp_typecheck_resolvet::convert_template_parameter - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - exprt cpp_typecheck_resolvet::convert_template_parameter( const cpp_idt &identifier) { @@ -286,24 +208,12 @@ exprt cpp_typecheck_resolvet::convert_template_parameter( return e; } -/*******************************************************************\ - -Function: cpp_typecheck_resolvet::convert_identifier - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - exprt cpp_typecheck_resolvet::convert_identifier( const cpp_idt &identifier, const wantt want, const cpp_typecheck_fargst &fargs) { - if(identifier.id_class==cpp_scopet::TEMPLATE_PARAMETER) + if(identifier.id_class==cpp_scopet::id_classt::TEMPLATE_PARAMETER) return convert_template_parameter(identifier); exprt e; @@ -329,11 +239,11 @@ exprt cpp_typecheck_resolvet::convert_identifier( const typet &type=component.type(); assert(type.is_not_nil()); - if(identifier.id_class==cpp_scopet::TYPEDEF) + if(identifier.id_class==cpp_scopet::id_classt::TYPEDEF) { e=type_exprt(type); } - else if(identifier.id_class==cpp_scopet::SYMBOL) + else if(identifier.id_class==cpp_scopet::id_classt::SYMBOL) { // A non-static, non-type member. // There has to be an object. @@ -348,7 +258,7 @@ exprt cpp_typecheck_resolvet::convert_identifier( std::cout << "I: " << identifier.class_identifier << " " << cpp_typecheck.cpp_scopes.current_scope(). - this_class_identifier << std::endl; + this_class_identifier << '\n'; #endif const exprt &this_expr= @@ -466,18 +376,6 @@ exprt cpp_typecheck_resolvet::convert_identifier( return e; } -/*******************************************************************\ - -Function: cpp_typecheck_resolvet::filter - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheck_resolvet::filter( resolve_identifierst &identifiers, const wantt want) @@ -494,15 +392,15 @@ void cpp_typecheck_resolvet::filter( switch(want) { - case TYPE: + case wantt::TYPE: match=(it->id()==ID_type); break; - case VAR: + case wantt::VAR: match=(it->id()!=ID_type); break; - case BOTH: + case wantt::BOTH: match=true; break; @@ -515,18 +413,6 @@ void cpp_typecheck_resolvet::filter( } } -/*******************************************************************\ - -Function: cpp_typecheck_resolvet::exact_match_functions - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheck_resolvet::exact_match_functions( resolve_identifierst &identifiers, const cpp_typecheck_fargst &fargs) @@ -552,18 +438,6 @@ void cpp_typecheck_resolvet::exact_match_functions( } } -/*******************************************************************\ - -Function: cpp_typecheck_resolvet::disambiguate_functions - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheck_resolvet::disambiguate_functions( resolve_identifierst &identifiers, const cpp_typecheck_fargst &fargs) @@ -709,18 +583,6 @@ void cpp_typecheck_resolvet::disambiguate_functions( } } -/*******************************************************************\ - -Function: cpp_typecheck_resolvet::make_constructors - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheck_resolvet::make_constructors( resolve_identifierst &identifiers) { @@ -812,18 +674,6 @@ void cpp_typecheck_resolvet::make_constructors( identifiers.swap(new_identifiers); } -/*******************************************************************\ - -Function: cpp_typecheck_resolvet::do_builtin - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - exprt cpp_typecheck_resolvet::do_builtin( const irep_idt &base_name, const cpp_template_args_non_tct &template_args) @@ -1010,20 +860,9 @@ exprt cpp_typecheck_resolvet::do_builtin( return dest; } -/*******************************************************************\ - -Function: cpp_typecheck_resolvet::resolve_scope - -Inputs: a cpp_name - -Outputs: a base_name, and potentially template arguments for - the base name; as side-effect, we got to the right - scope - -Purpose: - -\*******************************************************************/ - +/// \par parameters: a cpp_name +/// \return a base_name, and potentially template arguments for the base name; +/// as side-effect, we got to the right scope cpp_scopet &cpp_typecheck_resolvet::resolve_scope( const cpp_namet &cpp_name, irep_idt &base_name, @@ -1065,14 +904,14 @@ cpp_scopet &cpp_typecheck_resolvet::resolve_scope( cpp_typecheck.cpp_scopes.current_scope().lookup( final_base_name, recursive?cpp_scopet::RECURSIVE:cpp_scopet::QUALIFIED, - cpp_idt::TEMPLATE, + cpp_idt::id_classt::TEMPLATE, id_set); // std::cout << "S: " // << cpp_typecheck.cpp_scopes.current_scope().identifier - // << std::endl; + // << '\n'; // cpp_typecheck.cpp_scopes.current_scope().print(std::cout); - // std::cout << "X: " << id_set.size() <( cpp_typecheck.cpp_scopes.id_map[id]); - if(template_scope==NULL) + if(template_scope==nullptr) { cpp_typecheck.error().source_location=source_location; cpp_typecheck.error() << "template identifier: " << id << '\n' @@ -1353,10 +1181,10 @@ symbol_typet cpp_typecheck_resolvet::disambiguate_template_classes( m_it++) { std::cout << "M: " << m_it->cost - << " " << m_it->id << std::endl; + << " " << m_it->id << '\n'; } - std::cout << std::endl; + std::cout << '\n'; #endif const matcht &match=*matches.begin(); @@ -1403,18 +1231,6 @@ symbol_typet cpp_typecheck_resolvet::disambiguate_template_classes( #endif } -/*******************************************************************\ - -Function: cpp_typecheck_resolvet::resolve_namespace - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - cpp_scopet &cpp_typecheck_resolvet::resolve_namespace( const cpp_namet &cpp_name) { @@ -1455,23 +1271,11 @@ cpp_scopet &cpp_typecheck_resolvet::resolve_namespace( cpp_typecheck.error().source_location=source_location; cpp_typecheck.error() << "namespace `" - << base_name << "' is ambigous" << messaget::eom; + << base_name << "' is ambiguous" << messaget::eom; throw 0; } } -/*******************************************************************\ - -Function: cpp_typecheck_resolvet::show_identifiers - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheck_resolvet::show_identifiers( const irep_idt &base_name, const resolve_identifierst &identifiers, @@ -1564,22 +1368,10 @@ void cpp_typecheck_resolvet::show_identifiers( } } - out << std::endl; + out << '\n'; } } -/*******************************************************************\ - -Function: cpp_typecheck_resolvet::resolve - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - exprt cpp_typecheck_resolvet::resolve( const cpp_namet &cpp_name, const wantt want, @@ -1630,7 +1422,7 @@ exprt cpp_typecheck_resolvet::resolve( base_name, lookup_kind, id_set); else cpp_typecheck.cpp_scopes.current_scope().lookup( - base_name, lookup_kind, cpp_idt::TEMPLATE, id_set); + base_name, lookup_kind, cpp_idt::id_classt::TEMPLATE, id_set); // Argument-dependent name lookup #if 0 @@ -1695,7 +1487,7 @@ exprt cpp_typecheck_resolvet::resolve( have_methods=true; } - if(want==BOTH && have_classes && have_methods) + if(want==wantt::BOTH && have_classes && have_methods) { if(!fail_with_exception) return nil_exprt(); @@ -1708,7 +1500,7 @@ exprt cpp_typecheck_resolvet::resolve( throw 0; } - if(want==TYPE || have_classes) + if(want==wantt::TYPE || have_classes) { typet instance= disambiguate_template_classes(base_name, id_set, template_args); @@ -1731,7 +1523,7 @@ exprt cpp_typecheck_resolvet::resolve( } // change types into constructors if we want a constructor - if(want==VAR) + if(want==wantt::VAR) make_constructors(identifiers); filter(identifiers, want); @@ -1823,16 +1615,16 @@ exprt cpp_typecheck_resolvet::resolve( #if 0 exprt e1=*new_identifiers.begin(); exprt e2=*(++new_identifiers.begin()); - cpp_typecheck.str << "e1==e2: " << (e1==e2) << std::endl; + cpp_typecheck.str << "e1==e2: " << (e1==e2) << '\n'; cpp_typecheck.str << "e1.type==e2.type: " << (e1.type()==e2.type()) - << std::endl; + << '\n'; cpp_typecheck.str << "e1.id()==e2.id(): " << (e1.id()==e2.id()) - << std::endl; + << '\n'; cpp_typecheck.str << "e1.iden==e2.iden: " << (e1.get(ID_identifier)==e2.get(ID_identifier)) - << std::endl; - cpp_typecheck.str << "e1.iden:: " << e1.get(ID_identifier) << std::endl; - cpp_typecheck.str << "e2.iden:: " << e2.get(ID_identifier) << std::endl; + << '\n'; + cpp_typecheck.str << "e1.iden:: " << e1.get(ID_identifier) << '\n'; + cpp_typecheck.str << "e2.iden:: " << e2.get(ID_identifier) << '\n'; #endif } @@ -1877,7 +1669,7 @@ exprt cpp_typecheck_resolvet::resolve( switch(want) { - case VAR: + case wantt::VAR: if(result.id()==ID_type && !cpp_typecheck.cpp_is_pod(result.type())) { if(!fail_with_exception) @@ -1894,7 +1686,7 @@ exprt cpp_typecheck_resolvet::resolve( } break; - case TYPE: + case wantt::TYPE: if(result.id()!=ID_type) { if(!fail_with_exception) @@ -1918,18 +1710,6 @@ exprt cpp_typecheck_resolvet::resolve( return result; } -/*******************************************************************\ - -Function: cpp_typecheck_resolvet::guess_template_args - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheck_resolvet::guess_template_args( const exprt &template_expr, const exprt &desired_expr) @@ -1958,7 +1738,7 @@ void cpp_typecheck_resolvet::guess_template_args( { const cpp_idt &id=**it; // template parameter? - if(id.id_class==cpp_idt::TEMPLATE_PARAMETER) + if(id.id_class==cpp_idt::id_classt::TEMPLATE_PARAMETER) { // see if unassigned exprt &e=cpp_typecheck.template_map.expr_map[id.identifier]; @@ -1975,18 +1755,6 @@ void cpp_typecheck_resolvet::guess_template_args( } } -/*******************************************************************\ - -Function: cpp_typecheck_resolvet::guess_template_args - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheck_resolvet::guess_template_args( const typet &template_type, const typet &desired_type) @@ -2022,8 +1790,8 @@ void cpp_typecheck_resolvet::guess_template_args( // TT #if 0 - std::cout << "TT: " << template_type.pretty() << std::endl; - std::cout << "DT: " << desired_type.pretty() << std::endl; + std::cout << "TT: " << template_type.pretty() << '\n'; + std::cout << "DT: " << desired_type.pretty() << '\n'; #endif if(template_type.id()==ID_cpp_name) @@ -2035,7 +1803,7 @@ void cpp_typecheck_resolvet::guess_template_args( if(cpp_name.has_template_args()) { - // this could be s.th. like my_template, and we need + // this could be something like my_template, and we need // to match 'T'. Then 'desired_type' has to be a template instance. // TODO @@ -2062,7 +1830,7 @@ void cpp_typecheck_resolvet::guess_template_args( const cpp_idt &id=**it; // template argument? - if(id.id_class==cpp_idt::TEMPLATE_PARAMETER) + if(id.id_class==cpp_idt::id_classt::TEMPLATE_PARAMETER) { // see if unassigned typet &t=cpp_typecheck.template_map.type_map[id.identifier]; @@ -2075,7 +1843,7 @@ void cpp_typecheck_resolvet::guess_template_args( t.remove(ID_C_volatile); #if 0 std::cout << "ASSIGN " << id.identifier << " := " - << cpp_typecheck.to_string(desired_type) << std::endl; + << cpp_typecheck.to_string(desired_type) << '\n'; #endif } } @@ -2128,18 +1896,7 @@ void cpp_typecheck_resolvet::guess_template_args( } } -/*******************************************************************\ - -Function: cpp_typecheck_resolvet::guess_function_template_args - -Inputs: - -Outputs: - -Purpose: Guess template arguments for function templates - -\*******************************************************************/ - +/// Guess template arguments for function templates exprt cpp_typecheck_resolvet::guess_function_template_args( const exprt &expr, const cpp_typecheck_fargst &fargs) @@ -2203,7 +1960,7 @@ exprt cpp_typecheck_resolvet::guess_function_template_args( static_cast( cpp_typecheck.cpp_scopes.id_map[template_identifier]); - if(template_scope==NULL) + if(template_scope==nullptr) { cpp_typecheck.error().source_location=source_location; cpp_typecheck.error() << "template identifier: " @@ -2279,18 +2036,6 @@ exprt cpp_typecheck_resolvet::guess_function_template_args( return template_function_instance; } -/*******************************************************************\ - -Function: cpp_typecheck_resolvet::apply_template_args - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheck_resolvet::apply_template_args( exprt &expr, const cpp_template_args_non_tct &template_args_non_tc, @@ -2395,18 +2140,6 @@ void cpp_typecheck_resolvet::apply_template_args( } } -/*******************************************************************\ - -Function: cpp_typecheck_resolvet::disambiguate_functions - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - bool cpp_typecheck_resolvet::disambiguate_functions( const exprt &expr, unsigned &args_distance, @@ -2469,18 +2202,6 @@ bool cpp_typecheck_resolvet::disambiguate_functions( return fargs.match(type, args_distance, cpp_typecheck); } -/*******************************************************************\ - -Function: cpp_typecheck_resolvet::filter_for_named_scopes - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheck_resolvet::filter_for_named_scopes( cpp_scopest::id_sett &id_set) { @@ -2545,7 +2266,7 @@ void cpp_typecheck_resolvet::filter_for_named_scopes( break; } } - else if(id.id_class==cpp_scopet::TEMPLATE) + else if(id.id_class==cpp_scopet::id_classt::TEMPLATE) { // std::cout << "X3\n"; #if 0 @@ -2561,7 +2282,7 @@ void cpp_typecheck_resolvet::filter_for_named_scopes( } #endif } - else if(id.id_class==cpp_scopet::TEMPLATE_PARAMETER) + else if(id.id_class==cpp_scopet::id_classt::TEMPLATE_PARAMETER) { // std::cout << "X4\n"; // a template parameter may evaluate to be a scope: it could @@ -2571,12 +2292,12 @@ void cpp_typecheck_resolvet::filter_for_named_scopes( #if 0 cpp_typecheck.template_map.print(std::cout); std::cout << "S: " << cpp_typecheck.cpp_scopes.current_scope().identifier - << std::endl; + << '\n'; std::cout << "P: " << cpp_typecheck.cpp_scopes.current_scope().get_parent() - << std::endl; - std::cout << "I: " << id.identifier << std::endl; - std::cout << "E: " << e.pretty() << std::endl; + << '\n'; + std::cout << "I: " << id.identifier << '\n'; + std::cout << "E: " << e.pretty() << '\n'; #endif if(e.id()!=ID_type) @@ -2619,18 +2340,6 @@ void cpp_typecheck_resolvet::filter_for_named_scopes( id_set.swap(new_set); } -/*******************************************************************\ - -Function: cpp_typecheck_resolvet::filter_for_namespaces - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheck_resolvet::filter_for_namespaces( cpp_scopest::id_sett &id_set) { @@ -2651,18 +2360,6 @@ void cpp_typecheck_resolvet::filter_for_namespaces( } } -/*******************************************************************\ - -Function: cpp_typecheck_resolvet::resolve_with_arguments - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void cpp_typecheck_resolvet::resolve_with_arguments( cpp_scopest::id_sett &id_set, const irep_idt &base_name, diff --git a/src/cpp/cpp_typecheck_resolve.h b/src/cpp/cpp_typecheck_resolve.h index 07e3511e0b3..a10e0c32ee5 100644 --- a/src/cpp/cpp_typecheck_resolve.h +++ b/src/cpp/cpp_typecheck_resolve.h @@ -6,12 +6,16 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + #ifndef CPROVER_CPP_CPP_TYPECHECK_RESOLVE_H #define CPROVER_CPP_CPP_TYPECHECK_RESOLVE_H #include "cpp_typecheck_fargs.h" #include "cpp_name.h" #include "cpp_template_args.h" +#include "cpp_scopes.h" class cpp_typecheck_resolvet { @@ -19,7 +23,7 @@ class cpp_typecheck_resolvet cpp_typecheck_resolvet( class cpp_typecheckt &_cpp_typecheck); - typedef enum { VAR, TYPE, BOTH } wantt; + enum class wantt { VAR, TYPE, BOTH }; exprt resolve( const cpp_namet &cpp_name, diff --git a/src/cpp/cpp_typecheck_static_assert.cpp b/src/cpp/cpp_typecheck_static_assert.cpp index 3e449a9f043..d5d862772df 100644 --- a/src/cpp/cpp_typecheck_static_assert.cpp +++ b/src/cpp/cpp_typecheck_static_assert.cpp @@ -6,21 +6,12 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include +/// \file +/// C++ Language Type Checking #include "cpp_typecheck.h" -/*******************************************************************\ - -Function: cpp_typecheckt::convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void cpp_typecheckt::convert(cpp_static_assertt &cpp_static_assert) { diff --git a/src/cpp/cpp_typecheck_template.cpp b/src/cpp/cpp_typecheck_template.cpp index 79c609a0a4b..4fb722f011e 100644 --- a/src/cpp/cpp_typecheck_template.cpp +++ b/src/cpp/cpp_typecheck_template.cpp @@ -6,27 +6,20 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + +#include "cpp_typecheck.h" + +#include #include #include "cpp_type2name.h" -#include "cpp_typecheck.h" #include "cpp_declarator_converter.h" #include "cpp_template_type.h" #include "cpp_convert_type.h" #include "cpp_template_args.h" -/*******************************************************************\ - -Function: cpp_typecheckt::salvage_default_arguments - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::salvage_default_arguments( const template_typet &old_type, template_typet &new_type) @@ -48,18 +41,6 @@ void cpp_typecheckt::salvage_default_arguments( } } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_class_template - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_class_template( cpp_declarationt &declaration) { @@ -163,7 +144,7 @@ void cpp_typecheckt::typecheck_class_template( std::cout << "*****\n"; std::cout << *cpp_scopes.id_map[symbol_name]; std::cout << "*****\n"; - std::cout << "II: " << symbol_name << std::endl; + std::cout << "II: " << symbol_name << '\n'; #endif // We also replace the template scope (the old one could be deleted). @@ -180,7 +161,8 @@ void cpp_typecheckt::typecheck_class_template( previous_declaration.template_type()); } - assert(cpp_scopes.id_map[symbol_name]->id_class == cpp_idt::TEMPLATE_SCOPE); + assert(cpp_scopes.id_map[symbol_name]->id_class == + cpp_idt::id_classt::TEMPLATE_SCOPE); return; } @@ -212,27 +194,17 @@ void cpp_typecheckt::typecheck_class_template( // put into current scope cpp_idt &id=cpp_scopes.put_into_scope(*new_symbol); - id.id_class=cpp_idt::TEMPLATE; + id.id_class=cpp_idt::id_classt::TEMPLATE; id.prefix=cpp_scopes.current_scope().prefix+ id2string(new_symbol->base_name); // link the template symbol with the template scope cpp_scopes.id_map[symbol_name]=&template_scope; - assert(cpp_scopes.id_map[symbol_name]->id_class==cpp_idt::TEMPLATE_SCOPE); + assert(cpp_scopes.id_map[symbol_name]->id_class == + cpp_idt::id_classt::TEMPLATE_SCOPE); } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_function_template - - Inputs: - - Outputs: - - Purpose: typecheck function templates - -\*******************************************************************/ - +/// typecheck function templates void cpp_typecheckt::typecheck_function_template( cpp_declarationt &declaration) { @@ -326,28 +298,16 @@ void cpp_typecheckt::typecheck_function_template( // put into scope cpp_idt &id=cpp_scopes.put_into_scope(*new_symbol); - id.id_class=cpp_idt::TEMPLATE; + id.id_class=cpp_idt::id_classt::TEMPLATE; id.prefix=cpp_scopes.current_scope().prefix+ id2string(new_symbol->base_name); // link the template symbol with the template scope - assert(template_scope.id_class==cpp_idt::TEMPLATE_SCOPE); + assert(template_scope.id_class==cpp_idt::id_classt::TEMPLATE_SCOPE); cpp_scopes.id_map[symbol_name] = &template_scope; } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_class_template_member - - Inputs: - - Outputs: - - Purpose: typecheck class tempalte members; - these can be methods or static members - -\*******************************************************************/ - +/// typecheck class template members; these can be methods or static members void cpp_typecheckt::typecheck_class_template_member( cpp_declarationt &declaration) { @@ -378,9 +338,12 @@ void cpp_typecheckt::typecheck_class_template_member( else { return; // TODO + +#if 0 error().source_location=cpp_name.source_location(); error() << "bad template name" << eom; throw 0; +#endif } // let's find the class template this function template belongs to. @@ -389,7 +352,7 @@ void cpp_typecheckt::typecheck_class_template_member( cpp_scopes.current_scope().lookup( cpp_name.get_sub().front().get(ID_identifier), cpp_scopet::SCOPE_ONLY, // look only in current scope - cpp_scopet::TEMPLATE, // must be template + cpp_scopet::id_classt::TEMPLATE, // must be template id_set); if(id_set.empty()) @@ -409,9 +372,9 @@ void cpp_typecheckt::typecheck_class_template_member( << "' is ambiguous" << eom; throw 0; } - else if((*(id_set.begin()))->id_class!=cpp_idt::TEMPLATE) + else if((*(id_set.begin()))->id_class!=cpp_idt::id_classt::TEMPLATE) { - // std::cerr << *(*id_set.begin()) << std::endl; + // std::cerr << *(*id_set.begin()) << '\n'; error().source_location=cpp_name.source_location(); error() << "class template `" << cpp_name.get_sub().front().get(ID_identifier) @@ -460,18 +423,6 @@ void cpp_typecheckt::typecheck_class_template_member( } } -/*******************************************************************\ - -Function: cpp_typecheckt::class_template_identifier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string cpp_typecheckt::class_template_identifier( const irep_idt &base_name, const template_typet &template_type, @@ -531,18 +482,6 @@ std::string cpp_typecheckt::class_template_identifier( return identifier; } -/*******************************************************************\ - -Function: cpp_typecheckt::function_template_identifier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string cpp_typecheckt::function_template_identifier( const irep_idt &base_name, const template_typet &template_type, @@ -560,18 +499,6 @@ std::string cpp_typecheckt::function_template_identifier( return identifier; } -/*******************************************************************\ - -Function: cpp_typecheckt::convert_class_template_specialization - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::convert_class_template_specialization( cpp_declarationt &declaration) { @@ -598,7 +525,7 @@ void cpp_typecheckt::convert_class_template_specialization( // currently we are more restrictive // than the standard error().source_location=cpp_name.source_location(); - error() << "bad template-class-sepcialization name" << eom; + error() << "bad template-class-specialization name" << eom; throw 0; } @@ -616,7 +543,7 @@ void cpp_typecheckt::convert_class_template_specialization( cpp_scopest::id_sett id_set; cpp_scopes.current_scope().lookup( - base_name, cpp_scopet::SCOPE_ONLY, cpp_idt::TEMPLATE, id_set); + base_name, cpp_scopet::SCOPE_ONLY, cpp_idt::id_classt::TEMPLATE, id_set); // remove any specializations for(cpp_scopest::id_sett::iterator @@ -693,18 +620,6 @@ void cpp_typecheckt::convert_class_template_specialization( } } -/*******************************************************************\ - -Function: cpp_typecheckt::convert_template_function_or_member_specialization - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::convert_template_function_or_member_specialization( cpp_declarationt &declaration) { @@ -806,18 +721,6 @@ void cpp_typecheckt::convert_template_function_or_member_specialization( } } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_template_parameters - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - cpp_scopet &cpp_typecheckt::typecheck_template_parameters( template_typet &type) { @@ -833,7 +736,7 @@ cpp_scopet &cpp_typecheckt::typecheck_template_parameters( cpp_scopes.current_scope().prefix+id_suffix); template_scope.prefix=template_scope.get_parent().prefix+id_suffix; - template_scope.id_class=cpp_idt::TEMPLATE_SCOPE; + template_scope.id_class=cpp_idt::id_classt::TEMPLATE_SCOPE; cpp_scopes.go_to(template_scope); @@ -887,7 +790,7 @@ cpp_scopet &cpp_typecheckt::typecheck_template_parameters( // add to scope cpp_idt &id=scope.insert(base_name); id.identifier=identifier; - id.id_class=cpp_idt::TEMPLATE_PARAMETER; + id.id_class=cpp_idt::id_classt::TEMPLATE_PARAMETER; // is it a type or not? if(declaration.get_bool(ID_is_type)) @@ -949,18 +852,8 @@ cpp_scopet &cpp_typecheckt::typecheck_template_parameters( return template_scope; } -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_template_args - - Inputs: location, non-typechecked template arguments - - Outputs: typechecked template arguments - - Purpose: - -\*******************************************************************/ - +/// \par parameters: location, non-typechecked template arguments +/// \return typechecked template arguments cpp_template_args_tct cpp_typecheckt::typecheck_template_args( const source_locationt &source_location, const symbolt &template_symbol, @@ -1021,7 +914,8 @@ cpp_template_args_tct cpp_typecheckt::typecheck_template_args( // these need to be typechecked in the scope of the template, // not in the current scope! cpp_idt *template_scope=cpp_scopes.id_map[template_symbol.name]; - assert(template_scope!=NULL); + INVARIANT_STRUCTURED( + template_scope!=nullptr, nullptr_exceptiont, "template_scope is null"); cpp_scopes.go_to(*template_scope); } @@ -1065,13 +959,16 @@ cpp_template_args_tct cpp_typecheckt::typecheck_template_args( typet type=parameter.type(); - // First check the parameter type (might have ealier + // First check the parameter type (might have earlier // type parameters in it). Needs to be checked in scope // of template. { cpp_save_scopet cpp_saved_scope(cpp_scopes); cpp_idt *template_scope=cpp_scopes.id_map[template_symbol.name]; - assert(template_scope!=NULL); + INVARIANT_STRUCTURED( + template_scope!=nullptr, + nullptr_exceptiont, + "template_scope is null"); cpp_scopes.go_to(*template_scope); typecheck_type(type); } @@ -1098,18 +995,6 @@ cpp_template_args_tct cpp_typecheckt::typecheck_template_args( return result; } -/*******************************************************************\ - -Function: cpp_typecheckt::convert_template_declaration - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::convert_template_declaration( cpp_declarationt &declaration) { @@ -1170,7 +1055,7 @@ void cpp_typecheckt::convert_template_declaration( typecheck_class_template(declaration); return; } - // maybe function template, maybe class template member, maye + // maybe function template, maybe class template member, maybe // template variable else { diff --git a/src/cpp/cpp_typecheck_type.cpp b/src/cpp/cpp_typecheck_type.cpp index 0101ae9b93d..41fcd49b68c 100644 --- a/src/cpp/cpp_typecheck_type.cpp +++ b/src/cpp/cpp_typecheck_type.cpp @@ -6,29 +6,23 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + +#include "cpp_typecheck.h" + #include +#include +#include #include -#include "cpp_typecheck.h" #include "cpp_convert_type.h" #include "expr2cpp.h" -/*******************************************************************\ - -Function: cpp_typecheckt::typecheck_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cpp_typecheckt::typecheck_type(typet &type) { - assert(type.id()!=irep_idt()); + assert(!type.id().empty()); assert(type.is_not_nil()); try @@ -59,7 +53,7 @@ void cpp_typecheckt::typecheck_type(typet &type) exprt symbol_expr=resolve( cpp_name, - cpp_typecheck_resolvet::TYPE, + cpp_typecheck_resolvet::wantt::TYPE, cpp_typecheck_fargst()); if(symbol_expr.id()!=ID_type) @@ -114,8 +108,7 @@ void cpp_typecheckt::typecheck_type(typet &type) // Add 'this' to the parameters exprt a0(ID_parameter); a0.set(ID_C_base_name, ID_this); - a0.type().id(ID_pointer); - a0.type().subtype() = class_object; + a0.type()=pointer_type(class_object); parameters.insert(parameters.begin(), a0); } } @@ -126,7 +119,10 @@ void cpp_typecheckt::typecheck_type(typet &type) exprt &size_expr=to_array_type(type).size(); if(size_expr.is_not_nil()) + { typecheck_expr(size_expr); + simplify(size_expr, *this); + } typecheck_type(type.subtype()); @@ -209,7 +205,7 @@ void cpp_typecheckt::typecheck_type(typet &type) exprt symbol_expr=resolve( to_cpp_name(static_cast(tmp_type)), - cpp_typecheck_resolvet::BOTH, + cpp_typecheck_resolvet::wantt::BOTH, fargs); type=symbol_expr.type(); diff --git a/src/cpp/cpp_typecheck_using.cpp b/src/cpp/cpp_typecheck_using.cpp index 4908539a2d4..07796c4f1b8 100644 --- a/src/cpp/cpp_typecheck_using.cpp +++ b/src/cpp/cpp_typecheck_using.cpp @@ -6,21 +6,12 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include +/// \file +/// C++ Language Type Checking #include "cpp_typecheck.h" -/*******************************************************************\ - -Function: cpp_typecheckt::convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void cpp_typecheckt::convert(cpp_usingt &cpp_using) { @@ -63,7 +54,7 @@ void cpp_typecheckt::convert(cpp_usingt &cpp_using) { if(using_directive) { - if((*it)->id_class==cpp_idt::NAMESPACE) + if((*it)->id_class==cpp_idt::id_classt::NAMESPACE) cpp_scopes.current_scope().add_using_scope( static_cast(**it)); else @@ -74,8 +65,8 @@ void cpp_typecheckt::convert(cpp_usingt &cpp_using) else // declaration { // we copy all 'normal' identifiers into the current scope - if((*it)->id_class!=cpp_idt::TEMPLATE_PARAMETER && - (*it)->id_class!=cpp_idt::NAMESPACE) + if((*it)->id_class!=cpp_idt::id_classt::TEMPLATE_PARAMETER && + (*it)->id_class!=cpp_idt::id_classt::NAMESPACE) cpp_scopes.current_scope().insert(**it); } } diff --git a/src/cpp/cpp_typecheck_virtual_table.cpp b/src/cpp/cpp_typecheck_virtual_table.cpp index ec52b1270ae..f882db1f1af 100644 --- a/src/cpp/cpp_typecheck_virtual_table.cpp +++ b/src/cpp/cpp_typecheck_virtual_table.cpp @@ -6,18 +6,13 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include -#include +/// \file +/// C++ Language Type Checking #include "cpp_typecheck.h" -/*******************************************************************\ - -Function: cpp_typecheckt::do_virtual_table - -Author: Daniel Kroening, kroening@kroening.com - -\*******************************************************************/ +#include +#include void cpp_typecheckt::do_virtual_table(const symbolt &symbol) { @@ -37,21 +32,20 @@ void cpp_typecheckt::do_virtual_table(const symbolt &symbol) const code_typet &code_type=to_code_type(compo.type()); assert(code_type.parameters().size() > 0); - const pointer_typet &pointer_type = - static_cast(code_type.parameters()[0].type()); + const pointer_typet ¶meter_pointer_type= + to_pointer_type(code_type.parameters()[0].type()); - irep_idt class_id=pointer_type.subtype().get("identifier"); + irep_idt class_id=parameter_pointer_type.subtype().get("identifier"); std::map &value_map = vt_value_maps[class_id]; - exprt e=symbol_exprt(compo.get_name(), code_type); if(compo.get_bool("is_pure_virtual")) { - pointer_typet pointer_type(code_type); - e=null_pointer_exprt(pointer_type); + pointer_typet code_pointer_type=pointer_type(code_type); + e=null_pointer_exprt(code_pointer_type); value_map[compo.get("virtual_name")]=e; } else diff --git a/src/cpp/cpp_using.h b/src/cpp/cpp_using.h index fadc71accc4..580edec7c81 100644 --- a/src/cpp/cpp_using.h +++ b/src/cpp/cpp_using.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + #ifndef CPROVER_CPP_CPP_USING_H #define CPROVER_CPP_CPP_USING_H diff --git a/src/cpp/cpp_util.cpp b/src/cpp/cpp_util.cpp index 1a3c8dfd773..0e040b378a0 100644 --- a/src/cpp/cpp_util.cpp +++ b/src/cpp/cpp_util.cpp @@ -6,22 +6,10 @@ \*******************************************************************/ -#include -#include - #include "cpp_util.h" -/*******************************************************************\ - -Function: cpp_symbol_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include exprt cpp_symbol_expr(const symbolt &symbol) { diff --git a/src/cpp/cpp_util.h b/src/cpp/cpp_util.h index 17351354c1d..aeb48be73a2 100644 --- a/src/cpp/cpp_util.h +++ b/src/cpp/cpp_util.h @@ -6,38 +6,15 @@ \*******************************************************************/ + #ifndef CPROVER_CPP_CPP_UTIL_H #define CPROVER_CPP_CPP_UTIL_H #include #include -/*******************************************************************\ - -Function: cpp_symbol_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt cpp_symbol_expr(const symbolt &symbol); -/*******************************************************************\ - -Function: already_typechecked - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - inline void already_typechecked(irept &irep) { exprt tmp("already_typechecked"); diff --git a/src/cpp/expr2cpp.cpp b/src/cpp/expr2cpp.cpp index 1066d04553b..1f676b43b1c 100644 --- a/src/cpp/expr2cpp.cpp +++ b/src/cpp/expr2cpp.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +#include "expr2cpp.h" + #include #include @@ -18,21 +20,8 @@ Author: Daniel Kroening, kroening@cs.cmu.edu #include #include -#include "expr2cpp.h" #include "expr2cpp_class.h" -/*******************************************************************\ - -Function: expr2cppt::convert_struct - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2cppt::convert_struct( const exprt &src, unsigned &precedence) @@ -97,18 +86,6 @@ std::string expr2cppt::convert_struct( return dest; } -/*******************************************************************\ - -Function: expr2cppt::convert_constant - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2cppt::convert_constant( const constant_exprt &src, unsigned &precedence) @@ -125,18 +102,6 @@ std::string expr2cppt::convert_constant( return expr2ct::convert_constant(src, precedence); } -/*******************************************************************\ - -Function: expr2cppt::convert_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2cppt::convert_rec( const typet &src, const c_qualifierst &qualifiers, @@ -159,7 +124,7 @@ std::string expr2cppt::convert_rec( { return q+convert(src.subtype())+" &&"+d; } - else if(src.get(ID_C_c_type)!=irep_idt()) + else if(!src.get(ID_C_c_type).empty()) { const irep_idt c_type=src.get(ID_C_c_type); @@ -217,7 +182,7 @@ std::string expr2cppt::convert_rec( else dest+="struct"; - if(symbol.pretty_name!=irep_idt()) + if(!symbol.pretty_name.empty()) dest+=" "+id2string(symbol.pretty_name); dest+=d; @@ -230,7 +195,7 @@ std::string expr2cppt::convert_rec( dest+="enum"; - if(symbol.pretty_name!=irep_idt()) + if(!symbol.pretty_name.empty()) dest+=" "+id2string(symbol.pretty_name); dest+=d; @@ -395,18 +360,6 @@ std::string expr2cppt::convert_rec( return expr2ct::convert_rec(src, qualifiers, declarator); } -/*******************************************************************\ - -Function: expr2cppt::convert_cpp_this - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2cppt::convert_cpp_this( const exprt &src, unsigned precedence) @@ -414,18 +367,6 @@ std::string expr2cppt::convert_cpp_this( return "this"; } -/*******************************************************************\ - -Function: expr2cppt::convert_cpp_new - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2cppt::convert_cpp_new( const exprt &src, unsigned precedence) @@ -451,18 +392,6 @@ std::string expr2cppt::convert_cpp_new( return dest; } -/*******************************************************************\ - -Function: expr2cppt::convert_code_cpp_delete - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2cppt::convert_code_cpp_delete( const exprt &src, unsigned indent) @@ -482,18 +411,6 @@ std::string expr2cppt::convert_code_cpp_delete( return dest; } -/*******************************************************************\ - -Function: expr2cppt::convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2cppt::convert_with_precedence( const exprt &src, unsigned &precedence) @@ -525,18 +442,6 @@ std::string expr2cppt::convert_with_precedence( return expr2ct::convert_with_precedence(src, precedence); } -/*******************************************************************\ - -Function: expr2cppt::convert_code - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2cppt::convert_code( const codet &src, unsigned indent) @@ -554,18 +459,6 @@ std::string expr2cppt::convert_code( return expr2ct::convert_code(src, indent); } -/*******************************************************************\ - -Function: expr2cppt::convert_extractbit - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2cppt::convert_extractbit( const exprt &src, unsigned precedence) @@ -574,18 +467,6 @@ std::string expr2cppt::convert_extractbit( return convert(src.op0())+"["+convert(src.op1())+"]"; } -/*******************************************************************\ - -Function: expr2cppt::convert_extractbits - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2cppt::convert_extractbits( const exprt &src, unsigned precedence) @@ -596,18 +477,6 @@ std::string expr2cppt::convert_extractbits( convert(src.op2())+")"; } -/*******************************************************************\ - -Function: expr2cpp - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2cpp(const exprt &expr, const namespacet &ns) { expr2cppt expr2cpp(ns); @@ -617,18 +486,6 @@ std::string expr2cpp(const exprt &expr, const namespacet &ns) return expr2cpp.convert(expr); } -/*******************************************************************\ - -Function: type2cpp - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string type2cpp(const typet &type, const namespacet &ns) { expr2cppt expr2cpp(ns); diff --git a/src/cpp/expr2cpp.h b/src/cpp/expr2cpp.h index 6b39188f977..e37548708aa 100644 --- a/src/cpp/expr2cpp.h +++ b/src/cpp/expr2cpp.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ + #ifndef CPROVER_CPP_EXPR2CPP_H #define CPROVER_CPP_EXPR2CPP_H diff --git a/src/cpp/expr2cpp_class.h b/src/cpp/expr2cpp_class.h index 49ea2dcb245..464e24c848f 100644 --- a/src/cpp/expr2cpp_class.h +++ b/src/cpp/expr2cpp_class.h @@ -16,16 +16,6 @@ class expr2cppt:public expr2ct public: explicit expr2cppt(const namespacet &_ns):expr2ct(_ns) { } - std::string convert(const exprt &src) override - { - return expr2ct::convert(src); - } - - std::string convert(const typet &src) override - { - return expr2ct::convert(src); - } - protected: std::string convert_with_precedence( const exprt &src, diff --git a/src/cpp/parse.cpp b/src/cpp/parse.cpp index b16340c3eef..494f9e48ff5 100644 --- a/src/cpp/parse.cpp +++ b/src/cpp/parse.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Parsing + +#include "cpp_parser.h" + #include #include @@ -17,7 +22,6 @@ Author: Daniel Kroening, kroening@cs.cmu.edu #include #include "cpp_token_buffer.h" -#include "cpp_parser.h" #include "cpp_member_spec.h" #include "cpp_enum_type.h" @@ -37,70 +41,97 @@ struct indenter // NOLINT(readability/identifiers) cpp_tokent _tk; \ lex.LookAhead(0, _tk); \ std::cout << std::string(__indent, ' ') << "Text [" << _tk.line_no << "]: " \ - << _tk.text << std::endl; \ + << _tk.text << '\n'; \ } #endif class new_scopet { public: - new_scopet():kind(NONE), anon_count(0), parent(NULL) + new_scopet():kind(kindt::NONE), anon_count(0), parent(nullptr) { } - typedef enum { NONE, - TEMPLATE, MEMBER, FUNCTION, VARIABLE, - TYPEDEF, TAG, - NAMESPACE, CLASS_TEMPLATE, MEMBER_TEMPLATE, - FUNCTION_TEMPLATE, BLOCK, - NON_TYPE_TEMPLATE_PARAMETER, - TYPE_TEMPLATE_PARAMETER, - TEMPLATE_TEMPLATE_PARAMETER } kindt; + enum class kindt + { + NONE, + TEMPLATE, + MEMBER, + FUNCTION, + VARIABLE, + TYPEDEF, + TAG, + NAMESPACE, + CLASS_TEMPLATE, + MEMBER_TEMPLATE, + FUNCTION_TEMPLATE, + BLOCK, + NON_TYPE_TEMPLATE_PARAMETER, + TYPE_TEMPLATE_PARAMETER, + TEMPLATE_TEMPLATE_PARAMETER + }; + kindt kind; irep_idt id; bool is_type() const { - return kind==TYPEDEF || - kind==TYPE_TEMPLATE_PARAMETER || - kind==TAG || - kind==CLASS_TEMPLATE; + return kind==kindt::TYPEDEF || + kind==kindt::TYPE_TEMPLATE_PARAMETER || + kind==kindt::TAG || + kind==kindt::CLASS_TEMPLATE; } bool is_template() const { - return kind==FUNCTION_TEMPLATE || - kind==CLASS_TEMPLATE || - kind==MEMBER_TEMPLATE; + return kind==kindt::FUNCTION_TEMPLATE || + kind==kindt::CLASS_TEMPLATE || + kind==kindt::MEMBER_TEMPLATE; } bool is_named_scope() const { - return kind==NAMESPACE || - kind==TAG || - kind==TYPE_TEMPLATE_PARAMETER; + return kind==kindt::NAMESPACE || + kind==kindt::TAG || + kind==kindt::TYPE_TEMPLATE_PARAMETER; } static const char *kind2string(kindt kind) { switch(kind) { - case NONE: return "?"; - case TEMPLATE: return "TEMPLATE"; - case MEMBER: return "MEMBER"; - case FUNCTION: return "FUNCTION"; - case VARIABLE: return "VARIABLE"; - case TYPEDEF: return "TYPEDEF"; - case TAG: return "TAG"; - case NAMESPACE: return "NAMESPACE"; - case CLASS_TEMPLATE: return "CLASS_TEMPLATE"; - case MEMBER_TEMPLATE: return "MEMBER_TEMPLATE"; - case FUNCTION_TEMPLATE: return "FUNCTION_TEMPLATE"; - case BLOCK: return "BLOCK"; - case NON_TYPE_TEMPLATE_PARAMETER: return "NON_TYPE_TEMPLATE_PARAMETER"; - case TYPE_TEMPLATE_PARAMETER: return "TYPE_TEMPLATE_PARAMETER"; - case TEMPLATE_TEMPLATE_PARAMETER: return "TEMPLATE_TEMPLATE_PARAMETER"; - default: return ""; + case kindt::NONE: + return "?"; + case kindt::TEMPLATE: + return "TEMPLATE"; + case kindt::MEMBER: + return "MEMBER"; + case kindt::FUNCTION: + return "FUNCTION"; + case kindt::VARIABLE: + return "VARIABLE"; + case kindt::TYPEDEF: + return "TYPEDEF"; + case kindt::TAG: + return "TAG"; + case kindt::NAMESPACE: + return "NAMESPACE"; + case kindt::CLASS_TEMPLATE: + return "CLASS_TEMPLATE"; + case kindt::MEMBER_TEMPLATE: + return "MEMBER_TEMPLATE"; + case kindt::FUNCTION_TEMPLATE: + return "FUNCTION_TEMPLATE"; + case kindt::BLOCK: + return "BLOCK"; + case kindt::NON_TYPE_TEMPLATE_PARAMETER: + return "NON_TYPE_TEMPLATE_PARAMETER"; + case kindt::TYPE_TEMPLATE_PARAMETER: + return "TYPE_TEMPLATE_PARAMETER"; + case kindt::TEMPLATE_TEMPLATE_PARAMETER: + return "TEMPLATE_TEMPLATE_PARAMETER"; + default: + return ""; } } @@ -124,7 +155,7 @@ class new_scopet std::string full_name() const { - return (parent==NULL?"":(parent->full_name()+"::"))+ + return (parent==nullptr?"":(parent->full_name()+"::"))+ id2string(id); } @@ -150,18 +181,6 @@ class save_scopet new_scopet *old_scope; }; -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void new_scopet::print_rec(std::ostream &out, unsigned indent) const { for(id_mapt::const_iterator @@ -182,9 +201,10 @@ class Parser // NOLINT(readability/identifiers) public: explicit Parser(cpp_parsert &_cpp_parser): lex(_cpp_parser.token_buffer), - parser(_cpp_parser) + parser(_cpp_parser), + max_errors(10) { - root_scope.kind=new_scopet::NAMESPACE; + root_scope.kind=new_scopet::kindt::NAMESPACE; current_scope=&root_scope; } @@ -380,7 +400,7 @@ class Parser // NOLINT(readability/identifiers) { typet *p=&dest; - while(p->id()!=irep_idt() && p->is_not_nil()) + while(!p->id().empty() && p->is_not_nil()) { if(p->id()==ID_merged_type) { @@ -397,18 +417,6 @@ class Parser // NOLINT(readability/identifiers) unsigned int max_errors; }; -/*******************************************************************\ - -Function: Parser::add_id - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - new_scopet &Parser::add_id(const irept &cpp_name, new_scopet::kindt kind) { irep_idt id; @@ -422,18 +430,6 @@ new_scopet &Parser::add_id(const irept &cpp_name, new_scopet::kindt kind) return add_id(id, kind); } -/*******************************************************************\ - -Function: Parser::add_id - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - new_scopet &Parser::add_id(const irep_idt &id, new_scopet::kindt kind) { new_scopet &s=current_scope->id_map[id]; @@ -445,54 +441,18 @@ new_scopet &Parser::add_id(const irep_idt &id, new_scopet::kindt kind) return s; } -/*******************************************************************\ - -Function: Parser::make_sub_scope - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void Parser::make_sub_scope(const irept &cpp_name, new_scopet::kindt kind) { new_scopet &s=add_id(cpp_name, kind); current_scope=&s; } -/*******************************************************************\ - -Function: Parser::make_sub_scope - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void Parser::make_sub_scope(const irep_idt &id, new_scopet::kindt kind) { new_scopet &s=add_id(id, kind); current_scope=&s; } -/*******************************************************************\ - -Function: Parser::rString - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool Parser::rString(cpp_tokent &tk) { if(lex.get_token(tk)!=TOK_STRING) @@ -501,18 +461,6 @@ bool Parser::rString(cpp_tokent &tk) return true; } -/*******************************************************************\ - -Function: Parser::merge_types - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void Parser::merge_types(const typet &src, typet &dest) { if(src.is_nil()) @@ -533,18 +481,6 @@ void Parser::merge_types(const typet &src, typet &dest) } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool Parser::SyntaxError() { #define ERROR_TOKENS 4 @@ -579,18 +515,6 @@ bool Parser::SyntaxError() return ++number_of_errors < max_errors; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool Parser::rProgram(cpp_itemt &item) { while(lex.LookAhead(0)!='\0') @@ -610,18 +534,6 @@ bool Parser::rProgram(cpp_itemt &item) return false; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* definition : null.declaration @@ -669,18 +581,6 @@ bool Parser::rDefinition(cpp_itemt &item) return rDeclaration(item.make_declaration()); } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool Parser::rNullDeclaration(cpp_declarationt &decl) { cpp_tokent tk; @@ -693,18 +593,6 @@ bool Parser::rNullDeclaration(cpp_declarationt &decl) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* typedef : TYPEDEF type.specifier declarators ';' @@ -734,18 +622,6 @@ bool Parser::rTypedef(cpp_declarationt &declaration) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* USING Identifier '=' type.specifier ';' */ @@ -798,18 +674,6 @@ bool Parser::rTypedefUsing(cpp_declarationt &declaration) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool Parser::rTypedefStatement(codet &statement) { statement=codet(ID_decl); @@ -817,18 +681,6 @@ bool Parser::rTypedefStatement(codet &statement) return rTypedef((cpp_declarationt &)statement.op0()); } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* type.specifier : {cv.qualify} (integral.or.class.spec | name) {cv.qualify} @@ -891,18 +743,6 @@ bool Parser::rTypeSpecifier(typet &tspec, bool check) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - // isTypeSpecifier() returns true if the next is probably a type specifier. bool Parser::isTypeSpecifier() @@ -932,18 +772,6 @@ bool Parser::isTypeSpecifier() return false; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* linkage.spec : EXTERN String definition @@ -982,18 +810,6 @@ bool Parser::rLinkageSpec(cpp_linkage_spect &linkage_spec) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* namespace.spec : { INLINE } NAMESPACE Identifier definition @@ -1047,18 +863,6 @@ bool Parser::rNamespaceSpec(cpp_namespace_spect &namespace_spec) } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* using.declaration : USING { NAMESPACE } name ';' */ @@ -1087,18 +891,6 @@ bool Parser::rUsing(cpp_usingt &cpp_using) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* static_assert.declaration : STATIC_ASSERT ( expression , expression ) ';' */ @@ -1133,18 +925,6 @@ bool Parser::rStaticAssert(cpp_static_assertt &cpp_static_assert) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* linkage.body : '{' (definition)* '}' @@ -1180,18 +960,6 @@ bool Parser::rLinkageBody(cpp_linkage_spect::itemst &items) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* template.decl : TEMPLATE '<' temp.arg.list '>' declaration @@ -1214,7 +982,7 @@ bool Parser::rTemplateDecl(cpp_declarationt &decl) { TemplateDeclKind kind=tdk_unknown; - make_sub_scope("#template", new_scopet::TEMPLATE); + make_sub_scope("#template", new_scopet::kindt::TEMPLATE); current_scope->id_map.clear(); typet template_type; @@ -1265,18 +1033,6 @@ bool Parser::rTemplateDecl(cpp_declarationt &decl) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool Parser::rTemplateDecl2(typet &decl, TemplateDeclKind &kind) { cpp_tokent tk; @@ -1331,18 +1087,6 @@ bool Parser::rTemplateDecl2(typet &decl, TemplateDeclKind &kind) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* temp.arg.list : empty @@ -1375,18 +1119,6 @@ bool Parser::rTempArgList(irept &args) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* temp.arg.declaration : CLASS [Identifier] {'=' type.name} @@ -1446,7 +1178,7 @@ bool Parser::rTempArgDeclaration(cpp_declarationt &declaration) cpp_name.get_sub().push_back(name); declarator.name().swap(cpp_name); - add_id(declarator.name(), new_scopet::TYPE_TEMPLATE_PARAMETER); + add_id(declarator.name(), new_scopet::kindt::TYPE_TEMPLATE_PARAMETER); if(has_ellipsis) { @@ -1551,7 +1283,7 @@ bool Parser::rTempArgDeclaration(cpp_declarationt &declaration) << "Parser::rTempArgDeclaration 4\n"; #endif - add_id(declarator.name(), new_scopet::NON_TYPE_TEMPLATE_PARAMETER); + add_id(declarator.name(), new_scopet::kindt::NON_TYPE_TEMPLATE_PARAMETER); if(has_ellipsis) { @@ -1578,18 +1310,6 @@ bool Parser::rTempArgDeclaration(cpp_declarationt &declaration) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* extern.template.decl : EXTERN TEMPLATE declaration @@ -1613,18 +1333,6 @@ bool Parser::rExternTemplateDecl(irept &decl) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* declaration : integral.declaration @@ -1660,7 +1368,7 @@ bool Parser::rDeclaration(cpp_declarationt &declaration) #ifdef DEBUG indenter _i; std::cout << std::string(__indent, ' ') << "Parser::rDeclaration 0.1 token: " - << lex.LookAhead(0) << std::endl; + << lex.LookAhead(0) << '\n'; #endif if(!optAttribute(declaration)) @@ -1741,18 +1449,6 @@ bool Parser::rDeclaration(cpp_declarationt &declaration) } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* single declaration, for use in a condition (controlling expression of switch/while/if) */ bool Parser::rSimpleDeclaration(cpp_declarationt &declaration) @@ -1813,18 +1509,6 @@ bool Parser::rSimpleDeclaration(cpp_declarationt &declaration) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool Parser::rIntegralDeclaration( cpp_declarationt &declaration, cpp_storage_spect &storage_spec, @@ -1938,18 +1622,6 @@ bool Parser::rIntegralDeclaration( } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool Parser::rConstDeclaration( cpp_declarationt &declaration, cpp_storage_spect &storage_spec, @@ -1975,18 +1647,6 @@ bool Parser::rConstDeclaration( return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool Parser::rOtherDeclaration( cpp_declarationt &declaration, cpp_storage_spect &storage_spec, @@ -2164,18 +1824,6 @@ bool Parser::rOtherDeclaration( return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* This returns true for an declaration like: T (a); @@ -2215,18 +1863,6 @@ bool Parser::isConstructorDecl() } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* ptr.to.member : {'::'} (identifier {'<' any* '>'} '::')+ '*' @@ -2284,18 +1920,6 @@ bool Parser::isPtrToMember(int i) return false; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* member.spec : (FRIEND | INLINE | VIRTUAL | EXPLICIT)+ @@ -2326,18 +1950,6 @@ bool Parser::optMemberSpec(cpp_member_spect &member_spec) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* storage.spec : STATIC | EXTERN | AUTO | REGISTER | MUTABLE | ASM | THREAD_LOCAL @@ -2375,18 +1987,6 @@ bool Parser::optStorageSpec(cpp_storage_spect &storage_spec) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* cv.qualify : (CONSTEXPR | CONST | VOLATILE | RESTRICT)+ */ @@ -2459,18 +2059,6 @@ bool Parser::optCvQualify(typet &cv) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* dcl.align : ALIGNAS unary.expr @@ -2514,18 +2102,6 @@ bool Parser::optAlignas(typet &cv) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool Parser::rAttribute() { cpp_tokent tk; @@ -2550,18 +2126,6 @@ bool Parser::rAttribute() return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool Parser::optAttribute(cpp_declarationt &declaration) { if(lex.LookAhead(0)!='[' || @@ -2594,18 +2158,6 @@ bool Parser::optAttribute(cpp_declarationt &declaration) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* integral.or.class.spec @@ -2674,7 +2226,7 @@ bool Parser::optIntegralTypeOrClassSpec(typet &p) default: type_id=irep_idt(); } - if(type_id!=irep_idt()) + if(!type_id.empty()) { cpp_tokent tk; typet kw; @@ -2833,18 +2385,6 @@ bool Parser::optIntegralTypeOrClassSpec(typet &p) } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* constructor.decl : '(' {arg.decl.list} ')' {cv.qualify} {throw.decl} @@ -2963,18 +2503,6 @@ bool Parser::rConstructorDecl( return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* throw.decl : THROW '(' (name {','})* {name} ')' | THROW '(' '...' ')' @@ -3043,18 +2571,6 @@ bool Parser::optThrowDecl(irept &throw_decl) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* declarators : declarator.with.init (',' declarator.with.init)* @@ -3082,18 +2598,6 @@ bool Parser::rDeclarators( } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* declarator.with.init : ':' expression @@ -3208,18 +2712,6 @@ bool Parser::rDeclaratorWithInit( } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* __stdcall, __fastcall, __clrcall, __cdecl These are Visual-Studio specific. @@ -3242,18 +2734,6 @@ bool Parser::rDeclaratorQualifier() return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* declarator : (ptr.operator)* (name | '(' declarator ')') @@ -3285,7 +2765,7 @@ bool Parser::rDeclarator( std::cout << std::string(__indent, ' ') << "Parser::rDeclarator2 1\n"; #endif - // we can have one or more declatator qualifiers + // we can have one or more declarator qualifiers if(!rDeclaratorQualifier()) return false; @@ -3299,7 +2779,7 @@ bool Parser::rDeclarator( if(!optPtrOperator(d_outer)) return false; - // we can have another sequence of declatator qualifiers + // we can have another sequence of declarator qualifiers if(!rDeclaratorQualifier()) return false; @@ -3511,18 +2991,6 @@ bool Parser::rDeclarator( return true; } -/*******************************************************************\ - -Function: Parser::optPtrOperator - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* ptr.operator : (('*' | ptr.to.member)['&'] {cv.qualify})+ @@ -3648,18 +3116,6 @@ bool Parser::optPtrOperator(typet &ptrs) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* member.initializers : ':' member.init (',' member.init)* @@ -3692,18 +3148,6 @@ bool Parser::rMemberInitializers(irept &init) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* member.init : name '(' function.arguments ')' @@ -3780,18 +3224,6 @@ bool Parser::rMemberInit(exprt &init) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* name : {'::'} name2 ('::' name2)* @@ -3935,18 +3367,6 @@ bool Parser::rName(irept &name) } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* operator.name : '+' | '-' | '*' | '/' | '%' | '^' | '&' | '|' | '~' @@ -4049,7 +3469,7 @@ bool Parser::rOperatorName(irept &name) return rCastOperatorName(name); } - assert(operator_id!=irep_idt()); + assert(!operator_id.empty()); lex.get_token(tk); name=irept(operator_id); set_location(name, tk); @@ -4057,18 +3477,6 @@ bool Parser::rOperatorName(irept &name) return true; } -/*******************************************************************\ - -Function: Parser::rCastOperatorName - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* cast.operator.name : {cv.qualify} (integral.or.class.spec | name) {cv.qualify} @@ -4111,18 +3519,6 @@ bool Parser::rCastOperatorName(irept &name) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* ptr.to.member : {'::'} (identifier {template.args} '::')+ '*' @@ -4217,18 +3613,6 @@ bool Parser::rPtrToMember(irept &ptr_to_mem) return false; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* template.args : '<' '>' @@ -4372,18 +3756,6 @@ bool Parser::rTemplateArgs(irept &template_args) } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* arg.decl.list.or.init : arg.decl.list @@ -4430,18 +3802,6 @@ bool Parser::rArgDeclListOrInit( } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* arg.decl.list : empty @@ -4495,18 +3855,6 @@ bool Parser::rArgDeclList(irept &arglist) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* arg.declaration : {userdef.keyword | REGISTER} type.specifier arg.declarator @@ -4550,18 +3898,6 @@ bool Parser::rArgDeclaration(cpp_declarationt &declaration) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* initialize.expr : expression @@ -4649,18 +3985,6 @@ bool Parser::rInitializeExpr(exprt &expr) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* function.arguments : empty @@ -4701,18 +4025,6 @@ bool Parser::rFunctionArguments(exprt &args) } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* enum.spec : ENUM Identifier @@ -4800,18 +4112,6 @@ bool Parser::rEnumSpec(typet &spec) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* enum.body : Identifier {'=' expression} (',' Identifier {'=' expression})* {','} @@ -4854,26 +4154,14 @@ bool Parser::rEnumBody(irept &body) n.add(ID_value).swap(exp); } else - n.add(ID_value).make_nil(); - - if(lex.LookAhead(0)!=',') - return true; - - lex.get_token(tk); - } -} - -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: + n.add(ID_value).make_nil(); - Purpose: + if(lex.LookAhead(0)!=',') + return true; -\*******************************************************************/ + lex.get_token(tk); + } +} /* class.spec @@ -4968,7 +4256,7 @@ bool Parser::rClassSpec(typet &spec) #endif save_scopet saved_scope(current_scope); - make_sub_scope(spec.find(ID_tag), new_scopet::TAG); + make_sub_scope(spec.find(ID_tag), new_scopet::kindt::TAG); exprt body; @@ -4983,18 +4271,6 @@ bool Parser::rClassSpec(typet &spec) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* base.specifiers : ':' base.specifier (',' base.specifier)* @@ -5070,18 +4346,6 @@ bool Parser::rBaseSpecifiers(irept &bases) } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* class.body : '{' (class.members)* '}' */ @@ -5129,18 +4393,6 @@ bool Parser::rClassBody(exprt &body) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* class.member : (PUBLIC | PROTECTED | PRIVATE) ':' @@ -5166,7 +4418,7 @@ bool Parser::rClassMember(cpp_itemt &member) #ifdef DEBUG indenter _i; std::cout << std::string(__indent, ' ') << "Parser::rClassMember 0 " << t - << std::endl; + << '\n'; #endif // DEBUG if(t==TOK_PUBLIC || t==TOK_PROTECTED || t==TOK_PRIVATE) @@ -5221,18 +4473,6 @@ bool Parser::rClassMember(cpp_itemt &member) } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* access.decl : name ';' e.g. ::; @@ -5253,18 +4493,6 @@ bool Parser::rAccessDecl(irept &mem) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* comma.expression : expression @@ -5309,18 +4537,6 @@ bool Parser::rCommaExpression(exprt &exp) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* expression : conditional.expr {(AssignOp | '=') expression} right-to-left @@ -5402,18 +4618,6 @@ bool Parser::rExpression(exprt &exp, bool template_args) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* conditional.expr : logical.or.expr {'?' comma.expression ':' conditional.expr} right-to-left @@ -5462,18 +4666,6 @@ bool Parser::rConditionalExpr(exprt &exp, bool template_args) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* logical.or.expr : logical.and.expr @@ -5513,18 +4705,6 @@ bool Parser::rLogicalOrExpr(exprt &exp, bool template_args) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* logical.and.expr : inclusive.or.expr @@ -5564,18 +4744,6 @@ bool Parser::rLogicalAndExpr(exprt &exp, bool template_args) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* inclusive.or.expr : exclusive.or.expr @@ -5615,18 +4783,6 @@ bool Parser::rInclusiveOrExpr(exprt &exp, bool template_args) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* exclusive.or.expr : and.expr @@ -5666,18 +4822,6 @@ bool Parser::rExclusiveOrExpr(exprt &exp, bool template_args) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* and.expr : equality.expr @@ -5717,18 +4861,6 @@ bool Parser::rAndExpr(exprt &exp, bool template_args) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* equality.expr : relational.expr @@ -5769,18 +4901,6 @@ bool Parser::rEqualityExpr(exprt &exp, bool template_args) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* relational.expr : shift.expr @@ -5833,18 +4953,6 @@ bool Parser::rRelationalExpr(exprt &exp, bool template_args) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* shift.expr : additive.expr @@ -5885,18 +4993,6 @@ bool Parser::rShiftExpr(exprt &exp, bool template_args) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* additive.expr : multiply.expr @@ -5944,18 +5040,6 @@ bool Parser::rAdditiveExpr(exprt &exp) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* multiply.expr : pm.expr @@ -6008,18 +5092,6 @@ bool Parser::rMultiplyExpr(exprt &exp) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* pm.expr (pointer to member .*, ->*) : cast.expr @@ -6065,18 +5137,6 @@ bool Parser::rPmExpr(exprt &exp) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* cast.expr : unary.expr @@ -6138,18 +5198,6 @@ bool Parser::rCastExpr(exprt &exp) } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* type.name : type.specifier cast.declarator @@ -6187,18 +5235,6 @@ bool Parser::rTypeName(typet &tname) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* type.name | type.specifier { '(' type.specifier ( ',' type.specifier )* @@ -6376,18 +5412,6 @@ bool Parser::rTypeNameOrFunctionType(typet &tname) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* unary.expr : postfix.expr @@ -6501,18 +5525,6 @@ bool Parser::rUnaryExpr(exprt &exp) return rPostfixExpr(exp); } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* throw.expression : THROW {expression} @@ -6551,18 +5563,6 @@ bool Parser::rThrowExpr(exprt &exp) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* typeid.expr : TYPEID '(' expression ')' @@ -6627,18 +5627,6 @@ bool Parser::rTypeidExpr(exprt &exp) return false; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* sizeof.expr : SIZEOF unary.expr @@ -6713,18 +5701,6 @@ bool Parser::rSizeofExpr(exprt &exp) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* alignof.expr | ALIGNOF '(' type.name ')' @@ -6754,18 +5730,6 @@ bool Parser::rAlignofExpr(exprt &exp) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* noexcept.expr : NOEXCEPT '(' expression ')' @@ -6815,18 +5779,6 @@ bool Parser::isAllocateExpr(int t) return t==TOK_NEW || t==TOK_DELETE; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* allocate.expr : {Scope | userdef.keyword} NEW allocate.type @@ -6915,18 +5867,6 @@ bool Parser::rAllocateExpr(exprt &exp) return false; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* allocate.type : {'(' function.arguments ')'} type.specifier new.declarator @@ -7024,18 +5964,6 @@ bool Parser::rAllocateType( return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* new.declarator : empty @@ -7071,18 +5999,6 @@ bool Parser::rNewDeclarator(typet &decl) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* allocate.initializer : '(' {initialize.expr (',' initialize.expr)* } ')' @@ -7128,18 +6044,6 @@ bool Parser::rAllocateInitializer(exprt &init) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* postfix.exp : primary.exp @@ -7291,18 +6195,6 @@ bool Parser::rPostfixExpr(exprt &exp) } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* __uuidof( expression ) __uuidof( type ) @@ -7353,18 +6245,6 @@ bool Parser::rMSCuuidof(exprt &expr) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* __if_exists ( identifier ) { token stream } __if_not_exists ( identifier ) { token stream } @@ -7415,18 +6295,6 @@ bool Parser::rMSC_if_existsExpr(exprt &expr) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool Parser::rMSC_if_existsStatement(codet &code) { cpp_tokent tk1; @@ -7479,18 +6347,6 @@ bool Parser::rMSC_if_existsStatement(codet &code) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* __is_base_of ( base, derived ) __is_convertible_to ( from, to ) @@ -7543,18 +6399,6 @@ bool Parser::rTypePredicate(exprt &expr) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* primary.exp : Constant @@ -7633,7 +6477,7 @@ bool Parser::rPrimaryExpr(exprt &exp) case TOK_NULLPTR: lex.get_token(tk); - exp=constant_exprt(ID_NULL, pointer_typet(typet(ID_nullptr))); + exp=constant_exprt(ID_NULL, typet(ID_pointer, typet(ID_nullptr))); set_location(exp, tk); #ifdef DEBUG std::cout << std::string(__indent, ' ') << "Parser::rPrimaryExpr 6\n"; @@ -7795,18 +6639,6 @@ bool Parser::rPrimaryExpr(exprt &exp) } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* var.name : {'::'} name2 ('::' name2)* @@ -7830,18 +6662,6 @@ bool Parser::rVarName(exprt &name) return false; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool Parser::rVarNameCore(exprt &name) { #ifdef DEBUG @@ -7876,7 +6696,7 @@ bool Parser::rVarNameCore(exprt &name) #ifdef DEBUG std::cout << std::string(__indent, ' ') << "Parser::rVarNameCore 1.1 " << lex.LookAhead(0) - << std::endl; + << '\n'; #endif switch(lex.LookAhead(0)) @@ -7975,18 +6795,6 @@ bool Parser::rVarNameCore(exprt &name) } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool Parser::moreVarName() { if(lex.LookAhead(0)==TOK_SCOPE) @@ -7999,18 +6807,6 @@ bool Parser::moreVarName() return false; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* template.args : '<' any* '>' @@ -8112,18 +6908,6 @@ bool Parser::maybeTemplateArgs() return false; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* function.body : compound.statement | { asm } @@ -8173,18 +6957,6 @@ bool Parser::rFunctionBody(cpp_declaratort &declarator) } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* compound.statement : '{' (statement)* '}' @@ -8231,18 +7003,6 @@ bool Parser::rCompoundStatement(codet &statement) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* statement : compound.statement @@ -8522,18 +7282,6 @@ bool Parser::rStatement(codet &statement) } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* if.statement : IF '(' comma.expression ')' statement { ELSE statement } @@ -8582,18 +7330,6 @@ bool Parser::rIfStatement(codet &statement) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* switch.statement : SWITCH '(' comma.expression ')' statement @@ -8627,18 +7363,6 @@ bool Parser::rSwitchStatement(codet &statement) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* while.statement : WHILE '(' comma.expression ')' statement @@ -8672,18 +7396,6 @@ bool Parser::rWhileStatement(codet &statement) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* do.statement : DO statement WHILE '(' comma.expression ')' ';' @@ -8723,18 +7435,6 @@ bool Parser::rDoStatement(codet &statement) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* for.statement : FOR '(' expr.statement {comma.expression} ';' {comma.expression} ')' @@ -8796,18 +7496,6 @@ bool Parser::rForStatement(codet &statement) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* try.statement : TRY compound.statement (exception.handler)+ ';' @@ -8902,18 +7590,6 @@ bool Parser::rTryStatement(codet &statement) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool Parser::rMSC_tryStatement(codet &statement) { // These are for 'structured exception handling', @@ -8969,18 +7645,6 @@ bool Parser::rMSC_tryStatement(codet &statement) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool Parser::rMSC_leaveStatement(codet &statement) { // These are for 'structured exception handling', @@ -8997,18 +7661,6 @@ bool Parser::rMSC_leaveStatement(codet &statement) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool Parser::rGCCAsmStatement(codet &statement) { cpp_tokent tk; @@ -9110,18 +7762,6 @@ bool Parser::rGCCAsmStatement(codet &statement) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool Parser::rMSCAsmStatement(codet &statement) { cpp_tokent tk; @@ -9190,18 +7830,6 @@ bool Parser::rMSCAsmStatement(codet &statement) return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* expr.statement : ';' @@ -9283,18 +7911,6 @@ bool Parser::rExprStatement(codet &statement) } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool Parser::rCondition(exprt &statement) { cpp_token_buffert::post pos=lex.Save(); @@ -9320,18 +7936,6 @@ bool Parser::rCondition(exprt &statement) } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* declaration.statement : decl.head integral.or.class.spec {cv.qualify} {declarators} ';' @@ -9410,18 +8014,6 @@ bool Parser::rDeclarationStatement(codet &statement) } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* integral.decl.statement : decl.head integral.or.class.spec {cv.qualify} {declarators} ';' @@ -9467,18 +8059,6 @@ bool Parser::rIntegralDeclStatement( return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* other.decl.statement :decl.head name {cv.qualify} declarators ';' @@ -9533,35 +8113,11 @@ bool Parser::rOtherDeclStatement( return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool Parser::MaybeTypeNameOrClassTemplate(cpp_tokent &) { return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void Parser::SkipTo(int token) { cpp_tokent tk; @@ -9576,18 +8132,6 @@ void Parser::SkipTo(int token) } } -/*******************************************************************\ - -Function: Parser::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool Parser::operator()() { number_of_errors=0; @@ -9608,18 +8152,6 @@ bool Parser::operator()() return number_of_errors!=0; } -/*******************************************************************\ - -Function: cpp_parse - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool cpp_parse() { Parser parser(cpp_parser); diff --git a/src/cpp/recursion_counter.h b/src/cpp/recursion_counter.h index fab87c254f7..82ec1a77bbc 100644 --- a/src/cpp/recursion_counter.h +++ b/src/cpp/recursion_counter.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + #ifndef CPROVER_CPP_RECURSION_COUNTER_H #define CPROVER_CPP_RECURSION_COUNTER_H diff --git a/src/cpp/template_map.cpp b/src/cpp/template_map.cpp index 62d5b026207..4df80e3a089 100644 --- a/src/cpp/template_map.cpp +++ b/src/cpp/template_map.cpp @@ -6,21 +6,12 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include +/// \file +/// C++ Language Type Checking #include "template_map.h" -/*******************************************************************\ - -Function: template_mapt::apply - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void template_mapt::apply(typet &type) const { @@ -74,18 +65,6 @@ void template_mapt::apply(typet &type) const } } -/*******************************************************************\ - -Function: template_mapt::apply - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void template_mapt::apply(exprt &expr) const { apply(expr.type()); @@ -106,18 +85,6 @@ void template_mapt::apply(exprt &expr) const apply(*it); } -/*******************************************************************\ - -Function: template_mapt::lookup - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt template_mapt::lookup(const irep_idt &identifier) const { type_mapt::const_iterator t_it= @@ -139,18 +106,6 @@ exprt template_mapt::lookup(const irep_idt &identifier) const return static_cast(get_nil_irep()); } -/*******************************************************************\ - -Function: template_mapt::lookup_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet template_mapt::lookup_type(const irep_idt &identifier) const { type_mapt::const_iterator t_it= @@ -162,18 +117,6 @@ typet template_mapt::lookup_type(const irep_idt &identifier) const return static_cast(get_nil_irep()); } -/*******************************************************************\ - -Function: template_mapt::lookup_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt template_mapt::lookup_expr(const irep_idt &identifier) const { expr_mapt::const_iterator e_it= @@ -185,43 +128,19 @@ exprt template_mapt::lookup_expr(const irep_idt &identifier) const return static_cast(get_nil_irep()); } -/*******************************************************************\ - -Function: template_mapt::print - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void template_mapt::print(std::ostream &out) const { for(type_mapt::const_iterator it=type_map.begin(); it!=type_map.end(); it++) - out << it->first << " = " << it->second.pretty() << std::endl; + out << it->first << " = " << it->second.pretty() << '\n'; for(expr_mapt::const_iterator it=expr_map.begin(); it!=expr_map.end(); it++) - out << it->first << " = " << it->second.pretty() << std::endl; + out << it->first << " = " << it->second.pretty() << '\n'; } -/*******************************************************************\ - -Function: template_mapt::build - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void template_mapt::build( const template_typet &template_type, const cpp_template_args_tct &template_args) @@ -264,18 +183,6 @@ void template_mapt::build( } } -/*******************************************************************\ - -Function: template_mapt::set - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void template_mapt::set( const template_parametert ¶meter, const exprt &value) @@ -302,18 +209,6 @@ void template_mapt::set( } } -/*******************************************************************\ - -Function: template_mapt::build_unassigned - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void template_mapt::build_unassigned( const template_typet &template_type) { @@ -344,18 +239,6 @@ void template_mapt::build_unassigned( } } -/*******************************************************************\ - -Function: template_mapt::build_template_args - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - cpp_template_args_tct template_mapt::build_template_args( const template_typet &template_type) const { diff --git a/src/cpp/template_map.h b/src/cpp/template_map.h index c1347eca059..74531f3aaa9 100644 --- a/src/cpp/template_map.h +++ b/src/cpp/template_map.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +/// \file +/// C++ Language Type Checking + #ifndef CPROVER_CPP_TEMPLATE_MAP_H #define CPROVER_CPP_TEMPLATE_MAP_H diff --git a/src/doxyfile b/src/doxyfile new file mode 100644 index 00000000000..f339f070eec --- /dev/null +++ b/src/doxyfile @@ -0,0 +1,2430 @@ +# Doxyfile 1.8.11 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv +# for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = cprover + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = ../doc + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = YES + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO, these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES, upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. +# The default value is: NO. + +WARN_NO_PARAMDOC = YES + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = . ../doc + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: http://www.gnu.org/software/libiconv) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f, *.for, *.tcl, +# *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js. + +FILE_PATTERNS = *.cpp \ + *.h \ + *.md + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = solvers/z3/ + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = */.svn/* \ + */.git/* + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = ../doc/assets + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = ../doc/assets + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = ../doc/architectural/front-page.md + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see http://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the +# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the +# cost of reduced performance. This can be particularly helpful with template +# rich C++ code for which doxygen's built-in parser lacks the necessary type +# information. +# Note: The availability of this option depends on whether or not doxygen was +# generated with the -Duse-libclang=ON option for CMake. +# The default value is: NO. + +CLANG_ASSISTED_PARSING = NO + +# If clang assisted parsing is enabled you can provide the compiler with command +# line options that you would normally use when invoking the compiler. Note that +# the include paths will already be set by doxygen for the files and directories +# specified with INPUT and INCLUDE_PATH. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. + +CLANG_OPTIONS = + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = NO + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# http://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 217 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 74 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 124 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: http://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = YES + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# http://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from http://www.mathjax.org before deployment. +# The default value is: http://cdn.mathjax.org/mathjax/latest. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /
    " << std::endl; - out << std::endl; + out << "
\n"; + out << '\n'; break; } } } -/*******************************************************************\ - -Function: document_properties_html - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void document_properties_html( const goto_functionst &goto_functions, std::ostream &out) @@ -447,18 +367,6 @@ void document_properties_html( document_propertiest(goto_functions, out).html(); } -/*******************************************************************\ - -Function: document_properties_latex - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void document_properties_latex( const goto_functionst &goto_functions, std::ostream &out) diff --git a/src/goto-instrument/document_properties.h b/src/goto-instrument/document_properties.h index deeae63b645..35406ae2f30 100644 --- a/src/goto-instrument/document_properties.h +++ b/src/goto-instrument/document_properties.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Documentation of Properties + #ifndef CPROVER_GOTO_INSTRUMENT_DOCUMENT_PROPERTIES_H #define CPROVER_GOTO_INSTRUMENT_DOCUMENT_PROPERTIES_H diff --git a/src/goto-instrument/dot.cpp b/src/goto-instrument/dot.cpp index 455381c4c51..bf58fe12cd3 100644 --- a/src/goto-instrument/dot.cpp +++ b/src/goto-instrument/dot.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Dump Goto-Program as DOT Graph + +#include "dot.h" + #include #include #include @@ -17,8 +22,6 @@ Author: Daniel Kroening, kroening@kroening.com "size=\"30,40\";"\ "ratio=compress;" -#include "dot.h" - class dott { public: @@ -62,19 +65,10 @@ class dott std::set &); }; -/*******************************************************************\ - -Function: dott::write_dot_subgraph - - Inputs: output stream, name and goto program - - Outputs: true on error, false otherwise - - Purpose: writes the dot graph that corresponds to the goto program - to the output stream. - -\*******************************************************************/ - +/// writes the dot graph that corresponds to the goto program to the output +/// stream. +/// \par parameters: output stream, name and goto program +/// \return true on error, false otherwise void dott::write_dot_subgraph( std::ostream &out, const std::string &name, @@ -84,8 +78,8 @@ void dott::write_dot_subgraph( clusters.back().set("name", name); clusters.back().set("nr", subgraphscount); - out << "subgraph \"cluster_" << name << "\" {" << std::endl; - out << "label=\"" << name << "\";" << std::endl; + out << "subgraph \"cluster_" << name << "\" {\n"; + out << "label=\"" << name << "\";\n"; const goto_programt::instructionst &instructions = goto_program.instructions; @@ -93,7 +87,7 @@ void dott::write_dot_subgraph( if(instructions.empty()) { out << "Node_" << subgraphscount << "_0 " << - "[shape=Mrecord,fontsize=22,label=\"?\"];" << std::endl; + "[shape=Mrecord,fontsize=22,label=\"?\"];\n"; } else { @@ -191,7 +185,7 @@ void dott::write_dot_subgraph( out <<"Mrecord"; out << ",fontsize=22,label=\""; out << tmp.str(); - out << "\"];" << std::endl; + out << "\"];\n"; std::set tres; std::set fres; @@ -222,22 +216,10 @@ void dott::write_dot_subgraph( } } - out << "}" << std::endl; + out << "}\n"; subgraphscount++; } -/*******************************************************************\ - -Function: dott::do_dot_function_calls - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dott::do_dot_function_calls( std::ostream &out) { @@ -253,46 +235,33 @@ void dott::do_dot_function_calls( out << expr.op0().id() << " -> " "Node_" << cit->get("nr") << "_0" << " [lhead=\"cluster_" << expr.op1().get(ID_identifier) << "\"," << - "color=blue];" << std::endl; + "color=blue];\n"; } else { out << "subgraph \"cluster_" << expr.op1().get(ID_identifier) << - "\" {" << std::endl; - out << "rank=sink;"< " "Node_" << subgraphscount << "_0" << " [lhead=\"cluster_" << expr.op1().get("identifier") << "\"," << - "color=blue];" << std::endl; + "color=blue];\n"; subgraphscount++; } } } -/*******************************************************************\ - -Function: dott::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dott::output(std::ostream &out) { - out << "digraph G {" << std::endl; - out << DOTGRAPHSETTINGS << std::endl; + out << "digraph G {\n"; + out << DOTGRAPHSETTINGS << '\n'; std::list clusters; @@ -302,22 +271,12 @@ void dott::output(std::ostream &out) do_dot_function_calls(out); - out << "}" << std::endl; + out << "}\n"; } -/*******************************************************************\ - -Function: dott::escape - - Inputs: a string - - Outputs: the escaped string - - Purpose: escapes a string. beware, this might not work for all - kinds of strings. - -\*******************************************************************/ - +/// escapes a string. beware, this might not work for all kinds of strings. +/// \par parameters: a string +/// \return the escaped string std::string &dott::escape(std::string &str) { for(std::string::size_type i=0; i #include #include +#include #include #include #include @@ -22,43 +28,18 @@ Author: Daniel Kroening, kroening@kroening.com #include "goto_program2code.h" #include "dump_c_class.h" -#include "dump_c.h" - -/*******************************************************************\ - -Function: operator<< - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - inline std::ostream &operator << (std::ostream &out, dump_ct &src) { src(out); return out; } -/*******************************************************************\ - -Function: dump_ct::operator() - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void dump_ct::operator()(std::ostream &os) { std::stringstream func_decl_stream; std::stringstream compound_body_stream; std::stringstream global_var_stream; + std::stringstream global_decl_stream; std::stringstream func_body_stream; local_static_declst local_static_decls; @@ -113,17 +94,20 @@ void dump_ct::operator()(std::ostream &os) symbolt &symbol=it->second; bool tag_added=false; + // TODO we could get rid of some of the ID_anonymous by looking up + // the origin symbol types in typedef_types and adjusting any other + // uses of ID_tag if((symbol.type.id()==ID_union || symbol.type.id()==ID_struct) && symbol.type.get(ID_tag).empty()) { - assert(symbol.is_type); + PRECONDITION(symbol.is_type); symbol.type.set(ID_tag, ID_anonymous); tag_added=true; } else if(symbol.type.id()==ID_c_enum && symbol.type.find(ID_tag).get(ID_C_base_name).empty()) { - assert(symbol.is_type); + PRECONDITION(symbol.is_type); symbol.type.add(ID_tag).set(ID_C_base_name, ID_anonymous); tag_added=true; } @@ -162,14 +146,17 @@ void dump_ct::operator()(std::ostream &os) symbol.type.set(ID_tag, new_tag); } - // we don't want to dump in full all definitions - if(!tag_added && ignore(symbol)) + // we don't want to dump in full all definitions; in particular + // do not dump anonymous types that are defined in system headers + if((!tag_added || symbol.is_type) && ignore(symbol)) continue; - if(!symbols_sorted.insert(name_str).second) - assert(false); + bool inserted=symbols_sorted.insert(name_str).second; + CHECK_RETURN(inserted); } + gather_global_typedefs(); + // collect all declarations we might need, include local static variables bool skip_function_main=false; for(std::set::const_iterator @@ -188,13 +175,17 @@ void dump_ct::operator()(std::ostream &os) type_id==ID_incomplete_union || type_id==ID_c_enum)) { - os << "// " << symbol.name << std::endl; - os << "// " << symbol.location << std::endl; - - if(type_id==ID_c_enum) - convert_compound_enum(symbol.type, os); - else - os << type_to_string(symbol_typet(symbol.name)) << ";\n\n"; + if(!ignore(symbol)) + { + global_decl_stream << "// " << symbol.name << '\n'; + global_decl_stream << "// " << symbol.location << '\n'; + + if(type_id==ID_c_enum) + convert_compound_enum(symbol.type, global_decl_stream); + else + global_decl_stream << type_to_string(symbol_typet(symbol.name)) + << ";\n\n"; + } } else if(symbol.is_static_lifetime && symbol.type.id()!=ID_code) convert_global_variable( @@ -222,7 +213,8 @@ void dump_ct::operator()(std::ostream &os) { const symbolt &symbol=ns.lookup(*it); - if(symbol.type.id()!=ID_code) + if(symbol.type.id()!=ID_code || + symbol.is_type) continue; convert_function_declaration( @@ -251,61 +243,54 @@ void dump_ct::operator()(std::ostream &os) compound_body_stream); } + // Dump the code to the target stream; + // the statements before to this point collect the code to dump! for(std::set::const_iterator it=system_headers.begin(); it!=system_headers.end(); ++it) - os << "#include <" << *it << ">" << std::endl; + os << "#include <" << *it << ">\n"; if(!system_headers.empty()) - os << std::endl; + os << '\n'; if(global_var_stream.str().find("NULL")!=std::string::npos || func_body_stream.str().find("NULL")!=std::string::npos) { - os << "#ifndef NULL" << std::endl - << "#define NULL ((void*)0)" << std::endl - << "#endif" << std::endl; - os << std::endl; + os << "#ifndef NULL\n" + << "#define NULL ((void*)0)\n" + << "#endif\n\n"; } if(func_body_stream.str().find("FENCE")!=std::string::npos) { - os << "#ifndef FENCE" << std::endl - << "#define FENCE(x) ((void)0)" << std::endl - << "#endif" << std::endl; - os << std::endl; + os << "#ifndef FENCE\n" + << "#define FENCE(x) ((void)0)\n" + << "#endif\n\n"; } if(func_body_stream.str().find("IEEE_FLOAT_")!=std::string::npos) { - os << "#ifndef IEEE_FLOAT_EQUAL" << std::endl - << "#define IEEE_FLOAT_EQUAL(x,y) ((x)==(y))" << std::endl - << "#endif" << std::endl; - os << "#ifndef IEEE_FLOAT_NOTEQUAL" << std::endl - << "#define IEEE_FLOAT_NOTEQUAL(x,y) ((x)!=(y))" << std::endl - << "#endif" << std::endl; - os << std::endl; + os << "#ifndef IEEE_FLOAT_EQUAL\n" + << "#define IEEE_FLOAT_EQUAL(x,y) ((x)==(y))\n" + << "#endif\n" + << "#ifndef IEEE_FLOAT_NOTEQUAL\n" + << "#define IEEE_FLOAT_NOTEQUAL(x,y) ((x)!=(y))\n" + << "#endif\n\n"; } + if(!global_decl_stream.str().empty()) + os << global_decl_stream.str() << '\n'; + + dump_typedefs(os); + if(!func_decl_stream.str().empty()) - os << func_decl_stream.str() << std::endl; + os << func_decl_stream.str() << '\n'; if(!compound_body_stream.str().empty()) - os << compound_body_stream.str() << std::endl; + os << compound_body_stream.str() << '\n'; if(!global_var_stream.str().empty()) - os << global_var_stream.str() << std::endl; + os << global_var_stream.str() << '\n'; os << func_body_stream.str(); } -/*******************************************************************\ - -Function: dump_ct::convert_compound_declarations - -Inputs: - -Outputs: - -Purpose: declare compound types - -\*******************************************************************/ - +/// declare compound types void dump_ct::convert_compound_declaration( const symbolt &symbol, std::ostream &os_body) @@ -320,18 +305,6 @@ void dump_ct::convert_compound_declaration( convert_compound(symbol.type, symbol_typet(symbol.name), true, os_body); } -/*******************************************************************\ - -Function: dump_ct::convert_compound - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void dump_ct::convert_compound( const typet &type, const typet &unresolved, @@ -342,7 +315,7 @@ void dump_ct::convert_compound( { const symbolt &symbol= ns.lookup(to_symbol_type(type).get_identifier()); - assert(symbol.is_type); + DATA_INVARIANT(symbol.is_type, "symbol expected to be type symbol"); if(!ignore(symbol)) convert_compound(symbol.type, unresolved, recursive, os); @@ -351,7 +324,7 @@ void dump_ct::convert_compound( { const symbolt &symbol= ns.lookup(to_c_enum_tag_type(type).get_identifier()); - assert(symbol.is_type); + DATA_INVARIANT(symbol.is_type, "symbol expected to be type symbol"); if(!ignore(symbol)) convert_compound(symbol.type, unresolved, recursive, os); @@ -385,18 +358,6 @@ void dump_ct::convert_compound( convert_compound_enum(type, os); } -/*******************************************************************\ - -Function: dump_ct::convert_compound - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void dump_ct::convert_compound( const struct_union_typet &type, const typet &unresolved, @@ -408,11 +369,14 @@ void dump_ct::convert_compound( if(!converted_compound.insert(name).second) return; + // make sure typedef names used in the declaration are available + collect_typedefs(type, true); + const irept &bases = type.find(ID_bases); std::stringstream base_decls; forall_irep(parent_it, bases.get_sub()) { - assert(false); + UNREACHABLE; /* assert(parent_it->id() == ID_base); assert(parent_it->get(ID_type) == ID_symbol); @@ -466,19 +430,24 @@ void dump_ct::convert_compound( while(non_array_type->id()==ID_array) non_array_type=&(ns.follow(non_array_type->subtype())); - if(recursive && non_array_type->id()!=ID_pointer) - convert_compound(comp.type(), comp.type(), recursive, os); + if(recursive) + { + if(non_array_type->id()!=ID_pointer) + convert_compound(comp.type(), comp.type(), recursive, os); + else + collect_typedefs(comp.type(), true); + } irep_idt comp_name=comp.get_name(); - struct_body << indent(1) << "// " << comp_name << std::endl; + struct_body << indent(1) << "// " << comp_name << '\n'; struct_body << indent(1); // component names such as "main" would collide with other objects in the // namespace std::string fake_unique_name="NO/SUCH/NS::"+id2string(comp_name); std::string s=make_decl(fake_unique_name, comp.type()); - assert(s.find("NO/SUCH/NS")==std::string::npos); + POSTCONDITION(s.find("NO/SUCH/NS")==std::string::npos); if(comp_type.id()==ID_c_bit_field && to_c_bit_field_type(comp_type).get_width()==0) @@ -516,19 +485,35 @@ void dump_ct::convert_compound( struct_body << s; } else - assert(false); + UNREACHABLE; + + struct_body << ";\n"; + } - struct_body << ";" << std::endl; + typet unresolved_clean=unresolved; + typedef_typest::const_iterator td_entry= + typedef_types.find(unresolved); + irep_idt typedef_str; + if(td_entry!=typedef_types.end()) + { + unresolved_clean.remove(ID_C_typedef); + typedef_str=td_entry->second; + std::pair td_map_entry= + typedef_map.insert({typedef_str, typedef_infot(typedef_str)}); + PRECONDITION(!td_map_entry.second); + if(!td_map_entry.first->second.early) + td_map_entry.first->second.type_decl_str=""; + os << "typedef "; } - os << type_to_string(unresolved); + os << type_to_string(unresolved_clean); if(!base_decls.str().empty()) { - assert(language->id()=="cpp"); + PRECONDITION(language->id()=="cpp"); os << ": " << base_decls.str(); } - os << std::endl; - os << "{" << std::endl; + os << '\n'; + os << "{\n"; os << struct_body.str(); /* @@ -548,28 +533,16 @@ void dump_ct::convert_compound( os << " __attribute__ ((__transparent_union__))"; if(type.get_bool(ID_C_packed)) os << " __attribute__ ((__packed__))"; - os << ";"; - os << std::endl; - os << std::endl; + if(!typedef_str.empty()) + os << " " << typedef_str; + os << ";\n\n"; } -/*******************************************************************\ - -Function: dump_ct::convert_compound_enum - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void dump_ct::convert_compound_enum( const typet &type, std::ostream &os) { - assert(type.id()==ID_c_enum); + PRECONDITION(type.id()==ID_c_enum); const irept &tag=type.find(ID_tag); const irep_idt &name=tag.get(ID_C_base_name); @@ -608,18 +581,6 @@ void dump_ct::convert_compound_enum( os << ";\n\n"; } -/*******************************************************************\ - -Function: dump_ct::init_system_library_map - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - #define ADD_TO_SYSTEM_LIBRARY(v, header) \ for(size_t i=0; i typedef_names; + for(const auto &td : typedef_map) + typedef_names.insert(td.first); + code_blockt b; goto_program2codet p2s( irep_idt(), @@ -906,24 +878,222 @@ void dump_ct::cleanup_decl( b, local_static, local_type_decls, + typedef_names, system_headers); p2s(); - assert(b.operands().size()==1); + POSTCONDITION(b.operands().size()==1); decl.swap(b.op0()); } -/*******************************************************************\ +/// Find any typedef names contained in the input type and store their +/// declaration strings in typedef_map for eventual output. +/// \par parameters: type Type to inspect for ID_C_typedef entry +/// early Set to true to enforce that typedef is dumped before any function +/// declarations or struct definitions +void dump_ct::collect_typedefs(const typet &type, bool early) +{ + std::unordered_set deps; + collect_typedefs_rec(type, early, deps); +} -Function: dump_ct::convert_global_variables +/// Find any typedef names contained in the input type and store their +/// declaration strings in typedef_map for eventual output. +/// \par parameters: type Type to inspect for ID_C_typedef entry +/// early Set to true to enforce that typedef is dumped before any function +/// declarations or struct definitions +/// dependencies Typedefs used in the declaration of a given typedef +void dump_ct::collect_typedefs_rec( + const typet &type, + bool early, + std::unordered_set &dependencies) +{ + if(ignore(type)) + return; -Inputs: + std::unordered_set local_deps; -Outputs: + if(type.id()==ID_code) + { + const code_typet &code_type=to_code_type(type); -Purpose: + collect_typedefs_rec(code_type.return_type(), early, local_deps); + for(const auto ¶m : code_type.parameters()) + collect_typedefs_rec(param.type(), early, local_deps); + } + else if(type.id()==ID_pointer || type.id()==ID_array) + { + collect_typedefs_rec(type.subtype(), early, local_deps); + } + else if(type.id()==ID_symbol) + { + const symbolt &symbol= + ns.lookup(to_symbol_type(type).get_identifier()); + collect_typedefs_rec(symbol.type, early, local_deps); + } -\*******************************************************************/ + const irep_idt &typedef_str=type.get(ID_C_typedef); + + if(!typedef_str.empty()) + { + std::pair entry= + typedef_map.insert({typedef_str, typedef_infot(typedef_str)}); + + if(entry.second || + (early && entry.first->second.type_decl_str.empty())) + { + if(typedef_str=="__gnuc_va_list" || typedef_str == "va_list") + { + system_headers.insert("stdarg.h"); + early=false; + } + else + { + typet t=type; + t.remove(ID_C_typedef); + + std::ostringstream oss; + oss << "typedef " << make_decl(typedef_str, t) << ';'; + + entry.first->second.type_decl_str=oss.str(); + entry.first->second.dependencies=local_deps; + } + } + + if(early) + { + entry.first->second.early=true; + + for(const auto &d : local_deps) + { + auto td_entry=typedef_map.find(d); + PRECONDITION(td_entry!=typedef_map.end()); + td_entry->second.early=true; + } + } + + dependencies.insert(typedef_str); + } + + dependencies.insert(local_deps.begin(), local_deps.end()); +} + +/// find all global typdefs in the symbol table and store them in typedef_types +void dump_ct::gather_global_typedefs() +{ + // sort the symbols first to ensure deterministic replacement in + // typedef_types below as there could be redundant declarations + // typedef int x; + // typedef int y; + std::map symbols_sorted; + for(const auto &symbol_entry : copied_symbol_table.symbols) + symbols_sorted.insert( + {id2string(symbol_entry.first), symbol_entry.second}); + + for(const auto &symbol_entry : symbols_sorted) + { + const symbolt &symbol=symbol_entry.second; + + if(symbol.is_macro && symbol.is_type && + symbol.location.get_function().empty()) + { + const irep_idt &typedef_str=symbol.type.get(ID_C_typedef); + PRECONDITION(!typedef_str.empty()); + typedef_types[symbol.type]=typedef_str; + if(ignore(symbol)) + typedef_map.insert({typedef_str, typedef_infot(typedef_str)}); + else + collect_typedefs(symbol.type, false); + } + } +} + +/// print all typedefs that are not covered via typedef struct xyz { ... } name; +/// \return os output stream +void dump_ct::dump_typedefs(std::ostream &os) const +{ + // we need to compute a topological sort; we do so by picking all + // typedefs the dependencies of which have been emitted into to_insert + std::vector typedefs_sorted; + typedefs_sorted.reserve(typedef_map.size()); + + // elements in to_insert are lexicographically sorted and ready for + // output + std::map to_insert; + + typedef std::unordered_set id_sett; + id_sett typedefs_done; + std::unordered_map + forward_deps, reverse_deps; + + for(const auto &td : typedef_map) + if(!td.second.type_decl_str.empty()) + { + if(td.second.dependencies.empty()) + // those can be dumped immediately + to_insert.insert({id2string(td.first), td.second}); + else + { + // delay them until dependencies are dumped + forward_deps.insert({td.first, td.second.dependencies}); + for(const auto &d : td.second.dependencies) + reverse_deps[d].insert(td.first); + } + } + + while(!to_insert.empty()) + { + // the topologically next element (lexicographically ranked first + // among all the dependencies of which have been dumped) + typedef_infot t=to_insert.begin()->second; + to_insert.erase(to_insert.begin()); + // move to the output queue + typedefs_sorted.push_back(t); + + // find any depending typedefs that are now valid, or at least + // reduce the remaining dependencies + auto r_it=reverse_deps.find(t.typedef_name); + if(r_it==reverse_deps.end()) + continue; + + // reduce remaining dependencies + id_sett &r_deps=r_it->second; + for(id_sett::iterator it=r_deps.begin(); it!=r_deps.end(); ) // no ++it + { + auto f_it=forward_deps.find(*it); + if(f_it==forward_deps.end()) // might be done already + { + it=r_deps.erase(it); + continue; + } + + // update dependencies + id_sett &f_deps=f_it->second; + PRECONDITION(!f_deps.empty()); + PRECONDITION(f_deps.find(t.typedef_name)!=f_deps.end()); + f_deps.erase(t.typedef_name); + + if(f_deps.empty()) // all depenencies done now! + { + const auto td_entry=typedef_map.find(*it); + PRECONDITION(td_entry!=typedef_map.end()); + to_insert.insert({id2string(*it), td_entry->second}); + forward_deps.erase(*it); + it=r_deps.erase(it); + } + else + ++it; + } + } + + POSTCONDITION(forward_deps.empty()); + + for(const auto &td : typedefs_sorted) + os << td.type_decl_str << '\n'; + + if(!typedefs_sorted.empty()) + os << '\n'; +} void dump_ct::convert_global_variable( const symbolt &symbol, @@ -946,9 +1116,9 @@ void dump_ct::convert_global_variable( if((func.empty() || symbol.is_extern) && (symbol.value.is_nil() || !syms.empty())) { - os << "// " << symbol.name << std::endl; - os << "// " << symbol.location << std::endl; - os << expr_to_string(d) << std::endl; + os << "// " << symbol.name << '\n'; + os << "// " << symbol.location << '\n'; + os << expr_to_string(d) << '\n'; } if(!symbol.value.is_nil()) @@ -958,8 +1128,10 @@ void dump_ct::convert_global_variable( it=syms.begin(); it!=syms.end(); ++it) - if(!symbols_sorted.insert(id2string(*it)).second) - assert(false); + { + bool inserted=symbols_sorted.insert(id2string(*it)).second; + CHECK_RETURN(inserted); + } for(std::set::const_iterator it=symbols_sorted.begin(); @@ -978,28 +1150,16 @@ void dump_ct::convert_global_variable( local_static_decls[symbol.name]=d; else if(!symbol.value.is_nil()) { - os << "// " << symbol.name << std::endl; - os << "// " << symbol.location << std::endl; + os << "// " << symbol.name << '\n'; + os << "// " << symbol.location << '\n'; std::list empty_static, empty_types; cleanup_decl(d, empty_static, empty_types); - assert(empty_static.empty()); - os << expr_to_string(d) << std::endl; + CHECK_RETURN(empty_static.empty()); + os << expr_to_string(d) << '\n'; } } -/*******************************************************************\ - -Function: dump_ct::convert_function_declarations - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void dump_ct::convert_function_declaration( const symbolt &symbol, const bool skip_main, @@ -1021,6 +1181,10 @@ void dump_ct::convert_function_declaration( code_blockt b; std::list type_decls, local_static; + std::unordered_set typedef_names; + for(const auto &td : typedef_map) + typedef_names.insert(td.first); + goto_program2codet p2s( symbol.name, func_entry->second.body, @@ -1028,6 +1192,7 @@ void dump_ct::convert_function_declaration( b, local_static, type_decls, + typedef_names, system_headers); p2s(); @@ -1050,11 +1215,11 @@ void dump_ct::convert_function_declaration( converted_enum.swap(converted_e_bak); converted_compound.swap(converted_c_bak); - os_body << "// " << symbol.name << std::endl; - os_body << "// " << symbol.location << std::endl; - os_body << make_decl(symbol.name, symbol.type) << std::endl; + os_body << "// " << symbol.name << '\n'; + os_body << "// " << symbol.location << '\n'; + os_body << make_decl(symbol.name, symbol.type) << '\n'; os_body << expr_to_string(b); - os_body << std::endl << std::endl; + os_body << "\n\n"; declared_enum_constants.swap(enum_constants_bak); } @@ -1062,23 +1227,15 @@ void dump_ct::convert_function_declaration( if(symbol.name!=goto_functionst::entry_point() && symbol.name!=ID_main) { - os_decl << "// " << symbol.name << std::endl; - os_decl << "// " << symbol.location << std::endl; - os_decl << make_decl(symbol.name, symbol.type) << ";" << std::endl; + os_decl << "// " << symbol.name << '\n'; + os_decl << "// " << symbol.location << '\n'; + os_decl << make_decl(symbol.name, symbol.type) << ";\n"; } -} - -/*******************************************************************\ - -Function: find_block_position_rec - -Inputs: - -Outputs: - -Purpose: -\*******************************************************************/ + // make sure typedef names used in the function declaration are + // available + collect_typedefs(symbol.type, true); +} static bool find_block_position_rec( const irep_idt &identifier, @@ -1089,7 +1246,7 @@ static bool find_block_position_rec( if(!root.has_operands()) return false; - code_blockt *our_dest=0; + code_blockt *our_dest=nullptr; exprt::operandst &operands=root.operands(); exprt::operandst::iterator first_found=operands.end(); @@ -1159,18 +1316,6 @@ static bool find_block_position_rec( return false; } -/*******************************************************************\ - -Function: dump_ct::insert_local_static_decls - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void dump_ct::insert_local_static_decls( code_blockt &b, const std::list &local_static, @@ -1186,37 +1331,25 @@ void dump_ct::insert_local_static_decls( { local_static_declst::const_iterator d_it= local_static_decls.find(*it); - assert(d_it!=local_static_decls.end()); + PRECONDITION(d_it!=local_static_decls.end()); code_declt d=d_it->second; std::list redundant; cleanup_decl(d, redundant, type_decls); - code_blockt *dest_ptr=0; + code_blockt *dest_ptr=nullptr; exprt::operandst::iterator before=b.operands().end(); // some use of static variables might be optimised out if it is // within an if(false) { ... } block if(find_block_position_rec(*it, b, dest_ptr, before)) { - assert(dest_ptr!=0); + CHECK_RETURN(dest_ptr!=nullptr); dest_ptr->operands().insert(before, d); } } } -/*******************************************************************\ - -Function: dump_ct::insert_local_type_decls - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void dump_ct::insert_local_type_decls( code_blockt &b, const std::list &type_decls) @@ -1241,31 +1374,19 @@ void dump_ct::insert_local_type_decls( // another hack to ensure symbols inside types are seen skip.type()=type; - code_blockt *dest_ptr=0; + code_blockt *dest_ptr=nullptr; exprt::operandst::iterator before=b.operands().end(); // we might not find it in case a transparent union type cast // has been removed by cleanup operations if(find_block_position_rec(*it, b, dest_ptr, before)) { - assert(dest_ptr!=0); + CHECK_RETURN(dest_ptr!=nullptr); dest_ptr->operands().insert(before, skip); } } } -/*******************************************************************\ - -Function: dump_ct::cleanup_expr - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void dump_ct::cleanup_expr(exprt &expr) { Forall_operands(it, expr) @@ -1284,7 +1405,7 @@ void dump_ct::cleanup_expr(exprt &expr) exprt::operandst old_ops; old_ops.swap(expr.operands()); - assert(old_components.size()==old_ops.size()); + PRECONDITION(old_components.size()==old_ops.size()); exprt::operandst::iterator o_it=old_ops.begin(); for(struct_union_typet::componentst::const_iterator it=old_components.begin(); @@ -1326,7 +1447,7 @@ void dump_ct::cleanup_expr(exprt &expr) const struct_union_typet::componentt &comp= u_type_f.get_component(u.get_component_name()); const typet &u_op_type=comp.type(); - assert(u_op_type.id()==ID_pointer); + PRECONDITION(u_op_type.id()==ID_pointer); typecast_exprt tc(u.op(), u_op_type); expr.swap(tc); @@ -1413,18 +1534,6 @@ void dump_ct::cleanup_expr(exprt &expr) } } -/*******************************************************************\ - -Function: dump_ct::cleanup_type - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void dump_ct::cleanup_type(typet &type) { Forall_subtypes(it, type) @@ -1446,22 +1555,11 @@ void dump_ct::cleanup_type(typet &type) if(type.id()==ID_array) cleanup_expr(to_array_type(type).size()); - assert((type.id()!=ID_union && type.id()!=ID_struct) || - !type.get(ID_tag).empty()); + POSTCONDITION( + (type.id()!=ID_union && type.id()!=ID_struct) || + !type.get(ID_tag).empty()); } -/*******************************************************************\ - -Function: dump_ct::type_to_string - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - std::string dump_ct::type_to_string(const typet &type) { std::string ret; @@ -1471,18 +1569,6 @@ std::string dump_ct::type_to_string(const typet &type) return ret; } -/*******************************************************************\ - -Function: dump_ct::expr_to_string - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - std::string dump_ct::expr_to_string(const exprt &expr) { std::string ret; @@ -1492,46 +1578,26 @@ std::string dump_ct::expr_to_string(const exprt &expr) return ret; } -/*******************************************************************\ - -Function: dump_c - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dump_c( const goto_functionst &src, const bool use_system_headers, + const bool use_all_headers, const namespacet &ns, std::ostream &out) { - dump_ct goto2c(src, use_system_headers, ns, new_ansi_c_language); + dump_ct goto2c( + src, use_system_headers, use_all_headers, ns, new_ansi_c_language); out << goto2c; } -/*******************************************************************\ - -Function: dump_cpp - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dump_cpp( const goto_functionst &src, const bool use_system_headers, + const bool use_all_headers, const namespacet &ns, std::ostream &out) { - dump_ct goto2cpp(src, use_system_headers, ns, new_cpp_language); + dump_ct goto2cpp( + src, use_system_headers, use_all_headers, ns, new_cpp_language); out << goto2cpp; } diff --git a/src/goto-instrument/dump_c.h b/src/goto-instrument/dump_c.h index ff0efd496a6..afac58b9007 100644 --- a/src/goto-instrument/dump_c.h +++ b/src/goto-instrument/dump_c.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Dump C from Goto Program + #ifndef CPROVER_GOTO_INSTRUMENT_DUMP_C_H #define CPROVER_GOTO_INSTRUMENT_DUMP_C_H @@ -14,12 +17,14 @@ Author: Daniel Kroening, kroening@kroening.com void dump_c( const goto_functionst &src, const bool use_system_headers, + const bool use_all_headers, const namespacet &ns, std::ostream &out); void dump_cpp( const goto_functionst &src, const bool use_system_headers, + const bool use_all_headers, const namespacet &ns, std::ostream &out); diff --git a/src/goto-instrument/dump_c_class.h b/src/goto-instrument/dump_c_class.h index 6bb7b79638e..255cb88677e 100644 --- a/src/goto-instrument/dump_c_class.h +++ b/src/goto-instrument/dump_c_class.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Dump Goto-Program as C/C++ Source + #ifndef CPROVER_GOTO_INSTRUMENT_DUMP_C_CLASS_H #define CPROVER_GOTO_INSTRUMENT_DUMP_C_CLASS_H @@ -22,12 +25,14 @@ class dump_ct dump_ct( const goto_functionst &_goto_functions, const bool use_system_headers, + const bool use_all_headers, const namespacet &_ns, language_factoryt factory): goto_functions(_goto_functions), copied_symbol_table(_ns.get_symbol_table()), ns(copied_symbol_table), - language(factory()) + language(factory()), + use_all_headers(use_all_headers) { if(use_system_headers) init_system_library_map(); @@ -45,6 +50,7 @@ class dump_ct symbol_tablet copied_symbol_table; const namespacet ns; languaget *language; + const bool use_all_headers; typedef std::unordered_set convertedt; convertedt converted_compound, converted_global, converted_enum; @@ -59,12 +65,32 @@ class dump_ct declared_enum_constants_mapt; declared_enum_constants_mapt declared_enum_constants; + struct typedef_infot + { + irep_idt typedef_name; + std::string type_decl_str; + bool early; + std::unordered_set dependencies; + + explicit typedef_infot(const irep_idt &name): + typedef_name(name), + type_decl_str(""), + early(false) + { + } + }; + typedef std::map typedef_mapt; + typedef_mapt typedef_map; + typedef std::unordered_map typedef_typest; + typedef_typest typedef_types; + void init_system_library_map(); std::string type_to_string(const typet &type); std::string expr_to_string(const exprt &expr); bool ignore(const symbolt &symbol); + bool ignore(const typet &type); static std::string indent(const unsigned n) { @@ -85,6 +111,14 @@ class dump_ct return d_str.substr(0, d_str.size()-1); } + void collect_typedefs(const typet &type, bool early); + void collect_typedefs_rec( + const typet &type, + bool early, + std::unordered_set &dependencies); + void gather_global_typedefs(); + void dump_typedefs(std::ostream &os) const; + void convert_compound_declaration( const symbolt &symbol, std::ostream &os_body); diff --git a/src/goto-instrument/full_slicer.cpp b/src/goto-instrument/full_slicer.cpp index 887805ad80a..4b37e2da833 100644 --- a/src/goto-instrument/full_slicer.cpp +++ b/src/goto-instrument/full_slicer.cpp @@ -6,6 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Slicing + +#include "full_slicer.h" +#include "full_slicer_class.h" + #include #include #ifdef DEBUG_FULL_SLICERT @@ -13,20 +19,6 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "full_slicer_class.h" - -/*******************************************************************\ - -Function: full_slicert::add_dependencies - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void full_slicert::add_dependencies( const cfgt::nodet &node, queuet &queue, @@ -43,18 +35,6 @@ void full_slicert::add_dependencies( add_to_queue(queue, dep_node_to_cfg[it->first], node.PC); } -/*******************************************************************\ - -Function: full_slicert::add_dependencies - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void full_slicert::add_function_calls( const cfgt::nodet &node, queuet &queue, @@ -79,18 +59,6 @@ void full_slicert::add_function_calls( add_to_queue(queue, it->first, node.PC); } -/*******************************************************************\ - -Function: full_slicert::add_decl_dead - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void full_slicert::add_decl_dead( const cfgt::nodet &node, queuet &queue, @@ -122,18 +90,6 @@ void full_slicert::add_decl_dead( } } -/*******************************************************************\ - -Function: full_slicert::add_jumps - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void full_slicert::add_jumps( queuet &queue, jumpst &jumps, @@ -257,18 +213,6 @@ void full_slicert::add_jumps( } } -/*******************************************************************\ - -Function: full_slicert::fixedpoint - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void full_slicert::fixedpoint( goto_functionst &goto_functions, queuet &queue, @@ -318,18 +262,6 @@ void full_slicert::fixedpoint( } } -/*******************************************************************\ - -Function: implicit - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static bool implicit(goto_programt::const_targett target) { // some variables are used during symbolic execution only @@ -350,18 +282,6 @@ static bool implicit(goto_programt::const_targett target) return s.get_identifier()==CPROVER_PREFIX "rounding_mode"; } -/*******************************************************************\ - -Function: full_slicert::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void full_slicert::operator()( goto_functionst &goto_functions, const namespacet &ns, @@ -446,18 +366,6 @@ void full_slicert::operator()( goto_functions.update(); } -/*******************************************************************\ - -Function: full_slicer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void full_slicer( goto_functionst &goto_functions, const namespacet &ns, @@ -466,18 +374,6 @@ void full_slicer( full_slicert()(goto_functions, ns, criterion); } -/*******************************************************************\ - -Function: full_slicer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void full_slicer( goto_functionst &goto_functions, const namespacet &ns) @@ -486,18 +382,6 @@ void full_slicer( full_slicert()(goto_functions, ns, a); } -/*******************************************************************\ - -Function: property_slicer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void property_slicer( goto_functionst &goto_functions, const namespacet &ns, @@ -507,18 +391,6 @@ void property_slicer( full_slicert()(goto_functions, ns, p); } -/*******************************************************************\ - -Function: slicing_criteriont::~slicing_criteriont - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - slicing_criteriont::~slicing_criteriont() { } diff --git a/src/goto-instrument/full_slicer.h b/src/goto-instrument/full_slicer.h index d590025c8c4..9e39786c5a2 100644 --- a/src/goto-instrument/full_slicer.h +++ b/src/goto-instrument/full_slicer.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Slicing + #ifndef CPROVER_GOTO_INSTRUMENT_FULL_SLICER_H #define CPROVER_GOTO_INSTRUMENT_FULL_SLICER_H diff --git a/src/goto-instrument/full_slicer_class.h b/src/goto-instrument/full_slicer_class.h index 93894513f57..de1c50b54f4 100644 --- a/src/goto-instrument/full_slicer_class.h +++ b/src/goto-instrument/full_slicer_class.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Goto Program Slicing + #ifndef CPROVER_GOTO_INSTRUMENT_FULL_SLICER_CLASS_H #define CPROVER_GOTO_INSTRUMENT_FULL_SLICER_CLASS_H @@ -32,14 +35,6 @@ echo 'digraph g {' > c.dot ; cat c.goto | \ dot -Tpdf -oc-red.pdf c-red.dot #endif -/*******************************************************************\ - - Class: full_slicert - - Purpose: - -\*******************************************************************/ - class full_slicert { public: diff --git a/src/goto-instrument/function.cpp b/src/goto-instrument/function.cpp index 1ad749814bd..6c62a07f4f7 100644 --- a/src/goto-instrument/function.cpp +++ b/src/goto-instrument/function.cpp @@ -6,28 +6,19 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Function Entering and Exiting + +#include "function.h" + #include #include #include #include -#include +#include #include -#include "function.h" - -/*******************************************************************\ - -Function: function_to_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - code_function_callt function_to_call( symbol_tablet &symbol_table, const irep_idt &id, @@ -41,7 +32,7 @@ code_function_callt function_to_call( if(s_it==symbol_table.symbols.end()) { // not there - pointer_typet p(char_type()); + typet p=pointer_type(char_type()); p.subtype().set(ID_C_constant, true); code_typet function_type; @@ -87,18 +78,6 @@ code_function_callt function_to_call( return call; } -/*******************************************************************\ - -Function: function_enter - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void function_enter( symbol_tablet &symbol_table, goto_functionst &goto_functions, @@ -126,18 +105,6 @@ void function_enter( } } -/*******************************************************************\ - -Function: function_exit - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void function_exit( symbol_tablet &symbol_table, goto_functionst &goto_functions, diff --git a/src/goto-instrument/function.h b/src/goto-instrument/function.h index 207555a7cb5..88b486df6b0 100644 --- a/src/goto-instrument/function.h +++ b/src/goto-instrument/function.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Function Entering and Exiting + #ifndef CPROVER_GOTO_INSTRUMENT_FUNCTION_H #define CPROVER_GOTO_INSTRUMENT_FUNCTION_H diff --git a/src/goto-instrument/function_modifies.cpp b/src/goto-instrument/function_modifies.cpp index 0d5148c92c8..62721a3542b 100644 --- a/src/goto-instrument/function_modifies.cpp +++ b/src/goto-instrument/function_modifies.cpp @@ -6,21 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Modifies #include "function_modifies.h" -/*******************************************************************\ - -Function: function_modifiest::get_modifies_lhs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void function_modifiest::get_modifies_lhs( const local_may_aliast &local_may_alias, @@ -51,18 +42,6 @@ void function_modifiest::get_modifies_lhs( } } -/*******************************************************************\ - -Function: function_modifiest::get_modifies - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void function_modifiest::get_modifies( const local_may_aliast &local_may_alias, const goto_programt::const_targett i_it, @@ -90,18 +69,6 @@ void function_modifiest::get_modifies( } } -/*******************************************************************\ - -Function: function_modifiest::get_modifies_function - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void function_modifiest::get_modifies_function( const exprt &function, modifiest &modifies) diff --git a/src/goto-instrument/function_modifies.h b/src/goto-instrument/function_modifies.h index b4f44cda6d3..64becb1412c 100644 --- a/src/goto-instrument/function_modifies.h +++ b/src/goto-instrument/function_modifies.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Modifies + #ifndef CPROVER_GOTO_INSTRUMENT_FUNCTION_MODIFIES_H #define CPROVER_GOTO_INSTRUMENT_FUNCTION_MODIFIES_H diff --git a/src/goto-instrument/goto_instrument_languages.cpp b/src/goto-instrument/goto_instrument_languages.cpp index 4cc03bca860..cf0731573ac 100644 --- a/src/goto-instrument/goto_instrument_languages.cpp +++ b/src/goto-instrument/goto_instrument_languages.cpp @@ -6,26 +6,17 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Language Registration + +#include "goto_instrument_parse_options.h" + #include #include #include #include -#include "goto_instrument_parse_options.h" - -/*******************************************************************\ - -Function: goto_instrument_parse_optionst::register_languages - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_instrument_parse_optionst::register_languages() { register_language(new_ansi_c_language); diff --git a/src/goto-instrument/goto_instrument_main.cpp b/src/goto-instrument/goto_instrument_main.cpp index f25cbbcf9d8..0782ab6352b 100644 --- a/src/goto-instrument/goto_instrument_main.cpp +++ b/src/goto-instrument/goto_instrument_main.cpp @@ -6,21 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Main Module #include "goto_instrument_parse_options.h" -/*******************************************************************\ - -Function: main - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include #ifdef _MSC_VER int wmain(int argc, const wchar_t **argv_wide) diff --git a/src/goto-instrument/goto_instrument_parse_options.cpp b/src/goto-instrument/goto_instrument_parse_options.cpp index 66421b2e1e1..888853c6dc4 100644 --- a/src/goto-instrument/goto_instrument_parse_options.cpp +++ b/src/goto-instrument/goto_instrument_parse_options.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Main Module + +#include "goto_instrument_parse_options.h" + #include #include #include @@ -57,7 +62,6 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "goto_instrument_parse_options.h" #include "document_properties.h" #include "uninitialized.h" #include "full_slicer.h" @@ -90,18 +94,7 @@ Author: Daniel Kroening, kroening@kroening.com #include "unwind.h" #include "model_argc_argv.h" #include "undefined_functions.h" - -/*******************************************************************\ - -Function: goto_instrument_parse_optionst::eval_verbosity - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include "remove_function.h" void goto_instrument_parse_optionst::eval_verbosity() { @@ -117,23 +110,12 @@ void goto_instrument_parse_optionst::eval_verbosity() ui_message_handler.set_verbosity(v); } -/*******************************************************************\ - -Function: goto_instrument_parse_optionst::doit - - Inputs: - - Outputs: - - Purpose: invoke main modules - -\*******************************************************************/ - +/// invoke main modules int goto_instrument_parse_optionst::doit() { if(cmdline.isset("version")) { - std::cout << CBMC_VERSION << std::endl; + std::cout << CBMC_VERSION << '\n'; return 0; } @@ -200,19 +182,20 @@ int goto_instrument_parse_optionst::doit() throw "more than one of --unwinding-assertions,--partial-loops," "--continue-as-loops selected"; - goto_unwindt::unwind_strategyt unwind_strategy=goto_unwindt::ASSUME; + goto_unwindt::unwind_strategyt unwind_strategy= + goto_unwindt::unwind_strategyt::ASSUME; if(unwinding_assertions) { - unwind_strategy=goto_unwindt::ASSERT; + unwind_strategy=goto_unwindt::unwind_strategyt::ASSERT; } else if(partial_loops) { - unwind_strategy=goto_unwindt::PARTIAL; + unwind_strategy=goto_unwindt::unwind_strategyt::PARTIAL; } else if(continue_as_loops) { - unwind_strategy=goto_unwindt::CONTINUE; + unwind_strategy=goto_unwindt::unwind_strategyt::CONTINUE; } goto_unwindt goto_unwind; @@ -243,7 +226,7 @@ int goto_instrument_parse_optionst::doit() } else { - std::cout << result << std::endl; + std::cout << result << '\n'; } } } @@ -257,10 +240,9 @@ int goto_instrument_parse_optionst::doit() forall_goto_functions(f_it, goto_functions) { - std::cout << "////" << std::endl; - std::cout << "//// Function: " << f_it->first << std::endl; - std::cout << "////" << std::endl; - std::cout << std::endl; + std::cout << "////\n"; + std::cout << "//// Function: " << f_it->first << '\n'; + std::cout << "////\n\n"; const goto_programt &goto_program=f_it->second.body; @@ -268,8 +250,7 @@ int goto_instrument_parse_optionst::doit() { goto_program.output_instruction(ns, "", std::cout, i_it); std::cout << "Is threaded: " << (is_threaded(i_it)?"True":"False") - << std::endl; - std::cout << std::endl; + << "\n\n"; } } } @@ -323,11 +304,11 @@ int goto_instrument_parse_optionst::doit() forall_goto_functions(it, goto_functions) { local_bitvector_analysist local_bitvector_analysis(it->second); - std::cout << ">>>>" << std::endl; - std::cout << ">>>> " << it->first << std::endl; - std::cout << ">>>>" << std::endl; + std::cout << ">>>>\n"; + std::cout << ">>>> " << it->first << '\n'; + std::cout << ">>>>\n"; local_bitvector_analysis.output(std::cout, it->second, ns); - std::cout << std::endl; + std::cout << '\n'; } return 0; @@ -507,17 +488,7 @@ int goto_instrument_parse_optionst::doit() reaching_definitions_analysist rd_analysis(ns); rd_analysis(goto_functions, ns); - forall_goto_functions(f_it, goto_functions) - { - if(f_it->second.body_available()) - { - std::cout << "////" << std::endl; - std::cout << "//// Function: " << f_it->first << std::endl; - std::cout << "////" << std::endl; - std::cout << std::endl; - rd_analysis.output(ns, f_it->second.body, std::cout); - } - } + rd_analysis.output(ns, goto_functions, std::cout); return 0; } @@ -530,18 +501,7 @@ int goto_instrument_parse_optionst::doit() dependence_grapht dependence_graph(ns); dependence_graph(goto_functions, ns); - forall_goto_functions(f_it, goto_functions) - { - if(f_it->second.body_available()) - { - std::cout << "////" << std::endl; - std::cout << "//// Function: " << f_it->first << std::endl; - std::cout << "////" << std::endl; - std::cout << std::endl; - dependence_graph.output(ns, f_it->second.body, std::cout); - } - } - + dependence_graph.output(ns, goto_functions, std::cout); dependence_graph.output_dot(std::cout); return 0; @@ -619,6 +579,19 @@ int goto_instrument_parse_optionst::doit() return 0; } + if(cmdline.isset("print-internal-representation")) + { + for(auto const &pair : goto_functions.function_map) + for(auto const &ins : pair.second.body.instructions) + { + if(ins.code.is_not_nil()) + status() << ins.code.pretty() << eom; + if(ins.guard.is_not_nil()) + status() << "[guard] " << ins.guard.pretty() << eom; + } + return 0; + } + if(cmdline.isset("show-goto-functions")) { namespacet ns(symbol_table); @@ -649,7 +622,8 @@ int goto_instrument_parse_optionst::doit() if(cmdline.isset("dump-c") || cmdline.isset("dump-cpp")) { const bool is_cpp=cmdline.isset("dump-cpp"); - const bool h=cmdline.isset("use-system-headers"); + const bool h_libc=!cmdline.isset("no-system-headers"); + const bool h_all=cmdline.isset("use-all-headers"); namespacet ns(symbol_table); // restore RETURN instructions in case remove_returns had been @@ -668,10 +642,11 @@ int goto_instrument_parse_optionst::doit() error() << "failed to write to `" << cmdline.args[1] << "'"; return 10; } - (is_cpp ? dump_cpp : dump_c)(goto_functions, h, ns, out); + (is_cpp ? dump_cpp : dump_c)(goto_functions, h_libc, h_all, ns, out); } else - (is_cpp ? dump_cpp : dump_c)(goto_functions, h, ns, std::cout); + (is_cpp ? dump_cpp : dump_c)( + goto_functions, h_libc, h_all, ns, std::cout); return 0; } @@ -811,20 +786,9 @@ int goto_instrument_parse_optionst::doit() error() << "Out of memory" << eom; return 11; } +// NOLINTNEXTLINE(readability/fn_size) } -/*******************************************************************\ - -Function: goto_instrument_parse_optionst::do_indirect_call_and_rtti_removal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_instrument_parse_optionst::do_indirect_call_and_rtti_removal( bool force) { @@ -847,21 +811,9 @@ void goto_instrument_parse_optionst::do_indirect_call_and_rtti_removal( remove_instanceof(symbol_table, goto_functions); } -/*******************************************************************\ - -Function: goto_instrument_parse_optionst::do_remove_const_function_pointers_only - - Inputs: - - Outputs: - - Purpose: Remove function pointers that can be resolved by analysing - const variables (i.e. can be resolved using - remove_const_function_pointers). Function pointers that cannot - be resolved will be left as function pointers. - -\*******************************************************************/ - +/// Remove function pointers that can be resolved by analysing const variables +/// (i.e. can be resolved using remove_const_function_pointers). Function +/// pointers that cannot be resolved will be left as function pointers. void goto_instrument_parse_optionst::do_remove_const_function_pointers_only() { // Don't bother if we've already done a full function pointer @@ -880,18 +832,6 @@ void goto_instrument_parse_optionst::do_remove_const_function_pointers_only() true); // abort if we can't resolve via const pointers } -/*******************************************************************\ - -Function: goto_instrument_parse_optionst::do_partial_inlining - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_instrument_parse_optionst::do_partial_inlining() { if(partial_inlining_done) @@ -907,18 +847,6 @@ void goto_instrument_parse_optionst::do_partial_inlining() } } -/*******************************************************************\ - -Function: goto_instrument_parse_optionst::do_remove_returns - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_instrument_parse_optionst::do_remove_returns() { if(remove_returns_done) @@ -930,18 +858,6 @@ void goto_instrument_parse_optionst::do_remove_returns() remove_returns(symbol_table, goto_functions); } -/*******************************************************************\ - -Function: goto_instrument_parse_optionst::get_goto_program - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_instrument_parse_optionst::get_goto_program() { status() << "Reading GOTO program from `" << cmdline.args[0] << "'" << eom; @@ -954,18 +870,6 @@ void goto_instrument_parse_optionst::get_goto_program() config.set_from_symbol_table(symbol_table); } -/*******************************************************************\ - -Function: goto_instrument_parse_optionst::instrument_goto_program - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_instrument_parse_optionst::instrument_goto_program() { optionst options; @@ -1037,6 +941,15 @@ void goto_instrument_parse_optionst::instrument_goto_program() throw 0; } + if(cmdline.isset("remove-function-body")) + { + remove_functions( + symbol_table, + goto_functions, + cmdline.get_values("remove-function-body"), + get_message_handler()); + } + // we add the library in some cases, as some analyses benefit if(cmdline.isset("add-library") || @@ -1166,7 +1079,7 @@ void goto_instrument_parse_optionst::instrument_goto_program() } else { - std::cout << result << std::endl; + std::cout << result << '\n'; } } @@ -1216,7 +1129,7 @@ void goto_instrument_parse_optionst::instrument_goto_program() // add generic checks, if needed goto_check(ns, options, goto_functions); - // check for uninitalized local varibles + // check for uninitalized local variables if(cmdline.isset("uninitialized-check")) { status() << "Adding checks for uninitialized local variables" << eom; @@ -1427,7 +1340,7 @@ void goto_instrument_parse_optionst::instrument_goto_program() if(cmdline.isset("havoc-loops")) { - status() << "Havocing loops" << eom; + status() << "Havocking loops" << eom; havoc_loops(goto_functions); } @@ -1521,25 +1434,11 @@ void goto_instrument_parse_optionst::instrument_goto_program() full_slicer(goto_functions, ns); } - // label the assertions - label_properties(goto_functions); - // recalculate numbers, etc. goto_functions.update(); } -/*******************************************************************\ - -Function: goto_instrument_parse_optionst::help - - Inputs: - - Outputs: - - Purpose: display command line help - -\*******************************************************************/ - +/// display command line help void goto_instrument_parse_optionst::help() { std::cout << @@ -1569,6 +1468,8 @@ void goto_instrument_parse_optionst::help() " --show-symbol-table show symbol table\n" " --list-symbols list symbols with type information\n" HELP_SHOW_GOTO_FUNCTIONS + " --print-internal-representation\n" // NOLINTNEXTLINE(*) + " show verbose internal representation of the program\n" " --list-undefined-functions list functions without body\n" " --show-struct-alignment show struct members that might be concurrently accessed\n" // NOLINT(*) " --show-natural-loops show natural loop heads\n" @@ -1596,7 +1497,8 @@ void goto_instrument_parse_optionst::help() " --nondet-static add nondeterministic initialization of variables with static lifetime\n" // NOLINT(*) " --check-invariant function instruments invariant checking function\n" " --remove-pointers converts pointer arithmetic to base+offset expressions\n" // NOLINT(*) - " --undefined-function-is-assume-false\n" + // NOLINTNEXTLINE(whitespace/line_length) + " --undefined-function-is-assume-false\n" // NOLINTNEXTLINE(whitespace/line_length) " convert each call to an undefined function to assume(false)\n" "\n" "Loop transformations:\n" @@ -1637,9 +1539,12 @@ void goto_instrument_parse_optionst::help() HELP_REMOVE_CONST_FUNCTION_POINTERS " --add-library add models of C library functions\n" " --model-argc-argv model up to command line arguments\n" + // NOLINTNEXTLINE(whitespace/line_length) + " --remove-function-body remove the implementation of function (may be repeated)\n" "\n" "Other options:\n" - " --use-system-headers with --dump-c/--dump-cpp: generate C source with includes\n" // NOLINT(*) + " --no-system-headers with --dump-c/--dump-cpp: generate C source expanding libc includes\n" // NOLINT(*) + " --use-all-headers with --dump-c/--dump-cpp: generate C source with all includes\n" // NOLINT(*) " --version show version and exit\n" " --xml-ui use XML-formatted output\n" " --json-ui use JSON-formatted output\n" diff --git a/src/goto-instrument/goto_instrument_parse_options.h b/src/goto-instrument/goto_instrument_parse_options.h index 788bf543953..e2c4bf4fbc0 100644 --- a/src/goto-instrument/goto_instrument_parse_options.h +++ b/src/goto-instrument/goto_instrument_parse_options.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Command Line Parsing + #ifndef CPROVER_GOTO_INSTRUMENT_GOTO_INSTRUMENT_PARSE_OPTIONS_H #define CPROVER_GOTO_INSTRUMENT_GOTO_INSTRUMENT_PARSE_OPTIONS_H @@ -23,7 +26,7 @@ Author: Daniel Kroening, kroening@kroening.com "(all)" \ "(document-claims-latex)(document-claims-html)" \ "(document-properties-latex)(document-properties-html)" \ - "(dump-c)(dump-cpp)(use-system-headers)(dot)(xml)" \ + "(dump-c)(dump-cpp)(no-system-headers)(use-all-headers)(dot)(xml)" \ OPT_GOTO_CHECK \ /* no-X-check are deprecated and ignored */ \ "(no-bounds-check)(no-pointer-check)(no-div-by-zero-check)" \ @@ -57,6 +60,7 @@ Author: Daniel Kroening, kroening@kroening.com "(full-slice)(reachability-slice)(slice-global-inits)" \ "(inline)(partial-inline)(function-inline):(log):(no-caching)" \ OPT_REMOVE_CONST_FUNCTION_POINTERS \ + "(print-internal-representation)" \ "(remove-function-pointers)" \ "(show-claims)(show-properties)(property):" \ "(show-symbol-table)(show-points-to)(show-rw-set)" \ @@ -72,7 +76,8 @@ Author: Daniel Kroening, kroening@kroening.com "(z3)(add-library)(show-dependence-graph)" \ "(horn)(skip-loops):(apply-code-contracts)(model-argc-argv):" \ "(show-threaded)(list-calls-args)(print-path-lengths)" \ - "(undefined-function-is-assume-false)" + "(undefined-function-is-assume-false)" \ + "(remove-function-body):" class goto_instrument_parse_optionst: public parse_options_baset, diff --git a/src/goto-instrument/goto_program2code.cpp b/src/goto-instrument/goto_program2code.cpp index 400aca3b407..1a96eb4ee34 100644 --- a/src/goto-instrument/goto_program2code.cpp +++ b/src/goto-instrument/goto_program2code.cpp @@ -6,8 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Dump Goto-Program as C/C++ Source + +#include "goto_program2code.h" + #include +#include #include #include #include @@ -15,20 +21,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "goto_program2code.h" - -/*******************************************************************\ - -Function: skip_typecast - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - static const exprt &skip_typecast(const exprt &expr) { if(expr.id()!=ID_typecast) @@ -37,18 +29,6 @@ static const exprt &skip_typecast(const exprt &expr) return skip_typecast(to_typecast_expr(expr).op()); } -/*******************************************************************\ - -Function: goto_program2codet::operator() - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void goto_program2codet::operator()() { // labels stored for cleanup @@ -76,18 +56,6 @@ void goto_program2codet::operator()() cleanup_code(toplevel_block, ID_nil); } -/*******************************************************************\ - -Function: goto_program2codet::build_loop_map - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void goto_program2codet::build_loop_map() { loop_map.clear(); @@ -124,18 +92,6 @@ void goto_program2codet::build_loop_map() } } -/*******************************************************************\ - -Function: goto_program2codet::build_dead_map - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void goto_program2codet::build_dead_map() { dead_map.clear(); @@ -147,18 +103,6 @@ void goto_program2codet::build_dead_map() target->location_number; } -/*******************************************************************\ - -Function: goto_program2codet::scan_for_varargs - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void goto_program2codet::scan_for_varargs() { va_list_expr.clear(); @@ -166,14 +110,23 @@ void goto_program2codet::scan_for_varargs() forall_goto_program_instructions(target, goto_program) if(target->is_assign()) { + const exprt &l=to_code_assign(target->code).lhs(); const exprt &r=to_code_assign(target->code).rhs(); + // find va_arg_next if(r.id()==ID_side_effect && to_side_effect_expr(r).get_statement()==ID_gcc_builtin_va_arg_next) { assert(r.has_operands()); va_list_expr.insert(r.op0()); } + // try our modelling of va_start + else if(l.type().id()==ID_pointer && + l.type().get(ID_C_typedef)=="va_list" && + l.id()==ID_symbol && + r.id()==ID_typecast && + to_typecast_expr(r).op().id()==ID_address_of) + va_list_expr.insert(l); } if(!va_list_expr.empty()) @@ -200,18 +153,6 @@ void goto_program2codet::scan_for_varargs() } } -/*******************************************************************\ - -Function: goto_program2codet::convert_instruction - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - goto_programt::const_targett goto_program2codet::convert_instruction( goto_programt::const_targett target, goto_programt::const_targett upper_bound, @@ -316,18 +257,6 @@ goto_programt::const_targett goto_program2codet::convert_instruction( return target; } -/*******************************************************************\ - -Function: goto_program2codet::convert_labels - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void goto_program2codet::convert_labels( goto_programt::const_targett target, codet &dest) @@ -370,18 +299,6 @@ void goto_program2codet::convert_labels( latest_block->copy_to_operands(code_skipt()); } -/*******************************************************************\ - -Function: goto_program2codet::convert_assign - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - goto_programt::const_targett goto_program2codet::convert_assign( goto_programt::const_targett target, goto_programt::const_targett upper_bound, @@ -397,18 +314,6 @@ goto_programt::const_targett goto_program2codet::convert_assign( return target; } -/*******************************************************************\ - -Function: goto_program2codet::convert_assign_varargs - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - goto_programt::const_targett goto_program2codet::convert_assign_varargs( goto_programt::const_targett target, goto_programt::const_targett upper_bound, @@ -479,9 +384,7 @@ goto_programt::const_targett goto_program2codet::convert_assign_varargs( static_cast(r.find(ID_C_va_arg_type)); dereference_exprt deref( - typecast_exprt( - from_integer(0, signedbv_typet(config.ansi_c.pointer_width)), - pointer_typet(va_arg_type)), + null_pointer_exprt(pointer_type(va_arg_type)), va_arg_type); type_of.arguments().push_back(deref); @@ -504,18 +407,6 @@ goto_programt::const_targett goto_program2codet::convert_assign_varargs( return target; } -/*******************************************************************\ - -Function: goto_program2codet::convert_assign_rec - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void goto_program2codet::convert_assign_rec( const code_assignt &assign, codet &dest) @@ -530,7 +421,7 @@ void goto_program2codet::convert_assign_rec( { index_exprt index( assign.lhs(), - from_integer(i++, signedbv_typet(config.ansi_c.pointer_width)), + from_integer(i++, index_type()), type.subtype()); convert_assign_rec(code_assignt(index, *it), dest); } @@ -539,18 +430,6 @@ void goto_program2codet::convert_assign_rec( dest.copy_to_operands(assign); } -/*******************************************************************\ - -Function: goto_program2codet::convert_return - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - goto_programt::const_targett goto_program2codet::convert_return( goto_programt::const_targett target, goto_programt::const_targett upper_bound, @@ -581,18 +460,6 @@ goto_programt::const_targett goto_program2codet::convert_return( return target; } -/*******************************************************************\ - -Function: goto_program2codet::convert_decl - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - goto_programt::const_targett goto_program2codet::convert_decl( goto_programt::const_targett target, goto_programt::const_targett upper_bound, @@ -655,18 +522,6 @@ goto_programt::const_targett goto_program2codet::convert_decl( return target; } -/*******************************************************************\ - -Function: goto_program2codet::convert_do_while - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - goto_programt::const_targett goto_program2codet::convert_do_while( goto_programt::const_targett target, goto_programt::const_targett loop_end, @@ -692,18 +547,6 @@ goto_programt::const_targett goto_program2codet::convert_do_while( return target; } -/*******************************************************************\ - -Function: goto_program2codet::convert_goto - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - goto_programt::const_targett goto_program2codet::convert_goto( goto_programt::const_targett target, goto_programt::const_targett upper_bound, @@ -722,23 +565,11 @@ goto_programt::const_targett goto_program2codet::convert_goto( else if(!target->guard.is_true()) return convert_goto_switch(target, upper_bound, dest); else if(!loop_last_stack.empty()) - return convert_goto_break_continue(target, dest); + return convert_goto_break_continue(target, upper_bound, dest); else return convert_goto_goto(target, dest); } -/*******************************************************************\ - -Function: goto_program2codet::convert_goto_while - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - goto_programt::const_targett goto_program2codet::convert_goto_while( goto_programt::const_targett target, goto_programt::const_targett loop_end, @@ -838,18 +669,6 @@ goto_programt::const_targett goto_program2codet::convert_goto_while( return target; } -/*******************************************************************\ - -Function: goto_program2codet::get_cases - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - goto_programt::const_targett goto_program2codet::get_cases( goto_programt::const_targett target, goto_programt::const_targett upper_bound, @@ -952,18 +771,6 @@ goto_programt::const_targett goto_program2codet::get_cases( return cases_it; } -/*******************************************************************\ - -Function: goto_program2codet::set_block_end_points - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - bool goto_program2codet::set_block_end_points( goto_programt::const_targett upper_bound, const cfg_dominatorst &dominators, @@ -996,7 +803,14 @@ bool goto_program2codet::set_block_end_points( // ignore dead instructions for the following checks if(n.dominators.empty()) + { + // simplification may have figured out that a case is unreachable + // this is possibly getting too weird, abort to be safe + if(case_end==it->case_start) + return true; + continue; + } // find the last instruction dominated by the case start if(n.dominators.find(it->case_start)==n.dominators.end()) @@ -1014,18 +828,6 @@ bool goto_program2codet::set_block_end_points( return false; } -/*******************************************************************\ - -Function: goto_program2codet::remove_default - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - bool goto_program2codet::remove_default( const cfg_dominatorst &dominators, const cases_listt &cases, @@ -1088,18 +890,6 @@ bool goto_program2codet::remove_default( return false; } -/*******************************************************************\ - -Function: goto_program2codet::convert_goto_switch - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - goto_programt::const_targett goto_program2codet::convert_goto_switch( goto_programt::const_targett target, goto_programt::const_targett upper_bound, @@ -1279,18 +1069,6 @@ goto_programt::const_targett goto_program2codet::convert_goto_switch( return max_target; } -/*******************************************************************\ - -Function: goto_program2codet::convert_goto_if - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - goto_programt::const_targett goto_program2codet::convert_goto_if( goto_programt::const_targett target, goto_programt::const_targett upper_bound, @@ -1336,7 +1114,7 @@ goto_programt::const_targett goto_program2codet::convert_goto_if( upper_bound->location_number < end_if->location_number)) { if(!loop_last_stack.empty()) - return convert_goto_break_continue(target, dest); + return convert_goto_break_continue(target, upper_bound, dest); else return convert_goto_goto(target, dest); } @@ -1367,20 +1145,9 @@ goto_programt::const_targett goto_program2codet::convert_goto_if( return --target; } -/*******************************************************************\ - -Function: goto_program2codet::convert_goto_break_continue - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - goto_programt::const_targett goto_program2codet::convert_goto_break_continue( goto_programt::const_targett target, + goto_programt::const_targett upper_bound, codet &dest) { assert(!loop_last_stack.empty()); @@ -1390,7 +1157,7 @@ goto_programt::const_targett goto_program2codet::convert_goto_break_continue( // 1: ... goto_programt::const_targett next=target; for(++next; - next!=goto_program.instructions.end(); + next!=upper_bound && next!=goto_program.instructions.end(); ++next) { cfg_dominatorst::cfgt::entry_mapt::const_iterator i_entry= @@ -1467,18 +1234,6 @@ goto_programt::const_targett goto_program2codet::convert_goto_break_continue( return convert_goto_goto(target, dest); } -/*******************************************************************\ - -Function: goto_program2codet::convert_goto_goto - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - goto_programt::const_targett goto_program2codet::convert_goto_goto( goto_programt::const_targett target, codet &dest) @@ -1538,18 +1293,6 @@ goto_programt::const_targett goto_program2codet::convert_goto_goto( return target; } -/*******************************************************************\ - -Function: goto_program2codet::convert_start_thread - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - goto_programt::const_targett goto_program2codet::convert_start_thread( goto_programt::const_targett target, goto_programt::const_targett upper_bound, @@ -1635,7 +1378,7 @@ goto_programt::const_targett goto_program2codet::convert_start_thread( // we don't bother setting the type f.lhs()=cf.lhs(); f.function()=symbol_exprt("pthread_create", code_typet()); - exprt n=null_pointer_exprt(pointer_typet(empty_typet())); + exprt n=null_pointer_exprt(pointer_type(empty_typet())); f.arguments().push_back(n); f.arguments().push_back(n); f.arguments().push_back(cf.function()); @@ -1668,18 +1411,6 @@ goto_programt::const_targett goto_program2codet::convert_start_thread( return thread_end; } -/*******************************************************************\ - -Function: goto_program2codet::convert_throw - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - goto_programt::const_targett goto_program2codet::convert_throw( goto_programt::const_targett target, codet &dest) @@ -1689,18 +1420,6 @@ goto_programt::const_targett goto_program2codet::convert_throw( return target; } -/*******************************************************************\ - -Function: goto_program2codet::convert_catch - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - goto_programt::const_targett goto_program2codet::convert_catch( goto_programt::const_targett target, goto_programt::const_targett upper_bound, @@ -1711,18 +1430,6 @@ goto_programt::const_targett goto_program2codet::convert_catch( return target; } -/*******************************************************************\ - -Function: goto_program2codet::add_local_types - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void goto_program2codet::add_local_types(const typet &type) { if(type.id()==ID_symbol) @@ -1778,18 +1485,6 @@ void goto_program2codet::add_local_types(const typet &type) } } -/*******************************************************************\ - -Function: goto_program2codet::cleanup_code - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void goto_program2codet::cleanup_code( codet &code, const irep_idt parent_stmt) @@ -1818,6 +1513,11 @@ void goto_program2codet::cleanup_code( add_local_types(code.op0().type()); + const irep_idt &typedef_str=code.op0().type().get(ID_C_typedef); + if(!typedef_str.empty() && + typedef_names.find(typedef_str)==typedef_names.end()) + code.op0().type().remove(ID_C_typedef); + return; } else if(code.get_statement()==ID_function_call) @@ -1877,18 +1577,6 @@ void goto_program2codet::cleanup_code( } } -/*******************************************************************\ - -Function: goto_program2codet::cleanup_function_call - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void goto_program2codet::cleanup_function_call( const exprt &function, code_function_callt::argumentst &arguments) @@ -1919,18 +1607,6 @@ void goto_program2codet::cleanup_function_call( } } -/*******************************************************************\ - -Function: goto_program2codet::cleanup_code_block - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void goto_program2codet::cleanup_code_block( codet &code, const irep_idt parent_stmt) @@ -1984,18 +1660,6 @@ void goto_program2codet::cleanup_code_block( } } -/*******************************************************************\ - -Function: goto_program2codet::remove_const - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void goto_program2codet::remove_const(typet &type) { if(type.get_bool(ID_C_constant)) @@ -2030,18 +1694,6 @@ void goto_program2codet::remove_const(typet &type) } } -/*******************************************************************\ - -Function: has_labels - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - static bool has_labels(const codet &code) { if(code.get_statement()==ID_label) @@ -2054,18 +1706,6 @@ static bool has_labels(const codet &code) return false; } -/*******************************************************************\ - -Function: move_label_ifthenelse - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - static bool move_label_ifthenelse( exprt &expr, exprt &label_dest) @@ -2091,18 +1731,6 @@ static bool move_label_ifthenelse( return true; } -/*******************************************************************\ - -Function: goto_program2codet::cleanup_code_ifthenelse - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void goto_program2codet::cleanup_code_ifthenelse( codet &code, const irep_idt parent_stmt) @@ -2199,18 +1827,6 @@ void goto_program2codet::cleanup_code_ifthenelse( code=code_skipt(); } -/*******************************************************************\ - -Function: goto_program2codet::cleanup_expr - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void goto_program2codet::cleanup_expr(exprt &expr, bool no_typecast) { // we might have to do array -> pointer conversions @@ -2257,6 +1873,11 @@ void goto_program2codet::cleanup_expr(exprt &expr, bool no_typecast) add_local_types(t); expr=typecast_exprt(expr, t); + + const irep_idt &typedef_str=expr.type().get(ID_C_typedef); + if(!typedef_str.empty() && + typedef_names.find(typedef_str)==typedef_names.end()) + expr.type().remove(ID_C_typedef); } else if(expr.id()==ID_array || expr.id()==ID_vector) @@ -2269,6 +1890,11 @@ void goto_program2codet::cleanup_expr(exprt &expr, bool no_typecast) expr.make_typecast(t); add_local_types(t); + + const irep_idt &typedef_str=expr.type().get(ID_C_typedef); + if(!typedef_str.empty() && + typedef_names.find(typedef_str)==typedef_names.end()) + expr.type().remove(ID_C_typedef); } else if(expr.id()==ID_side_effect) { @@ -2384,6 +2010,11 @@ void goto_program2codet::cleanup_expr(exprt &expr, bool no_typecast) { add_local_types(expr.type()); + const irep_idt &typedef_str=expr.type().get(ID_C_typedef); + if(!typedef_str.empty() && + typedef_names.find(typedef_str)==typedef_names.end()) + expr.type().remove(ID_C_typedef); + assert(expr.type().id()!=ID_union && expr.type().id()!=ID_struct); } diff --git a/src/goto-instrument/goto_program2code.h b/src/goto-instrument/goto_program2code.h index d39dfc4e5d1..2093774b709 100644 --- a/src/goto-instrument/goto_program2code.h +++ b/src/goto-instrument/goto_program2code.h @@ -6,10 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Dump Goto-Program as C/C++ Source + #ifndef CPROVER_GOTO_INSTRUMENT_GOTO_PROGRAM2CODE_H #define CPROVER_GOTO_INSTRUMENT_GOTO_PROGRAM2CODE_H #include +#include #include @@ -49,6 +53,7 @@ class goto_program2codet code_blockt &_dest, id_listt &_local_static, id_listt &_type_names, + const id_sett &_typedef_names, std::set &_system_headers): func_name(identifier), goto_program(_goto_program), @@ -57,6 +62,7 @@ class goto_program2codet toplevel_block(_dest), local_static(_local_static), type_names(_type_names), + typedef_names(_typedef_names), system_headers(_system_headers) { assert(local_static.empty()); @@ -78,6 +84,7 @@ class goto_program2codet code_blockt &toplevel_block; id_listt &local_static; id_listt &type_names; + const id_sett &typedef_names; std::set &system_headers; std::unordered_set va_list_expr; @@ -193,6 +200,7 @@ class goto_program2codet goto_programt::const_targett convert_goto_break_continue( goto_programt::const_targett target, + goto_programt::const_targett upper_bound, codet &dest); goto_programt::const_targett convert_goto_goto( diff --git a/src/goto-instrument/havoc_loops.cpp b/src/goto-instrument/havoc_loops.cpp index 88cb37075ad..d612a31fc03 100644 --- a/src/goto-instrument/havoc_loops.cpp +++ b/src/goto-instrument/havoc_loops.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Havoc Loops + +#include "havoc_loops.h" + #include #include @@ -14,7 +19,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include "function_modifies.h" -#include "havoc_loops.h" class havoc_loopst { @@ -59,18 +63,6 @@ class havoc_loopst goto_programt::targett get_loop_exit(const loopt &); }; -/*******************************************************************\ - -Function: havoc_loopst::get_loop_exit - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - goto_programt::targett havoc_loopst::get_loop_exit(const loopt &loop) { assert(!loop.empty()); @@ -89,18 +81,6 @@ goto_programt::targett havoc_loopst::get_loop_exit(const loopt &loop) return ++last; } -/*******************************************************************\ - -Function: havoc_loopst::build_havoc_code - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void havoc_loopst::build_havoc_code( const goto_programt::targett loop_head, const modifiest &modifies, @@ -122,18 +102,6 @@ void havoc_loopst::build_havoc_code( } } -/*******************************************************************\ - -Function: havoc_loopst::havoc_loop - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void havoc_loopst::havoc_loop( const goto_programt::targett loop_head, const loopt &loop) @@ -144,7 +112,7 @@ void havoc_loopst::havoc_loop( modifiest modifies; get_modifies(loop, modifies); - // build the havoc-ing code + // build the havocking code goto_programt havoc_code; build_havoc_code(loop_head, modifies, havoc_code); @@ -178,18 +146,6 @@ void havoc_loopst::havoc_loop( remove_skip(goto_function.body); } -/*******************************************************************\ - -Function: havoc_loopst::get_modifies - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void havoc_loopst::get_modifies( const loopt &loop, modifiest &modifies) @@ -220,18 +176,6 @@ void havoc_loopst::get_modifies( } } -/*******************************************************************\ - -Function: havoc_loopst::havoc_loops - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void havoc_loopst::havoc_loops() { // iterate over the (natural) loops in the function @@ -240,18 +184,6 @@ void havoc_loopst::havoc_loops() havoc_loop(loop.first, loop.second); } -/*******************************************************************\ - -Function: havoc_loops - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void havoc_loops(goto_functionst &goto_functions) { function_modifiest function_modifies(goto_functions); diff --git a/src/goto-instrument/havoc_loops.h b/src/goto-instrument/havoc_loops.h index 901e75d4fe5..dc3245a1162 100644 --- a/src/goto-instrument/havoc_loops.h +++ b/src/goto-instrument/havoc_loops.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Havoc Loops + #ifndef CPROVER_GOTO_INSTRUMENT_HAVOC_LOOPS_H #define CPROVER_GOTO_INSTRUMENT_HAVOC_LOOPS_H diff --git a/src/goto-instrument/horn_encoding.cpp b/src/goto-instrument/horn_encoding.cpp index c72f5db9af8..31fcb187848 100644 --- a/src/goto-instrument/horn_encoding.cpp +++ b/src/goto-instrument/horn_encoding.cpp @@ -8,21 +8,12 @@ Date: June 2015 \*******************************************************************/ -#include +/// \file +/// Horn-clause Encoding #include "horn_encoding.h" -/*******************************************************************\ - -Function: horn_encoding - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void horn_encoding( const goto_functionst &, diff --git a/src/goto-instrument/horn_encoding.h b/src/goto-instrument/horn_encoding.h index e6db93159be..44160c35ceb 100644 --- a/src/goto-instrument/horn_encoding.h +++ b/src/goto-instrument/horn_encoding.h @@ -6,6 +6,9 @@ Module: Horn-clause Encoding \*******************************************************************/ +/// \file +/// Horn-clause Encoding + #ifndef CPROVER_GOTO_INSTRUMENT_HORN_ENCODING_H #define CPROVER_GOTO_INSTRUMENT_HORN_ENCODING_H diff --git a/src/goto-instrument/interrupt.cpp b/src/goto-instrument/interrupt.cpp index 8fa40380617..38a5a258ff6 100644 --- a/src/goto-instrument/interrupt.cpp +++ b/src/goto-instrument/interrupt.cpp @@ -8,6 +8,11 @@ Date: September 2011 \*******************************************************************/ +/// \file +/// Interrupt Instrumentation + +#include "interrupt.h" + #include #include #include @@ -16,25 +21,12 @@ Date: September 2011 #include -#include "interrupt.h" #include "rw_set.h" #ifdef LOCAL_MAY #include #endif -/*******************************************************************\ - -Function: poential_race_on_read - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool potential_race_on_read( const rw_set_baset &code_rw_set, const rw_set_baset &isr_rw_set) @@ -49,18 +41,6 @@ bool potential_race_on_read( return false; } -/*******************************************************************\ - -Function: poential_race_on_write - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool potential_race_on_write( const rw_set_baset &code_rw_set, const rw_set_baset &isr_rw_set) @@ -78,18 +58,6 @@ bool potential_race_on_write( return false; } -/*******************************************************************\ - -Function: interrupt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interrupt( value_setst &value_sets, const symbol_tablet &symbol_table, @@ -185,18 +153,6 @@ void interrupt( } } -/*******************************************************************\ - -Function: get_isr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - symbol_exprt get_isr( const symbol_tablet &symbol_table, const irep_idt &interrupt_handler) @@ -231,18 +187,6 @@ symbol_exprt get_isr( return isr; } -/*******************************************************************\ - -Function: interrupt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interrupt( value_setst &value_sets, const symbol_tablet &symbol_table, diff --git a/src/goto-instrument/interrupt.h b/src/goto-instrument/interrupt.h index b37cfcf8854..711c4fa32df 100644 --- a/src/goto-instrument/interrupt.h +++ b/src/goto-instrument/interrupt.h @@ -8,6 +8,9 @@ Date: September 2011 \*******************************************************************/ +/// \file +/// Interrupt Instrumentation for Goto Programs + #ifndef CPROVER_GOTO_INSTRUMENT_INTERRUPT_H #define CPROVER_GOTO_INSTRUMENT_INTERRUPT_H diff --git a/src/goto-instrument/k_induction.cpp b/src/goto-instrument/k_induction.cpp index 92ab83e51b1..9a018e1c331 100644 --- a/src/goto-instrument/k_induction.cpp +++ b/src/goto-instrument/k_induction.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// k-induction + +#include "k_induction.h" + #include #include @@ -15,7 +20,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "unwind.h" #include "loop_utils.h" -#include "k_induction.h" class k_inductiont { @@ -49,18 +53,6 @@ class k_inductiont const loopt &); }; -/*******************************************************************\ - -Function: k_inductiont::process_loop - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void k_inductiont::process_loop( const goto_programt::targett loop_head, const loopt &loop) @@ -79,7 +71,7 @@ void k_inductiont::process_loop( // now unwind k times goto_unwindt goto_unwind; goto_unwind.unwind(goto_function.body, loop_head, loop_exit, k, - goto_unwindt::PARTIAL); + goto_unwindt::unwind_strategyt::PARTIAL); // assume the loop condition has become false goto_programt::instructiont assume(ASSUME); @@ -95,7 +87,7 @@ void k_inductiont::process_loop( modifiest modifies; get_modifies(local_may_alias, loop, modifies); - // build the havoc-ing code + // build the havocking code goto_programt havoc_code; build_havoc_code(loop_head, modifies, havoc_code); @@ -103,8 +95,13 @@ void k_inductiont::process_loop( std::vector iteration_points; goto_unwindt goto_unwind; - goto_unwind.unwind(goto_function.body, loop_head, loop_exit, k+1, - goto_unwindt::PARTIAL, iteration_points); + goto_unwind.unwind( + goto_function.body, + loop_head, + loop_exit, + k+1, + goto_unwindt::unwind_strategyt::PARTIAL, + iteration_points); // we can remove everything up to the first assertion for(goto_programt::targett t=loop_head; t!=loop_exit; t++) @@ -141,18 +138,6 @@ void k_inductiont::process_loop( remove_skip(goto_function.body); } -/*******************************************************************\ - -Function: k_inductiont::k_induction - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void k_inductiont::k_induction() { // iterate over the (natural) loops in the function @@ -164,18 +149,6 @@ void k_inductiont::k_induction() process_loop(l_it->first, l_it->second); } -/*******************************************************************\ - -Function: k_induction - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void k_induction( goto_functionst &goto_functions, bool base_case, bool step_case, diff --git a/src/goto-instrument/k_induction.h b/src/goto-instrument/k_induction.h index 5c5918f923a..e5af8b0c43f 100644 --- a/src/goto-instrument/k_induction.h +++ b/src/goto-instrument/k_induction.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// k-induction + #ifndef CPROVER_GOTO_INSTRUMENT_K_INDUCTION_H #define CPROVER_GOTO_INSTRUMENT_K_INDUCTION_H diff --git a/src/goto-instrument/loop_utils.cpp b/src/goto-instrument/loop_utils.cpp index 90981198321..ee02a3b1695 100644 --- a/src/goto-instrument/loop_utils.cpp +++ b/src/goto-instrument/loop_utils.cpp @@ -6,24 +6,15 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - -#include -#include +/// \file +/// Helper functions for k-induction and loop invariants #include "loop_utils.h" -/*******************************************************************\ - -Function: get_loop_exit - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include +#include goto_programt::targett get_loop_exit(const loopt &loop) { @@ -43,18 +34,6 @@ goto_programt::targett get_loop_exit(const loopt &loop) return ++last; } -/*******************************************************************\ - -Function: build_havoc_code - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void build_havoc_code( const goto_programt::targett loop_head, const modifiest &modifies, @@ -76,18 +55,6 @@ void build_havoc_code( } } -/*******************************************************************\ - -Function: get_modifies_lhs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static void get_modifies_lhs( const local_may_aliast &local_may_alias, goto_programt::const_targett t, @@ -118,18 +85,6 @@ static void get_modifies_lhs( } } -/*******************************************************************\ - -Function: get_modifies - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void get_modifies( const local_may_aliast &local_may_alias, const loopt &loop, diff --git a/src/goto-instrument/loop_utils.h b/src/goto-instrument/loop_utils.h index e6558291c4d..57407ecec1b 100644 --- a/src/goto-instrument/loop_utils.h +++ b/src/goto-instrument/loop_utils.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Helper functions for k-induction and loop invariants + #ifndef CPROVER_GOTO_INSTRUMENT_LOOP_UTILS_H #define CPROVER_GOTO_INSTRUMENT_LOOP_UTILS_H diff --git a/src/goto-instrument/mmio.cpp b/src/goto-instrument/mmio.cpp index b66633146a0..a7a21a2f1a9 100644 --- a/src/goto-instrument/mmio.cpp +++ b/src/goto-instrument/mmio.cpp @@ -8,6 +8,11 @@ Date: September 2011 \*******************************************************************/ +/// \file +/// Memory-mapped I/O Instrumentation for Goto Programs + +#include "mmio.h" + #include #include @@ -28,20 +33,6 @@ Date: September 2011 #include #endif -#include "mmio.h" - -/*******************************************************************\ - -Function: mmio - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void mmio( value_setst &value_sets, const symbol_tablet &symbol_table, @@ -171,18 +162,6 @@ void mmio( } } -/*******************************************************************\ - -Function: mmio - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void mmio( value_setst &value_sets, class symbol_tablet &symbol_table, diff --git a/src/goto-instrument/mmio.h b/src/goto-instrument/mmio.h index bb3684c4a34..eab567f9873 100644 --- a/src/goto-instrument/mmio.h +++ b/src/goto-instrument/mmio.h @@ -8,6 +8,9 @@ Date: September 2011 \*******************************************************************/ +/// \file +/// Memory-mapped I/O Instrumentation for Goto Programs + #ifndef CPROVER_GOTO_INSTRUMENT_MMIO_H #define CPROVER_GOTO_INSTRUMENT_MMIO_H diff --git a/src/goto-instrument/model_argc_argv.cpp b/src/goto-instrument/model_argc_argv.cpp index 113c6d46a81..7e01d66e62a 100644 --- a/src/goto-instrument/model_argc_argv.cpp +++ b/src/goto-instrument/model_argc_argv.cpp @@ -8,6 +8,11 @@ Date: April 2016 \*******************************************************************/ +/// \file +/// Initialize command line arguments + +#include "model_argc_argv.h" + #include #include @@ -24,20 +29,6 @@ Date: April 2016 #include #include -#include "model_argc_argv.h" - -/*******************************************************************\ - -Function: model_argc_argv - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool model_argc_argv( symbol_tablet &symbol_table, goto_functionst &goto_functions, @@ -47,7 +38,7 @@ bool model_argc_argv( messaget message(message_handler); const namespacet ns(symbol_table); - const symbolt *init_symbol=0; + const symbolt *init_symbol=nullptr; if(ns.lookup(CPROVER_PREFIX "initialize", init_symbol)) { message.error() << "Linking not done, missing " diff --git a/src/goto-instrument/model_argc_argv.h b/src/goto-instrument/model_argc_argv.h index 0b47c68555e..08a214f6fd6 100644 --- a/src/goto-instrument/model_argc_argv.h +++ b/src/goto-instrument/model_argc_argv.h @@ -8,6 +8,9 @@ Date: April 2016 \*******************************************************************/ +/// \file +/// Initialize command line arguments + #ifndef CPROVER_GOTO_INSTRUMENT_MODEL_ARGC_ARGV_H #define CPROVER_GOTO_INSTRUMENT_MODEL_ARGC_ARGV_H diff --git a/src/goto-instrument/nondet_static.cpp b/src/goto-instrument/nondet_static.cpp index 90eb8ab3c08..e5e3b7649cf 100644 --- a/src/goto-instrument/nondet_static.cpp +++ b/src/goto-instrument/nondet_static.cpp @@ -9,6 +9,11 @@ Date: November 2011 \*******************************************************************/ +/// \file +/// Nondeterministic initialization of certain global scope variables + +#include "nondet_static.h" + #include #include #include @@ -16,20 +21,6 @@ Date: November 2011 #include -#include "nondet_static.h" - -/*******************************************************************\ - -Function: nondet_static - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void nondet_static( const namespacet &ns, goto_functionst &goto_functions, @@ -80,18 +71,6 @@ void nondet_static( } -/*******************************************************************\ - -Function: nondet_static - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void nondet_static( const namespacet &ns, goto_functionst &goto_functions) diff --git a/src/goto-instrument/nondet_static.h b/src/goto-instrument/nondet_static.h index 274b9cc5c91..97f3f0e683b 100644 --- a/src/goto-instrument/nondet_static.h +++ b/src/goto-instrument/nondet_static.h @@ -9,6 +9,9 @@ Date: November 2011 \*******************************************************************/ +/// \file +/// Nondeterministic initialization of certain global scope variables + #ifndef CPROVER_GOTO_INSTRUMENT_NONDET_STATIC_H #define CPROVER_GOTO_INSTRUMENT_NONDET_STATIC_H diff --git a/src/goto-instrument/nondet_volatile.cpp b/src/goto-instrument/nondet_volatile.cpp index 43969dfa9d2..4da1ebf6731 100644 --- a/src/goto-instrument/nondet_volatile.cpp +++ b/src/goto-instrument/nondet_volatile.cpp @@ -8,22 +8,13 @@ Date: September 2011 \*******************************************************************/ -#include -#include +/// \file +/// Volatile Variables #include "nondet_volatile.h" -/*******************************************************************\ - -Function: is_volatile - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include bool is_volatile( const symbol_tablet &symbol_table, @@ -43,18 +34,6 @@ bool is_volatile( return false; } -/*******************************************************************\ - -Function: nondet_volatile_rhs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void nondet_volatile_rhs(const symbol_tablet &symbol_table, exprt &expr) { Forall_operands(it, expr) @@ -75,18 +54,6 @@ void nondet_volatile_rhs(const symbol_tablet &symbol_table, exprt &expr) } } -/*******************************************************************\ - -Function: nondet_volatile_lhs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void nondet_volatile_lhs(const symbol_tablet &symbol_table, exprt &expr) { if(expr.id()==ID_if) @@ -110,18 +77,6 @@ void nondet_volatile_lhs(const symbol_tablet &symbol_table, exprt &expr) } } -/*******************************************************************\ - -Function: nondet_volatile - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void nondet_volatile( symbol_tablet &symbol_table, goto_programt &goto_program) @@ -164,18 +119,6 @@ void nondet_volatile( } } -/*******************************************************************\ - -Function: nondet_volatile - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void nondet_volatile( symbol_tablet &symbol_table, goto_functionst &goto_functions) diff --git a/src/goto-instrument/nondet_volatile.h b/src/goto-instrument/nondet_volatile.h index 1a4457d6842..8cb3930fd56 100644 --- a/src/goto-instrument/nondet_volatile.h +++ b/src/goto-instrument/nondet_volatile.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Volatile Variables + #ifndef CPROVER_GOTO_INSTRUMENT_NONDET_VOLATILE_H #define CPROVER_GOTO_INSTRUMENT_NONDET_VOLATILE_H diff --git a/src/goto-instrument/object_id.cpp b/src/goto-instrument/object_id.cpp index f8fa7de4ca0..f63581bcd38 100644 --- a/src/goto-instrument/object_id.cpp +++ b/src/goto-instrument/object_id.cpp @@ -6,21 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "object_id.h" - -/*******************************************************************\ - -Function: get_objects_rec - - Inputs: - - Outputs: - - Purpose: +/// \file +/// Object Identifiers -\*******************************************************************/ +#include "object_id.h" -typedef enum { LHS_R, LHS_W, READ } get_modet; +enum class get_modet { LHS_R, LHS_W, READ }; void get_objects_rec( get_modet mode, @@ -30,18 +21,18 @@ void get_objects_rec( { if(expr.id()==ID_symbol) { - if(mode==LHS_W || mode==READ) + if(mode==get_modet::LHS_W || mode==get_modet::READ) dest.insert(object_idt(to_symbol_expr(expr))); } else if(expr.id()==ID_index) { const index_exprt &index_expr=to_index_expr(expr); - if(mode==LHS_R || mode==READ) - get_objects_rec(READ, index_expr.index(), dest, ""); + if(mode==get_modet::LHS_R || mode==get_modet::READ) + get_objects_rec(get_modet::READ, index_expr.index(), dest, ""); - if(mode==LHS_R) - get_objects_rec(READ, index_expr.array(), dest, "[]"+suffix); + if(mode==get_modet::LHS_R) + get_objects_rec(get_modet::READ, index_expr.array(), dest, "[]"+suffix); else get_objects_rec(mode, index_expr.array(), dest, "[]"+suffix); } @@ -49,8 +40,8 @@ void get_objects_rec( { const if_exprt &if_expr=to_if_expr(expr); - if(mode==LHS_R || mode==READ) - get_objects_rec(READ, if_expr.cond(), dest, ""); + if(mode==get_modet::LHS_R || mode==get_modet::READ) + get_objects_rec(get_modet::READ, if_expr.cond(), dest, ""); get_objects_rec(mode, if_expr.true_case(), dest, suffix); get_objects_rec(mode, if_expr.false_case(), dest, suffix); @@ -67,99 +58,39 @@ void get_objects_rec( const dereference_exprt &dereference_expr= to_dereference_expr(expr); - if(mode==LHS_R || mode==READ) - get_objects_rec(READ, dereference_expr.pointer(), dest, ""); + if(mode==get_modet::LHS_R || mode==get_modet::READ) + get_objects_rec(get_modet::READ, dereference_expr.pointer(), dest, ""); } else { - if(mode==LHS_R || mode==READ) + if(mode==get_modet::LHS_R || mode==get_modet::READ) forall_operands(it, expr) - get_objects_rec(READ, *it, dest, ""); + get_objects_rec(get_modet::READ, *it, dest, ""); } } -/*******************************************************************\ - -Function: get_objects - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void get_objects(const exprt &expr, object_id_sett &dest) { - get_objects_rec(READ, expr, dest, ""); + get_objects_rec(get_modet::READ, expr, dest, ""); } -/*******************************************************************\ - -Function: get_objects_r - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void get_objects_r(const code_assignt &assign, object_id_sett &dest) { - get_objects_rec(LHS_R, assign.lhs(), dest, ""); - get_objects_rec(READ, assign.rhs(), dest, ""); + get_objects_rec(get_modet::LHS_R, assign.lhs(), dest, ""); + get_objects_rec(get_modet::READ, assign.rhs(), dest, ""); } -/*******************************************************************\ - -Function: get_objects_w - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void get_objects_w(const code_assignt &assign, object_id_sett &dest) { - get_objects_rec(LHS_W, assign.lhs(), dest, ""); + get_objects_rec(get_modet::LHS_W, assign.lhs(), dest, ""); } -/*******************************************************************\ - -Function: get_objects_w_lhs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void get_objects_w(const exprt &lhs, object_id_sett &dest) { - get_objects_rec(LHS_W, lhs, dest, ""); + get_objects_rec(get_modet::LHS_W, lhs, dest, ""); } -/*******************************************************************\ - -Function: get_objects_r_lhs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void get_objects_r_lhs(const exprt &lhs, object_id_sett &dest) { - get_objects_rec(LHS_R, lhs, dest, ""); + get_objects_rec(get_modet::LHS_R, lhs, dest, ""); } diff --git a/src/goto-instrument/object_id.h b/src/goto-instrument/object_id.h index ac928e29b5f..f7c597a798b 100644 --- a/src/goto-instrument/object_id.h +++ b/src/goto-instrument/object_id.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Object Identifiers + #ifndef CPROVER_GOTO_INSTRUMENT_OBJECT_ID_H #define CPROVER_GOTO_INSTRUMENT_OBJECT_ID_H diff --git a/src/goto-instrument/points_to.cpp b/src/goto-instrument/points_to.cpp index da29e800292..843d5755aee 100644 --- a/src/goto-instrument/points_to.cpp +++ b/src/goto-instrument/points_to.cpp @@ -6,19 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "points_to.h" - -/*******************************************************************\ - -Function: points_tot::fixedpoint - - Inputs: - - Outputs: - - Purpose: +/// \file +/// Field-sensitive, location-insensitive points-to analysis -\*******************************************************************/ +#include "points_to.h" void points_tot::fixedpoint() { @@ -42,18 +33,6 @@ void points_tot::fixedpoint() while(added); } -/*******************************************************************\ - -Function: points_tot::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void points_tot::output(std::ostream &out) const { for(value_mapt::const_iterator @@ -71,22 +50,10 @@ void points_tot::output(std::ostream &out) const out << " " << *o_it; } - out << std::endl; + out << '\n'; } } -/*******************************************************************\ - -Function: points_tot::transform - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool points_tot::transform(const cfgt::nodet &e) { bool result=false; diff --git a/src/goto-instrument/points_to.h b/src/goto-instrument/points_to.h index 4805de2343c..8b4a47d980a 100644 --- a/src/goto-instrument/points_to.h +++ b/src/goto-instrument/points_to.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Field-sensitive, location-insensitive points-to analysis + #ifndef CPROVER_GOTO_INSTRUMENT_POINTS_TO_H #define CPROVER_GOTO_INSTRUMENT_POINTS_TO_H @@ -16,14 +19,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "object_id.h" -/*******************************************************************\ - - Class: points_tot - - Purpose: - -\*******************************************************************/ - class points_tot { public: diff --git a/src/goto-instrument/race_check.cpp b/src/goto-instrument/race_check.cpp index 8f26d89bf56..aec5eedda53 100644 --- a/src/goto-instrument/race_check.cpp +++ b/src/goto-instrument/race_check.cpp @@ -8,6 +8,11 @@ Date: February 2006 \*******************************************************************/ +/// \file +/// Race Detection for Threaded Goto Programs + +#include "race_check.h" + #include #include #include @@ -20,7 +25,6 @@ Date: February 2006 #include #include -#include "race_check.h" #include "rw_set.h" #ifdef LOCAL_MAY @@ -64,18 +68,6 @@ class w_guardst symbol_tablet &symbol_table; }; -/*******************************************************************\ - -Function: w_guardst::get_guard_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const symbolt &w_guardst::get_guard_symbol(const irep_idt &object) { const irep_idt identifier=id2string(object)+"$w_guard"; @@ -100,18 +92,6 @@ const symbolt &w_guardst::get_guard_symbol(const irep_idt &object) return *symbol_ptr; } -/*******************************************************************\ - -Function: w_guardst::add_initialization - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void w_guardst::add_initialization(goto_programt &goto_program) const { goto_programt::targett t=goto_program.instructions.begin(); @@ -132,18 +112,6 @@ void w_guardst::add_initialization(goto_programt &goto_program) const } } -/*******************************************************************\ - -Function: comment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string comment(const rw_set_baset::entryt &entry, bool write) { std::string result; @@ -157,18 +125,6 @@ std::string comment(const rw_set_baset::entryt &entry, bool write) return result; } -/*******************************************************************\ - -Function: is_shared - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool is_shared( const namespacet &ns, const symbol_exprt &symbol_expr) @@ -189,18 +145,6 @@ bool is_shared( return symbol.is_shared(); } -/*******************************************************************\ - -Function: race_check - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool has_shared_entries( const namespacet &ns, const rw_set_baset &rw_set) @@ -222,18 +166,6 @@ bool has_shared_entries( return false; } -/*******************************************************************\ - -Function: race_check - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void race_check( value_setst &value_sets, symbol_tablet &symbol_table, @@ -339,18 +271,6 @@ void race_check( remove_skip(goto_program); } -/*******************************************************************\ - -Function: race_check - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void race_check( value_setst &value_sets, symbol_tablet &symbol_table, @@ -372,18 +292,6 @@ void race_check( goto_program.update(); } -/*******************************************************************\ - -Function: race_check - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void race_check( value_setst &value_sets, symbol_tablet &symbol_table, diff --git a/src/goto-instrument/race_check.h b/src/goto-instrument/race_check.h index 1c7cd3e5be8..442d142ddc0 100644 --- a/src/goto-instrument/race_check.h +++ b/src/goto-instrument/race_check.h @@ -8,6 +8,9 @@ Date: February 2006 \*******************************************************************/ +/// \file +/// Race Detection for Threaded Goto Programs + #ifndef CPROVER_GOTO_INSTRUMENT_RACE_CHECK_H #define CPROVER_GOTO_INSTRUMENT_RACE_CHECK_H diff --git a/src/goto-instrument/reachability_slicer.cpp b/src/goto-instrument/reachability_slicer.cpp index 073f9284add..c92333e31a3 100644 --- a/src/goto-instrument/reachability_slicer.cpp +++ b/src/goto-instrument/reachability_slicer.cpp @@ -6,29 +6,20 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Slicer +#include "reachability_slicer.h" + +#include #include #include #include #include "full_slicer_class.h" -#include "reachability_slicer.h" #include "reachability_slicer_class.h" -/*******************************************************************\ - -Function: reachability_slicert::fixedpoint_assertions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void reachability_slicert::fixedpoint_assertions( const is_threadedt &is_threaded, slicing_criteriont &criterion) @@ -64,18 +55,6 @@ void reachability_slicert::fixedpoint_assertions( } } -/*******************************************************************\ - -Function: reachability_slicert::slice - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void reachability_slicert::slice(goto_functionst &goto_functions) { // now replace those instructions that do not reach any assertions @@ -101,18 +80,6 @@ void reachability_slicert::slice(goto_functionst &goto_functions) goto_functions.update(); } -/*******************************************************************\ - -Function: reachability_slicer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void reachability_slicer(goto_functionst &goto_functions) { reachability_slicert s; @@ -120,18 +87,6 @@ void reachability_slicer(goto_functionst &goto_functions) s(goto_functions, a); } -/*******************************************************************\ - -Function: reachability_slicer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void reachability_slicer( goto_functionst &goto_functions, const std::list &properties) diff --git a/src/goto-instrument/reachability_slicer.h b/src/goto-instrument/reachability_slicer.h index e45aa81f27e..4d82e4b194e 100644 --- a/src/goto-instrument/reachability_slicer.h +++ b/src/goto-instrument/reachability_slicer.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Slicing + #ifndef CPROVER_GOTO_INSTRUMENT_REACHABILITY_SLICER_H #define CPROVER_GOTO_INSTRUMENT_REACHABILITY_SLICER_H diff --git a/src/goto-instrument/reachability_slicer_class.h b/src/goto-instrument/reachability_slicer_class.h index 224259b57cd..4f21049892e 100644 --- a/src/goto-instrument/reachability_slicer_class.h +++ b/src/goto-instrument/reachability_slicer_class.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Goto Program Slicing + #ifndef CPROVER_GOTO_INSTRUMENT_REACHABILITY_SLICER_CLASS_H #define CPROVER_GOTO_INSTRUMENT_REACHABILITY_SLICER_CLASS_H @@ -16,14 +19,6 @@ Author: Daniel Kroening, kroening@kroening.com class slicing_criteriont; -/*******************************************************************\ - - Class: reachability_slicert - - Purpose: - -\*******************************************************************/ - class reachability_slicert { public: diff --git a/src/goto-instrument/remove_function.cpp b/src/goto-instrument/remove_function.cpp new file mode 100644 index 00000000000..131438d1af6 --- /dev/null +++ b/src/goto-instrument/remove_function.cpp @@ -0,0 +1,74 @@ +/*******************************************************************\ + +Module: Remove function definition + +Author: Michael Tautschnig + +Date: April 2017 + +\*******************************************************************/ + +/// \file +/// Remove function definition + +#include "remove_function.h" + +#include + +#include + +/// Remove the body of function "identifier" such that an analysis will treat it +/// as a side-effect free function with non-deterministic return value. +/// \par parameters: symbol_table Input symbol table to be modified +/// goto_functions Input functions to be modified +/// identifier Function to be removed +/// message_handler Error/status output +void remove_function( + symbol_tablet &symbol_table, + goto_functionst &goto_functions, + const irep_idt &identifier, + message_handlert &message_handler) +{ + messaget message(message_handler); + + goto_functionst::function_mapt::iterator entry= + goto_functions.function_map.find(identifier); + + if(entry==goto_functions.function_map.end()) + { + message.error() << "No function " << identifier + << " in goto program" << messaget::eom; + return; + } + else if(entry->second.is_inlined()) + { + message.warning() << "Function " << identifier << " is inlined, " + << "instantiations will not be removed" + << messaget::eom; + } + + if(entry->second.body_available()) + { + message.status() << "Removing body of " << identifier + << messaget::eom; + entry->second.clear(); + symbol_table.lookup(identifier).value.make_nil(); + } +} + +/// Remove the body of all functions listed in "names" such that an analysis +/// will treat it as a side-effect free function with non-deterministic return +/// value. +/// \par parameters: symbol_table Input symbol table to be modified +/// goto_functions Input functions to be modified +/// names List of functions to be removed +/// message_handler Error/status output +void remove_functions( + symbol_tablet &symbol_table, + goto_functionst &goto_functions, + const std::list &names, + message_handlert &message_handler) +{ + for(const auto &f : names) + remove_function(symbol_table, goto_functions, f, message_handler); +} diff --git a/src/goto-instrument/remove_function.h b/src/goto-instrument/remove_function.h new file mode 100644 index 00000000000..e11db1757ba --- /dev/null +++ b/src/goto-instrument/remove_function.h @@ -0,0 +1,38 @@ +/*******************************************************************\ + +Module: Remove function definition + +Author: Michael Tautschnig + +Date: April 2017 + +\*******************************************************************/ + +/// \file +/// Remove function definition + +#ifndef CPROVER_GOTO_INSTRUMENT_REMOVE_FUNCTION_H +#define CPROVER_GOTO_INSTRUMENT_REMOVE_FUNCTION_H + +#include +#include + +#include + +class goto_functionst; +class message_handlert; +class symbol_tablet; + +void remove_function( + symbol_tablet &symbol_table, + goto_functionst &goto_functions, + const irep_idt &identifier, + message_handlert &message_handler); + +void remove_functions( + symbol_tablet &symbol_table, + goto_functionst &goto_functions, + const std::list &names, + message_handlert &message_handler); + +#endif // CPROVER_GOTO_INSTRUMENT_REMOVE_FUNCTION_H diff --git a/src/goto-instrument/rw_set.cpp b/src/goto-instrument/rw_set.cpp index 531a3ea70b4..39681fe5660 100644 --- a/src/goto-instrument/rw_set.cpp +++ b/src/goto-instrument/rw_set.cpp @@ -8,6 +8,11 @@ Date: February 2006 \*******************************************************************/ +/// \file +/// Race Detection for Threaded Goto Programs + +#include "rw_set.h" + #include #include #include @@ -16,55 +21,29 @@ Date: February 2006 #include -#include "rw_set.h" - -/*******************************************************************\ - -Function: rw_set_baset::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rw_set_baset::output(std::ostream &out) const { - out << "READ:" << std::endl; + out << "READ:\n"; for(entriest::const_iterator it=r_entries.begin(); it!=r_entries.end(); it++) { out << it->second.object << " if " - << from_expr(ns, "", it->second.guard) << std::endl; + << from_expr(ns, "", it->second.guard) << '\n'; } - out << std::endl; + out << '\n'; - out << "WRITE:" << std::endl; + out << "WRITE:\n"; for(entriest::const_iterator it=w_entries.begin(); it!=w_entries.end(); it++) { out << it->second.object << " if " - << from_expr(ns, "", it->second.guard) << std::endl; + << from_expr(ns, "", it->second.guard) << '\n'; } } -/*******************************************************************\ - -Function: rw_set_loct::compute - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void _rw_set_loct::compute() { if(target->is_assign()) @@ -97,36 +76,12 @@ void _rw_set_loct::compute() } } -/*******************************************************************\ - -Function: rw_set_loct::assign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void _rw_set_loct::assign(const exprt &lhs, const exprt &rhs) { read(rhs); read_write_rec(lhs, false, true, "", guardt()); } -/*******************************************************************\ - -Function: rw_set_loct::read_write_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void _rw_set_loct::read_write_rec( const exprt &expr, bool r, bool w, @@ -190,7 +145,7 @@ void _rw_set_loct::read_write_rec( { /* as an under-approximation */ // std::cout << "Sorry, LOCAL_MAY too imprecise. " - // << Omitting some variables." << std::endl; + // << Omitting some variables.\n"; irep_idt object=ID_unknown; entryt &entry=r_entries[object]; @@ -240,18 +195,6 @@ void _rw_set_loct::read_write_rec( } } -/*******************************************************************\ - -Function: rw_set_functiont::compute_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rw_set_functiont::compute_rec(const exprt &function) { if(function.id()==ID_symbol) diff --git a/src/goto-instrument/rw_set.h b/src/goto-instrument/rw_set.h index 9322efbfc3e..15c3766f23c 100644 --- a/src/goto-instrument/rw_set.h +++ b/src/goto-instrument/rw_set.h @@ -8,6 +8,9 @@ Date: February 2006 \*******************************************************************/ +/// \file +/// Race Detection for Threaded Goto Programs + #ifndef CPROVER_GOTO_INSTRUMENT_RW_SET_H #define CPROVER_GOTO_INSTRUMENT_RW_SET_H @@ -263,13 +266,13 @@ class rw_set_with_trackt:public _rw_set_loct void track_deref(const entryt &entry, bool read) { - if(dereferencing && dereferenced.size()==0) + if(dereferencing && dereferenced.empty()) { dereferenced.insert(dereferenced.begin(), entry); if(read) set_reads.insert(entry.object); } - else if(dereferencing && dereferenced.size()>0) + else if(dereferencing && !dereferenced.empty()) dereferenced_from.insert( std::make_pair(entry.object, dereferenced.front().object)); } diff --git a/src/goto-instrument/show_locations.cpp b/src/goto-instrument/show_locations.cpp index ef31898e294..b02dcb1b099 100644 --- a/src/goto-instrument/show_locations.cpp +++ b/src/goto-instrument/show_locations.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Show program locations + +#include "show_locations.h" + #include #include @@ -13,20 +18,6 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "show_locations.h" - -/*******************************************************************\ - -Function: show_locations - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void show_locations( ui_message_handlert::uit ui, const irep_idt function_id, @@ -41,7 +32,7 @@ void show_locations( switch(ui) { - case ui_message_handlert::XML_UI: + case ui_message_handlert::uit::XML_UI: { xmlt xml("program_location"); xml.new_element("function").data=id2string(function_id); @@ -55,14 +46,14 @@ void show_locations( l.new_element("function").data= id2string(source_location.get_function()); - std::cout << xml << std::endl; + std::cout << xml << '\n'; } break; - case ui_message_handlert::PLAIN: + case ui_message_handlert::uit::PLAIN: std::cout << function_id << " " << it->location_number << " " - << it->source_location << std::endl; + << it->source_location << '\n'; break; default: @@ -71,18 +62,6 @@ void show_locations( } } -/*******************************************************************\ - -Function: show_locations - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void show_locations( ui_message_handlert::uit ui, const goto_functionst &goto_functions) diff --git a/src/goto-instrument/show_locations.h b/src/goto-instrument/show_locations.h index 60861add675..3f71b19ca48 100644 --- a/src/goto-instrument/show_locations.h +++ b/src/goto-instrument/show_locations.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Show program locations + #ifndef CPROVER_GOTO_INSTRUMENT_SHOW_LOCATIONS_H #define CPROVER_GOTO_INSTRUMENT_SHOW_LOCATIONS_H diff --git a/src/goto-instrument/skip_loops.cpp b/src/goto-instrument/skip_loops.cpp index f79fae9d7b4..d8be5f1e7ef 100644 --- a/src/goto-instrument/skip_loops.cpp +++ b/src/goto-instrument/skip_loops.cpp @@ -8,28 +8,19 @@ Date: January 2016 \*******************************************************************/ +/// \file +/// Skip over selected loops by adding gotos + +#include "skip_loops.h" + #include #include #include -#include "skip_loops.h" - typedef std::set loop_idst; typedef std::map loop_mapt; -/*******************************************************************\ - -Function: skip_loops - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static bool skip_loops( goto_programt &goto_program, const loop_idst &loop_ids, @@ -71,18 +62,6 @@ static bool skip_loops( return false; } -/*******************************************************************\ - -Function: skip_loops - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static bool parse_loop_ids( const std::string &loop_ids, loop_mapt &loop_map) @@ -111,18 +90,6 @@ static bool parse_loop_ids( return false; } -/*******************************************************************\ - -Function: skip_loops - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool skip_loops( goto_functionst &goto_functions, const std::string &loop_ids, diff --git a/src/goto-instrument/skip_loops.h b/src/goto-instrument/skip_loops.h index d2c9af8996f..c5e84c6172c 100644 --- a/src/goto-instrument/skip_loops.h +++ b/src/goto-instrument/skip_loops.h @@ -8,6 +8,9 @@ Date: January 2016 \*******************************************************************/ +/// \file +/// Skip over selected loops by adding gotos + #ifndef CPROVER_GOTO_INSTRUMENT_SKIP_LOOPS_H #define CPROVER_GOTO_INSTRUMENT_SKIP_LOOPS_H diff --git a/src/goto-instrument/stack_depth.cpp b/src/goto-instrument/stack_depth.cpp index 0c5e0f81146..2897a4e6697 100644 --- a/src/goto-instrument/stack_depth.cpp +++ b/src/goto-instrument/stack_depth.cpp @@ -8,6 +8,11 @@ Date: November 2011 \*******************************************************************/ +/// \file +/// Stack depth checks + +#include "stack_depth.h" + #include #include #include @@ -16,20 +21,6 @@ Date: November 2011 #include -#include "stack_depth.h" - -/*******************************************************************\ - -Function: add_stack_depth_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - symbol_exprt add_stack_depth_symbol(symbol_tablet &symbol_table) { const irep_idt identifier="$stack_depth"; @@ -51,18 +42,6 @@ symbol_exprt add_stack_depth_symbol(symbol_tablet &symbol_table) return symbol_exprt(identifier, type); } -/*******************************************************************\ - -Function: stack_depth - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void stack_depth( goto_programt &goto_program, const symbol_exprt &symbol, @@ -103,18 +82,6 @@ void stack_depth( goto_program.insert_before_swap(last, minus_ins); } -/*******************************************************************\ - -Function: stack_depth - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void stack_depth( symbol_tablet &symbol_table, goto_functionst &goto_functions, diff --git a/src/goto-instrument/stack_depth.h b/src/goto-instrument/stack_depth.h index f24964ff611..8d0414121d7 100644 --- a/src/goto-instrument/stack_depth.h +++ b/src/goto-instrument/stack_depth.h @@ -8,6 +8,9 @@ Date: November 2011 \*******************************************************************/ +/// \file +/// Stack depth checks + #ifndef CPROVER_GOTO_INSTRUMENT_STACK_DEPTH_H #define CPROVER_GOTO_INSTRUMENT_STACK_DEPTH_H diff --git a/src/goto-instrument/thread_instrumentation.cpp b/src/goto-instrument/thread_instrumentation.cpp index 4c23234d051..a2943424a33 100644 --- a/src/goto-instrument/thread_instrumentation.cpp +++ b/src/goto-instrument/thread_instrumentation.cpp @@ -6,21 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "thread_instrumentation.h" -/*******************************************************************\ - -Function: has_start_thread - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include static bool has_start_thread(const goto_programt &goto_program) { @@ -31,18 +20,6 @@ static bool has_start_thread(const goto_programt &goto_program) return false; } -/*******************************************************************\ - -Function: thread_exit_instrumentation - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void thread_exit_instrumentation(goto_programt &goto_program) { if(goto_program.instructions.empty()) @@ -66,7 +43,7 @@ void thread_exit_instrumentation(goto_programt &goto_program) binary_exprt get_may("get_may"); // NULL is any - get_may.op0()=constant_exprt(ID_NULL, pointer_typet(empty_typet())); + get_may.op0()=null_pointer_exprt(pointer_type(empty_typet())); get_may.op1()=address_of_exprt(mutex_locked_string); end->make_assertion(not_exprt(get_may)); @@ -76,18 +53,6 @@ void thread_exit_instrumentation(goto_programt &goto_program) end->function=function; } -/*******************************************************************\ - -Function: thread_exit_instrumentation - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void thread_exit_instrumentation(goto_functionst &goto_functions) { // we'll look for START THREAD @@ -117,18 +82,6 @@ void thread_exit_instrumentation(goto_functionst &goto_functions) } } -/*******************************************************************\ - -Function: mutex_init_instrumentation - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void mutex_init_instrumentation( const symbol_tablet &symbol_table, goto_programt &goto_program, @@ -165,18 +118,6 @@ void mutex_init_instrumentation( } } -/*******************************************************************\ - -Function: mutex_init_instrumentation - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void mutex_init_instrumentation( const symbol_tablet &symbol_table, goto_functionst &goto_functions) diff --git a/src/goto-instrument/thread_instrumentation.h b/src/goto-instrument/thread_instrumentation.h index eb9e159b206..c4c92394d72 100644 --- a/src/goto-instrument/thread_instrumentation.h +++ b/src/goto-instrument/thread_instrumentation.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_GOTO_INSTRUMENT_THREAD_INSTRUMENTATION_H #define CPROVER_GOTO_INSTRUMENT_THREAD_INSTRUMENTATION_H diff --git a/src/goto-instrument/undefined_functions.cpp b/src/goto-instrument/undefined_functions.cpp index 53fff3ff84b..f76815d3009 100644 --- a/src/goto-instrument/undefined_functions.cpp +++ b/src/goto-instrument/undefined_functions.cpp @@ -8,23 +8,14 @@ Date: July 2016 \*******************************************************************/ -#include - -#include +/// \file +/// Handling of functions without body #include "undefined_functions.h" -/*******************************************************************\ - -Function: list_undefined_functions - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include void list_undefined_functions( const goto_functionst &goto_functions, @@ -34,21 +25,9 @@ void list_undefined_functions( forall_goto_functions(it, goto_functions) if(!ns.lookup(it->first).is_macro && !it->second.body_available()) - os << it->first << std::endl; + os << it->first << '\n'; } -/*******************************************************************\ - -Function: undefined_function_abort_path - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void undefined_function_abort_path(goto_functionst &goto_functions) { Forall_goto_functions(it, goto_functions) diff --git a/src/goto-instrument/undefined_functions.h b/src/goto-instrument/undefined_functions.h index 7b700c839a0..e9bb9df6f95 100644 --- a/src/goto-instrument/undefined_functions.h +++ b/src/goto-instrument/undefined_functions.h @@ -8,11 +8,16 @@ Date: July 2016 \*******************************************************************/ +/// \file +/// Handling of functions without body + #ifndef CPROVER_UNDEFINED_FUNCTIONS_H #define CPROVER_UNDEFINED_FUNCTIONS_H #include +class namespacet; + class goto_functionst; void list_undefined_functions( diff --git a/src/goto-instrument/uninitialized.cpp b/src/goto-instrument/uninitialized.cpp index c048a518440..ca33c6bfbbb 100644 --- a/src/goto-instrument/uninitialized.cpp +++ b/src/goto-instrument/uninitialized.cpp @@ -8,22 +8,17 @@ Date: January 2010 \*******************************************************************/ +/// \file +/// Detection for Uninitialized Local Variables + +#include "uninitialized.h" + #include #include #include #include -#include "uninitialized.h" - -/*******************************************************************\ - - Class: uninitializedt - - Purpose: - -\*******************************************************************/ - class uninitializedt { public: @@ -47,19 +42,7 @@ class uninitializedt void get_tracking(goto_programt::const_targett i_it); }; -/*******************************************************************\ - -Function: uninitializedt::get_tracking - - Inputs: - - Outputs: - - Purpose: which variables need tracking, - i.e., are uninitialized and may be read? - -\*******************************************************************/ - +/// which variables need tracking, i.e., are uninitialized and may be read? void uninitializedt::get_tracking(goto_programt::const_targett i_it) { std::list objects=objects_read(*i_it); @@ -80,18 +63,6 @@ void uninitializedt::get_tracking(goto_programt::const_targett i_it) } } -/*******************************************************************\ - -Function: uninitializedt::add_assertions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void uninitializedt::add_assertions(goto_programt &goto_program) { uninitialized_analysis(goto_program, ns); @@ -223,18 +194,6 @@ void uninitializedt::add_assertions(goto_programt &goto_program) } } -/*******************************************************************\ - -Function: add_uninitialized_locals_assertions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void add_uninitialized_locals_assertions( symbol_tablet &symbol_table, goto_functionst &goto_functions) @@ -247,18 +206,6 @@ void add_uninitialized_locals_assertions( } } -/*******************************************************************\ - -Function: show_uninitialized - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void show_uninitialized( const class symbol_tablet &symbol_table, const goto_functionst &goto_functions, @@ -270,10 +217,9 @@ void show_uninitialized( { if(f_it->second.body_available()) { - out << "////" << std::endl; - out << "//// Function: " << f_it->first << std::endl; - out << "////" << std::endl; - out << std::endl; + out << "////\n"; + out << "//// Function: " << f_it->first << '\n'; + out << "////\n\n"; uninitialized_analysist uninitialized_analysis; uninitialized_analysis(f_it->second.body, ns); uninitialized_analysis.output(ns, f_it->second.body, out); diff --git a/src/goto-instrument/uninitialized.h b/src/goto-instrument/uninitialized.h index 1f4b27b5964..11437eee972 100644 --- a/src/goto-instrument/uninitialized.h +++ b/src/goto-instrument/uninitialized.h @@ -8,6 +8,9 @@ Date: January 2010 \*******************************************************************/ +/// \file +/// Detection for Uninitialized Local Variables + #ifndef CPROVER_GOTO_INSTRUMENT_UNINITIALIZED_H #define CPROVER_GOTO_INSTRUMENT_UNINITIALIZED_H diff --git a/src/goto-instrument/unwind.cpp b/src/goto-instrument/unwind.cpp index 1d3e2cc29e8..78015b22e6f 100644 --- a/src/goto-instrument/unwind.cpp +++ b/src/goto-instrument/unwind.cpp @@ -7,6 +7,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Loop unwinding + +#include "unwind.h" + #ifdef DEBUG #include #endif @@ -15,21 +20,8 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "unwind.h" #include "loop_utils.h" -/*******************************************************************\ - -Function: parse_unwindset - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void parse_unwindset(const std::string &us, unwind_sett &unwind_set) { assert(unwind_set.empty()); @@ -64,18 +56,6 @@ void parse_unwindset(const std::string &us, unwind_sett &unwind_set) } } -/*******************************************************************\ - -Function: copy_segment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_unwindt::copy_segment( const goto_programt::const_targett start, const goto_programt::const_targett end, // exclusive @@ -130,18 +110,6 @@ void goto_unwindt::copy_segment( } } -/*******************************************************************\ - -Function: unwind - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_unwindt::unwind( goto_programt &goto_program, const goto_programt::const_targett loop_head, @@ -154,18 +122,6 @@ void goto_unwindt::unwind( iteration_points); } -/*******************************************************************\ - -Function: unwind - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_unwindt::unwind( goto_programt &goto_program, const goto_programt::const_targett loop_head, @@ -180,7 +136,7 @@ void goto_unwindt::unwind( // rest program after unwound part goto_programt rest_program; - if(unwind_strategy==PARTIAL) + if(unwind_strategy==unwind_strategyt::PARTIAL) { goto_programt::targett t=rest_program.add_instruction(); unwind_log.insert(t, loop_head->location_number); @@ -190,7 +146,7 @@ void goto_unwindt::unwind( t->function=loop_head->function; t->location_number=loop_head->location_number; } - else if(unwind_strategy==CONTINUE) + else if(unwind_strategy==unwind_strategyt::CONTINUE) { copy_segment(loop_head, loop_exit, rest_program); } @@ -216,9 +172,9 @@ void goto_unwindt::unwind( goto_programt::targett new_t=rest_program.add_instruction(); - if(unwind_strategy==ASSERT) + if(unwind_strategy==unwind_strategyt::ASSERT) new_t->make_assertion(exit_cond); - else if(unwind_strategy==ASSUME) + else if(unwind_strategy==unwind_strategyt::ASSUME) new_t->make_assumption(exit_cond); else assert(false); @@ -334,18 +290,6 @@ void goto_unwindt::unwind( goto_program.destructive_insert(loop_exit, copies); } -/*******************************************************************\ - -Function: get_k - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - int goto_unwindt::get_k( const irep_idt func, const unsigned loop_id, @@ -369,18 +313,6 @@ int goto_unwindt::get_k( return k; } -/*******************************************************************\ - -Function: unwind - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_unwindt::unwind( goto_programt &goto_program, const unwind_sett &unwind_set, @@ -430,18 +362,6 @@ void goto_unwindt::unwind( } } -/*******************************************************************\ - -Function: operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_unwindt::operator()( goto_functionst &goto_functions, const unwind_sett &unwind_set, @@ -458,7 +378,7 @@ void goto_unwindt::operator()( continue; #ifdef DEBUG - std::cout << "Function: " << it->first << std::endl; + std::cout << "Function: " << it->first << '\n'; #endif goto_programt &goto_program=goto_function.body; @@ -467,18 +387,6 @@ void goto_unwindt::operator()( } } -/*******************************************************************\ - -Function: show_log_json - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - // call after calling goto_functions.update()! jsont goto_unwindt::unwind_logt::output_log_json() const { diff --git a/src/goto-instrument/unwind.h b/src/goto-instrument/unwind.h index 7240c3a4c61..6e86a5d98e2 100644 --- a/src/goto-instrument/unwind.h +++ b/src/goto-instrument/unwind.h @@ -7,6 +7,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Loop unwinding + #ifndef CPROVER_GOTO_INSTRUMENT_UNWIND_H #define CPROVER_GOTO_INSTRUMENT_UNWIND_H @@ -14,6 +17,8 @@ Author: Daniel Kroening, kroening@kroening.com #include #include +class goto_functionst; + // -1: do not unwind loop typedef std::map> unwind_sett; @@ -22,7 +27,7 @@ void parse_unwindset(const std::string &us, unwind_sett &unwind_set); class goto_unwindt { public: - typedef enum { CONTINUE, PARTIAL, ASSERT, ASSUME } unwind_strategyt; + enum class unwind_strategyt { CONTINUE, PARTIAL, ASSERT, ASSUME }; // unwind loop @@ -47,14 +52,14 @@ class goto_unwindt goto_programt &goto_program, const unwind_sett &unwind_set, const int k=-1, // -1: no global bound - const unwind_strategyt unwind_strategy=PARTIAL); + const unwind_strategyt unwind_strategy=unwind_strategyt::PARTIAL); // unwind all functions void operator()( goto_functionst &goto_functions, const unsigned k, // global bound - const unwind_strategyt unwind_strategy=PARTIAL) + const unwind_strategyt unwind_strategy=unwind_strategyt::PARTIAL) { const unwind_sett unwind_set; operator()(goto_functions, unwind_set, k, unwind_strategy); @@ -64,7 +69,7 @@ class goto_unwindt goto_functionst &goto_functions, const unwind_sett &unwind_set, const int k=-1, // -1: no global bound - const unwind_strategyt unwind_strategy=PARTIAL); + const unwind_strategyt unwind_strategy=unwind_strategyt::PARTIAL); // unwind log diff --git a/src/goto-instrument/wmm/abstract_event.cpp b/src/goto-instrument/wmm/abstract_event.cpp index c02a4a4d1f7..41e8efb78f2 100644 --- a/src/goto-instrument/wmm/abstract_event.cpp +++ b/src/goto-instrument/wmm/abstract_event.cpp @@ -8,28 +8,19 @@ Date: 2012 \*******************************************************************/ -#include "abstract_event.h" - -/*******************************************************************\ - -Function: abstract_eventt::unsafe_pair_lwfence_param - - Inputs: +/// \file +/// abstract events - Outputs: - - Purpose: - -\*******************************************************************/ +#include "abstract_event.h" bool abstract_eventt::unsafe_pair_lwfence_param(const abstract_eventt &next, memory_modelt model, bool lwsync_met) const { /* pairs with fences are not properly pairs */ - if(operation==Fence || next.operation==Fence - || operation==Lwfence || next.operation==Lwfence - || operation==ASMfence || next.operation==ASMfence) + if(operation==operationt::Fence || next.operation==operationt::Fence + || operation==operationt::Lwfence || next.operation==operationt::Lwfence + || operation==operationt::ASMfence || next.operation==operationt::ASMfence) return false; /* pairs of shared variables */ @@ -39,40 +30,64 @@ bool abstract_eventt::unsafe_pair_lwfence_param(const abstract_eventt &next, switch(model) { case TSO: - return (thread==next.thread && operation==Write && next.operation==Read); + return (thread==next.thread && + operation==operationt::Write && + next.operation==operationt::Read); case PSO: - return (thread==next.thread && operation==Write + return (thread==next.thread && operation==operationt::Write /* lwsyncWW -> mfenceWW */ - && !(operation==Write && next.operation==Write && lwsync_met)); + && !(operation==operationt::Write && + next.operation==operationt::Write && + lwsync_met)); case RMO: return thread==next.thread && /* lwsyncWW -> mfenceWW */ - !(operation==Write && next.operation==Write && lwsync_met) && + !(operation==operationt::Write && + next.operation==operationt::Write && + lwsync_met) && /* lwsyncRW -> mfenceRW */ - !(operation==Read && next.operation==Write && lwsync_met) && + !(operation==operationt::Read && + next.operation==operationt::Write && + lwsync_met) && /* lwsyncRR -> mfenceRR */ - !(operation==Read && next.operation==Read && lwsync_met) && + !(operation==operationt::Read && + next.operation==operationt::Read && + lwsync_met) && /* if posWW, wsi maintained by the processor */ - !(variable==next.variable && operation==Write && next.operation==Write) && + !(variable==next.variable && + operation==operationt::Write && + next.operation==operationt::Write) && /* if posRW, fri maintained by the processor */ - !(variable==next.variable && operation==Read && next.operation==Write); + !(variable==next.variable && + operation==operationt::Read && + next.operation==operationt::Write); case Power: return ((thread==next.thread /* lwsyncWW -> mfenceWW */ - && !(operation==Write && next.operation==Write && lwsync_met) + && !(operation==operationt::Write && + next.operation==operationt::Write && + lwsync_met) /* lwsyncRW -> mfenceRW */ - && !(operation==Read && next.operation==Write && lwsync_met) + && !(operation==operationt::Read && + next.operation==operationt::Write && + lwsync_met) /* lwsyncRR -> mfenceRR */ - && !(operation==Read && next.operation==Read && lwsync_met) + && !(operation==operationt::Read && + next.operation==operationt::Read && + lwsync_met) /* if posWW, wsi maintained by the processor */ - && (variable!=next.variable || operation!=Write || next.operation!=Write)) + && (variable!=next.variable || + operation!=operationt::Write || + next.operation!=operationt::Write)) /* rfe */ - || (thread!=next.thread && operation==Write && next.operation==Read - && variable==next.variable)); + || (thread!=next.thread && + operation==operationt::Write && + next.operation==operationt::Read && + variable==next.variable)); case Unknown: { @@ -83,26 +98,17 @@ bool abstract_eventt::unsafe_pair_lwfence_param(const abstract_eventt &next, return true; } -/*******************************************************************\ - -Function: abstract_eventt::unsafe_pair_asm - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool abstract_eventt::unsafe_pair_asm(const abstract_eventt &next, memory_modelt model, unsigned char met) const { /* pairs with fences are not properly pairs */ - if(operation==Fence || next.operation==Fence - || operation==Lwfence || next.operation==Lwfence - || operation==ASMfence || next.operation==ASMfence) + if(operation==operationt::Fence || + next.operation==operationt::Fence || + operation==operationt::Lwfence || + next.operation==operationt::Lwfence || + operation==operationt::ASMfence || + next.operation==operationt::ASMfence) return false; /* pairs of shared variables */ @@ -112,31 +118,38 @@ bool abstract_eventt::unsafe_pair_asm(const abstract_eventt &next, switch(model) { case TSO: - return (thread==next.thread && operation==Write && next.operation==Read - && (met&1)==0); + return (thread==next.thread && + operation==operationt::Write && + next.operation==operationt::Read && + (met&1)==0); case PSO: - return (thread==next.thread && operation==Write - && (met&3)==0); + return (thread==next.thread && + operation==operationt::Write && + (met&3)==0); case RMO: return thread==next.thread && (met&15)==0 && /* if posWW, wsi maintained by the processor */ - !(variable==next.variable && operation==Write && next.operation==Write) && + !(variable==next.variable && + operation==operationt::Write && + next.operation==operationt::Write) && /* if posRW, fri maintained by the processor */ - !(variable==next.variable && operation==Read && next.operation==Write); + !(variable==next.variable && + operation==operationt::Read && + next.operation==operationt::Write); case Power: return (thread==next.thread && (met&15)==0 && /* if posWW, wsi maintained by the processor */ (variable!=next.variable || - operation!=Write || - next.operation!=Write)) || + operation!=operationt::Write || + next.operation!=operationt::Write)) || /* rfe */ (thread!=next.thread && - operation==Write && - next.operation==Read && + operation==operationt::Write && + next.operation==operationt::Read && variable==next.variable); case Unknown: diff --git a/src/goto-instrument/wmm/abstract_event.h b/src/goto-instrument/wmm/abstract_event.h index db76a92f1f4..3f9936c112d 100644 --- a/src/goto-instrument/wmm/abstract_event.h +++ b/src/goto-instrument/wmm/abstract_event.h @@ -8,6 +8,9 @@ Date: 2012 \*******************************************************************/ +/// \file +/// abstract events + #ifndef CPROVER_GOTO_INSTRUMENT_WMM_ABSTRACT_EVENT_H #define CPROVER_GOTO_INSTRUMENT_WMM_ABSTRACT_EVENT_H @@ -16,10 +19,6 @@ Date: 2012 #include "wmm.h" -/*******************************************************************\ - abstract event -\*******************************************************************/ - class abstract_eventt:public graph_nodet { protected: @@ -28,7 +27,7 @@ class abstract_eventt:public graph_nodet public: /* for now, both fence functions and asm fences accepted */ - typedef enum {Write, Read, Fence, Lwfence, ASMfence} operationt; + enum class operationt { Write, Read, Fence, Lwfence, ASMfence }; operationt operation; unsigned thread; @@ -46,7 +45,18 @@ class abstract_eventt:public graph_nodet bool RWcumul; bool RRcumul; - abstract_eventt() + abstract_eventt(): + operation(operationt::Write), + thread(0), + id(0), + local(false), + WRfence(false), + WWfence(false), + RRfence(false), + RWfence(false), + WWcumul(false), + RWcumul(false), + RRcumul(false) { } @@ -111,7 +121,9 @@ class abstract_eventt:public graph_nodet bool is_fence() const { - return operation==Fence || operation==Lwfence || operation==ASMfence; + return operation==operationt::Fence || + operation==operationt::Lwfence || + operation==operationt::ASMfence; } /* checks the safety of the pair locally (i.e., w/o taking fences @@ -138,11 +150,11 @@ class abstract_eventt:public graph_nodet { switch(operation) { - case Write: return "W"; - case Read: return "R"; - case Fence: return "F"; - case Lwfence: return "f"; - case ASMfence: return "asm:"; + case operationt::Write: return "W"; + case operationt::Read: return "R"; + case operationt::Fence: return "F"; + case operationt::Lwfence: return "f"; + case operationt::ASMfence: return "asm:"; } assert(false); return "?"; @@ -152,16 +164,18 @@ class abstract_eventt:public graph_nodet const abstract_eventt &second) const { return - (WRfence && first.operation==Write && second.operation==Read) || + (WRfence && + first.operation==operationt::Write && + second.operation==operationt::Read) || ((WWfence || WWcumul) && - first.operation==Write && - second.operation==Write) || + first.operation==operationt::Write && + second.operation==operationt::Write) || ((RWfence || RWcumul) && - first.operation==Read && - second.operation==Write) || + first.operation==operationt::Read && + second.operation==operationt::Write) || ((RRfence || RRcumul) && - first.operation==Read && - second.operation==Read); + first.operation==operationt::Read && + second.operation==operationt::Read); } bool is_direct() const { return WWfence || WRfence || RRfence || RWfence; } diff --git a/src/goto-instrument/wmm/cycle_collection.cpp b/src/goto-instrument/wmm/cycle_collection.cpp index 1239aef6fa8..64b619c4369 100644 --- a/src/goto-instrument/wmm/cycle_collection.cpp +++ b/src/goto-instrument/wmm/cycle_collection.cpp @@ -8,22 +8,15 @@ Date: 2012 \*******************************************************************/ -#include +/// \file +/// collection of cycles in graph of abstract events #include "event_graph.h" -/*******************************************************************\ - -Function: event_grapht::graph_explorert::filter_thin_air - - Inputs: - - Outputs: - - Purpose: after the collection, eliminates the executions forbidden - by an indirect thin-air +#include -\*******************************************************************/ +/// after the collection, eliminates the executions forbidden by an indirect +/// thin-air void event_grapht::graph_explorert::filter_thin_air( std::set &set_of_cycles) { @@ -54,18 +47,7 @@ void event_grapht::graph_explorert::filter_thin_air( #endif } -/*******************************************************************\ - -Function: event_grapht::graph_explorert::collect_cycles - - Inputs: - - Outputs: - - Purpose: Tarjan 1972 adapted and modified for events - -\*******************************************************************/ - +/// Tarjan 1972 adapted and modified for events void event_grapht::graph_explorert::collect_cycles( std::set &set_of_cycles, memory_modelt model) @@ -74,7 +56,7 @@ void event_grapht::graph_explorert::collect_cycles( for(std::size_t i=0; i* order=0; + std::list* order=nullptr; /* on Power, rfe pairs are also potentially unsafe */ switch(model) { @@ -123,20 +105,8 @@ void event_grapht::graph_explorert::collect_cycles( filter_thin_air(set_of_cycles); } -/*******************************************************************\ - -Function: event_grapht::graph_explorert::extract_cycle - - Inputs: - - Outputs: - - Purpose: extracts a (whole, unreduced) cycle from the stack. - Note: it may not be a real cycle yet -- we cannot check - the size before a call to this function. - -\*******************************************************************/ - +/// extracts a (whole, unreduced) cycle from the stack. Note: it may not be a +/// real cycle yet -- we cannot check the size before a call to this function. event_grapht::critical_cyclet event_grapht::graph_explorert::extract_cycle( event_idt vertex, event_idt source, @@ -176,18 +146,8 @@ event_grapht::critical_cyclet event_grapht::graph_explorert::extract_cycle( return new_cycle; } -/*******************************************************************\ - -Function: event_grapht::graph_explorert::backtrack - - Inputs: get_po_only: used for po-transitivity - - Outputs: - - Purpose: see event_grapht::collect_cycles - -\*******************************************************************/ - +/// see event_grapht::collect_cycles +/// \param get_po_only: used for po-transitivity bool event_grapht::graph_explorert::backtrack( std::set &set_of_cycles, event_idt source, @@ -263,7 +223,7 @@ bool event_grapht::graph_explorert::backtrack( if(!this_vertex.local) { /* only the lwsyncWR can be interpreted as poWR (i.e., skip of the fence) */ - if(lwfence_met && this_vertex.operation!=abstract_eventt::Read) + if(lwfence_met && this_vertex.operation!=abstract_eventt::operationt::Read) return false; // {no_comm=true;get_com_only=false;}//return false; bool has_to_be_unsafe_updated=false; @@ -274,9 +234,9 @@ bool event_grapht::graph_explorert::backtrack( id2string(this_vertex.variable).find("[]")==std::string::npos) { /* no more than 4 events per thread */ - if(this_vertex.operation!=abstract_eventt::Fence && - this_vertex.operation!=abstract_eventt::Lwfence && - this_vertex.operation!=abstract_eventt::ASMfence) + if(this_vertex.operation!=abstract_eventt::operationt::Fence && + this_vertex.operation!=abstract_eventt::operationt::Lwfence && + this_vertex.operation!=abstract_eventt::operationt::ASMfence) { if(events_per_thread[this_vertex.thread]==4) return false; @@ -295,13 +255,16 @@ bool event_grapht::graph_explorert::backtrack( point_stack.pop(); const event_idt preprevious=point_stack.top(); point_stack.push(previous); - if(!egraph[preprevious].unsafe_pair(this_vertex, model) - && !(this_vertex.operation==abstract_eventt::Fence - || egraph[preprevious].operation==abstract_eventt::Fence - || this_vertex.operation==abstract_eventt::Lwfence - || egraph[preprevious].operation==abstract_eventt::Lwfence - || this_vertex.operation==abstract_eventt::ASMfence - || egraph[preprevious].operation==abstract_eventt::ASMfence)) + if(!egraph[preprevious].unsafe_pair(this_vertex, model) && + !(this_vertex.operation==abstract_eventt::operationt::Fence || + egraph[preprevious].operation== + abstract_eventt::operationt::Fence || + this_vertex.operation==abstract_eventt::operationt::Lwfence || + egraph[preprevious].operation== + abstract_eventt::operationt::Lwfence || + this_vertex.operation==abstract_eventt::operationt::ASMfence || + egraph[preprevious].operation== + abstract_eventt::operationt::ASMfence)) return false; } } @@ -316,14 +279,15 @@ bool event_grapht::graph_explorert::backtrack( not taken into account) */ if(!point_stack.empty() && egraph.are_po_ordered(point_stack.top(), vertex) && - this_vertex.operation!=abstract_eventt::Fence && - this_vertex.operation!=abstract_eventt::Lwfence && - this_vertex.operation!=abstract_eventt::ASMfence && + this_vertex.operation!=abstract_eventt::operationt::Fence && + this_vertex.operation!=abstract_eventt::operationt::Lwfence && + this_vertex.operation!=abstract_eventt::operationt::ASMfence && this_vertex.variable==egraph[point_stack.top()].variable) { if(same_var_pair || - (this_vertex.operation==abstract_eventt::Read && - egraph[point_stack.top()].operation==abstract_eventt::Read)) + (this_vertex.operation==abstract_eventt::operationt::Read && + egraph[point_stack.top()].operation== + abstract_eventt::operationt::Read)) { events_per_thread[this_vertex.thread]--; return false; // {no_comm=true;get_com_only=false;} //return false; @@ -339,18 +303,18 @@ bool event_grapht::graph_explorert::backtrack( /* constraint 1.b */ if(!point_stack.empty() && egraph.are_po_ordered(point_stack.top(), vertex) && - this_vertex.operation!=abstract_eventt::Fence && - this_vertex.operation!=abstract_eventt::Lwfence && - this_vertex.operation!=abstract_eventt::ASMfence && + this_vertex.operation!=abstract_eventt::operationt::Fence && + this_vertex.operation!=abstract_eventt::operationt::Lwfence && + this_vertex.operation!=abstract_eventt::operationt::ASMfence && this_vertex.variable!=egraph[point_stack.top()].variable) { same_var_pair_updated=false; } /* constraint 2: per variable, either W W, R W, W R, or R W R */ - if(this_vertex.operation!=abstract_eventt::Fence && - this_vertex.operation!=abstract_eventt::Lwfence && - this_vertex.operation!=abstract_eventt::ASMfence) + if(this_vertex.operation!=abstract_eventt::operationt::Fence && + this_vertex.operation!=abstract_eventt::operationt::Lwfence && + this_vertex.operation!=abstract_eventt::operationt::ASMfence) { const unsigned char nb_writes=writes_per_variable[this_vertex.variable]; const unsigned char nb_reads=reads_per_variable[this_vertex.variable]; @@ -360,7 +324,7 @@ bool event_grapht::graph_explorert::backtrack( events_per_thread[this_vertex.thread]--; return false; // {no_comm=true;get_com_only=false;} //return false; } - else if(this_vertex.operation==abstract_eventt::Write) + else if(this_vertex.operation==abstract_eventt::operationt::Write) { if(nb_writes==2) { @@ -370,7 +334,7 @@ bool event_grapht::graph_explorert::backtrack( else writes_per_variable[this_vertex.variable]++; } - else if(this_vertex.operation==abstract_eventt::Read) + else if(this_vertex.operation==abstract_eventt::operationt::Read) { if(nb_reads==2) { @@ -522,11 +486,11 @@ bool event_grapht::graph_explorert::backtrack( point_stack.pop(); /* removes variable access */ - if(this_vertex.operation!=abstract_eventt::Fence && - this_vertex.operation!=abstract_eventt::Lwfence && - this_vertex.operation!=abstract_eventt::ASMfence) + if(this_vertex.operation!=abstract_eventt::operationt::Fence && + this_vertex.operation!=abstract_eventt::operationt::Lwfence && + this_vertex.operation!=abstract_eventt::operationt::ASMfence) { - if(this_vertex.operation==abstract_eventt::Write) + if(this_vertex.operation==abstract_eventt::operationt::Write) writes_per_variable[this_vertex.variable]--; else reads_per_variable[this_vertex.variable]--; @@ -544,32 +508,34 @@ bool event_grapht::graph_explorert::backtrack( (po_trans > 1 || po_trans==0) && !point_stack.empty() && egraph.are_po_ordered(point_stack.top(), vertex) && - this_vertex.operation!=abstract_eventt::Fence && - (this_vertex.operation!=abstract_eventt::Lwfence || - egraph[point_stack.top()].operation==abstract_eventt::Write) && - (this_vertex.operation!=abstract_eventt::ASMfence || + this_vertex.operation!=abstract_eventt::operationt::Fence && + (this_vertex.operation!=abstract_eventt::operationt::Lwfence || + egraph[point_stack.top()].operation== + abstract_eventt::operationt::Write) && + (this_vertex.operation!=abstract_eventt::operationt::ASMfence || !this_vertex.WRfence || - egraph[point_stack.top()].operation==abstract_eventt::Write)) + egraph[point_stack.top()].operation== + abstract_eventt::operationt::Write)) { skip_tracked.insert(vertex); std::stack tmp; - while(marked_stack.size()>0 && marked_stack.top()!=vertex) + while(!marked_stack.empty() && marked_stack.top()!=vertex) { tmp.push(marked_stack.top()); mark[marked_stack.top()]=false; marked_stack.pop(); } - if(marked_stack.size()>0) + if(!marked_stack.empty()) { assert(marked_stack.top()==vertex); mark[vertex]=true; } else { - while(tmp.size()>0) + while(!tmp.empty()) { marked_stack.push(tmp.top()); mark[tmp.top()]=true; @@ -590,11 +556,13 @@ bool event_grapht::graph_explorert::backtrack( /* skip lwfence by po-transition only if we consider a WR */ // TO CHECK const bool is_lwfence= - (this_vertex.operation==abstract_eventt::Lwfence && - egraph[point_stack.top()].operation==abstract_eventt::Write) || - (this_vertex.operation==abstract_eventt::ASMfence && + (this_vertex.operation==abstract_eventt::operationt::Lwfence && + egraph[point_stack.top()].operation== + abstract_eventt::operationt::Write) || + (this_vertex.operation==abstract_eventt::operationt::ASMfence && (!this_vertex.WRfence && - egraph[point_stack.top()].operation==abstract_eventt::Write)); + egraph[point_stack.top()].operation== + abstract_eventt::operationt::Write)); for(wmm_grapht::edgest::const_iterator w_it= egraph.po_out(vertex).begin(); diff --git a/src/goto-instrument/wmm/data_dp.cpp b/src/goto-instrument/wmm/data_dp.cpp index ce700dc1f8a..d24b17d9651 100644 --- a/src/goto-instrument/wmm/data_dp.cpp +++ b/src/goto-instrument/wmm/data_dp.cpp @@ -8,23 +8,16 @@ Date: 2012 \*******************************************************************/ -#include +/// \file +/// data dependencies #include "data_dp.h" -#include "abstract_event.h" - -/*******************************************************************\ - -Function: data_dpt::dp_analysis - - Inputs: - Outputs: - - Purpose: insertion +#include -\*******************************************************************/ +#include "abstract_event.h" +/// insertion void data_dpt::dp_analysis( const datat &read, bool local_read, @@ -66,18 +59,6 @@ void data_dpt::dp_analysis( } } -/*******************************************************************\ - -Function: data_dpt::dp_analysis - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void data_dpt::dp_analysis( const abstract_eventt &read, const abstract_eventt &write) @@ -87,18 +68,7 @@ void data_dpt::dp_analysis( dp_analysis(d_read, read.local, d_write, write.local); } -/*******************************************************************\ - -Function: data_dpt::dp - - Inputs: - - Outputs: - - Purpose: search in N^2 - -\*******************************************************************/ - +/// search in N^2 bool data_dpt::dp(const abstract_eventt &e1, const abstract_eventt &e2) const { for(const_iterator it1=begin(); it1!=end(); ++it1) @@ -143,18 +113,7 @@ bool data_dpt::dp(const abstract_eventt &e1, const abstract_eventt &e2) const return false; } -/*******************************************************************\ - -Function: data_dpt::dp_merge - - Inputs: - - Outputs: - - Purpose: merge in N^3 - -\*******************************************************************/ - +/// merge in N^3 void data_dpt::dp_merge() { if(size()<2) @@ -198,18 +157,6 @@ void data_dpt::dp_merge() dp_merge(); } -/*******************************************************************\ - -Function: data_dpt::print - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void data_dpt::print(messaget &message) { #ifdef DEBUG diff --git a/src/goto-instrument/wmm/data_dp.h b/src/goto-instrument/wmm/data_dp.h index 6b352acccfd..abd7641fb9c 100644 --- a/src/goto-instrument/wmm/data_dp.h +++ b/src/goto-instrument/wmm/data_dp.h @@ -8,6 +8,9 @@ Date: 2012 \*******************************************************************/ +/// \file +/// data dependencies + #ifndef CPROVER_GOTO_INSTRUMENT_WMM_DATA_DP_H #define CPROVER_GOTO_INSTRUMENT_WMM_DATA_DP_H @@ -18,10 +21,6 @@ Date: 2012 class abstract_eventt; class messaget; -/*******************************************************************\ - data dependencies -\*******************************************************************/ - struct datat { irep_idt id; diff --git a/src/goto-instrument/wmm/event_graph.cpp b/src/goto-instrument/wmm/event_graph.cpp index 9490d69f46c..d5d9df2aff4 100644 --- a/src/goto-instrument/wmm/event_graph.cpp +++ b/src/goto-instrument/wmm/event_graph.cpp @@ -8,6 +8,9 @@ Date: 2012 \*******************************************************************/ +/// \file +/// graph of abstract events + #include "event_graph.h" #include @@ -22,32 +25,20 @@ static const char *colour_map[NB_COLOURS]= "deeppink", "indigo", "olivedrab"}; #define print_colour(u) colour_map[u%NB_COLOURS] -/*******************************************************************\ - -Function: event_grapht::print_rec_graph - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void event_grapht::print_rec_graph(std::ofstream &file, event_idt node_id, std::set &visited) { const abstract_eventt &node=operator[](node_id); file << node_id << "[label=\"" << node << ", " << node.source_location << - "\"];" << std::endl; + "\"];\n"; visited.insert(node_id); for(wmm_grapht::edgest::const_iterator it=po_out(node_id).begin(); it!=po_out(node_id).end(); ++it) { - file << node_id << "->" << it->first << "[]" << std::endl; - file << "{rank=same; " << node_id << "; " << it->first << "}" << std::endl; + file << node_id << "->" << it->first << "[]\n"; + file << "{rank=same; " << node_id << "; " << it->first << "}\n"; if(visited.find(it->first)==visited.end()) print_rec_graph(file, it->first, visited); } @@ -56,54 +47,32 @@ void event_grapht::print_rec_graph(std::ofstream &file, event_idt node_id, it=com_out(node_id).begin(); it!=com_out(node_id).end(); ++it) { - file << node_id << "->" << it->first << "[style=\"dotted\"]" << std::endl; + file << node_id << "->" << it->first << "[style=\"dotted\"]\n"; if(visited.find(it->first)==visited.end()) print_rec_graph(file, it->first, visited); } } -/*******************************************************************\ - -Function: event_grapht::print_graph - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void event_grapht::print_graph() { - assert(po_order.size()>0); + assert(!po_order.empty()); std::set visited; event_idt root=po_order.front(); std::ofstream file; file.open("graph.dot"); - file << "digraph G {" << std::endl; - file << "rankdir=LR;" << std::endl; + file << "digraph G {\n"; + file << "rankdir=LR;\n"; print_rec_graph(file, root, visited); - file << "}" << std::endl; + file << "}\n"; } -/*******************************************************************\ - -Function: event_grapht::copy_segment - - Inputs: begin: top of the subgraph - end: bottom of the subgraph - - Outputs: - - Purpose: copies the segment - -\*******************************************************************/ - +/// copies the segment +/// \param begin: top of the subgraph +/// \param end: bottom of the subgraph void event_grapht::explore_copy_segment(std::set &explored, event_idt begin, event_idt end) const { - // std::cout << "explores " << begin << " against " << end << std::endl; + // std::cout << "explores " << begin << " against " << end << '\n'; if(explored.find(begin)!=explored.end()) return; @@ -144,12 +113,12 @@ event_idt event_grapht::copy_segment(event_idt begin, event_idt end) /* collects the nodes of the subgraph */ explore_copy_segment(covered, begin, end); - if(covered.size()==0) + if(covered.empty()) return end; // for(std::set::const_iterator it=covered.begin(); // it!=covered.end(); ++it) -// std::cout << "covered: " << *it << std::endl; +// std::cout << "covered: " << *it << '\n'; std::map orig2copy; @@ -214,18 +183,6 @@ event_idt event_grapht::copy_segment(event_idt begin, event_idt end) return orig2copy[end]; } -/*******************************************************************\ - -Function: event_grapht::critical_cyclet::check_AC - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool event_grapht::critical_cyclet::check_AC( const_iterator s_it, const abstract_eventt &first, @@ -237,7 +194,7 @@ bool event_grapht::critical_cyclet::check_AC( for(; AC_it!=end(); ++AC_it) { const abstract_eventt &AC_evt=egraph[*AC_it]; - if(AC_evt.operation==abstract_eventt::Fence) + if(AC_evt.operation==abstract_eventt::operationt::Fence) { AC=true; break; @@ -254,7 +211,7 @@ bool event_grapht::critical_cyclet::check_AC( for(AC_it=begin(); ; ++AC_it) { const abstract_eventt &AC_evt=egraph[*AC_it]; - if(AC_evt.operation==abstract_eventt::Fence) + if(AC_evt.operation==abstract_eventt::operationt::Fence) { AC=true; break; @@ -267,18 +224,6 @@ bool event_grapht::critical_cyclet::check_AC( return AC; } -/*******************************************************************\ - -Function: event_grapht::critical_cyclet::check_BC - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool event_grapht::critical_cyclet::check_BC( const_iterator it, const abstract_eventt &first, @@ -300,7 +245,7 @@ bool event_grapht::critical_cyclet::check_BC( for(; BC_it!=begin(); --BC_it) { const abstract_eventt &BC_evt=egraph[*BC_it]; - if(BC_evt.operation==abstract_eventt::Fence) + if(BC_evt.operation==abstract_eventt::operationt::Fence) { BC=true; break; @@ -319,7 +264,7 @@ bool event_grapht::critical_cyclet::check_BC( for(; ; --BC_it) { const abstract_eventt &BC_evt=egraph[*BC_it]; - if(BC_evt.operation==abstract_eventt::Fence) + if(BC_evt.operation==abstract_eventt::operationt::Fence) { BC=true; break; @@ -332,18 +277,6 @@ bool event_grapht::critical_cyclet::check_BC( return BC; } -/*******************************************************************\ - -Function: event_grapht::critical_cyclet::is_unsafe - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool event_grapht::critical_cyclet::is_unsafe(memory_modelt model, bool fast) { egraph.message.debug() << "cycle is safe?" << messaget::eom; @@ -372,20 +305,21 @@ bool event_grapht::critical_cyclet::is_unsafe(memory_modelt model, bool fast) const abstract_eventt &next_evt=egraph[*next]; /* strong fence -- this pair is safe */ - if(it_evt.operation==abstract_eventt::Fence) + if(it_evt.operation==abstract_eventt::operationt::Fence) continue; - if(next_evt.operation==abstract_eventt::Fence) + if(next_evt.operation==abstract_eventt::operationt::Fence) continue; /* first element is a weak fence */ - if(it_evt.operation==abstract_eventt::Lwfence) + if(it_evt.operation==abstract_eventt::operationt::Lwfence) continue; /* selects the next event which is not a weak fence */ const_iterator s_it=next; - for( ; s_it!=end() && egraph[*s_it].operation==abstract_eventt::Lwfence; + for(; s_it!=end() && + egraph[*s_it].operation==abstract_eventt::operationt::Lwfence; ++s_it) { } @@ -395,7 +329,7 @@ bool event_grapht::critical_cyclet::is_unsafe(memory_modelt model, bool fast) const abstract_eventt &s_evt=egraph[*s_it]; - if(s_evt.operation==abstract_eventt::Fence) + if(s_evt.operation==abstract_eventt::operationt::Fence) continue; /* if the whole cycle has been explored */ @@ -509,18 +443,19 @@ bool event_grapht::critical_cyclet::is_unsafe(memory_modelt model, bool fast) } /* strong fence -- this pair is safe */ - if(egraph[back()].operation==abstract_eventt::Fence - || egraph[front()].operation==abstract_eventt::Fence) + if(egraph[back()].operation==abstract_eventt::operationt::Fence + || egraph[front()].operation==abstract_eventt::operationt::Fence) return unsafe_met; /* first element is a weak fence */ - if(egraph[back()].operation==abstract_eventt::Lwfence) + if(egraph[back()].operation==abstract_eventt::operationt::Lwfence) return unsafe_met; /* selects the next event which is not a weak fence */ const_iterator s_it; for(s_it=begin(); - s_it!=end() && egraph[*s_it].operation==abstract_eventt::Lwfence; + s_it!=end() && + egraph[*s_it].operation==abstract_eventt::operationt::Lwfence; s_it++) { } @@ -529,7 +464,7 @@ bool event_grapht::critical_cyclet::is_unsafe(memory_modelt model, bool fast) if(s_it==end()) return unsafe_met; - if(egraph[*s_it].operation==abstract_eventt::Fence) + if(egraph[*s_it].operation==abstract_eventt::operationt::Fence) return unsafe_met; const abstract_eventt &first=egraph[back()]; @@ -623,18 +558,7 @@ bool event_grapht::critical_cyclet::is_unsafe(memory_modelt model, bool fast) return unsafe_met; } -/*******************************************************************\ - -Function: event_grapht::critical_cyclet::is_unsafe_asm - - Inputs: - - Outputs: - - Purpose: same as is_unsafe, but with ASM fences - -\*******************************************************************/ - +/// same as is_unsafe, but with ASM fences bool event_grapht::critical_cyclet::is_unsafe_asm( memory_modelt model, bool fast) @@ -663,10 +587,10 @@ bool event_grapht::critical_cyclet::is_unsafe_asm( fences_met=0; /* fence -- this pair is safe */ - if(egraph[*it].operation==abstract_eventt::ASMfence) + if(egraph[*it].operation==abstract_eventt::operationt::ASMfence) continue; - if(egraph[*(++it)].operation==abstract_eventt::ASMfence) + if(egraph[*(++it)].operation==abstract_eventt::operationt::ASMfence) { --it; continue; @@ -679,14 +603,15 @@ bool event_grapht::critical_cyclet::is_unsafe_asm( --it; for(; - s_it!=end() && egraph[*s_it].operation==abstract_eventt::ASMfence; + s_it!=end() && + egraph[*s_it].operation==abstract_eventt::operationt::ASMfence; s_it++) fences_met |= egraph[*s_it].fence_value(); if(s_it==end()) continue; - if(egraph[*s_it].operation==abstract_eventt::ASMfence) + if(egraph[*s_it].operation==abstract_eventt::operationt::ASMfence) continue; /* if the whole cycle has been explored */ @@ -714,7 +639,7 @@ bool event_grapht::critical_cyclet::is_unsafe_asm( for(; AC_it!=end() && egraph[*AC_it].thread==second.thread; AC_it++) - if(egraph[*AC_it].operation==abstract_eventt::ASMfence + if(egraph[*AC_it].operation==abstract_eventt::operationt::ASMfence && egraph[*AC_it].is_cumul() && egraph[*AC_it].is_corresponding_fence(egraph[*it], egraph[*s_it])) { @@ -730,7 +655,7 @@ bool event_grapht::critical_cyclet::is_unsafe_asm( for(AC_it=begin(); !(egraph[*AC_it]==first) && egraph[*AC_it].thread==second.thread; AC_it++) - if(egraph[*AC_it].operation==abstract_eventt::ASMfence && + if(egraph[*AC_it].operation==abstract_eventt::operationt::ASMfence && egraph[*AC_it].is_cumul() && egraph[*AC_it].is_corresponding_fence(egraph[*it], egraph[*s_it])) { @@ -758,7 +683,7 @@ bool event_grapht::critical_cyclet::is_unsafe_asm( BC_it!=begin() && egraph[*BC_it].thread==first.thread; BC_it--) { - if(egraph[*BC_it].operation==abstract_eventt::ASMfence && + if(egraph[*BC_it].operation==abstract_eventt::operationt::ASMfence && egraph[*BC_it].is_cumul() && egraph[*BC_it].is_corresponding_fence(egraph[*it], egraph[*s_it])) { @@ -775,7 +700,7 @@ bool event_grapht::critical_cyclet::is_unsafe_asm( for(BC_it=end(); !(egraph[*BC_it]==second) && egraph[*BC_it].thread==first.thread; BC_it--) - if(egraph[*BC_it].operation==abstract_eventt::ASMfence && + if(egraph[*BC_it].operation==abstract_eventt::operationt::ASMfence && egraph[*BC_it].is_cumul() && egraph[*BC_it].is_corresponding_fence(egraph[*it], egraph[*s_it])) { @@ -827,8 +752,8 @@ bool event_grapht::critical_cyclet::is_unsafe_asm( } /* strong fence -- this pair is safe */ - if(egraph[back()].operation==abstract_eventt::ASMfence - || egraph[front()].operation==abstract_eventt::ASMfence) + if(egraph[back()].operation==abstract_eventt::operationt::ASMfence + || egraph[front()].operation==abstract_eventt::operationt::ASMfence) return unsafe_met; fences_met=0; @@ -836,14 +761,16 @@ bool event_grapht::critical_cyclet::is_unsafe_asm( /* selects the next event which is not a weak fence */ const_iterator s_it; for(s_it=begin(); - s_it!=end() && egraph[*s_it].operation==abstract_eventt::ASMfence; s_it++) + s_it!=end() && + egraph[*s_it].operation==abstract_eventt::operationt::ASMfence; + s_it++) fences_met |= egraph[*s_it].fence_value(); /* if the whole cycle has been explored */ if(s_it==end()) return unsafe_met; - if(egraph[*s_it].operation==abstract_eventt::ASMfence) + if(egraph[*s_it].operation==abstract_eventt::operationt::ASMfence) return unsafe_met; const abstract_eventt &first=egraph[back()]; @@ -867,7 +794,7 @@ bool event_grapht::critical_cyclet::is_unsafe_asm( for(; AC_it!=end() && egraph[*AC_it].thread==second.thread; AC_it++) - if(egraph[*AC_it].operation==abstract_eventt::ASMfence + if(egraph[*AC_it].operation==abstract_eventt::operationt::ASMfence && egraph[*AC_it].is_cumul() && egraph[*AC_it].is_corresponding_fence(first, second)) { @@ -883,7 +810,7 @@ bool event_grapht::critical_cyclet::is_unsafe_asm( for(AC_it=begin(); !(egraph[*AC_it]==first) && egraph[*AC_it].thread==second.thread; AC_it++) - if(egraph[*AC_it].operation==abstract_eventt::ASMfence && + if(egraph[*AC_it].operation==abstract_eventt::operationt::ASMfence && egraph[*AC_it].is_cumul() && egraph[*AC_it].is_corresponding_fence(first, second)) { @@ -902,7 +829,7 @@ bool event_grapht::critical_cyclet::is_unsafe_asm( for(; BC_it!=begin() && egraph[*BC_it].thread==first.thread; BC_it--) - if(egraph[*BC_it].operation==abstract_eventt::ASMfence + if(egraph[*BC_it].operation==abstract_eventt::operationt::ASMfence && egraph[*BC_it].is_cumul() && egraph[*BC_it].is_corresponding_fence(first, second)) { @@ -920,7 +847,7 @@ bool event_grapht::critical_cyclet::is_unsafe_asm( for(; !(egraph[*BC_it]==second) && egraph[*BC_it].thread==first.thread; BC_it--) - if(egraph[*BC_it].operation==abstract_eventt::ASMfence + if(egraph[*BC_it].operation==abstract_eventt::operationt::ASMfence && egraph[*BC_it].is_cumul() && egraph[*BC_it].is_corresponding_fence(first, second)) { @@ -965,18 +892,6 @@ bool event_grapht::critical_cyclet::is_unsafe_asm( return unsafe_met; } -/*******************************************************************\ - -Function: event_grapht::critical_cyclet::is_not_uniproc - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool event_grapht::critical_cyclet::is_not_uniproc() const { const_iterator it=begin(); @@ -985,9 +900,9 @@ bool event_grapht::critical_cyclet::is_not_uniproc() const for(; it!=end(); ++it) { const abstract_eventt &it_evt=egraph[*it]; - if(it_evt.operation!=abstract_eventt::Fence - && it_evt.operation!=abstract_eventt::Lwfence - && it_evt.operation!=abstract_eventt::ASMfence) + if(it_evt.operation!=abstract_eventt::operationt::Fence + && it_evt.operation!=abstract_eventt::operationt::Lwfence + && it_evt.operation!=abstract_eventt::operationt::ASMfence) break; } @@ -1006,27 +921,15 @@ bool event_grapht::critical_cyclet::is_not_uniproc() const { const abstract_eventt &it_evt=egraph[*it]; if(it_evt.variable!=var - && it_evt.operation!=abstract_eventt::Fence - && it_evt.operation!=abstract_eventt::Lwfence - && it_evt.operation!=abstract_eventt::ASMfence) + && it_evt.operation!=abstract_eventt::operationt::Fence + && it_evt.operation!=abstract_eventt::operationt::Lwfence + && it_evt.operation!=abstract_eventt::operationt::ASMfence) break; } return (it!=end()); } -/*******************************************************************\ - -Function: event_grapht::critical_cyclet::is_not_weak_uniproc - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool event_grapht::critical_cyclet::is_not_weak_uniproc() const { const_iterator it=begin(); @@ -1035,9 +938,9 @@ bool event_grapht::critical_cyclet::is_not_weak_uniproc() const for(; it!=end(); it++) { const abstract_eventt &it_evt=egraph[*it]; - if(it_evt.operation!=abstract_eventt::Fence - && it_evt.operation!=abstract_eventt::Lwfence - && it_evt.operation!=abstract_eventt::ASMfence) + if(it_evt.operation!=abstract_eventt::operationt::Fence + && it_evt.operation!=abstract_eventt::operationt::Lwfence + && it_evt.operation!=abstract_eventt::operationt::ASMfence) break; } @@ -1053,29 +956,17 @@ bool event_grapht::critical_cyclet::is_not_weak_uniproc() const const abstract_eventt &it_evt=egraph[*it]; if( !(it_evt.variable==var - &&(it==begin() || it_evt.operation!=abstract_eventt::Read - || egraph[*prev].operation!=abstract_eventt::Read)) - && it_evt.operation!=abstract_eventt::Fence - && it_evt.operation!=abstract_eventt::Lwfence - && it_evt.operation!=abstract_eventt::ASMfence) + &&(it==begin() || it_evt.operation!=abstract_eventt::operationt::Read + || egraph[*prev].operation!=abstract_eventt::operationt::Read)) + && it_evt.operation!=abstract_eventt::operationt::Fence + && it_evt.operation!=abstract_eventt::operationt::Lwfence + && it_evt.operation!=abstract_eventt::operationt::ASMfence) break; } return (it!=end()); } -/*******************************************************************\ - -Function: event_grapht::critical_cyclet::is_not_thin_air - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool event_grapht::critical_cyclet::is_not_thin_air() const { // assert(size()>2); @@ -1094,8 +985,8 @@ bool event_grapht::critical_cyclet::is_not_thin_air() const const abstract_eventt &next=egraph[*n_it]; /* rf */ - if(current.operation==abstract_eventt::Write && - next.operation==abstract_eventt::Read) + if(current.operation==abstract_eventt::operationt::Write && + next.operation==abstract_eventt::operationt::Read) continue; /* data dependencies */ @@ -1111,8 +1002,8 @@ bool event_grapht::critical_cyclet::is_not_thin_air() const const abstract_eventt &next=egraph[front()]; /* rf */ - if(current.operation==abstract_eventt::Write && - next.operation==abstract_eventt::Read) + if(current.operation==abstract_eventt::operationt::Write && + next.operation==abstract_eventt::operationt::Read) return false; /* data dependencies */ @@ -1124,18 +1015,6 @@ bool event_grapht::critical_cyclet::is_not_thin_air() const return true; } -/*******************************************************************\ - -Function: event_grapht::critical_cyclet::print - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string event_grapht::critical_cyclet::print() const { std::string cycle="Cycle: "; @@ -1144,18 +1023,6 @@ std::string event_grapht::critical_cyclet::print() const return cycle + " End of cycle."; } -/*******************************************************************\ - -Function: event_grapht::critical_cyclet::print_unsafes - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string event_grapht::critical_cyclet::print_unsafes() const { std::string name="Unsafe pairs: "; @@ -1167,24 +1034,24 @@ std::string event_grapht::critical_cyclet::print_unsafes() const const abstract_eventt &last=egraph[it->first]; if(last.variable==first.variable - && last.operation==abstract_eventt::Write - && first.operation==abstract_eventt::Read) + && last.operation==abstract_eventt::operationt::Write + && first.operation==abstract_eventt::operationt::Read) { name += " Rf"; name += (last.thread==first.thread?"i":"e"); } else if(last.variable==first.variable && - last.operation==abstract_eventt::Read && - first.operation==abstract_eventt::Write && + last.operation==abstract_eventt::operationt::Read && + first.operation==abstract_eventt::operationt::Write && (last.thread!=first.thread || it->first > it->second)) { name += " Fr"; name += (last.thread==first.thread?"i":"e"); } else if(last.variable==first.variable && - last.operation==abstract_eventt::Write && - first.operation==abstract_eventt::Write && + last.operation==abstract_eventt::operationt::Write && + first.operation==abstract_eventt::operationt::Write && (last.thread!=first.thread || it->first > it->second)) { /* we prefer to write Po rather than Wsi */ @@ -1192,7 +1059,7 @@ std::string event_grapht::critical_cyclet::print_unsafes() const name += (last.thread==first.thread?"i":"e"); } else if(last.thread==first.thread && - last.operation!=abstract_eventt::Fence) + last.operation!=abstract_eventt::operationt::Fence) { name += " Po"; name += (last.variable==first.variable?"s":"d") + last.get_operation() @@ -1203,18 +1070,6 @@ std::string event_grapht::critical_cyclet::print_unsafes() const return name; } -/*******************************************************************\ - -Function: event_grapht::critical_cyclet::print_events - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string event_grapht::critical_cyclet::print_events() const { std::string cycle="Cycle: "; @@ -1227,18 +1082,6 @@ std::string event_grapht::critical_cyclet::print_events() const return cycle+" End of cycle."; } -/*******************************************************************\ - -Function: event_grapht::critical_cyclet::print_output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string event_grapht::critical_cyclet::print_output() const { std::string cycle; @@ -1252,18 +1095,6 @@ std::string event_grapht::critical_cyclet::print_output() const return cycle; } -/*******************************************************************\ - -Function: event_grapht::critical_cyclet::print_detail - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string event_grapht::critical_cyclet::print_detail( const critical_cyclet &reduced, std::map &map_id2var, @@ -1293,18 +1124,6 @@ std::string event_grapht::critical_cyclet::print_detail( return cycle; } -/*******************************************************************\ - -Function: event_grapht::critical_cyclet::print_all - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string event_grapht::critical_cyclet::print_all( memory_modelt model, std::map &map_id2var, @@ -1335,18 +1154,6 @@ std::string event_grapht::critical_cyclet::print_all( return cycle; } -/*******************************************************************\ - -Function: event_grapht::critical_cyclet::hide_internals - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void event_grapht::critical_cyclet::hide_internals( critical_cyclet &reduced) const { @@ -1423,18 +1230,6 @@ void event_grapht::critical_cyclet::hide_internals( } } -/*******************************************************************\ - -Function: event_grapht::critical_cyclet::print_name - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string event_grapht::critical_cyclet::print_name( const critical_cyclet &reduced, memory_modelt model) const @@ -1453,15 +1248,15 @@ std::string event_grapht::critical_cyclet::print_name( { const abstract_eventt &prev=egraph[*prev_it]; - if(prev.operation==abstract_eventt::Fence || - prev.operation==abstract_eventt::Lwfence || - prev.operation==abstract_eventt::ASMfence) + if(prev.operation==abstract_eventt::operationt::Fence || + prev.operation==abstract_eventt::operationt::Lwfence || + prev.operation==abstract_eventt::operationt::ASMfence) { ++extra_fence_count; // nothing to do } - else if(cur.operation==abstract_eventt::Fence) + else if(cur.operation==abstract_eventt::operationt::Fence) { const_iterator n_it=cur_it; bool wraparound=false; @@ -1477,9 +1272,9 @@ std::string event_grapht::critical_cyclet::print_name( n_it=reduced.begin(); } const abstract_eventt &cand=egraph[*n_it]; - if(cand.operation!=abstract_eventt::Fence && - cand.operation!=abstract_eventt::Lwfence && - cand.operation!=abstract_eventt::ASMfence) + if(cand.operation!=abstract_eventt::operationt::Fence && + cand.operation!=abstract_eventt::operationt::Lwfence && + cand.operation!=abstract_eventt::operationt::ASMfence) break; if(!wraparound) ++cur_it; @@ -1487,14 +1282,14 @@ std::string event_grapht::critical_cyclet::print_name( ++extra_fence_count; } const abstract_eventt &succ=egraph[*n_it]; - assert(succ.operation==abstract_eventt::Read || - succ.operation==abstract_eventt::Write); + assert(succ.operation==abstract_eventt::operationt::Read || + succ.operation==abstract_eventt::operationt::Write); name += (model==Power?" Sync":" MFence"); name += (prev.variable==succ.variable?"s":"d") + prev.get_operation() + succ.get_operation(); } - else if(cur.operation==abstract_eventt::Lwfence) + else if(cur.operation==abstract_eventt::operationt::Lwfence) { std::string cand_name=" LwSync"; const_iterator n_it=cur_it; @@ -1511,12 +1306,12 @@ std::string event_grapht::critical_cyclet::print_name( n_it=reduced.begin(); } const abstract_eventt &cand=egraph[*n_it]; - if(cand.operation!=abstract_eventt::Fence && - cand.operation!=abstract_eventt::Lwfence && - cand.operation!=abstract_eventt::ASMfence) + if(cand.operation!=abstract_eventt::operationt::Fence && + cand.operation!=abstract_eventt::operationt::Lwfence && + cand.operation!=abstract_eventt::operationt::ASMfence) break; - else if(cand.operation==abstract_eventt::Fence || - (cand.operation==abstract_eventt::ASMfence && + else if(cand.operation==abstract_eventt::operationt::Fence || + (cand.operation==abstract_eventt::operationt::ASMfence && cand.fence_value()&1)) cand_name=(model==Power?" Sync":" MFence"); if(!wraparound) @@ -1525,14 +1320,14 @@ std::string event_grapht::critical_cyclet::print_name( ++extra_fence_count; } const abstract_eventt &succ=egraph[*n_it]; - assert(succ.operation==abstract_eventt::Read || - succ.operation==abstract_eventt::Write); + assert(succ.operation==abstract_eventt::operationt::Read || + succ.operation==abstract_eventt::operationt::Write); name += cand_name; name += (prev.variable==succ.variable?"s":"d") + prev.get_operation() + succ.get_operation(); } - else if(cur.operation==abstract_eventt::ASMfence) + else if(cur.operation==abstract_eventt::operationt::ASMfence) { std::string cand_name; if(cur.fence_value()&1) @@ -1553,12 +1348,12 @@ std::string event_grapht::critical_cyclet::print_name( n_it=reduced.begin(); } const abstract_eventt &cand=egraph[*n_it]; - if(cand.operation!=abstract_eventt::Fence && - cand.operation!=abstract_eventt::Lwfence && - cand.operation!=abstract_eventt::ASMfence) + if(cand.operation!=abstract_eventt::operationt::Fence && + cand.operation!=abstract_eventt::operationt::Lwfence && + cand.operation!=abstract_eventt::operationt::ASMfence) break; - else if(cand.operation==abstract_eventt::Fence || - (cand.operation==abstract_eventt::ASMfence && + else if(cand.operation==abstract_eventt::operationt::Fence || + (cand.operation==abstract_eventt::operationt::ASMfence && cand.fence_value()&1)) cand_name=(model==Power?" Sync":" MFence"); if(!wraparound) @@ -1567,24 +1362,24 @@ std::string event_grapht::critical_cyclet::print_name( ++extra_fence_count; } const abstract_eventt &succ=egraph[*n_it]; - assert(succ.operation==abstract_eventt::Read || - succ.operation==abstract_eventt::Write); + assert(succ.operation==abstract_eventt::operationt::Read || + succ.operation==abstract_eventt::operationt::Write); name += cand_name; name += (prev.variable==succ.variable?"s":"d") + prev.get_operation() + succ.get_operation(); } else if(prev.variable==cur.variable - && prev.operation==abstract_eventt::Write - && cur.operation==abstract_eventt::Read) + && prev.operation==abstract_eventt::operationt::Write + && cur.operation==abstract_eventt::operationt::Read) { name += " Rf"; name += (prev.thread==cur.thread?"i":"e"); } else if(prev.variable==cur.variable - && prev.operation==abstract_eventt::Read - && cur.operation==abstract_eventt::Write + && prev.operation==abstract_eventt::operationt::Read + && cur.operation==abstract_eventt::operationt::Write && (prev.thread!=cur.thread || *prev_it > *cur_it)) { name += " Fr"; @@ -1592,8 +1387,8 @@ std::string event_grapht::critical_cyclet::print_name( } else if(prev.variable==cur.variable && - prev.operation==abstract_eventt::Write && - cur.operation==abstract_eventt::Write && + prev.operation==abstract_eventt::operationt::Write && + cur.operation==abstract_eventt::operationt::Write && (prev.thread!=cur.thread || *prev_it > *cur_it)) { /* we prefer to write Po rather than Wsi */ @@ -1602,13 +1397,13 @@ std::string event_grapht::critical_cyclet::print_name( } else if(prev.thread==cur.thread - && prev.operation!=abstract_eventt::Fence - && prev.operation!=abstract_eventt::Lwfence - && prev.operation!=abstract_eventt::ASMfence) + && prev.operation!=abstract_eventt::operationt::Fence + && prev.operation!=abstract_eventt::operationt::Lwfence + && prev.operation!=abstract_eventt::operationt::ASMfence) { const data_dpt &dep=egraph.map_data_dp[cur.thread]; - if(prev.operation==abstract_eventt::Read && + if(prev.operation==abstract_eventt::operationt::Read && dep.dp(prev, cur)) { name += " DpData"; @@ -1646,13 +1441,13 @@ std::string event_grapht::critical_cyclet::print_name( const abstract_eventt &first=egraph[reduced.front()]; const abstract_eventt &last=egraph[reduced.back()]; - assert(last.operation!=abstract_eventt::Fence && - last.operation!=abstract_eventt::Lwfence && - last.operation!=abstract_eventt::ASMfence); + assert(last.operation!=abstract_eventt::operationt::Fence && + last.operation!=abstract_eventt::operationt::Lwfence && + last.operation!=abstract_eventt::operationt::ASMfence); - if(first.operation==abstract_eventt::Fence || - first.operation==abstract_eventt::Lwfence || - first.operation==abstract_eventt::ASMfence) + if(first.operation==abstract_eventt::operationt::Fence || + first.operation==abstract_eventt::operationt::Lwfence || + first.operation==abstract_eventt::operationt::ASMfence) { std::string cand_name=" LwSync"; const_iterator it=reduced.begin(); @@ -1660,35 +1455,35 @@ std::string event_grapht::critical_cyclet::print_name( { const abstract_eventt &cand=egraph[*it]; - if(cand.operation!=abstract_eventt::Fence && - cand.operation!=abstract_eventt::Lwfence && - cand.operation!=abstract_eventt::ASMfence) + if(cand.operation!=abstract_eventt::operationt::Fence && + cand.operation!=abstract_eventt::operationt::Lwfence && + cand.operation!=abstract_eventt::operationt::ASMfence) break; - else if(cand.operation==abstract_eventt::Fence || - (cand.operation==abstract_eventt::ASMfence && + else if(cand.operation==abstract_eventt::operationt::Fence || + (cand.operation==abstract_eventt::operationt::ASMfence && cand.fence_value()&1)) cand_name=(model==Power?" Sync":" MFence"); } assert(it!=reduced.begin() && it!=reduced.end()); const abstract_eventt &succ=egraph[*it]; - assert(succ.operation==abstract_eventt::Read || - succ.operation==abstract_eventt::Write); + assert(succ.operation==abstract_eventt::operationt::Read || + succ.operation==abstract_eventt::operationt::Write); name += cand_name; name += (last.variable==succ.variable?"s":"d") + last.get_operation() + succ.get_operation(); } else if(last.variable==first.variable - && last.operation==abstract_eventt::Write - && first.operation==abstract_eventt::Read) + && last.operation==abstract_eventt::operationt::Write + && first.operation==abstract_eventt::operationt::Read) { name += " Rf"; name += (last.thread==first.thread?"i":"e"); } else if(last.variable==first.variable - && last.operation==abstract_eventt::Read - && first.operation==abstract_eventt::Write + && last.operation==abstract_eventt::operationt::Read + && first.operation==abstract_eventt::operationt::Write && (last.thread!=first.thread || reduced.back() > reduced.front())) { name += " Fr"; @@ -1696,8 +1491,8 @@ std::string event_grapht::critical_cyclet::print_name( } else if(last.variable==first.variable && - last.operation==abstract_eventt::Write && - first.operation==abstract_eventt::Write && + last.operation==abstract_eventt::operationt::Write && + first.operation==abstract_eventt::operationt::Write && (last.thread!=first.thread || reduced.back() > reduced.front())) { /* we prefer to write Po rather than Wsi */ @@ -1709,7 +1504,7 @@ std::string event_grapht::critical_cyclet::print_name( { const data_dpt &dep=egraph.map_data_dp[last.thread]; - if(last.operation==abstract_eventt::Read && + if(last.operation==abstract_eventt::operationt::Read && dep.dp(last, first)) { name += " DpData"; @@ -1740,18 +1535,6 @@ std::string event_grapht::critical_cyclet::print_name( return name; } -/*******************************************************************\ - -Function: event_grapht::critical_cyclet::print_dot - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void event_grapht::critical_cyclet::print_dot( std::ostream &str, unsigned colour, @@ -1763,12 +1546,11 @@ void event_grapht::critical_cyclet::print_dot( const abstract_eventt &ev=egraph[*it]; /* id of the cycle in comments */ - str << "/* " << id << " */" << std::endl; + str << "/* " << id << " */\n"; /* vertex */ str << ev.id << "[label=\"\\\\lb {" << ev.id << "}" << ev.get_operation(); - str << "{" << ev.variable << "} {} @thread" << ev.thread << "\"];"; - str << std::endl; + str << "{" << ev.variable << "} {} @thread" << ev.thread << "\"];\n"; } /* print edges */ @@ -1778,7 +1560,7 @@ void event_grapht::critical_cyclet::print_dot( const abstract_eventt &cur=egraph[*cur_it]; /* id of the cycle in comments */ - str << "/* " << id << " */" << std::endl; + str << "/* " << id << " */\n"; /* edge */ if(prev_it!=end()) @@ -1786,7 +1568,7 @@ void event_grapht::critical_cyclet::print_dot( const abstract_eventt &prev=egraph[*prev_it]; str << prev.id << "->"; - if(cur.operation==abstract_eventt::Fence) + if(cur.operation==abstract_eventt::operationt::Fence) { const_iterator n_it=cur_it; ++n_it; @@ -1797,7 +1579,7 @@ void event_grapht::critical_cyclet::print_dot( str << (prev.variable==cur.variable?"s":"d"); str << prev.get_operation() << succ.get_operation(); } - else if(cur.operation==abstract_eventt::Lwfence) + else if(cur.operation==abstract_eventt::operationt::Lwfence) { const_iterator n_it=cur_it; ++n_it; @@ -1808,22 +1590,22 @@ void event_grapht::critical_cyclet::print_dot( str <"; - if(first.operation==abstract_eventt::Fence) + if(first.operation==abstract_eventt::operationt::Fence) { const_iterator next=begin(); ++next; @@ -1864,7 +1646,7 @@ void event_grapht::critical_cyclet::print_dot( str << (last.variable==first.variable?"s":"d"); str << last.get_operation() << succ.get_operation(); } - else if(first.operation==abstract_eventt::Lwfence) + else if(first.operation==abstract_eventt::operationt::Lwfence) { const_iterator next=begin(); ++next; @@ -1874,22 +1656,22 @@ void event_grapht::critical_cyclet::print_dot( str << last.get_operation() << succ.get_operation(); } else if(last.variable==first.variable && - last.operation==abstract_eventt::Write && - first.operation==abstract_eventt::Read) + last.operation==abstract_eventt::operationt::Write && + first.operation==abstract_eventt::operationt::Read) { str << first.id << "[label=\""; str << "Rf" << (last.thread==first.thread?"i":"e"); } else if(last.variable==first.variable && - last.operation==abstract_eventt::Read && - first.operation==abstract_eventt::Write) + last.operation==abstract_eventt::operationt::Read && + first.operation==abstract_eventt::operationt::Write) { str << first.id << "[label=\""; str << "Fr" << (last.thread==first.thread?"i":"e"); } else if(last.variable==first.variable && - last.operation==abstract_eventt::Write && - first.operation==abstract_eventt::Write && + last.operation==abstract_eventt::operationt::Write && + first.operation==abstract_eventt::operationt::Write && last.thread!=first.thread) { /* we prefer to write Po rather than Wsi */ @@ -1897,7 +1679,7 @@ void event_grapht::critical_cyclet::print_dot( str << "Ws" << (last.thread==first.thread?"i":"e"); } else if(last.thread==first.thread && - last.operation!=abstract_eventt::Fence) + last.operation!=abstract_eventt::operationt::Fence) { str << first.id << "[label=\""; str << "Po" << (last.variable==first.variable?"s":"d"); @@ -1906,5 +1688,5 @@ void event_grapht::critical_cyclet::print_dot( else str << first.id << "[label=\"?"; - str << "\", color=" << print_colour(colour) << "];" < wmm_grapht; typedef wmm_grapht::node_indext event_idt; @@ -98,9 +97,8 @@ class event_grapht from.hide_internals(&target) */ void hide_internals(critical_cyclet &reduced) const; - /* checks whether there is at leat one pair which is unsafe - (takes fences and dependencies into account), and adds - the unsafe pairs in the set */ + /// checks whether there is at least one pair which is unsafe (takes fences + /// and dependencies into account), and adds the unsafe pairs in the set bool is_unsafe(memory_modelt model, bool fast=false); /* do not update the unsafe pairs set */ @@ -179,7 +177,7 @@ class event_grapht { critical_cyclet reduced(egraph, id); this->hide_internals(reduced); - assert(reduced.size()>0); + assert(!reduced.empty()); return print_name(reduced, model); } else @@ -347,6 +345,9 @@ class event_grapht public: explicit event_grapht(messaget &_message): + max_var(0), + max_po_trans(0), + ignore_arrays(false), filter_thin_air(true), filter_uniproc(true), message(_message) diff --git a/src/goto-instrument/wmm/fence.cpp b/src/goto-instrument/wmm/fence.cpp index 34c0c387ac5..82e9308278d 100644 --- a/src/goto-instrument/wmm/fence.cpp +++ b/src/goto-instrument/wmm/fence.cpp @@ -8,10 +8,13 @@ Date: February 2012 \*******************************************************************/ -#include +/// \file +/// Fences for instrumentation #include "fence.h" +#include + bool is_fence( const goto_programt::instructiont &instruction, const namespacet &ns) diff --git a/src/goto-instrument/wmm/fence.h b/src/goto-instrument/wmm/fence.h index 5d14c2cc7a3..0e08d23be28 100644 --- a/src/goto-instrument/wmm/fence.h +++ b/src/goto-instrument/wmm/fence.h @@ -8,6 +8,9 @@ Date: February 2012 \*******************************************************************/ +/// \file +/// Fences for instrumentation + #ifndef CPROVER_GOTO_INSTRUMENT_WMM_FENCE_H #define CPROVER_GOTO_INSTRUMENT_WMM_FENCE_H diff --git a/src/goto-instrument/wmm/goto2graph.cpp b/src/goto-instrument/wmm/goto2graph.cpp index 390a21b6c3a..011ef1a36ac 100644 --- a/src/goto-instrument/wmm/goto2graph.cpp +++ b/src/goto-instrument/wmm/goto2graph.cpp @@ -8,6 +8,11 @@ Date: 2012 \*******************************************************************/ +/// \file +/// Turns a goto-program into an abstract event graph + +#include "goto2graph.h" + #include #include #include @@ -25,23 +30,11 @@ Date: 2012 #include "../rw_set.h" #include "fence.h" -#include "goto2graph.h" // #define PRINT_UNSAFES -/*******************************************************************\ - -Function: instrumentert::local - - Inputs: - - Outputs: - - Purpose: is local variable? - -\*******************************************************************/ - +/// is local variable? bool inline instrumentert::local(const irep_idt &id) { std::string identifier=id2string(id); @@ -95,20 +88,8 @@ bool inline instrumentert::cfg_visitort::local(const irep_idt &i) return instrumenter.local(i); } -/*******************************************************************\ - -Function: instrumentert::goto2graph_cfg - - Inputs: - - Outputs: - - Purpose: goes through CFG and build a static abstract event - graph overapproximating the read/write relations for any - executions - -\*******************************************************************/ - +/// goes through CFG and build a static abstract event graph overapproximating +/// the read/write relations for any executions unsigned instrumentert::goto2graph_cfg( value_setst &value_sets, memory_modelt model, @@ -169,18 +150,6 @@ unsigned instrumentert::goto2graph_cfg( return visitor.max_thread; } -/*******************************************************************\ - -Function: instrumentert::cfg_visitort::visit_cfg_function - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void instrumentert::cfg_visitort::visit_cfg_function( /* value_sets and options */ value_setst &value_sets, @@ -319,18 +288,6 @@ void instrumentert::cfg_visitort::visit_cfg_function( } } -/*******************************************************************\ - -Function: instrumentert::visit_cfg_propagate - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void inline instrumentert::cfg_visitort::visit_cfg_propagate( goto_programt::instructionst::iterator i_it) { @@ -343,34 +300,11 @@ void inline instrumentert::cfg_visitort::visit_cfg_propagate( in_pos[i_it].insert(node); } -/*******************************************************************\ - -Function: instrumentert::visit_cfg_thread - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void instrumentert::cfg_visitort::visit_cfg_thread() const { } -/*******************************************************************\ - -Function: instrumentert::visit_cfg_reference_function - - Inputs: - - Outputs: - - Purpose: references the first and last edges of the function - -\*******************************************************************/ - +/// references the first and last edges of the function /* OBSOLETE */ /* Note: can be merged with visit_cfg_body */ /* Warning: we iterate here over the successive instructions of the @@ -459,18 +393,6 @@ void inline instrumentert::cfg_visitort::visit_cfg_reference_function( std::make_pair(in_nodes, out_nodes); } -/*******************************************************************\ - -Function: alt_copy_segment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - event_idt alt_copy_segment(wmm_grapht &alt_egraph, event_idt begin, event_idt end) { @@ -480,18 +402,6 @@ event_idt alt_copy_segment(wmm_grapht &alt_egraph, return end; } -/*******************************************************************\ - -Function: instrumentert::visit_cfg_visitort::contains_shared_array - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool instrumentert::cfg_visitort::contains_shared_array( goto_programt::const_targett targ, goto_programt::const_targett i_it, @@ -540,18 +450,7 @@ bool instrumentert::cfg_visitort::contains_shared_array( } -/*******************************************************************\ - -Function: instrumentert::visit_cfg_visitort::visit_cfg_body - - Inputs: - - Outputs: - - Purpose: strategy: fwd/bwd alternation - -\*******************************************************************/ - +/// strategy: fwd/bwd alternation void inline instrumentert::cfg_visitort::visit_cfg_body( goto_programt::const_targett i_it, loop_strategyt replicate_body, @@ -597,18 +496,6 @@ void inline instrumentert::cfg_visitort::visit_cfg_body( } } -/*******************************************************************\ - -Function: instrumentert::visit_cfg_visitort::visit_cfg_duplicate - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void inline instrumentert::cfg_visitort::visit_cfg_duplicate( goto_programt::const_targett targ, goto_programt::const_targett i_it) @@ -672,18 +559,7 @@ void inline instrumentert::cfg_visitort::visit_cfg_duplicate( } } -/*******************************************************************\ - -Function: instrumentert::visit_cfg_visitort::visit_cfg_backedge - - Inputs: - - Outputs: - - Purpose: strategy: fwd/bwd alternation - -\*******************************************************************/ - +/// strategy: fwd/bwd alternation void inline instrumentert::cfg_visitort::visit_cfg_backedge( goto_programt::const_targett targ, goto_programt::const_targett i_it) @@ -750,18 +626,6 @@ void inline instrumentert::cfg_visitort::visit_cfg_backedge( } } -/*******************************************************************\ - -Function: instrumentert::visit_cfg_goto - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void instrumentert::cfg_visitort::visit_cfg_goto( goto_programt::instructionst::iterator i_it, loop_strategyt replicate_body, @@ -791,18 +655,6 @@ void instrumentert::cfg_visitort::visit_cfg_goto( } } -/*******************************************************************\ - -Function: intrumentert::visit_cfg_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void instrumentert::cfg_visitort::visit_cfg_function_call( value_setst &value_sets, goto_programt::instructionst::iterator i_it, @@ -870,23 +722,11 @@ void instrumentert::cfg_visitort::visit_cfg_function_call( } } -/*******************************************************************\ - -Function: instrumentert::visit_cfg_lwfence - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void instrumentert::cfg_visitort::visit_cfg_lwfence( goto_programt::instructionst::iterator i_it) { const goto_programt::instructiont &instruction=*i_it; - const abstract_eventt new_fence_event(abstract_eventt::Lwfence, + const abstract_eventt new_fence_event(abstract_eventt::operationt::Lwfence, thread, "f", instrumenter.unique_id++, instruction.source_location, false); const event_idt new_fence_node=egraph.add_node(); egraph[new_fence_node](new_fence_event); @@ -914,18 +754,6 @@ void instrumentert::cfg_visitort::visit_cfg_lwfence( updated.insert(i_it); } -/*******************************************************************\ - -Function: instrumentert::visit_cfg_lwfence - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void instrumentert::cfg_visitort::visit_cfg_asm_fence( goto_programt::instructionst::iterator i_it) { @@ -937,7 +765,7 @@ void instrumentert::cfg_visitort::visit_cfg_asm_fence( bool WWcumul=instruction.code.get_bool(ID_WWcumul); bool RRcumul=instruction.code.get_bool(ID_RRcumul); bool RWcumul=instruction.code.get_bool(ID_RWcumul); - const abstract_eventt new_fence_event(abstract_eventt::ASMfence, + const abstract_eventt new_fence_event(abstract_eventt::operationt::ASMfence, thread, "asm", instrumenter.unique_id++, instruction.source_location, false, WRfence, WWfence, RRfence, RWfence, WWcumul, RWcumul, RRcumul); const event_idt new_fence_node=egraph.add_node(); @@ -966,18 +794,6 @@ void instrumentert::cfg_visitort::visit_cfg_asm_fence( updated.insert(i_it); } -/*******************************************************************\ - -Function: instrumentert::visit_cfg_assign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void instrumentert::cfg_visitort::visit_cfg_assign( value_setst &value_sets, namespacet &ns, @@ -1026,7 +842,7 @@ void instrumentert::cfg_visitort::visit_cfg_assign( assert(read_expr); #endif - const abstract_eventt new_read_event(abstract_eventt::Read, + const abstract_eventt new_read_event(abstract_eventt::operationt::Read, thread, id2string(read), instrumenter.unique_id++, instruction.source_location, local(read)); @@ -1124,7 +940,7 @@ void instrumentert::cfg_visitort::visit_cfg_assign( // assert(write_expr); /* creates Write */ - const abstract_eventt new_write_event(abstract_eventt::Write, + const abstract_eventt new_write_event(abstract_eventt::operationt::Write, thread, id2string(write), instrumenter.unique_id++, instruction.source_location, local(write)); @@ -1295,23 +1111,11 @@ void instrumentert::cfg_visitort::visit_cfg_assign( } } -/*******************************************************************\ - -Function: instrumentert::visit_cfg_fence - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void instrumentert::cfg_visitort::visit_cfg_fence( goto_programt::instructionst::iterator i_it) { const goto_programt::instructiont &instruction=*i_it; - const abstract_eventt new_fence_event(abstract_eventt::Fence, + const abstract_eventt new_fence_event(abstract_eventt::operationt::Fence, thread, "F", instrumenter.unique_id++, instruction.source_location, false); const event_idt new_fence_node=egraph.add_node(); egraph[new_fence_node](new_fence_event); @@ -1342,36 +1146,12 @@ void instrumentert::cfg_visitort::visit_cfg_fence( updated.insert(i_it); } -/*******************************************************************\ - -Function: intrumentert::visit_cfg_skip - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void instrumentert::cfg_visitort::visit_cfg_skip( goto_programt::instructionst::iterator i_it) { visit_cfg_propagate(i_it); } -/*******************************************************************\ - -Function: intrumentert::add_instr_to_interleaving - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void inline instrumentert::add_instr_to_interleaving( goto_programt::instructionst::iterator it, goto_programt &interleaving) @@ -1404,18 +1184,6 @@ void inline instrumentert::add_instr_to_interleaving( current_instruction->swap(new_instruction); } -/*******************************************************************\ - -Function: instrumentert::is_cfg_spurious - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool instrumentert::is_cfg_spurious(const event_grapht::critical_cyclet &cyc) { message.debug() << "spurious by CFG? " << messaget::eom; @@ -1430,7 +1198,7 @@ bool instrumentert::is_cfg_spurious(const event_grapht::critical_cyclet &cyc) const source_locationt ¤t_location=current_event.source_location; /* select relevant thread (po) -- or function contained in this thread */ - goto_programt *current_po=0; + goto_programt *current_po=nullptr; bool thread_found=false; Forall_goto_functions(f_it, goto_functions) @@ -1557,18 +1325,6 @@ bool instrumentert::is_cfg_spurious(const event_grapht::critical_cyclet &cyc) #endif } -/*******************************************************************\ - -Function: instrumentert::cfg_cycles_filter - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void instrumentert::cfg_cycles_filter() { if(!set_of_cycles.empty()) @@ -1616,18 +1372,6 @@ void instrumentert::cfg_cycles_filter() message.status() << "No cycle to filter" << messaget::eom; } -/*******************************************************************\ - -Function: instrumentert::print_outputs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void inline instrumentert::print_outputs_local( const std::set &set, std::ofstream &dot, @@ -1657,10 +1401,10 @@ void inline instrumentert::print_outputs_local( message.debug() << it->print_unsafes() << messaget::eom; #endif it->print_dot(dot, colour++, model); - ref << it->print_name(model, hide_internals) << std::endl; - output << it->print_output() << std::endl; + ref << it->print_name(model, hide_internals) << '\n'; + output << it->print_output() << '\n'; all << it->print_all(model, map_id2var, map_var2id, hide_internals) - << std::endl; + << '\n'; /* emphasises instrumented events */ for(std::list::const_iterator it_e=it->begin(); @@ -1682,7 +1426,7 @@ void inline instrumentert::print_outputs_local( { dot << ev.id << "[label=\"\\\\lb {" << ev.id << "}"; dot << ev.get_operation() << "{" << ev.variable << "} {} @thread"; - dot << ev.thread << "\",color=red,shape=box];" << std::endl; + dot << ev.thread << "\",color=red,shape=box];\n"; } } } @@ -1698,7 +1442,7 @@ void inline instrumentert::print_outputs_local( for(std::set::iterator it=same_po[i].begin(); it!=same_po[i].end(); it++) dot << egraph[*it].id << ";"; - dot << "};" << std::endl; + dot << "};\n"; } } @@ -1709,15 +1453,14 @@ void inline instrumentert::print_outputs_local( same_file.begin(); it!=same_file.end(); it++) { - dot << "subgraph cluster_" << irep_id_hash()(it->first) << "{" - << std::endl; - dot << " label=\"" << it->first << "\";" << std::endl; + dot << "subgraph cluster_" << irep_id_hash()(it->first) << "{\n"; + dot << " label=\"" << it->first << "\";\n"; for(std::set::const_iterator ev_it=it->second.begin(); ev_it!=it->second.end(); ev_it++) { - dot << " " << egraph[*ev_it].id << ";" << std::endl; + dot << " " << egraph[*ev_it].id << ";\n"; } - dot << "};" << std::endl; + dot << "};\n"; } } @@ -1728,11 +1471,11 @@ void inline instrumentert::print_outputs_local( m_it!=map_id2var.end(); ++m_it) { - table << std::endl << "| " << m_it->first << " : " << m_it->second; + table << "\n| " << m_it->first << " : " << m_it->second; } - table << std::endl; + table << '\n'; table << std::string(80, '-'); - table << std::endl; + table << '\n'; } void instrumentert::print_outputs(memory_modelt model, bool hide_internals) @@ -1749,8 +1492,8 @@ void instrumentert::print_outputs(memory_modelt model, bool hide_internals) all.open("all.txt"); table.open("table.txt"); - dot << "digraph G {" << std::endl; - dot << "nodesep=1; ranksep=1;" << std::endl; + dot << "digraph G {\n"; + dot << "nodesep=1; ranksep=1;\n"; /* prints cycles in the different outputs */ if(!set_of_cycles.empty()) @@ -1764,21 +1507,21 @@ void instrumentert::print_outputs(memory_modelt model, bool hide_internals) std::string name="scc_" + std::to_string(i) + ".dot"; local_dot.open(name.c_str()); - local_dot << "digraph G {" << std::endl; - local_dot << "nodesep=1; ranksep=1;" << std::endl; + local_dot << "digraph G {\n"; + local_dot << "nodesep=1; ranksep=1;\n"; print_outputs_local(set_of_cycles_per_SCC[i], local_dot, ref, output, all, table, model, hide_internals); - local_dot << "}" << std::endl; + local_dot << "}\n"; local_dot.close(); dot << i << "[label=\"SCC " << i << "\",link=\"" << "scc_" << i; - dot << ".svg\"]" << std::endl; + dot << ".svg\"]\n"; } } else message.debug() << "no cycles to output" << messaget::eom; - dot << "}" << std::endl; + dot << "}\n"; dot.close(); ref.close(); @@ -1787,18 +1530,7 @@ void instrumentert::print_outputs(memory_modelt model, bool hide_internals) table.close(); } -/*******************************************************************\ - -Function: instrumentert::collect_cycles_by_SCCs - - Inputs: - - Outputs: - - Purpose: Note: can be distributed (#define DISTRIBUTED) - -\*******************************************************************/ - +/// Note: can be distributed (#define DISTRIBUTED) #if 1 // #ifdef _WIN32 void instrumentert::collect_cycles_by_SCCs(memory_modelt model) diff --git a/src/goto-instrument/wmm/goto2graph.h b/src/goto-instrument/wmm/goto2graph.h index 46193c5239a..ea2a79f8b99 100644 --- a/src/goto-instrument/wmm/goto2graph.h +++ b/src/goto-instrument/wmm/goto2graph.h @@ -8,6 +8,9 @@ Date: 2012 \*******************************************************************/ +/// \file +/// Instrumenter + #ifndef CPROVER_GOTO_INSTRUMENT_WMM_GOTO2GRAPH_H #define CPROVER_GOTO_INSTRUMENT_WMM_GOTO2GRAPH_H @@ -255,18 +258,18 @@ class instrumentert } } - // TODO: move the visitor outside, and inherit + /// TODO: move the visitor outside, and inherit virtual void visit_cfg_function( - /* value_sets and options */ + /// value_sets and options value_setst &value_sets, memory_modelt model, bool no_dependencies, loop_strategyt duplicate_body, - /* functino to analyse */ + /// function to analyse const irep_idt &function, - /* incoming edges */ + /// incoming edges const std::set &initial_vertex, - /* outcoming edges */ + /// outcoming edges std::set &ending_vertex); bool inline local(const irep_idt &i); @@ -325,11 +328,18 @@ class instrumentert std::multimap id2loc; std::multimap id2cycloc; - instrumentert(symbol_tablet &_symbol_table, goto_functionst &_goto_f, - messaget &_message) - :ns(_symbol_table), goto_functions(_goto_f), render_po_aligned(true), - render_by_file(false), render_by_function(false), message(_message), - egraph(_message) + instrumentert( + symbol_tablet &_symbol_table, + goto_functionst &_goto_f, + messaget &_message): + ns(_symbol_table), + goto_functions(_goto_f), + render_po_aligned(true), + render_by_file(false), + render_by_function(false), + message(_message), + egraph(_message), + num_sccs(0) { } diff --git a/src/goto-instrument/wmm/instrumenter_pensieve.h b/src/goto-instrument/wmm/instrumenter_pensieve.h index 7a5210448fe..1e954344322 100644 --- a/src/goto-instrument/wmm/instrumenter_pensieve.h +++ b/src/goto-instrument/wmm/instrumenter_pensieve.h @@ -6,6 +6,9 @@ Module: Instrumenter \*******************************************************************/ +/// \file +/// Instrumenter + #ifndef CPROVER_GOTO_INSTRUMENT_WMM_INSTRUMENTER_PENSIEVE_H #define CPROVER_GOTO_INSTRUMENT_WMM_INSTRUMENTER_PENSIEVE_H diff --git a/src/goto-instrument/wmm/instrumenter_strategies.cpp b/src/goto-instrument/wmm/instrumenter_strategies.cpp index c5bb5563973..df22da52540 100644 --- a/src/goto-instrument/wmm/instrumenter_strategies.cpp +++ b/src/goto-instrument/wmm/instrumenter_strategies.cpp @@ -8,29 +8,19 @@ Date: 2012 \*******************************************************************/ -#include -#include - +/// \file +/// Strategies for picking the abstract events to instrument #include "goto2graph.h" +#include +#include + #ifdef HAVE_GLPK #include #include #endif -/*******************************************************************\ - -Function: instrumentert::instrument_with_strategy - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void instrumentert::instrument_with_strategy(instrumentation_strategyt strategy) { var_to_instr.clear(); @@ -90,18 +80,6 @@ void instrumentert::instrument_with_strategy(instrumentation_strategyt strategy) message.debug() << "no cycles to instrument" << messaget::eom; } -/*******************************************************************\ - -Function: instrumentert::instrument_all_inserter - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void inline instrumentert::instrument_all_inserter( const std::set &set_of_cycles) { @@ -130,18 +108,6 @@ void inline instrumentert::instrument_all_inserter( } } -/*******************************************************************\ - -Function: instrumentert::instrument_one_event_per_cycle - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void inline instrumentert::instrument_one_event_per_cycle_inserter( const std::set &set_of_cycles) { @@ -193,18 +159,6 @@ void inline instrumentert::instrument_one_event_per_cycle_inserter( } } -/*******************************************************************\ - -Function: instrumentert::instrument_one_read_per_cycle - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void inline instrumentert::instrument_one_read_per_cycle_inserter( const std::set &set_of_cycles) { @@ -212,18 +166,6 @@ void inline instrumentert::instrument_one_read_per_cycle_inserter( throw "read first strategy not implemented yet"; } -/*******************************************************************\ - -Function: instrumentert::instrument_one_write_per_cycle - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void inline instrumentert::instrument_one_write_per_cycle_inserter( const std::set &set_of_cycles) { @@ -231,45 +173,22 @@ void inline instrumentert::instrument_one_write_per_cycle_inserter( throw "write first strategy not implemented yet"; } -/*******************************************************************\ - -Function: instrumentert::cost - - Inputs: - - Outputs: - - Purpose: cost function - -\*******************************************************************/ - +/// cost function unsigned inline instrumentert::cost( const event_grapht::critical_cyclet::delayt &e) { /* cost(poW*)=1 cost(poRW)=cost(rfe)=2 cost(poRR)=3 */ - if(egraph[e.first].operation==abstract_eventt::Write) + if(egraph[e.first].operation==abstract_eventt::operationt::Write) return 1; - else if(egraph[e.second].operation==abstract_eventt::Write + else if(egraph[e.second].operation==abstract_eventt::operationt::Write || !e.is_po) return 2; else return 3; } -/*******************************************************************\ - -Function: instrumentert::instrument_minimum_interference - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void inline instrumentert::instrument_minimum_interference_inserter( const std::set &set_of_cycles) { @@ -434,18 +353,6 @@ void inline instrumentert::instrument_minimum_interference_inserter( #endif } -/*******************************************************************\ - -Function: instrumentert::instrument_my_events_inserter - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void inline instrumentert::instrument_my_events_inserter( const std::set &set, const std::set &my_events) @@ -478,18 +385,6 @@ void inline instrumentert::instrument_my_events_inserter( } } -/*******************************************************************\ - -Function: instrumentert::instrument_my_events - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void instrumentert::instrument_my_events( const std::set &my_events) { @@ -508,18 +403,6 @@ void instrumentert::instrument_my_events( message.debug() << "no cycles to instrument" << messaget::eom; } -/*******************************************************************\ - -Function: extract_my_events - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::set instrumentert::extract_my_events() { std::ifstream file; diff --git a/src/goto-instrument/wmm/pair_collection.cpp b/src/goto-instrument/wmm/pair_collection.cpp index c86a0e6994b..bceae75663c 100644 --- a/src/goto-instrument/wmm/pair_collection.cpp +++ b/src/goto-instrument/wmm/pair_collection.cpp @@ -9,26 +9,18 @@ Date: 2013 \*******************************************************************/ -#include - -#include +/// \file +/// collection of pairs (for Pensieve's static delay-set analysis) in graph of +/// abstract events #include "event_graph.h" -#define OUTPUT(s, fence, file, line, id, type) \ - s< - Purpose: +#include -\*******************************************************************/ +#define OUTPUT(s, fence, file, line, id, type) \ + s<(first_event.operation)); } catch(std::string s) { @@ -72,18 +64,6 @@ void event_grapht::graph_pensieve_explorert::collect_pairs(namespacet &ns) res.close(); } -/*******************************************************************\ - -Function: event_grapht::graph_explorert::find_second_event - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool event_grapht::graph_pensieve_explorert::find_second_event( event_idt current) { diff --git a/src/goto-instrument/wmm/shared_buffers.cpp b/src/goto-instrument/wmm/shared_buffers.cpp index 9703a778a8d..f68b29b2fec 100644 --- a/src/goto-instrument/wmm/shared_buffers.cpp +++ b/src/goto-instrument/wmm/shared_buffers.cpp @@ -8,39 +8,18 @@ Author: Daniel Kroening, kroening@kroening.com #include "shared_buffers.h" #include "fence.h" - #include "../rw_set.h" -/*******************************************************************\ - -Function: shared_buffert::unique - - Inputs: - - Outputs: - - Purpose: returns a unique id (for fresh variables) - -\*******************************************************************/ +#include +/// returns a unique id (for fresh variables) std::string shared_bufferst::unique(void) { message.debug()<<"$fresh#"+std::to_string(uniq)< imposes not to have other writes in the buffer assignment( @@ -546,18 +437,7 @@ void shared_bufferst::det_flush( buff1_thd_expr)); } -/*******************************************************************\ - -Function: shared_bufferst::nondet_flush - - Inputs: - - Outputs: - - Purpose: instruments read - -\*******************************************************************/ - +/// instruments read void shared_bufferst::nondet_flush( goto_programt &goto_program, goto_programt::targett &target, @@ -1055,18 +935,6 @@ void shared_bufferst::nondet_flush( } } -/*******************************************************************\ - -Function: is_buffered - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool shared_bufferst::is_buffered( const namespacet &ns, const symbol_exprt &symbol_expr, @@ -1141,21 +1009,9 @@ bool shared_bufferst::is_buffered_in_general( return false; } -/*******************************************************************\ - -Function: affected_by_delay - - Inputs: - - Outputs: - - Purpose: analysis over the goto-program which computes in - affected_by_delay_set the variables (non necessarily - shared themselves) whose value could be changed as - effect of a read delay - -\*******************************************************************/ - +/// analysis over the goto-program which computes in affected_by_delay_set the +/// variables (non necessarily shared themselves) whose value could be changed +/// as effect of a read delay void shared_bufferst::affected_by_delay( symbol_tablet &symbol_table, value_setst &value_sets, @@ -1190,19 +1046,7 @@ void shared_bufferst::affected_by_delay( } } -/*******************************************************************\ - -Function: weak_memory_cfg - - Inputs: - - Outputs: - - Purpose: instruments the program for the pairs detected through the - CFG - -\*******************************************************************/ - +/// instruments the program for the pairs detected through the CFG void shared_bufferst::cfg_visitort::weak_memory( value_setst &value_sets, const irep_idt &function, @@ -1328,7 +1172,7 @@ void shared_bufferst::cfg_visitort::weak_memory( r_it->second.object, vars.type); symbol_exprt new_read_expr=symbol_exprt( vars.read_delayed_var, - pointer_typet(vars.type)); + pointer_type(vars.type)); symbol_exprt read_delayed_expr=symbol_exprt( vars.read_delayed, bool_typet()); diff --git a/src/goto-instrument/wmm/shared_buffers.h b/src/goto-instrument/wmm/shared_buffers.h index 50e3c2ec4db..0550291637e 100644 --- a/src/goto-instrument/wmm/shared_buffers.h +++ b/src/goto-instrument/wmm/shared_buffers.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_GOTO_INSTRUMENT_WMM_SHARED_BUFFERS_H #define CPROVER_GOTO_INSTRUMENT_WMM_SHARED_BUFFERS_H @@ -221,7 +222,7 @@ class shared_bufferst protected: class symbol_tablet &symbol_table; - // number of threads interferring + // number of threads interfering unsigned nb_threads; // instrumentations (not to be instrumented again) diff --git a/src/goto-instrument/wmm/weak_memory.cpp b/src/goto-instrument/wmm/weak_memory.cpp index efe8a73ffaf..0e1b5cbbc90 100644 --- a/src/goto-instrument/wmm/weak_memory.cpp +++ b/src/goto-instrument/wmm/weak_memory.cpp @@ -8,6 +8,9 @@ Date: September 2011 \*******************************************************************/ +/// \file +/// Weak Memory Instrumentation for Threaded Goto Programs + /* * Strategy: we first overapproximate all the read/write sequences of * the program executions with a read/write graph. We then detect the @@ -16,6 +19,8 @@ Date: September 2011 * in the program. */ +#include "weak_memory.h" + #include #include @@ -26,22 +31,10 @@ Date: September 2011 #include "../rw_set.h" -#include "weak_memory.h" #include "shared_buffers.h" #include "goto2graph.h" -/*******************************************************************\ - -Function: introduce_temporaries - - Inputs: - - Outputs: - - Purpose: all access to shared variables is pushed into assignments - -\*******************************************************************/ - +/// all access to shared variables is pushed into assignments void introduce_temporaries( value_setst &value_sets, symbol_tablet &symbol_table, @@ -110,18 +103,6 @@ void introduce_temporaries( } } -/*******************************************************************\ - -Function: weak_memory - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void weak_memory( memory_modelt model, value_setst &value_sets, @@ -209,7 +190,7 @@ void weak_memory( <<" cycles found"<is_goto() || it->is_dead() || it->is_assert() || it->is_assume() || it->is_atomic_begin() || it->is_atomic_end() || diff --git a/src/goto-programs/basic_blocks.h b/src/goto-programs/basic_blocks.h index 9759697a09e..d667c4655d4 100644 --- a/src/goto-programs/basic_blocks.h +++ b/src/goto-programs/basic_blocks.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Group Basic Blocks in Goto Program + #ifndef CPROVER_GOTO_PROGRAMS_BASIC_BLOCKS_H #define CPROVER_GOTO_PROGRAMS_BASIC_BLOCKS_H diff --git a/src/goto-programs/builtin_functions.cpp b/src/goto-programs/builtin_functions.cpp index 0cef3e382b4..530e5e31574 100644 --- a/src/goto-programs/builtin_functions.cpp +++ b/src/goto-programs/builtin_functions.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Program Transformation + +#include "goto_convert_class.h" + #include #include @@ -24,24 +29,11 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include +#include #include -#include "goto_convert_class.h" #include "format_strings.h" -/*******************************************************************\ - -Function: goto_convertt::do_prob_uniform - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::do_prob_uniform( const exprt &lhs, const exprt &function, @@ -120,18 +112,6 @@ void goto_convertt::do_prob_uniform( copy(assignment, ASSIGN, dest); } -/*******************************************************************\ - -Function: goto_convertt::do_prob_coin - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::do_prob_coin( const exprt &lhs, const exprt &function, @@ -209,18 +189,6 @@ void goto_convertt::do_prob_coin( copy(assignment, ASSIGN, dest); } -/*******************************************************************\ - -Function: goto_convertt::do_printf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::do_printf( const exprt &lhs, const exprt &function, @@ -256,18 +224,6 @@ void goto_convertt::do_printf( assert(false); } -/*******************************************************************\ - -Function: goto_convertt::do_scanf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::do_scanf( const exprt &lhs, const exprt &function, @@ -278,7 +234,7 @@ void goto_convertt::do_scanf( if(f_id==CPROVER_PREFIX "scanf") { - if(arguments.size()<1) + if(arguments.empty()) { error().source_location=function.find_source_location(); error() << "scanf takes at least one argument" << eom; @@ -335,7 +291,9 @@ void goto_convertt::do_scanf( copy(array_copy_statement, OTHER, dest); #else - exprt lhs=dereference_exprt(ptr, type.subtype()); + exprt lhs= + index_exprt( + dereference_exprt(ptr, type), from_integer(0, index_type())); exprt rhs=side_effect_expr_nondett(type.subtype()); code_assignt assign(lhs, rhs); assign.add_source_location()=function.source_location(); @@ -371,18 +329,6 @@ void goto_convertt::do_scanf( assert(false); } -/*******************************************************************\ - -Function: goto_convertt::do_input - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::do_input( const exprt &lhs, const exprt &function, @@ -404,18 +350,6 @@ void goto_convertt::do_input( copy(input_code, OTHER, dest); } -/*******************************************************************\ - -Function: goto_convertt::do_output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::do_output( const exprt &lhs, const exprt &function, @@ -437,18 +371,6 @@ void goto_convertt::do_output( copy(output_code, OTHER, dest); } -/*******************************************************************\ - -Function: goto_convertt::do_atomic_begin - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::do_atomic_begin( const exprt &lhs, const exprt &function, @@ -473,18 +395,6 @@ void goto_convertt::do_atomic_begin( t->source_location=function.source_location(); } -/*******************************************************************\ - -Function: goto_convertt::do_atomic_end - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::do_atomic_end( const exprt &lhs, const exprt &function, @@ -509,18 +419,6 @@ void goto_convertt::do_atomic_end( t->source_location=function.source_location(); } -/*******************************************************************\ - -Function: goto_convertt::do_cpp_new - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::do_cpp_new( const exprt &lhs, const side_effect_exprt &rhs, @@ -641,18 +539,6 @@ void goto_convertt::do_cpp_new( dest.destructive_append(tmp_initializer); } -/*******************************************************************\ - -Function: set_class_identifier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void set_class_identifier( struct_exprt &expr, const namespacet &ns, @@ -678,18 +564,6 @@ void set_class_identifier( } } -/*******************************************************************\ - -Function: goto_convertt::do_java_new - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::do_java_new( const exprt &lhs, const side_effect_exprt &rhs, @@ -728,7 +602,7 @@ void goto_convertt::do_java_new( // we produce a malloc side-effect, which stays side_effect_exprt malloc_expr(ID_malloc); malloc_expr.copy_to_operands(object_size); - malloc_expr.type()=pointer_typet(object_type); + malloc_expr.type()=rhs.type(); goto_programt::targett t_n=dest.add_instruction(ASSIGN); t_n->code=code_assignt(lhs, malloc_expr); @@ -745,18 +619,6 @@ void goto_convertt::do_java_new( t_i->source_location=location; } -/*******************************************************************\ - -Function: goto_convertt::do_java_new_array - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::do_java_new_array( const exprt &lhs, const side_effect_exprt &rhs, @@ -796,7 +658,7 @@ void goto_convertt::do_java_new_array( // we produce a malloc side-effect, which stays side_effect_exprt malloc_expr(ID_malloc); malloc_expr.copy_to_operands(object_size); - malloc_expr.type()=pointer_typet(object_type); + malloc_expr.type()=rhs.type(); goto_programt::targett t_n=dest.add_instruction(ASSIGN); t_n->code=code_assignt(lhs, malloc_expr); @@ -824,7 +686,17 @@ void goto_convertt::do_java_new_array( struct_type.components()[2].get_name(), struct_type.components()[2].type()); side_effect_exprt data_cpp_new_expr(ID_cpp_new_array, data.type()); - data_cpp_new_expr.set(ID_size, rhs.op0()); + + // The instruction may specify a (hopefully small) upper bound on the + // array size, in which case we allocate a fixed-length array that may + // be larger than the `length` member rather than use a true variable- + // length array, which produces a more complex formula in the current + // backend. + const irept size_bound=rhs.find(ID_length_upper_bound); + if(size_bound.is_nil()) + data_cpp_new_expr.set(ID_size, rhs.op0()); + else + data_cpp_new_expr.set(ID_size, size_bound); goto_programt::targett t_p=dest.add_instruction(ASSIGN); t_p->code=code_assignt(data, data_cpp_new_expr); t_p->source_location=location; @@ -893,19 +765,7 @@ void goto_convertt::do_java_new_array( } } -/*******************************************************************\ - -Function: goto_convertt::cpp_new_initializer - - Inputs: - - Outputs: - - Purpose: builds a goto program for object initialization - after new - -\*******************************************************************/ - +/// builds a goto program for object initialization after new void goto_convertt::cpp_new_initializer( const exprt &lhs, const side_effect_exprt &rhs, @@ -934,18 +794,6 @@ void goto_convertt::cpp_new_initializer( } } -/*******************************************************************\ - -Function: goto_convertt::get_array_argument - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt goto_convertt::get_array_argument(const exprt &src) { if(src.id()==ID_typecast) @@ -982,51 +830,8 @@ exprt goto_convertt::get_array_argument(const exprt &src) return src.op0().op0(); } -/*******************************************************************\ - -Function: goto_convertt::do_array_set - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::do_array_set( - const exprt &lhs, - const exprt &function, - const exprt::operandst &arguments, - goto_programt &dest) -{ - if(arguments.size()!=2) - { - error().source_location=function.find_source_location(); - error() << "array_set expects two arguments" << eom; - throw 0; - } - - codet array_set_statement; - array_set_statement.set_statement(ID_array_set); - array_set_statement.operands()=arguments; - - copy(array_set_statement, OTHER, dest); -} - -/*******************************************************************\ - -Function: goto_convertt::do_array_copy - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::do_array_copy( +void goto_convertt::do_array_op( + const irep_idt &id, const exprt &lhs, const exprt &function, const exprt::operandst &arguments, @@ -1035,29 +840,18 @@ void goto_convertt::do_array_copy( if(arguments.size()!=2) { error().source_location=function.find_source_location(); - error() << "array_copy expects two arguments" << eom; + error() << id << " expects two arguments" << eom; throw 0; } - codet array_copy_statement; - array_copy_statement.set_statement(ID_array_copy); - array_copy_statement.operands()=arguments; + codet array_op_statement; + array_op_statement.set_statement(id); + array_op_statement.operands()=arguments; + array_op_statement.add_source_location()=function.source_location(); - copy(array_copy_statement, OTHER, dest); + copy(array_op_statement, OTHER, dest); } -/*******************************************************************\ - -Function: goto_convertt::do_array_equal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::do_array_equal( const exprt &lhs, const exprt &function, @@ -1096,23 +890,12 @@ void goto_convertt::do_array_equal( assignment.lhs()=lhs; assignment.rhs()=binary_exprt( lhs_array, ID_array_equal, rhs_array, lhs.type()); + assignment.add_source_location()=function.source_location(); convert(assignment, dest); } } -/*******************************************************************\ - -Function: is_lvalue - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool is_lvalue(const exprt &expr) { if(expr.id()==ID_index) @@ -1127,18 +910,6 @@ bool is_lvalue(const exprt &expr) return false; } -/*******************************************************************\ - -Function: make_va_list - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt make_va_list(const exprt &expr) { // we first strip any typecast @@ -1154,19 +925,7 @@ exprt make_va_list(const exprt &expr) return expr; } -/*******************************************************************\ - -Function: goto_convertt::do_function_call_symbol - - Inputs: - - Outputs: - - Purpose: add function calls to function queue for later - processing - -\*******************************************************************/ - +/// add function calls to function queue for later processing void goto_convertt::do_function_call_symbol( const exprt &lhs, const symbol_exprt &function, @@ -1427,19 +1186,21 @@ void goto_convertt::do_function_call_symbol( assignment.add_source_location()=function.source_location(); copy(assignment, ASSIGN, dest); } - else if(has_prefix(id2string(identifier), CPROVER_PREFIX "array_set")) + else if(identifier==CPROVER_PREFIX "array_equal") { - do_array_set(lhs, function, arguments, dest); + do_array_equal(lhs, function, arguments, dest); } - else if(identifier==CPROVER_PREFIX "array_equal" || - identifier=="__CPROVER::array_equal") + else if(identifier==CPROVER_PREFIX "array_set") { - do_array_equal(lhs, function, arguments, dest); + do_array_op(ID_array_set, lhs, function, arguments, dest); } - else if(identifier==CPROVER_PREFIX "array_copy" || - identifier=="__CPROVER::array_equal") + else if(identifier==CPROVER_PREFIX "array_copy") { - do_array_copy(lhs, function, arguments, dest); + do_array_op(ID_array_copy, lhs, function, arguments, dest); + } + else if(identifier==CPROVER_PREFIX "array_replace") + { + do_array_op(ID_array_replace, lhs, function, arguments, dest); } else if(identifier=="printf") /* @@ -1545,8 +1306,18 @@ void goto_convertt::do_function_call_symbol( throw 0; } - const irep_idt description= - "assertion "+id2string(get_string_constant(arguments[3])); + irep_idt description; + try + { + description="assertion "+id2string(get_string_constant(arguments[3])); + } + catch(int) + { + // we might be building newlib, where __assert_func is passed + // a pointer-typed symbol; the warning will still have been + // printed + description="assertion"; + } goto_programt::targett t=dest.add_instruction(ASSERT); t->guard=false_exprt(); @@ -1558,7 +1329,7 @@ void goto_convertt::do_function_call_symbol( } else if(identifier==CPROVER_PREFIX "fence") { - if(arguments.size()<1) + if(arguments.empty()) { error().source_location=function.find_source_location(); error() << "`" << identifier @@ -1613,8 +1384,7 @@ void goto_convertt::do_function_call_symbol( if(lhs.is_not_nil()) { - typet t=pointer_typet(); - t.subtype()=lhs.type(); + typet t=pointer_type(lhs.type()); dereference_exprt rhs(lhs.type()); rhs.op0()=typecast_exprt(list_arg, t); rhs.add_source_location()=function.source_location(); @@ -1997,6 +1767,77 @@ void goto_convertt::do_function_call_symbol( // void __sync_lock_release (type *ptr, ...) } + else if(identifier=="__builtin_isgreater" || + identifier=="__builtin_isgreater" || + identifier=="__builtin_isgreaterequal" || + identifier=="__builtin_isless" || + identifier=="__builtin_islessequal" || + identifier=="__builtin_islessgreater" || + identifier=="__builtin_isunordered") + { + // these support two double or two float arguments; we call the + // appropriate internal version + if(arguments.size()!=2 || + (arguments[0].type()!=double_type() && + arguments[0].type()!=float_type()) || + (arguments[1].type()!=double_type() && + arguments[1].type()!=float_type())) + { + error().source_location=function.find_source_location(); + error() << "`" << identifier + << "' expected to have two float/double arguments" + << eom; + throw 0; + } + + exprt::operandst new_arguments=arguments; + + bool use_double=arguments[0].type()==double_type(); + if(arguments[0].type()!=arguments[1].type()) + { + if(use_double) + new_arguments[1].make_typecast(arguments[0].type()); + else + { + new_arguments[0].make_typecast(arguments[1].type()); + use_double=true; + } + } + + code_typet f_type=to_code_type(function.type()); + f_type.remove_ellipsis(); + const typet &a_t=new_arguments[0].type(); + f_type.parameters()= + code_typet::parameterst(2, code_typet::parametert(a_t)); + + // replace __builtin_ by CPROVER_PREFIX + std::string name=CPROVER_PREFIX+id2string(identifier).substr(10); + // append d or f for double/float + name+=use_double?'d':'f'; + + symbol_exprt new_function=function; + new_function.set_identifier(name); + new_function.type()=f_type; + + code_function_callt function_call; + function_call.lhs()=lhs; + function_call.function()=new_function; + function_call.arguments()=new_arguments; + function_call.add_source_location()=function.source_location(); + + if(!symbol_table.has_symbol(name)) + { + code_typet(); + symbolt new_symbol; + new_symbol.base_name=name; + new_symbol.name=name; + new_symbol.type=f_type; + new_symbol.location=function.source_location(); + symbol_table.add(new_symbol); + } + + copy(function_call, FUNCTION_CALL, dest); + } else { do_function_call_symbol(*symbol); diff --git a/src/goto-programs/cfg.h b/src/goto-programs/cfg.h index 2fc7522a67d..2e1bd83598b 100644 --- a/src/goto-programs/cfg.h +++ b/src/goto-programs/cfg.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Control Flow Graph + #ifndef CPROVER_GOTO_PROGRAMS_CFG_H #define CPROVER_GOTO_PROGRAMS_CFG_H @@ -14,14 +17,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "goto_functions.h" -/*******************************************************************\ - - Class: cfg_baset - - Purpose: - -\*******************************************************************/ - class empty_cfg_nodet { }; @@ -36,6 +31,31 @@ struct cfg_base_nodet:public graph_nodet, public T I PC; }; +/// A multi-procedural control flow graph (CFG) whose nodes store references to +/// instructions in a GOTO program. +/// +/// An instance of cfg_baset is a directed graph whose nodes inherit from a +/// user-provided type T and store a pointer to an instruction of some +/// goto program in the field `PC`. The field `PC` of every node points to the +/// original GOTO instruction that gave rise to the node, and the field +/// cfg_baset::entry_map maps every GOTO instruction to some CFG node. +/// +/// The CFG is constructed on the operator() from either one goto_programt or +/// multiple goto_programt objects (stored in a goto_functionst). The edges of +/// the CFG are created on the method compute_edges(), and notably include: +/// +/// - Edges from location A to B if both A and B belong to the same +/// goto_programt and A can flow into B. +/// - An edge from each FUNCTION_CALL instruction and the first instruction of +/// the called function, when that function body is available and its body is +/// non-empty. +/// - For each FUNCTION_CALL instruction found, an edge between the exit point +/// of the called function and the instruction immediately after the +/// FUNCTION_CALL, when the function body is available and its body is +/// non-empty. +/// +/// Note that cfg_baset is the base class of many other subclasses and the +/// specific edges constructed by operator() can be different in those. template @@ -136,14 +156,6 @@ class cfg_baset:public grapht< cfg_base_nodet > bool nodes_empty(P &program) const { return program.instructions.empty(); } }; -/*******************************************************************\ - - Class: concurrent_cfg_baset - - Purpose: - -\*******************************************************************/ - template @@ -157,14 +169,6 @@ class concurrent_cfg_baset:public virtual cfg_baset typename cfg_baset::entryt &entry); }; -/*******************************************************************\ - - Class: procedure_local_cfg_baset - - Purpose: - -\*******************************************************************/ - template @@ -179,14 +183,6 @@ class procedure_local_cfg_baset:public virtual cfg_baset typename cfg_baset::entryt &entry); }; -/*******************************************************************\ - - Class: procedure_local_concurrent_cfg_baset - - Purpose: - -\*******************************************************************/ - template @@ -196,18 +192,6 @@ class procedure_local_concurrent_cfg_baset: { }; -/*******************************************************************\ - -Function: cfg_baset::compute_edges_goto - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void cfg_baset::compute_edges_goto( const goto_programt &goto_program, @@ -224,18 +208,6 @@ void cfg_baset::compute_edges_goto( this->add_edge(entry, entry_map[t]); } -/*******************************************************************\ - -Function: cfg_baset::compute_edges_catch - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void cfg_baset::compute_edges_catch( const goto_programt &goto_program, @@ -254,18 +226,6 @@ void cfg_baset::compute_edges_catch( this->add_edge(entry, entry_map[t]); } -/*******************************************************************\ - -Function: cfg_baset::compute_edges_throw - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void cfg_baset::compute_edges_throw( const goto_programt &goto_program, @@ -276,18 +236,6 @@ void cfg_baset::compute_edges_throw( // no (trivial) successors } -/*******************************************************************\ - -Function: cfg_baset::compute_edges_start_thread - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void cfg_baset::compute_edges_start_thread( const goto_programt &goto_program, @@ -299,18 +247,6 @@ void cfg_baset::compute_edges_start_thread( this->add_edge(entry, entry_map[next_PC]); } -/*******************************************************************\ - -Function: concurrent_cfg_baset::compute_edges_start_thread - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void concurrent_cfg_baset::compute_edges_start_thread( const goto_programt &goto_program, @@ -329,18 +265,6 @@ void concurrent_cfg_baset::compute_edges_start_thread( this->add_edge(entry, this->entry_map[t]); } -/*******************************************************************\ - -Function: cfg_baset::compute_edges_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void cfg_baset::compute_edges_function_call( const goto_functionst &goto_functions, @@ -392,18 +316,6 @@ void cfg_baset::compute_edges_function_call( this->add_edge(entry, entry_map[next_PC]); } -/*******************************************************************\ - -Function: procedure_local_cfg_baset::compute_edges_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void procedure_local_cfg_baset::compute_edges_function_call( const goto_functionst &goto_functions, @@ -422,18 +334,6 @@ void procedure_local_cfg_baset::compute_edges_function_call( this->add_edge(entry, this->entry_map[next_PC]); } -/*******************************************************************\ - -Function: cfg_baset::compute_edges - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void cfg_baset::compute_edges( const goto_functionst &goto_functions, @@ -508,18 +408,6 @@ void cfg_baset::compute_edges( } } -/*******************************************************************\ - -Function: cfg_baset::compute_edges - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void cfg_baset::compute_edges( const goto_functionst &goto_functions, @@ -531,18 +419,6 @@ void cfg_baset::compute_edges( compute_edges(goto_functions, goto_program, it); } -/*******************************************************************\ - -Function: cfg_baset::compute_edges - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void cfg_baset::compute_edges( const goto_functionst &goto_functions) diff --git a/src/goto-programs/class_hierarchy.cpp b/src/goto-programs/class_hierarchy.cpp index 14e8cdadee9..0ef3ae5a21e 100644 --- a/src/goto-programs/class_hierarchy.cpp +++ b/src/goto-programs/class_hierarchy.cpp @@ -8,25 +8,20 @@ Date: April 2016 \*******************************************************************/ -#include - -#include -#include +/// \file +/// Class Hierarchy #include "class_hierarchy.h" -/*******************************************************************\ - -Function: class_hierarchyt::operator() - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include +#include +/// Looks for all the struct types in the symbol table and construct a map from +/// class names to a data structure that contains lists of parent and child +/// classes for each struct type (ie class). +/// \param symbol_table: The symbol table to analyze void class_hierarchyt::operator()(const symbol_tablet &symbol_table) { forall_symbols(it, symbol_table.symbols) @@ -52,18 +47,6 @@ void class_hierarchyt::operator()(const symbol_tablet &symbol_table) } } -/*******************************************************************\ - -Function: class_hierarchyt::get_children_trans_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void class_hierarchyt::get_children_trans_rec( const irep_idt &c, idst &dest) const @@ -81,18 +64,6 @@ void class_hierarchyt::get_children_trans_rec( get_children_trans_rec(child, dest); } -/*******************************************************************\ - -Function: class_hierarchyt::get_parents_trans_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void class_hierarchyt::get_parents_trans_rec( const irep_idt &c, idst &dest) const @@ -110,18 +81,6 @@ void class_hierarchyt::get_parents_trans_rec( get_parents_trans_rec(child, dest); } -/*******************************************************************\ - -Function: class_hierarchyt::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void class_hierarchyt::output(std::ostream &out) const { for(const auto &c : class_map) @@ -136,18 +95,6 @@ void class_hierarchyt::output(std::ostream &out) const } } -/*******************************************************************\ - -Function: output_dot - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::ostream &output_dot(std::ostream &ostr, const class_hierarchyt &hierarchy) { ostr << "digraph call_graph {\n" diff --git a/src/goto-programs/class_hierarchy.h b/src/goto-programs/class_hierarchy.h index d124c66e558..3ce43ba4038 100644 --- a/src/goto-programs/class_hierarchy.h +++ b/src/goto-programs/class_hierarchy.h @@ -8,6 +8,9 @@ Date: April 2016 \*******************************************************************/ +/// \file +/// Class Hierarchy + #ifndef CPROVER_GOTO_PROGRAMS_CLASS_HIERARCHY_H #define CPROVER_GOTO_PROGRAMS_CLASS_HIERARCHY_H diff --git a/src/goto-programs/class_identifier.cpp b/src/goto-programs/class_identifier.cpp index 6e814174e51..3e92586e759 100644 --- a/src/goto-programs/class_identifier.cpp +++ b/src/goto-programs/class_identifier.cpp @@ -6,24 +6,18 @@ Author: Chris Smowton, chris.smowton@diffblue.com \*******************************************************************/ +/// \file +/// Extract class identifier + #include "class_identifier.h" #include +#include #include -/*******************************************************************\ - -Function: build_class_identifier - - Inputs: Struct expression - - Outputs: Member expression giving the clsid field of the input, - or its parent, grandparent, etc. - - Purpose: - -\*******************************************************************/ - +/// \par parameters: Struct expression +/// \return Member expression giving the clsid field of the input, or its +/// parent, grandparent, etc. static exprt build_class_identifier( const exprt &src, const namespacet &ns) @@ -56,19 +50,9 @@ static exprt build_class_identifier( } } -/*******************************************************************\ - -Function: get_class_identifier_field - - Inputs: Pointer expression of any pointer type, including void*, - and a recommended access type if the pointer is void-typed. - - Outputs: Member expression to access a class identifier, as above. - - Purpose: - -\*******************************************************************/ - +/// \par parameters: Pointer expression of any pointer type, including void*, +/// and a recommended access type if the pointer is void-typed. +/// \return Member expression to access a class identifier, as above. exprt get_class_identifier_field( const exprt &this_expr_in, const symbol_typet &suggested_type, @@ -83,7 +67,7 @@ exprt get_class_identifier_field( "Non-pointer this-arg in remove-virtuals?"); const auto &points_to=this_expr.type().subtype(); if(points_to==empty_typet()) - this_expr=typecast_exprt(this_expr, pointer_typet(suggested_type)); + this_expr=typecast_exprt(this_expr, pointer_type(suggested_type)); exprt deref=dereference_exprt(this_expr, this_expr.type().subtype()); return build_class_identifier(deref, ns); } diff --git a/src/goto-programs/class_identifier.h b/src/goto-programs/class_identifier.h index 8ae6dc4ce71..ccc679b8e1f 100644 --- a/src/goto-programs/class_identifier.h +++ b/src/goto-programs/class_identifier.h @@ -6,6 +6,9 @@ Author: Chris Smowton, chris.smowton@diffblue.com \*******************************************************************/ +/// \file +/// Extract class identifier + #ifndef CPROVER_GOTO_PROGRAMS_CLASS_IDENTIFIER_H #define CPROVER_GOTO_PROGRAMS_CLASS_IDENTIFIER_H diff --git a/src/goto-programs/compute_called_functions.cpp b/src/goto-programs/compute_called_functions.cpp index 0c1acc08d22..36e2b7a1a8b 100644 --- a/src/goto-programs/compute_called_functions.cpp +++ b/src/goto-programs/compute_called_functions.cpp @@ -6,22 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Query Called Functions #include "compute_called_functions.h" -/*******************************************************************\ - -Function: compute_address_taken_functions - - Inputs: - - Outputs: - - Purpose: get all functions whose address is taken - -\*******************************************************************/ +#include +/// get all functions whose address is taken void compute_address_taken_functions( const exprt &src, std::set &address_taken) @@ -40,18 +32,7 @@ void compute_address_taken_functions( } } -/*******************************************************************\ - -Function: compute_functions - - Inputs: - - Outputs: - - Purpose: get all functions in the expression - -\*******************************************************************/ - +/// get all functions in the expression void compute_functions( const exprt &src, std::set &address_taken) @@ -64,18 +45,7 @@ void compute_functions( address_taken.insert(to_symbol_expr(src).get_identifier()); } -/*******************************************************************\ - -Function: compute_address_taken_functions - - Inputs: - - Outputs: - - Purpose: get all functions whose address is taken - -\*******************************************************************/ - +/// get all functions whose address is taken void compute_address_taken_functions( const goto_programt &goto_program, std::set &address_taken) @@ -87,18 +57,7 @@ void compute_address_taken_functions( } } -/*******************************************************************\ - -Function: compute_address_taken_functions - - Inputs: - - Outputs: - - Purpose: get all functions whose address is taken - -\*******************************************************************/ - +/// get all functions whose address is taken void compute_address_taken_functions( const goto_functionst &goto_functions, std::set &address_taken) @@ -107,18 +66,7 @@ void compute_address_taken_functions( compute_address_taken_functions(it->second.body, address_taken); } -/*******************************************************************\ - -Function: compute_called_functions - - Inputs: - - Outputs: - - Purpose: computes the functions that are (potentially) called - -\*******************************************************************/ - +/// computes the functions that are (potentially) called void compute_called_functions( const goto_functionst &goto_functions, std::set &functions) @@ -163,18 +111,7 @@ void compute_called_functions( } } -/*******************************************************************\ - -Function: compute_called_functions - - Inputs: - - Outputs: - - Purpose: computes the functions that are (potentially) called - -\*******************************************************************/ - +/// computes the functions that are (potentially) called void compute_called_functions( const goto_modelt &goto_model, std::set &functions) diff --git a/src/goto-programs/compute_called_functions.h b/src/goto-programs/compute_called_functions.h index 40dba2b894e..6f92b420b37 100644 --- a/src/goto-programs/compute_called_functions.h +++ b/src/goto-programs/compute_called_functions.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Query Called Functions + #ifndef CPROVER_GOTO_PROGRAMS_COMPUTE_CALLED_FUNCTIONS_H #define CPROVER_GOTO_PROGRAMS_COMPUTE_CALLED_FUNCTIONS_H diff --git a/src/goto-programs/destructor.cpp b/src/goto-programs/destructor.cpp index ba1fe127a5f..3efdd50c5bf 100644 --- a/src/goto-programs/destructor.cpp +++ b/src/goto-programs/destructor.cpp @@ -6,22 +6,13 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include -#include +/// \file +/// Destructor Calls #include "destructor.h" -/*******************************************************************\ - -Function: get_destructor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include code_function_callt get_destructor( const namespacet &ns, diff --git a/src/goto-programs/destructor.h b/src/goto-programs/destructor.h index 2ea310361f3..737ada1d93a 100644 --- a/src/goto-programs/destructor.h +++ b/src/goto-programs/destructor.h @@ -6,13 +6,16 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Destructor Calls + #ifndef CPROVER_GOTO_PROGRAMS_DESTRUCTOR_H #define CPROVER_GOTO_PROGRAMS_DESTRUCTOR_H #include #include -code_function_callt get_destructor( +class code_function_callt get_destructor( const namespacet &ns, const typet &type); diff --git a/src/goto-programs/elf_reader.cpp b/src/goto-programs/elf_reader.cpp index 9a2212bfbfc..39bc20de7c6 100644 --- a/src/goto-programs/elf_reader.cpp +++ b/src/goto-programs/elf_reader.cpp @@ -6,21 +6,12 @@ Module: Read ELF \*******************************************************************/ -#include +/// \file +/// Read ELF #include "elf_reader.h" -/*******************************************************************\ - -Function: elf_readert::elf_readert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include elf_readert::elf_readert(std::istream &_in):in(_in) { @@ -130,18 +121,6 @@ elf_readert::elf_readert(std::istream &_in):in(_in) } } -/*******************************************************************\ - -Function: elf_readert::get_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string elf_readert::get_string(std::streampos index) const { in.seekg(string_table_offset+index); @@ -160,18 +139,6 @@ std::string elf_readert::get_string(std::streampos index) const return result; } -/*******************************************************************\ - -Function: elf_readert::has_section - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool elf_readert::has_section(const std::string &name) const { for(unsigned i=0; i -#include - -#include - -#include +/// \file +/// Format String Parser #include "format_strings.h" -/*******************************************************************\ - -Function: parse_flags - - Inputs: - - Outputs: +#include +#include - Purpose: +#include -\*******************************************************************/ +#include void parse_flags( std::string::const_iterator &it, @@ -36,36 +27,29 @@ void parse_flags( { switch(*it) { - case '#': curtok.flags.push_back(format_tokent::ALTERNATE); break; - case '0': curtok.flags.push_back(format_tokent::ZERO_PAD); break; - case '-': curtok.flags.push_back(format_tokent::LEFT_ADJUST); break; - case ' ': curtok.flags.push_back(format_tokent::SIGNED_SPACE); break; - case '+': curtok.flags.push_back(format_tokent::SIGN); break; + case '#': + curtok.flags.push_back(format_tokent::flag_typet::ALTERNATE); break; + case '0': + curtok.flags.push_back(format_tokent::flag_typet::ZERO_PAD); break; + case '-': + curtok.flags.push_back(format_tokent::flag_typet::LEFT_ADJUST); break; + case ' ': + curtok.flags.push_back(format_tokent::flag_typet::SIGNED_SPACE); break; + case '+': + curtok.flags.push_back(format_tokent::flag_typet::SIGN); break; default: throw 0; } it++; } } -/*******************************************************************\ - -Function: parse_field_width - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void parse_field_width( std::string::const_iterator &it, format_tokent &curtok) { if(*it=='*') { - curtok.flags.push_back(format_tokent::ASTERISK); + curtok.flags.push_back(format_tokent::flag_typet::ASTERISK); it++; } @@ -74,18 +58,6 @@ void parse_field_width( curtok.field_width=string2integer(tmp); } -/*******************************************************************\ - -Function: parse_precision - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void parse_precision( std::string::const_iterator &it, format_tokent &curtok) @@ -96,7 +68,7 @@ void parse_precision( if(*it=='*') { - curtok.flags.push_back(format_tokent::ASTERISK); + curtok.flags.push_back(format_tokent::flag_typet::ASTERISK); it++; } else @@ -108,18 +80,6 @@ void parse_precision( } } -/*******************************************************************\ - -Function: parse_length_modifier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void parse_length_modifier( std::string::const_iterator &it, format_tokent &curtok) @@ -129,44 +89,32 @@ void parse_length_modifier( it++; if(*it=='h') it++; - curtok.length_modifier = format_tokent::LEN_h; + curtok.length_modifier = format_tokent::length_modifierst::LEN_h; } else if(*it=='l') { it++; if(*it=='l') it++; - curtok.length_modifier = format_tokent::LEN_l; + curtok.length_modifier = format_tokent::length_modifierst::LEN_l; } else if(*it=='L') { it++; - curtok.length_modifier = format_tokent::LEN_L; + curtok.length_modifier = format_tokent::length_modifierst::LEN_L; } else if(*it=='j') { it++; - curtok.length_modifier = format_tokent::LEN_j; + curtok.length_modifier = format_tokent::length_modifierst::LEN_j; } else if(*it=='t') { it++; - curtok.length_modifier = format_tokent::LEN_L; + curtok.length_modifier = format_tokent::length_modifierst::LEN_L; } } -/*******************************************************************\ - -Function: parse_conversion_specifier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void parse_conversion_specifier( const std::string &arg_string, std::string::const_iterator &it, @@ -176,34 +124,37 @@ void parse_conversion_specifier( { case 'd': case 'i': - curtok.type=format_tokent::INT; - curtok.representation=format_tokent::SIGNED_DEC; + curtok.type=format_tokent::token_typet::INT; + curtok.representation=format_tokent::representationt::SIGNED_DEC; break; case 'o': - curtok.type=format_tokent::INT; - curtok.representation=format_tokent::UNSIGNED_OCT; + curtok.type=format_tokent::token_typet::INT; + curtok.representation=format_tokent::representationt::UNSIGNED_OCT; break; case 'u': - curtok.type=format_tokent::INT; - curtok.representation=format_tokent::UNSIGNED_DEC; + curtok.type=format_tokent::token_typet::INT; + curtok.representation=format_tokent::representationt::UNSIGNED_DEC; break; case 'x': case 'X': - curtok.type=format_tokent::INT; - curtok.representation=format_tokent::UNSIGNED_HEX; + curtok.type=format_tokent::token_typet::INT; + curtok.representation=format_tokent::representationt::UNSIGNED_HEX; break; case 'e': - case 'E': curtok.type=format_tokent::FLOAT; break; + case 'E': curtok.type=format_tokent::token_typet::FLOAT; break; case 'f': - case 'F': curtok.type=format_tokent::FLOAT; break; + case 'F': curtok.type=format_tokent::token_typet::FLOAT; break; case 'g': - case 'G': curtok.type=format_tokent::FLOAT; break; + case 'G': curtok.type=format_tokent::token_typet::FLOAT; break; case 'a': - case 'A': curtok.type=format_tokent::FLOAT; break; - case 'c': curtok.type=format_tokent::CHAR; break; - case 's': curtok.type=format_tokent::STRING; break; - case 'p': curtok.type=format_tokent::POINTER; break; - case '%': curtok.type=format_tokent::TEXT; curtok.value="%"; break; + case 'A': curtok.type=format_tokent::token_typet::FLOAT; break; + case 'c': curtok.type=format_tokent::token_typet::CHAR; break; + case 's': curtok.type=format_tokent::token_typet::STRING; break; + case 'p': curtok.type=format_tokent::token_typet::POINTER; break; + case '%': + curtok.type=format_tokent::token_typet::TEXT; + curtok.value="%"; + break; case '[': // pattern matching in, e.g., fscanf. { std::string tmp; @@ -229,18 +180,6 @@ void parse_conversion_specifier( it++; } -/*******************************************************************\ - -Function: parse_format_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - format_token_listt parse_format_string(const std::string &arg_string) { format_token_listt token_list; @@ -264,8 +203,8 @@ format_token_listt parse_format_string(const std::string &arg_string) else { if(token_list.empty() || - token_list.back().type!=format_tokent::TEXT) - token_list.push_back(format_tokent(format_tokent::TEXT)); + token_list.back().type!=format_tokent::token_typet::TEXT) + token_list.push_back(format_tokent(format_tokent::token_typet::TEXT)); std::string tmp; for( ; it!=arg_string.end() && *it!='%'; it++) @@ -279,78 +218,67 @@ format_token_listt parse_format_string(const std::string &arg_string) return token_list; } -/*******************************************************************\ - -Function: get_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet get_type(const format_tokent &token) { switch(token.type) { - case format_tokent::INT: + case format_tokent::token_typet::INT: switch(token.length_modifier) { - case format_tokent::LEN_h: - if(token.representation==format_tokent::SIGNED_DEC) + case format_tokent::length_modifierst::LEN_h: + if(token.representation==format_tokent::representationt::SIGNED_DEC) return signed_char_type(); else return unsigned_char_type(); - case format_tokent::LEN_hh: - if(token.representation==format_tokent::SIGNED_DEC) + case format_tokent::length_modifierst::LEN_hh: + if(token.representation==format_tokent::representationt::SIGNED_DEC) return signed_short_int_type(); else return unsigned_short_int_type(); - case format_tokent::LEN_l: - if(token.representation==format_tokent::SIGNED_DEC) + case format_tokent::length_modifierst::LEN_l: + if(token.representation==format_tokent::representationt::SIGNED_DEC) return signed_long_int_type(); else return unsigned_long_int_type(); - case format_tokent::LEN_ll: - if(token.representation==format_tokent::SIGNED_DEC) + case format_tokent::length_modifierst::LEN_ll: + if(token.representation==format_tokent::representationt::SIGNED_DEC) return signed_long_long_int_type(); else return unsigned_long_long_int_type(); default: - if(token.representation==format_tokent::SIGNED_DEC) + if(token.representation==format_tokent::representationt::SIGNED_DEC) return signed_int_type(); else return unsigned_int_type(); } - case format_tokent::FLOAT: + case format_tokent::token_typet::FLOAT: switch(token.length_modifier) { - case format_tokent::LEN_l: return double_type(); - case format_tokent::LEN_L: return long_double_type(); + case format_tokent::length_modifierst::LEN_l: return double_type(); + case format_tokent::length_modifierst::LEN_L: return long_double_type(); default: return float_type(); } - case format_tokent::CHAR: + case format_tokent::token_typet::CHAR: switch(token.length_modifier) { - case format_tokent::LEN_l: return wchar_t_type(); + case format_tokent::length_modifierst::LEN_l: return wchar_t_type(); default: return char_type(); } - case format_tokent::POINTER: + case format_tokent::token_typet::POINTER: return pointer_type(void_type()); - case format_tokent::STRING: + case format_tokent::token_typet::STRING: switch(token.length_modifier) { - case format_tokent::LEN_l: return array_typet(wchar_t_type(), nil_exprt()); + case format_tokent::length_modifierst::LEN_l: + return array_typet(wchar_t_type(), nil_exprt()); default: return array_typet(char_type(), nil_exprt()); } diff --git a/src/goto-programs/format_strings.h b/src/goto-programs/format_strings.h index 4959d51123e..8c233324ecf 100644 --- a/src/goto-programs/format_strings.h +++ b/src/goto-programs/format_strings.h @@ -6,6 +6,9 @@ Author: CM Wintersteiger \*******************************************************************/ +/// \file +/// Format String Parser + #ifndef CPROVER_GOTO_PROGRAMS_FORMAT_STRINGS_H #define CPROVER_GOTO_PROGRAMS_FORMAT_STRINGS_H @@ -18,39 +21,57 @@ Author: CM Wintersteiger class format_tokent { public: - typedef enum { UNKNOWN, - TEXT, - INT, // d, i, o, u, x - FLOAT, // a, e, f, g - CHAR, // c - STRING, // s - POINTER // p - } token_typet; - - typedef enum { ALTERNATE, ZERO_PAD, LEFT_ADJUST, - SIGNED_SPACE, SIGN, ASTERISK } flag_typet; - - typedef enum + enum class token_typet { - LEN_undef, LEN_h, LEN_hh, LEN_l, LEN_ll, - LEN_L, LEN_j, LEN_t - } length_modifierst; - - typedef enum + UNKNOWN, + TEXT, + INT, // d, i, o, u, x + FLOAT, // a, e, f, g + CHAR, // c + STRING, // s + POINTER // p + }; + + enum class flag_typet + { + ALTERNATE, + ZERO_PAD, + LEFT_ADJUST, + SIGNED_SPACE, + SIGN, + ASTERISK + }; + + enum class length_modifierst + { + LEN_undef, + LEN_h, + LEN_hh, + LEN_l, + LEN_ll, + LEN_L, + LEN_j, + LEN_t + }; + + enum class representationt { - SIGNED_undef, SIGNED_DEC, UNSIGNED_DEC, - UNSIGNED_OCT, UNSIGNED_HEX - } representationt; + SIGNED_undef, + SIGNED_DEC, + UNSIGNED_DEC, + UNSIGNED_OCT, + UNSIGNED_HEX + }; explicit format_tokent(token_typet _type) : type(_type), - length_modifier(LEN_undef), - representation(SIGNED_undef) + length_modifier(length_modifierst::LEN_undef), + representation(representationt::SIGNED_undef) { } format_tokent(): - type(UNKNOWN), - length_modifier(LEN_undef), - representation(SIGNED_undef) + type(token_typet::UNKNOWN), + length_modifier(length_modifierst::LEN_undef), + representation(representationt::SIGNED_undef) { } diff --git a/src/goto-programs/goto_asm.cpp b/src/goto-programs/goto_asm.cpp index 782d601a29e..63492b5d9ce 100644 --- a/src/goto-programs/goto_asm.cpp +++ b/src/goto-programs/goto_asm.cpp @@ -6,19 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "goto_convert_class.h" - -/*******************************************************************\ - -Function: goto_convertt::convert_asm - - Inputs: +/// \file +/// Assembler -> Goto - Outputs: - - Purpose: - -\*******************************************************************/ +#include "goto_convert_class.h" void goto_convertt::convert_asm( const code_asmt &code, diff --git a/src/goto-programs/goto_clean_expr.cpp b/src/goto-programs/goto_clean_expr.cpp index c7fa8637194..ad5fea6ac5f 100644 --- a/src/goto-programs/goto_clean_expr.cpp +++ b/src/goto-programs/goto_clean_expr.cpp @@ -6,27 +6,18 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Program Transformation + +#include "goto_convert_class.h" + #include #include #include #include #include -#include - -#include "goto_convert_class.h" - -/*******************************************************************\ - -Function: goto_convertt::make_compound_literal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include symbol_exprt goto_convertt::make_compound_literal( const exprt &expr, @@ -69,18 +60,6 @@ symbol_exprt goto_convertt::make_compound_literal( return result; } -/*******************************************************************\ - -Function: goto_convertt::needs_cleaning - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool goto_convertt::needs_cleaning(const exprt &expr) { if(expr.id()==ID_dereference || @@ -125,18 +104,7 @@ bool goto_convertt::needs_cleaning(const exprt &expr) return false; } -/*******************************************************************\ - -Function: goto_convertt::rewrite_boolean - - Inputs: - - Outputs: - - Purpose: re-write boolean operators into ?: - -\*******************************************************************/ - +/// re-write boolean operators into ?: void goto_convertt::rewrite_boolean(exprt &expr) { assert(expr.id()==ID_and || expr.id()==ID_or); @@ -192,18 +160,6 @@ void goto_convertt::rewrite_boolean(exprt &expr) expr.swap(tmp); } -/*******************************************************************\ - -Function: goto_convertt::clean_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::clean_expr( exprt &expr, goto_programt &dest, @@ -481,18 +437,6 @@ void goto_convertt::clean_expr( } } -/*******************************************************************\ - -Function: goto_convertt::clean_expr_address_of - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::clean_expr_address_of( exprt &expr, goto_programt &dest) @@ -556,18 +500,6 @@ void goto_convertt::clean_expr_address_of( clean_expr_address_of(*it, dest); } -/*******************************************************************\ - -Function: goto_convertt::remove_gcc_conditional_expression - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::remove_gcc_conditional_expression( exprt &expr, goto_programt &dest) diff --git a/src/goto-programs/goto_convert.cpp b/src/goto-programs/goto_convert.cpp index 25118d0b223..e2238e377d4 100644 --- a/src/goto-programs/goto_convert.cpp +++ b/src/goto-programs/goto_convert.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Program Transformation + +#include "goto_convert.h" + #include #include @@ -17,24 +22,11 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include +#include -#include "goto_convert.h" #include "goto_convert_class.h" #include "destructor.h" -/*******************************************************************\ - -Function: is_empty - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static bool is_empty(const goto_programt &goto_program) { forall_goto_program_instructions(it, goto_program) @@ -46,19 +38,8 @@ static bool is_empty(const goto_programt &goto_program) return true; } -/*******************************************************************\ - -Function: finish_catch_push_targets - - Inputs: - - Outputs: - - Purpose: Populate the CATCH instructions with the targets - corresponding to their associated labels - -\*******************************************************************/ - +/// Populate the CATCH instructions with the targets corresponding to their +/// associated labels static void finish_catch_push_targets(goto_programt &dest) { std::map label_targets; @@ -215,17 +196,19 @@ void goto_convertt::finish_gotos(goto_programt &dest) if(!stack_is_prefix) { - warning() << "Encountered goto (" << goto_label << - ") that enters one or more lexical blocks;" << - "omitting constructors and destructors." << eom; + debug().source_location=i.code.find_source_location(); + debug() << "encountered goto `" << goto_label + << "' that enters one or more lexical blocks; " + << "omitting constructors and destructors" << eom; } else { auto unwind_to_size=label_stack.size(); if(unwind_to_sizeguard=gg.guard; // goto_programt doesn't provide an erase operation, // perhaps for a good reason, so let's be cautious and just - // flatten the un-needed instructions into skips. + // flatten the unneeded instructions into skips. for(auto it=gg.ifiter, itend=gg.gotoiter; it!=itend; ++it) it->make_skip(); } } -/*******************************************************************\ - -Function: goto_convertt::goto_convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::goto_convert(const codet &code, goto_programt &dest) { goto_convert_rec(code, dest); } -/*******************************************************************\ - -Function: goto_convertt::goto_convert_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::goto_convert_rec( const codet &code, goto_programt &dest) @@ -385,18 +320,6 @@ void goto_convertt::goto_convert_rec( finish_catch_push_targets(dest); } -/*******************************************************************\ - -Function: goto_convertt::copy - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::copy( const codet &code, goto_program_instruction_typet type, @@ -407,18 +330,6 @@ void goto_convertt::copy( t->source_location=code.source_location(); } -/*******************************************************************\ - -Function: goto_convert::convert_label - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_label( const code_labelt &code, goto_programt &dest) @@ -454,18 +365,6 @@ void goto_convertt::convert_label( target->labels.push_front(label); } -/*******************************************************************\ - -Function: goto_convert::convert_gcc_local_label - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_gcc_local_label( const codet &code, goto_programt &dest) @@ -473,37 +372,17 @@ void goto_convertt::convert_gcc_local_label( // ignore for now } -/*******************************************************************\ - -Function: goto_convert::convert_switch_case - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_switch_case( const code_switch_caset &code, goto_programt &dest) { - if(code.operands().size()!=2) - { - error().source_location=code.find_source_location(); - error() << "switch-case statement expected to have two operands" - << eom; - throw 0; - } - goto_programt tmp; convert(code.code(), tmp); goto_programt::targett target=tmp.instructions.begin(); dest.destructive_append(tmp); - // default? + // is a default target given? if(code.is_default()) targets.set_default(target); @@ -524,18 +403,6 @@ void goto_convertt::convert_switch_case( } } -/*******************************************************************\ - -Function: goto_convert::convert_gcc_switch_case_range - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_gcc_switch_case_range( const codet &code, goto_programt &dest) @@ -569,18 +436,7 @@ void goto_convertt::convert_gcc_switch_case_range( #endif } -/*******************************************************************\ - -Function: goto_convertt::convert - - Inputs: - - Outputs: - - Purpose: converts 'code' and appends the result to 'dest' - -\*******************************************************************/ - +/// converts 'code' and appends the result to 'dest' void goto_convertt::convert( const codet &code, goto_programt &dest) @@ -714,18 +570,6 @@ void goto_convertt::convert( } } -/*******************************************************************\ - -Function: goto_convertt::convert_block - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_block( const code_blockt &code, goto_programt &dest) @@ -757,18 +601,6 @@ void goto_convertt::convert_block( targets.destructor_stack.resize(old_stack_size); } -/*******************************************************************\ - -Function: goto_convertt::convert_expression - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_expression( const code_expressiont &code, goto_programt &dest) @@ -812,18 +644,6 @@ void goto_convertt::convert_expression( } } -/*******************************************************************\ - -Function: goto_convertt::convert_decl - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_decl( const code_declt &code, goto_programt &dest) @@ -884,27 +704,13 @@ void goto_convertt::convert_decl( if(destructor.is_not_nil()) { // add "this" - exprt this_expr(ID_address_of, pointer_typet()); - this_expr.type().subtype()=symbol.type; - this_expr.copy_to_operands(symbol_expr); + address_of_exprt this_expr(symbol_expr, pointer_type(symbol.type)); destructor.arguments().push_back(this_expr); targets.destructor_stack.push_back(destructor); } } -/*******************************************************************\ - -Function: goto_convertt::convert_decl_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_decl_type( const codet &code, goto_programt &dest) @@ -912,18 +718,6 @@ void goto_convertt::convert_decl_type( // we remove these } -/*******************************************************************\ - -Function: goto_convertt::convert_assign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_assign( const code_assignt &code, goto_programt &dest) @@ -1011,18 +805,6 @@ void goto_convertt::convert_assign( } } -/*******************************************************************\ - -Function: goto_convertt::convert_init - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_init( const codet &code, goto_programt &dest) @@ -1041,18 +823,6 @@ void goto_convertt::convert_init( convert(to_code_assign(assignment), dest); } -/*******************************************************************\ - -Function: goto_convertt::convert_cpp_delete - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_cpp_delete( const codet &code, goto_programt &dest) @@ -1118,18 +888,6 @@ void goto_convertt::convert_cpp_delete( convert(delete_call, dest); } -/*******************************************************************\ - -Function: goto_convertt::convert_assert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_assert( const code_assertt &code, goto_programt &dest) @@ -1145,18 +903,6 @@ void goto_convertt::convert_assert( t->source_location.set("user-provided", true); } -/*******************************************************************\ - -Function: goto_convertt::convert_skip - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_skip( const codet &code, goto_programt &dest) @@ -1166,18 +912,6 @@ void goto_convertt::convert_skip( t->code=code; } -/*******************************************************************\ - -Function: goto_convertt::convert_assume - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_assume( const code_assumet &code, goto_programt &dest) @@ -1191,24 +925,12 @@ void goto_convertt::convert_assume( t->source_location=code.source_location(); } -/*******************************************************************\ - -Function: goto_convertt::convert_loop_invariant - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_loop_invariant( - const codet &code, - goto_programt::targett loop) -{ - exprt invariant= - static_cast(code.find(ID_C_spec_loop_invariant)); +void goto_convertt::convert_loop_invariant( + const codet &code, + goto_programt::targett loop) +{ + exprt invariant= + static_cast(code.find(ID_C_spec_loop_invariant)); if(invariant.is_nil()) return; @@ -1226,18 +948,6 @@ void goto_convertt::convert_loop_invariant( loop->guard.add(ID_C_spec_loop_invariant).swap(invariant); } -/*******************************************************************\ - -Function: goto_convertt::convert_for - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_for( const code_fort &code, goto_programt &dest) @@ -1337,18 +1047,6 @@ void goto_convertt::convert_for( old_targets.restore(targets); } -/*******************************************************************\ - -Function: goto_convertt::convert_while - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_while( const code_whilet &code, goto_programt &dest) @@ -1409,18 +1107,6 @@ void goto_convertt::convert_while( old_targets.restore(targets); } -/*******************************************************************\ - -Function: goto_convertt::convert_dowhile - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_dowhile( const codet &code, goto_programt &dest) @@ -1493,18 +1179,6 @@ void goto_convertt::convert_dowhile( old_targets.restore(targets); } -/*******************************************************************\ - -Function: goto_convertt::case_guard - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt goto_convertt::case_guard( const exprt &value, const exprt::operandst &case_op) @@ -1532,18 +1206,6 @@ exprt goto_convertt::case_guard( return dest; } -/*******************************************************************\ - -Function: goto_convertt::convert_switch - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_switch( const code_switcht &code, goto_programt &dest) @@ -1555,6 +1217,7 @@ void goto_convertt::convert_switch( // default: Pd; // } // -------------------- + // location // x: if(v==x) goto X; // y: if(v==y) goto Y; // goto d; @@ -1563,13 +1226,19 @@ void goto_convertt::convert_switch( // d: Pd; // z: ; - if(code.operands().size()<2) - { - error().source_location=code.find_source_location(); - error() << "switch takes at least two operands" << eom; - throw 0; - } + // we first add a 'location' node for the switch statement, + // which would otherwise not be recorded + dest.add_instruction()->make_location( + code.source_location()); + + // get the location of the end of the body, but + // default to location of switch, if none + source_locationt body_end_location= + code.body().get_statement()==ID_block? + to_code_block(code.body()).end_location(): + code.source_location(); + // do the value we switch over exprt argument=code.value(); goto_programt sideeffects; @@ -1582,7 +1251,7 @@ void goto_convertt::convert_switch( goto_programt tmp_z; goto_programt::targett z=tmp_z.add_instruction(); z->make_skip(); - z->source_location=code.source_location(); + z->source_location=body_end_location; // set the new targets -- continue stays as is targets.set_break(z); @@ -1591,10 +1260,7 @@ void goto_convertt::convert_switch( targets.cases_map.clear(); goto_programt tmp; - - forall_operands(it, code) - if(it!=code.operands().begin()) - convert(to_code(*it), tmp); + convert(code.body(), tmp); goto_programt tmp_cases; @@ -1627,18 +1293,6 @@ void goto_convertt::convert_switch( old_targets.restore(targets); } -/*******************************************************************\ - -Function: goto_convertt::convert_break - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_break( const code_breakt &code, goto_programt &dest) @@ -1660,18 +1314,6 @@ void goto_convertt::convert_break( t->source_location=code.source_location(); } -/*******************************************************************\ - -Function: goto_convertt::convert_return - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_return( const code_returnt &code, goto_programt &dest) @@ -1742,18 +1384,6 @@ void goto_convertt::convert_return( t->source_location=new_code.source_location(); } -/*******************************************************************\ - -Function: goto_convertt::convert_continue - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_continue( const code_continuet &code, goto_programt &dest) @@ -1775,18 +1405,6 @@ void goto_convertt::convert_continue( t->source_location=code.source_location(); } -/*******************************************************************\ - -Function: goto_convertt::convert_goto - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_goto( const codet &code, goto_programt &dest) @@ -1800,18 +1418,6 @@ void goto_convertt::convert_goto( targets.gotos.push_back(std::make_pair(t, targets.destructor_stack)); } -/*******************************************************************\ - -Function: goto_convertt::convert_gcc_computed_goto - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_gcc_computed_goto( const codet &code, goto_programt &dest) @@ -1825,18 +1431,6 @@ void goto_convertt::convert_gcc_computed_goto( targets.computed_gotos.push_back(t); } -/*******************************************************************\ - -Function: goto_convertt::convert_non_deterministic_goto - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_non_deterministic_goto( const codet &code, goto_programt &dest) @@ -1844,18 +1438,6 @@ void goto_convertt::convert_non_deterministic_goto( convert_goto(code, dest); } -/*******************************************************************\ - -Function: goto_convertt::convert_specc_notify - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_specc_notify( const codet &code, goto_programt &dest) @@ -1873,18 +1455,6 @@ void goto_convertt::convert_specc_notify( copy(code, OTHER, dest); } -/*******************************************************************\ - -Function: goto_convertt::convert_specc_event - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_specc_event( const exprt &op, std::set &events) @@ -1911,18 +1481,6 @@ void goto_convertt::convert_specc_event( } } -/*******************************************************************\ - -Function: goto_convertt::convert_specc_wait - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_specc_wait( const codet &code, goto_programt &dest) @@ -1951,18 +1509,6 @@ void goto_convertt::convert_specc_wait( copy(code, OTHER, dest); } -/*******************************************************************\ - -Function: goto_convertt::convert_specc_par - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_specc_par( const codet &code, goto_programt &dest) @@ -1970,18 +1516,6 @@ void goto_convertt::convert_specc_par( copy(code, OTHER, dest); } -/*******************************************************************\ - -Function: goto_convertt::convert_start_thread - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_start_thread( const codet &code, goto_programt &dest) @@ -2021,18 +1555,6 @@ void goto_convertt::convert_start_thread( } } -/*******************************************************************\ - -Function: goto_convertt::convert_end_thread - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_end_thread( const codet &code, goto_programt &dest) @@ -2047,18 +1569,6 @@ void goto_convertt::convert_end_thread( copy(code, END_THREAD, dest); } -/*******************************************************************\ - -Function: goto_convertt::convert_atomic_begin - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_atomic_begin( const codet &code, goto_programt &dest) @@ -2073,18 +1583,6 @@ void goto_convertt::convert_atomic_begin( copy(code, ATOMIC_BEGIN, dest); } -/*******************************************************************\ - -Function: goto_convertt::convert_atomic_end - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_atomic_end( const codet &code, goto_programt &dest) @@ -2099,18 +1597,6 @@ void goto_convertt::convert_atomic_end( copy(code, ATOMIC_END, dest); } -/*******************************************************************\ - -Function: goto_convertt::convert_bp_enforce - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_bp_enforce( const codet &code, goto_programt &dest) @@ -2170,18 +1656,6 @@ void goto_convertt::convert_bp_enforce( dest.destructive_append(tmp); } -/*******************************************************************\ - -Function: goto_convertt::convert_bp_abortif - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_bp_abortif( const codet &code, goto_programt &dest) @@ -2205,18 +1679,6 @@ void goto_convertt::convert_bp_abortif( t->source_location=code.source_location(); } -/*******************************************************************\ - -Function: goto_convertt::convert_ifthenelse - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_ifthenelse( const code_ifthenelset &code, goto_programt &dest) @@ -2268,18 +1730,6 @@ void goto_convertt::convert_ifthenelse( generate_ifthenelse(tmp_guard, tmp_then, tmp_else, source_location, dest); } -/*******************************************************************\ - -Function: goto_convertt::collect_operands - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::collect_operands( const exprt &expr, const irep_idt &id, @@ -2297,36 +1747,16 @@ void goto_convertt::collect_operands( } } -/*******************************************************************\ - -Function: is_size_one - - Inputs: Goto program 'g' - - Outputs: True if 'g' has one instruction - - Purpose: This is (believed to be) faster than using std::list.size - -\*******************************************************************/ - +/// This is (believed to be) faster than using std::list.size +/// \par parameters: Goto program 'g' +/// \return True if 'g' has one instruction static inline bool is_size_one(const goto_programt &g) { return (!g.instructions.empty()) && ++g.instructions.begin()==g.instructions.end(); } -/*******************************************************************\ - -Function: goto_convertt::generate_ifthenelse - - Inputs: - - Outputs: - - Purpose: if(guard) true_case; else false_case; - -\*******************************************************************/ - +/// if(guard) true_case; else false_case; void goto_convertt::generate_ifthenelse( const exprt &guard, goto_programt &true_case, @@ -2467,18 +1897,7 @@ void goto_convertt::generate_ifthenelse( dest.destructive_append(tmp_z); } -/*******************************************************************\ - -Function: goto_convertt::generate_conditional_branch - - Inputs: - - Outputs: - - Purpose: if(guard) goto target; - -\*******************************************************************/ - +/// if(guard) goto target; static bool has_and_or(const exprt &expr) { forall_operands(it, expr) @@ -2529,18 +1948,7 @@ void goto_convertt::generate_conditional_branch( } } -/*******************************************************************\ - -Function: goto_convertt::generate_conditional_branch - - Inputs: - - Outputs: - - Purpose: if(guard) goto target_true; else goto target_false; - -\*******************************************************************/ - +/// if(guard) goto target_true; else goto target_false; void goto_convertt::generate_conditional_branch( const exprt &guard, goto_programt::targett target_true, @@ -2618,18 +2026,6 @@ void goto_convertt::generate_conditional_branch( t_false->source_location=source_location; } -/*******************************************************************\ - -Function: goto_convertt::get_string_constant - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool goto_convertt::get_string_constant( const exprt &expr, irep_idt &value) @@ -2671,18 +2067,6 @@ bool goto_convertt::get_string_constant( return true; } -/*******************************************************************\ - -Function: goto_convertt::get_string_constant - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - irep_idt goto_convertt::get_string_constant(const exprt &expr) { irep_idt result; @@ -2699,18 +2083,6 @@ irep_idt goto_convertt::get_string_constant(const exprt &expr) return result; } -/*******************************************************************\ - -Function: goto_convertt::get_constant - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt goto_convertt::get_constant(const exprt &expr) { if(expr.id()==ID_symbol) @@ -2737,18 +2109,6 @@ exprt goto_convertt::get_constant(const exprt &expr) return expr; } -/*******************************************************************\ - -Function: goto_convertt::new_tmp_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - symbolt &goto_convertt::new_tmp_symbol( const typet &type, const std::string &suffix, @@ -2772,18 +2132,6 @@ symbolt &goto_convertt::new_tmp_symbol( return new_symbol; } -/*******************************************************************\ - -Function: goto_convertt::make_temp_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::make_temp_symbol( exprt &expr, const std::string &suffix, @@ -2804,18 +2152,6 @@ void goto_convertt::make_temp_symbol( expr=new_symbol.symbol_expr(); } -/*******************************************************************\ - -Function: goto_convertt::new_name - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::new_name(symbolt &symbol) { // rename it @@ -2825,18 +2161,6 @@ void goto_convertt::new_name(symbolt &symbol) symbol_table.add(symbol); } -/*******************************************************************\ - -Function: goto_convertt::lookup - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const symbolt &goto_convertt::lookup(const irep_idt &identifier) { const symbolt *symbol; @@ -2848,24 +2172,15 @@ const symbolt &goto_convertt::lookup(const irep_idt &identifier) return *symbol; } -/*******************************************************************\ - -Function: goto_convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convert( const codet &code, symbol_tablet &symbol_table, goto_programt &dest, message_handlert &message_handler) { + const unsigned errors_before= + message_handler.get_message_count(messaget::M_ERROR); + goto_convertt goto_convert(symbol_table, message_handler); try @@ -2876,33 +2191,21 @@ void goto_convert( catch(int) { goto_convert.error(); - throw 0; } catch(const char *e) { goto_convert.error() << e << messaget::eom; - throw 0; } catch(const std::string &e) { goto_convert.error() << e << messaget::eom; - throw 0; } -} - -/*******************************************************************\ - -Function: goto_convert - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ + if(message_handler.get_message_count(messaget::M_ERROR)!=errors_before) + throw 0; +} void goto_convert( symbol_tablet &symbol_table, diff --git a/src/goto-programs/goto_convert.h b/src/goto-programs/goto_convert.h index 499c24aa572..c0196486ae4 100644 --- a/src/goto-programs/goto_convert.h +++ b/src/goto-programs/goto_convert.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Program Transformation + #ifndef CPROVER_GOTO_PROGRAMS_GOTO_CONVERT_H #define CPROVER_GOTO_PROGRAMS_GOTO_CONVERT_H diff --git a/src/goto-programs/goto_convert_class.h b/src/goto-programs/goto_convert_class.h index b018810e76e..6061e369d42 100644 --- a/src/goto-programs/goto_convert_class.h +++ b/src/goto-programs/goto_convert_class.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Program Transformation + #ifndef CPROVER_GOTO_PROGRAMS_GOTO_CONVERT_CLASS_H #define CPROVER_GOTO_PROGRAMS_GOTO_CONVERT_CLASS_H @@ -314,7 +317,11 @@ class goto_convertt:public messaget continue_set(false), default_set(false), throw_set(false), - leave_set(false) + leave_set(false), + break_stack_size(0), + continue_stack_size(0), + throw_stack_size(0), + leave_stack_size(0) { } @@ -537,7 +544,8 @@ class goto_convertt:public messaget const exprt &rhs, const exprt::operandst &arguments, goto_programt &dest); - void do_array_copy( + void do_array_op( + const irep_idt &id, const exprt &lhs, const exprt &rhs, const exprt::operandst &arguments, diff --git a/src/goto-programs/goto_convert_exceptions.cpp b/src/goto-programs/goto_convert_exceptions.cpp index 63f503e8a0b..581ae2bcecd 100644 --- a/src/goto-programs/goto_convert_exceptions.cpp +++ b/src/goto-programs/goto_convert_exceptions.cpp @@ -6,21 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Program Transformation #include "goto_convert_class.h" -/*******************************************************************\ - -Function: goto_convertt::convert_msc_try_finally - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void goto_convertt::convert_msc_try_finally( const codet &code, @@ -60,18 +51,6 @@ void goto_convertt::convert_msc_try_finally( dest.destructive_append(tmp); } -/*******************************************************************\ - -Function: goto_convertt::convert_msc_try_except - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_msc_try_except( const codet &code, goto_programt &dest) @@ -88,18 +67,6 @@ void goto_convertt::convert_msc_try_except( // todo: generate exception tracking } -/*******************************************************************\ - -Function: goto_convertt::convert_msc_leave - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_msc_leave( const codet &code, goto_programt &dest) @@ -126,18 +93,6 @@ void goto_convertt::convert_msc_leave( t->source_location=code.source_location(); } -/*******************************************************************\ - -Function: goto_convertt::convert_java_try_catch - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_java_try_catch( const codet &code, goto_programt &dest) @@ -193,18 +148,6 @@ void goto_convertt::convert_java_try_catch( dest.destructive_append(end); } -/*******************************************************************\ - -Function: goto_convertt::convert_try_catch - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_try_catch( const codet &code, goto_programt &dest) @@ -258,18 +201,6 @@ void goto_convertt::convert_try_catch( dest.destructive_append(end); } -/*******************************************************************\ - -Function: goto_convertt::convert_CPROVER_try_catch - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_CPROVER_try_catch( const codet &code, goto_programt &dest) @@ -307,18 +238,6 @@ void goto_convertt::convert_CPROVER_try_catch( dest.destructive_append(tmp); } -/*******************************************************************\ - -Function: goto_convertt::convert_CPROVER_throw - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_CPROVER_throw( const codet &code, goto_programt &dest) @@ -356,18 +275,6 @@ void goto_convertt::convert_CPROVER_throw( } } -/*******************************************************************\ - -Function: goto_convertt::convert_CPROVER_try_finally - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::convert_CPROVER_try_finally( const codet &code, goto_programt &dest) @@ -392,18 +299,6 @@ void goto_convertt::convert_CPROVER_try_finally( convert(to_code(code.op1()), dest); } -/*******************************************************************\ - -Function: goto_convertt::exception_flag - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - symbol_exprt goto_convertt::exception_flag() { irep_idt id="$exception_flag"; @@ -426,18 +321,6 @@ symbol_exprt goto_convertt::exception_flag() return symbol_exprt(id, bool_typet()); } -/*******************************************************************\ - -Function: goto_convertt::unwind_destructor_stack - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::unwind_destructor_stack( const source_locationt &source_location, std::size_t final_stack_size, diff --git a/src/goto-programs/goto_convert_function_call.cpp b/src/goto-programs/goto_convert_function_call.cpp index 6fe2b42bbc1..85d5d75358d 100644 --- a/src/goto-programs/goto_convert_function_call.cpp +++ b/src/goto-programs/goto_convert_function_call.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Program Transformation + +#include "goto_convert_class.h" + #include #include @@ -14,21 +19,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include - -#include "goto_convert_class.h" - -/*******************************************************************\ - -Function: goto_convertt::convert_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void goto_convertt::convert_function_call( const code_function_callt &function_call, @@ -41,18 +32,6 @@ void goto_convertt::convert_function_call( dest); } -/*******************************************************************\ - -Function: goto_convertt::do_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::do_function_call( const exprt &lhs, const exprt &function, @@ -109,18 +88,6 @@ void goto_convertt::do_function_call( } } -/*******************************************************************\ - -Function: goto_convertt::do_function_call_if - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::do_function_call_if( const exprt &lhs, const if_exprt &function, @@ -185,18 +152,6 @@ void goto_convertt::do_function_call_if( dest.destructive_append(tmp_z); } -/*******************************************************************\ - -Function: goto_convertt::do_function_call_other - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::do_function_call_other( const exprt &lhs, const exprt &function, diff --git a/src/goto-programs/goto_convert_functions.cpp b/src/goto-programs/goto_convert_functions.cpp index b25d8870f09..5a35d5e2ef7 100644 --- a/src/goto-programs/goto_convert_functions.cpp +++ b/src/goto-programs/goto_convert_functions.cpp @@ -8,6 +8,8 @@ Date: June 2003 \*******************************************************************/ +#include "goto_convert_functions.h" + #include #include @@ -15,21 +17,8 @@ Date: June 2003 #include #include -#include "goto_convert_functions.h" #include "goto_inline.h" -/*******************************************************************\ - -Function: goto_convert_functionst::goto_convert_functionst - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - goto_convert_functionst::goto_convert_functionst( symbol_tablet &_symbol_table, goto_functionst &_functions, @@ -39,34 +28,10 @@ goto_convert_functionst::goto_convert_functionst( { } -/*******************************************************************\ - -Function: goto_convert_functionst::~goto_convert_functionst - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - goto_convert_functionst::~goto_convert_functionst() { } -/*******************************************************************\ - -Function: goto_convert_functionst::goto_convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convert_functionst::goto_convert() { // warning! hash-table iterators are not stable @@ -105,18 +70,6 @@ void goto_convert_functionst::goto_convert() #endif } -/*******************************************************************\ - -Function: goto_convert_functionst::hide - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool goto_convert_functionst::hide(const goto_programt &goto_program) { forall_goto_program_instructions(i_it, goto_program) @@ -129,18 +82,6 @@ bool goto_convert_functionst::hide(const goto_programt &goto_program) return false; } -/*******************************************************************\ - -Function: goto_convert_functionst::add_return - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convert_functionst::add_return( goto_functionst::goto_functiont &f, const source_locationt &source_location) @@ -194,18 +135,6 @@ void goto_convert_functionst::add_return( t->source_location=source_location; } -/*******************************************************************\ - -Function: goto_convert_functionst::convert_function - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convert_functionst::convert_function(const irep_idt &identifier) { const symbolt &symbol=ns.lookup(identifier); @@ -292,18 +221,6 @@ void goto_convert_functionst::convert_function(const irep_idt &identifier) f.make_hidden(); } -/*******************************************************************\ - -Function: goto_convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convert( symbol_tablet &symbol_table, goto_modelt &goto_model, @@ -313,23 +230,24 @@ void goto_convert( goto_model.symbol_table.swap(symbol_table); } -/*******************************************************************\ - -Function: goto_convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +void goto_convert( + goto_modelt &goto_model, + message_handlert &message_handler) +{ + goto_convert( + goto_model.symbol_table, + goto_model.goto_functions, + message_handler); +} void goto_convert( symbol_tablet &symbol_table, goto_functionst &functions, message_handlert &message_handler) { + const unsigned errors_before= + message_handler.get_message_count(messaget::M_ERROR); + goto_convert_functionst goto_convert_functions( symbol_table, functions, message_handler); @@ -341,33 +259,21 @@ void goto_convert( catch(int) { goto_convert_functions.error(); - throw 0; } catch(const char *e) { goto_convert_functions.error() << e << messaget::eom; - throw 0; } catch(const std::string &e) { goto_convert_functions.error() << e << messaget::eom; - throw 0; } -} - -/*******************************************************************\ - -Function: goto_convert - - Inputs: - - Outputs: - Purpose: - -\*******************************************************************/ + if(message_handler.get_message_count(messaget::M_ERROR)!=errors_before) + throw 0; +} void goto_convert( const irep_idt &identifier, @@ -375,6 +281,9 @@ void goto_convert( goto_functionst &functions, message_handlert &message_handler) { + const unsigned errors_before= + message_handler.get_message_count(messaget::M_ERROR); + goto_convert_functionst goto_convert_functions( symbol_table, functions, message_handler); @@ -386,18 +295,18 @@ void goto_convert( catch(int) { goto_convert_functions.error(); - throw 0; } catch(const char *e) { goto_convert_functions.error() << e << messaget::eom; - throw 0; } catch(const std::string &e) { goto_convert_functions.error() << e << messaget::eom; - throw 0; } + + if(message_handler.get_message_count(messaget::M_ERROR)!=errors_before) + throw 0; } diff --git a/src/goto-programs/goto_convert_functions.h b/src/goto-programs/goto_convert_functions.h index 9678c928609..85de9a67b97 100644 --- a/src/goto-programs/goto_convert_functions.h +++ b/src/goto-programs/goto_convert_functions.h @@ -8,6 +8,9 @@ Date: June 2003 \*******************************************************************/ +/// \file +/// Goto Programs with Functions + #ifndef CPROVER_GOTO_PROGRAMS_GOTO_CONVERT_FUNCTIONS_H #define CPROVER_GOTO_PROGRAMS_GOTO_CONVERT_FUNCTIONS_H @@ -18,20 +21,25 @@ Date: June 2003 void goto_convert( symbol_tablet &symbol_table, goto_functionst &functions, - message_handlert &message_handler); + message_handlert &); -// convert it all! +// confusing, will go away void goto_convert( symbol_tablet &symbol_table, goto_modelt &dest, - message_handlert &message_handler); + message_handlert &); + +// convert it all! +void goto_convert( + goto_modelt &, + message_handlert &); // just convert a specific function void goto_convert( const irep_idt &identifier, symbol_tablet &symbol_table, goto_functionst &functions, - message_handlert &message_handler); + message_handlert &); class goto_convert_functionst:public goto_convertt { @@ -49,7 +57,7 @@ class goto_convert_functionst:public goto_convertt protected: goto_functionst &functions; - static bool hide(const goto_programt &goto_program); + static bool hide(const goto_programt &); // // function calls diff --git a/src/goto-programs/goto_convert_new_switch_case.cpp b/src/goto-programs/goto_convert_new_switch_case.cpp deleted file mode 100644 index 4a81a4176a2..00000000000 --- a/src/goto-programs/goto_convert_new_switch_case.cpp +++ /dev/null @@ -1,2674 +0,0 @@ -/*******************************************************************\ - -Module: Program Transformation - -Author: Daniel Kroening, kroening@kroening.com - -\*******************************************************************/ - -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include "goto_convert.h" -#include "goto_convert_class.h" -#include "destructor.h" - -/*******************************************************************\ - -Function: is_empty - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -static bool is_empty(const goto_programt &goto_program) -{ - forall_goto_program_instructions(it, goto_program) - if(!it->is_skip() || - !it->labels.empty() || - !it->code.is_nil()) - return false; - - return true; -} - -/*******************************************************************\ - -Function: goto_convertt::finish_gotos - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::finish_gotos() -{ - for(const auto &target : targets.gotos) - { - goto_programt::instructiont &i=*target; - - if(i.code.get_statement()=="non-deterministic-goto") - { - const irept &destinations=i.code.find("destinations"); - - i.make_goto(); - - forall_irep(it, destinations.get_sub()) - { - labelst::const_iterator l_it= - targets.labels.find(it->id_string()); - - if(l_it==targets.labels.end()) - { - err_location(i.code); - str << "goto label `" << it->id_string() << "' not found"; - error_msg(); - throw 0; - } - - i.targets.push_back(l_it->second); - } - } - else if(i.is_start_thread()) - { - const irep_idt &goto_label=i.code.get(ID_destination); - - labelst::const_iterator l_it= - targets.labels.find(goto_label); - - if(l_it==targets.labels.end()) - { - err_location(i.code); - str << "goto label `" << goto_label << "' not found"; - error_msg(); - throw 0; - } - - i.targets.push_back(l_it->second); - } - else if(i.code.get_statement()==ID_goto) - { - const irep_idt &goto_label=i.code.get(ID_destination); - - labelst::const_iterator l_it=targets.labels.find(goto_label); - - if(l_it==targets.labels.end()) - { - err_location(i.code); - str << "goto label `" << goto_label << "' not found"; - error_msg(); - throw 0; - } - - i.targets.clear(); - i.targets.push_back(l_it->second); - } - else - { - err_location(i.code); - error() << "finish_gotos: unexpected goto" << eom; - throw 0; - } - } - - targets.gotos.clear(); -} - -/*******************************************************************\ - -Function: goto_convertt::finish_computed_gotos - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::finish_computed_gotos(goto_programt &goto_program) -{ - for(const auto &target : targets.computed_gotos) - { - goto_programt::instructiont &i=*target; - exprt destination=i.code.op0(); - - assert(destination.id()==ID_dereference); - assert(destination.operands().size()==1); - - exprt pointer=destination.op0(); - - // remember the expression for later checks - i.type=OTHER; - i.code=code_expressiont(pointer); - - // insert huge case-split - for(const auto &label : targets.labels) - { - exprt label_expr(ID_label, empty_typet()); - label_expr.set(ID_identifier, label.first); - - equal_exprt guard; - - guard.lhs()=pointer; - guard.rhs()=address_of_exprt(label_expr); - - goto_programt::targett t= - goto_program.insert_after(target); - - t->make_goto(label.second); - t->source_location=i.source_location; - t->guard=guard; - } - } - - targets.computed_gotos.clear(); -} - -/*******************************************************************\ - -Function: goto_convertt::goto_convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::goto_convert(const codet &code, goto_programt &dest) -{ - goto_convert_rec(code, dest); -} - -/*******************************************************************\ - -Function: goto_convertt::goto_convert_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::goto_convert_rec( - const codet &code, - goto_programt &dest) -{ - convert(code, dest); - - finish_gotos(); - finish_computed_gotos(dest); -} - -/*******************************************************************\ - -Function: goto_convertt::copy - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::copy( - const codet &code, - goto_program_instruction_typet type, - goto_programt &dest) -{ - goto_programt::targett t=dest.add_instruction(type); - t->code=code; - t->source_location=code.source_location(); -} - -/*******************************************************************\ - -Function: goto_convert::convert_label - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_label( - const code_labelt &code, - goto_programt &dest) -{ - if(code.operands().size()!=1) - { - err_location(code); - error() << "label statement expected to have one operand" << eom; - throw 0; - } - - // grab the label - const irep_idt &label=code.get_label(); - - goto_programt tmp; - - // magic thread creation label? - if(has_prefix(id2string(label), "__CPROVER_ASYNC_")) - { - // this is like a START_THREAD - codet tmp_code(ID_start_thread); - tmp_code.copy_to_operands(code.op0()); - tmp_code.add_source_location()=code.source_location(); - convert(tmp_code, tmp); - } - else - convert(to_code(code.op0()), tmp); - - goto_programt::targett target=tmp.instructions.begin(); - dest.destructive_append(tmp); - - targets.labels.insert(std::pair - (label, target)); - target->labels.push_front(label); -} - -/*******************************************************************\ - -Function: goto_convert::convert_gcc_local_label - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_gcc_local_label( - const codet &code, - goto_programt &dest) -{ - // ignore for now -} - -/*******************************************************************\ - -Function: goto_convert::convert_switch_case - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_switch_case( - const code_switch_caset &code, - goto_programt &dest) -{ - if(code.operands().size()!=2) - { - err_location(code); - error() << "switch-case statement expected to have two operands" << eom; - throw 0; - } - - goto_programt tmp; - convert(code.code(), tmp); - - goto_programt::targett target=tmp.instructions.begin(); - dest.destructive_append(tmp); - - // default? - - if(code.is_default()) - targets.set_default(target); - else - { - // cases? - - cases_mapt::iterator cases_entry=targets.cases_map.find(target); - if(cases_entry==targets.cases_map.end()) - { - // We generate a 'goto'-instruction for this. - goto_programt::targett g= - dest.add_instruction(GOTO); - - g->source_location=code.source_location(); - - targets.cases.push_back(std::make_pair(g, caset())); - - cases_entry=targets.cases_map.insert(std::make_pair( - g, --targets.cases.end())).first; - } - - exprt::operandst &case_op_dest=cases_entry->second->second; - case_op_dest.push_back(code.case_op()); - } -} - -/*******************************************************************\ - -Function: goto_convert::convert_gcc_switch_case_range - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_gcc_switch_case_range( - const codet &code, - goto_programt &dest) -{ - if(code.operands().size()!=3) - { - err_location(code); - error() << "GCC's switch-case-range statement expected to have " - << "three operands" << eom; - throw 0; - } - - goto_programt tmp; - convert(to_code(code.op2()), tmp); - - // goto_programt::targett target=tmp.instructions.begin(); - dest.destructive_append(tmp); - - #if 0 - cases_mapt::iterator cases_entry=targets.cases_map.find(target); - if(cases_entry==targets.cases_map.end()) - { - targets.cases.push_back(std::make_pair(target, caset())); - cases_entry=targets.cases_map.insert(std::make_pair( - target, --targets.cases.end())).first; - } - - // TODO - exprt::operandst &case_op_dest=cases_entry->second->second; - case_op_dest.push_back(code.case_op()); - #endif -} - -/*******************************************************************\ - -Function: goto_convertt::convert - - Inputs: - - Outputs: - - Purpose: converts 'code' and appends the result to 'dest' - -\*******************************************************************/ - -void goto_convertt::convert( - const codet &code, - goto_programt &dest) -{ - const irep_idt &statement=code.get_statement(); - - if(statement==ID_block) - convert_block(to_code_block(code), dest); - else if(statement==ID_decl) - convert_decl(to_code_decl(code), dest); - else if(statement==ID_decl_type) - convert_decl_type(code, dest); - else if(statement==ID_expression) - convert_expression(to_code_expression(code), dest); - else if(statement==ID_assign) - convert_assign(to_code_assign(code), dest); - else if(statement==ID_init) - convert_init(code, dest); - else if(statement==ID_assert) - convert_assert(to_code_assert(code), dest); - else if(statement==ID_assume) - convert_assume(to_code_assume(code), dest); - else if(statement==ID_function_call) - convert_function_call(to_code_function_call(code), dest); - else if(statement==ID_label) - convert_label(to_code_label(code), dest); - else if(statement==ID_gcc_local_label) - convert_gcc_local_label(code, dest); - else if(statement==ID_switch_case) - convert_switch_case(to_code_switch_case(code), dest); - else if(statement==ID_gcc_switch_case_range) - convert_gcc_switch_case_range(code, dest); - else if(statement==ID_for) - convert_for(to_code_for(code), dest); - else if(statement==ID_while) - convert_while(to_code_while(code), dest); - else if(statement==ID_dowhile) - convert_dowhile(code, dest); - else if(statement==ID_switch) - convert_switch(to_code_switch(code), dest); - else if(statement==ID_break) - convert_break(to_code_break(code), dest); - else if(statement==ID_return) - convert_return(to_code_return(code), dest); - else if(statement==ID_continue) - convert_continue(to_code_continue(code), dest); - else if(statement==ID_goto) - convert_goto(code, dest); - else if(statement==ID_gcc_computed_goto) - convert_gcc_computed_goto(code, dest); - else if(statement==ID_skip) - convert_skip(code, dest); - else if(statement=="non-deterministic-goto") - convert_non_deterministic_goto(code, dest); - else if(statement==ID_ifthenelse) - convert_ifthenelse(to_code_ifthenelse(code), dest); - else if(statement==ID_specc_notify) - convert_specc_notify(code, dest); - else if(statement==ID_specc_wait) - convert_specc_wait(code, dest); - else if(statement==ID_specc_par) - convert_specc_par(code, dest); - else if(statement==ID_start_thread) - convert_start_thread(code, dest); - else if(statement==ID_end_thread) - convert_end_thread(code, dest); - else if(statement==ID_atomic_begin) - convert_atomic_begin(code, dest); - else if(statement==ID_atomic_end) - convert_atomic_end(code, dest); - else if(statement==ID_bp_enforce) - convert_bp_enforce(code, dest); - else if(statement==ID_bp_abortif) - convert_bp_abortif(code, dest); - else if(statement==ID_cpp_delete || - statement=="cpp_delete[]") - convert_cpp_delete(code, dest); - else if(statement==ID_msc_try_except) - convert_msc_try_except(code, dest); - else if(statement==ID_msc_try_finally) - convert_msc_try_finally(code, dest); - else if(statement==ID_msc_leave) - convert_msc_leave(code, dest); - else if(statement==ID_try_catch) // C++ try/catch - convert_try_catch(code, dest); - else if(statement==ID_CPROVER_try_catch) // CPROVER-homemade - convert_CPROVER_try_catch(code, dest); - else if(statement==ID_CPROVER_throw) // CPROVER-homemade - convert_CPROVER_throw(code, dest); - else if(statement==ID_CPROVER_try_finally) - convert_CPROVER_try_finally(code, dest); - else if(statement==ID_asm) - convert_asm(to_code_asm(code), dest); - else if(statement==ID_static_assert) - { - assert(code.operands().size()==2); - exprt assertion=code.op0(); - assertion.make_typecast(bool_typet()); - simplify(assertion, ns); - if(assertion.is_false()) - { - err_location(code.op0()); - str << "static assertion " - << get_string_constant(code.op1()); - error_msg(); - throw 0; - } - else if(assertion.is_true()) - { - } - else - { - // we may wish to complain - } - } - else if(statement==ID_dead) - copy(code, DEAD, dest); - else if(statement==ID_decl_block) - { - forall_operands(it, code) - convert(to_code(*it), dest); - } - else - copy(code, OTHER, dest); - - // make sure dest is never empty - if(dest.instructions.empty()) - { - dest.add_instruction(SKIP); - dest.instructions.back().code.make_nil(); - dest.instructions.back().source_location=code.source_location(); - } -} - -/*******************************************************************\ - -Function: goto_convertt::convert_block - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_block( - const code_blockt &code, - goto_programt &dest) -{ - const source_locationt &end_location=code.end_location(); - - // this saves the size of the destructor stack - std::size_t old_stack_size=targets.destructor_stack.size(); - - // now convert block - forall_operands(it, code) - { - const codet &b_code=to_code(*it); - convert(b_code, dest); - } - - // see if we need to do any destructors - unwind_destructor_stack(end_location, old_stack_size, dest); - - // remove those destructors - targets.destructor_stack.resize(old_stack_size); -} - -/*******************************************************************\ - -Function: goto_convertt::convert_expression - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_expression( - const code_expressiont &code, - goto_programt &dest) -{ - if(code.operands().size()!=1) - { - err_location(code); - error() << "expression statement takes one operand" << eom; - throw 0; - } - - exprt expr=code.op0(); - - if(expr.id()==ID_if) - { - // We do a special treatment for c?t:f - // by compiling to if(c) t; else f; - const if_exprt &if_expr=to_if_expr(expr); - code_ifthenelset tmp_code; - tmp_code.add_source_location()=expr.source_location(); - tmp_code.cond()=if_expr.cond(); - tmp_code.then_case()=code_expressiont(if_expr.true_case()); - tmp_code.then_case().add_source_location()=expr.source_location(); - tmp_code.else_case()=code_expressiont(if_expr.false_case()); - tmp_code.else_case().add_source_location()=expr.source_location(); - convert_ifthenelse(tmp_code, dest); - } - else - { - clean_expr(expr, dest, false); // result _not_ used - - // Any residual expression? - // We keep it to add checks later. - if(expr.is_not_nil()) - { - codet tmp=code; - tmp.op0()=expr; - tmp.add_source_location()=expr.source_location(); - copy(tmp, OTHER, dest); - } - } -} - -/*******************************************************************\ - -Function: goto_convertt::convert_decl - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_decl( - const code_declt &code, - goto_programt &dest) -{ - const exprt &op0=code.op0(); - - if(op0.id()!=ID_symbol) - { - err_location(op0); - error() << "decl statement expects symbol as first operand" << eom; - throw 0; - } - - const irep_idt &identifier=op0.get(ID_identifier); - - const symbolt &symbol=lookup(identifier); - - if(symbol.is_static_lifetime || - symbol.type.id()==ID_code) - return; // this is a SKIP! - - if(code.operands().size()==1) - { - copy(code, DECL, dest); - } - else - { - // this is expected to go away - exprt initializer; - - codet tmp=code; - initializer=code.op1(); - tmp.operands().resize(1); - - // Break up into decl and assignment. - // Decl must be visible before initializer. - copy(tmp, DECL, dest); - - code_assignt assign(code.op0(), initializer); - assign.add_source_location()=tmp.source_location(); - - convert_assign(assign, dest); - } - - // now create a 'dead' instruction -- will be added after the - // destructor created below as unwind_destructor_stack pops off the - // top of the destructor stack - const symbol_exprt symbol_expr(symbol.name, symbol.type); - - { - code_deadt code_dead(symbol_expr); - targets.destructor_stack.push_back(code_dead); - } - - // do destructor - code_function_callt destructor=get_destructor(ns, symbol.type); - - if(destructor.is_not_nil()) - { - // add "this" - exprt this_expr(ID_address_of, pointer_typet()); - this_expr.type().subtype()=symbol.type; - this_expr.copy_to_operands(symbol_expr); - destructor.arguments().push_back(this_expr); - - targets.destructor_stack.push_back(destructor); - } -} - -/*******************************************************************\ - -Function: goto_convertt::convert_decl_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_decl_type( - const codet &code, - goto_programt &dest) -{ - // we remove these -} - -/*******************************************************************\ - -Function: goto_convertt::convert_assign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_assign( - const code_assignt &code, - goto_programt &dest) -{ - exprt lhs=code.lhs(), - rhs=code.rhs(); - - clean_expr(lhs, dest); - - if(rhs.id()==ID_side_effect && - rhs.get(ID_statement)==ID_function_call) - { - if(rhs.operands().size()!=2) - { - err_location(rhs); - error() << "function_call sideeffect takes two operands" << eom; - throw 0; - } - - Forall_operands(it, rhs) - clean_expr(*it, dest); - - do_function_call(lhs, rhs.op0(), rhs.op1().operands(), dest); - } - else if(rhs.id()==ID_side_effect && - (rhs.get(ID_statement)==ID_cpp_new || - rhs.get(ID_statement)==ID_cpp_new_array)) - { - Forall_operands(it, rhs) - clean_expr(*it, dest); - - do_cpp_new(lhs, to_side_effect_expr(rhs), dest); - } - else if(rhs.id()==ID_side_effect && - rhs.get(ID_statement)==ID_java_new) - { - Forall_operands(it, rhs) - clean_expr(*it, dest); - - do_java_new(lhs, to_side_effect_expr(rhs), dest); - } - else if(rhs.id()==ID_side_effect && - rhs.get(ID_statement)==ID_java_new_array) - { - Forall_operands(it, rhs) - clean_expr(*it, dest); - - do_java_new_array(lhs, to_side_effect_expr(rhs), dest); - } - else if(rhs.id()==ID_side_effect && - rhs.get(ID_statement)==ID_malloc) - { - // just preserve - Forall_operands(it, rhs) - clean_expr(*it, dest); - - code_assignt new_assign(code); - new_assign.lhs()=lhs; - new_assign.rhs()=rhs; - - copy(new_assign, ASSIGN, dest); - } - else - { - clean_expr(rhs, dest); - - if(lhs.id()==ID_typecast) - { - assert(lhs.operands().size()==1); - - // add a typecast to the rhs - exprt new_rhs=rhs; - rhs.make_typecast(lhs.op0().type()); - - // remove typecast from lhs - exprt tmp=lhs.op0(); - lhs.swap(tmp); - } - - code_assignt new_assign(code); - new_assign.lhs()=lhs; - new_assign.rhs()=rhs; - - copy(new_assign, ASSIGN, dest); - } -} - -/*******************************************************************\ - -Function: goto_convertt::convert_init - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_init( - const codet &code, - goto_programt &dest) -{ - if(code.operands().size()!=2) - { - err_location(code); - error() << "init statement takes two operands" << eom; - throw 0; - } - - // make it an assignment - codet assignment=code; - assignment.set_statement(ID_assign); - - convert(to_code_assign(assignment), dest); -} - -/*******************************************************************\ - -Function: goto_convertt::convert_cpp_delete - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_cpp_delete( - const codet &code, - goto_programt &dest) -{ - if(code.operands().size()!=1) - { - err_location(code); - error() << "cpp_delete statement takes one operand" << eom; - throw 0; - } - - exprt tmp_op=code.op0(); - - clean_expr(tmp_op, dest); - - // we call the destructor, and then free - const exprt &destructor= - static_cast(code.find(ID_destructor)); - - irep_idt delete_identifier; - - if(code.get_statement()==ID_cpp_delete_array) - delete_identifier="__delete_array"; - else if(code.get_statement()==ID_cpp_delete) - delete_identifier="__delete"; - else - assert(false); - - if(destructor.is_not_nil()) - { - if(code.get_statement()==ID_cpp_delete_array) - { - // build loop - } - else if(code.get_statement()==ID_cpp_delete) - { - // just one object - exprt deref_op(ID_dereference, tmp_op.type().subtype()); - deref_op.copy_to_operands(tmp_op); - - codet tmp_code=to_code(destructor); - replace_new_object(deref_op, tmp_code); - convert(tmp_code, dest); - } - else - assert(false); - } - - // now do "free" - exprt delete_symbol=ns.lookup(delete_identifier).symbol_expr(); - - assert(to_code_type(delete_symbol.type()).parameters().size()==1); - - typet arg_type= - to_code_type(delete_symbol.type()).parameters().front().type(); - - code_function_callt delete_call; - delete_call.function()=delete_symbol; - delete_call.arguments().push_back(typecast_exprt(tmp_op, arg_type)); - delete_call.lhs().make_nil(); - delete_call.add_source_location()=code.source_location(); - - convert(delete_call, dest); -} - -/*******************************************************************\ - -Function: goto_convertt::convert_assert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_assert( - const code_assertt &code, - goto_programt &dest) -{ - exprt cond=code.assertion(); - - clean_expr(cond, dest); - - goto_programt::targett t=dest.add_instruction(ASSERT); - t->guard.swap(cond); - t->source_location=code.source_location(); - t->source_location.set(ID_property, ID_assertion); - t->source_location.set("user-provided", true); -} - -/*******************************************************************\ - -Function: goto_convertt::convert_skip - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_skip( - const codet &code, - goto_programt &dest) -{ - goto_programt::targett t=dest.add_instruction(SKIP); - t->source_location=code.source_location(); - t->code=code; -} - -/*******************************************************************\ - -Function: goto_convertt::convert_assert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_assume( - const code_assumet &code, - goto_programt &dest) -{ - exprt op=code.assumption(); - - clean_expr(op, dest); - - goto_programt::targett t=dest.add_instruction(ASSUME); - t->guard.swap(op); - t->source_location=code.source_location(); -} - -/*******************************************************************\ - -Function: goto_convertt::convert_for - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_for( - const code_fort &code, - goto_programt &dest) -{ - // turn for(A; c; B) { P } into - // A; while(c) { P; B; } - //----------------------------- - // A; - // u: sideeffects in c - // v: if(!c) goto z; - // w: P; - // x: B; <-- continue target - // y: goto u; - // z: ; <-- break target - - // A; - if(code.init().is_not_nil()) - convert(to_code(code.init()), dest); - - exprt cond=code.cond(); - - goto_programt sideeffects; - clean_expr(cond, sideeffects); - - // save break/continue targets - break_continue_targetst old_targets(targets); - - // do the u label - goto_programt::targett u=sideeffects.instructions.begin(); - - // do the v label - goto_programt tmp_v; - goto_programt::targett v=tmp_v.add_instruction(); - - // do the z label - goto_programt tmp_z; - goto_programt::targett z=tmp_z.add_instruction(SKIP); - z->source_location=code.source_location(); - - // do the x label - goto_programt tmp_x; - - if(code.op2().is_nil()) - { - tmp_x.add_instruction(SKIP); - tmp_x.instructions.back().source_location=code.source_location(); - } - else - { - exprt tmp_B=code.iter(); - - clean_expr(tmp_B, tmp_x, false); - - if(tmp_x.instructions.empty()) - { - tmp_x.add_instruction(SKIP); - tmp_x.instructions.back().source_location=code.source_location(); - } - } - - // optimize the v label - if(sideeffects.instructions.empty()) - u=v; - - // set the targets - targets.set_break(z); - targets.set_continue(tmp_x.instructions.begin()); - - // v: if(!c) goto z; - v->make_goto(z); - v->guard=cond; - v->guard.make_not(); - v->source_location=cond.source_location(); - - // do the w label - goto_programt tmp_w; - convert(code.body(), tmp_w); - - // y: goto u; - goto_programt tmp_y; - goto_programt::targett y=tmp_y.add_instruction(); - y->make_goto(u); - y->guard=true_exprt(); - y->source_location=code.source_location(); - - dest.destructive_append(sideeffects); - dest.destructive_append(tmp_v); - dest.destructive_append(tmp_w); - dest.destructive_append(tmp_x); - dest.destructive_append(tmp_y); - dest.destructive_append(tmp_z); - - // restore break/continue - old_targets.restore(targets); -} - -/*******************************************************************\ - -Function: goto_convertt::convert_while - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_while( - const code_whilet &code, - goto_programt &dest) -{ - const exprt &cond=code.cond(); - const source_locationt &source_location=code.source_location(); - - // while(c) P; - //-------------------- - // v: sideeffects in c - // if(!c) goto z; - // x: P; - // y: goto v; <-- continue target - // z: ; <-- break target - - // save break/continue targets - break_continue_targetst old_targets(targets); - - // do the z label - goto_programt tmp_z; - goto_programt::targett z=tmp_z.add_instruction(); - z->make_skip(); - z->source_location=source_location; - - goto_programt tmp_branch; - generate_conditional_branch( - boolean_negate(cond), z, source_location, tmp_branch); - - // do the v label - goto_programt::targett v=tmp_branch.instructions.begin(); - - // do the y label - goto_programt tmp_y; - goto_programt::targett y=tmp_y.add_instruction(); - - // set the targets - targets.set_break(z); - targets.set_continue(y); - - // do the x label - goto_programt tmp_x; - convert(code.body(), tmp_x); - - // y: if(c) goto v; - y->make_goto(v); - y->guard=true_exprt(); - y->source_location=code.source_location(); - - dest.destructive_append(tmp_branch); - dest.destructive_append(tmp_x); - dest.destructive_append(tmp_y); - dest.destructive_append(tmp_z); - - // restore break/continue - old_targets.restore(targets); -} - -/*******************************************************************\ - -Function: goto_convertt::convert_dowhile - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_dowhile( - const codet &code, - goto_programt &dest) -{ - if(code.operands().size()!=2) - { - err_location(code); - error() << "dowhile takes two operands" << eom; - throw 0; - } - - // save source location - source_locationt condition_location=code.op0().find_source_location(); - - exprt cond=code.op0(); - - goto_programt sideeffects; - clean_expr(cond, sideeffects); - - // do P while(c); - //-------------------- - // w: P; - // x: sideeffects in c <-- continue target - // y: if(c) goto w; - // z: ; <-- break target - - // save break/continue targets - break_continue_targetst old_targets(targets); - - // do the y label - goto_programt tmp_y; - goto_programt::targett y=tmp_y.add_instruction(); - - // do the z label - goto_programt tmp_z; - goto_programt::targett z=tmp_z.add_instruction(); - z->make_skip(); - z->source_location=code.source_location(); - - // do the x label - goto_programt::targett x; - if(sideeffects.instructions.empty()) - x=y; - else - x=sideeffects.instructions.begin(); - - // set the targets - targets.set_break(z); - targets.set_continue(x); - - // do the w label - goto_programt tmp_w; - convert(to_code(code.op1()), tmp_w); - goto_programt::targett w=tmp_w.instructions.begin(); - - // y: if(c) goto w; - y->make_goto(w); - y->guard=cond; - y->source_location=condition_location; - - dest.destructive_append(tmp_w); - dest.destructive_append(sideeffects); - dest.destructive_append(tmp_y); - dest.destructive_append(tmp_z); - - // restore break/continue targets - old_targets.restore(targets); -} - -/*******************************************************************\ - -Function: goto_convertt::case_guard - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -exprt goto_convertt::case_guard( - const exprt &value, - const exprt::operandst &case_op) -{ - exprt dest=exprt(ID_or, bool_typet()); - dest.reserve_operands(case_op.size()); - - forall_expr(it, case_op) - { - equal_exprt eq_expr; - eq_expr.lhs()=value; - eq_expr.rhs()=*it; - dest.move_to_operands(eq_expr); - } - - assert(!dest.operands().empty()); - - if(dest.operands().size()==1) - { - exprt tmp; - tmp.swap(dest.op0()); - dest.swap(tmp); - } - - return dest; -} - -/*******************************************************************\ - -Function: goto_convertt::convert_switch - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_switch( - const code_switcht &code, - goto_programt &dest) -{ - // switch(v) { - // case x: Px; - // case y: Py; - // ... - // default: Pd; - // } - // -------------------- - // a: goto X; - // X: if(v!=x) goto Y; - // Px; - // Y: if(v!=y) goto Z; - // Py; - // Z: ... - // Pd; - // z: ; - - if(code.operands().size()<2) - { - err_location(code); - error() << "switch takes at least two operands" << eom; - throw 0; - } - - exprt argument=code.value(); - - goto_programt sideeffects; - clean_expr(argument, sideeffects); - - // save break/default/cases targets - break_switch_targetst old_targets(targets); - - // do the a label - goto_programt tmp_a; - goto_programt::targett a=tmp_a.add_instruction(); - a->make_goto(); - a->source_location=code.source_location(); - - // do the z label - goto_programt tmp_z; - goto_programt::targett z=tmp_z.add_instruction(); - z->make_skip(); - z->source_location=code.source_location(); - - // set the new targets -- continue stays as is - targets.set_break(z); - targets.set_default(z); - targets.cases.clear(); - targets.cases_map.clear(); - - goto_programt tmp; - - forall_operands(it, code) - if(it!=code.operands().begin()) - convert(to_code(*it), tmp); - - goto_programt tmp_cases; - - goto_programt::targett previous=a; - - for(casest::iterator it=targets.cases.begin(); - it!=targets.cases.end(); - it++) - { - const caset &case_ops=it->second; - - // we generate a goto for 'case' - assert(it->first->is_goto()); - - assert(!case_ops.empty()); - - exprt guard_expr=case_guard(argument, case_ops); - - // adjust previous case to jump here - previous->set_target(it->first); - it->first->guard=guard_expr; - - previous=it->first; - } - - { - // adjust previous to jump to default target - previous->set_target(targets.default_target); - } - - dest.destructive_append(sideeffects); - dest.destructive_append(tmp_a); - dest.destructive_append(tmp_cases); - dest.destructive_append(tmp); - dest.destructive_append(tmp_z); - - // restore old targets - old_targets.restore(targets); -} - -/*******************************************************************\ - -Function: goto_convertt::convert_break - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_break( - const code_breakt &code, - goto_programt &dest) -{ - if(!targets.break_set) - { - err_location(code); - error() << "break without target" << eom; - throw 0; - } - - // need to process destructor stack - unwind_destructor_stack( - code.source_location(), targets.break_stack_size, dest); - - // add goto - goto_programt::targett t=dest.add_instruction(); - t->make_goto(targets.break_target); - t->source_location=code.source_location(); -} - -/*******************************************************************\ - -Function: goto_convertt::convert_return - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_return( - const code_returnt &code, - goto_programt &dest) -{ - if(!targets.return_set) - { - err_location(code); - error() << "return without target" << eom; - throw 0; - } - - if(!code.operands().empty() && - code.operands().size()!=1) - { - err_location(code); - error() << "return takes none or one operand" << eom; - throw 0; - } - - code_returnt new_code(code); - - if(new_code.has_return_value()) - { - bool result_is_used= - new_code.return_value().type().id()!=ID_empty; - - goto_programt sideeffects; - clean_expr(new_code.return_value(), sideeffects, result_is_used); - dest.destructive_append(sideeffects); - - // remove void-typed return value - if(!result_is_used) - new_code.return_value().make_nil(); - } - - if(targets.has_return_value) - { - if(!new_code.has_return_value()) - { - err_location(new_code); - error() << "function must return value" << eom; - throw 0; - } - - // Now add a return node to set the return value. - goto_programt::targett t=dest.add_instruction(); - t->make_return(); - t->code=new_code; - t->source_location=new_code.source_location(); - } - else - { - if(new_code.has_return_value() && - new_code.return_value().type().id()!=ID_empty) - { - err_location(new_code); - error() << "function must not return value" << eom; - throw 0; - } - } - - // Need to process _entire_ destructor stack. - unwind_destructor_stack(code.source_location(), 0, dest); - - // add goto to end-of-function - goto_programt::targett t=dest.add_instruction(); - t->make_goto(targets.return_target, true_exprt()); - t->source_location=new_code.source_location(); -} - -/*******************************************************************\ - -Function: goto_convertt::convert_continue - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_continue( - const code_continuet &code, - goto_programt &dest) -{ - if(!targets.continue_set) - { - err_location(code); - error() << "continue without target" << eom; - throw 0; - } - - // need to process destructor stack - unwind_destructor_stack( - code.source_location(), targets.continue_stack_size, dest); - - // add goto - goto_programt::targett t=dest.add_instruction(); - t->make_goto(targets.continue_target); - t->source_location=code.source_location(); -} - -/*******************************************************************\ - -Function: goto_convertt::convert_goto - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_goto( - const codet &code, - goto_programt &dest) -{ - goto_programt::targett t=dest.add_instruction(); - t->make_goto(); - t->source_location=code.source_location(); - t->code=code; - - // remember it to do target later - targets.gotos.push_back(t); -} - -/*******************************************************************\ - -Function: goto_convertt::convert_gcc_computed_goto - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_gcc_computed_goto( - const codet &code, - goto_programt &dest) -{ - goto_programt::targett t=dest.add_instruction(); - t->make_skip(); - t->source_location=code.source_location(); - t->code=code; - - // remember it to do this later - targets.computed_gotos.push_back(t); -} - -/*******************************************************************\ - -Function: goto_convertt::convert_non_deterministic_goto - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_non_deterministic_goto( - const codet &code, - goto_programt &dest) -{ - convert_goto(code, dest); -} - -/*******************************************************************\ - -Function: goto_convertt::convert_specc_notify - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_specc_notify( - const codet &code, - goto_programt &dest) -{ - #if 0 - goto_programt::targett t=dest.add_instruction(EVENT); - - forall_operands(it, code) - convert_specc_event(*it, t->events); - - t->code.swap(code); - t->source_location=code.source_location(); - #endif - - copy(code, OTHER, dest); -} - -/*******************************************************************\ - -Function: goto_convertt::convert_specc_event - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_specc_event( - const exprt &op, - std::set &events) -{ - if(op.id()==ID_or || op.id()==ID_and) - { - forall_operands(it, op) - convert_specc_event(*it, events); - } - else if(op.id()==ID_specc_event) - { - irep_idt event=op.get(ID_identifier); - - if(has_prefix(id2string(event), "specc::")) - event=std::string(id2string(event), 7, std::string::npos); - - events.insert(event); - } - else - { - err_location(op); - error() << "convert_convert_event got " << op.id() << eom; - throw 0; - } -} - -/*******************************************************************\ - -Function: goto_convertt::convert_specc_wait - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_specc_wait( - const codet &code, - goto_programt &dest) -{ - #if 0 - goto_programt::targett t=dest.add_instruction(WAIT); - - if(code.operands().size()!=1) - { - err_location(code); - error() << "specc_wait expects one operand" << eom; - throw 0; - } - - const exprt &op=code.op0(); - - if(op.id()=="or") - t->or_semantics=true; - - convert_specc_event(op, t->events); - - t->code.swap(code); - t->source_location=code.source_location(); - #endif - - copy(code, OTHER, dest); -} - -/*******************************************************************\ - -Function: goto_convertt::convert_specc_par - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_specc_par( - const codet &code, - goto_programt &dest) -{ - copy(code, OTHER, dest); -} - -/*******************************************************************\ - -Function: goto_convertt::convert_start_thread - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_start_thread( - const codet &code, - goto_programt &dest) -{ - if(code.operands().size()!=1) - { - err_location(code); - error() << "start_thread expects one operand" << eom; - throw 0; - } - - goto_programt::targett start_thread= - dest.add_instruction(START_THREAD); - - start_thread->source_location=code.source_location(); - - { - // start_thread label; - // goto tmp; - // label: op0-code - // end_thread - // tmp: skip - - goto_programt::targett goto_instruction=dest.add_instruction(GOTO); - goto_instruction->guard=true_exprt(); - goto_instruction->source_location=code.source_location(); - - goto_programt tmp; - convert(to_code(code.op0()), tmp); - goto_programt::targett end_thread=tmp.add_instruction(END_THREAD); - end_thread->source_location=code.source_location(); - - start_thread->targets.push_back(tmp.instructions.begin()); - dest.destructive_append(tmp); - goto_instruction->targets.push_back(dest.add_instruction(SKIP)); - dest.instructions.back().source_location=code.source_location(); - } -} - -/*******************************************************************\ - -Function: goto_convertt::convert_end_thread - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_end_thread( - const codet &code, - goto_programt &dest) -{ - if(!code.operands().empty()) - { - err_location(code); - error() << "end_thread expects no operands" << eom; - throw 0; - } - - copy(code, END_THREAD, dest); -} - -/*******************************************************************\ - -Function: goto_convertt::convert_atomic_begin - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_atomic_begin( - const codet &code, - goto_programt &dest) -{ - if(!code.operands().empty()) - { - err_location(code); - error() << "atomic_begin expects no operands" << eom; - throw 0; - } - - copy(code, ATOMIC_BEGIN, dest); -} - -/*******************************************************************\ - -Function: goto_convertt::convert_atomic_end - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_atomic_end( - const codet &code, - goto_programt &dest) -{ - if(!code.operands().empty()) - { - err_location(code); - error() << "atomic_end expects no operands" << eom; - throw 0; - } - - copy(code, ATOMIC_END, dest); -} - -/*******************************************************************\ - -Function: goto_convertt::convert_bp_enforce - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_bp_enforce( - const codet &code, - goto_programt &dest) -{ - if(code.operands().size()!=2) - { - err_location(code); - str << "bp_enfroce expects two arguments"; - error_msg(); - throw 0; - } - - // do an assume - exprt op=code.op0(); - - clean_expr(op, dest); - - goto_programt::targett t=dest.add_instruction(ASSUME); - t->guard=op; - t->source_location=code.source_location(); - - // change the assignments - - goto_programt tmp; - convert(to_code(code.op1()), tmp); - - if(!op.is_true()) - { - exprt constraint(op); - make_next_state(constraint); - - Forall_goto_program_instructions(it, tmp) - { - if(it->is_assign()) - { - assert(it->code.get(ID_statement)==ID_assign); - - // add constrain - codet constrain(ID_bp_constrain); - constrain.reserve_operands(2); - constrain.move_to_operands(it->code); - constrain.copy_to_operands(constraint); - it->code.swap(constrain); - - it->type=OTHER; - } - else if(it->is_other() && - it->code.get(ID_statement)==ID_bp_constrain) - { - // add to constraint - assert(it->code.operands().size()==2); - it->code.op1()= - and_exprt(it->code.op1(), constraint); - } - } - } - - dest.destructive_append(tmp); -} - -/*******************************************************************\ - -Function: goto_convertt::convert_bp_abortif - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_bp_abortif( - const codet &code, - goto_programt &dest) -{ - if(code.operands().size()!=1) - { - err_location(code); - error() << "bp_abortif expects one argument" << eom; - throw 0; - } - - // do an assert - exprt op=code.op0(); - - clean_expr(op, dest); - - op.make_not(); - - goto_programt::targett t=dest.add_instruction(ASSERT); - t->guard.swap(op); - t->source_location=code.source_location(); -} - -/*******************************************************************\ - -Function: goto_convertt::convert_ifthenelse - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::convert_ifthenelse( - const code_ifthenelset &code, - goto_programt &dest) -{ - if(code.operands().size()!=3) - { - err_location(code); - error() << "ifthenelse takes three operands" << eom; - throw 0; - } - - assert(code.then_case().is_not_nil()); - - bool has_else= - !code.else_case().is_nil(); - - const source_locationt &source_location=code.source_location(); - - // We do a bit of special treatment for && in the condition - // in case cleaning would be needed otherwise. - if(code.cond().id()==ID_and && - code.cond().operands().size()==2 && - (needs_cleaning(code.cond().op0()) || needs_cleaning(code.cond().op1())) && - !has_else) - { - // if(a && b) XX --> if(a) if(b) XX - code_ifthenelset new_if0, new_if1; - new_if0.cond()=code.cond().op0(); - new_if1.cond()=code.cond().op1(); - new_if0.add_source_location()=source_location; - new_if1.add_source_location()=source_location; - new_if1.then_case()=code.then_case(); - new_if0.then_case()=new_if1; - return convert_ifthenelse(new_if0, dest); - } - - // convert 'then'-branch - goto_programt tmp_then; - convert(to_code(code.then_case()), tmp_then); - - goto_programt tmp_else; - - if(has_else) - convert(to_code(code.else_case()), tmp_else); - - exprt tmp_guard=code.cond(); - clean_expr(tmp_guard, dest); - - generate_ifthenelse(tmp_guard, tmp_then, tmp_else, source_location, dest); -} - -/*******************************************************************\ - -Function: goto_convertt::collect_operands - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::collect_operands( - const exprt &expr, - const irep_idt &id, - std::list &dest) -{ - if(expr.id()!=id) - { - dest.push_back(expr); - } - else - { - // left-to-right is important - forall_operands(it, expr) - collect_operands(*it, id, dest); - } -} - -/*******************************************************************\ - -Function: goto_convertt::generate_ifthenelse - - Inputs: - - Outputs: - - Purpose: if(guard) true_case; else false_case; - -\*******************************************************************/ - -void goto_convertt::generate_ifthenelse( - const exprt &guard, - goto_programt &true_case, - goto_programt &false_case, - const source_locationt &source_location, - goto_programt &dest) -{ - if(is_empty(true_case) && - is_empty(false_case)) - return; - - // do guarded gotos directly - if(is_empty(false_case) && - // true_case.instructions.size()==1 optimised - !true_case.instructions.empty() && - ++true_case.instructions.begin()==true_case.instructions.end() && - true_case.instructions.back().is_goto() && - true_case.instructions.back().guard.is_true() && - true_case.instructions.back().labels.empty()) - { - // The above conjunction deliberately excludes the instance - // if(some) { label: goto somewhere; } - true_case.instructions.back().guard=guard; - dest.destructive_append(true_case); - return; - } - - // similarly, do guarded assertions directly - if(true_case.instructions.size()==1 && - true_case.instructions.back().is_assert() && - true_case.instructions.back().guard.is_false() && - true_case.instructions.back().labels.empty()) - { - // The above conjunction deliberately excludes the instance - // if(some) { label: assert(0); } - true_case.instructions.back().guard=boolean_negate(guard); - dest.destructive_append(true_case); - true_case.instructions.clear(); - } - - // similarly, do guarded assertions directly - if(false_case.instructions.size()==1 && - false_case.instructions.back().is_assert() && - false_case.instructions.back().guard.is_false() && - false_case.instructions.back().labels.empty()) - { - // The above conjunction deliberately excludes the instance - // if(some) ... else { label: assert(0); } - false_case.instructions.back().guard=guard; - dest.destructive_append(false_case); - false_case.instructions.clear(); - } - - // Flip around if no 'true' case code. - if(is_empty(true_case)) - return generate_ifthenelse( - boolean_negate(guard), false_case, true_case, source_location, dest); - - bool has_else=!is_empty(false_case); - - // if(c) P; - //-------------------- - // v: if(!c) goto z; - // w: P; - // z: ; - - // if(c) P; else Q; - //-------------------- - // v: if(!c) goto y; - // w: P; - // x: goto z; - // y: Q; - // z: ; - - // do the x label - goto_programt tmp_x; - goto_programt::targett x=tmp_x.add_instruction(); - - // do the z label - goto_programt tmp_z; - goto_programt::targett z=tmp_z.add_instruction(); - z->make_skip(); - z->source_location=source_location; - - // y: Q; - goto_programt tmp_y; - goto_programt::targett y; - if(has_else) - { - tmp_y.swap(false_case); - y=tmp_y.instructions.begin(); - } - - // v: if(!c) goto z/y; - goto_programt tmp_v; - generate_conditional_branch( - boolean_negate(guard), has_else?y:z, source_location, tmp_v); - - // w: P; - goto_programt tmp_w; - tmp_w.swap(true_case); - - // x: goto z; - x->make_goto(z); - assert(!tmp_w.instructions.empty()); - x->source_location=tmp_w.instructions.back().source_location; - - dest.destructive_append(tmp_v); - dest.destructive_append(tmp_w); - - if(has_else) - { - dest.destructive_append(tmp_x); - dest.destructive_append(tmp_y); - } - - dest.destructive_append(tmp_z); -} - -/*******************************************************************\ - -Function: goto_convertt::generate_conditional_branch - - Inputs: - - Outputs: - - Purpose: if(guard) goto target; - -\*******************************************************************/ - -static bool has_and_or(const exprt &expr) -{ - forall_operands(it, expr) - if(has_and_or(*it)) - return true; - - if(expr.id()==ID_and || expr.id()==ID_or) - return true; - - return false; -} - -void goto_convertt::generate_conditional_branch( - const exprt &guard, - goto_programt::targett target_true, - const source_locationt &source_location, - goto_programt &dest) -{ - if(has_and_or(guard) && needs_cleaning(guard)) - { - // if(guard) goto target; - // becomes - // if(guard) goto target; else goto next; - // next: skip; - - goto_programt tmp; - goto_programt::targett target_false=tmp.add_instruction(); - target_false->make_skip(); - target_false->source_location=source_location; - - generate_conditional_branch( - guard, target_true, target_false, source_location, dest); - - dest.destructive_append(tmp); - } - else - { - // simple branch - exprt cond=guard; - clean_expr(cond, dest); - - goto_programt tmp; - goto_programt::targett g=tmp.add_instruction(); - g->make_goto(target_true); - g->guard=cond; - g->source_location=source_location; - dest.destructive_append(tmp); - } -} - -/*******************************************************************\ - -Function: goto_convertt::generate_conditional_branch - - Inputs: - - Outputs: - - Purpose: if(guard) goto target_true; else goto target_false; - -\*******************************************************************/ - -void goto_convertt::generate_conditional_branch( - const exprt &guard, - goto_programt::targett target_true, - goto_programt::targett target_false, - const source_locationt &source_location, - goto_programt &dest) -{ - if(guard.id()==ID_not) - { - assert(guard.operands().size()==1); - // simply swap targets - generate_conditional_branch( - guard.op0(), target_false, target_true, source_location, dest); - return; - } - - if(guard.id()==ID_and) - { - // turn - // if(a && b) goto target_true; else goto target_false; - // into - // if(!a) goto target_false; - // if(!b) goto target_false; - // goto target_true; - - std::list op; - collect_operands(guard, guard.id(), op); - - forall_expr_list(it, op) - generate_conditional_branch( - boolean_negate(*it), target_false, source_location, dest); - - goto_programt::targett t_true=dest.add_instruction(); - t_true->make_goto(target_true); - t_true->guard=true_exprt(); - t_true->source_location=source_location; - - return; - } - else if(guard.id()==ID_or) - { - // turn - // if(a || b) goto target_true; else goto target_false; - // into - // if(a) goto target_true; - // if(b) goto target_true; - // goto target_false; - - std::list op; - collect_operands(guard, guard.id(), op); - - forall_expr_list(it, op) - generate_conditional_branch( - *it, target_true, source_location, dest); - - goto_programt::targett t_false=dest.add_instruction(); - t_false->make_goto(target_false); - t_false->guard=true_exprt(); - t_false->source_location=guard.source_location(); - - return; - } - - exprt cond=guard; - clean_expr(cond, dest); - - goto_programt::targett t_true=dest.add_instruction(); - t_true->make_goto(target_true); - t_true->guard=cond; - t_true->source_location=source_location; - - goto_programt::targett t_false=dest.add_instruction(); - t_false->make_goto(target_false); - t_false->guard=true_exprt(); - t_false->source_location=source_location; -} - -/*******************************************************************\ - -Function: goto_convertt::get_string_constant - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -const irep_idt goto_convertt::get_string_constant( - const exprt &expr) -{ - if(expr.id()==ID_typecast && - expr.operands().size()==1) - return get_string_constant(expr.op0()); - - if(expr.id()==ID_address_of && - expr.operands().size()==1 && - expr.op0().id()==ID_index && - expr.op0().operands().size()==2) - { - exprt index_op=get_constant(expr.op0().op0()); - simplify(index_op, ns); - - if(index_op.id()==ID_string_constant) - return index_op.get(ID_value); - else if(index_op.id()==ID_array) - { - std::string result; - forall_operands(it, index_op) - if(it->is_constant()) - { - unsigned i=integer2long( - binary2integer(id2string(to_constant_expr(*it).get_value()), true)); - - if(i!=0) // to skip terminating 0 - result+=static_cast(i); - } - - return result; - } - } - - if(expr.id()==ID_string_constant) - return expr.get(ID_value); - - err_location(expr); - str << "expected string constant, but got: " - << expr.pretty(); - error_msg(); - - throw 0; -} - -/*******************************************************************\ - -Function: goto_convertt::get_constant - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -exprt goto_convertt::get_constant(const exprt &expr) -{ - if(expr.id()==ID_symbol) - { - const symbolt &symbol= - ns.lookup(to_symbol_expr(expr)); - - return symbol.value; - } - else if(expr.id()==ID_member) - { - exprt tmp=expr; - tmp.op0()=get_constant(expr.op0()); - return tmp; - } - else if(expr.id()==ID_index) - { - exprt tmp=expr; - tmp.op0()=get_constant(expr.op0()); - tmp.op1()=get_constant(expr.op1()); - return tmp; - } - else - return expr; -} - -/*******************************************************************\ - -Function: goto_convertt::new_tmp_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -symbolt &goto_convertt::new_tmp_symbol( - const typet &type, - const std::string &suffix, - goto_programt &dest, - const source_locationt &source_location) -{ - auxiliary_symbolt new_symbol; - symbolt *symbol_ptr; - - do - { - new_symbol.base_name="tmp_"+suffix+"$"+std::to_string(++temporary_counter); - new_symbol.name=tmp_symbol_prefix+id2string(new_symbol.base_name); - new_symbol.type=type; - new_symbol.location=source_location; - } - while(symbol_table.move(new_symbol, symbol_ptr)); - - tmp_symbols.push_back(symbol_ptr->name); - - goto_programt::targett t=dest.add_instruction(DECL); - t->code=code_declt(symbol_ptr->symbol_expr()); - t->source_location=source_location; - - return *symbol_ptr; -} - -/*******************************************************************\ - -Function: goto_convertt::make_temp_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::make_temp_symbol( - exprt &expr, - const std::string &suffix, - goto_programt &dest) -{ - const source_locationt source_location=expr.find_source_location(); - - symbolt &new_symbol= - new_tmp_symbol(expr.type(), suffix, dest, source_location); - - code_assignt assignment; - assignment.lhs()=new_symbol.symbol_expr(); - assignment.rhs()=expr; - assignment.add_source_location()=source_location; - - convert(assignment, dest); - - expr=new_symbol.symbol_expr(); -} - -/*******************************************************************\ - -Function: goto_convertt::new_name - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convertt::new_name(symbolt &symbol) -{ - // rename it - get_new_name(symbol, ns); - - // store in symbol_table - symbol_table.add(symbol); -} - -/*******************************************************************\ - -Function: goto_convertt::lookup - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -const symbolt &goto_convertt::lookup(const irep_idt &identifier) const -{ - const symbolt *symbol; - if(ns.lookup(identifier, symbol)) - { - error() << "failed to find symbol " << identifier << eom; - throw 0; - } - return *symbol; -} - -/*******************************************************************\ - -Function: goto_convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convert( - const codet &code, - symbol_tablet &symbol_table, - goto_programt &dest, - message_handlert &message_handler) -{ - goto_convertt goto_convert(symbol_table, message_handler); - - try - { - goto_convert.goto_convert(code, dest); - } - - catch(int) - { - goto_convert.error_msg(); - } - - catch(const char *e) - { - goto_convert.str << e; - goto_convert.error_msg(); - } - - catch(const std::string &e) - { - goto_convert.str << e; - goto_convert.error_msg(); - } - - if(goto_convert.get_error_found()) - throw 0; -} - -/*******************************************************************\ - -Function: goto_convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void goto_convert( - symbol_tablet &symbol_table, - goto_programt &dest, - message_handlert &message_handler) -{ - // find main symbol - const symbol_tablet::symbolst::const_iterator s_it= - symbol_table.symbols.find("main"); - - if(s_it==symbol_table.symbols.end()) - { - error() << "failed to find main symbol" << eom; - throw 0; - } - - const symbolt &symbol=s_it->second; - - ::goto_convert(to_code(symbol.value), symbol_table, dest, message_handler); -} diff --git a/src/goto-programs/goto_convert_side_effect.cpp b/src/goto-programs/goto_convert_side_effect.cpp index dbebb856ec1..1d12ba8e9d7 100644 --- a/src/goto-programs/goto_convert_side_effect.cpp +++ b/src/goto-programs/goto_convert_side_effect.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Program Transformation + +#include "goto_convert_class.h" + #include #include #include @@ -13,21 +18,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include - -#include "goto_convert_class.h" - -/*******************************************************************\ - -Function: goto_convertt::has_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include bool goto_convertt::has_function_call(const exprt &expr) { @@ -42,18 +33,6 @@ bool goto_convertt::has_function_call(const exprt &expr) return false; } -/*******************************************************************\ - -Function: goto_convertt::remove_assignment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::remove_assignment( side_effect_exprt &expr, goto_programt &dest, @@ -114,7 +93,7 @@ void goto_convertt::remove_assignment( else { error().source_location=expr.find_source_location(); - error() << "assignment `" << statement << "' not yet supproted" + error() << "assignment `" << statement << "' not yet supported" << eom; throw 0; } @@ -157,18 +136,6 @@ void goto_convertt::remove_assignment( expr.make_nil(); } -/*******************************************************************\ - -Function: goto_convertt::remove_pre - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::remove_pre( side_effect_exprt &expr, goto_programt &dest, @@ -256,18 +223,6 @@ void goto_convertt::remove_pre( expr.make_nil(); } -/*******************************************************************\ - -Function: goto_convertt::remove_post - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::remove_post( side_effect_exprt &expr, goto_programt &dest, @@ -374,18 +329,6 @@ void goto_convertt::remove_post( dest.destructive_append(tmp2); } -/*******************************************************************\ - -Function: goto_convertt::remove_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::remove_function_call( side_effect_exprt &expr, goto_programt &dest, @@ -466,18 +409,6 @@ void goto_convertt::remove_function_call( static_cast(expr)=new_symbol.symbol_expr(); } -/*******************************************************************\ - -Function: goto_convertt::replace_new_object - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::replace_new_object( const exprt &object, exprt &dest) @@ -489,18 +420,6 @@ void goto_convertt::replace_new_object( replace_new_object(object, *it); } -/*******************************************************************\ - -Function: goto_convertt::remove_cpp_new - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::remove_cpp_new( side_effect_exprt &expr, goto_programt &dest, @@ -531,18 +450,6 @@ void goto_convertt::remove_cpp_new( convert(call, dest); } -/*******************************************************************\ - -Function: goto_convertt::remove_cpp_delete - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::remove_cpp_delete( side_effect_exprt &expr, goto_programt &dest, @@ -562,18 +469,6 @@ void goto_convertt::remove_cpp_delete( expr.make_nil(); } -/*******************************************************************\ - -Function: goto_convertt::remove_malloc - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::remove_malloc( side_effect_exprt &expr, goto_programt &dest, @@ -611,18 +506,6 @@ void goto_convertt::remove_malloc( convert(call, dest); } -/*******************************************************************\ - -Function: goto_convertt::remove_temporary_object - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::remove_temporary_object( side_effect_exprt &expr, goto_programt &dest, @@ -663,18 +546,6 @@ void goto_convertt::remove_temporary_object( static_cast(expr)=new_symbol.symbol_expr(); } -/*******************************************************************\ - -Function: goto_convertt::remove_statement_expression - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::remove_statement_expression( side_effect_exprt &expr, goto_programt &dest, @@ -683,7 +554,7 @@ void goto_convertt::remove_statement_expression( // This is a gcc extension of the form ({ ....; expr; }) // The value is that of the final expression. // The expression is copied into a temporary before the - // scope is destoyed. + // scope is destroyed. if(expr.operands().size()!=1) { @@ -765,18 +636,6 @@ void goto_convertt::remove_statement_expression( static_cast(expr)=tmp_symbol_expr; } -/*******************************************************************\ - -Function: goto_convertt::remove_push_catch - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::remove_push_catch( side_effect_exprt &expr, goto_programt &dest) @@ -788,18 +647,6 @@ void goto_convertt::remove_push_catch( expr.make_nil(); } -/*******************************************************************\ - -Function: goto_convertt::remove_side_effect - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_convertt::remove_side_effect( side_effect_exprt &expr, goto_programt &dest, diff --git a/src/goto-programs/goto_functions.cpp b/src/goto-programs/goto_functions.cpp index d11868339b3..9c14c8bc6bc 100644 --- a/src/goto-programs/goto_functions.cpp +++ b/src/goto-programs/goto_functions.cpp @@ -8,19 +8,10 @@ Date: June 2003 \*******************************************************************/ -#include "goto_functions.h" - -/*******************************************************************\ - -Function: get_local_identifiers - - Inputs: +/// \file +/// Goto Programs with Functions - Outputs: - - Purpose: - -\*******************************************************************/ +#include "goto_functions.h" void get_local_identifiers( const goto_function_templatet &goto_function, diff --git a/src/goto-programs/goto_functions.h b/src/goto-programs/goto_functions.h index 096fab391ec..7fc9f70628a 100644 --- a/src/goto-programs/goto_functions.h +++ b/src/goto-programs/goto_functions.h @@ -8,6 +8,9 @@ Date: June 2003 \*******************************************************************/ +/// \file +/// Goto Programs with Functions + #ifndef CPROVER_GOTO_PROGRAMS_GOTO_FUNCTIONS_H #define CPROVER_GOTO_PROGRAMS_GOTO_FUNCTIONS_H diff --git a/src/goto-programs/goto_functions_template.h b/src/goto-programs/goto_functions_template.h index 9333cce06b3..3ea7a7bad83 100644 --- a/src/goto-programs/goto_functions_template.h +++ b/src/goto-programs/goto_functions_template.h @@ -8,6 +8,9 @@ Date: June 2003 \*******************************************************************/ +/// \file +/// Goto Programs with Functions + #ifndef CPROVER_GOTO_PROGRAMS_GOTO_FUNCTIONS_TEMPLATE_H #define CPROVER_GOTO_PROGRAMS_GOTO_FUNCTIONS_TEMPLATE_H @@ -158,18 +161,6 @@ class goto_functions_templatet } }; -/*******************************************************************\ - -Function: goto_functions_templatet::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void goto_functions_templatet::output( const namespacet &ns, @@ -190,18 +181,6 @@ void goto_functions_templatet::output( } } -/*******************************************************************\ - -Function: goto_functions_templatet::compute_location_numbers - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void goto_functions_templatet::compute_location_numbers() { @@ -214,18 +193,6 @@ void goto_functions_templatet::compute_location_numbers() it->second.body.compute_location_numbers(nr); } -/*******************************************************************\ - -Function: goto_functions_templatet::compute_incoming_edges - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void goto_functions_templatet::compute_incoming_edges() { @@ -236,18 +203,6 @@ void goto_functions_templatet::compute_incoming_edges() it->second.body.compute_incoming_edges(); } -/*******************************************************************\ - -Function: goto_functions_templatet::compute_target_numbers - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void goto_functions_templatet::compute_target_numbers() { @@ -258,18 +213,6 @@ void goto_functions_templatet::compute_target_numbers() it->second.body.compute_target_numbers(); } -/*******************************************************************\ - -Function: goto_functions_templatet::compute_loop_numbers - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void goto_functions_templatet::compute_loop_numbers() { diff --git a/src/goto-programs/goto_inline.cpp b/src/goto-programs/goto_inline.cpp index 01c0f1bf392..49aca830b3b 100644 --- a/src/goto-programs/goto_inline.cpp +++ b/src/goto-programs/goto_inline.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Function Inlining + +#include "goto_inline.h" + #include #include @@ -15,21 +20,8 @@ Author: Daniel Kroening, kroening@kroening.com #include #include "remove_skip.h" -#include "goto_inline.h" #include "goto_inline_class.h" -/*******************************************************************\ - -Function: goto_inline - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_inline( goto_modelt &goto_model, message_handlert &message_handler, @@ -43,18 +35,6 @@ void goto_inline( adjust_function); } -/*******************************************************************\ - -Function: goto_inline - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_inline( goto_functionst &goto_functions, const namespacet &ns, @@ -118,28 +98,13 @@ void goto_inline( } } -/*******************************************************************\ - -Function: goto_partial_inline - - Inputs: - goto_model: - Source of the symbol table and function map to use. - message_handler: - Message handler used by goto_inlinet. - smallfunc_limit: - The maximum number of instructions in functions to be inlined. - adjust_function: - Tell goto_inlinet to adjust function. - - Outputs: - - Purpose: - Inline all function calls to functions either marked as "inlined" or - smaller than smallfunc_limit (by instruction count). - -\*******************************************************************/ - +/// Inline all function calls to functions either marked as "inlined" or +/// smaller than smallfunc_limit (by instruction count). +/// \param goto_model: Source of the symbol table and function map to use. +/// \param message_handler: Message handler used by goto_inlinet. +/// \param smallfunc_limit: The maximum number of instructions in functions to +/// be inlined. +/// \param adjust_function: Tell goto_inlinet to adjust function. void goto_partial_inline( goto_modelt &goto_model, message_handlert &message_handler, @@ -155,31 +120,15 @@ void goto_partial_inline( adjust_function); } -/*******************************************************************\ - -Function: goto_partial_inline - - Inputs: - goto_functions: - The function map to use to find functions containing calls and function - bodies. - ns: - Namespace used by goto_inlinet. - message_handler: - Message handler used by goto_inlinet. - smallfunc_limit: - The maximum number of instructions in functions to be inlined. - adjust_function: - Tell goto_inlinet to adjust function. - - Outputs: - - Purpose: - Inline all function calls to functions either marked as "inlined" or - smaller than smallfunc_limit (by instruction count). - -\*******************************************************************/ - +/// Inline all function calls to functions either marked as "inlined" or +/// smaller than smallfunc_limit (by instruction count). +/// \param goto_functions: The function map to use to find functions containing +/// calls and function bodies. +/// \param ns: Namespace used by goto_inlinet. +/// \param message_handler: Message handler used by goto_inlinet. +/// \param smallfunc_limit: The maximum number of instructions in functions to +/// be inlined. +/// \param adjust_function: Tell goto_inlinet to adjust function. void goto_partial_inline( goto_functionst &goto_functions, const namespacet &ns, @@ -259,24 +208,12 @@ void goto_partial_inline( goto_inline.goto_inline(inline_map, false); } -/*******************************************************************\ - -Function: goto_function_inline - - Inputs: - goto_model: Source of the symbol table and function map to use. - function: The function whose calls to inline. - message_handler: Message handler used by goto_inlinet. - adjust_function: Tell goto_inlinet to adjust function. - caching: Tell goto_inlinet to cache. - - Outputs: - - Purpose: - Inline all function calls made from a particular function - -\*******************************************************************/ - +/// Inline all function calls made from a particular function +/// \param goto_model: Source of the symbol table and function map to use. +/// \param function: The function whose calls to inline. +/// \param message_handler: Message handler used by goto_inlinet. +/// \param adjust_function: Tell goto_inlinet to adjust function. +/// \param caching: Tell goto_inlinet to cache. void goto_function_inline( goto_modelt &goto_model, const irep_idt function, @@ -294,25 +231,13 @@ void goto_function_inline( caching); } -/*******************************************************************\ - -Function: goto_function_inline - - Inputs: - goto_functions: The function map to use to find function bodies. - function: The function whose calls to inline. - ns: Namespace used by goto_inlinet. - message_handler: Message handler used by goto_inlinet. - adjust_function: Tell goto_inlinet to adjust function. - caching: Tell goto_inlinet to cache. - - Outputs: - - Purpose: - Inline all function calls made from a particular function - -\*******************************************************************/ - +/// Inline all function calls made from a particular function +/// \param goto_functions: The function map to use to find function bodies. +/// \param function: The function whose calls to inline. +/// \param ns: Namespace used by goto_inlinet. +/// \param message_handler: Message handler used by goto_inlinet. +/// \param adjust_function: Tell goto_inlinet to adjust function. +/// \param caching: Tell goto_inlinet to cache. void goto_function_inline( goto_functionst &goto_functions, const irep_idt function, @@ -357,18 +282,6 @@ void goto_function_inline( goto_inline.goto_inline(function, goto_function, inline_map, true); } -/*******************************************************************\ - -Function: goto_function_inline_and_log - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - jsont goto_function_inline_and_log( goto_functionst &goto_functions, const irep_idt function, diff --git a/src/goto-programs/goto_inline.h b/src/goto-programs/goto_inline.h index 5d3dd54fa6d..3319aa36172 100644 --- a/src/goto-programs/goto_inline.h +++ b/src/goto-programs/goto_inline.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Function Inlining + #ifndef CPROVER_GOTO_PROGRAMS_GOTO_INLINE_H #define CPROVER_GOTO_PROGRAMS_GOTO_INLINE_H diff --git a/src/goto-programs/goto_inline_class.cpp b/src/goto-programs/goto_inline_class.cpp index f7c8e4509af..355c25d6d21 100644 --- a/src/goto-programs/goto_inline_class.cpp +++ b/src/goto-programs/goto_inline_class.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Function Inlining + +#include "goto_inline_class.h" + #ifdef DEBUG #include #endif @@ -21,19 +26,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "remove_skip.h" #include "goto_inline.h" -#include "goto_inline_class.h" - -/*******************************************************************\ - -Function: goto_inlinet::parameter_assignments - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ void goto_inlinet::parameter_assignments( const goto_programt::targett target, @@ -66,7 +58,7 @@ void goto_inlinet::parameter_assignments( const irep_idt &identifier=parameter.get_identifier(); - if(identifier==irep_idt()) + if(identifier.empty()) { error().source_location=source_location; error() << "no identifier for function parameter" << eom; @@ -167,18 +159,6 @@ void goto_inlinet::parameter_assignments( } } -/*******************************************************************\ - -Function: goto_inlinet::parameter_destruction - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_inlinet::parameter_destruction( const goto_programt::targett target, const irep_idt &function_name, // name of called function @@ -203,7 +183,7 @@ void goto_inlinet::parameter_destruction( const irep_idt &identifier=parameter.get_identifier(); - if(identifier==irep_idt()) + if(identifier.empty()) { error().source_location=source_location; error() << "no identifier for function parameter" << eom; @@ -223,18 +203,6 @@ void goto_inlinet::parameter_destruction( } } -/*******************************************************************\ - -Function: goto_inlinet::replace_return - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_inlinet::replace_return( goto_programt &dest, // inlining this const exprt &lhs, // lhs in caller @@ -348,18 +316,6 @@ void goto_inlinet::replace_return( } } -/*******************************************************************\ - -Function: replace_location - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void replace_location( source_locationt &dest, const source_locationt &new_location) @@ -373,28 +329,16 @@ void replace_location( dest=new_location; - if(comment!=irep_idt()) + if(!comment.empty()) dest.set_comment(comment); - if(property_class!=irep_idt()) + if(!property_class.empty()) dest.set_property_class(property_class); - if(property_id!=irep_idt()) + if(!property_id.empty()) dest.set_property_id(property_id); } -/*******************************************************************\ - -Function: replace_location - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void replace_location( exprt &dest, const source_locationt &new_location) @@ -406,18 +350,6 @@ void replace_location( replace_location(dest.add_source_location(), new_location); } -/*******************************************************************\ - -Function: goto_inlinet::insert_function_body - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_inlinet::insert_function_body( const goto_functiont &goto_function, goto_programt &dest, @@ -519,18 +451,6 @@ void goto_inlinet::insert_function_body( dest.destructive_insert(target, tmp); } -/*******************************************************************\ - -Function: goto_inlinet::insert_function_nobody - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_inlinet::insert_function_nobody( goto_programt &dest, const exprt &lhs, @@ -584,18 +504,6 @@ void goto_inlinet::insert_function_nobody( dest.destructive_insert(target, tmp); } -/*******************************************************************\ - -Function: goto_inlinet::expand_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_inlinet::expand_function_call( goto_programt &dest, const inline_mapt &inline_map, @@ -608,7 +516,7 @@ void goto_inlinet::expand_function_call( assert(!transitive || inline_map.empty()); #ifdef DEBUG - std::cout << "Expanding call:" << std::endl; + std::cout << "Expanding call:\n"; dest.output_instruction(ns, "", std::cout, target); #endif @@ -721,18 +629,6 @@ void goto_inlinet::expand_function_call( } } -/*******************************************************************\ - -Function: goto_inlinet::get_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_inlinet::get_call( goto_programt::const_targett it, exprt &lhs, @@ -762,35 +658,11 @@ void goto_inlinet::get_call( } } -/*******************************************************************\ - -Function: goto_inlinet::is_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool goto_inlinet::is_call(goto_programt::const_targett it) { return it->is_function_call() || is_bp_call(it); } -/*******************************************************************\ - -Function: goto_inlinet::is_bp_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool goto_inlinet::is_bp_call(goto_programt::const_targett it) { if(!it->is_other()) @@ -802,18 +674,6 @@ bool goto_inlinet::is_bp_call(goto_programt::const_targett it) it->code.op0().op1().get(ID_statement)==ID_function_call; } -/*******************************************************************\ - -Function: goto_inline - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_inlinet::goto_inline( const inline_mapt &inline_map, const bool force_full) @@ -833,18 +693,6 @@ void goto_inlinet::goto_inline( } } -/*******************************************************************\ - -Function: goto_inline - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_inlinet::goto_inline( const irep_idt identifier, goto_functiont &goto_function, @@ -860,18 +708,6 @@ void goto_inlinet::goto_inline( force_full); } -/*******************************************************************\ - -Function: goto_inline - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_inlinet::goto_inline_nontransitive( const irep_idt identifier, goto_functiont &goto_function, @@ -926,18 +762,6 @@ void goto_inlinet::goto_inline_nontransitive( finished_set.insert(identifier); } -/*******************************************************************\ - -Function: goto_inline_transitive - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const goto_inlinet::goto_functiont &goto_inlinet::goto_inline_transitive( const irep_idt identifier, const goto_functiont &goto_function, @@ -999,18 +823,6 @@ const goto_inlinet::goto_functiont &goto_inlinet::goto_inline_transitive( return cached; } -/*******************************************************************\ - -Function: is_ignored - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool goto_inlinet::is_ignored(const irep_idt id) const { return @@ -1022,18 +834,6 @@ bool goto_inlinet::is_ignored(const irep_idt id) const id=="__CPROVER_cover"; } -/*******************************************************************\ - -Function: check_inline_map - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool goto_inlinet::check_inline_map( const irep_idt identifier, const inline_mapt &inline_map) const @@ -1080,18 +880,6 @@ bool goto_inlinet::check_inline_map( return true; } -/*******************************************************************\ - -Function: check_inline_map - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool goto_inlinet::check_inline_map(const inline_mapt &inline_map) const { forall_goto_functions(f_it, goto_functions) @@ -1103,18 +891,6 @@ bool goto_inlinet::check_inline_map(const inline_mapt &inline_map) const return true; } -/*******************************************************************\ - -Function: output_inline_map - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_inlinet::output_inline_map( std::ostream &out, const inline_mapt &inline_map) @@ -1161,18 +937,6 @@ void goto_inlinet::output_inline_map( } } -/*******************************************************************\ - -Function: output_cache - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_inlinet::output_cache(std::ostream &out) const { for(auto it=cache.begin(); it!=cache.end(); it++) @@ -1184,18 +948,6 @@ void goto_inlinet::output_cache(std::ostream &out) const } } -/*******************************************************************\ - -Function: cleanup - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - // remove segment that refer to the given goto program void goto_inlinet::goto_inline_logt::cleanup( const goto_programt &goto_program) @@ -1204,18 +956,6 @@ void goto_inlinet::goto_inline_logt::cleanup( log_map.erase(it); } -/*******************************************************************\ - -Function: cleanup - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_inlinet::goto_inline_logt::cleanup( const goto_functionst::function_mapt &function_map) { @@ -1231,18 +971,6 @@ void goto_inlinet::goto_inline_logt::cleanup( } } -/*******************************************************************\ - -Function: add_segment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_inlinet::goto_inline_logt::add_segment( const goto_programt &goto_program, const unsigned begin_location_number, @@ -1270,18 +998,6 @@ void goto_inlinet::goto_inline_logt::add_segment( log_map[start]=info; } -/*******************************************************************\ - -Function: copy_from - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_inlinet::goto_inline_logt::copy_from( const goto_programt &from, const goto_programt &to) @@ -1321,18 +1037,6 @@ void goto_inlinet::goto_inline_logt::copy_from( } } -/*******************************************************************\ - -Function: output_inline_log_json - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - // call after goto_functions.update()! jsont goto_inlinet::goto_inline_logt::output_inline_log_json() const { diff --git a/src/goto-programs/goto_inline_class.h b/src/goto-programs/goto_inline_class.h index e043bf48807..c2356759e40 100644 --- a/src/goto-programs/goto_inline_class.h +++ b/src/goto-programs/goto_inline_class.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_GOTO_PROGRAMS_GOTO_INLINE_CLASS_H #define CPROVER_GOTO_PROGRAMS_GOTO_INLINE_CLASS_H diff --git a/src/goto-programs/goto_model.h b/src/goto-programs/goto_model.h index 37b491dc996..6e9ebbc6f37 100644 --- a/src/goto-programs/goto_model.h +++ b/src/goto-programs/goto_model.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symbol Table + CFG + #ifndef CPROVER_GOTO_PROGRAMS_GOTO_MODEL_H #define CPROVER_GOTO_PROGRAMS_GOTO_MODEL_H diff --git a/src/goto-programs/goto_program.cpp b/src/goto-programs/goto_program.cpp index c1b72dc7bbf..e6055e98b3a 100644 --- a/src/goto-programs/goto_program.cpp +++ b/src/goto-programs/goto_program.cpp @@ -6,31 +6,24 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - -#include - -#include +/// \file +/// Program Transformation #include "goto_program.h" -/*******************************************************************\ - -Function: goto_programt::output_instruction - - Inputs: - ns - the namespace to resolve the expressions in - identifier - the identifier used to find a symbol to identify the - source language - out - the stream to write the goto string to - it - an iterator pointing to the instruction to convert - - Outputs: See below. +#include - Purpose: See below. +#include -\*******************************************************************/ +#include +/// See below. +/// \param ns: the namespace to resolve the expressions in +/// \param identifier: the identifier used to find a symbol to identify the +/// source language +/// \param out: the stream to write the goto string to +/// \param it: an iterator pointing to the instruction to convert +/// \return See below. std::ostream &goto_programt::output_instruction( const class namespacet &ns, const irep_idt &identifier, @@ -40,26 +33,19 @@ std::ostream &goto_programt::output_instruction( return output_instruction(ns, identifier, out, *it); } -/*******************************************************************\ - -Function: goto_programt::output_instruction - - Inputs: - ns - the namespace to resolve the expressions in - identifier - the identifier used to find a symbol to identify the - source language - out - the stream to write the goto string to - instruction - the instruction to convert - - Outputs: Appends to out a two line representation of the instruction - - Purpose: Writes to out a two line string representation of the specific - instruction. It is of the format: - // {location} file {source file} line {line in source file} - {representation of the instruction} - -\*******************************************************************/ - +/// Writes to \p out a two/three line string representation of a given +/// \p instruction. The output is of the format: +/// ``` +/// // {location} file {source file} line {line in source file} +/// // Labels: {list-of-labels} +/// {representation of the instruction} +/// ``` +/// \param ns: the namespace to resolve the expressions in +/// \param identifier: the identifier used to find a symbol to identify the +/// source language +/// \param out: the stream to write the goto string to +/// \param instruction: the instruction to convert +/// \return Appends to out a two line representation of the instruction std::ostream &goto_programt::output_instruction( const namespacet &ns, const irep_idt &identifier, @@ -229,18 +215,6 @@ std::ostream &goto_programt::output_instruction( return out; } -/*******************************************************************\ - -Function: goto_programt::get_decl_identifiers - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_programt::get_decl_identifiers( decl_identifierst &decl_identifiers) const { @@ -256,18 +230,6 @@ void goto_programt::get_decl_identifiers( } } -/*******************************************************************\ - -Function: parse_lhs_read - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void parse_lhs_read(const exprt &src, std::list &dest) { if(src.id()==ID_dereference) @@ -295,18 +257,6 @@ void parse_lhs_read(const exprt &src, std::list &dest) } } -/*******************************************************************\ - -Function: expressions_read - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::list expressions_read( const goto_programt::instructiont &instruction) { @@ -352,18 +302,6 @@ std::list expressions_read( return dest; } -/*******************************************************************\ - -Function: expressions_written - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::list expressions_written( const goto_programt::instructiont &instruction) { @@ -392,18 +330,6 @@ std::list expressions_written( return dest; } -/*******************************************************************\ - -Function: get_objects_read - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void objects_read( const exprt &src, std::list &dest) @@ -428,18 +354,6 @@ void objects_read( } } -/*******************************************************************\ - -Function: objects_read - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::list objects_read( const goto_programt::instructiont &instruction) { @@ -453,18 +367,6 @@ std::list objects_read( return dest; } -/*******************************************************************\ - -Function: objects_written - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void objects_written( const exprt &src, std::list &dest) @@ -479,18 +381,6 @@ void objects_written( dest.push_back(src); } -/*******************************************************************\ - -Function: objects_written - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::list objects_written( const goto_programt::instructiont &instruction) { @@ -504,18 +394,6 @@ std::list objects_written( return dest; } -/*******************************************************************\ - -Function: as_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string as_string( const class namespacet &ns, const goto_programt::instructiont &i) @@ -606,6 +484,4 @@ std::string as_string( default: throw "unknown statement"; } - - return ""; } diff --git a/src/goto-programs/goto_program.h b/src/goto-programs/goto_program.h index a4abbb8355b..02b8b10f599 100644 --- a/src/goto-programs/goto_program.h +++ b/src/goto-programs/goto_program.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Concrete Goto Program + #ifndef CPROVER_GOTO_PROGRAMS_GOTO_PROGRAM_H #define CPROVER_GOTO_PROGRAMS_GOTO_PROGRAM_H @@ -17,7 +20,6 @@ Author: Daniel Kroening, kroening@kroening.com /*! \brief A specialization of goto_program_templatet over goto programs in which instructions have codet type. - \ingroup gr_goto_programs */ class goto_programt:public goto_program_templatet { @@ -93,13 +95,7 @@ std::string as_string( const namespacet &ns, const goto_programt::instructiont &); -/*******************************************************************\ - Class: instruction_iterator_hashert - - Purpose: - Function class to get hash of GOTO program instruction iterator - -\*******************************************************************/ +/// Function class to get hash of GOTO program instruction iterator class instruction_iterator_hashert { public: diff --git a/src/goto-programs/goto_program_irep.cpp b/src/goto-programs/goto_program_irep.cpp index 3ddc09e27a3..91ffd45065b 100644 --- a/src/goto-programs/goto_program_irep.cpp +++ b/src/goto-programs/goto_program_irep.cpp @@ -8,23 +8,14 @@ Date: May 2007 \*******************************************************************/ -#include - -#include +/// \file +/// goto_programt -> irep conversion #include "goto_program_irep.h" -/*******************************************************************\ - -Function: convert - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include void convert(const goto_programt::instructiont &instruction, irept &irep) { @@ -62,18 +53,6 @@ void convert(const goto_programt::instructiont &instruction, irept &irep) } } -/*******************************************************************\ - -Function: convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void convert( const irept &irep, goto_programt::instructiont &instruction) @@ -94,18 +73,6 @@ void convert( instruction.labels.push_back(lsub.id()); } -/*******************************************************************\ - -Function: convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void convert(const goto_programt &program, irept &irep) { irep.id("goto-program"); @@ -117,18 +84,6 @@ void convert(const goto_programt &program, irept &irep) } } -/*******************************************************************\ - -Function: convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void convert(const irept &irep, goto_programt &program) { assert(irep.id()=="goto-program"); @@ -179,7 +134,7 @@ void convert(const irept &irep, goto_programt &program) if(fit==program.instructions.end()) { std::cout << "Warning: could not resolve target link " - << "during irep->goto_program translation." << std::endl; + << "during irep->goto_program translation.\n"; throw 0; } } diff --git a/src/goto-programs/goto_program_irep.h b/src/goto-programs/goto_program_irep.h index aef5c1f9f0a..4659e62f9d4 100644 --- a/src/goto-programs/goto_program_irep.h +++ b/src/goto-programs/goto_program_irep.h @@ -8,6 +8,9 @@ Date: May 2007 \*******************************************************************/ +/// \file +/// goto_programt -> irep conversion + #ifndef CPROVER_GOTO_PROGRAMS_GOTO_PROGRAM_IREP_H #define CPROVER_GOTO_PROGRAMS_GOTO_PROGRAM_IREP_H diff --git a/src/goto-programs/goto_program_template.cpp b/src/goto-programs/goto_program_template.cpp index 80fc9089c74..89b310c8d01 100644 --- a/src/goto-programs/goto_program_template.cpp +++ b/src/goto-programs/goto_program_template.cpp @@ -6,21 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Goto Program Template #include "goto_program_template.h" -/*******************************************************************\ - -Function: operator<< - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include std::ostream &operator<<(std::ostream &out, goto_program_instruction_typet t) { diff --git a/src/goto-programs/goto_program_template.h b/src/goto-programs/goto_program_template.h index dd6e0ae74b3..742875aa0ab 100644 --- a/src/goto-programs/goto_program_template.h +++ b/src/goto-programs/goto_program_template.h @@ -6,11 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Goto Program Template + #ifndef CPROVER_GOTO_PROGRAMS_GOTO_PROGRAM_TEMPLATE_H #define CPROVER_GOTO_PROGRAMS_GOTO_PROGRAM_TEMPLATE_H -/*! \defgroup gr_goto_programs Goto programs */ - #include #include #include @@ -23,7 +24,8 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -typedef enum +/// The type of an instruction in a GOTO program. +enum goto_program_instruction_typet { NO_INSTRUCTION_TYPE=0, GOTO=1, // branch, possibly guarded @@ -44,19 +46,30 @@ typedef enum FUNCTION_CALL=16, // call a function THROW=17, // throw an exception CATCH=18 // catch an exception -} goto_program_instruction_typet; +}; std::ostream &operator<<(std::ostream &, goto_program_instruction_typet); -/*! \brief A generic container class for a control flow graph - for one function, in the form of a goto-program - \ingroup gr_goto_programs -*/ +/// A generic container class for the GOTO intermediate representation of one +/// function. +/// +/// A function is represented by a std::list of instructions. Execution starts +/// in the first instruction of the list. Then, the execution of the i-th +/// instruction is followed by the execution of the (i+1)-th instruction unless +/// instruction i jumps to some other instruction in the list. See the internal +/// class instructiont for additional details +/// +/// Although it is straightforward to compute the control flow graph (CFG) of a +/// function from the list of instructions and the goto target locations in +/// instructions, the GOTO intermediate representation is _not_ regarded as the +/// CFG of a function. See instead the class cfg_baset, which is based on grapht +/// and allows for easier implementation of generic graph algorithms (e.g., +/// dominator analysis). template class goto_program_templatet { public: - // Copying is deleted as this class contains pointers that cannot be copied + /// Copying is deleted as this class contains pointers that cannot be copied goto_program_templatet(const goto_program_templatet &)=delete; goto_program_templatet &operator=(const goto_program_templatet &)=delete; @@ -77,60 +90,127 @@ class goto_program_templatet return *this; } - /*! \brief Container for an instruction of the goto-program - */ + /// This class represents an instruction in the GOTO intermediate + /// representation. Three fields are key: + /// + /// - type: an enum value describing the action performed by this instruction + /// - guard: an (arbitrarily complex) expression (usually an \ref exprt) of + /// Boolean type + /// - code: a code statement (usually a \ref codet) + /// + /// The meaning of an instruction node depends on the `type` field. Different + /// kinds of instructions make use of the fields `guard` and `code` for + /// different purposes. We list below, using a mixture of pseudo code and + /// plain English, the meaning of different kinds of instructions. + /// We use `guard`, `code`, and `targets` to mean the value of the + /// respective fields in this class: + /// + /// - GOTO: + /// if `guard` then goto `targets` + /// - RETURN: + /// Set the value returned by `code` (which shall be either nil or an + /// instance of code_returnt) and then jump to the end of the function. + /// - DECL: + /// Introduces a symbol denoted by the field `code` (an instance of + /// code_declt), the life-time of which is bounded by a corresponding DEAD + /// instruction. + /// - FUNCTION_CALL: + /// Invoke the function denoted by field `code` (an instance of + /// code_function_callt). + /// - ASSIGN: + /// Update the left-hand side of `code` (an instance of code_assignt) to + /// the value of the right-hand side. + /// - OTHER: + /// Execute the `code` (an instance of codet of kind ID_fence, ID_printf, + /// ID_array_copy, ID_array_set, ID_input, ID_output, ...). + /// - ASSUME: + /// Wait for `guard` to evaluate to true. + /// - ASSERT: + /// Using ASSERT instructions is the one and only way to express + /// properties to be verified. Execution paths abort if `guard` evaluates + /// to false. + /// - SKIP, LOCATION: + /// No-op. + /// - ATOMIC_BEGIN, ATOMIC_END: + /// When a thread executes ATOMIC_BEGIN, no thread other will be able to + /// execute any instruction until the same thread executes ATOMIC_END. + /// - END_FUNCTION: + /// Can only occur as the last instruction of the list. + /// - START_THREAD: + /// Create a new thread and run the code of this function starting from + /// targets[0]. Quite often the instruction pointed by targets[0] will be + /// just a FUNCTION_CALL, followed by an END_THREAD. + /// - END_THREAD: + /// Terminate the calling thread. + /// - THROW: + /// throw `exception1`, ..., `exceptionN` + /// where the list of exceptions is extracted from the `code` field + /// - CATCH, when code.find(ID_exception_list) is non-empty: + /// Establishes that from here to the next occurrence of CATCH with an + /// empty list (see below) if + /// - `exception1` is thrown, then goto `target1`, + /// - ... + /// - `exceptionN` is thrown, then goto `targetN`. + /// The list of exceptions is obtained from the `code` field and the list + /// of targets from the `targets` field. + /// - CATCH, when empty code.find(ID_exception_list) is empty: + /// clears all the catch clauses established as per the above in this + /// function? class instructiont { public: codeT code; - //! function this belongs to + /// The function this instruction belongs to irep_idt function; - //! the location of the instruction in the source file + /// The location of the instruction in the source file source_locationt source_location; - //! what kind of instruction? + /// What kind of instruction? goto_program_instruction_typet type; - //! guard for gotos, assume, assert + /// Guard for gotos, assume, assert guardT guard; // The below will eventually become a single target only. - //! the target for gotos and for start_thread nodes + /// The target for gotos and for start_thread nodes typedef typename std::list::iterator targett; typedef typename std::list::const_iterator const_targett; typedef std::list targetst; typedef std::list const_targetst; + /// The list of successor instructions targetst targets; - // for the usual case of a single target + /// Returns the first (and only) successor for the usual case of a single + /// target targett get_target() const { assert(targets.size()==1); return targets.front(); } - // for the usual case of a single target + /// Sets the first (and only) successor for the usual case of a single + /// target void set_target(targett t) { targets.clear(); targets.push_back(t); } - //! goto target labels + /// Goto target labels typedef std::list labelst; labelst labels; // will go away std::set incoming_edges; - //! is this node a branch target? + /// Is this node a branch target? bool is_target() const { return target_number!=nil_target; } - //! clear the node + /// Clear the node void clear(goto_program_instruction_typet _type) { type=_type; @@ -142,6 +222,8 @@ class goto_program_templatet void make_goto() { clear(GOTO); } void make_return() { clear(RETURN); } void make_skip() { clear(SKIP); } + void make_location(const source_locationt &l) + { clear(LOCATION); source_location=l; } void make_throw() { clear(THROW); } void make_catch() { clear(CATCH); } void make_assertion(const guardT &g) { clear(ASSERT); guard=g; } @@ -205,7 +287,7 @@ class goto_program_templatet { } - //! swap two instructions + /// Swap two instructions void swap(instructiont &instruction) { using std::swap; @@ -217,30 +299,30 @@ class goto_program_templatet swap(instruction.function, function); } - //! Uniquely identify an invalid target or location #if (defined _MSC_VER && _MSC_VER <= 1800) // Visual Studio <= 2013 does not support constexpr, making // numeric_limits::max() unviable for a static const member static const unsigned nil_target= static_cast(-1); #else + /// Uniquely identify an invalid target or location static const unsigned nil_target= std::numeric_limits::max(); #endif - //! A globally unique number to identify a program location. - //! It's guaranteed to be ordered in program order within - //! one goto_program. + /// A globally unique number to identify a program location. + /// It's guaranteed to be ordered in program order within + /// one goto_program. unsigned location_number; - //! Number unique per function to identify loops + /// Number unique per function to identify loops unsigned loop_number; - //! A number to identify branch targets. - //! This is \ref nil_target if it's not a target. + /// A number to identify branch targets. + /// This is \ref nil_target if it's not a target. unsigned target_number; - //! Returns true if the instruction is a backwards branch. + /// Returns true if the instruction is a backwards branch. bool is_backwards_goto() const { if(!is_goto()) @@ -268,17 +350,17 @@ class goto_program_templatet typedef typename std::list targetst; typedef typename std::list const_targetst; - //! The list of instructions in the goto program + /// The list of instructions in the goto program instructionst instructions; - // Convert a const_targett to a targett - use with care and avoid - // whenever possible + /// Convert a const_targett to a targett - use with care and avoid + /// whenever possible targett const_cast_target(const_targett t) { return instructions.erase(t, t); } - // Dummy for templates with possible const contexts + /// Dummy for templates with possible const contexts const_targett const_cast_target(const_targett t) const { return t; @@ -306,7 +388,7 @@ class goto_program_templatet void compute_incoming_edges(); - //! Insertion that preserves jumps to "target". + /// Insertion that preserves jumps to "target". void insert_before_swap(targett target) { assert(target!=instructions.end()); @@ -314,16 +396,16 @@ class goto_program_templatet instructions.insert(next, instructiont())->swap(*target); } - //! Insertion that preserves jumps to "target". - //! The instruction is destroyed. + /// Insertion that preserves jumps to "target". + /// The instruction is destroyed. void insert_before_swap(targett target, instructiont &instruction) { insert_before_swap(target); target->swap(instruction); } - //! Insertion that preserves jumps to "target". - //! The program p is destroyed. + /// Insertion that preserves jumps to "target". + /// The program p is destroyed. void insert_before_swap( targett target, goto_program_templatet &p) @@ -337,21 +419,21 @@ class goto_program_templatet instructions.splice(next, p.instructions); } - //! Insertion before the given target - //! \return newly inserted location + /// Insertion before the given target + /// \return newly inserted location targett insert_before(const_targett target) { return instructions.insert(target, instructiont()); } - //! Insertion after the given target - //! \return newly inserted location + /// Insertion after the given target + /// \return newly inserted location targett insert_after(const_targett target) { return instructions.insert(std::next(target), instructiont()); } - //! Appends the given program, which is destroyed + /// Appends the given program, which is destroyed void destructive_append(goto_program_templatet &p) { instructions.splice(instructions.end(), @@ -359,8 +441,8 @@ class goto_program_templatet // BUG: The iterators to p-instructions are invalidated! } - //! Inserts the given program at the given location. - //! The program is destroyed. + /// Inserts the given program at the given location. + /// The program is destroyed. void destructive_insert( const_targett target, goto_program_templatet &p) @@ -369,78 +451,78 @@ class goto_program_templatet // BUG: The iterators to p-instructions are invalidated! } - //! Adds an instruction at the end. - //! \return The newly added instruction. + /// Adds an instruction at the end. + /// \return The newly added instruction. targett add_instruction() { instructions.push_back(instructiont()); return --instructions.end(); } - //! Adds an instruction of given type at the end. - //! \return The newly added instruction. + /// Adds an instruction of given type at the end. + /// \return The newly added instruction. targett add_instruction(goto_program_instruction_typet type) { instructions.push_back(instructiont(type)); return --instructions.end(); } - //! Output goto program to given stream + /// Output goto program to given stream std::ostream &output( const namespacet &ns, const irep_idt &identifier, std::ostream &out) const; - //! Output goto-program to given stream + /// Output goto-program to given stream std::ostream &output(std::ostream &out) const { return output(namespacet(symbol_tablet()), "", out); } - //! Output a single instruction + /// Output a single instruction virtual std::ostream &output_instruction( const namespacet &ns, const irep_idt &identifier, std::ostream &out, typename instructionst::const_iterator it) const=0; - //! Compute the target numbers + /// Compute the target numbers void compute_target_numbers(); - //! Compute location numbers + /// Compute location numbers void compute_location_numbers(unsigned &nr) { for(auto &i : instructions) i.location_number=nr++; } - //! Compute location numbers + /// Compute location numbers void compute_location_numbers() { unsigned nr=0; compute_location_numbers(nr); } - //! Compute loop numbers + /// Compute loop numbers void compute_loop_numbers(); - //! Update all indices + /// Update all indices void update(); - //! Human-readable loop name + /// Human-readable loop name static irep_idt loop_id(const_targett target) { return id2string(target->function)+"."+ std::to_string(target->loop_number); } - //! Is the program empty? + /// Is the program empty? bool empty() const { return instructions.empty(); } - //! Constructor + /// Constructor goto_program_templatet() { } @@ -449,13 +531,13 @@ class goto_program_templatet { } - //! Swap the goto program + /// Swap the goto program void swap(goto_program_templatet &program) { program.instructions.swap(instructions); } - //! Clear the goto program + /// Clear the goto program void clear() { instructions.clear(); @@ -469,10 +551,10 @@ class goto_program_templatet return end_function; } - //! Copy a full goto program, preserving targets + /// Copy a full goto program, preserving targets void copy_from(const goto_program_templatet &src); - //! Does the goto program have an assertion? + /// Does the goto program have an assertion? bool has_assertion() const; }; diff --git a/src/goto-programs/goto_trace.cpp b/src/goto-programs/goto_trace.cpp index ad8bdcdfdd9..ddea10e38d2 100644 --- a/src/goto-programs/goto_trace.cpp +++ b/src/goto-programs/goto_trace.cpp @@ -8,6 +8,11 @@ Author: Daniel Kroening \*******************************************************************/ +/// \file +/// Traces of GOTO Programs + +#include "goto_trace.h" + #include #include @@ -17,20 +22,6 @@ Author: Daniel Kroening #include #include -#include "goto_trace.h" - -/*******************************************************************\ - -Function: goto_tracet::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_tracet::output( const class namespacet &ns, std::ostream &out) const @@ -39,18 +30,6 @@ void goto_tracet::output( step.output(ns, out); } -/*******************************************************************\ - -Function: goto_tracet::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_trace_stept::output( const namespacet &ns, std::ostream &out) const @@ -59,24 +38,25 @@ void goto_trace_stept::output( switch(type) { - case goto_trace_stept::ASSERT: out << "ASSERT"; break; - case goto_trace_stept::ASSUME: out << "ASSUME"; break; - case goto_trace_stept::LOCATION: out << "LOCATION"; break; - case goto_trace_stept::ASSIGNMENT: out << "ASSIGNMENT"; break; - case goto_trace_stept::GOTO: out << "GOTO"; break; - case goto_trace_stept::DECL: out << "DECL"; break; - case goto_trace_stept::OUTPUT: out << "OUTPUT"; break; - case goto_trace_stept::INPUT: out << "INPUT"; break; - case goto_trace_stept::ATOMIC_BEGIN: out << "ATOMC_BEGIN"; break; - case goto_trace_stept::ATOMIC_END: out << "ATOMIC_END"; break; - case goto_trace_stept::SHARED_READ: out << "SHARED_READ"; break; - case goto_trace_stept::SHARED_WRITE: out << "SHARED WRITE"; break; - case goto_trace_stept::FUNCTION_CALL: out << "FUNCTION CALL"; break; - case goto_trace_stept::FUNCTION_RETURN: out << "FUNCTION RETURN"; break; + case goto_trace_stept::typet::ASSERT: out << "ASSERT"; break; + case goto_trace_stept::typet::ASSUME: out << "ASSUME"; break; + case goto_trace_stept::typet::LOCATION: out << "LOCATION"; break; + case goto_trace_stept::typet::ASSIGNMENT: out << "ASSIGNMENT"; break; + case goto_trace_stept::typet::GOTO: out << "GOTO"; break; + case goto_trace_stept::typet::DECL: out << "DECL"; break; + case goto_trace_stept::typet::OUTPUT: out << "OUTPUT"; break; + case goto_trace_stept::typet::INPUT: out << "INPUT"; break; + case goto_trace_stept::typet::ATOMIC_BEGIN: out << "ATOMC_BEGIN"; break; + case goto_trace_stept::typet::ATOMIC_END: out << "ATOMIC_END"; break; + case goto_trace_stept::typet::SHARED_READ: out << "SHARED_READ"; break; + case goto_trace_stept::typet::SHARED_WRITE: out << "SHARED WRITE"; break; + case goto_trace_stept::typet::FUNCTION_CALL: out << "FUNCTION CALL"; break; + case goto_trace_stept::typet::FUNCTION_RETURN: + out << "FUNCTION RETURN"; break; default: assert(false); } - if(type==ASSERT || type==ASSUME || type==GOTO) + if(type==typet::ASSERT || type==typet::ASSUME || type==typet::GOTO) out << " (" << cond_value << ")"; if(hidden) @@ -133,18 +113,6 @@ void goto_trace_stept::output( out << "\n"; } -/*******************************************************************\ - -Function: trace_value_binary - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string trace_value_binary( const exprt &expr, const namespacet &ns) @@ -208,18 +176,6 @@ std::string trace_value_binary( return "?"; } -/*******************************************************************\ - -Function: trace_value - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void trace_value( std::ostream &out, const namespacet &ns, @@ -250,18 +206,6 @@ void trace_value( << "\n"; } -/*******************************************************************\ - -Function: show_state_header - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void show_state_header( std::ostream &out, const goto_trace_stept &state, @@ -280,18 +224,6 @@ void show_state_header( out << "----------------------------------------------------" << "\n"; } -/*******************************************************************\ - -Function: is_index_member_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool is_index_member_symbol(const exprt &src) { if(src.id()==ID_index) @@ -304,18 +236,6 @@ bool is_index_member_symbol(const exprt &src) return false; } -/*******************************************************************\ - -Function: show_goto_trace - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void show_goto_trace( std::ostream &out, const namespacet &ns, @@ -332,7 +252,7 @@ void show_goto_trace( switch(step.type) { - case goto_trace_stept::ASSERT: + case goto_trace_stept::typet::ASSERT: if(!step.cond_value) { out << "\n"; @@ -348,7 +268,7 @@ void show_goto_trace( } break; - case goto_trace_stept::ASSUME: + case goto_trace_stept::typet::ASSUME: if(!step.cond_value) { out << "\n"; @@ -363,13 +283,13 @@ void show_goto_trace( } break; - case goto_trace_stept::LOCATION: + case goto_trace_stept::typet::LOCATION: break; - case goto_trace_stept::GOTO: + case goto_trace_stept::typet::GOTO: break; - case goto_trace_stept::ASSIGNMENT: + case goto_trace_stept::typet::ASSIGNMENT: if(step.pc->is_assign() || step.pc->is_return() || // returns have a lhs! step.pc->is_function_call() || @@ -392,7 +312,7 @@ void show_goto_trace( } break; - case goto_trace_stept::DECL: + case goto_trace_stept::typet::DECL: if(prev_step_nr!=step.step_nr || first_step) { first_step=false; @@ -403,7 +323,7 @@ void show_goto_trace( trace_value(out, ns, step.lhs_object, step.full_lhs, step.full_lhs_value); break; - case goto_trace_stept::OUTPUT: + case goto_trace_stept::typet::OUTPUT: if(step.formatted) { printf_formattert printf_formatter(ns); @@ -433,7 +353,7 @@ void show_goto_trace( } break; - case goto_trace_stept::INPUT: + case goto_trace_stept::typet::INPUT: show_state_header(out, step, step.pc->source_location, step.step_nr); out << " INPUT " << step.io_id << ":"; @@ -453,21 +373,21 @@ void show_goto_trace( out << "\n"; break; - case goto_trace_stept::FUNCTION_CALL: - case goto_trace_stept::FUNCTION_RETURN: - case goto_trace_stept::SPAWN: - case goto_trace_stept::MEMORY_BARRIER: - case goto_trace_stept::ATOMIC_BEGIN: - case goto_trace_stept::ATOMIC_END: - case goto_trace_stept::DEAD: + case goto_trace_stept::typet::FUNCTION_CALL: + case goto_trace_stept::typet::FUNCTION_RETURN: + case goto_trace_stept::typet::SPAWN: + case goto_trace_stept::typet::MEMORY_BARRIER: + case goto_trace_stept::typet::ATOMIC_BEGIN: + case goto_trace_stept::typet::ATOMIC_END: + case goto_trace_stept::typet::DEAD: break; - case goto_trace_stept::CONSTRAINT: + case goto_trace_stept::typet::CONSTRAINT: assert(false); break; - case goto_trace_stept::SHARED_READ: - case goto_trace_stept::SHARED_WRITE: + case goto_trace_stept::typet::SHARED_READ: + case goto_trace_stept::typet::SHARED_WRITE: assert(false); break; diff --git a/src/goto-programs/goto_trace.h b/src/goto-programs/goto_trace.h index 507d538ada0..4c8a3accc8a 100644 --- a/src/goto-programs/goto_trace.h +++ b/src/goto-programs/goto_trace.h @@ -8,6 +8,9 @@ Date: July 2005 \*******************************************************************/ +/// \file +/// Traces of GOTO Programs + #ifndef CPROVER_GOTO_PROGRAMS_GOTO_TRACE_H #define CPROVER_GOTO_PROGRAMS_GOTO_TRACE_H @@ -33,38 +36,55 @@ class goto_trace_stept public: unsigned step_nr; - bool is_assignment() const { return type==ASSIGNMENT; } - bool is_assume() const { return type==ASSUME; } - bool is_assert() const { return type==ASSERT; } - bool is_goto() const { return type==GOTO; } - bool is_constraint() const { return type==CONSTRAINT; } - bool is_function_call() const { return type==FUNCTION_CALL; } - bool is_function_return() const { return type==FUNCTION_RETURN; } - bool is_location() const { return type==LOCATION; } - bool is_output() const { return type==OUTPUT; } - bool is_input() const { return type==INPUT; } - bool is_decl() const { return type==DECL; } - bool is_dead() const { return type==DEAD; } - bool is_shared_read() const { return type==SHARED_READ; } - bool is_shared_write() const { return type==SHARED_WRITE; } - bool is_spawn() const { return type==SPAWN; } - bool is_memory_barrier() const { return type==MEMORY_BARRIER; } - bool is_atomic_begin() const { return type==ATOMIC_BEGIN; } - bool is_atomic_end() const { return type==ATOMIC_END; } - - typedef enum { NONE, ASSIGNMENT, ASSUME, ASSERT, GOTO, - LOCATION, INPUT, OUTPUT, DECL, DEAD, - FUNCTION_CALL, FUNCTION_RETURN, - CONSTRAINT, - SHARED_READ, SHARED_WRITE, - SPAWN, MEMORY_BARRIER, ATOMIC_BEGIN, ATOMIC_END } typet; + bool is_assignment() const { return type==typet::ASSIGNMENT; } + bool is_assume() const { return type==typet::ASSUME; } + bool is_assert() const { return type==typet::ASSERT; } + bool is_goto() const { return type==typet::GOTO; } + bool is_constraint() const { return type==typet::CONSTRAINT; } + bool is_function_call() const { return type==typet::FUNCTION_CALL; } + bool is_function_return() const { return type==typet::FUNCTION_RETURN; } + bool is_location() const { return type==typet::LOCATION; } + bool is_output() const { return type==typet::OUTPUT; } + bool is_input() const { return type==typet::INPUT; } + bool is_decl() const { return type==typet::DECL; } + bool is_dead() const { return type==typet::DEAD; } + bool is_shared_read() const { return type==typet::SHARED_READ; } + bool is_shared_write() const { return type==typet::SHARED_WRITE; } + bool is_spawn() const { return type==typet::SPAWN; } + bool is_memory_barrier() const { return type==typet::MEMORY_BARRIER; } + bool is_atomic_begin() const { return type==typet::ATOMIC_BEGIN; } + bool is_atomic_end() const { return type==typet::ATOMIC_END; } + + enum class typet + { + NONE, + ASSIGNMENT, + ASSUME, + ASSERT, + GOTO, + LOCATION, + INPUT, + OUTPUT, + DECL, + DEAD, + FUNCTION_CALL, + FUNCTION_RETURN, + CONSTRAINT, + SHARED_READ, + SHARED_WRITE, + SPAWN, + MEMORY_BARRIER, + ATOMIC_BEGIN, + ATOMIC_END + }; + typet type; // we may choose to hide a step bool hidden; // we categorize - typedef enum { STATE, ACTUAL_PARAMETER } assignment_typet; + enum class assignment_typet { STATE, ACTUAL_PARAMETER }; assignment_typet assignment_type; goto_programt::const_targett pc; @@ -105,9 +125,9 @@ class goto_trace_stept goto_trace_stept(): step_nr(0), - type(NONE), + type(typet::NONE), hidden(false), - assignment_type(STATE), + assignment_type(assignment_typet::STATE), thread_nr(0), cond_value(false), formatted(false) diff --git a/src/goto-programs/graphml_witness.cpp b/src/goto-programs/graphml_witness.cpp index 85bd1eec40f..4f4f6f56741 100644 --- a/src/goto-programs/graphml_witness.cpp +++ b/src/goto-programs/graphml_witness.cpp @@ -6,27 +6,18 @@ Author: Daniel Kroening \*******************************************************************/ +/// \file +/// Witnesses for Traces and Proofs + +#include "graphml_witness.h" + #include #include -#include +#include #include #include #include -#include "graphml_witness.h" - -/*******************************************************************\ - -Function: graphml_witnesst::remove_l0_l1 - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void graphml_witnesst::remove_l0_l1(exprt &expr) { if(expr.id()==ID_symbol) @@ -53,18 +44,6 @@ void graphml_witnesst::remove_l0_l1(exprt &expr) remove_l0_l1(*it); } -/*******************************************************************\ - -Function: graphml_witnesst::convert_assign_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string graphml_witnesst::convert_assign_rec( const irep_idt &identifier, const code_assignt &assign) @@ -81,7 +60,7 @@ std::string graphml_witnesst::convert_assign_rec( { index_exprt index( assign.lhs(), - from_integer(i++, signedbv_typet(config.ansi_c.pointer_width)), + from_integer(i++, index_type()), type.subtype()); if(!result.empty()) result+=' '; @@ -156,18 +135,6 @@ std::string graphml_witnesst::convert_assign_rec( return result; } -/*******************************************************************\ - -Function: filter_out - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static bool filter_out( const goto_tracet &goto_trace, const goto_tracet::stepst::const_iterator &prev_it, @@ -203,18 +170,7 @@ static bool filter_out( return false; } -/*******************************************************************\ - -Function: graphml_witnesst::operator() - - Inputs: - - Outputs: - - Purpose: counterexample witness - -\*******************************************************************/ - +/// counterexample witness void graphml_witnesst::operator()(const goto_tracet &goto_trace) { graphml.key_values["sourcecodelang"]="C"; @@ -245,7 +201,7 @@ void graphml_witnesst::operator()(const goto_tracet &goto_trace) goto_tracet::stepst::const_iterator next=it; ++next; if(next!=goto_trace.steps.end() && - next->type==goto_trace_stept::ASSIGNMENT && + next->type==goto_trace_stept::typet::ASSIGNMENT && it->full_lhs==next->full_lhs && it->pc->source_location==next->pc->source_location) { @@ -265,7 +221,7 @@ void graphml_witnesst::operator()(const goto_tracet &goto_trace) graphml[node].line=source_location.get_line(); graphml[node].thread_nr=it->thread_nr; graphml[node].is_violation= - it->type==goto_trace_stept::ASSERT && !it->cond_value; + it->type==goto_trace_stept::typet::ASSERT && !it->cond_value; graphml[node].has_invariant=false; step_to_node[it->step_nr]=node; @@ -299,9 +255,9 @@ void graphml_witnesst::operator()(const goto_tracet &goto_trace) switch(it->type) { - case goto_trace_stept::ASSIGNMENT: - case goto_trace_stept::ASSERT: - case goto_trace_stept::GOTO: + case goto_trace_stept::typet::ASSIGNMENT: + case goto_trace_stept::typet::ASSERT: + case goto_trace_stept::typet::GOTO: { xmlt edge("edge"); edge.set_attribute("source", graphml[from].node_name); @@ -317,7 +273,7 @@ void graphml_witnesst::operator()(const goto_tracet &goto_trace) data_l.data=id2string(graphml[from].line); } - if(it->type==goto_trace_stept::ASSIGNMENT && + if(it->type==goto_trace_stept::typet::ASSIGNMENT && it->lhs_object_value.is_not_nil() && it->full_lhs.is_not_nil()) { @@ -337,7 +293,7 @@ void graphml_witnesst::operator()(const goto_tracet &goto_trace) val_s.data=id2string(it->pc->source_location.get_function()); } } - else if(it->type==goto_trace_stept::GOTO && + else if(it->type==goto_trace_stept::typet::GOTO && it->pc->is_goto()) { xmlt &val=edge.new_element("data"); @@ -374,22 +330,22 @@ void graphml_witnesst::operator()(const goto_tracet &goto_trace) } break; - case goto_trace_stept::DECL: - case goto_trace_stept::FUNCTION_CALL: - case goto_trace_stept::FUNCTION_RETURN: - case goto_trace_stept::LOCATION: - case goto_trace_stept::ASSUME: - case goto_trace_stept::INPUT: - case goto_trace_stept::OUTPUT: - case goto_trace_stept::SHARED_READ: - case goto_trace_stept::SHARED_WRITE: - case goto_trace_stept::SPAWN: - case goto_trace_stept::MEMORY_BARRIER: - case goto_trace_stept::ATOMIC_BEGIN: - case goto_trace_stept::ATOMIC_END: - case goto_trace_stept::DEAD: - case goto_trace_stept::CONSTRAINT: - case goto_trace_stept::NONE: + case goto_trace_stept::typet::DECL: + case goto_trace_stept::typet::FUNCTION_CALL: + case goto_trace_stept::typet::FUNCTION_RETURN: + case goto_trace_stept::typet::LOCATION: + case goto_trace_stept::typet::ASSUME: + case goto_trace_stept::typet::INPUT: + case goto_trace_stept::typet::OUTPUT: + case goto_trace_stept::typet::SHARED_READ: + case goto_trace_stept::typet::SHARED_WRITE: + case goto_trace_stept::typet::SPAWN: + case goto_trace_stept::typet::MEMORY_BARRIER: + case goto_trace_stept::typet::ATOMIC_BEGIN: + case goto_trace_stept::typet::ATOMIC_END: + case goto_trace_stept::typet::DEAD: + case goto_trace_stept::typet::CONSTRAINT: + case goto_trace_stept::typet::NONE: // ignore break; } @@ -398,18 +354,7 @@ void graphml_witnesst::operator()(const goto_tracet &goto_trace) } } -/*******************************************************************\ - -Function: graphml_witnesst::operator() - - Inputs: - - Outputs: - - Purpose: proof witness - -\*******************************************************************/ - +/// proof witness void graphml_witnesst::operator()(const symex_target_equationt &equation) { graphml.key_values["sourcecodelang"]="C"; @@ -500,9 +445,9 @@ void graphml_witnesst::operator()(const symex_target_equationt &equation) switch(it->type) { - case goto_trace_stept::ASSIGNMENT: - case goto_trace_stept::ASSERT: - case goto_trace_stept::GOTO: + case goto_trace_stept::typet::ASSIGNMENT: + case goto_trace_stept::typet::ASSERT: + case goto_trace_stept::typet::GOTO: { xmlt edge("edge"); edge.set_attribute("source", graphml[from].node_name); @@ -546,22 +491,22 @@ void graphml_witnesst::operator()(const symex_target_equationt &equation) } break; - case goto_trace_stept::DECL: - case goto_trace_stept::FUNCTION_CALL: - case goto_trace_stept::FUNCTION_RETURN: - case goto_trace_stept::LOCATION: - case goto_trace_stept::ASSUME: - case goto_trace_stept::INPUT: - case goto_trace_stept::OUTPUT: - case goto_trace_stept::SHARED_READ: - case goto_trace_stept::SHARED_WRITE: - case goto_trace_stept::SPAWN: - case goto_trace_stept::MEMORY_BARRIER: - case goto_trace_stept::ATOMIC_BEGIN: - case goto_trace_stept::ATOMIC_END: - case goto_trace_stept::DEAD: - case goto_trace_stept::CONSTRAINT: - case goto_trace_stept::NONE: + case goto_trace_stept::typet::DECL: + case goto_trace_stept::typet::FUNCTION_CALL: + case goto_trace_stept::typet::FUNCTION_RETURN: + case goto_trace_stept::typet::LOCATION: + case goto_trace_stept::typet::ASSUME: + case goto_trace_stept::typet::INPUT: + case goto_trace_stept::typet::OUTPUT: + case goto_trace_stept::typet::SHARED_READ: + case goto_trace_stept::typet::SHARED_WRITE: + case goto_trace_stept::typet::SPAWN: + case goto_trace_stept::typet::MEMORY_BARRIER: + case goto_trace_stept::typet::ATOMIC_BEGIN: + case goto_trace_stept::typet::ATOMIC_END: + case goto_trace_stept::typet::DEAD: + case goto_trace_stept::typet::CONSTRAINT: + case goto_trace_stept::typet::NONE: // ignore break; } diff --git a/src/goto-programs/graphml_witness.h b/src/goto-programs/graphml_witness.h index 65a6b8e5406..053eb801146 100644 --- a/src/goto-programs/graphml_witness.h +++ b/src/goto-programs/graphml_witness.h @@ -6,6 +6,9 @@ Author: Daniel Kroening \*******************************************************************/ +/// \file +/// Witnesses for Traces and Proofs + #ifndef CPROVER_GOTO_PROGRAMS_GRAPHML_WITNESS_H #define CPROVER_GOTO_PROGRAMS_GRAPHML_WITNESS_H diff --git a/src/goto-programs/initialize_goto_model.cpp b/src/goto-programs/initialize_goto_model.cpp index 2df9af9f350..e0efc4768e4 100644 --- a/src/goto-programs/initialize_goto_model.cpp +++ b/src/goto-programs/initialize_goto_model.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Get a Goto Program + +#include "initialize_goto_model.h" + #include #include @@ -18,19 +23,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "goto_convert_functions.h" #include "read_goto_binary.h" -#include "initialize_goto_model.h" - -/*******************************************************************\ - -Function: initialize_goto_model - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ bool initialize_goto_model( goto_modelt &goto_model, @@ -90,9 +82,12 @@ bool initialize_goto_model( lf.filename=filename; lf.language=get_language_from_filename(filename); - if(lf.language==NULL) + if(lf.language==nullptr) { - msg.error("failed to figure out type of file", filename); + source_locationt location; + location.set_file(filename); + msg.error().source_location=location; + msg.error() << "failed to figure out type of file" << messaget::eom; return true; } diff --git a/src/goto-programs/initialize_goto_model.h b/src/goto-programs/initialize_goto_model.h index bf940e4c713..8a8a859125c 100644 --- a/src/goto-programs/initialize_goto_model.h +++ b/src/goto-programs/initialize_goto_model.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Initialize a Goto Program + #ifndef CPROVER_GOTO_PROGRAMS_INITIALIZE_GOTO_MODEL_H #define CPROVER_GOTO_PROGRAMS_INITIALIZE_GOTO_MODEL_H diff --git a/src/goto-programs/interpreter.cpp b/src/goto-programs/interpreter.cpp index 2b4841a7c22..817d04c3a59 100644 --- a/src/goto-programs/interpreter.cpp +++ b/src/goto-programs/interpreter.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Interpreter for GOTO Programs + +#include "interpreter.h" + #include #include #include @@ -14,21 +19,8 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "interpreter.h" #include "interpreter_class.h" -/*******************************************************************\ - -Function: interpretert::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interpretert::operator()() { build_memory_map(); @@ -58,53 +50,27 @@ void interpretert::operator()() } } -/*******************************************************************\ - -Function: interpretert::show_state - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interpretert::show_state() { - std::cout << std::endl; - std::cout << "----------------------------------------------------" - << std::endl; + std::cout << "\n----------------------------------------------------\n"; if(PC==function->second.body.instructions.end()) { std::cout << "End of function `" - << function->first << "'" << std::endl; + << function->first << "'\n"; } else function->second.body.output_instruction( ns, function->first, std::cout, PC); - std::cout << std::endl; + std::cout << '\n'; } -/*******************************************************************\ - -Function: interpretert::command - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interpretert::command() { #define BUFSIZE 100 char command[BUFSIZE]; - if(fgets(command, BUFSIZE-1, stdin)==NULL) + if(fgets(command, BUFSIZE-1, stdin)==nullptr) { done=true; return; @@ -116,18 +82,6 @@ void interpretert::command() done=true; } -/*******************************************************************\ - -Function: interpretert::step - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interpretert::step() { if(PC==function->second.body.instructions.end()) @@ -221,18 +175,6 @@ void interpretert::step() PC=next_PC; } -/*******************************************************************\ - -Function: interpretert::execute_goto - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interpretert::execute_goto() { if(evaluate_boolean(PC->guard)) @@ -247,18 +189,6 @@ void interpretert::execute_goto() } } -/*******************************************************************\ - -Function: interpretert::execute_other - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interpretert::execute_other() { const irep_idt &statement=PC->code.get_statement(); @@ -273,35 +203,11 @@ void interpretert::execute_other() throw "unexpected OTHER statement: "+id2string(statement); } -/*******************************************************************\ - -Function: interpretert::execute_decl - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interpretert::execute_decl() { assert(PC->code.get_statement()==ID_decl); } -/*******************************************************************\ - -Function: interpretert::execute_assign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interpretert::execute_assign() { const code_assignt &code_assign= @@ -318,24 +224,12 @@ void interpretert::execute_assign() if(size!=rhs.size()) std::cout << "!! failed to obtain rhs (" << rhs.size() << " vs. " - << size << ")" << std::endl; + << size << ")\n"; else assign(address, rhs); } } -/*******************************************************************\ - -Function: interpretert::assign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interpretert::assign( mp_integer address, const std::vector &rhs) @@ -346,60 +240,24 @@ void interpretert::assign( { memory_cellt &cell=memory[integer2unsigned(address)]; std::cout << "** assigning " << cell.identifier - << "[" << cell.offset << "]:=" << rhs[i] << std::endl; + << "[" << cell.offset << "]:=" << rhs[i] << '\n'; cell.value=rhs[i]; } } } -/*******************************************************************\ - -Function: interpretert::execute_assume - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interpretert::execute_assume() { if(!evaluate_boolean(PC->guard)) throw "assumption failed"; } -/*******************************************************************\ - -Function: interpretert::execute_assert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interpretert::execute_assert() { if(!evaluate_boolean(PC->guard)) throw "assertion failed"; } -/*******************************************************************\ - -Function: interpretert::execute_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interpretert::execute_function_call() { const code_function_callt &function_call= @@ -502,18 +360,6 @@ void interpretert::execute_function_call() throw "no body for "+id2string(identifier); } -/*******************************************************************\ - -Function: interpretert::build_memory_map - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interpretert::build_memory_map() { // put in a dummy for NULL @@ -529,18 +375,6 @@ void interpretert::build_memory_map() stack_pointer=memory.size(); } -/*******************************************************************\ - -Function: interpretert::build_memory_map - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interpretert::build_memory_map(const symbolt &symbol) { unsigned size=0; @@ -570,18 +404,6 @@ void interpretert::build_memory_map(const symbolt &symbol) } } -/*******************************************************************\ - -Function: interpretert::get_size - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - unsigned interpretert::get_size(const typet &type) const { if(type.id()==ID_struct) @@ -638,18 +460,6 @@ unsigned interpretert::get_size(const typet &type) const return 1; } -/*******************************************************************\ - -Function: interpreter - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interpreter( const symbol_tablet &symbol_table, const goto_functionst &goto_functions) diff --git a/src/goto-programs/interpreter.h b/src/goto-programs/interpreter.h index bf909502793..20113a54fc6 100644 --- a/src/goto-programs/interpreter.h +++ b/src/goto-programs/interpreter.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Interpreter for GOTO Programs + #ifndef CPROVER_GOTO_PROGRAMS_INTERPRETER_H #define CPROVER_GOTO_PROGRAMS_INTERPRETER_H diff --git a/src/goto-programs/interpreter_class.h b/src/goto-programs/interpreter_class.h index 14c429a1a86..e1ac3ec14b7 100644 --- a/src/goto-programs/interpreter_class.h +++ b/src/goto-programs/interpreter_class.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Interpreter for GOTO Programs + #ifndef CPROVER_GOTO_PROGRAMS_INTERPRETER_CLASS_H #define CPROVER_GOTO_PROGRAMS_INTERPRETER_CLASS_H @@ -23,7 +26,9 @@ class interpretert const goto_functionst &_goto_functions): symbol_table(_symbol_table), ns(_symbol_table), - goto_functions(_goto_functions) + goto_functions(_goto_functions), + stack_pointer(0), + done(false) { } diff --git a/src/goto-programs/interpreter_evaluate.cpp b/src/goto-programs/interpreter_evaluate.cpp index a9d62740cc3..ac848315618 100644 --- a/src/goto-programs/interpreter_evaluate.cpp +++ b/src/goto-programs/interpreter_evaluate.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Interpreter for GOTO Programs + +#include "interpreter_class.h" + #include #include @@ -13,20 +18,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "interpreter_class.h" - -/*******************************************************************\ - -Function: interpretert::evaluate - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interpretert::read( mp_integer address, std::vector &dest) const @@ -47,18 +38,6 @@ void interpretert::read( } } -/*******************************************************************\ - -Function: interpretert::evaluate - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void interpretert::evaluate( const exprt &expr, std::vector &dest) const @@ -165,7 +144,7 @@ void interpretert::evaluate( } else if(expr.id()==ID_or) { - if(expr.operands().size()<1) + if(expr.operands().empty()) throw id2string(expr.id())+" expects at least one operand"; bool result=false; @@ -209,7 +188,7 @@ void interpretert::evaluate( } else if(expr.id()==ID_and) { - if(expr.operands().size()<1) + if(expr.operands().empty()) throw id2string(expr.id())+" expects at least one operand"; bool result=true; @@ -423,21 +402,9 @@ void interpretert::evaluate( std::cout << "!! failed to evaluate expression: " << from_expr(ns, function->first, expr) - << std::endl; + << '\n'; } -/*******************************************************************\ - -Function: interpretert::evaluate_address - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - mp_integer interpretert::evaluate_address(const exprt &expr) const { if(expr.id()==ID_symbol) @@ -507,7 +474,7 @@ mp_integer interpretert::evaluate_address(const exprt &expr) const std::cout << "!! failed to evaluate address: " << from_expr(ns, function->first, expr) - << std::endl; + << '\n'; return 0; } diff --git a/src/goto-programs/json_goto_trace.cpp b/src/goto-programs/json_goto_trace.cpp index da6590fe2de..744e26500db 100644 --- a/src/goto-programs/json_goto_trace.cpp +++ b/src/goto-programs/json_goto_trace.cpp @@ -8,25 +8,16 @@ Author: Daniel Kroening \*******************************************************************/ -#include - -#include - -#include +/// \file +/// Traces of GOTO Programs #include "json_goto_trace.h" -/*******************************************************************\ - -Function: convert - - Inputs: - - Outputs: +#include - Purpose: +#include -\*******************************************************************/ +#include void convert( const namespacet &ns, @@ -50,7 +41,7 @@ void convert( switch(step.type) { - case goto_trace_stept::ASSERT: + case goto_trace_stept::typet::ASSERT: if(!step.cond_value) { irep_idt property_id; @@ -77,8 +68,8 @@ void convert( } break; - case goto_trace_stept::ASSIGNMENT: - case goto_trace_stept::DECL: + case goto_trace_stept::typet::ASSIGNMENT: + case goto_trace_stept::typet::DECL: { irep_idt identifier=step.lhs_object.get_identifier(); json_objectt &json_assignment=dest_array.push_back().make_object(); @@ -121,12 +112,15 @@ void convert( json_assignment["thread"]=json_numbert(std::to_string(step.thread_nr)); json_assignment["assignmentType"]= - json_stringt(step.assignment_type==goto_trace_stept::ACTUAL_PARAMETER? - "actual-parameter":"variable"); + json_stringt( + step.assignment_type== + goto_trace_stept::assignment_typet::ACTUAL_PARAMETER? + "actual-parameter": + "variable"); } break; - case goto_trace_stept::OUTPUT: + case goto_trace_stept::typet::OUTPUT: { json_objectt &json_output=dest_array.push_back().make_object(); @@ -150,7 +144,7 @@ void convert( } break; - case goto_trace_stept::INPUT: + case goto_trace_stept::typet::INPUT: { json_objectt &json_input=dest_array.push_back().make_object(); @@ -174,11 +168,11 @@ void convert( } break; - case goto_trace_stept::FUNCTION_CALL: - case goto_trace_stept::FUNCTION_RETURN: + case goto_trace_stept::typet::FUNCTION_CALL: + case goto_trace_stept::typet::FUNCTION_RETURN: { std::string tag= - (step.type==goto_trace_stept::FUNCTION_CALL)? + (step.type==goto_trace_stept::typet::FUNCTION_CALL)? "function-call":"function-return"; json_objectt &json_call_return=dest_array.push_back().make_object(); diff --git a/src/goto-programs/json_goto_trace.h b/src/goto-programs/json_goto_trace.h index a4a3f2757fe..102569b50e6 100644 --- a/src/goto-programs/json_goto_trace.h +++ b/src/goto-programs/json_goto_trace.h @@ -8,6 +8,9 @@ Date: November 2005 \*******************************************************************/ +/// \file +/// Traces of GOTO Programs + #ifndef CPROVER_GOTO_PROGRAMS_JSON_GOTO_TRACE_H #define CPROVER_GOTO_PROGRAMS_JSON_GOTO_TRACE_H diff --git a/src/goto-programs/link_to_library.cpp b/src/goto-programs/link_to_library.cpp index c3ead7e6ecb..2464aca83fe 100644 --- a/src/goto-programs/link_to_library.cpp +++ b/src/goto-programs/link_to_library.cpp @@ -6,26 +6,18 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Library Linking + +#include "link_to_library.h" + #include #include -#include "link_to_library.h" #include "compute_called_functions.h" #include "goto_convert_functions.h" -/*******************************************************************\ - -Function: link_to_library - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void link_to_library( goto_modelt &goto_model, message_handlert &message_handler) @@ -36,18 +28,6 @@ void link_to_library( message_handler); } -/*******************************************************************\ - -Function: link_to_library - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void link_to_library( symbol_tablet &symbol_table, goto_functionst &goto_functions, diff --git a/src/goto-programs/link_to_library.h b/src/goto-programs/link_to_library.h index cb266e5d8fa..c45c5efbfa2 100644 --- a/src/goto-programs/link_to_library.h +++ b/src/goto-programs/link_to_library.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Library Linking + #ifndef CPROVER_GOTO_PROGRAMS_LINK_TO_LIBRARY_H #define CPROVER_GOTO_PROGRAMS_LINK_TO_LIBRARY_H diff --git a/src/goto-programs/loop_ids.cpp b/src/goto-programs/loop_ids.cpp index 4d3eedec739..5f4c560a0bd 100644 --- a/src/goto-programs/loop_ids.cpp +++ b/src/goto-programs/loop_ids.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Loop IDs + +#include "loop_ids.h" + #include #include @@ -13,20 +18,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "loop_ids.h" - -/*******************************************************************\ - -Function: show_loop_ids - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void show_loop_ids( ui_message_handlert::uit ui, const goto_modelt &goto_model) @@ -34,25 +25,13 @@ void show_loop_ids( show_loop_ids(ui, goto_model.goto_functions); } -/*******************************************************************\ - -Function: show_loop_ids - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void show_loop_ids( ui_message_handlert::uit ui, const goto_programt &goto_program) { switch(ui) { - case ui_message_handlert::PLAIN: + case ui_message_handlert::uit::PLAIN: { forall_goto_program_instructions(it, goto_program) { @@ -69,7 +48,7 @@ void show_loop_ids( } break; } - case ui_message_handlert::XML_UI: + case ui_message_handlert::uit::XML_UI: { forall_goto_program_instructions(it, goto_program) { @@ -87,7 +66,7 @@ void show_loop_ids( } break; } - case ui_message_handlert::JSON_UI: + case ui_message_handlert::uit::JSON_UI: assert(false); // use function below } } @@ -97,7 +76,7 @@ void show_loop_ids_json( const goto_programt &goto_program, json_arrayt &loops) { - assert(ui==ui_message_handlert::JSON_UI); // use function above + assert(ui==ui_message_handlert::uit::JSON_UI); // use function above forall_goto_program_instructions(it, goto_program) { @@ -113,30 +92,18 @@ void show_loop_ids_json( } } -/*******************************************************************\ - -Function: show_loop_ids - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void show_loop_ids( ui_message_handlert::uit ui, const goto_functionst &goto_functions) { switch(ui) { - case ui_message_handlert::PLAIN: - case ui_message_handlert::XML_UI: + case ui_message_handlert::uit::PLAIN: + case ui_message_handlert::uit::XML_UI: forall_goto_functions(it, goto_functions) show_loop_ids(ui, it->second.body); break; - case ui_message_handlert::JSON_UI: + case ui_message_handlert::uit::JSON_UI: json_objectt json_result; json_arrayt &loops=json_result["loops"].make_array(); diff --git a/src/goto-programs/loop_ids.h b/src/goto-programs/loop_ids.h index da17118698c..a9f439286d7 100644 --- a/src/goto-programs/loop_ids.h +++ b/src/goto-programs/loop_ids.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Loop IDs + #ifndef CPROVER_GOTO_PROGRAMS_LOOP_IDS_H #define CPROVER_GOTO_PROGRAMS_LOOP_IDS_H diff --git a/src/goto-programs/mm_io.cpp b/src/goto-programs/mm_io.cpp new file mode 100644 index 00000000000..16ffc1063d0 --- /dev/null +++ b/src/goto-programs/mm_io.cpp @@ -0,0 +1,134 @@ +/*******************************************************************\ + +Module: Perform Memory-mapped I/O instrumentation + +Author: Daniel Kroening + +Date: April 2017 + +\*******************************************************************/ + +/// \file +/// Perform Memory-mapped I/O instrumentation + +#include "mm_io.h" + +#include +#include +#include + +#include "remove_returns.h" + +void collect_deref_expr( + const exprt &src, + std::set &dest) +{ + if(src.id()==ID_dereference) + dest.insert(to_dereference_expr(src)); + + for(const auto & op : src.operands()) + collect_deref_expr(op, dest); // recursive call +} + +void mm_io( + const exprt &mm_io_r, + const exprt &mm_io_w, + goto_functionst::goto_functiont &goto_function, + const namespacet &ns) +{ + for(goto_programt::instructionst::iterator it= + goto_function.body.instructions.begin(); + it!=goto_function.body.instructions.end(); + it++) + { + std::set deref_expr_w, deref_expr_r; + + if(it->is_assign()) + { + auto &a=to_code_assign(it->code); + collect_deref_expr(a.rhs(), deref_expr_r); + + if(mm_io_r.is_not_nil()) + { + if(deref_expr_r.size()==1) + { + const dereference_exprt &d=*deref_expr_r.begin(); + source_locationt source_location=it->source_location; + irep_idt function=it->function; + code_function_callt fc; + const code_typet &ct=to_code_type(mm_io_r.type()); + + irep_idt identifier=to_symbol_expr(mm_io_r).get_identifier(); + irep_idt r_identifier=id2string(identifier)+RETURN_VALUE_SUFFIX; + symbol_exprt return_value(r_identifier, ct.return_type()); + if_exprt if_expr(integer_address(d.pointer()), return_value, d); + replace_expr(d, if_expr, a.rhs()); + + const typet &pt=ct.parameters()[0].type(); + const typet &st=ct.parameters()[1].type(); + exprt size=size_of_expr(d.type(), ns); + fc.arguments().resize(2); + fc.arguments()[0]=typecast_exprt(d.pointer(), pt); + fc.arguments()[1]=typecast_exprt(size, st); + fc.function()=mm_io_r; + goto_function.body.insert_before_swap(it); + it->make_function_call(fc); + it->source_location=source_location; + it->function=function; + it++; + } + } + + if(mm_io_w.is_not_nil()) + { + if(a.lhs().id()==ID_dereference) + { + const dereference_exprt &d=to_dereference_expr(a.lhs()); + source_locationt source_location=it->source_location; + irep_idt function=it->function; + code_function_callt fc; + const code_typet &ct=to_code_type(mm_io_w.type()); + const typet &pt=ct.parameters()[0].type(); + const typet &st=ct.parameters()[1].type(); + const typet &vt=ct.parameters()[2].type(); + exprt size=size_of_expr(d.type(), ns); + fc.arguments().resize(3); + fc.arguments()[0]=typecast_exprt(d.pointer(), pt); + fc.arguments()[1]=typecast_exprt(size, st); + fc.arguments()[2]=typecast_exprt(a.rhs(), vt); + fc.function()=mm_io_w; + goto_function.body.insert_before_swap(it); + it->make_function_call(fc); + it->source_location=source_location; + it->function=function; + it++; + } + } + } + } +} + +void mm_io( + const symbol_tablet &symbol_table, + goto_functionst &goto_functions) +{ + const namespacet ns(symbol_table); + exprt mm_io_r=nil_exprt(), mm_io_w=nil_exprt(); + + irep_idt id_r=CPROVER_PREFIX "mm_io_r"; + irep_idt id_w=CPROVER_PREFIX "mm_io_w"; + + if(symbol_table.has_symbol(id_r)) + mm_io_r=symbol_table.lookup(id_r).symbol_expr(); + + if(symbol_table.has_symbol(id_w)) + mm_io_w=symbol_table.lookup(id_w).symbol_expr(); + + for(auto & f : goto_functions.function_map) + mm_io(mm_io_r, mm_io_w, f.second, ns); +} + +void mm_io(goto_modelt &model) +{ + mm_io(model.symbol_table, model.goto_functions); +} diff --git a/src/goto-programs/mm_io.h b/src/goto-programs/mm_io.h new file mode 100644 index 00000000000..dd9058b63c5 --- /dev/null +++ b/src/goto-programs/mm_io.h @@ -0,0 +1,22 @@ +/*******************************************************************\ + +Module: Perform Memory-mapped I/O instrumentation + +Author: Daniel Kroening + +Date: April 2017 + +\*******************************************************************/ + +/// \file +/// Perform Memory-mapped I/O instrumentation + +#ifndef CPROVER_GOTO_PROGRAMS_MM_IO_H +#define CPROVER_GOTO_PROGRAMS_MM_IO_H + +#include + +void mm_io(const symbol_tablet &, goto_functionst &); +void mm_io(goto_modelt &); + +#endif // CPROVER_GOTO_PROGRAMS_MM_IO_H diff --git a/src/goto-programs/module.md b/src/goto-programs/module.md new file mode 100644 index 00000000000..f1224d46492 --- /dev/null +++ b/src/goto-programs/module.md @@ -0,0 +1,273 @@ +\ingroup module_hidden +\defgroup module_goto-programs Goto Conversion & Instrumentation + +\author Kareem Khazem + +\section goto-conversion Goto Conversion + +In the \ref goto-programs directory. + +**Key classes:** +* goto_programt +* goto_functionst +* \ref goto_program_templatet::instructiont + +\dot +digraph G { + node [shape=box]; + rankdir="LR"; + 1 [shape=none, label=""]; + 2 [label="goto conversion"]; + 3 [shape=none, label=""]; + 1 -> 2 [label="Symbol table"]; + 2 -> 3 [label="goto-programs, goto-functions, symbol table"]; +} +\enddot + +At this stage, CBMC constructs a goto-program from a symbol table. It +does not use the parse tree or the source file at all for this step. This +may seem surprising, because the symbols are stored in a hash table and +therefore have no intrinsic order; nevertheless, every \ref symbolt is +associated with a \ref source_locationt, allowing CBMC to figure out the +lexical order. + +The structure of what is informally called a goto-program follows. The +entire target program is converted to a single \ref goto_functionst +object. The goto functions contains a set of \ref goto_programt objects; +each of these correspond to a "function" or "method" in the target +program. Each goto_program contains a list of +\ref goto_program_templatet::instructiont "instructions"; each +instruction contains an associated statement---these are subtypes of +\ref codet. Each instruction also contains a "target", which will be +empty for now. + +\dot +digraph G{ + graph [nojustify=true]; + node [shape=box]; + compound=true; + + subgraph cluster_src { + 1 [shape="none", label="source files"]; + 2 [label="file1.c\n-----------\nint main(){ + int x = 5; + if(x > 7){ + x = 9; } } + +void foo(){}"]; + 1 -> 2 [color=white]; + + 100 [label="file2.c\n--------\nchar bar(){ }"]; + 2 -> 100 [color=white]; + } + + 1 -> 3 [label="corresponds to", lhead=cluster_goto, + ltail=cluster_src]; + + subgraph cluster_goto { + 3 [label="a\ngoto_functionst", URL="\ref goto_functionst", shape=none]; + 4 [label="function_map\n(a map from irep_idt\nto goto_programt)"]; + } + 4 -> 5 [lhead=cluster_funmap, label="value:"]; + + subgraph cluster_funmap { + 9 [label="bar\n(an irep_idt)", URL="\ref irep_idt"]; + 10 [label="a goto_programt", URL="\ref goto_programt"]; + 9->10 [label="maps to"]; + + 5 [label="main\n(an irep_idt)", URL="\ref irep_idt"]; + + 7 [label="foo\n(an irep_idt)", URL="\ref irep_idt"]; + 8 [label="a goto_programt", URL="\ref goto_programt"]; + 7->8 [label="maps to"]; + + subgraph cluster_goto_program { + 11 [shape=none, label="a\ngoto_programt", URL="\ref goto_programt"]; + 12 [label="instructions\n(a list of instructiont)"]; + } + 5 -> 11 [lhead=cluster_goto_program, label="maps to:"]; + + } + + 12 -> target1 [lhead=cluster_instructions]; + + subgraph cluster_instructions { + subgraph cluster_ins1{ + code1 [label="code", URL="\ref codet"]; + target1 [label="target"]; + } + + target1 -> target2 [color=white,lhead=cluster_ins2, + ltail=cluster_ins1]; + + subgraph cluster_ins2{ + code2 [label="code", URL="\ref codet"]; + target2 [label="target"]; + } + + target2 -> target3 [color=white,lhead=cluster_ins3, + ltail=cluster_ins2]; + + subgraph cluster_ins3{ + code3 [label="code", URL="\ref codet"]; + target3 [label="target"]; + } + + target3 -> target4 [color=white,lhead=cluster_ins4, + ltail=cluster_ins3]; + + subgraph cluster_ins4{ + code4 [label="code", URL="\ref codet"]; + target4 [label="target"]; + } + + } + + subgraph cluster_decl { + decl1 [label="type:\ncode_declt", URL="\ref code_declt", + shape=none]; + subgraph cluster_decl_in{ + cluster_decl_in_1 [label="symbol()", shape=none]; + cluster_decl_in_2 [label="x"]; + cluster_decl_in_1 -> cluster_decl_in_2 [color=white]; + } + decl1 -> cluster_decl_in_1 [lhead="cluster_decl_in", color=white]; + } + code1 -> decl1 [lhead=cluster_decl]; + + subgraph cluster_assign1 { + assign1 [label="type:\ncode_assignt", URL="\ref code_assignt", + shape=none]; + subgraph cluster_assign1_in{ + cluster_assign1_in_1 [label="lhs()", shape=none]; + cluster_assign1_in_2 [label="x"]; + cluster_assign1_in_1 -> cluster_assign1_in_2 [color=white]; + + cluster_assign1_in_3 [label="rhs()", shape=none]; + cluster_assign1_in_4 [label="5"]; + cluster_assign1_in_3 -> cluster_assign1_in_4 [color=white]; + } + assign1 -> cluster_assign1_in_1 [lhead="cluster_assign1_in", color=white]; + } + code2 -> assign1 [lhead=cluster_assign1]; + + subgraph cluster_if { + if [label="type:\ncode_ifthenelset", URL="\ref code_ifthenelset", + shape=none]; + if_body [label="..."]; + if -> if_body [color=white]; + } + code3 -> if [lhead=cluster_if]; + + subgraph cluster_assign2 { + assign2 [label="type:\ncode_assignt", URL="\ref code_assignt", + shape=none]; + subgraph cluster_assign2_in{ + cluster_assign2_in_1 [label="lhs()", shape=none]; + cluster_assign2_in_2 [label="x"]; + cluster_assign2_in_1 -> cluster_assign2_in_2 [color=white]; + + cluster_assign2_in_3 [label="rhs()", shape=none]; + cluster_assign2_in_4 [label="9"]; + cluster_assign2_in_3 -> cluster_assign2_in_4 [color=white]; + } + assign2 -> cluster_assign2_in_1 [lhead="cluster_assign2_in", color=white]; + } + code4 -> assign2 [lhead=cluster_assign2]; + +} +\enddot + +This is not the final form of the goto-functions, since the lists of +instructions will be 'normalized' in the next step (Instrumentation), +which removes some instructions and adds targets to others. + +Note that goto_programt and goto_functionst are each template +instantiations; they are currently the *only* specialization of +goto_program_templatet and goto_functions_templatet, respectively. This +means that the generated Doxygen documentation can be somewhat obtuse +about the actual types of things, and is unable to generate links to the +correct classes. Note that the +\ref goto_program_templatet::instructiont::code "code" member of a +goto_programt's instruction has type \ref codet (its type in the +goto_program_templatet documentation is given as "codeT", as this is the +name of the template's type parameter); similarly, the type of a guard +of an instruction is \ref guardt. + +--- +\section instrumentation Instrumentation + +In the \ref goto-programs directory. + +**Key classes:** +* goto_programt +* goto_functionst +* \ref goto_program_templatet::instructiont + +\dot +digraph G { + node [shape=box]; + rankdir="LR"; + 1 [shape=none, label=""]; + 2 [label="goto conversion"]; + 3 [shape=none, label=""]; + 1 -> 2 [label="goto-programs, goto-functions, symbol table"]; + 2 -> 3 [label="transformed goto-programs"]; +} +\enddot + +This stage applies several transformations to the goto-programs from the +previous stage: + +* The diagram in the previous stage showed a goto_programt with four + instructions, but real programs usually yield instruction lists that + are littered with \ref code_skipt "skip" statements. The + instrumentation stage removes the majority of these. + +* Function pointers are removed. They are turned into switch statements + (but see the next point; switch statements are further transformed). + +* Compound blocks are eliminated. There are several subclasses of + \ref codet that count as 'compound blocks;' therefore, later stages in + the CBMC pipeline that switch over the codet subtype of a particular + instruction should not need to consider these types. In particular: + + * code_ifthenelset is turned into GOTOs. In particular, the bodies of + the conditionals are flattened into lists of instructions, inline + with the rest of the instruction in the goto_programt. The guard of + the conditional is placed onto the + \ref goto_program_templatet::instructiont::guard "guard" member of + an instruction whose code member is of type \ref code_gotot. The + \ref goto_program_templatet::instructiont::targets "targets" member + of that instruction points to the appropriate branch of the + conditional. (Note that although instructions have a list of + targets, in practice an instruction should only ever have at most + one target; you should check this invariant with an assertion if you + rely on it). + + The order of instructions in a list of instructions---as well as the + targets of GOTOs---are both displayed as arrows when viewing a + goto-program as a Graphviz DOT file with `goto-instrument --dot`. + The semantics of a goto-program is: the next instruction is the next + instruction in the list, unless the current instruction has a + target; in that case, check the guard of the instruction, and jump + to the target if the guard evaluates to true. + + * switch statements, for and while loops, and try-catches are also + transformed into lists of instructions guarded by GOTOs. + + * \ref code_blockt "code blocks" are transformed into lists of + instructions. + +* \ref code_returnt "return statements" are transformed into + (unconditional) GOTOs whose target is the \ref END_FUNCTION + instruction. Each goto_programt should have precisely one such + instruction. Note the presence of \ref code_deadt, which has a + \ref code_deadt::symbol() "symbol()" member. Deads mark symbols that + have just gone out of scope; typically, a GOTO that jumps to an + END_FUNCTION instruction is preceded by a series of deads. Deads also + follow sequences of instructions that were part of the body of a + block (loop, conditional etc.) if there were symbols declared in that + block. + +This stage concludes the *analysis-independent* program transformations. diff --git a/src/goto-programs/osx_fat_reader.cpp b/src/goto-programs/osx_fat_reader.cpp index aa9594ec203..c8a853922f7 100644 --- a/src/goto-programs/osx_fat_reader.cpp +++ b/src/goto-programs/osx_fat_reader.cpp @@ -6,27 +6,18 @@ Module: Read Mach-O \*******************************************************************/ -#include -#include +/// \file +/// Read Mach-O #include "osx_fat_reader.h" +#include +#include + #ifdef __APPLE__ #include #endif -/*******************************************************************\ - -Function: is_osx_fat_magic - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool is_osx_fat_magic(char hdr[4]) { #ifdef __APPLE__ @@ -43,18 +34,6 @@ bool is_osx_fat_magic(char hdr[4]) return false; } -/*******************************************************************\ - -Function: osx_fat_readert::osx_fat_readert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - osx_fat_readert::osx_fat_readert(std::ifstream &in) : has_gb_arch(false) { @@ -94,18 +73,6 @@ osx_fat_readert::osx_fat_readert(std::ifstream &in) : #endif } -/*******************************************************************\ - -Function: osx_fat_readert::extract_gb - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool osx_fat_readert::extract_gb( const std::string &source, const std::string &dest) const diff --git a/src/goto-programs/osx_fat_reader.h b/src/goto-programs/osx_fat_reader.h index e164548607b..715fc9f1eec 100644 --- a/src/goto-programs/osx_fat_reader.h +++ b/src/goto-programs/osx_fat_reader.h @@ -6,6 +6,9 @@ Module: Read OS X Fat Binaries \*******************************************************************/ +/// \file +/// Read OS X Fat Binaries + #ifndef CPROVER_GOTO_PROGRAMS_OSX_FAT_READER_H #define CPROVER_GOTO_PROGRAMS_OSX_FAT_READER_H diff --git a/src/goto-programs/parameter_assignments.cpp b/src/goto-programs/parameter_assignments.cpp index 2052bdb09d8..747ed374b23 100644 --- a/src/goto-programs/parameter_assignments.cpp +++ b/src/goto-programs/parameter_assignments.cpp @@ -8,11 +8,14 @@ Date: September 2015 \*******************************************************************/ -#include -#include +/// \file +/// Add parameter assignments #include "parameter_assignments.h" +#include +#include + class parameter_assignmentst { public: @@ -32,18 +35,7 @@ class parameter_assignmentst goto_programt &goto_program); }; -/*******************************************************************\ - -Function: parameter_assignmentst::do_function_calls - -Inputs: - -Outputs: - -Purpose: turns x=f(...) into f(...); lhs=f#return_value; - -\*******************************************************************/ - +/// turns x=f(...) into f(...); lhs=f#return_value; void parameter_assignmentst::do_function_calls( goto_functionst &goto_functions, goto_programt &goto_program) @@ -98,36 +90,13 @@ void parameter_assignmentst::do_function_calls( } } -/*******************************************************************\ - -Function: parameter_assignmentst::operator() - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void parameter_assignmentst::operator()(goto_functionst &goto_functions) { Forall_goto_functions(it, goto_functions) do_function_calls(goto_functions, it->second.body); } -/*******************************************************************\ - -Function: parameter_assignments - -Inputs: - -Outputs: - -Purpose: removes returns - -\*******************************************************************/ - +/// removes returns void parameter_assignments( symbol_tablet &symbol_table, goto_functionst &goto_functions) @@ -136,18 +105,7 @@ void parameter_assignments( rr(goto_functions); } -/*******************************************************************\ - -Function: parameter_assignments - -Inputs: - -Outputs: - -Purpose: removes returns - -\*******************************************************************/ - +/// removes returns void parameter_assignments(goto_modelt &goto_model) { parameter_assignmentst rr(goto_model.symbol_table); diff --git a/src/goto-programs/parameter_assignments.h b/src/goto-programs/parameter_assignments.h index b9cafe8f932..61eb180d7cd 100644 --- a/src/goto-programs/parameter_assignments.h +++ b/src/goto-programs/parameter_assignments.h @@ -8,6 +8,9 @@ Date: September 2015 \*******************************************************************/ +/// \file +/// Add parameter assignments + #ifndef CPROVER_GOTO_PROGRAMS_PARAMETER_ASSIGNMENTS_H #define CPROVER_GOTO_PROGRAMS_PARAMETER_ASSIGNMENTS_H diff --git a/src/goto-programs/pointer_arithmetic.cpp b/src/goto-programs/pointer_arithmetic.cpp index 0639a0dbca4..a89e1c04218 100644 --- a/src/goto-programs/pointer_arithmetic.cpp +++ b/src/goto-programs/pointer_arithmetic.cpp @@ -6,22 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include -#include - #include "pointer_arithmetic.h" -/*******************************************************************\ - -Function: pointer_arithmetict::pointer_arithmetict - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include pointer_arithmetict::pointer_arithmetict(const exprt &src) { @@ -30,18 +18,6 @@ pointer_arithmetict::pointer_arithmetict(const exprt &src) read(src); } -/*******************************************************************\ - -Function: pointer_arithmetict::read - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void pointer_arithmetict::read(const exprt &src) { if(src.id()==ID_plus) @@ -87,18 +63,6 @@ void pointer_arithmetict::read(const exprt &src) make_pointer(src); } -/*******************************************************************\ - -Function: pointer_arithmetict::add_to_offset - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void pointer_arithmetict::add_to_offset(const exprt &src) { if(offset.is_nil()) @@ -116,18 +80,6 @@ void pointer_arithmetict::add_to_offset(const exprt &src) } } -/*******************************************************************\ - -Function: pointer_arithmetict::make_pointer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void pointer_arithmetict::make_pointer(const exprt &src) { if(pointer.is_nil()) diff --git a/src/goto-programs/pointer_arithmetic.h b/src/goto-programs/pointer_arithmetic.h index 4e59e78ff52..7aafa7e233c 100644 --- a/src/goto-programs/pointer_arithmetic.h +++ b/src/goto-programs/pointer_arithmetic.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_GOTO_PROGRAMS_POINTER_ARITHMETIC_H #define CPROVER_GOTO_PROGRAMS_POINTER_ARITHMETIC_H diff --git a/src/goto-programs/property_checker.cpp b/src/goto-programs/property_checker.cpp index 01c8d2f08ae..7c39bc34e06 100644 --- a/src/goto-programs/property_checker.cpp +++ b/src/goto-programs/property_checker.cpp @@ -6,63 +6,30 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "property_checker.h" - -/*******************************************************************\ - -Function: property_checkert::as_string - - Inputs: - - Outputs: - - Purpose: +/// \file +/// Property Checker Interface -\*******************************************************************/ +#include "property_checker.h" std::string property_checkert::as_string(resultt result) { switch(result) { - case property_checkert::PASS: return "OK"; - case property_checkert::FAIL: return "FAILURE"; - case property_checkert::ERROR: return "ERROR"; - case property_checkert::UNKNOWN: return "UNKNOWN"; + case property_checkert::resultt::PASS: return "OK"; + case property_checkert::resultt::FAIL: return "FAILURE"; + case property_checkert::resultt::ERROR: return "ERROR"; + case property_checkert::resultt::UNKNOWN: return "UNKNOWN"; } return ""; } -/*******************************************************************\ - -Function: property_checkert::property_checkert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - property_checkert::property_checkert( message_handlert &_message_handler): messaget(_message_handler) { } -/*******************************************************************\ - -Function: property_checkert::initialize_property_map - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void property_checkert::initialize_property_map( const goto_functionst &goto_functions) { @@ -82,7 +49,7 @@ void property_checkert::initialize_property_map( irep_idt property_id=source_location.get_property_id(); property_statust &property_status=property_map[property_id]; - property_status.result=UNKNOWN; + property_status.result=resultt::UNKNOWN; property_status.location=i_it; } } diff --git a/src/goto-programs/property_checker.h b/src/goto-programs/property_checker.h index 95c209f2430..fd89606a752 100644 --- a/src/goto-programs/property_checker.h +++ b/src/goto-programs/property_checker.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Property Checker Interface + #ifndef CPROVER_GOTO_PROGRAMS_PROPERTY_CHECKER_H #define CPROVER_GOTO_PROGRAMS_PROPERTY_CHECKER_H @@ -26,7 +29,7 @@ class property_checkert:public messaget explicit property_checkert( message_handlert &_message_handler); - typedef enum { PASS, FAIL, ERROR, UNKNOWN } resultt; + enum class resultt { PASS, FAIL, ERROR, UNKNOWN }; static std::string as_string(resultt); diff --git a/src/goto-programs/read_bin_goto_object.cpp b/src/goto-programs/read_bin_goto_object.cpp index 9c92b403cf1..ebfaf6a75d1 100644 --- a/src/goto-programs/read_bin_goto_object.cpp +++ b/src/goto-programs/read_bin_goto_object.cpp @@ -8,26 +8,21 @@ Date: June 2006 \*******************************************************************/ +/// \file +/// Read goto object files. + +#include "read_bin_goto_object.h" + #include #include #include #include #include "goto_functions.h" -#include "read_bin_goto_object.h" - -/*******************************************************************\ - -Function: read_goto_object_v3 - - Inputs: input stream, symbol_table, functions - - Outputs: true on error, false otherwise - - Purpose: read goto binary format v3 - -\*******************************************************************/ +/// read goto binary format v3 +/// \par parameters: input stream, symbol_table, functions +/// \return true on error, false otherwise bool read_bin_goto_object_v3( std::istream &in, const std::string &filename, @@ -168,18 +163,9 @@ bool read_bin_goto_object_v3( return false; } -/*******************************************************************\ - -Function: read_goto_object - - Inputs: input stream, symbol table, functions - - Outputs: true on error, false otherwise - - Purpose: reads a goto binary file back into a symbol and a function table - -\*******************************************************************/ - +/// reads a goto binary file back into a symbol and a function table +/// \par parameters: input stream, symbol table, functions +/// \return true on error, false otherwise bool read_bin_goto_object( std::istream &in, const std::string &filename, @@ -191,9 +177,9 @@ bool read_bin_goto_object( { char hdr[4]; - hdr[0]=in.get(); - hdr[1]=in.get(); - hdr[2]=in.get(); + hdr[0]=static_cast(in.get()); + hdr[1]=static_cast(in.get()); + hdr[2]=static_cast(in.get()); if(hdr[0]=='G' && hdr[1]=='B' && hdr[2]=='F') { @@ -201,7 +187,7 @@ bool read_bin_goto_object( } else { - hdr[3]=in.get(); + hdr[3]=static_cast(in.get()); if(hdr[0]==0x7f && hdr[1]=='G' && hdr[2]=='B' && hdr[3]=='F') { // OK! diff --git a/src/goto-programs/read_bin_goto_object.h b/src/goto-programs/read_bin_goto_object.h index a4b679427d7..e7b684b3cc4 100644 --- a/src/goto-programs/read_bin_goto_object.h +++ b/src/goto-programs/read_bin_goto_object.h @@ -8,6 +8,9 @@ Date: May 2007 \*******************************************************************/ +/// \file +/// Read goto object files. + #ifndef CPROVER_GOTO_PROGRAMS_READ_BIN_GOTO_OBJECT_H #define CPROVER_GOTO_PROGRAMS_READ_BIN_GOTO_OBJECT_H diff --git a/src/goto-programs/read_goto_binary.cpp b/src/goto-programs/read_goto_binary.cpp index b5919d93eee..1a4887cf0e9 100644 --- a/src/goto-programs/read_goto_binary.cpp +++ b/src/goto-programs/read_goto_binary.cpp @@ -6,6 +6,11 @@ Module: Read Goto Programs \*******************************************************************/ +/// \file +/// Read Goto Programs + +#include "read_goto_binary.h" + #if defined(__linux__) || \ defined(__FreeBSD_kernel__) || \ defined(__GNU__) || \ @@ -29,23 +34,10 @@ Module: Read Goto Programs #include #include "goto_model.h" -#include "read_goto_binary.h" #include "read_bin_goto_object.h" #include "elf_reader.h" #include "osx_fat_reader.h" -/*******************************************************************\ - -Function: read_goto_binary - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool read_goto_binary( const std::string &filename, goto_modelt &dest, @@ -55,18 +47,6 @@ bool read_goto_binary( filename, dest.symbol_table, dest.goto_functions, message_handler); } -/*******************************************************************\ - -Function: read_goto_binary - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool read_goto_binary( const std::string &filename, symbol_tablet &symbol_table, @@ -172,18 +152,6 @@ bool read_goto_binary( return true; } -/*******************************************************************\ - -Function: is_goto_binary - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool is_goto_binary(const std::string &filename) { #ifdef _MSC_VER @@ -245,18 +213,6 @@ bool is_goto_binary(const std::string &filename) return false; } -/*******************************************************************\ - -Function: rename_symbols_in_function - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static void rename_symbols_in_function( goto_functionst::goto_functiont &function, const rename_symbolt &rename_symbol) @@ -271,25 +227,14 @@ static void rename_symbols_in_function( } } -/*******************************************************************\ - -Function: link_functions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static bool link_functions( symbol_tablet &dest_symbol_table, goto_functionst &dest_functions, const symbol_tablet &src_symbol_table, goto_functionst &src_functions, const rename_symbolt &rename_symbol, - const std::unordered_set &weak_symbols) + const std::unordered_set &weak_symbols, + const replace_symbolt &object_type_updates) { namespacet ns(dest_symbol_table); namespacet src_ns(src_symbol_table); @@ -358,7 +303,7 @@ static bool link_functions( rename_symbolt macro_application; forall_symbols(it, dest_symbol_table.symbols) - if(it->second.is_macro) + if(it->second.is_macro && !it->second.is_type) { const symbolt &symbol=it->second; @@ -368,8 +313,8 @@ static bool link_functions( #if 0 if(!base_type_eq(symbol.type, ns.lookup(id).type, ns)) { - std::cerr << symbol << std::endl; - std::cerr << ns.lookup(id) << std::endl; + std::cerr << symbol << '\n'; + std::cerr << ns.lookup(id) << '\n'; } assert(base_type_eq(symbol.type, ns.lookup(id).type, ns)); #endif @@ -381,21 +326,22 @@ static bool link_functions( Forall_goto_functions(dest_it, dest_functions) rename_symbols_in_function(dest_it->second, macro_application); + if(!object_type_updates.expr_map.empty()) + { + Forall_goto_functions(dest_it, dest_functions) + Forall_goto_program_instructions(iit, dest_it->second.body) + { + object_type_updates(iit->code); + object_type_updates(iit->guard); + } + } + return false; } -/*******************************************************************\ - -Function: read_object_and_link - - Inputs: a file_name - - Outputs: true on error, false otherwise - - Purpose: reads an object file - -\*******************************************************************/ - +/// reads an object file +/// \par parameters: a file_name +/// \return true on error, false otherwise bool read_object_and_link( const std::string &file_name, symbol_tablet &symbol_table, @@ -427,26 +373,22 @@ bool read_object_and_link( if(linking.typecheck_main()) return true; - if(link_functions(symbol_table, functions, - temp_model.symbol_table, temp_model.goto_functions, - linking.rename_symbol, weak_symbols)) + if(link_functions( + symbol_table, + functions, + temp_model.symbol_table, + temp_model.goto_functions, + linking.rename_symbol, + weak_symbols, + linking.object_type_updates)) return true; return false; } -/*******************************************************************\ - -Function: read_object_and_link - - Inputs: a file_name - - Outputs: true on error, false otherwise - - Purpose: reads an object file - -\*******************************************************************/ - +/// reads an object file +/// \par parameters: a file_name +/// \return true on error, false otherwise bool read_object_and_link( const std::string &file_name, goto_modelt &goto_model, diff --git a/src/goto-programs/read_goto_binary.h b/src/goto-programs/read_goto_binary.h index f926179b134..bbaba7a5c11 100644 --- a/src/goto-programs/read_goto_binary.h +++ b/src/goto-programs/read_goto_binary.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Read Goto Programs + #ifndef CPROVER_GOTO_PROGRAMS_READ_GOTO_BINARY_H #define CPROVER_GOTO_PROGRAMS_READ_GOTO_BINARY_H diff --git a/src/goto-programs/remove_asm.cpp b/src/goto-programs/remove_asm.cpp index a77d1e0e418..29958434d48 100644 --- a/src/goto-programs/remove_asm.cpp +++ b/src/goto-programs/remove_asm.cpp @@ -9,15 +9,19 @@ Date: December 2014 \*******************************************************************/ +/// \file +/// Remove 'asm' statements by compiling into suitable standard code + +#include "remove_asm.h" + #include +#include #include #include #include -#include "remove_asm.h" - class remove_asmt { public: @@ -48,18 +52,6 @@ class remove_asmt goto_programt &dest); }; -/*******************************************************************\ - -Function: remove_asmt::gcc_asm_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void remove_asmt::gcc_asm_function_call( const irep_idt &function_base_name, const codet &code, @@ -70,7 +62,8 @@ void remove_asmt::gcc_asm_function_call( code_function_callt function_call; function_call.lhs().make_nil(); - const pointer_typet void_pointer=pointer_typet(void_typet()); + const typet void_pointer= + pointer_type(void_typet()); // outputs forall_operands(it, code.op1()) @@ -118,18 +111,7 @@ void remove_asmt::gcc_asm_function_call( } } -/*******************************************************************\ - -Function: remove_asmt::process_instruction - -Inputs: - -Outputs: - -Purpose: removes assembler - -\*******************************************************************/ - +/// removes assembler void remove_asmt::process_instruction( goto_programt::instructiont &instruction, goto_programt &dest) @@ -143,7 +125,7 @@ void remove_asmt::process_instruction( const irep_idt &i_str= to_string_constant(code.op0()).get_value(); - // std::cout << "DOING " << i_str << std::endl; + // std::cout << "DOING " << i_str << '\n'; std::istringstream str(id2string(i_str)); assembler_parser.clear(); @@ -163,7 +145,7 @@ void remove_asmt::process_instruction( std::cout << "A ********************\n"; for(const auto &ins : instruction) { - std::cout << "XX: " << ins.pretty() << std::endl; + std::cout << "XX: " << ins.pretty() << '\n'; } std::cout << "B ********************\n"; @@ -302,18 +284,7 @@ void remove_asmt::process_instruction( } } -/*******************************************************************\ - -Function: remove_asmt::process_function - -Inputs: - -Outputs: - -Purpose: removes assembler - -\*******************************************************************/ - +/// removes assembler void remove_asmt::process_function( goto_functionst::goto_functiont &goto_function) { @@ -333,18 +304,7 @@ void remove_asmt::process_function( } } -/*******************************************************************\ - -Function: remove_asmt:operator() - -Inputs: - -Outputs: - -Purpose: removes assembler - -\*******************************************************************/ - +/// removes assembler void remove_asmt::operator()() { Forall_goto_functions(it, goto_functions) @@ -353,18 +313,7 @@ void remove_asmt::operator()() } } -/*******************************************************************\ - -Function: remove_asm - -Inputs: - -Outputs: - -Purpose: removes assembler - -\*******************************************************************/ - +/// removes assembler void remove_asm( symbol_tablet &symbol_table, goto_functionst &goto_functions) @@ -372,18 +321,7 @@ void remove_asm( remove_asmt(symbol_table, goto_functions)(); } -/*******************************************************************\ - -Function: remove_asm - -Inputs: - -Outputs: - -Purpose: removes assembler - -\*******************************************************************/ - +/// removes assembler void remove_asm(goto_modelt &goto_model) { remove_asmt(goto_model.symbol_table, goto_model.goto_functions)(); diff --git a/src/goto-programs/remove_asm.h b/src/goto-programs/remove_asm.h index a0de50fc699..7717ba59ca0 100644 --- a/src/goto-programs/remove_asm.h +++ b/src/goto-programs/remove_asm.h @@ -9,6 +9,9 @@ Date: December 2014 \*******************************************************************/ +/// \file +/// Remove 'asm' statements by compiling into suitable standard code + #ifndef CPROVER_GOTO_PROGRAMS_REMOVE_ASM_H #define CPROVER_GOTO_PROGRAMS_REMOVE_ASM_H diff --git a/src/goto-programs/remove_complex.cpp b/src/goto-programs/remove_complex.cpp index 44539fb5f1e..13ff90f908b 100644 --- a/src/goto-programs/remove_complex.cpp +++ b/src/goto-programs/remove_complex.cpp @@ -8,21 +8,12 @@ Date: September 2014 \*******************************************************************/ -#include +/// \file +/// Remove 'complex' data type #include "remove_complex.h" -/*******************************************************************\ - -Function: complex_member - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ +#include static exprt complex_member(const exprt &expr, irep_idt id) { @@ -45,18 +36,6 @@ static exprt complex_member(const exprt &expr, irep_idt id) } } -/*******************************************************************\ - -Function: have_to_remove_complex - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static bool have_to_remove_complex(const typet &type); static bool have_to_remove_complex(const exprt &expr) @@ -94,18 +73,6 @@ static bool have_to_remove_complex(const exprt &expr) return false; } -/*******************************************************************\ - -Function: have_to_remove_complex - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static bool have_to_remove_complex(const typet &type) { if(type.id()==ID_struct || type.id()==ID_union) @@ -129,18 +96,7 @@ static bool have_to_remove_complex(const typet &type) return false; } -/*******************************************************************\ - -Function: remove_complex - -Inputs: - -Outputs: - -Purpose: removes complex data type - -\*******************************************************************/ - +/// removes complex data type static void remove_complex(typet &); static void remove_complex(exprt &expr) @@ -274,18 +230,7 @@ static void remove_complex(exprt &expr) remove_complex(expr.type()); } -/*******************************************************************\ - -Function: remove_complex - -Inputs: - -Outputs: - -Purpose: removes complex data type - -\*******************************************************************/ - +/// removes complex data type static void remove_complex(typet &type) { if(!have_to_remove_complex(type)) @@ -327,54 +272,21 @@ static void remove_complex(typet &type) } } -/*******************************************************************\ - -Function: remove_complex - -Inputs: - -Outputs: - -Purpose: removes complex data type - -\*******************************************************************/ - +/// removes complex data type static void remove_complex(symbolt &symbol) { remove_complex(symbol.value); remove_complex(symbol.type); } -/*******************************************************************\ - -Function: remove_complex - -Inputs: - -Outputs: - -Purpose: removes complex data type - -\*******************************************************************/ - +/// removes complex data type void remove_complex(symbol_tablet &symbol_table) { Forall_symbols(it, symbol_table.symbols) remove_complex(it->second); } -/*******************************************************************\ - -Function: remove_complex - -Inputs: - -Outputs: - -Purpose: removes complex data type - -\*******************************************************************/ - +/// removes complex data type static void remove_complex( goto_functionst::goto_functiont &goto_function) { @@ -387,36 +299,14 @@ static void remove_complex( } } -/*******************************************************************\ - -Function: remove_complex - -Inputs: - -Outputs: - -Purpose: removes complex data type - -\*******************************************************************/ - +/// removes complex data type static void remove_complex(goto_functionst &goto_functions) { Forall_goto_functions(it, goto_functions) remove_complex(it->second); } -/*******************************************************************\ - -Function: remove_complex - -Inputs: - -Outputs: - -Purpose: removes complex data type - -\*******************************************************************/ - +/// removes complex data type void remove_complex( symbol_tablet &symbol_table, goto_functionst &goto_functions) @@ -425,18 +315,7 @@ void remove_complex( remove_complex(goto_functions); } -/*******************************************************************\ - -Function: remove_complex - -Inputs: - -Outputs: - -Purpose: removes complex data type - -\*******************************************************************/ - +/// removes complex data type void remove_complex(goto_modelt &goto_model) { remove_complex(goto_model.symbol_table, goto_model.goto_functions); diff --git a/src/goto-programs/remove_complex.h b/src/goto-programs/remove_complex.h index c42784318cf..098470ecc1a 100644 --- a/src/goto-programs/remove_complex.h +++ b/src/goto-programs/remove_complex.h @@ -8,6 +8,9 @@ Date: September 2014 \*******************************************************************/ +/// \file +/// Remove the 'complex' data type by compilation into structs + #ifndef CPROVER_GOTO_PROGRAMS_REMOVE_COMPLEX_H #define CPROVER_GOTO_PROGRAMS_REMOVE_COMPLEX_H diff --git a/src/goto-programs/remove_const_function_pointers.cpp b/src/goto-programs/remove_const_function_pointers.cpp index c0a7d8d5380..de5649892f2 100644 --- a/src/goto-programs/remove_const_function_pointers.cpp +++ b/src/goto-programs/remove_const_function_pointers.cpp @@ -6,91 +6,60 @@ Author: Thomas Kiley, thomas.kiley@diffblue.com \*******************************************************************/ +/// \file +/// Goto Programs + +#include "remove_const_function_pointers.h" + #include #include #include -#include "remove_const_function_pointers.h" - #define LOG(message, irep) \ debug() << "Case " << __LINE__ << " : " << message << "\n" \ << irep.pretty() << eom; -/*******************************************************************\ - -Function: remove_const_function_pointerst::remove_const_function_pointerst - - Inputs: - message_handler - The message handler for messaget - base_expression - The function call through a function pointer - ns - The namespace to use to resolve types - symbol_table - The symbol table to look up symbols in - - Outputs: - - Purpose: To take a function call on a function pointer, and if possible - resolve it to a small collection of possible values. - -\*******************************************************************/ - +/// To take a function call on a function pointer, and if possible resolve it to +/// a small collection of possible values. +/// \param message_handler: The message handler for messaget +/// \param ns: The namespace to use to resolve types +/// \param symbol_table: The symbol table to look up symbols in remove_const_function_pointerst::remove_const_function_pointerst( message_handlert &message_handler, - const exprt &base_expression, const namespacet &ns, const symbol_tablet &symbol_table): messaget(message_handler), - original_expression(base_expression), ns(ns), symbol_table(symbol_table) {} -/*******************************************************************\ - -Function: remove_const_function_pointerst::operator() - - Inputs: - out_functions - The functions that (symbols of type ID_code) the base - expression could take. - - Outputs: Returns true if it was able to resolve the call, false if not. - If it returns true, out_functions will be populated by all the - possible values the function pointer could be. - - Purpose: To take a function call on a function pointer, and if possible - resolve it to a small collection of possible values. It will - resolve function pointers that are const and: - - assigned directly to a function - - assigned to a value in an array of functions - - assigned to a const struct component - Or variations within. - -\*******************************************************************/ - +/// To take a function call on a function pointer, and if possible resolve it to +/// a small collection of possible values. It will resolve function pointers +/// that are const and: - assigned directly to a function - assigned to a value +/// in an array of functions - assigned to a const struct component Or +/// variations within. +/// \param base_expression: The function call through a function pointer +/// \param out_functions: The functions that (symbols of type ID_code) the base +/// expression could take. +/// \return Returns true if it was able to resolve the call, false if not. If it +/// returns true, out_functions will be populated by all the possible values +/// the function pointer could be. bool remove_const_function_pointerst::operator()( + const exprt &base_expression, functionst &out_functions) { // Replace all const symbols with their values - exprt non_symbol_expression=replace_const_symbols(original_expression); + exprt non_symbol_expression=replace_const_symbols(base_expression); return try_resolve_function_call(non_symbol_expression, out_functions); } -/*******************************************************************\ - -Function: remove_const_function_pointerst::replace_const_symbols - - Inputs: - expression - The expression to resolve symbols in - - Outputs: Returns a modified version of the expression, with all - const symbols resolved to their actual values. - - Purpose: To collapse the symbols down to their values where possible - This takes a very general approach, recreating the expr tree - exactly as it was and ignoring what type of expressions are found - and instead recurses over all the operands. - -\*******************************************************************/ - +/// To collapse the symbols down to their values where possible This takes a +/// very general approach, recreating the expr tree exactly as it was and +/// ignoring what type of expressions are found and instead recurses over all +/// the operands. +/// \param expression: The expression to resolve symbols in +/// \return Returns a modified version of the expression, with all const symbols +/// resolved to their actual values. exprt remove_const_function_pointerst::replace_const_symbols( const exprt &expression) const { @@ -129,19 +98,9 @@ exprt remove_const_function_pointerst::replace_const_symbols( } } -/*******************************************************************\ - -Function: remove_const_function_pointerst::resolve_symbol - - Inputs: - symbol_expr - The symbol expression - - Outputs: The expression value of the symbol. - - Purpose: Look up a symbol in the symbol table and return its value - -\*******************************************************************/ - +/// Look up a symbol in the symbol table and return its value +/// \param symbol_expr: The symbol expression +/// \return The expression value of the symbol. exprt remove_const_function_pointerst::resolve_symbol( const symbol_exprt &symbol_expr) const { @@ -150,25 +109,14 @@ exprt remove_const_function_pointerst::resolve_symbol( return symbol.value; } -/*******************************************************************\ - -Function: remove_const_function_pointerst::try_resolve_function_call - - Inputs: - expr - The expression to get the possible function calls - out_functions - The functions this expression could be resolved to - - Outputs: Returns true if it was able to resolve the expression to some - specific functions. If this is the case, out_functions will contain - the possible functions. - - Purpose: To resolve an expression to the specific function calls it can - be. This is different to try_resolve_expression which isn't - explicitly looking for functions and is instead just trying - to squash particular exprt structures. - -\*******************************************************************/ - +/// To resolve an expression to the specific function calls it can be. This is +/// different to try_resolve_expression which isn't explicitly looking for +/// functions and is instead just trying to squash particular exprt structures. +/// \param expr: The expression to get the possible function calls +/// \param out_functions: The functions this expression could be resolved to +/// \return Returns true if it was able to resolve the expression to some +/// specific functions. If this is the case, out_functions will contain the +/// possible functions. bool remove_const_function_pointerst::try_resolve_function_call( const exprt &expr, functionst &out_functions) { @@ -216,6 +164,20 @@ bool remove_const_function_pointerst::try_resolve_function_call( resolved=false; } } + else if(simplified_expr.id()==ID_constant) + { + if(simplified_expr.is_zero()) + { + // We have the null pointer - no need to throw everything away + // but we don't add any functions either + resolved=true; + } + else + { + LOG("Non-zero constant value found", simplified_expr); + resolved=false; + } + } else { LOG("Unrecognised expression", simplified_expr); @@ -233,23 +195,12 @@ bool remove_const_function_pointerst::try_resolve_function_call( } } -/*******************************************************************\ - -Function: remove_const_function_pointerst::try_resolve_function_calls - - Inputs: - exprs - The expressions to evaluate - out_functions - The functions these expressions resolve to - - Outputs: Returns true if able to resolve each of the expressions down - to one or more functions. - - Purpose: To resolve a collection of expressions to the specific function - calls they can be. Returns a collection if and only if all of - them can be resolved. - -\*******************************************************************/ - +/// To resolve a collection of expressions to the specific function calls they +/// can be. Returns a collection if and only if all of them can be resolved. +/// \param exprs: The expressions to evaluate +/// \param out_functions: The functions these expressions resolve to +/// \return Returns true if able to resolve each of the expressions down to one +/// or more functions. bool remove_const_function_pointerst::try_resolve_function_calls( const expressionst &exprs, functionst &out_functions) { @@ -274,27 +225,17 @@ bool remove_const_function_pointerst::try_resolve_function_calls( return true; } -/*******************************************************************\ - -Function: remove_const_function_pointerst::try_resolve_index_of_function_call - - Inputs: - index_expr - The index expression to resolve to possible function calls - out_functions - The functions this expression could be - - Outputs: Returns true if it was able to resolve the index expression to some - specific functions. If this is the case, out_functions will contain - the possible functions. - - Purpose: To resolve an expression to the specific function calls it can - be. Specifically, this function deals with index expressions - where it squashes its array and squash its index - If we can get a precise number for the index, we - try_resolve_function_call on its value otherwise - try_resolve_function_call on each and return the union of them all - -\*******************************************************************/ - +/// To resolve an expression to the specific function calls it can be. +/// Specifically, this function deals with index expressions where it squashes +/// its array and squash its index If we can get a precise number for the index, +/// we try_resolve_function_call on its value otherwise +/// try_resolve_function_call on each and return the union of them all +/// \param index_expr: The index expression to resolve to possible function +/// calls +/// \param out_functions: The functions this expression could be +/// \return Returns true if it was able to resolve the index expression to some +/// specific functions. If this is the case, out_functions will contain the +/// possible functions. bool remove_const_function_pointerst::try_resolve_index_of_function_call( const index_exprt &index_expr, functionst &out_functions) { @@ -318,24 +259,15 @@ bool remove_const_function_pointerst::try_resolve_index_of_function_call( return try_resolve_function_calls(potential_array_values, out_functions); } -/*******************************************************************\ - -Function: remove_const_function_pointerst::try_resolve_member_function_call - - Inputs: - member_expr - The member expression to resolve to possible function calls - out_functions - The functions this expression could be - - Outputs: Returns true if it was able to resolve the member expression to some - specific functions. If this is the case, out_functions will contain - the possible functions. - - Purpose: To resolve an expression to the specific function calls it can - be. Specifically, this function deals with member expressions - by using try_resolve_member and then recursing on its value. - -\*******************************************************************/ - +/// To resolve an expression to the specific function calls it can be. +/// Specifically, this function deals with member expressions by using +/// try_resolve_member and then recursing on its value. +/// \param member_expr: The member expression to resolve to possible function +/// calls +/// \param out_functions: The functions this expression could be +/// \return Returns true if it was able to resolve the member expression to some +/// specific functions. If this is the case, out_functions will contain the +/// possible functions. bool remove_const_function_pointerst::try_resolve_member_function_call( const member_exprt &member_expr, functionst &out_functions) { @@ -359,24 +291,14 @@ bool remove_const_function_pointerst::try_resolve_member_function_call( return try_resolve_function_calls(potential_component_values, out_functions); } -/*******************************************************************\ - -Function: remove_const_function_pointerst::try_resolve_address_of_function_call - - Inputs: - address_expr - The address_of expression to resolve to possible function - calls - out_functions - The functions this expression could be - - Outputs: Returns true if it was able to resolve the address_of expression to - some specific functions. If this is the case, out_functions will - contain the possible functions. - - Purpose: To resolve an expression to the specific function calls it can - be. Specifically, this function deals with address_of expressions. - -\*******************************************************************/ - +/// To resolve an expression to the specific function calls it can be. +/// Specifically, this function deals with address_of expressions. +/// \param address_expr: The address_of expression to resolve to possible +/// function calls +/// \param out_functions: The functions this expression could be +/// \return Returns true if it was able to resolve the address_of expression to +/// some specific functions. If this is the case, out_functions will contain +/// the possible functions. bool remove_const_function_pointerst::try_resolve_address_of_function_call( const address_of_exprt &address_expr, functionst &out_functions) { @@ -389,24 +311,15 @@ bool remove_const_function_pointerst::try_resolve_address_of_function_call( return resolved; } -/*******************************************************************\ - -Function: remove_const_function_pointerst::try_resolve_dereference_function_call - - Inputs: - deref_expr - The dereference expression to resolve to possible function calls - out_functions - The functions this expression could be - - Outputs: Returns true if it was able to resolve the dereference expression to - some specific functions. If this is the case, out_functions will - contain the possible functions. - - Purpose: To resolve an expression to the specific function calls it can - be. Specifically, this function deals with dereference expressions - by using try_resolve_dereferebce and then recursing on its value. - -\*******************************************************************/ - +/// To resolve an expression to the specific function calls it can be. +/// Specifically, this function deals with dereference expressions by using +/// try_resolve_dereferebce and then recursing on its value. +/// \param deref_expr: The dereference expression to resolve to possible +/// function calls +/// \param out_functions: The functions this expression could be +/// \return Returns true if it was able to resolve the dereference expression to +/// some specific functions. If this is the case, out_functions will contain +/// the possible functions. bool remove_const_function_pointerst::try_resolve_dereference_function_call( const dereference_exprt &deref_expr, functionst &out_functions) { @@ -430,24 +343,15 @@ bool remove_const_function_pointerst::try_resolve_dereference_function_call( return try_resolve_function_calls(potential_deref_values, out_functions); } -/*******************************************************************\ - -Function: remove_const_function_pointerst::try_resolve_typecast_function_call - - Inputs: - typecast_expr - The typecast expression to resolve to possible function calls - out_functions - The functions this expression could be - - Outputs: Returns true if it was able to resolve the typecast expression to - some specific functions. If this is the case, out_functions will - contain the possible functions. - - Purpose: To resolve an expression to the specific function calls it can - be. Specifically, this function deals with typecast expressions - by looking at the type cast values. - -\*******************************************************************/ - +/// To resolve an expression to the specific function calls it can be. +/// Specifically, this function deals with typecast expressions by looking at +/// the type cast values. +/// \param typecast_expr: The typecast expression to resolve to possible +/// function calls +/// \param out_functions: The functions this expression could be +/// \return Returns true if it was able to resolve the typecast expression to +/// some specific functions. If this is the case, out_functions will contain +/// the possible functions. bool remove_const_function_pointerst::try_resolve_typecast_function_call( const typecast_exprt &typecast_expr, functionst &out_functions) { @@ -471,33 +375,20 @@ bool remove_const_function_pointerst::try_resolve_typecast_function_call( } } -/*******************************************************************\ - -Function: remove_const_function_pointerst::try_resolve_expression - - Inputs: - expr - The expression to try and squash - out_resolved_expression - The squashed version of this expression - out_is_const - Is the squashed expression constant - - Outputs: Returns true providing the squashing went OK (note it - may not have squashed anything). The out_resolved_expression will in - this case be all the possible squashed versions of the supplied - expression. - The out_is_const will return whether the squashed value is suitably - const (e.g. if we squashed a struct access, was the struct const). - - Purpose: To squash various expr types to simplify the expression. - ID_index -> dig to find ID_array and get the values out of it - ID_member -> dig to find ID_struct and extract the component value - ID_dereference -> dig to find ID_address_of and extract the value - ID_typecast -> return the value - ID_symbol -> return false, const symbols are squashed first and - non const symbols cannot be squashed - Everything else -> unchanged - -\*******************************************************************/ - +/// To squash various expr types to simplify the expression. ID_index -> dig to +/// find ID_array and get the values out of it ID_member -> dig to find +/// ID_struct and extract the component value ID_dereference -> dig to find +/// ID_address_of and extract the value ID_typecast -> return the value +/// ID_symbol -> return false, const symbols are squashed first and non const +/// symbols cannot be squashed Everything else -> unchanged +/// \param expr: The expression to try and squash +/// \param out_resolved_expression: The squashed version of this expression +/// \param out_is_const: Is the squashed expression constant +/// \return Returns true providing the squashing went OK (note it may not have +/// squashed anything). The out_resolved_expression will in this case be all +/// the possible squashed versions of the supplied expression. The +/// out_is_const will return whether the squashed value is suitably const +/// (e.g. if we squashed a struct access, was the struct const). bool remove_const_function_pointerst::try_resolve_expression( const exprt &expr, expressionst &out_resolved_expression, bool &out_is_const) { @@ -559,25 +450,14 @@ bool remove_const_function_pointerst::try_resolve_expression( } } -/*******************************************************************\ - -Function: remove_const_function_pointerst::try_resolve_index_value - - Inputs: - expr - The expression of the index of the index expression (e.g. - index_exprt::index()) - out_array_index - The constant value the index takes - - Outputs: Returns true if was able to find a constant value for the index - expression. If true, then out_array_index will be the index within - the array that the function pointer is pointing to. - - Purpose: Given an index into an array, resolve, if possible, the index - that is being accessed. This deals with symbols and typecasts to - constant values. - -\*******************************************************************/ - +/// Given an index into an array, resolve, if possible, the index that is being +/// accessed. This deals with symbols and typecasts to constant values. +/// \param expr: The expression of the index of the index expression (e.g. +/// index_exprt::index()) +/// \param out_array_index: The constant value the index takes +/// \return Returns true if was able to find a constant value for the index +/// expression. If true, then out_array_index will be the index within the +/// array that the function pointer is pointing to. bool remove_const_function_pointerst::try_resolve_index_value( const exprt &expr, mp_integer &out_array_index) { @@ -610,28 +490,16 @@ bool remove_const_function_pointerst::try_resolve_index_value( } } -/*******************************************************************\ - -Function: remove_const_function_pointerst::try_resolve_index_of - - Inputs: - index_expr - The index expression to to resolve - out_expressions - The expressions this expression could be - out_is_const - Is the squashed expression constant - - Outputs: Returns true if it was able to squash the index expression - If this is the case, out_expressions will contain - the possible values this index_of could return - The out_is_const will return whether either the array itself - is const, or the values of the array are const. - - Purpose: To squash an index access by first finding the array it is accessing - Then if the index can be resolved, return the squashed value. If - the index can't be determined then squash each value in the array - and return them all. - -\*******************************************************************/ - +/// To squash an index access by first finding the array it is accessing Then if +/// the index can be resolved, return the squashed value. If the index can't be +/// determined then squash each value in the array and return them all. +/// \param index_expr: The index expression to to resolve +/// \param out_expressions: The expressions this expression could be +/// \param out_is_const: Is the squashed expression constant +/// \return Returns true if it was able to squash the index expression If this +/// is the case, out_expressions will contain the possible values this +/// index_of could return The out_is_const will return whether either the +/// array itself is const, or the values of the array are const. bool remove_const_function_pointerst::try_resolve_index_of( const index_exprt &index_expr, expressionst &out_expressions, @@ -701,10 +569,7 @@ bool remove_const_function_pointerst::try_resolve_index_of( for(const exprt &resolved_array_entry : array_contents) { - if(!resolved_array_entry.is_zero()) - { - out_expressions.push_back(resolved_array_entry); - } + out_expressions.push_back(resolved_array_entry); } } } @@ -728,26 +593,14 @@ bool remove_const_function_pointerst::try_resolve_index_of( } } -/*******************************************************************\ - -Function: remove_const_function_pointerst::try_resolve_member - - Inputs: - member_expr - The member expression to resolve. - out_expressions - The expressions this component could be - out_is_const - Is the squashed expression constant - - Outputs: Returns true if it was able to squash the member expression - If this is the case, out_expressions will contain - the possible values this member could return - The out_is_const will return whether the struct - is const. - - Purpose: To squash an member access by first finding the struct it is accessing - Then return the squashed value of the relevant component. - -\*******************************************************************/ - +/// To squash an member access by first finding the struct it is accessing Then +/// return the squashed value of the relevant component. +/// \param member_expr: The member expression to resolve. +/// \param out_expressions: The expressions this component could be +/// \param out_is_const: Is the squashed expression constant +/// \return Returns true if it was able to squash the member expression If this +/// is the case, out_expressions will contain the possible values this member +/// could return The out_is_const will return whether the struct is const. bool remove_const_function_pointerst::try_resolve_member( const member_exprt &member_expr, expressionst &out_expressions, @@ -805,27 +658,16 @@ bool remove_const_function_pointerst::try_resolve_member( } } -/*******************************************************************\ - -Function: remove_const_function_pointerst::try_resolve_dereference - - Inputs: - deref_expr - The dereference expression to resolve. - out_expressions - The expressions this dereference could be - out_is_const - Is the squashed expression constant - - Outputs: Returns true if it was able to squash the dereference expression - If this is the case, out_expressions will contain - the possible values this dereference could return - The out_is_const will return whether the object that gets - dereferenced is constant. - - Purpose: To squash a dereference access by first finding the address_of - the dereference is dereferencing. - Then return the squashed value of the relevant component. - -\*******************************************************************/ - +/// To squash a dereference access by first finding the address_of the +/// dereference is dereferencing. Then return the squashed value of the relevant +/// component. +/// \param deref_expr: The dereference expression to resolve. +/// \param out_expressions: The expressions this dereference could be +/// \param out_is_const: Is the squashed expression constant +/// \return Returns true if it was able to squash the dereference expression If +/// this is the case, out_expressions will contain the possible values this +/// dereference could return The out_is_const will return whether the object +/// that gets dereferenced is constant. bool remove_const_function_pointerst::try_resolve_dereference( const dereference_exprt &deref_expr, expressionst &out_expressions, @@ -890,23 +732,13 @@ bool remove_const_function_pointerst::try_resolve_dereference( } } -/*******************************************************************\ - -Function: remove_const_function_pointerst::try_resolve_dereference - - Inputs: - typecast_expr - The typecast expression to resolve. - out_expressions - The expressions this typecast could be - out_is_const - Is the squashed expression constant - - Outputs: Returns true if it was able to squash the typecast expression - If this is the case, out_expressions will contain - the possible values after removing the typecast. - - Purpose: To squash a typecast access. - -\*******************************************************************/ - +/// To squash a typecast access. +/// \param typecast_expr: The typecast expression to resolve. +/// \param out_expressions: The expressions this typecast could be +/// \param out_is_const: Is the squashed expression constant +/// \return Returns true if it was able to squash the typecast expression If +/// this is the case, out_expressions will contain the possible values after +/// removing the typecast. bool remove_const_function_pointerst::try_resolve_typecast( const typecast_exprt &typecast_expr, expressionst &out_expressions, @@ -934,39 +766,19 @@ bool remove_const_function_pointerst::try_resolve_typecast( } } -/*******************************************************************\ - -Function: remove_const_function_pointerst::is_expression_const - - Inputs: - expression - The expression to check - - Outputs: Returns true if the type of the expression is constant. - - Purpose: To evaluate the const-ness of the expression type. - -\*******************************************************************/ - +/// To evaluate the const-ness of the expression type. +/// \param expression: The expression to check +/// \return Returns true if the type of the expression is constant. bool remove_const_function_pointerst::is_const_expression( const exprt &expression) const { return is_const_type(expression.type()); } -/*******************************************************************\ - -Function: remove_const_function_pointerst::is_type_const - - Inputs: - type - The type to check - - Outputs: Returns true if the type has ID_C_constant or is an array - since arrays are implicitly const in C. - - Purpose: To evaluate the const-ness of the type. - -\*******************************************************************/ - +/// To evaluate the const-ness of the type. +/// \param type: The type to check +/// \return Returns true if the type has ID_C_constant or is an array since +/// arrays are implicitly const in C. bool remove_const_function_pointerst::is_const_type(const typet &type) const { c_qualifierst qualifers(type); @@ -981,21 +793,11 @@ bool remove_const_function_pointerst::is_const_type(const typet &type) const } } -/*******************************************************************\ - -Function: remove_const_function_pointerst::get_component_value - - Inputs: - struct_expr - The expression of the structure being accessed - member_expr - The expression saying which component is being accessed - - Outputs: Returns the value of a specific component for a given struct - expression. - - Purpose: To extract the value of the specific component within a struct - -\*******************************************************************/ - +/// To extract the value of the specific component within a struct +/// \param struct_expr: The expression of the structure being accessed +/// \param member_expr: The expression saying which component is being accessed +/// \return Returns the value of a specific component for a given struct +/// expression. exprt remove_const_function_pointerst::get_component_value( const struct_exprt &struct_expr, const member_exprt &member_expr) { diff --git a/src/goto-programs/remove_const_function_pointers.h b/src/goto-programs/remove_const_function_pointers.h index 6516fb6ec64..469deaec032 100644 --- a/src/goto-programs/remove_const_function_pointers.h +++ b/src/goto-programs/remove_const_function_pointers.h @@ -6,6 +6,9 @@ Author: Thomas Kiley, thomas.kiley@diffblue.com \*******************************************************************/ +/// \file +/// Goto Programs + #ifndef CPROVER_GOTO_PROGRAMS_REMOVE_CONST_FUNCTION_POINTERS_H #define CPROVER_GOTO_PROGRAMS_REMOVE_CONST_FUNCTION_POINTERS_H @@ -24,11 +27,10 @@ class remove_const_function_pointerst:public messaget typedef std::list expressionst; remove_const_function_pointerst( message_handlert &message_handler, - const exprt &base_expression, const namespacet &ns, const symbol_tablet &symbol_table); - bool operator()(functionst &out_functions); + bool operator()(const exprt &base_expression, functionst &out_functions); private: exprt replace_const_symbols(const exprt &expression) const; @@ -90,7 +92,6 @@ class remove_const_function_pointerst:public messaget exprt get_component_value( const struct_exprt &struct_expr, const member_exprt &member_expr); - const exprt original_expression; const namespacet &ns; const symbol_tablet &symbol_table; }; diff --git a/src/goto-programs/remove_exceptions.cpp b/src/goto-programs/remove_exceptions.cpp index e73eba8d2ec..09fe45f2dec 100644 --- a/src/goto-programs/remove_exceptions.cpp +++ b/src/goto-programs/remove_exceptions.cpp @@ -8,6 +8,11 @@ Date: December 2016 \*******************************************************************/ +/// \file +/// Remove exception handling + +#include "remove_exceptions.h" + #ifdef DEBUG #include #endif @@ -15,11 +20,10 @@ Date: December 2016 #include #include +#include #include #include -#include "remove_exceptions.h" - class remove_exceptionst { typedef std::vectormake_assignment(); @@ -134,19 +127,8 @@ void remove_exceptionst::add_exceptional_returns( } } -/*******************************************************************\ - -Function: remove_exceptionst::instrument_exception_handler - -Inputs: - -Outputs: - -Purpose: at the beginning of each handler in function f - adds exc=f#exception_value; f#exception_value=NULL; - -\*******************************************************************/ - +/// at the beginning of each handler in function f adds exc=f#exception_value; +/// f#exception_value=NULL; void remove_exceptionst::instrument_exception_handler( const goto_functionst::function_mapt::iterator &func_it, const goto_programt::instructionst::iterator &instr_it) @@ -165,7 +147,7 @@ void remove_exceptionst::instrument_exception_handler( symbol_table.lookup(id2string(function_id)+EXC_SUFFIX); // next we reset the exceptional return to NULL symbol_exprt lhs_expr_null=function_symbol.symbol_expr(); - null_pointer_exprt rhs_expr_null((pointer_typet(empty_typet()))); + null_pointer_exprt rhs_expr_null(pointer_type(empty_typet())); // add the assignment goto_programt::targett t_null=goto_program.insert_after(instr_it); @@ -190,19 +172,8 @@ void remove_exceptionst::instrument_exception_handler( instr_it->make_skip(); } -/*******************************************************************\ - -Function: remove_exceptionst::instrument_throw - -Inputs: - -Outputs: - -Purpose: instruments each throw with conditional GOTOS to the - corresponding exception handlers - -\*******************************************************************/ - +/// instruments each throw with conditional GOTOS to the corresponding +/// exception handlers void remove_exceptionst::instrument_throw( const goto_functionst::function_mapt::iterator &func_it, const goto_programt::instructionst::iterator &instr_it, @@ -281,19 +252,8 @@ void remove_exceptionst::instrument_throw( instr_it->code=assignment; } -/*******************************************************************\ - -Function: remove_exceptionst::instrument_function_call - -Inputs: - -Outputs: - -Purpose: instruments each function call that may escape exceptions - with conditional GOTOS to the corresponding exception handlers - -\*******************************************************************/ - +/// instruments each function call that may escape exceptions with conditional +/// GOTOS to the corresponding exception handlers void remove_exceptionst::instrument_function_call( const goto_functionst::function_mapt::iterator &func_it, const goto_programt::instructionst::iterator &instr_it, @@ -367,7 +327,7 @@ void remove_exceptionst::instrument_function_call( // add a null check (so that instanceof can be applied) equal_exprt eq_null( callee_exc, - null_pointer_exprt(pointer_typet(empty_typet()))); + null_pointer_exprt(pointer_type(empty_typet()))); goto_programt::targett t_null=goto_program.insert_after(instr_it); t_null->make_goto(next_it); t_null->source_location=instr_it->source_location; @@ -388,20 +348,9 @@ void remove_exceptionst::instrument_function_call( } } -/*******************************************************************\ - -Function: remove_exceptionst::instrument_exceptions - -Inputs: - -Outputs: - -Purpose: instruments throws, function calls that may escape exceptions - and exception handlers. Additionally, it re-computes - the live-range of local variables in order to add DEAD instructions. - -\*******************************************************************/ - +/// instruments throws, function calls that may escape exceptions and exception +/// handlers. Additionally, it re-computes the live-range of local variables in +/// order to add DEAD instructions. void remove_exceptionst::instrument_exceptions( const goto_functionst::function_mapt::iterator &func_it) { @@ -438,7 +387,7 @@ void remove_exceptionst::instrument_exceptions( else { #ifdef DEBUG - std::cout << "Remove exceptions: empty stack" << std::endl; + std::cout << "Remove exceptions: empty stack\n"; #endif } } @@ -484,18 +433,6 @@ void remove_exceptionst::instrument_exceptions( } } -/*******************************************************************\ - -Function: remove_exceptionst::operator() - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void remove_exceptionst::operator()(goto_functionst &goto_functions) { Forall_goto_functions(it, goto_functions) @@ -504,18 +441,7 @@ void remove_exceptionst::operator()(goto_functionst &goto_functions) instrument_exceptions(it); } -/*******************************************************************\ - -Function: remove_exceptions - -Inputs: - -Outputs: - -Purpose: removes throws/CATCH-POP/CATCH-PUSH - -\*******************************************************************/ - +/// removes throws/CATCH-POP/CATCH-PUSH void remove_exceptions( symbol_tablet &symbol_table, goto_functionst &goto_functions) @@ -524,18 +450,7 @@ void remove_exceptions( remove_exceptions(goto_functions); } -/*******************************************************************\ - -Function: remove_exceptions - -Inputs: - -Outputs: - -Purpose: removes throws/CATCH-POP/CATCH-PUSH - -\*******************************************************************/ - +/// removes throws/CATCH-POP/CATCH-PUSH void remove_exceptions(goto_modelt &goto_model) { remove_exceptionst remove_exceptions(goto_model.symbol_table); diff --git a/src/goto-programs/remove_exceptions.h b/src/goto-programs/remove_exceptions.h index 89162b5833d..47cf349cf13 100644 --- a/src/goto-programs/remove_exceptions.h +++ b/src/goto-programs/remove_exceptions.h @@ -8,6 +8,9 @@ Date: December 2016 \*******************************************************************/ +/// \file +/// Remove function exceptional returns + #ifndef CPROVER_GOTO_PROGRAMS_REMOVE_EXCEPTIONS_H #define CPROVER_GOTO_PROGRAMS_REMOVE_EXCEPTIONS_H diff --git a/src/goto-programs/remove_function_pointers.cpp b/src/goto-programs/remove_function_pointers.cpp index 2d5be9c0ab2..bec1ce5ea47 100644 --- a/src/goto-programs/remove_function_pointers.cpp +++ b/src/goto-programs/remove_function_pointers.cpp @@ -6,34 +6,30 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Program Transformation + +#include "remove_function_pointers.h" + #include #include #include #include #include -#include #include #include #include #include #include +#include -#include +#include #include "remove_skip.h" -#include "remove_function_pointers.h" #include "compute_called_functions.h" #include "remove_const_function_pointers.h" -/*******************************************************************\ - - Class: remove_function_pointerst - - Purpose: - -\*******************************************************************/ - class remove_function_pointerst:public messaget { public: @@ -54,7 +50,7 @@ class remove_function_pointerst:public messaget bool add_safety_assertion; // We can optionally halt the FP removal if we aren't able to use - // remove_const_function_pointerst to sucessfully narrow to a small + // remove_const_function_pointerst to successfully narrow to a small // subset of possible functions and just leave the function pointer // as it is. // This can be activated in goto-instrument using @@ -94,18 +90,6 @@ class remove_function_pointerst:public messaget } }; -/*******************************************************************\ - -Function: remove_function_pointerst::remove_function_pointerst - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - remove_function_pointerst::remove_function_pointerst( message_handlert &_message_handler, symbol_tablet &_symbol_table, @@ -125,18 +109,6 @@ remove_function_pointerst::remove_function_pointerst( type_map[f_it->first]=f_it->second.type; } -/*******************************************************************\ - -Function: remove_function_pointerst::arg_is_type_compatible - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool remove_function_pointerst::arg_is_type_compatible( const typet &call_type, const typet &function_type) @@ -169,18 +141,6 @@ bool remove_function_pointerst::arg_is_type_compatible( return false; } -/*******************************************************************\ - -Function: remove_function_pointerst::is_type_compatible - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool remove_function_pointerst::is_type_compatible( bool return_value_used, const code_typet &call_type, @@ -231,18 +191,6 @@ bool remove_function_pointerst::is_type_compatible( return true; } -/*******************************************************************\ - -Function: remove_function_pointerst::fix_argument_types - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void remove_function_pointerst::fix_argument_types( code_function_callt &function_call) { @@ -268,18 +216,6 @@ void remove_function_pointerst::fix_argument_types( } } -/*******************************************************************\ - -Function: remove_function_pointerst::fix_return_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void remove_function_pointerst::fix_return_type( code_function_callt &function_call, goto_programt &dest) @@ -319,18 +255,6 @@ void remove_function_pointerst::fix_return_type( old_lhs, typecast_exprt(tmp_symbol_expr, old_lhs.type())); } -/*******************************************************************\ - -Function: remove_function_pointerst::remove_function_pointer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void remove_function_pointerst::remove_function_pointer( goto_programt &goto_program, goto_programt::targett target) @@ -370,14 +294,15 @@ void remove_function_pointerst::remove_function_pointer( else { remove_const_function_pointerst fpr( - get_message_handler(), pointer, ns, symbol_table); + get_message_handler(), ns, symbol_table); - found_functions=fpr(functions); + found_functions=fpr(pointer, functions); - // Either found_functions is true therefore the functions should not - // be empty - // Or found_functions is false therefore the functions should be empty - assert(found_functions != functions.empty()); + // if found_functions is false, functions should be empty + // however, it is possible for found_functions to be true and functions + // to be empty (this happens if the pointer can only resolve to the null + // pointer) + CHECK_RETURN(found_functions || functions.empty()); if(functions.size()==1) { @@ -391,7 +316,7 @@ void remove_function_pointerst::remove_function_pointer( if(only_resolve_const_fps) { // If this mode is enabled, we only remove function pointers - // that we can resolve either to an exact funciton, or an exact subset + // that we can resolve either to an exact function, or an exact subset // (e.g. a variable index in a constant array). // Since we haven't found functions, we would now resort to // replacing the function pointer with any function with a valid signature @@ -450,10 +375,7 @@ void remove_function_pointerst::remove_function_pointer( t3->make_goto(t_final, true_exprt()); // goto to call - address_of_exprt address_of; - address_of.object()=fun; - address_of.type()=pointer_typet(); - address_of.type().subtype()=fun.type(); + address_of_exprt address_of(fun, pointer_type(fun.type())); if(address_of.type()!=pointer.type()) address_of.make_typecast(pointer.type()); @@ -510,18 +432,6 @@ void remove_function_pointerst::remove_function_pointer( << functions.size() << " possible targets" << eom; } -/*******************************************************************\ - -Function: remove_function_pointerst::remove_function_pointers - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool remove_function_pointerst::remove_function_pointers( goto_programt &goto_program) { @@ -549,18 +459,6 @@ bool remove_function_pointerst::remove_function_pointers( return did_something; } -/*******************************************************************\ - -Function: remove_function_pointerst::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void remove_function_pointerst::operator()(goto_functionst &functions) { bool did_something=false; @@ -580,18 +478,6 @@ void remove_function_pointerst::operator()(goto_functionst &functions) functions.compute_location_numbers(); } -/*******************************************************************\ - -Function: remove_function_pointers - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool remove_function_pointers(message_handlert &_message_handler, symbol_tablet &symbol_table, const goto_functionst &goto_functions, @@ -610,18 +496,6 @@ bool remove_function_pointers(message_handlert &_message_handler, return rfp.remove_function_pointers(goto_program); } -/*******************************************************************\ - -Function: remove_function_pointers - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void remove_function_pointers( message_handlert &_message_handler, symbol_tablet &symbol_table, @@ -640,18 +514,6 @@ void remove_function_pointers( rfp(goto_functions); } -/*******************************************************************\ - -Function: remove_function_pointers - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void remove_function_pointers(message_handlert &_message_handler, goto_modelt &goto_model, bool add_safety_assertion, diff --git a/src/goto-programs/remove_function_pointers.h b/src/goto-programs/remove_function_pointers.h index e8eea37ea75..3038a940637 100644 --- a/src/goto-programs/remove_function_pointers.h +++ b/src/goto-programs/remove_function_pointers.h @@ -8,6 +8,9 @@ Date: June 2003 \*******************************************************************/ +/// \file +/// Remove Indirect Function Calls + #ifndef CPROVER_GOTO_PROGRAMS_REMOVE_FUNCTION_POINTERS_H #define CPROVER_GOTO_PROGRAMS_REMOVE_FUNCTION_POINTERS_H diff --git a/src/goto-programs/remove_instanceof.cpp b/src/goto-programs/remove_instanceof.cpp index 3fc2699ef47..bc76c7e5991 100644 --- a/src/goto-programs/remove_instanceof.cpp +++ b/src/goto-programs/remove_instanceof.cpp @@ -6,9 +6,14 @@ Author: Chris Smowton, chris.smowton@diffblue.com \*******************************************************************/ +/// \file +/// Remove Instance-of Operators + +#include "remove_instanceof.h" + #include "class_hierarchy.h" #include "class_identifier.h" -#include "remove_instanceof.h" + #include #include @@ -54,19 +59,10 @@ class remove_instanceoft bool contains_instanceof(const exprt &); }; -/*******************************************************************\ - -Function: remove_instanceoft::contains_instanceof - - Inputs: Expression `expr` - - Outputs: Returns true if `expr` contains any instanceof ops - - Purpose: Avoid breaking sharing by checking for instanceof - before calling lower_instanceof. - -\*******************************************************************/ - +/// Avoid breaking sharing by checking for instanceof before calling +/// lower_instanceof. +/// \par parameters: Expression `expr` +/// \return Returns true if `expr` contains any instanceof ops bool remove_instanceoft::contains_instanceof( const exprt &expr) { @@ -78,24 +74,12 @@ bool remove_instanceoft::contains_instanceof( return false; } -/*******************************************************************\ - -Function: remove_instanceoft::lower_instanceof - - Inputs: Expression to lower `expr` and the `goto_program` and - instruction `this_inst` it belongs to. - - Outputs: Side-effect on `expr` replacing it with an explicit clsid test - - Purpose: Replaces an expression like - e instanceof A - with - e.@class_identifier == "A" - Or a big-or of similar expressions if we know of subtypes - that also satisfy the given test. - -\*******************************************************************/ - +/// Replaces an expression like e instanceof A with e.@class_identifier == "A" +/// Or a big-or of similar expressions if we know of subtypes that also satisfy +/// the given test. +/// \par parameters: Expression to lower `expr` and the `goto_program` and +/// instruction `this_inst` it belongs to. +/// \return Side-effect on `expr` replacing it with an explicit clsid test void remove_instanceoft::lower_instanceof( exprt &expr, goto_programt &goto_program, @@ -163,20 +147,12 @@ void remove_instanceoft::lower_instanceof( } } -/*******************************************************************\ - -Function: remove_instanceoft::lower_instanceof - - Inputs: GOTO program instruction `target` whose instanceof expressions, - if any, should be replaced with explicit tests, and the - `goto_program` it is part of. - - Outputs: Side-effect on `target` as above. - - Purpose: See function above - -\*******************************************************************/ - +/// See function above +/// \par parameters: GOTO program instruction `target` whose instanceof +/// expressions, +/// if any, should be replaced with explicit tests, and the +/// `goto_program` it is part of. +/// \return Side-effect on `target` as above. void remove_instanceoft::lower_instanceof( goto_programt &goto_program, goto_programt::targett target, @@ -197,18 +173,10 @@ void remove_instanceoft::lower_instanceof( lower_instanceof(target->guard, goto_program, target, inst_switch); } -/*******************************************************************\ - -Function: remove_instanceoft::lower_instanceof - - Inputs: `goto_program`, all of whose instanceof expressions will - be replaced by explicit class-identifier tests. - - Outputs: Side-effect on `goto_program` as above. - - Purpose: See function above - -\*******************************************************************/ +/// See function above +/// \par parameters: `goto_program`, all of whose instanceof expressions will +/// be replaced by explicit class-identifier tests. +/// \return Side-effect on `goto_program` as above. bool remove_instanceoft::lower_instanceof(goto_programt &goto_program) { instanceof_instt inst_switch; @@ -229,19 +197,9 @@ bool remove_instanceoft::lower_instanceof(goto_programt &goto_program) return false; } -/*******************************************************************\ - -Function: remove_instanceoft::lower_instanceof - - Inputs: None - - Outputs: Side-effects on this->goto_functions, replacing every - instanceof in every function with an explicit test. - - Purpose: See function above - -\*******************************************************************/ - +/// See function above +/// \return Side-effects on this->goto_functions, replacing every instanceof in +/// every function with an explicit test. void remove_instanceoft::lower_instanceof() { bool changed=false; @@ -251,22 +209,12 @@ void remove_instanceoft::lower_instanceof() goto_functions.compute_location_numbers(); } -/*******************************************************************\ - -Function: remove_instanceof - - Inputs: `goto_functions`, a function map, and the corresponding - `symbol_table`. - - Outputs: Side-effects on goto_functions, replacing every - instanceof in every function with an explicit test. - Extra auxiliary variables may be introduced into - `symbol_table`. - - Purpose: See function above - -\*******************************************************************/ - +/// See function above +/// \par parameters: `goto_functions`, a function map, and the corresponding +/// `symbol_table`. +/// \return Side-effects on goto_functions, replacing every instanceof in every +/// function with an explicit test. Extra auxiliary variables may be +/// introduced into `symbol_table`. void remove_instanceof( symbol_tablet &symbol_table, goto_functionst &goto_functions) diff --git a/src/goto-programs/remove_instanceof.h b/src/goto-programs/remove_instanceof.h index 7b4682ba9bf..15a02bf35b2 100644 --- a/src/goto-programs/remove_instanceof.h +++ b/src/goto-programs/remove_instanceof.h @@ -6,6 +6,9 @@ Author: Chris Smowton, chris.smowton@diffblue.com \*******************************************************************/ +/// \file +/// Remove Instance-of Operators + #ifndef CPROVER_GOTO_PROGRAMS_REMOVE_INSTANCEOF_H #define CPROVER_GOTO_PROGRAMS_REMOVE_INSTANCEOF_H diff --git a/src/goto-programs/remove_returns.cpp b/src/goto-programs/remove_returns.cpp index 9ca6554275c..d74e135693b 100644 --- a/src/goto-programs/remove_returns.cpp +++ b/src/goto-programs/remove_returns.cpp @@ -8,11 +8,14 @@ Date: September 2009 \*******************************************************************/ -#include -#include +/// \file +/// Remove function return values #include "remove_returns.h" +#include +#include + class remove_returnst { public: @@ -45,18 +48,7 @@ class remove_returnst goto_programt &goto_program); }; -/*******************************************************************\ - -Function: remove_returnst::replace_returns - -Inputs: - -Outputs: - -Purpose: turns 'return x' into an assignment to fkt#return_value - -\*******************************************************************/ - +/// turns 'return x' into an assignment to fkt#return_value void remove_returnst::replace_returns( goto_functionst::function_mapt::iterator f_it) { @@ -121,18 +113,7 @@ void remove_returnst::replace_returns( } } -/*******************************************************************\ - -Function: remove_returnst::do_function_calls - -Inputs: - -Outputs: - -Purpose: turns x=f(...) into f(...); lhs=f#return_value; - -\*******************************************************************/ - +/// turns x=f(...) into f(...); lhs=f#return_value; void remove_returnst::do_function_calls( goto_functionst &goto_functions, goto_programt &goto_program) @@ -208,18 +189,6 @@ void remove_returnst::do_function_calls( } } -/*******************************************************************\ - -Function: remove_returnst::operator() - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void remove_returnst::operator()(goto_functionst &goto_functions) { Forall_goto_functions(it, goto_functions) @@ -229,18 +198,7 @@ void remove_returnst::operator()(goto_functionst &goto_functions) } } -/*******************************************************************\ - -Function: remove_returns - -Inputs: - -Outputs: - -Purpose: removes returns - -\*******************************************************************/ - +/// removes returns void remove_returns( symbol_tablet &symbol_table, goto_functionst &goto_functions) @@ -249,36 +207,13 @@ void remove_returns( rr(goto_functions); } -/*******************************************************************\ - -Function: remove_returns - -Inputs: - -Outputs: - -Purpose: removes returns - -\*******************************************************************/ - +/// removes returns void remove_returns(goto_modelt &goto_model) { remove_returnst rr(goto_model.symbol_table); rr(goto_model.goto_functions); } -/*******************************************************************\ - -Function: original_return_type - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - code_typet original_return_type( const symbol_tablet &symbol_table, const irep_idt &function_id) @@ -307,18 +242,7 @@ code_typet original_return_type( return type; } -/*******************************************************************\ - -Function: remove_returnst::restore_returns - -Inputs: - -Outputs: - -Purpose: turns 'return x' into an assignment to fkt#return_value - -\*******************************************************************/ - +/// turns 'return x' into an assignment to fkt#return_value bool remove_returnst::restore_returns( goto_functionst::function_mapt::iterator f_it) { @@ -391,18 +315,7 @@ bool remove_returnst::restore_returns( return false; } -/*******************************************************************\ - -Function: remove_returnst::undo_function_calls - -Inputs: - -Outputs: - -Purpose: turns f(...); lhs=f#return_value; into x=f(...) - -\*******************************************************************/ - +/// turns f(...); lhs=f#return_value; into x=f(...) void remove_returnst::undo_function_calls( goto_functionst &goto_functions, goto_programt &goto_program) @@ -461,18 +374,6 @@ void remove_returnst::undo_function_calls( } } -/*******************************************************************\ - -Function: remove_returnst::restore() - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void remove_returnst::restore(goto_functionst &goto_functions) { // restore all types first @@ -487,18 +388,7 @@ void remove_returnst::restore(goto_functionst &goto_functions) } } -/*******************************************************************\ - -Function: restore_returns - -Inputs: - -Outputs: - -Purpose: restores return statements - -\*******************************************************************/ - +/// restores return statements void restore_returns( symbol_tablet &symbol_table, goto_functionst &goto_functions) diff --git a/src/goto-programs/remove_returns.h b/src/goto-programs/remove_returns.h index 453d8a7be7f..d4e50cae57b 100644 --- a/src/goto-programs/remove_returns.h +++ b/src/goto-programs/remove_returns.h @@ -8,6 +8,9 @@ Date: September 2009 \*******************************************************************/ +/// \file +/// Remove function returns + #ifndef CPROVER_GOTO_PROGRAMS_REMOVE_RETURNS_H #define CPROVER_GOTO_PROGRAMS_REMOVE_RETURNS_H diff --git a/src/goto-programs/remove_skip.cpp b/src/goto-programs/remove_skip.cpp index dedeb8aca2a..816960b1ea0 100644 --- a/src/goto-programs/remove_skip.cpp +++ b/src/goto-programs/remove_skip.cpp @@ -6,19 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "remove_skip.h" - -/*******************************************************************\ - -Function: is_skip - - Inputs: - - Outputs: - - Purpose: +/// \file +/// Program Transformation -\*******************************************************************/ +#include "remove_skip.h" static bool is_skip(goto_programt::instructionst::iterator it) { @@ -76,18 +67,7 @@ static bool is_skip(goto_programt::instructionst::iterator it) return false; } -/*******************************************************************\ - -Function: remove_skip - - Inputs: - - Outputs: - - Purpose: remove unnecessary skip statements - -\*******************************************************************/ - +/// remove unnecessary skip statements void remove_skip(goto_programt &goto_program) { // This needs to be a fixed-point, as @@ -174,18 +154,7 @@ void remove_skip(goto_programt &goto_program) while(goto_program.instructions.size() #include #include #include -#include "remove_static_init_loops.h" - class remove_static_init_loopst { public: @@ -29,19 +32,10 @@ class remove_static_init_loopst const symbol_tablet &symbol_table; }; -/*******************************************************************\ - -Function: unwind_enum_static - - Inputs: goto_functions and options - - Outputs: side effect is adding loops to unwindset - - Purpose: unwind static initialization loops of Java enums as far as - the enum has elements, thus flattening them completely - -\*******************************************************************/ - +/// unwind static initialization loops of Java enums as far as the enum has +/// elements, thus flattening them completely +/// \par parameters: goto_functions and options +/// \return side effect is adding loops to unwindset void remove_static_init_loopst::unwind_enum_static( const goto_functionst &goto_functions, optionst &options) @@ -95,19 +89,10 @@ void remove_static_init_loopst::unwind_enum_static( } } -/*******************************************************************\ - -Function: remove_static_init_loops - - Inputs: symbol table, goto_functions and options - - Outputs: side effect is adding loops to unwindset - - Purpose: this is the entry point for the removal of loops in static - initialization code of Java enums - -\*******************************************************************/ - +/// this is the entry point for the removal of loops in static initialization +/// code of Java enums +/// \par parameters: symbol table, goto_functions and options +/// \return side effect is adding loops to unwindset void remove_static_init_loops( const symbol_tablet &symbol_table, const goto_functionst &goto_functions, diff --git a/src/goto-programs/remove_static_init_loops.h b/src/goto-programs/remove_static_init_loops.h index dd07ec6a670..eee270215a2 100644 --- a/src/goto-programs/remove_static_init_loops.h +++ b/src/goto-programs/remove_static_init_loops.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Unwind loops in static initializers + #include #include diff --git a/src/goto-programs/remove_unreachable.cpp b/src/goto-programs/remove_unreachable.cpp index 14f92e97be1..562546f377b 100644 --- a/src/goto-programs/remove_unreachable.cpp +++ b/src/goto-programs/remove_unreachable.cpp @@ -6,23 +6,15 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include -#include +/// \file +/// Program Transformation #include "remove_unreachable.h" -/*******************************************************************\ - -Function: remove_unreachable - - Inputs: - - Outputs: - - Purpose: remove unreachable code - -\*******************************************************************/ +#include +#include +/// remove unreachable code void remove_unreachable(goto_programt &goto_program) { std::set reachable; @@ -55,3 +47,13 @@ void remove_unreachable(goto_programt &goto_program) it->make_skip(); } } + +/// Removes unreachable instructions from all functions. +/// \par parameters: The goto functions from which the unreachable functions are +/// to be removed. +/// \return None. +void remove_unreachable(goto_functionst &goto_functions) +{ + Forall_goto_functions(f_it, goto_functions) + remove_unreachable(f_it->second.body); +} diff --git a/src/goto-programs/remove_unreachable.h b/src/goto-programs/remove_unreachable.h index 694cd8c0af8..5267529d364 100644 --- a/src/goto-programs/remove_unreachable.h +++ b/src/goto-programs/remove_unreachable.h @@ -6,11 +6,15 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Program Transformation + #ifndef CPROVER_GOTO_PROGRAMS_REMOVE_UNREACHABLE_H #define CPROVER_GOTO_PROGRAMS_REMOVE_UNREACHABLE_H #include "goto_functions.h" void remove_unreachable(goto_programt &goto_program); +void remove_unreachable(goto_functionst &goto_functions); #endif // CPROVER_GOTO_PROGRAMS_REMOVE_UNREACHABLE_H diff --git a/src/goto-programs/remove_unused_functions.cpp b/src/goto-programs/remove_unused_functions.cpp index 860af2e1d73..fd2d8cca614 100644 --- a/src/goto-programs/remove_unused_functions.cpp +++ b/src/goto-programs/remove_unused_functions.cpp @@ -6,21 +6,12 @@ Author: CM Wintersteiger \*******************************************************************/ -#include +/// \file +/// Unused function removal #include "remove_unused_functions.h" -/*******************************************************************\ - -Function: remove_unused_functions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void remove_unused_functions( goto_functionst &functions, @@ -42,7 +33,7 @@ void remove_unused_functions( messaget message(message_handler); - if(unused_functions.size()>0) + if(!unused_functions.empty()) { message.statistics() << "Dropping " << unused_functions.size() << " of " << @@ -54,18 +45,6 @@ void remove_unused_functions( functions.function_map.erase(f); } -/*******************************************************************\ - -Function: find_used_functions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void find_used_functions( const irep_idt &start, goto_functionst &functions, diff --git a/src/goto-programs/remove_unused_functions.h b/src/goto-programs/remove_unused_functions.h index b571de4e059..550d657f299 100644 --- a/src/goto-programs/remove_unused_functions.h +++ b/src/goto-programs/remove_unused_functions.h @@ -6,6 +6,9 @@ Author: CM Wintersteiger \*******************************************************************/ +/// \file +/// Unused function removal + #ifndef CPROVER_GOTO_PROGRAMS_REMOVE_UNUSED_FUNCTIONS_H #define CPROVER_GOTO_PROGRAMS_REMOVE_UNUSED_FUNCTIONS_H diff --git a/src/goto-programs/remove_vector.cpp b/src/goto-programs/remove_vector.cpp index f7b63e42d4f..c0e90033968 100644 --- a/src/goto-programs/remove_vector.cpp +++ b/src/goto-programs/remove_vector.cpp @@ -8,21 +8,12 @@ Date: September 2014 \*******************************************************************/ -#include +/// \file +/// Remove 'vector' data type #include "remove_vector.h" -/*******************************************************************\ - -Function: have_to_remove_vector - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ +#include static bool have_to_remove_vector(const typet &type); @@ -51,18 +42,6 @@ static bool have_to_remove_vector(const exprt &expr) return false; } -/*******************************************************************\ - -Function: have_to_remove_vector - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - static bool have_to_remove_vector(const typet &type) { if(type.id()==ID_struct || type.id()==ID_union) @@ -87,18 +66,7 @@ static bool have_to_remove_vector(const typet &type) return false; } -/*******************************************************************\ - -Function: remove_vector - -Inputs: - -Outputs: - -Purpose: removes vector data type - -\*******************************************************************/ - +/// removes vector data type static void remove_vector(typet &); static void remove_vector(exprt &expr) @@ -174,18 +142,7 @@ static void remove_vector(exprt &expr) remove_vector(expr.type()); } -/*******************************************************************\ - -Function: remove_vector - -Inputs: - -Outputs: - -Purpose: removes vector data type - -\*******************************************************************/ - +/// removes vector data type static void remove_vector(typet &type) { if(!have_to_remove_vector(type)) @@ -223,54 +180,21 @@ static void remove_vector(typet &type) } } -/*******************************************************************\ - -Function: remove_vector - -Inputs: - -Outputs: - -Purpose: removes vector data type - -\*******************************************************************/ - +/// removes vector data type static void remove_vector(symbolt &symbol) { remove_vector(symbol.value); remove_vector(symbol.type); } -/*******************************************************************\ - -Function: remove_vector - -Inputs: - -Outputs: - -Purpose: removes vector data type - -\*******************************************************************/ - +/// removes vector data type static void remove_vector(symbol_tablet &symbol_table) { Forall_symbols(it, symbol_table.symbols) remove_vector(it->second); } -/*******************************************************************\ - -Function: remove_vector - -Inputs: - -Outputs: - -Purpose: removes vector data type - -\*******************************************************************/ - +/// removes vector data type void remove_vector(goto_functionst::goto_functiont &goto_function) { remove_vector(goto_function.type); @@ -282,36 +206,14 @@ void remove_vector(goto_functionst::goto_functiont &goto_function) } } -/*******************************************************************\ - -Function: remove_vector - -Inputs: - -Outputs: - -Purpose: removes vector data type - -\*******************************************************************/ - +/// removes vector data type static void remove_vector(goto_functionst &goto_functions) { Forall_goto_functions(it, goto_functions) remove_vector(it->second); } -/*******************************************************************\ - -Function: remove_vector - -Inputs: - -Outputs: - -Purpose: removes vector data type - -\*******************************************************************/ - +/// removes vector data type void remove_vector( symbol_tablet &symbol_table, goto_functionst &goto_functions) @@ -320,18 +222,7 @@ void remove_vector( remove_vector(goto_functions); } -/*******************************************************************\ - -Function: remove_vector - -Inputs: - -Outputs: - -Purpose: removes vector data type - -\*******************************************************************/ - +/// removes vector data type void remove_vector(goto_modelt &goto_model) { remove_vector(goto_model.symbol_table, goto_model.goto_functions); diff --git a/src/goto-programs/remove_vector.h b/src/goto-programs/remove_vector.h index ffcb58421b4..960d75953a8 100644 --- a/src/goto-programs/remove_vector.h +++ b/src/goto-programs/remove_vector.h @@ -8,6 +8,9 @@ Date: September 2014 \*******************************************************************/ +/// \file +/// Remove the 'vector' data type by compilation into arrays + #ifndef CPROVER_GOTO_PROGRAMS_REMOVE_VECTOR_H #define CPROVER_GOTO_PROGRAMS_REMOVE_VECTOR_H diff --git a/src/goto-programs/remove_virtual_functions.cpp b/src/goto-programs/remove_virtual_functions.cpp index fde2f5f8405..5ae06fceeb0 100644 --- a/src/goto-programs/remove_virtual_functions.cpp +++ b/src/goto-programs/remove_virtual_functions.cpp @@ -6,20 +6,16 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include -#include +/// \file +/// Remove Virtual Function (Method) Calls +#include "remove_virtual_functions.h" #include "class_hierarchy.h" #include "class_identifier.h" -#include "remove_virtual_functions.h" - -/*******************************************************************\ - Class: remove_virtual_functionst - - Purpose: - -\*******************************************************************/ +#include +#include +#include class remove_virtual_functionst { @@ -67,18 +63,6 @@ class remove_virtual_functionst const irep_idt &component_name) const; }; -/*******************************************************************\ - -Function: remove_virtual_functionst::remove_virtual_functionst - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - remove_virtual_functionst::remove_virtual_functionst( const symbol_tablet &_symbol_table, const goto_functionst &goto_functions): @@ -88,18 +72,6 @@ remove_virtual_functionst::remove_virtual_functionst( class_hierarchy(symbol_table); } -/*******************************************************************\ - -Function: remove_virtual_functionst::remove_virtual_function - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void remove_virtual_functionst::remove_virtual_function( goto_programt &goto_program, goto_programt::targett target) @@ -175,7 +147,8 @@ void remove_virtual_functionst::remove_virtual_function( t1->make_function_call(code); auto &newcall=to_code_function_call(t1->code); newcall.function()=fun.symbol_expr; - pointer_typet need_type(symbol_typet(fun.symbol_expr.get(ID_C_class))); + typet need_type= + pointer_type(symbol_typet(fun.symbol_expr.get(ID_C_class))); if(!type_eq(newcall.arguments()[0].type(), need_type, ns)) newcall.arguments()[0].make_typecast(need_type); } @@ -231,28 +204,17 @@ void remove_virtual_functionst::remove_virtual_function( target->make_skip(); } -/*******************************************************************\ - -Function: remove_virtual_functionst::get_child_functions_rec - - Inputs: `this_id`: class name - `last_method_defn`: the most-derived parent of `this_id` - to define the requested function - `component_name`: name of the function searched for - - Outputs: `functions` is assigned a list of {class name, function symbol} - pairs indicating that if `this` is of the given class, then the - call will target the given function. Thus if A <: B <: C and A - and C provide overrides of `f` (but B does not), - get_child_functions_rec("C", C.f, "f") -> [{"C", C.f}, - {"B", C.f}, - {"A", A.f}] - - Purpose: Used by get_functions to track the most-derived parent that - provides an override of a given function. - -\*******************************************************************/ - +/// Used by get_functions to track the most-derived parent that provides an +/// override of a given function. +/// \par parameters: `this_id`: class name +/// `last_method_defn`: the most-derived parent of `this_id` to define the +/// requested function +/// `component_name`: name of the function searched for +/// \return `functions` is assigned a list of {class name, function symbol} +/// pairs indicating that if `this` is of the given class, then the call will +/// target the given function. Thus if A <: B <: C and A and C provide +/// overrides of `f` (but B does not), get_child_functions_rec("C", C.f, "f") +/// -> [{"C", C.f}, {"B", C.f}, {"A", A.f}] void remove_virtual_functionst::get_child_functions_rec( const irep_idt &this_id, const symbol_exprt &last_method_defn, @@ -290,18 +252,6 @@ void remove_virtual_functionst::get_child_functions_rec( } } -/*******************************************************************\ - -Function: remove_virtual_functionst::get_functions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void remove_virtual_functionst::get_functions( const exprt &function, functionst &functions) @@ -352,18 +302,6 @@ void remove_virtual_functionst::get_functions( functions.push_back(root_function); } -/*******************************************************************\ - -Function: remove_virtual_functionst::get_method - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt remove_virtual_functionst::get_method( const irep_idt &class_id, const irep_idt &component_name) const @@ -378,18 +316,6 @@ exprt remove_virtual_functionst::get_method( return symbol->symbol_expr(); } -/*******************************************************************\ - -Function: remove_virtual_functionst::remove_virtual_functions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool remove_virtual_functionst::remove_virtual_functions( goto_programt &goto_program) { @@ -416,18 +342,6 @@ bool remove_virtual_functionst::remove_virtual_functions( return did_something; } -/*******************************************************************\ - -Function: remove_virtual_functionst::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void remove_virtual_functionst::operator()(goto_functionst &functions) { bool did_something=false; @@ -447,18 +361,6 @@ void remove_virtual_functionst::operator()(goto_functionst &functions) functions.compute_location_numbers(); } -/*******************************************************************\ - -Function: remove_virtual_functions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void remove_virtual_functions( const symbol_tablet &symbol_table, goto_functionst &goto_functions) @@ -469,18 +371,6 @@ void remove_virtual_functions( rvf(goto_functions); } -/*******************************************************************\ - -Function: remove_virtual_functions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void remove_virtual_functions(goto_modelt &goto_model) { remove_virtual_functions( diff --git a/src/goto-programs/remove_virtual_functions.h b/src/goto-programs/remove_virtual_functions.h index 0fec71a318f..af83cf57e4d 100644 --- a/src/goto-programs/remove_virtual_functions.h +++ b/src/goto-programs/remove_virtual_functions.h @@ -8,6 +8,9 @@ Date: April 2016 \*******************************************************************/ +/// \file +/// Remove Virtual Function (Method) Calls + #ifndef CPROVER_GOTO_PROGRAMS_REMOVE_VIRTUAL_FUNCTIONS_H #define CPROVER_GOTO_PROGRAMS_REMOVE_VIRTUAL_FUNCTIONS_H diff --git a/src/goto-programs/safety_checker.cpp b/src/goto-programs/safety_checker.cpp index 275cffbbe09..b1236c08dc7 100644 --- a/src/goto-programs/safety_checker.cpp +++ b/src/goto-programs/safety_checker.cpp @@ -6,37 +6,16 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "safety_checker.h" - -/*******************************************************************\ - -Function: safety_checkert::safety_checkert - - Inputs: +/// \file +/// Safety Checker Interface - Outputs: - - Purpose: - -\*******************************************************************/ +#include "safety_checker.h" safety_checkert::safety_checkert(const namespacet &_ns): ns(_ns) { } -/*******************************************************************\ - -Function: safety_checkert::safety_checkert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - safety_checkert::safety_checkert( const namespacet &_ns, message_handlert &_message_handler): diff --git a/src/goto-programs/safety_checker.h b/src/goto-programs/safety_checker.h index f4c4c3694ba..bb1492d6f53 100644 --- a/src/goto-programs/safety_checker.h +++ b/src/goto-programs/safety_checker.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Safety Checker Interface + #ifndef CPROVER_GOTO_PROGRAMS_SAFETY_CHECKER_H #define CPROVER_GOTO_PROGRAMS_SAFETY_CHECKER_H @@ -26,7 +29,7 @@ class safety_checkert:public messaget const namespacet &_ns, message_handlert &_message_handler); - typedef enum { SAFE, UNSAFE, ERROR } resultt; + enum class resultt { SAFE, UNSAFE, ERROR }; // check whether all assertions in goto_functions are safe // if UNSAFE, then a trace is returned diff --git a/src/goto-programs/set_properties.cpp b/src/goto-programs/set_properties.cpp index fc79d4dcfe7..5861d8d2fda 100644 --- a/src/goto-programs/set_properties.cpp +++ b/src/goto-programs/set_properties.cpp @@ -6,23 +6,13 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include -#include - +/// \file +/// Set Properties #include "set_properties.h" -/*******************************************************************\ - -Function: set_properties - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include void set_properties( goto_programt &goto_program, @@ -48,35 +38,11 @@ void set_properties( } } -/*******************************************************************\ - -Function: label_properties - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void label_properties(goto_modelt &goto_model) { label_properties(goto_model.goto_functions); } -/*******************************************************************\ - -Function: label_properties - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void label_properties( goto_programt &goto_program, std::map &property_counters) @@ -119,36 +85,12 @@ void label_properties( } } -/*******************************************************************\ - -Function: label_properties - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void label_properties(goto_programt &goto_program) { std::map property_counters; label_properties(goto_program, property_counters); } -/*******************************************************************\ - -Function: set_properties - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void set_properties( goto_modelt &goto_model, const std::list &properties) @@ -156,18 +98,6 @@ void set_properties( set_properties(goto_model.goto_functions, properties); } -/*******************************************************************\ - -Function: set_properties - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void set_properties( goto_functionst &goto_functions, const std::list &properties) @@ -184,18 +114,6 @@ void set_properties( throw "property "+id2string(*property_set.begin())+" not found"; } -/*******************************************************************\ - -Function: label_properties - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void label_properties(goto_functionst &goto_functions) { std::map property_counters; @@ -208,35 +126,11 @@ void label_properties(goto_functionst &goto_functions) label_properties(it->second.body, property_counters); } -/*******************************************************************\ - -Function: make_assertions_false - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void make_assertions_false(goto_modelt &goto_model) { make_assertions_false(goto_model.goto_functions); } -/*******************************************************************\ - -Function: make_assertions_false - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void make_assertions_false( goto_functionst &goto_functions) { diff --git a/src/goto-programs/set_properties.h b/src/goto-programs/set_properties.h index 8f302b79bee..53d1bee93d7 100644 --- a/src/goto-programs/set_properties.h +++ b/src/goto-programs/set_properties.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Set the properties to check + #ifndef CPROVER_GOTO_PROGRAMS_SET_PROPERTIES_H #define CPROVER_GOTO_PROGRAMS_SET_PROPERTIES_H diff --git a/src/goto-programs/show_goto_functions.cpp b/src/goto-programs/show_goto_functions.cpp index 83eb3434717..05ff49f7ca4 100644 --- a/src/goto-programs/show_goto_functions.cpp +++ b/src/goto-programs/show_goto_functions.cpp @@ -6,6 +6,11 @@ Author: Peter Schrammel \*******************************************************************/ +/// \file +/// Show goto functions + +#include "show_goto_functions.h" + #include #include @@ -19,22 +24,9 @@ Author: Peter Schrammel #include #include -#include "show_goto_functions.h" #include "goto_functions.h" #include "goto_model.h" -/*******************************************************************\ - -Function: cbmc_parseoptionst::show_goto_functions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void show_goto_functions( const namespacet &ns, ui_message_handlert::uit ui, @@ -42,38 +34,26 @@ void show_goto_functions( { switch(ui) { - case ui_message_handlert::XML_UI: + case ui_message_handlert::uit::XML_UI: { show_goto_functions_xmlt xml_show_functions(ns); xml_show_functions(goto_functions, std::cout); } break; - case ui_message_handlert::JSON_UI: + case ui_message_handlert::uit::JSON_UI: { show_goto_functions_jsont json_show_functions(ns); json_show_functions(goto_functions, std::cout); } break; - case ui_message_handlert::PLAIN: + case ui_message_handlert::uit::PLAIN: goto_functions.output(ns, std::cout); break; } } -/*******************************************************************\ - -Function: show_goto_functions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void show_goto_functions( const goto_modelt &goto_model, ui_message_handlert::uit ui) diff --git a/src/goto-programs/show_goto_functions.h b/src/goto-programs/show_goto_functions.h index a496682961e..4f63fde97a6 100644 --- a/src/goto-programs/show_goto_functions.h +++ b/src/goto-programs/show_goto_functions.h @@ -6,6 +6,9 @@ Author: Peter Schrammel \*******************************************************************/ +/// \file +/// Show the goto functions + #ifndef CPROVER_GOTO_PROGRAMS_SHOW_GOTO_FUNCTIONS_H #define CPROVER_GOTO_PROGRAMS_SHOW_GOTO_FUNCTIONS_H diff --git a/src/goto-programs/show_goto_functions_json.cpp b/src/goto-programs/show_goto_functions_json.cpp index 47a19e0662a..3cb1dfd4dd8 100644 --- a/src/goto-programs/show_goto_functions_json.cpp +++ b/src/goto-programs/show_goto_functions_json.cpp @@ -6,6 +6,11 @@ Author: Thomas Kiley \*******************************************************************/ +/// \file +/// Goto Program + +#include "show_goto_functions_json.h" + #include #include @@ -18,39 +23,16 @@ Author: Thomas Kiley #include "goto_functions.h" #include "goto_model.h" -#include "show_goto_functions_json.h" - -/*******************************************************************\ - -Function: show_goto_functions_jsont::show_goto_functions_jsont - - Inputs: - ns - the namespace to use to resolve names with - - Outputs: - - Purpose: For outputing the GOTO program in a readable JSON format. - -\*******************************************************************/ +/// For outputting the GOTO program in a readable JSON format. +/// \param ns: the namespace to use to resolve names with show_goto_functions_jsont::show_goto_functions_jsont(const namespacet &ns): ns(ns) {} -/*******************************************************************\ - -Function: show_goto_functions_jsont::convert - - Inputs: - goto_functions - the goto functions that make up the program - - Outputs: - - Purpose: Walks through all of the functions in the program and returns - a JSON object representing all their functions - -\*******************************************************************/ - +/// Walks through all of the functions in the program and returns a JSON object +/// representing all their functions +/// \param goto_functions: the goto functions that make up the program json_objectt show_goto_functions_jsont::convert( const goto_functionst &goto_functions) { @@ -95,7 +77,7 @@ json_objectt show_goto_functions_jsont::convert( instruction_entry["instruction"]= json_stringt(instruction_builder.str()); - if(instruction.code.operands().size()>0) + if(!instruction.code.operands().empty()) { json_arrayt operand_array; for(const exprt &operand : instruction.code.operands()) @@ -129,24 +111,13 @@ json_objectt show_goto_functions_jsont::convert( return json_result; } -/*******************************************************************\ - -Function: show_goto_functions_jsont::operator() - - Inputs: - goto_functions - the goto functions that make up the program - out - the stream to write the object to - append - should a command and newline be appended to the stream - before writing the JSON object. Defaults to true - - Outputs: - - Purpose: Print the json object generated by - show_goto_functions_jsont::show_goto_functions to the provided - stream (e.g. std::cout) - -\*******************************************************************/ - +/// Print the json object generated by +/// show_goto_functions_jsont::show_goto_functions to the provided stream (e.g. +/// std::cout) +/// \param goto_functions: the goto functions that make up the program +/// \param out: the stream to write the object to +/// \param append: should a command and newline be appended to the stream before +/// writing the JSON object. Defaults to true void show_goto_functions_jsont::operator()( const goto_functionst &goto_functions, std::ostream &out, diff --git a/src/goto-programs/show_goto_functions_json.h b/src/goto-programs/show_goto_functions_json.h index b6313247f43..0f2c7a9e8e5 100644 --- a/src/goto-programs/show_goto_functions_json.h +++ b/src/goto-programs/show_goto_functions_json.h @@ -6,6 +6,9 @@ Author: Thomas Kiley \*******************************************************************/ +/// \file +/// Goto Program + #ifndef CPROVER_GOTO_PROGRAMS_SHOW_GOTO_FUNCTIONS_JSON_H #define CPROVER_GOTO_PROGRAMS_SHOW_GOTO_FUNCTIONS_JSON_H diff --git a/src/goto-programs/show_goto_functions_xml.cpp b/src/goto-programs/show_goto_functions_xml.cpp index 7ccdd71a4ff..33424074949 100644 --- a/src/goto-programs/show_goto_functions_xml.cpp +++ b/src/goto-programs/show_goto_functions_xml.cpp @@ -6,10 +6,14 @@ Author: Thomas Kiley \*******************************************************************/ +/// \file +/// Goto Program + +#include "show_goto_functions_xml.h" + #include #include - #include #include #include @@ -19,53 +23,19 @@ Author: Thomas Kiley #include "goto_functions.h" #include "goto_model.h" -#include "show_goto_functions_xml.h" - -/*******************************************************************\ - -Function: show_goto_functions_xmlt::show_goto_functions_xmlt - - Inputs: - ns - the namespace to use to resolve names with - - Outputs: - - Purpose: For outputing the GOTO program in a readable xml format. - -\*******************************************************************/ - +/// For outputting the GOTO program in a readable xml format. +/// \param ns: the namespace to use to resolve names with show_goto_functions_xmlt::show_goto_functions_xmlt(const namespacet &ns): ns(ns) {} -/*******************************************************************\ - -Function: show_goto_functions_xmlt::convert - - Inputs: - goto_functions - the goto functions that make up the program - - Outputs: - - Purpose: Walks through all of the functions in the program and returns - an xml object representing all their functions. Produces output - like this: - - - - - - - // 34 file main.c line 1 - s = { 'a', 'b', 'c', 0 }; - - - - - - -\*******************************************************************/ - +/// Walks through all of the functions in the program and returns an xml object +/// representing all their functions. Produces output like this: +/// +/// +/// // 34 file main.c line 1 s = { 'a', 'b', 'c', 0 }; +/// +/// \param goto_functions: the goto functions that make up the program xmlt show_goto_functions_xmlt::convert( const goto_functionst &goto_functions) { @@ -114,24 +84,13 @@ xmlt show_goto_functions_xmlt::convert( return xml_functions; } -/*******************************************************************\ - -Function: show_goto_functions_xmlt::operator() - - Inputs: - goto_functions - the goto functions that make up the program - out - the stream to write the object to - append - should a command and newline be appended to the stream - before writing the xml object. Defaults to true - - Outputs: - - Purpose: Print the xml object generated by - show_goto_functions_xmlt::show_goto_functions to the provided - stream (e.g. std::cout) - -\*******************************************************************/ - +/// Print the xml object generated by +/// show_goto_functions_xmlt::show_goto_functions to the provided stream (e.g. +/// std::cout) +/// \param goto_functions: the goto functions that make up the program +/// \param out: the stream to write the object to +/// \param append: should a command and newline be appended to the stream before +/// writing the xml object. Defaults to true void show_goto_functions_xmlt::operator()( const goto_functionst &goto_functions, std::ostream &out, diff --git a/src/goto-programs/show_goto_functions_xml.h b/src/goto-programs/show_goto_functions_xml.h index 6e170b5f32d..1d47bba0b55 100644 --- a/src/goto-programs/show_goto_functions_xml.h +++ b/src/goto-programs/show_goto_functions_xml.h @@ -6,6 +6,9 @@ Author: Thomas Kiley \*******************************************************************/ +/// \file +/// Goto Program + #ifndef CPROVER_GOTO_PROGRAMS_SHOW_GOTO_FUNCTIONS_XML_H #define CPROVER_GOTO_PROGRAMS_SHOW_GOTO_FUNCTIONS_XML_H diff --git a/src/goto-programs/show_properties.cpp b/src/goto-programs/show_properties.cpp index c7a6bdedf3f..df88b4cb8b8 100644 --- a/src/goto-programs/show_properties.cpp +++ b/src/goto-programs/show_properties.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Show Claims + +#include "show_properties.h" + #include #include @@ -15,22 +20,9 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "show_properties.h" #include "goto_functions.h" #include "goto_model.h" -/*******************************************************************\ - -Function: cbmc_parseoptionst::show_properties - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void show_properties( const namespacet &ns, const irep_idt &identifier, @@ -53,7 +45,7 @@ void show_properties( switch(ui) { - case ui_message_handlert::XML_UI: + case ui_message_handlert::uit::XML_UI: { // use me instead xmlt xml_property("property"); @@ -67,23 +59,23 @@ void show_properties( xml_property.new_element("expression").data= from_expr(ns, identifier, ins.guard); - std::cout << xml_property << std::endl; + std::cout << xml_property << '\n'; } break; - case ui_message_handlert::JSON_UI: + case ui_message_handlert::uit::JSON_UI: assert(false); break; - case ui_message_handlert::PLAIN: - std::cout << "Property " << property_id << ":" << std::endl; + case ui_message_handlert::uit::PLAIN: + std::cout << "Property " << property_id << ":\n"; - std::cout << " " << ins.source_location << std::endl - << " " << description << std::endl + std::cout << " " << ins.source_location << '\n' + << " " << description << '\n' << " " << from_expr(ns, identifier, ins.guard) - << std::endl; + << '\n'; - std::cout << std::endl; + std::cout << '\n'; break; default: @@ -93,18 +85,6 @@ void show_properties( } -/*******************************************************************\ - -Function: cbmc_parseoptionst::show_properties_json - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void show_properties_json( json_arrayt &json_properties, const namespacet &ns, @@ -137,18 +117,6 @@ void show_properties_json( } } -/*******************************************************************\ - -Function: show_properties_json - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void show_properties_json( const namespacet &ns, const goto_functionst &goto_functions) @@ -168,24 +136,12 @@ void show_properties_json( std::cout << ",\n" << json_result; } -/*******************************************************************\ - -Function: show_properties - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void show_properties( const namespacet &ns, ui_message_handlert::uit ui, const goto_functionst &goto_functions) { - if(ui == ui_message_handlert::JSON_UI) + if(ui == ui_message_handlert::uit::JSON_UI) show_properties_json(ns, goto_functions); else for(const auto &fct : goto_functions.function_map) @@ -193,24 +149,12 @@ void show_properties( show_properties(ns, fct.first, ui, fct.second.body); } -/*******************************************************************\ - -Function: show_properties - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void show_properties( const goto_modelt &goto_model, ui_message_handlert::uit ui) { const namespacet ns(goto_model.symbol_table); - if(ui == ui_message_handlert::JSON_UI) + if(ui == ui_message_handlert::uit::JSON_UI) show_properties_json(ns, goto_model.goto_functions); else show_properties(ns, ui, goto_model.goto_functions); diff --git a/src/goto-programs/show_properties.h b/src/goto-programs/show_properties.h index 0feff5f6a3d..b5564818195 100644 --- a/src/goto-programs/show_properties.h +++ b/src/goto-programs/show_properties.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Show the properties + #ifndef CPROVER_GOTO_PROGRAMS_SHOW_PROPERTIES_H #define CPROVER_GOTO_PROGRAMS_SHOW_PROPERTIES_H diff --git a/src/goto-programs/show_symbol_table.cpp b/src/goto-programs/show_symbol_table.cpp index 955a444695a..6a15759f11e 100644 --- a/src/goto-programs/show_symbol_table.cpp +++ b/src/goto-programs/show_symbol_table.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Show the symbol table + +#include "show_symbol_table.h" + #include #include @@ -13,36 +18,11 @@ Author: Daniel Kroening, kroening@kroening.com #include #include "goto_model.h" -#include "show_symbol_table.h" - -/*******************************************************************\ - -Function: show_symbol_table_xml_ui - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ void show_symbol_table_xml_ui() { } -/*******************************************************************\ - -Function: show_symbol_table_plain - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void show_symbol_table_plain( const goto_modelt &goto_model, std::ostream &out) @@ -68,7 +48,7 @@ void show_symbol_table_plain( else { ptr=get_language_from_mode(symbol.mode); - if(ptr==NULL) + if(ptr==nullptr) throw "symbol "+id2string(symbol.name)+" has unknown mode"; } @@ -130,29 +110,17 @@ void show_symbol_table_plain( } } -/*******************************************************************\ - -Function: show_symbol_table - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void show_symbol_table( const goto_modelt &goto_model, ui_message_handlert::uit ui) { switch(ui) { - case ui_message_handlert::PLAIN: + case ui_message_handlert::uit::PLAIN: show_symbol_table_plain(goto_model, std::cout); break; - case ui_message_handlert::XML_UI: + case ui_message_handlert::uit::XML_UI: show_symbol_table_xml_ui(); break; diff --git a/src/goto-programs/show_symbol_table.h b/src/goto-programs/show_symbol_table.h index 6e3b387f863..5ad717e7049 100644 --- a/src/goto-programs/show_symbol_table.h +++ b/src/goto-programs/show_symbol_table.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Show the symbol table + #ifndef CPROVER_GOTO_PROGRAMS_SHOW_SYMBOL_TABLE_H #define CPROVER_GOTO_PROGRAMS_SHOW_SYMBOL_TABLE_H diff --git a/src/goto-programs/slice_global_inits.cpp b/src/goto-programs/slice_global_inits.cpp index 5e58888d366..2518a754af5 100644 --- a/src/goto-programs/slice_global_inits.cpp +++ b/src/goto-programs/slice_global_inits.cpp @@ -8,6 +8,11 @@ Date: December 2016 \*******************************************************************/ +/// \file +/// Remove initializations of unused global variables + +#include "slice_global_inits.h" + #include #include @@ -20,20 +25,6 @@ Date: December 2016 #include #include -#include "slice_global_inits.h" - -/*******************************************************************\ - -Function: slice_global_inits - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void slice_global_inits( const namespacet &ns, goto_functionst &goto_functions) diff --git a/src/goto-programs/slice_global_inits.h b/src/goto-programs/slice_global_inits.h index 7907c31c49b..25a96121961 100644 --- a/src/goto-programs/slice_global_inits.h +++ b/src/goto-programs/slice_global_inits.h @@ -8,6 +8,9 @@ Date: December 2016 \*******************************************************************/ +/// \file +/// Remove initializations of unused global variables + #ifndef CPROVER_GOTO_PROGRAMS_SLICE_GLOBAL_INITS_H #define CPROVER_GOTO_PROGRAMS_SLICE_GLOBAL_INITS_H diff --git a/src/goto-programs/string_abstraction.cpp b/src/goto-programs/string_abstraction.cpp index 67abff95812..299d27cceef 100644 --- a/src/goto-programs/string_abstraction.cpp +++ b/src/goto-programs/string_abstraction.cpp @@ -6,30 +6,23 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// String Abstraction + +#include "string_abstraction.h" + #include +#include #include #include #include #include #include -#include +#include #include "pointer_arithmetic.h" -#include "string_abstraction.h" - -/*******************************************************************\ - -Function: string_abstractiont::build_wrap - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ bool string_abstractiont::build_wrap( const exprt &object, @@ -60,18 +53,6 @@ bool string_abstractiont::build_wrap( return false; } -/*******************************************************************\ - -Function: string_abstractiont::is_ptr_string_struct - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool string_abstractiont::is_ptr_string_struct(const typet &type) const { return type.id()==ID_pointer && @@ -83,18 +64,6 @@ static inline bool is_ptr_argument(const typet &type) return type.id()==ID_pointer; } -/*******************************************************************\ - -Function: string_abstraction - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_abstraction( symbol_tablet &symbol_table, message_handlert &message_handler, @@ -104,18 +73,6 @@ void string_abstraction( string_abstraction(dest); } -/*******************************************************************\ - -Function: string_abstraction - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_abstraction( symbol_tablet &symbol_table, message_handlert &message_handler, @@ -125,18 +82,6 @@ void string_abstraction( string_abstraction(dest); } -/*******************************************************************\ - -Function: string_abstractiont::string_abstractiont - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - string_abstractiont::string_abstractiont( symbol_tablet &_symbol_table, message_handlert &_message_handler): @@ -153,57 +98,33 @@ string_abstractiont::string_abstractiont( s.components()[0].set_name("is_zero"); s.components()[0].set_pretty_name("is_zero"); - s.components()[0].type()=build_type(IS_ZERO); + s.components()[0].type()=build_type(whatt::IS_ZERO); s.components()[1].set_name("length"); s.components()[1].set_pretty_name("length"); - s.components()[1].type()=build_type(LENGTH); + s.components()[1].type()=build_type(whatt::LENGTH); s.components()[2].set_name("size"); s.components()[2].set_pretty_name("size"); - s.components()[2].type()=build_type(SIZE); + s.components()[2].type()=build_type(whatt::SIZE); string_struct=s; } -/*******************************************************************\ - -Function: string_abstractiont::build_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet string_abstractiont::build_type(whatt what) { typet type; switch(what) { - case IS_ZERO: type=bool_typet(); break; - case LENGTH: type=size_type(); break; - case SIZE: type=size_type(); break; + case whatt::IS_ZERO: type=bool_typet(); break; + case whatt::LENGTH: type=size_type(); break; + case whatt::SIZE: type=size_type(); break; } return type; } -/*******************************************************************\ - -Function: string_abstractiont::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_abstractiont::operator()(goto_functionst &dest) { Forall_goto_functions(it, dest) @@ -229,18 +150,6 @@ void string_abstractiont::operator()(goto_functionst &dest) } } -/*******************************************************************\ - -Function: string_abstractiont::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_abstractiont::operator()(goto_programt &dest) { abstract(dest); @@ -251,18 +160,6 @@ void string_abstractiont::operator()(goto_programt &dest) initialization.clear(); } -/*******************************************************************\ - -Function: string_abstractiont::add_str_arguments - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_abstractiont::add_str_arguments( const irep_idt &name, goto_functionst::goto_functiont &fct) @@ -302,18 +199,6 @@ void string_abstractiont::add_str_arguments( symb_parameters.end(), str_args.begin(), str_args.end()); } -/*******************************************************************\ - -Function: string_abstractiont::add_argument - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_abstractiont::add_argument( code_typet::parameterst &str_args, const symbolt &fct_symbol, @@ -322,7 +207,7 @@ void string_abstractiont::add_argument( const irep_idt &identifier) { typet final_type=is_ptr_argument(type)? - type:pointer_typet(type); + type:pointer_type(type); str_args.push_back(code_typet::parametert(final_type)); str_args.back().add_source_location()=fct_symbol.location; @@ -342,18 +227,6 @@ void string_abstractiont::add_argument( symbol_table.move(new_symbol); } -/*******************************************************************\ - -Function: string_abstractiont::abstract - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_abstractiont::abstract(goto_programt &dest) { locals.clear(); @@ -369,18 +242,6 @@ void string_abstractiont::abstract(goto_programt &dest) locals.clear(); } -/*******************************************************************\ - -Function: string_abstractiont::declare_define_locals - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_abstractiont::declare_define_locals(goto_programt &dest) { typedef std::unordered_map @@ -417,18 +278,6 @@ void string_abstractiont::declare_define_locals(goto_programt &dest) } } -/*******************************************************************\ - -Function: string_abstractiont::make_decl_and_def - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_abstractiont::make_decl_and_def(goto_programt &dest, goto_programt::targett ref_instr, const irep_idt &identifier, @@ -464,18 +313,6 @@ void string_abstractiont::make_decl_and_def(goto_programt &dest, } } -/*******************************************************************\ - -Function: string_abstractiont::make_val_or_dummy_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt string_abstractiont::make_val_or_dummy_rec(goto_programt &dest, goto_programt::targett ref_instr, const symbolt &symbol, const typet &source_type) @@ -545,18 +382,6 @@ exprt string_abstractiont::make_val_or_dummy_rec(goto_programt &dest, return nil_exprt(); } -/*******************************************************************\ - -Function: string_abstractiont::add_dummy_symbol_and_value - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - symbol_exprt string_abstractiont::add_dummy_symbol_and_value( goto_programt &dest, goto_programt::targett ref_instr, @@ -598,11 +423,11 @@ symbol_exprt string_abstractiont::add_dummy_symbol_and_value( { new_symbol.value=struct_exprt(string_struct); new_symbol.value.operands().resize(3); - new_symbol.value.op0()=build_unknown(IS_ZERO, false); - new_symbol.value.op1()=build_unknown(LENGTH, false); + new_symbol.value.op0()=build_unknown(whatt::IS_ZERO, false); + new_symbol.value.op1()=build_unknown(whatt::LENGTH, false); new_symbol.value.op2()=to_array_type(source_type).size().id()==ID_infinity? - build_unknown(SIZE, false):to_array_type(source_type).size(); - make_type(new_symbol.value.op2(), build_type(SIZE)); + build_unknown(whatt::SIZE, false):to_array_type(source_type).size(); + make_type(new_symbol.value.op2(), build_type(whatt::SIZE)); } else new_symbol.value= @@ -623,18 +448,6 @@ symbol_exprt string_abstractiont::add_dummy_symbol_and_value( return sym_expr; } -/*******************************************************************\ - -Function: string_abstractiont::abstract - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - goto_programt::targett string_abstractiont::abstract( goto_programt &dest, goto_programt::targett it) @@ -682,18 +495,6 @@ goto_programt::targett string_abstractiont::abstract( return it; } -/*******************************************************************\ - -Function: string_abstractiont::abstract_assign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - goto_programt::targett string_abstractiont::abstract_assign( goto_programt &dest, goto_programt::targett target) @@ -721,18 +522,6 @@ goto_programt::targett string_abstractiont::abstract_assign( return target; } -/*******************************************************************\ - -Function: string_abstractiont::abstract_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_abstractiont::abstract_function_call( goto_programt &dest, goto_programt::targett target) @@ -786,18 +575,6 @@ void string_abstractiont::abstract_function_call( arguments.insert(arguments.end(), str_args.begin(), str_args.end()); } -/*******************************************************************\ - -Function: string_abstractiont::has_string_macros - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool string_abstractiont::has_string_macros(const exprt &expr) { if(expr.id()=="is_zero_string" || @@ -812,18 +589,6 @@ bool string_abstractiont::has_string_macros(const exprt &expr) return false; } -/*******************************************************************\ - -Function: string_abstractiont::replace_string_macros - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_abstractiont::replace_string_macros( exprt &expr, bool lhs, @@ -832,19 +597,19 @@ void string_abstractiont::replace_string_macros( if(expr.id()=="is_zero_string") { assert(expr.operands().size()==1); - exprt tmp=build(expr.op0(), IS_ZERO, lhs, source_location); + exprt tmp=build(expr.op0(), whatt::IS_ZERO, lhs, source_location); expr.swap(tmp); } else if(expr.id()=="zero_string_length") { assert(expr.operands().size()==1); - exprt tmp=build(expr.op0(), LENGTH, lhs, source_location); + exprt tmp=build(expr.op0(), whatt::LENGTH, lhs, source_location); expr.swap(tmp); } else if(expr.id()=="buffer_size") { assert(expr.operands().size()==1); - exprt tmp=build(expr.op0(), SIZE, false, source_location); + exprt tmp=build(expr.op0(), whatt::SIZE, false, source_location); expr.swap(tmp); } else @@ -852,18 +617,6 @@ void string_abstractiont::replace_string_macros( replace_string_macros(*it, lhs, source_location); } -/*******************************************************************\ - -Function: string_abstractiont::build - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt string_abstractiont::build( const exprt &pointer, whatt what, @@ -888,31 +641,16 @@ exprt string_abstractiont::build( exprt result=member(str_struct, what); - if(what==LENGTH || what==SIZE) + if(what==whatt::LENGTH || what==whatt::SIZE) { // adjust for offset - exprt pointer_offset(ID_pointer_offset, size_type()); - pointer_offset.copy_to_operands(pointer); - if(pointer_offset.is_not_nil() && - !pointer_offset.is_zero()) - result=minus_exprt(result, pointer_offset); + result=minus_exprt(result, pointer_offset(pointer)); + result.op0().make_typecast(result.op1().type()); } return result; } -/*******************************************************************\ - -Function: string_abstractiont::build_abstraction_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const typet &string_abstractiont::build_abstraction_type(const typet &type) { const typet &eff_type=ns.follow(type); @@ -932,18 +670,6 @@ const typet &string_abstractiont::build_abstraction_type(const typet &type) std::make_pair(eff_type, map_entry->second)).first->second; } -/*******************************************************************\ - -Function: string_abstractiont::build_abstraction_type_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const typet &string_abstractiont::build_abstraction_type_rec(const typet &type, const abstraction_types_mapt &known) { @@ -963,7 +689,7 @@ const typet &string_abstractiont::build_abstraction_type_rec(const typet &type, // char* or void* or char[] if(is_char_type(eff_type.subtype()) || eff_type.subtype().id()==ID_empty) - map_entry.first->second=pointer_typet(string_struct); + map_entry.first->second=pointer_type(string_struct); else { const typet &subt=build_abstraction_type_rec(eff_type.subtype(), known); @@ -973,8 +699,7 @@ const typet &string_abstractiont::build_abstraction_type_rec(const typet &type, map_entry.first->second= array_typet(subt, to_array_type(eff_type).size()); else - map_entry.first->second= - pointer_typet(subt); + map_entry.first->second=pointer_type(subt); } } } @@ -1008,18 +733,6 @@ const typet &string_abstractiont::build_abstraction_type_rec(const typet &type, return map_entry.first->second; } -/*******************************************************************\ - -Function: string_abstractiont::build - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool string_abstractiont::build(const exprt &object, exprt &dest, bool write) { const typet &abstract_type=build_abstraction_type(object.type()); @@ -1084,18 +797,6 @@ bool string_abstractiont::build(const exprt &object, exprt &dest, bool write) return true; } -/*******************************************************************\ - -Function: string_abstractiont::build_if - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool string_abstractiont::build_if(const if_exprt &o_if, exprt &dest, bool write) { @@ -1124,18 +825,6 @@ bool string_abstractiont::build_if(const if_exprt &o_if, return false; } -/*******************************************************************\ - -Function: string_abstractiont::build_array - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool string_abstractiont::build_array(const array_exprt &object, exprt &dest, bool write) { @@ -1160,18 +849,6 @@ bool string_abstractiont::build_array(const array_exprt &object, return true; } -/*******************************************************************\ - -Function: string_abstractiont::build_pointer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool string_abstractiont::build_pointer(const exprt &object, exprt &dest, bool write) { @@ -1204,18 +881,6 @@ bool string_abstractiont::build_pointer(const exprt &object, return true; } -/*******************************************************************\ - -Function: string_abstractiont::build_unknown - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt string_abstractiont::build_unknown(whatt what, bool write) { typet type=build_type(what); @@ -1227,12 +892,12 @@ exprt string_abstractiont::build_unknown(whatt what, bool write) switch(what) { - case IS_ZERO: + case whatt::IS_ZERO: result=false_exprt(); break; - case LENGTH: - case SIZE: + case whatt::LENGTH: + case whatt::SIZE: result=side_effect_expr_nondett(type); break; } @@ -1240,18 +905,6 @@ exprt string_abstractiont::build_unknown(whatt what, bool write) return result; } -/*******************************************************************\ - -Function: string_abstractiont::build_unknown - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt string_abstractiont::build_unknown(const typet &type, bool write) { if(write) @@ -1279,18 +932,6 @@ exprt string_abstractiont::build_unknown(const typet &type, bool write) return ns.lookup(identifier).symbol_expr(); } -/*******************************************************************\ - -Function: string_abstractiont::build_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool string_abstractiont::build_symbol(const symbol_exprt &sym, exprt &dest) { const symbolt &symbol=ns.lookup(sym.get_identifier()); @@ -1318,18 +959,6 @@ bool string_abstractiont::build_symbol(const symbol_exprt &sym, exprt &dest) return false; } -/*******************************************************************\ - -Function: string_abstractiont::build_new_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_abstractiont::build_new_symbol(const symbolt &symbol, const irep_idt &identifier, const typet &type) { @@ -1361,18 +990,6 @@ void string_abstractiont::build_new_symbol(const symbolt &symbol, } } -/*******************************************************************\ - -Function: string_abstractiont::build_symbol_constant - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool string_abstractiont::build_symbol_constant( const mp_integer &zero_length, const mp_integer &buf_size, @@ -1401,8 +1018,8 @@ bool string_abstractiont::build_symbol_constant( value.operands().resize(3); value.op0()=true_exprt(); - value.op1()=from_integer(zero_length, build_type(LENGTH)); - value.op2()=from_integer(buf_size, build_type(SIZE)); + value.op1()=from_integer(zero_length, build_type(whatt::LENGTH)); + value.op2()=from_integer(buf_size, build_type(whatt::SIZE)); // initialization goto_programt::targett assignment1=initialization.add_instruction(); @@ -1418,18 +1035,6 @@ bool string_abstractiont::build_symbol_constant( return false; } -/*******************************************************************\ - -Function: string_abstractiont::move_lhs_arithmetic - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_abstractiont::move_lhs_arithmetic(exprt &lhs, exprt &rhs) { if(lhs.id()==ID_minus) @@ -1442,18 +1047,6 @@ void string_abstractiont::move_lhs_arithmetic(exprt &lhs, exprt &rhs) } } -/*******************************************************************\ - -Function: string_abstractiont::abstract_pointer_assign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - goto_programt::targett string_abstractiont::abstract_pointer_assign( goto_programt &dest, goto_programt::targett target) @@ -1499,18 +1092,6 @@ goto_programt::targett string_abstractiont::abstract_pointer_assign( } } -/*******************************************************************\ - -Function: string_abstractiont::abstract_char_assign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - goto_programt::targett string_abstractiont::abstract_char_assign( goto_programt &dest, goto_programt::targett target) @@ -1535,7 +1116,7 @@ goto_programt::targett string_abstractiont::abstract_char_assign( exprt new_lhs; if(!build_wrap(i_lhs.array(), new_lhs, true)) { - exprt i2=member(new_lhs, LENGTH); + exprt i2=member(new_lhs, whatt::LENGTH); assert(i2.is_not_nil()); exprt new_length=i_lhs.index(); @@ -1553,10 +1134,10 @@ goto_programt::targett string_abstractiont::abstract_char_assign( exprt new_lhs; if(!build_wrap(ptr.pointer, new_lhs, true)) { - const exprt i2=member(new_lhs, LENGTH); + const exprt i2=member(new_lhs, whatt::LENGTH); assert(i2.is_not_nil()); - make_type(ptr.offset, build_type(LENGTH)); + make_type(ptr.offset, build_type(whatt::LENGTH)); return char_assign( dest, @@ -1564,7 +1145,7 @@ goto_programt::targett string_abstractiont::abstract_char_assign( new_lhs, i2, ptr.offset.is_nil()? - from_integer(0, build_type(LENGTH)): + from_integer(0, build_type(whatt::LENGTH)): ptr.offset); } } @@ -1572,18 +1153,6 @@ goto_programt::targett string_abstractiont::abstract_char_assign( return target; } -/*******************************************************************\ - -Function: string_abstractiont::char_assign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - goto_programt::targett string_abstractiont::char_assign( goto_programt &dest, goto_programt::targett target, @@ -1593,7 +1162,7 @@ goto_programt::targett string_abstractiont::char_assign( { goto_programt tmp; - const exprt i1=member(new_lhs, IS_ZERO); + const exprt i1=member(new_lhs, whatt::IS_ZERO); assert(i1.is_not_nil()); goto_programt::targett assignment1=tmp.add_instruction(); @@ -1621,18 +1190,6 @@ goto_programt::targett string_abstractiont::char_assign( return target; } -/*******************************************************************\ - -Function: string_abstractiont::value_assignments - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - goto_programt::targett string_abstractiont::value_assignments( goto_programt &dest, goto_programt::targett target, @@ -1680,18 +1237,6 @@ goto_programt::targett string_abstractiont::value_assignments( return target; } -/*******************************************************************\ - -Function: string_abstractiont::value_assignments_if - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - goto_programt::targett string_abstractiont::value_assignments_if( goto_programt &dest, goto_programt::targett target, @@ -1730,18 +1275,6 @@ goto_programt::targett string_abstractiont::value_assignments_if( return last; } -/*******************************************************************\ - -Function: string_abstractiont::value_assignments_string_struct - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - goto_programt::targett string_abstractiont::value_assignments_string_struct( goto_programt &dest, goto_programt::targett target, @@ -1753,8 +1286,8 @@ goto_programt::targett string_abstractiont::value_assignments_string_struct( { goto_programt::targett assignment=tmp.add_instruction(ASSIGN); assignment->code=code_assignt( - member(lhs, IS_ZERO), - member(rhs, IS_ZERO)); + member(lhs, whatt::IS_ZERO), + member(rhs, whatt::IS_ZERO)); assignment->code.add_source_location()=target->source_location; assignment->function=target->function; assignment->source_location=target->source_location; @@ -1763,8 +1296,8 @@ goto_programt::targett string_abstractiont::value_assignments_string_struct( { goto_programt::targett assignment=tmp.add_instruction(ASSIGN); assignment->code=code_assignt( - member(lhs, LENGTH), - member(rhs, LENGTH)); + member(lhs, whatt::LENGTH), + member(rhs, whatt::LENGTH)); assignment->code.add_source_location()=target->source_location; assignment->function=target->function; assignment->source_location=target->source_location; @@ -1773,8 +1306,8 @@ goto_programt::targett string_abstractiont::value_assignments_string_struct( { goto_programt::targett assignment=tmp.add_instruction(ASSIGN); assignment->code=code_assignt( - member(lhs, SIZE), - member(rhs, SIZE)); + member(lhs, whatt::SIZE), + member(rhs, whatt::SIZE)); assignment->code.add_source_location()=target->source_location; assignment->function=target->function; assignment->source_location=target->source_location; @@ -1788,18 +1321,6 @@ goto_programt::targett string_abstractiont::value_assignments_string_struct( return last; } -/*******************************************************************\ - -Function: string_abstractiont::member - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt string_abstractiont::member(const exprt &a, whatt what) { if(a.is_nil()) @@ -1813,9 +1334,9 @@ exprt string_abstractiont::member(const exprt &a, whatt what) switch(what) { - case IS_ZERO: result.set_component_name("is_zero"); break; - case SIZE: result.set_component_name("size"); break; - case LENGTH: result.set_component_name("length"); break; + case whatt::IS_ZERO: result.set_component_name("is_zero"); break; + case whatt::SIZE: result.set_component_name("size"); break; + case whatt::LENGTH: result.set_component_name("length"); break; } return result; diff --git a/src/goto-programs/string_abstraction.h b/src/goto-programs/string_abstraction.h index 2ea2be22da9..9443b09d68b 100644 --- a/src/goto-programs/string_abstraction.h +++ b/src/goto-programs/string_abstraction.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// String Abstraction + #ifndef CPROVER_GOTO_PROGRAMS_STRING_ABSTRACTION_H #define CPROVER_GOTO_PROGRAMS_STRING_ABSTRACTION_H @@ -16,14 +19,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "goto_functions.h" -/*******************************************************************\ - - Class: string_abstractiont - - Purpose: - -\*******************************************************************/ - class string_abstractiont:public messaget { public: @@ -108,7 +103,7 @@ class string_abstractiont:public messaget goto_programt::targett target, const exprt &lhs, const exprt &rhs); - typedef enum { IS_ZERO, LENGTH, SIZE } whatt; + enum class whatt { IS_ZERO, LENGTH, SIZE }; static typet build_type(whatt what); exprt build( diff --git a/src/goto-programs/string_instrumentation.cpp b/src/goto-programs/string_instrumentation.cpp index d53e2465386..f4ce4129eed 100644 --- a/src/goto-programs/string_instrumentation.cpp +++ b/src/goto-programs/string_instrumentation.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// String Abstraction + +#include "string_instrumentation.h" + #include #include @@ -16,21 +21,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include - -#include "string_instrumentation.h" - -/*******************************************************************\ - -Function: is_zero_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include exprt is_zero_string( const exprt &what, @@ -42,18 +33,6 @@ exprt is_zero_string( return result; } -/*******************************************************************\ - -Function: zero_string_length - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt zero_string_length( const exprt &what, bool write) @@ -64,18 +43,6 @@ exprt zero_string_length( return result; } -/*******************************************************************\ - -Function: buffer_size - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt buffer_size(const exprt &what) { exprt result("buffer_size", size_type()); @@ -83,18 +50,6 @@ exprt buffer_size(const exprt &what) return result; } -/*******************************************************************\ - - Class: string_instrumentationt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - class string_instrumentationt:public messaget { public: @@ -197,18 +152,6 @@ class string_instrumentationt:public messaget const mp_integer &limit); }; -/*******************************************************************\ - -Function: string_instrumentation - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_instrumentation( symbol_tablet &symbol_table, message_handlert &message_handler, @@ -218,18 +161,6 @@ void string_instrumentation( string_instrumentation(dest); } -/*******************************************************************\ - -Function: string_instrumentation - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_instrumentation( symbol_tablet &symbol_table, message_handlert &message_handler, @@ -239,18 +170,6 @@ void string_instrumentation( string_instrumentation(dest); } -/*******************************************************************\ - -Function: string_instrumentationt::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_instrumentationt::operator()(goto_functionst &dest) { for(goto_functionst::function_mapt::iterator @@ -262,36 +181,12 @@ void string_instrumentationt::operator()(goto_functionst &dest) } } -/*******************************************************************\ - -Function: string_instrumentationt::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_instrumentationt::operator()(goto_programt &dest) { Forall_goto_program_instructions(it, dest) instrument(dest, it); } -/*******************************************************************\ - -Function: string_instrumentationt::instrument - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_instrumentationt::instrument( goto_programt &dest, goto_programt::targett it) @@ -311,18 +206,6 @@ void string_instrumentationt::instrument( } } -/*******************************************************************\ - -Function: string_instrumentationt::do_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_instrumentationt::do_function_call( goto_programt &dest, goto_programt::targett target) @@ -375,18 +258,6 @@ void string_instrumentationt::do_function_call( } } -/*******************************************************************\ - -Function: string_instrumentationt::do_sprintf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_instrumentationt::do_sprintf( goto_programt &dest, goto_programt::targett target, @@ -429,18 +300,6 @@ void string_instrumentationt::do_sprintf( dest.insert_before_swap(target, tmp); } -/*******************************************************************\ - -Function: string_instrumentationt::do_snprintf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_instrumentationt::do_snprintf( goto_programt &dest, goto_programt::targett target, @@ -484,18 +343,6 @@ void string_instrumentationt::do_snprintf( dest.insert_before_swap(target, tmp); } -/*******************************************************************\ - -Function: string_instrumentationt::do_fscanf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_instrumentationt::do_fscanf( goto_programt &dest, goto_programt::targett target, @@ -529,18 +376,6 @@ void string_instrumentationt::do_fscanf( dest.insert_before_swap(target, tmp); } -/*******************************************************************\ - -Function: string_instrumentationt::do_format_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_instrumentationt::do_format_string_read( goto_programt &dest, goto_programt::const_targett target, @@ -562,7 +397,7 @@ void string_instrumentationt::do_format_string_read( for(const auto &token : token_list) { - if(token.type==format_tokent::STRING) + if(token.type==format_tokent::token_typet::STRING) { const exprt &arg=arguments[argument_start_inx+args]; const typet &arg_type=ns.follow(arg.type()); @@ -591,10 +426,13 @@ void string_instrumentationt::do_format_string_read( } } - if(token.type!=format_tokent::TEXT && - token.type!=format_tokent::UNKNOWN) args++; + if(token.type!=format_tokent::token_typet::TEXT && + token.type!=format_tokent::token_typet::UNKNOWN) args++; - if(find(token.flags.begin(), token.flags.end(), format_tokent::ASTERISK)!= + if(find( + token.flags.begin(), + token.flags.end(), + format_tokent::flag_typet::ASTERISK)!= token.flags.end()) args++; // just eat the additional argument } @@ -641,18 +479,6 @@ void string_instrumentationt::do_format_string_read( } } -/*******************************************************************\ - -Function: string_instrumentationt::do_format_string_write - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_instrumentationt::do_format_string_write( goto_programt &dest, goto_programt::const_targett target, @@ -674,13 +500,16 @@ void string_instrumentationt::do_format_string_write( for(const auto &token : token_list) { - if(find(token.flags.begin(), token.flags.end(), format_tokent::ASTERISK)!= + if(find( + token.flags.begin(), + token.flags.end(), + format_tokent::flag_typet::ASTERISK)!= token.flags.end()) continue; // asterisk means `ignore this' switch(token.type) { - case format_tokent::STRING: + case format_tokent::token_typet::STRING: { const exprt &argument=arguments[argument_start_inx+args]; const typet &arg_type=ns.follow(argument.type()); @@ -729,8 +558,8 @@ void string_instrumentationt::do_format_string_write( args++; break; } - case format_tokent::TEXT: - case format_tokent::UNKNOWN: + case format_tokent::token_typet::TEXT: + case format_tokent::token_typet::UNKNOWN: { // nothing break; @@ -800,18 +629,6 @@ void string_instrumentationt::do_format_string_write( } } -/*******************************************************************\ - -Function: string_instrumentationt::do_strncmp - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_instrumentationt::do_strncmp( goto_programt &dest, goto_programt::targett target, @@ -819,18 +636,6 @@ void string_instrumentationt::do_strncmp( { } -/*******************************************************************\ - -Function: string_instrumentationt::do_strchr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_instrumentationt::do_strchr( goto_programt &dest, goto_programt::targett target, @@ -858,18 +663,6 @@ void string_instrumentationt::do_strchr( dest.insert_before_swap(target, tmp); } -/*******************************************************************\ - -Function: string_instrumentationt::do_strrchr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_instrumentationt::do_strrchr( goto_programt &dest, goto_programt::targett target, @@ -897,18 +690,6 @@ void string_instrumentationt::do_strrchr( dest.insert_before_swap(target, tmp); } -/*******************************************************************\ - -Function: string_instrumentationt::do_strstr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_instrumentationt::do_strstr( goto_programt &dest, goto_programt::targett target, @@ -943,18 +724,6 @@ void string_instrumentationt::do_strstr( dest.insert_before_swap(target, tmp); } -/*******************************************************************\ - -Function: string_instrumentationt::do_strtok - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_instrumentationt::do_strtok( goto_programt &dest, goto_programt::targett target, @@ -989,18 +758,6 @@ void string_instrumentationt::do_strtok( dest.insert_before_swap(target, tmp); } -/*******************************************************************\ - -Function: string_instrumentationt::do_strerror - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_instrumentationt::do_strerror( goto_programt &dest, goto_programt::targett it, @@ -1068,14 +825,12 @@ void string_instrumentationt::do_strerror( } // return a pointer to some magic buffer - exprt index=exprt(ID_index, char_type()); - index.copy_to_operands( + index_exprt index( symbol_buf.symbol_expr(), - from_integer(0, index_type())); + from_integer(0, index_type()), + char_type()); - exprt ptr=exprt(ID_address_of, pointer_typet()); - ptr.type().subtype()=char_type(); - ptr.copy_to_operands(index); + address_of_exprt ptr(index); // make that zero-terminated { @@ -1097,18 +852,6 @@ void string_instrumentationt::do_strerror( dest.insert_before_swap(it, tmp); } -/*******************************************************************\ - -Function: string_instrumentationt::invalidate_buffer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void string_instrumentationt::invalidate_buffer( goto_programt &dest, goto_programt::const_targett target, diff --git a/src/goto-programs/string_instrumentation.h b/src/goto-programs/string_instrumentation.h index cd52bb54a84..9d8bda00370 100644 --- a/src/goto-programs/string_instrumentation.h +++ b/src/goto-programs/string_instrumentation.h @@ -6,11 +6,16 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// String Abstraction + #ifndef CPROVER_GOTO_PROGRAMS_STRING_INSTRUMENTATION_H #define CPROVER_GOTO_PROGRAMS_STRING_INSTRUMENTATION_H #include "goto_functions.h" +class message_handlert; + void string_instrumentation( symbol_tablet &symbol_table, message_handlert &message_handler, diff --git a/src/goto-programs/vcd_goto_trace.cpp b/src/goto-programs/vcd_goto_trace.cpp index 3fe1ebbb660..4becb3af583 100644 --- a/src/goto-programs/vcd_goto_trace.cpp +++ b/src/goto-programs/vcd_goto_trace.cpp @@ -8,6 +8,11 @@ Date: June 2011 \*******************************************************************/ +/// \file +/// Traces of GOTO Programs in VCD (Value Change Dump) Format + +#include "vcd_goto_trace.h" + #include #include #include @@ -16,20 +21,6 @@ Date: June 2011 #include #include -#include "vcd_goto_trace.h" - -/*******************************************************************\ - -Function: output_vcd - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string as_vcd_binary( const exprt &expr, const namespacet &ns) @@ -90,18 +81,6 @@ std::string as_vcd_binary( return ""; } -/*******************************************************************\ - -Function: output_vcd - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void output_vcd( const namespacet &ns, const goto_tracet &goto_trace, @@ -149,7 +128,7 @@ void output_vcd( { switch(step.type) { - case goto_trace_stept::ASSIGNMENT: + case goto_trace_stept::typet::ASSIGNMENT: { irep_idt identifier=step.lhs_object.get_identifier(); const typet &type=step.lhs_object.type(); diff --git a/src/goto-programs/vcd_goto_trace.h b/src/goto-programs/vcd_goto_trace.h index 5b9a3680cb6..0f7990b92bd 100644 --- a/src/goto-programs/vcd_goto_trace.h +++ b/src/goto-programs/vcd_goto_trace.h @@ -8,6 +8,9 @@ Date: June 2011 \*******************************************************************/ +/// \file +/// Traces of GOTO Programs in VCD (Value Change Dump) Format + #ifndef CPROVER_GOTO_PROGRAMS_VCD_GOTO_TRACE_H #define CPROVER_GOTO_PROGRAMS_VCD_GOTO_TRACE_H diff --git a/src/goto-programs/wp.cpp b/src/goto-programs/wp.cpp index 7f10498810d..cb9981793d7 100644 --- a/src/goto-programs/wp.cpp +++ b/src/goto-programs/wp.cpp @@ -6,26 +6,17 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Weakest Preconditions + +#include "wp.h" + // #include #include #include #include -#include "wp.h" - -/*******************************************************************\ - -Function: has_nondet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool has_nondet(const exprt &dest) { forall_operands(it, dest) @@ -44,18 +35,6 @@ bool has_nondet(const exprt &dest) return false; } -/*******************************************************************\ - -Function: approximate_nondet_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void approximate_nondet_rec(exprt &dest, unsigned &count) { if(dest.id()==ID_side_effect && @@ -71,37 +50,14 @@ void approximate_nondet_rec(exprt &dest, unsigned &count) approximate_nondet_rec(*it, count); } -/*******************************************************************\ - -Function: approximate_nondet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void approximate_nondet(exprt &dest) { static unsigned count=0; // not proper, should be quantified approximate_nondet_rec(dest, count); } -/*******************************************************************\ - -Function: aliasing - - Inputs: - - Outputs: - - Purpose: consider possible aliasing - -\*******************************************************************/ - -typedef enum { A_MAY, A_MUST, A_MUSTNOT } aliasingt; +/// consider possible aliasing +enum class aliasingt { A_MAY, A_MUST, A_MUSTNOT }; aliasingt aliasing( const exprt &e1, const exprt &e2, @@ -122,20 +78,20 @@ aliasingt aliasing( // fairly radical. Ignores struct prefixes and the like. if(!base_type_eq(e1.type(), e2.type(), ns)) - return A_MUSTNOT; + return aliasingt::A_MUSTNOT; // syntactically the same? if(e1==e2) - return A_MUST; + return aliasingt::A_MUST; // the trivial case first if(e1.id()==ID_symbol && e2.id()==ID_symbol) { if(to_symbol_expr(e1).get_identifier()== to_symbol_expr(e2).get_identifier()) - return A_MUST; + return aliasingt::A_MUST; else - return A_MUSTNOT; + return aliasingt::A_MUSTNOT; } // an array or struct will never alias with a variable, @@ -143,31 +99,19 @@ aliasingt aliasing( if(e1.id()==ID_index || e1.id()==ID_struct) if(e2.id()!=ID_dereference && e1.id()!=e2.id()) - return A_MUSTNOT; + return aliasingt::A_MUSTNOT; if(e2.id()==ID_index || e2.id()==ID_struct) if(e2.id()!=ID_dereference && e1.id()!=e2.id()) - return A_MUSTNOT; + return aliasingt::A_MUSTNOT; // we give up, and say it may // (could do much more here) - return A_MAY; + return aliasingt::A_MAY; } -/*******************************************************************\ - -Function: substitute_rec - - Inputs: - - Outputs: - - Purpose: replace 'what' by 'by' in 'dest', - considering possible aliasing - -\*******************************************************************/ - +/// replace 'what' by 'by' in 'dest', considering possible aliasing void substitute_rec( exprt &dest, const exprt &what, @@ -187,11 +131,11 @@ void substitute_rec( // could these be possible the same? switch(aliasing(dest, what, ns)) { - case A_MUST: + case aliasingt::A_MUST: dest=by; // they are always the same break; - case A_MAY: + case aliasingt::A_MAY: { // consider possible aliasing between 'what' and 'dest' exprt what_address=address_of_exprt(what); @@ -210,25 +154,13 @@ void substitute_rec( return; } - case A_MUSTNOT: + case aliasingt::A_MUSTNOT: // nothing to do break; } } } -/*******************************************************************\ - -Function: rewrite_assignment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rewrite_assignment(exprt &lhs, exprt &rhs) { if(lhs.id()==ID_member) // turn s.x:=e into s:=(s with .x=e) @@ -267,18 +199,6 @@ void rewrite_assignment(exprt &lhs, exprt &rhs) } } -/*******************************************************************\ - -Function: wp_assign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt wp_assign( const code_assignt &code, const exprt &post, @@ -300,18 +220,6 @@ exprt wp_assign( return pre; } -/*******************************************************************\ - -Function: wp_assume - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt wp_assume( const code_assumet &code, const exprt &post, @@ -320,18 +228,6 @@ exprt wp_assume( return implies_exprt(code.assumption(), post); } -/*******************************************************************\ - -Function: wp_decl - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt wp_decl( const code_declt &code, const exprt &post, @@ -345,18 +241,6 @@ exprt wp_decl( return wp_assign(assignment, post, ns); } -/*******************************************************************\ - -Function: wp - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt wp( const codet &code, const exprt &post, diff --git a/src/goto-programs/wp.h b/src/goto-programs/wp.h index 741298b9507..d967ce3dd0a 100644 --- a/src/goto-programs/wp.h +++ b/src/goto-programs/wp.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Weakest Preconditions + #ifndef CPROVER_GOTO_PROGRAMS_WP_H #define CPROVER_GOTO_PROGRAMS_WP_H @@ -13,16 +16,12 @@ class codet; class exprt; class namespacet; -/*! \defgroup gr_wp Weakest precondition */ - /*! \brief Compute the weakest precondition of the given program * piece \a code with respect to the expression \a post. * \param code Program * \param post Postcondition * \param ns Namespace * \return Weakest precondition - * - * \ingroup gr_wp */ exprt wp( const codet &code, @@ -31,7 +30,6 @@ exprt wp( /*! \brief approximate the non-deterministic choice in a way cheaper than by (proper) quantification - * \ingroup gr_wp */ void approximate_nondet(exprt &dest); diff --git a/src/goto-programs/write_goto_binary.cpp b/src/goto-programs/write_goto_binary.cpp index f5649e992d3..75542144d91 100644 --- a/src/goto-programs/write_goto_binary.cpp +++ b/src/goto-programs/write_goto_binary.cpp @@ -6,26 +6,18 @@ Author: CM Wintersteiger \*******************************************************************/ +/// \file +/// Write GOTO binaries + +#include "write_goto_binary.h" + #include #include #include #include -#include "write_goto_binary.h" - -/*******************************************************************\ - -Function: goto_programt::write_goto_binary_v3 - - Inputs: - - Outputs: - - Purpose: Writes a goto program to disc, using goto binary format ver 2 - -\*******************************************************************/ - +/// Writes a goto program to disc, using goto binary format ver 2 bool write_goto_binary_v3( std::ostream &out, const symbol_tablet &lsymbol_table, @@ -127,18 +119,7 @@ bool write_goto_binary_v3( return false; } -/*******************************************************************\ - -Function: goto_programt::write_goto_binary - - Inputs: - - Outputs: - - Purpose: Writes a goto program to disc - -\*******************************************************************/ - +/// Writes a goto program to disc bool write_goto_binary( std::ostream &out, const symbol_tablet &lsymbol_table, @@ -172,18 +153,7 @@ bool write_goto_binary( return false; } -/*******************************************************************\ - -Function: goto_programt::write_goto_binary - - Inputs: - - Outputs: - - Purpose: Writes a goto program to disc - -\*******************************************************************/ - +/// Writes a goto program to disc bool write_goto_binary( const std::string &filename, const symbol_tablet &symbol_table, diff --git a/src/goto-programs/write_goto_binary.h b/src/goto-programs/write_goto_binary.h index 5b5f0aef18c..fd3acd9cb77 100644 --- a/src/goto-programs/write_goto_binary.h +++ b/src/goto-programs/write_goto_binary.h @@ -6,6 +6,9 @@ Author: CM Wintersteiger \*******************************************************************/ +/// \file +/// Write GOTO binaries + #ifndef CPROVER_GOTO_PROGRAMS_WRITE_GOTO_BINARY_H #define CPROVER_GOTO_PROGRAMS_WRITE_GOTO_BINARY_H diff --git a/src/goto-programs/xml_goto_trace.cpp b/src/goto-programs/xml_goto_trace.cpp index 6469b2a2132..dca2c704a2b 100644 --- a/src/goto-programs/xml_goto_trace.cpp +++ b/src/goto-programs/xml_goto_trace.cpp @@ -8,6 +8,11 @@ Author: Daniel Kroening \*******************************************************************/ +/// \file +/// Traces of GOTO Programs + +#include "xml_goto_trace.h" + #include #include @@ -16,20 +21,6 @@ Author: Daniel Kroening #include #include -#include "xml_goto_trace.h" - -/*******************************************************************\ - -Function: convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void convert( const namespacet &ns, const goto_tracet &goto_trace, @@ -49,7 +40,7 @@ void convert( switch(step.type) { - case goto_trace_stept::ASSERT: + case goto_trace_stept::typet::ASSERT: if(!step.cond_value) { irep_idt property_id; @@ -76,8 +67,8 @@ void convert( } break; - case goto_trace_stept::ASSIGNMENT: - case goto_trace_stept::DECL: + case goto_trace_stept::typet::ASSIGNMENT: + case goto_trace_stept::typet::DECL: { irep_idt identifier=step.lhs_object.get_identifier(); xmlt &xml_assignment=dest.new_element("assignment"); @@ -128,7 +119,8 @@ void convert( xml_assignment.set_attribute("step_nr", std::to_string(step.step_nr)); xml_assignment.set_attribute("assignment_type", - step.assignment_type==goto_trace_stept::ACTUAL_PARAMETER? + step.assignment_type== + goto_trace_stept::assignment_typet::ACTUAL_PARAMETER? "actual_parameter":"state"); if(step.lhs_object_value.is_not_nil()) @@ -137,7 +129,7 @@ void convert( } break; - case goto_trace_stept::OUTPUT: + case goto_trace_stept::typet::OUTPUT: { printf_formattert printf_formatter(ns); printf_formatter(id2string(step.format_string), step.io_args); @@ -162,7 +154,7 @@ void convert( } break; - case goto_trace_stept::INPUT: + case goto_trace_stept::typet::INPUT: { xmlt &xml_input=dest.new_element("input"); xml_input.new_element("input_id").data=id2string(step.io_id); @@ -183,11 +175,11 @@ void convert( } break; - case goto_trace_stept::FUNCTION_CALL: - case goto_trace_stept::FUNCTION_RETURN: + case goto_trace_stept::typet::FUNCTION_CALL: + case goto_trace_stept::typet::FUNCTION_RETURN: { std::string tag= - (step.type==goto_trace_stept::FUNCTION_CALL)? + (step.type==goto_trace_stept::typet::FUNCTION_CALL)? "function_call":"function_return"; xmlt &xml_call_return=dest.new_element(tag); diff --git a/src/goto-programs/xml_goto_trace.h b/src/goto-programs/xml_goto_trace.h index 123e0d69877..ce77b09c450 100644 --- a/src/goto-programs/xml_goto_trace.h +++ b/src/goto-programs/xml_goto_trace.h @@ -8,6 +8,9 @@ Date: November 2005 \*******************************************************************/ +/// \file +/// Traces of GOTO Programs + #ifndef CPROVER_GOTO_PROGRAMS_XML_GOTO_TRACE_H #define CPROVER_GOTO_PROGRAMS_XML_GOTO_TRACE_H diff --git a/src/goto-symex/adjust_float_expressions.cpp b/src/goto-symex/adjust_float_expressions.cpp index 46dee137447..f2b09db09ec 100644 --- a/src/goto-symex/adjust_float_expressions.cpp +++ b/src/goto-symex/adjust_float_expressions.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symbolic Execution + +#include "adjust_float_expressions.h" + #include #include #include @@ -15,20 +20,6 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "adjust_float_expressions.h" - -/*******************************************************************\ - -Function: have_to_adjust_float_expressions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static bool have_to_adjust_float_expressions( const exprt &expr, const namespacet &ns) @@ -84,19 +75,8 @@ static bool have_to_adjust_float_expressions( return false; } -/*******************************************************************\ - -Function: adjust_float_expressions - - Inputs: - - Outputs: - - Purpose: This adds the rounding mode to floating-point operations, - including those in vectors and complex numbers. - -\*******************************************************************/ - +/// This adds the rounding mode to floating-point operations, including those in +/// vectors and complex numbers. void adjust_float_expressions( exprt &expr, const namespacet &ns) @@ -199,18 +179,6 @@ void adjust_float_expressions( } } -/*******************************************************************\ - -Function: adjust_float_expressions - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - static void adjust_float_expressions( goto_functionst::goto_functiont &goto_function, const namespacet &ns) @@ -222,18 +190,6 @@ static void adjust_float_expressions( } } -/*******************************************************************\ - -Function: adjust_float_expressions - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void adjust_float_expressions( goto_functionst &goto_functions, const namespacet &ns) @@ -242,18 +198,6 @@ void adjust_float_expressions( adjust_float_expressions(it->second, ns); } -/*******************************************************************\ - -Function: adjust_float_expressions - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void adjust_float_expressions(goto_modelt &goto_model) { namespacet ns(goto_model.symbol_table); diff --git a/src/goto-symex/adjust_float_expressions.h b/src/goto-symex/adjust_float_expressions.h index f8547c59fa8..5cfd01d740f 100644 --- a/src/goto-symex/adjust_float_expressions.h +++ b/src/goto-symex/adjust_float_expressions.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symbolic Execution + #ifndef CPROVER_GOTO_SYMEX_ADJUST_FLOAT_EXPRESSIONS_H #define CPROVER_GOTO_SYMEX_ADJUST_FLOAT_EXPRESSIONS_H diff --git a/src/goto-symex/auto_objects.cpp b/src/goto-symex/auto_objects.cpp index 1b3e6f2d636..2338b102593 100644 --- a/src/goto-symex/auto_objects.cpp +++ b/src/goto-symex/auto_objects.cpp @@ -6,25 +6,16 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symbolic Execution of ANSI-C + +#include "goto_symex.h" + #include #include #include #include -#include "goto_symex.h" - -/*******************************************************************\ - -Function: goto_symext::make_auto_object - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt goto_symext::make_auto_object(const typet &type) { dynamic_counter++; @@ -43,18 +34,6 @@ exprt goto_symext::make_auto_object(const typet &type) return symbol_exprt(symbol.name, symbol.type); } -/*******************************************************************\ - -Function: goto_symext::initialize_auto_object - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::initialize_auto_object( const exprt &expr, statet &state) @@ -87,8 +66,9 @@ void goto_symext::initialize_auto_object( { // could be NULL nondeterministically - address_of_exprt address_of_expr= - address_of_exprt(make_auto_object(type.subtype())); + address_of_exprt address_of_expr( + make_auto_object(type.subtype()), + pointer_type); if_exprt rhs( side_effect_expr_nondett(bool_typet()), @@ -101,18 +81,6 @@ void goto_symext::initialize_auto_object( } } -/*******************************************************************\ - -Function: goto_symext::trigger_auto_object - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::trigger_auto_object( const exprt &expr, statet &state) diff --git a/src/goto-symex/build_goto_trace.cpp b/src/goto-symex/build_goto_trace.cpp index 909a437bd9c..ee03e7e0bd8 100644 --- a/src/goto-symex/build_goto_trace.cpp +++ b/src/goto-symex/build_goto_trace.cpp @@ -8,6 +8,11 @@ Author: Daniel Kroening \*******************************************************************/ +/// \file +/// Traces of GOTO Programs + +#include "build_goto_trace.h" + #include #include @@ -19,20 +24,6 @@ Author: Daniel Kroening #include "partial_order_concurrency.h" -#include "build_goto_trace.h" - -/*******************************************************************\ - -Function: build_full_lhs_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt build_full_lhs_rec( const prop_convt &prop_conv, const namespacet &ns, @@ -110,18 +101,6 @@ exprt build_full_lhs_rec( return src_original; } -/*******************************************************************\ - -Function: adjust_lhs_object - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt adjust_lhs_object( const prop_convt &prop_conv, const namespacet &ns, @@ -130,18 +109,6 @@ exprt adjust_lhs_object( return nil_exprt(); } -/*******************************************************************\ - -Function: build_goto_trace - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void build_goto_trace( const symex_target_equationt &target, symex_target_equationt::SSA_stepst::const_iterator end_step, @@ -220,9 +187,13 @@ void build_goto_trace( // drop PHI and GUARD assignments altogether if(it->is_assignment() && - (SSA_step.assignment_type==symex_target_equationt::PHI || - SSA_step.assignment_type==symex_target_equationt::GUARD)) + (SSA_step.assignment_type== + symex_target_equationt::assignment_typet::PHI || + SSA_step.assignment_type== + symex_target_equationt::assignment_typet::GUARD)) + { continue; + } goto_tracet::stepst &steps=time_map[current_time]; steps.push_back(goto_trace_stept()); @@ -247,10 +218,12 @@ void build_goto_trace( goto_trace_step.assignment_type= (it->is_assignment()&& - (SSA_step.assignment_type==symex_targett::VISIBLE_ACTUAL_PARAMETER || - SSA_step.assignment_type==symex_targett::HIDDEN_ACTUAL_PARAMETER))? - goto_trace_stept::ACTUAL_PARAMETER: - goto_trace_stept::STATE; + (SSA_step.assignment_type== + symex_targett::assignment_typet::VISIBLE_ACTUAL_PARAMETER || + SSA_step.assignment_type== + symex_targett::assignment_typet::HIDDEN_ACTUAL_PARAMETER))? + goto_trace_stept::assignment_typet::ACTUAL_PARAMETER: + goto_trace_stept::assignment_typet::STATE; if(SSA_step.original_full_lhs.is_not_nil()) goto_trace_step.full_lhs= @@ -290,7 +263,7 @@ void build_goto_trace( } // Now assemble into a single goto_trace. - // This expoits sorted-ness of the map. + // This exploits sorted-ness of the map. for(auto &t_it : time_map) goto_trace.steps.splice(goto_trace.steps.end(), t_it.second); @@ -312,18 +285,6 @@ void build_goto_trace( s_it.step_nr=++step_nr; } -/*******************************************************************\ - -Function: build_goto_trace - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void build_goto_trace( const symex_target_equationt &target, const prop_convt &prop_conv, diff --git a/src/goto-symex/build_goto_trace.h b/src/goto-symex/build_goto_trace.h index f7350d41ffe..16df35f7e7e 100644 --- a/src/goto-symex/build_goto_trace.h +++ b/src/goto-symex/build_goto_trace.h @@ -8,6 +8,9 @@ Date: July 2005 \*******************************************************************/ +/// \file +/// Traces of GOTO Programs + #ifndef CPROVER_GOTO_SYMEX_BUILD_GOTO_TRACE_H #define CPROVER_GOTO_SYMEX_BUILD_GOTO_TRACE_H diff --git a/src/goto-symex/goto_symex.cpp b/src/goto-symex/goto_symex.cpp index a3d55220e8d..7e50d9d9125 100644 --- a/src/goto-symex/goto_symex.cpp +++ b/src/goto-symex/goto_symex.cpp @@ -6,43 +6,22 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Symbolic Execution #include "goto_symex.h" +#include + unsigned goto_symext::nondet_count=0; unsigned goto_symext::dynamic_counter=0; -/*******************************************************************\ - -Function: goto_symext::do_simplify - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::do_simplify(exprt &expr) { if(options.get_bool_option("simplify")) simplify(expr, ns); } -/*******************************************************************\ - -Function: goto_symext::replace_nondet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::replace_nondet(exprt &expr) { if(expr.id()==ID_side_effect && diff --git a/src/goto-symex/goto_symex.h b/src/goto-symex/goto_symex.h index f8c2cda0bf9..de4253f4dc2 100644 --- a/src/goto-symex/goto_symex.h +++ b/src/goto-symex/goto_symex.h @@ -6,12 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symbolic Execution + #ifndef CPROVER_GOTO_SYMEX_GOTO_SYMEX_H #define CPROVER_GOTO_SYMEX_GOTO_SYMEX_H -/*! \defgroup goto_symex Symbolic execution of goto programs -*/ - #include #include @@ -152,6 +152,16 @@ class goto_symext irep_idt guard_identifier; // symex + virtual void symex_transition( + statet &state, + goto_programt::const_targett to, + bool is_backwards_goto=false); + virtual void symex_transition(statet &state) + { + goto_programt::const_targett next=state.source.pc; + ++next; + symex_transition(state, next); + } virtual void symex_goto(statet &state); virtual void symex_start_thread(statet &state); diff --git a/src/goto-symex/goto_symex_state.cpp b/src/goto-symex/goto_symex_state.cpp index e1a8938d823..6402923c4cf 100644 --- a/src/goto-symex/goto_symex_state.cpp +++ b/src/goto-symex/goto_symex_state.cpp @@ -6,52 +6,32 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symbolic Execution + +#include "goto_symex_state.h" + #include #include #include +#include #include #include #include -#include "goto_symex_state.h" - -/*******************************************************************\ - -Function: goto_symex_statet::goto_symex_statet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - goto_symex_statet::goto_symex_statet(): depth(0), - symex_target(NULL), + symex_target(nullptr), atomic_section_id(0), record_events(true), - dirty(0) + dirty(nullptr) { threads.resize(1); new_frame(); } -/*******************************************************************\ - -Function: goto_symex_statet::initialize - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symex_statet::initialize(const goto_functionst &goto_functions) { goto_functionst::function_mapt::const_iterator it= @@ -67,18 +47,6 @@ void goto_symex_statet::initialize(const goto_functionst &goto_functions) top().calling_location.pc=top().end_of_function; } -/*******************************************************************\ - -Function: goto_symex_statet::level0t::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symex_statet::level0t::operator()( ssa_exprt &ssa_expr, const namespacet &ns, @@ -98,7 +66,7 @@ void goto_symex_statet::level0t::operator()( if(ns.lookup(obj_identifier, s)) { - std::cerr << "level0: failed to find " << obj_identifier << std::endl; + std::cerr << "level0: failed to find " << obj_identifier << '\n'; abort(); } @@ -111,18 +79,6 @@ void goto_symex_statet::level0t::operator()( ssa_expr.set_level_0(thread_nr); } -/*******************************************************************\ - -Function: goto_symex_statet::level1t::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symex_statet::level1t::operator()(ssa_exprt &ssa_expr) { // already renamed? @@ -139,19 +95,8 @@ void goto_symex_statet::level1t::operator()(ssa_exprt &ssa_expr) ssa_expr.set_level_1(it->second.second); } -/*******************************************************************\ - -Function: goto_symex_statet::constant_propagation - - Inputs: - - Outputs: - - Purpose: This function determines what expressions are to - be propagated as "constants" - -\*******************************************************************/ - +/// This function determines what expressions are to be propagated as +/// "constants" bool goto_symex_statet::constant_propagation(const exprt &expr) const { if(expr.is_constant()) @@ -181,8 +126,12 @@ bool goto_symex_statet::constant_propagation(const exprt &expr) const { // propagate stuff with sizeof in it forall_operands(it, expr) + { if(it->find(ID_C_c_sizeof_type).is_not_nil()) return true; + else if(!constant_propagation(*it)) + return false; + } return true; } @@ -240,19 +189,7 @@ bool goto_symex_statet::constant_propagation(const exprt &expr) const return false; } -/*******************************************************************\ - -Function: goto_symex_statet::constant_propagation_reference - - Inputs: - - Outputs: - - Purpose: this function determines which reference-typed - expressions are constant - -\*******************************************************************/ - +/// this function determines which reference-typed expressions are constant bool goto_symex_statet::constant_propagation_reference(const exprt &expr) const { if(expr.id()==ID_symbol) @@ -277,18 +214,7 @@ bool goto_symex_statet::constant_propagation_reference(const exprt &expr) const return false; } -/*******************************************************************\ - -Function: goto_symex_statet::assignment - - Inputs: - - Outputs: - - Purpose: write to a variable - -\*******************************************************************/ - +/// write to a variable static bool check_renaming(const exprt &expr); static bool check_renaming(const typet &type) @@ -375,7 +301,7 @@ static void assert_l1_renaming(const exprt &expr) #if 1 if(check_renaming_l1(expr)) { - std::cerr << expr.pretty() << std::endl; + std::cerr << expr.pretty() << '\n'; assert(false); } #else @@ -388,7 +314,7 @@ static void assert_l2_renaming(const exprt &expr) #if 1 if(check_renaming(expr)) { - std::cerr << expr.pretty() << std::endl; + std::cerr << expr.pretty() << '\n'; assert(false); } #else @@ -455,24 +381,12 @@ void goto_symex_statet::assignment( } #if 0 - std::cout << "Assigning " << l1_identifier << std::endl; + std::cout << "Assigning " << l1_identifier << '\n'; value_set.output(ns, std::cout); - std::cout << "**********************" << std::endl; + std::cout << "**********************\n"; #endif } -/*******************************************************************\ - -Function: goto_symex_statet::propagationt::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symex_statet::propagationt::operator()(exprt &expr) { if(expr.id()==ID_symbol) @@ -494,18 +408,6 @@ void goto_symex_statet::propagationt::operator()(exprt &expr) } } -/*******************************************************************\ - -Function: goto_symex_statet::set_ssa_indices - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symex_statet::set_ssa_indices( ssa_exprt &ssa_expr, const namespacet &ns, @@ -539,18 +441,6 @@ void goto_symex_statet::set_ssa_indices( } } -/*******************************************************************\ - -Function: goto_symex_statet::rename - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symex_statet::rename( exprt &expr, const namespacet &ns, @@ -642,18 +532,7 @@ void goto_symex_statet::rename( } } -/*******************************************************************\ - -Function: goto_symex_statet::l2_thread_read_encoding - - Inputs: - - Outputs: - - Purpose: thread encoding - -\*******************************************************************/ - +/// thread encoding bool goto_symex_statet::l2_thread_read_encoding( ssa_exprt &expr, const namespacet &ns) @@ -663,7 +542,7 @@ bool goto_symex_statet::l2_thread_read_encoding( return false; // is it a shared object? - assert(dirty!=0); + INVARIANT_STRUCTURED(dirty!=nullptr, nullptr_exceptiont, "dirty is null"); const irep_idt &obj_identifier=expr.get_object_name(); if(obj_identifier=="goto_symex::\\guard" || (!ns.lookup(obj_identifier).is_shared() && @@ -759,7 +638,7 @@ bool goto_symex_statet::l2_thread_read_encoding( ssa_l1.get_original_expr(), tmp, source, - symex_targett::PHI); + symex_targett::assignment_typet::PHI); set_ssa_indices(ssa_l1, ns, L2); expr=ssa_l1; @@ -788,7 +667,8 @@ bool goto_symex_statet::l2_thread_read_encoding( expr=ssa_l1; // and record that - assert(symex_target!=NULL); + INVARIANT_STRUCTURED( + symex_target!=nullptr, nullptr_exceptiont, "symex_target is null"); symex_target->shared_read( guard.as_expr(), expr, @@ -798,18 +678,7 @@ bool goto_symex_statet::l2_thread_read_encoding( return true; } -/*******************************************************************\ - -Function: goto_symex_statet::l2_thread_write_encoding - - Inputs: - - Outputs: - - Purpose: thread encoding - -\*******************************************************************/ - +/// thread encoding bool goto_symex_statet::l2_thread_write_encoding( const ssa_exprt &expr, const namespacet &ns) @@ -818,7 +687,7 @@ bool goto_symex_statet::l2_thread_write_encoding( return false; // is it a shared object? - assert(dirty!=0); + INVARIANT_STRUCTURED(dirty!=nullptr, nullptr_exceptiont, "dirty is null"); const irep_idt &obj_identifier=expr.get_object_name(); if(obj_identifier=="goto_symex::\\guard" || (!ns.lookup(obj_identifier).is_shared() && @@ -846,18 +715,6 @@ bool goto_symex_statet::l2_thread_write_encoding( return threads.size()>1; } -/*******************************************************************\ - -Function: goto_symex_statet::rename_address - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symex_statet::rename_address( exprt &expr, const namespacet &ns, @@ -935,18 +792,6 @@ void goto_symex_statet::rename_address( } } -/*******************************************************************\ - -Function: goto_symex_statet::rename - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symex_statet::rename( typet &type, const irep_idt &l1_identifier, @@ -1018,18 +863,6 @@ void goto_symex_statet::rename( l1_type_entry.first->second=type; } -/*******************************************************************\ - -Function: goto_symex_statet::get_original_name - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symex_statet::get_original_name(exprt &expr) const { get_original_name(expr.type()); @@ -1042,18 +875,6 @@ void goto_symex_statet::get_original_name(exprt &expr) const get_original_name(*it); } -/*******************************************************************\ - -Function: goto_symex_statet::get_original_name - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symex_statet::get_original_name(typet &type) const { // rename all the symbols with their last known value @@ -1082,18 +903,6 @@ void goto_symex_statet::get_original_name(typet &type) const } } -/*******************************************************************\ - -Function: goto_symex_statet::get_l1_name - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symex_statet::get_l1_name(exprt &expr) const { // do not reset the type ! @@ -1106,18 +915,6 @@ void goto_symex_statet::get_l1_name(exprt &expr) const get_l1_name(*it); } -/*******************************************************************\ - -Function: goto_symex_statet::switch_to_thread - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symex_statet::switch_to_thread(unsigned t) { assert(source.thread_nr +/// \file +/// Memory model for partial order concurrency #include "memory_model.h" -/*******************************************************************\ - -Function: memory_model_baset::memory_model_baset - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include memory_model_baset::memory_model_baset(const namespacet &_ns): partial_order_concurrencyt(_ns), @@ -28,34 +19,10 @@ memory_model_baset::memory_model_baset(const namespacet &_ns): { } -/*******************************************************************\ - -Function: memory_model_baset::~memory_model_baset - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - memory_model_baset::~memory_model_baset() { } -/*******************************************************************\ - -Function: memory_model_baset::nondet_bool_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - symbol_exprt memory_model_baset::nondet_bool_symbol( const std::string &prefix) { @@ -64,18 +31,6 @@ symbol_exprt memory_model_baset::nondet_bool_symbol( bool_typet()); } -/*******************************************************************\ - -Function: memory_model_baset::po - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool memory_model_baset::po(event_it e1, event_it e2) { // within same thread @@ -88,18 +43,6 @@ bool memory_model_baset::po(event_it e1, event_it e2) } } -/*******************************************************************\ - -Function: memory_model_baset::read_from - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void memory_model_baset::read_from(symex_target_equationt &equation) { // We iterate over all the reads, and diff --git a/src/goto-symex/memory_model.h b/src/goto-symex/memory_model.h index b72c3672613..083a75efa5b 100644 --- a/src/goto-symex/memory_model.h +++ b/src/goto-symex/memory_model.h @@ -6,6 +6,9 @@ Author: Michael Tautschnig, michael.tautschnig@cs.ox.ac.uk \*******************************************************************/ +/// \file +/// Memory models for partial order concurrency + #ifndef CPROVER_GOTO_SYMEX_MEMORY_MODEL_H #define CPROVER_GOTO_SYMEX_MEMORY_MODEL_H diff --git a/src/goto-symex/memory_model_pso.cpp b/src/goto-symex/memory_model_pso.cpp index 629451fc80b..2ef634e208c 100644 --- a/src/goto-symex/memory_model_pso.cpp +++ b/src/goto-symex/memory_model_pso.cpp @@ -6,23 +6,14 @@ Author: Michael Tautschnig, michael.tautschnig@cs.ox.ac.uk \*******************************************************************/ -#include "memory_model_pso.h" - -/*******************************************************************\ - -Function: memory_model_psot::operator() - - Inputs: +/// \file +/// Memory model for partial order concurrency - Outputs: - - Purpose: - -\*******************************************************************/ +#include "memory_model_pso.h" void memory_model_psot::operator()(symex_target_equationt &equation) { - print(8, "Adding PSO constraints"); + statistics() << "Adding PSO constraints" << eom; build_event_lists(equation); build_clock_type(equation); @@ -35,18 +26,6 @@ void memory_model_psot::operator()(symex_target_equationt &equation) #endif } -/*******************************************************************\ - -Function: memory_model_psot::program_order_is_relaxed - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool memory_model_psot::program_order_is_relaxed( partial_order_concurrencyt::event_it e1, partial_order_concurrencyt::event_it e2) const diff --git a/src/goto-symex/memory_model_pso.h b/src/goto-symex/memory_model_pso.h index 386a035bdcb..ca3cab0cd14 100644 --- a/src/goto-symex/memory_model_pso.h +++ b/src/goto-symex/memory_model_pso.h @@ -6,6 +6,9 @@ Author: Michael Tautschnig, michael.tautschnig@cs.ox.ac.uk \*******************************************************************/ +/// \file +/// Memory models for partial order concurrency + #ifndef CPROVER_GOTO_SYMEX_MEMORY_MODEL_PSO_H #define CPROVER_GOTO_SYMEX_MEMORY_MODEL_PSO_H diff --git a/src/goto-symex/memory_model_sc.cpp b/src/goto-symex/memory_model_sc.cpp index 7c131269802..cfe30c80766 100644 --- a/src/goto-symex/memory_model_sc.cpp +++ b/src/goto-symex/memory_model_sc.cpp @@ -6,25 +6,16 @@ Author: Michael Tautschnig, michael.tautschnig@cs.ox.ac.uk \*******************************************************************/ -#include +/// \file +/// Memory model for partial order concurrency #include "memory_model_sc.h" -/*******************************************************************\ - -Function: memory_model_sct::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void memory_model_sct::operator()(symex_target_equationt &equation) { - print(8, "Adding SC constraints"); + statistics() << "Adding SC constraints" << eom; build_event_lists(equation); build_clock_type(equation); @@ -35,36 +26,12 @@ void memory_model_sct::operator()(symex_target_equationt &equation) from_read(equation); } -/*******************************************************************\ - -Function: memory_model_sct::before - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt memory_model_sct::before(event_it e1, event_it e2) { return partial_order_concurrencyt::before( e1, e2, AX_PROPAGATION); } -/*******************************************************************\ - -Function: memory_model_sct::program_order_is_relaxed - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool memory_model_sct::program_order_is_relaxed( partial_order_concurrencyt::event_it e1, partial_order_concurrencyt::event_it e2) const @@ -75,18 +42,6 @@ bool memory_model_sct::program_order_is_relaxed( return false; } -/*******************************************************************\ - -Function: memory_model_sct::build_per_thread_map - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void memory_model_sct::build_per_thread_map( const symex_target_equationt &equation, per_thread_mapt &dest) const @@ -98,7 +53,7 @@ void memory_model_sct::build_per_thread_map( e_it!=equation.SSA_steps.end(); e_it++) { - // concurreny-related? + // concurrency-related? if(!e_it->is_shared_read() && !e_it->is_shared_write() && !e_it->is_spawn() && @@ -108,18 +63,6 @@ void memory_model_sct::build_per_thread_map( } } -/*******************************************************************\ - -Function: memory_model_sct::thread_spawn - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void memory_model_sct::thread_spawn( symex_target_equationt &equation, const per_thread_mapt &per_thread_map) @@ -203,18 +146,6 @@ void memory_model_sct::thread_spawn( } #endif -/*******************************************************************\ - -Function: memory_model_sct::program_order - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void memory_model_sct::program_order( symex_target_equationt &equation) { @@ -262,18 +193,6 @@ void memory_model_sct::program_order( } } -/*******************************************************************\ - -Function: memory_model_sct::write_serialization_external - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void memory_model_sct::write_serialization_external( symex_target_equationt &equation) { @@ -326,18 +245,6 @@ void memory_model_sct::write_serialization_external( } } -/*******************************************************************\ - -Function: memory_model_sct::from_read - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void memory_model_sct::from_read(symex_target_equationt &equation) { // from-read: (w', w) in ws and (w', r) in rf -> (r, w) in fr diff --git a/src/goto-symex/memory_model_sc.h b/src/goto-symex/memory_model_sc.h index 66709ae22be..33e2edcb461 100644 --- a/src/goto-symex/memory_model_sc.h +++ b/src/goto-symex/memory_model_sc.h @@ -6,6 +6,9 @@ Author: Michael Tautschnig, michael.tautschnig@cs.ox.ac.uk \*******************************************************************/ +/// \file +/// Memory models for partial order concurrency + #ifndef CPROVER_GOTO_SYMEX_MEMORY_MODEL_SC_H #define CPROVER_GOTO_SYMEX_MEMORY_MODEL_SC_H diff --git a/src/goto-symex/memory_model_tso.cpp b/src/goto-symex/memory_model_tso.cpp index 1fec15c9bdd..5b390267086 100644 --- a/src/goto-symex/memory_model_tso.cpp +++ b/src/goto-symex/memory_model_tso.cpp @@ -6,26 +6,17 @@ Author: Michael Tautschnig, michael.tautschnig@cs.ox.ac.uk \*******************************************************************/ -#include -#include +/// \file +/// Memory model for partial order concurrency #include "memory_model_tso.h" -/*******************************************************************\ - -Function: memory_model_tsot::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include void memory_model_tsot::operator()(symex_target_equationt &equation) { - print(8, "Adding TSO constraints"); + statistics() << "Adding TSO constraints" << eom; build_event_lists(equation); build_clock_type(equation); @@ -38,36 +29,12 @@ void memory_model_tsot::operator()(symex_target_equationt &equation) #endif } -/*******************************************************************\ - -Function: memory_model_tsot::before - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt memory_model_tsot::before(event_it e1, event_it e2) { return partial_order_concurrencyt::before( e1, e2, AX_SC_PER_LOCATION | AX_PROPAGATION); } -/*******************************************************************\ - -Function: memory_model_tsot::program_order_is_relaxed - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool memory_model_tsot::program_order_is_relaxed( partial_order_concurrencyt::event_it e1, partial_order_concurrencyt::event_it e2) const @@ -84,18 +51,6 @@ bool memory_model_tsot::program_order_is_relaxed( return e1->is_shared_write() && e2->is_shared_read(); } -/*******************************************************************\ - -Function: memory_model_tsot::program_order - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void memory_model_tsot::program_order( symex_target_equationt &equation) { diff --git a/src/goto-symex/memory_model_tso.h b/src/goto-symex/memory_model_tso.h index 11de873e02a..87592e471f6 100644 --- a/src/goto-symex/memory_model_tso.h +++ b/src/goto-symex/memory_model_tso.h @@ -6,6 +6,9 @@ Author: Michael Tautschnig, michael.tautschnig@cs.ox.ac.uk \*******************************************************************/ +/// \file +/// Memory models for partial order concurrency + #ifndef CPROVER_GOTO_SYMEX_MEMORY_MODEL_TSO_H #define CPROVER_GOTO_SYMEX_MEMORY_MODEL_TSO_H diff --git a/src/goto-symex/module.md b/src/goto-symex/module.md new file mode 100644 index 00000000000..6c8321ce33e --- /dev/null +++ b/src/goto-symex/module.md @@ -0,0 +1,44 @@ +\ingroup module_hidden +\defgroup module_goto-symex Symbolic Execution & Counterexample Production + +\author Kareem Khazem + +**Key classes:** +* goto_symex_statet +* goto_symext + +\dot +digraph G { + node [shape=box]; + rankdir="LR"; + 1 [shape=none, label=""]; + 2 [label="goto conversion"]; + 3 [shape=none, label=""]; + 1 -> 2 [label="goto-programs, goto-functions, symbol table"]; + 2 -> 3 [label="equations"]; +} +\enddot + +--- +\section counter-example-production Counter Example Production + +In the \ref goto-symex directory. + +**Key classes:** +* symex_target_equationt +* prop_convt +* \ref bmct +* fault_localizationt +* counterexample_beautificationt + +\dot +digraph G { + node [shape=box]; + rankdir="LR"; + 1 [shape=none, label=""]; + 2 [label="goto conversion"]; + 3 [shape=none, label=""]; + 1 -> 2 [label="solutions"]; + 2 -> 3 [label="counter-examples"]; +} +\enddot diff --git a/src/goto-symex/partial_order_concurrency.cpp b/src/goto-symex/partial_order_concurrency.cpp index 7ec03afab34..e0f82ba6af2 100644 --- a/src/goto-symex/partial_order_concurrency.cpp +++ b/src/goto-symex/partial_order_concurrency.cpp @@ -6,58 +6,25 @@ Author: Michael Tautschnig, michael.tautschnig@cs.ox.ac.uk \*******************************************************************/ -#include - -#include -#include +/// \file +/// Add constraints to equation encoding partial orders on events #include "partial_order_concurrency.h" -/*******************************************************************\ - -Function: partial_order_concurrencyt::~partial_order_concurrencyt - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include +#include partial_order_concurrencyt::partial_order_concurrencyt( const namespacet &_ns):ns(_ns) { } -/*******************************************************************\ - -Function: partial_order_concurrencyt::~partial_order_concurrencyt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - partial_order_concurrencyt::~partial_order_concurrencyt() { } -/*******************************************************************\ - -Function: partial_order_concurrencyt::add_init_writes - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void partial_order_concurrencyt::add_init_writes( symex_target_equationt &equation) { @@ -96,7 +63,7 @@ void partial_order_concurrencyt::add_init_writes( // no SSA L2 index, thus nondet value SSA_step.ssa_lhs=e_it->ssa_lhs; SSA_step.ssa_lhs.remove_level_2(); - SSA_step.type=goto_trace_stept::SHARED_WRITE; + SSA_step.type=goto_trace_stept::typet::SHARED_WRITE; SSA_step.atomic_section_id=0; SSA_step.source=e_it->source; } @@ -107,18 +74,6 @@ void partial_order_concurrencyt::add_init_writes( equation.SSA_steps.splice(equation.SSA_steps.begin(), init_steps); } -/*******************************************************************\ - -Function: partial_order_concurrencyt::build_event_lists - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void partial_order_concurrencyt::build_event_lists( symex_target_equationt &equation) { @@ -169,18 +124,6 @@ void partial_order_concurrencyt::build_event_lists( } } -/*******************************************************************\ - -Function: partial_order_concurrencyt::rw_clock_id - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - irep_idt partial_order_concurrencyt::rw_clock_id( event_it event, axiomt axiom) @@ -195,18 +138,6 @@ irep_idt partial_order_concurrencyt::rw_clock_id( return ""; } -/*******************************************************************\ - -Function: partial_order_concurrencyt::clock - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - symbol_exprt partial_order_concurrencyt::clock( event_it event, axiomt axiom) @@ -230,18 +161,6 @@ symbol_exprt partial_order_concurrencyt::clock( return symbol_exprt(identifier, clock_type); } -/*******************************************************************\ - -Function: partial_order_concurrencyt::build_clock_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void partial_order_concurrencyt::build_clock_type( const symex_target_equationt &equation) { @@ -252,18 +171,6 @@ void partial_order_concurrencyt::build_clock_type( clock_type=unsignedbv_typet(integer2unsigned(width)); } -/*******************************************************************\ - -Function: partial_order_concurrencyt::before - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt partial_order_concurrencyt::before( event_it e1, event_it e2, unsigned axioms) { @@ -298,18 +205,6 @@ exprt partial_order_concurrencyt::before( return conjunction(ops); } -/*******************************************************************\ - -Function: partial_order_concurrencyt::add_constraint - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void partial_order_concurrencyt::add_constraint( symex_target_equationt &equation, const exprt &cond, diff --git a/src/goto-symex/partial_order_concurrency.h b/src/goto-symex/partial_order_concurrency.h index c18c8925d42..5163451e210 100644 --- a/src/goto-symex/partial_order_concurrency.h +++ b/src/goto-symex/partial_order_concurrency.h @@ -6,6 +6,9 @@ Author: Michael Tautschnig, michael.tautschnig@cs.ox.ac.uk \*******************************************************************/ +/// \file +/// Add constraints to equation encoding partial orders on events + #ifndef CPROVER_GOTO_SYMEX_PARTIAL_ORDER_CONCURRENCY_H #define CPROVER_GOTO_SYMEX_PARTIAL_ORDER_CONCURRENCY_H @@ -24,13 +27,13 @@ class partial_order_concurrencyt:public messaget typedef eventst::const_iterator event_it; // the name of a clock variable for a shared read/write - typedef enum + enum axiomt { AX_SC_PER_LOCATION=1, AX_NO_THINAIR=2, AX_OBSERVATION=4, AX_PROPAGATION=8 - } axiomt; + }; static irep_idt rw_clock_id( event_it e, @@ -191,14 +194,14 @@ class partial_order_concurrencyt { public: // the is-acyclic checks - typedef enum + enum acyclict { AC_UNIPROC=0, AC_THINAIR=1, AC_GHB=2, AC_PPC_WS_FENCE=3, AC_N_AXIOMS=4 - } acyclict; + }; typedef abstract_eventt evtt; typedef std::map > adj_matrixt; diff --git a/src/goto-symex/postcondition.cpp b/src/goto-symex/postcondition.cpp index c93aa52a407..4383439b72d 100644 --- a/src/goto-symex/postcondition.cpp +++ b/src/goto-symex/postcondition.cpp @@ -6,23 +6,15 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include -#include +/// \file +/// Symbolic Execution -#include "goto_symex_state.h" #include "postcondition.h" -/*******************************************************************\ - - Class: postconditiont - - Inputs: - - Outputs: - - Purpose: +#include +#include -\*******************************************************************/ +#include "goto_symex_state.h" class postconditiont { @@ -55,18 +47,6 @@ class postconditiont bool is_used(const exprt &expr, const irep_idt &identifier); }; -/*******************************************************************\ - -Function: postcondition - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void postcondition( const namespacet &ns, const value_sett &value_set, @@ -86,18 +66,6 @@ void postcondition( } } -/*******************************************************************\ - -Function: postconditiont::is_used_address_of - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool postconditiont::is_used_address_of( const exprt &expr, const irep_idt &identifier) @@ -128,18 +96,6 @@ bool postconditiont::is_used_address_of( return false; } -/*******************************************************************\ - -Function: postconditiont::compute - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void postconditiont::compute(exprt &dest) { // weaken due to assignment @@ -149,18 +105,6 @@ void postconditiont::compute(exprt &dest) strengthen(dest); } -/*******************************************************************\ - -Function: postconditiont::strengthen - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void postconditiont::weaken(exprt &dest) { if(dest.id()==ID_and && @@ -183,18 +127,6 @@ void postconditiont::weaken(exprt &dest) // otherwise, no weakening needed } -/*******************************************************************\ - -Function: postconditiont::strengthen - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void postconditiont::strengthen(exprt &dest) { const irep_idt &lhs_identifier=SSA_step.ssa_lhs.get_object_name(); @@ -216,18 +148,6 @@ void postconditiont::strengthen(exprt &dest) } } -/*******************************************************************\ - -Function: postconditiont::is_used - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool postconditiont::is_used( const exprt &expr, const irep_idt &identifier) diff --git a/src/goto-symex/postcondition.h b/src/goto-symex/postcondition.h index 3e84235da47..4f154a572cf 100644 --- a/src/goto-symex/postcondition.h +++ b/src/goto-symex/postcondition.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Generate Equation using Symbolic Execution + #ifndef CPROVER_GOTO_SYMEX_POSTCONDITION_H #define CPROVER_GOTO_SYMEX_POSTCONDITION_H diff --git a/src/goto-symex/precondition.cpp b/src/goto-symex/precondition.cpp index 15cc3e180a2..11657a78e55 100644 --- a/src/goto-symex/precondition.cpp +++ b/src/goto-symex/precondition.cpp @@ -6,24 +6,16 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - -#include +/// \file +/// Symbolic Execution -#include "goto_symex_state.h" #include "precondition.h" -/*******************************************************************\ - - Class: preconditiont - - Inputs: - - Outputs: +#include - Purpose: +#include -\*******************************************************************/ +#include "goto_symex_state.h" class preconditiont { @@ -57,18 +49,6 @@ class preconditiont void compute_address_of(exprt &dest); }; -/*******************************************************************\ - -Function: precondition - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void precondition( const namespacet &ns, value_setst &value_sets, @@ -89,18 +69,6 @@ void precondition( } } -/*******************************************************************\ - -Function: preconditiont::compute_address_of - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void preconditiont::compute_address_of(exprt &dest) { if(dest.id()==ID_symbol) @@ -125,35 +93,11 @@ void preconditiont::compute_address_of(exprt &dest) } } -/*******************************************************************\ - -Function: preconditiont::compute - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void preconditiont::compute(exprt &dest) { compute_rec(dest); } -/*******************************************************************\ - -Function: preconditiont::compute_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void preconditiont::compute_rec(exprt &dest) { if(dest.id()==ID_address_of) diff --git a/src/goto-symex/precondition.h b/src/goto-symex/precondition.h index 0d8b0caa23d..8adebcbd8c3 100644 --- a/src/goto-symex/precondition.h +++ b/src/goto-symex/precondition.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Generate Equation using Symbolic Execution + #ifndef CPROVER_GOTO_SYMEX_PRECONDITION_H #define CPROVER_GOTO_SYMEX_PRECONDITION_H diff --git a/src/goto-symex/rewrite_union.cpp b/src/goto-symex/rewrite_union.cpp index f0a329af5ae..0f40f934b84 100644 --- a/src/goto-symex/rewrite_union.cpp +++ b/src/goto-symex/rewrite_union.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symbolic Execution of ANSI-C + +#include "rewrite_union.h" + #include #include #include @@ -13,21 +18,7 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include - -#include "rewrite_union.h" - -/*******************************************************************\ - -Function: have_to_rewrite_union - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include static bool have_to_rewrite_union( const exprt &expr, @@ -51,19 +42,8 @@ static bool have_to_rewrite_union( return false; } -/*******************************************************************\ - -Function: rewrite_union - - Inputs: - - Outputs: - - Purpose: We rewrite u.c for unions u into byte_extract(u, 0), - and { .c = v } into byte_update(NIL, 0, v) - -\*******************************************************************/ - +/// We rewrite u.c for unions u into byte_extract(u, 0), and { .c = v } into +/// byte_update(NIL, 0, v) void rewrite_union( exprt &expr, const namespacet &ns) @@ -97,18 +77,6 @@ void rewrite_union( } } -/*******************************************************************\ - -Function: rewrite_union - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - static void rewrite_union( goto_functionst::goto_functiont &goto_function, const namespacet &ns) @@ -120,18 +88,6 @@ static void rewrite_union( } } -/*******************************************************************\ - -Function: rewrite_union - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void rewrite_union( goto_functionst &goto_functions, const namespacet &ns) @@ -140,18 +96,6 @@ void rewrite_union( rewrite_union(it->second, ns); } -/*******************************************************************\ - -Function: rewrite_union - -Inputs: - -Outputs: - -Purpose: - -\*******************************************************************/ - void rewrite_union(goto_modelt &goto_model) { namespacet ns(goto_model.symbol_table); diff --git a/src/goto-symex/rewrite_union.h b/src/goto-symex/rewrite_union.h index 7215e0bf0a4..d2c9b1772b4 100644 --- a/src/goto-symex/rewrite_union.h +++ b/src/goto-symex/rewrite_union.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symbolic Execution + #ifndef CPROVER_GOTO_SYMEX_REWRITE_UNION_H #define CPROVER_GOTO_SYMEX_REWRITE_UNION_H diff --git a/src/goto-symex/slice.cpp b/src/goto-symex/slice.cpp index ab377e2d9c9..0a59b7befea 100644 --- a/src/goto-symex/slice.cpp +++ b/src/goto-symex/slice.cpp @@ -6,22 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Slicer for symex traces #include "slice.h" -#include "symex_slice_class.h" - -/*******************************************************************\ - -Function: symex_slicet::get_symbols - - Inputs: - - Outputs: - Purpose: +#include -\*******************************************************************/ +#include "symex_slice_class.h" void symex_slicet::get_symbols(const exprt &expr) { @@ -34,35 +26,11 @@ void symex_slicet::get_symbols(const exprt &expr) depends.insert(to_symbol_expr(expr).get_identifier()); } -/*******************************************************************\ - -Function: symex_slicet::get_symbols - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_slicet::get_symbols(const typet &type) { // TODO } -/*******************************************************************\ - -Function: symex_slicet::slice - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_slicet::slice( symex_target_equationt &equation, const expr_listt &exprs) @@ -74,18 +42,6 @@ void symex_slicet::slice( slice(equation); } -/*******************************************************************\ - -Function: symex_slicet::slice - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_slicet::slice(symex_target_equationt &equation) { for(symex_target_equationt::SSA_stepst::reverse_iterator @@ -95,68 +51,56 @@ void symex_slicet::slice(symex_target_equationt &equation) slice(*it); } -/*******************************************************************\ - -Function: symex_slicet::slice - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_slicet::slice(symex_target_equationt::SSA_stept &SSA_step) { get_symbols(SSA_step.guard); switch(SSA_step.type) { - case goto_trace_stept::ASSERT: + case goto_trace_stept::typet::ASSERT: get_symbols(SSA_step.cond_expr); break; - case goto_trace_stept::ASSUME: + case goto_trace_stept::typet::ASSUME: get_symbols(SSA_step.cond_expr); break; - case goto_trace_stept::GOTO: + case goto_trace_stept::typet::GOTO: get_symbols(SSA_step.cond_expr); break; - case goto_trace_stept::LOCATION: + case goto_trace_stept::typet::LOCATION: // ignore break; - case goto_trace_stept::ASSIGNMENT: + case goto_trace_stept::typet::ASSIGNMENT: slice_assignment(SSA_step); break; - case goto_trace_stept::DECL: + case goto_trace_stept::typet::DECL: slice_decl(SSA_step); break; - case goto_trace_stept::OUTPUT: - case goto_trace_stept::INPUT: + case goto_trace_stept::typet::OUTPUT: + case goto_trace_stept::typet::INPUT: break; - case goto_trace_stept::DEAD: + case goto_trace_stept::typet::DEAD: // ignore for now break; - case goto_trace_stept::CONSTRAINT: - case goto_trace_stept::SHARED_READ: - case goto_trace_stept::SHARED_WRITE: - case goto_trace_stept::ATOMIC_BEGIN: - case goto_trace_stept::ATOMIC_END: - case goto_trace_stept::SPAWN: - case goto_trace_stept::MEMORY_BARRIER: + case goto_trace_stept::typet::CONSTRAINT: + case goto_trace_stept::typet::SHARED_READ: + case goto_trace_stept::typet::SHARED_WRITE: + case goto_trace_stept::typet::ATOMIC_BEGIN: + case goto_trace_stept::typet::ATOMIC_END: + case goto_trace_stept::typet::SPAWN: + case goto_trace_stept::typet::MEMORY_BARRIER: // ignore for now break; - case goto_trace_stept::FUNCTION_CALL: - case goto_trace_stept::FUNCTION_RETURN: + case goto_trace_stept::typet::FUNCTION_CALL: + case goto_trace_stept::typet::FUNCTION_RETURN: // ignore for now break; @@ -165,18 +109,6 @@ void symex_slicet::slice(symex_target_equationt::SSA_stept &SSA_step) } } -/*******************************************************************\ - -Function: symex_slicet::slice_assignment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_slicet::slice_assignment( symex_target_equationt::SSA_stept &SSA_step) { @@ -192,18 +124,6 @@ void symex_slicet::slice_assignment( get_symbols(SSA_step.ssa_rhs); } -/*******************************************************************\ - -Function: symex_slicet::slice_decl - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_slicet::slice_decl( symex_target_equationt::SSA_stept &SSA_step) { @@ -217,20 +137,11 @@ void symex_slicet::slice_decl( } } -/*******************************************************************\ - -Function: symex_slice_classt::collect_open_variables - - Inputs: equation - symex trace - open_variables - target set - - Outputs: None. But open_variables is modified as a side-effect. - - Purpose: Collect the open variables, i.e., variables that are used - in RHS but never written in LHS - -\*******************************************************************/ - +/// Collect the open variables, i.e., variables that are used in RHS but never +/// written in LHS +/// \param equation: symex trace +/// \param open_variables: target set +/// \return None. But open_variables is modified as a side-effect. void symex_slicet::collect_open_variables( const symex_target_equationt &equation, symbol_sett &open_variables) @@ -248,39 +159,39 @@ void symex_slicet::collect_open_variables( switch(SSA_step.type) { - case goto_trace_stept::ASSERT: + case goto_trace_stept::typet::ASSERT: get_symbols(SSA_step.cond_expr); break; - case goto_trace_stept::ASSUME: + case goto_trace_stept::typet::ASSUME: get_symbols(SSA_step.cond_expr); break; - case goto_trace_stept::LOCATION: + case goto_trace_stept::typet::LOCATION: // ignore break; - case goto_trace_stept::ASSIGNMENT: + case goto_trace_stept::typet::ASSIGNMENT: get_symbols(SSA_step.ssa_rhs); lhs.insert(SSA_step.ssa_lhs.get_identifier()); break; - case goto_trace_stept::OUTPUT: - case goto_trace_stept::INPUT: - case goto_trace_stept::DEAD: - case goto_trace_stept::NONE: + case goto_trace_stept::typet::OUTPUT: + case goto_trace_stept::typet::INPUT: + case goto_trace_stept::typet::DEAD: + case goto_trace_stept::typet::NONE: break; - case goto_trace_stept::DECL: - case goto_trace_stept::FUNCTION_CALL: - case goto_trace_stept::FUNCTION_RETURN: - case goto_trace_stept::CONSTRAINT: - case goto_trace_stept::SHARED_READ: - case goto_trace_stept::SHARED_WRITE: - case goto_trace_stept::ATOMIC_BEGIN: - case goto_trace_stept::ATOMIC_END: - case goto_trace_stept::SPAWN: - case goto_trace_stept::MEMORY_BARRIER: + case goto_trace_stept::typet::DECL: + case goto_trace_stept::typet::FUNCTION_CALL: + case goto_trace_stept::typet::FUNCTION_RETURN: + case goto_trace_stept::typet::CONSTRAINT: + case goto_trace_stept::typet::SHARED_READ: + case goto_trace_stept::typet::SHARED_WRITE: + case goto_trace_stept::typet::ATOMIC_BEGIN: + case goto_trace_stept::typet::ATOMIC_END: + case goto_trace_stept::typet::SPAWN: + case goto_trace_stept::typet::MEMORY_BARRIER: // ignore for now break; @@ -295,38 +206,17 @@ void symex_slicet::collect_open_variables( open_variables.erase(lhs.begin(), lhs.end()); } -/*******************************************************************\ - -Function: slice - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void slice(symex_target_equationt &equation) { symex_slicet symex_slice; symex_slice.slice(equation); } -/*******************************************************************\ - -Function: collect_open_variables - - Inputs: equation - symex trace - open_variables - target set - - Outputs: None. But open_variables is modified as a side-effect. - - Purpose: Collect the open variables, i.e. variables that are used - in RHS but never written in LHS - -\*******************************************************************/ - +/// Collect the open variables, i.e. variables that are used in RHS but never +/// written in LHS +/// \param equation: symex trace +/// \param open_variables: target set +/// \return None. But open_variables is modified as a side-effect. void collect_open_variables( const symex_target_equationt &equation, symbol_sett &open_variables) @@ -335,19 +225,10 @@ void collect_open_variables( symex_slice.collect_open_variables(equation, open_variables); } -/*******************************************************************\ - -Function: slice - - Inputs: equation - symex trace to be sliced - expression - list of expressions, targets for slicing - - Outputs: None. But equation is modified as a side-effect. - - Purpose: Slice the symex trace with respect to a list of expressions - -\*******************************************************************/ - +/// Slice the symex trace with respect to a list of expressions +/// \param equation: symex trace to be sliced +/// \param expression: list of expressions, targets for slicing +/// \return None. But equation is modified as a side-effect. void slice(symex_target_equationt &equation, const expr_listt &expressions) { @@ -355,18 +236,6 @@ void slice(symex_target_equationt &equation, symex_slice.slice(equation, expressions); } -/*******************************************************************\ - -Function: simple_slice - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void simple_slice(symex_target_equationt &equation) { // just find the last assertion diff --git a/src/goto-symex/slice.h b/src/goto-symex/slice.h index 1fd15969274..2bc887a0c9f 100644 --- a/src/goto-symex/slice.h +++ b/src/goto-symex/slice.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Slicer for symex traces + #ifndef CPROVER_GOTO_SYMEX_SLICE_H #define CPROVER_GOTO_SYMEX_SLICE_H diff --git a/src/goto-symex/slice_by_trace.cpp b/src/goto-symex/slice_by_trace.cpp index 096edf8ae38..828b457caa0 100644 --- a/src/goto-symex/slice_by_trace.cpp +++ b/src/goto-symex/slice_by_trace.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Slicer for symex traces + +#include "slice_by_trace.h" + #include #include #include @@ -19,25 +24,11 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "slice_by_trace.h" - -/*******************************************************************\ - -Function: slice_by_trace - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_slice_by_tracet::slice_by_trace( std::string trace_files, symex_target_equationt &equation) { - std::cout << "Slicing by trace..." << std::endl; + std::cout << "Slicing by trace...\n"; merge_identifier="goto_symex::\\merge"; merge_symbol=symbol_exprt(typet(ID_bool)); @@ -119,29 +110,17 @@ void symex_slice_by_tracet::slice_by_trace( SSA_step.guard=t_guard.as_expr(); SSA_step.ssa_lhs.make_nil(); SSA_step.cond_expr.swap(trace_condition); - SSA_step.type=goto_trace_stept::ASSUME; + SSA_step.type=goto_trace_stept::typet::ASSUME; SSA_step.source=empty_source; assign_merges(equation); // Now add the merge variable assignments to eqn - std::cout << "Finished slicing by trace..." << std::endl; + std::cout << "Finished slicing by trace...\n"; } -/*******************************************************************\ - -Function: read_trace - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_slice_by_tracet::read_trace(std::string filename) { - std::cout << "Reading trace from file " << filename << std::endl; + std::cout << "Reading trace from file " << filename << '\n'; std::ifstream file(filename); if(file.fail()) throw "failed to read from trace file"; @@ -184,18 +163,6 @@ void symex_slice_by_tracet::read_trace(std::string filename) t.push_back(t_e); } -/*******************************************************************\ - -Function: parse_alphabet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool symex_slice_by_tracet::parse_alphabet(std::string read_line) { if((read_line==":") || (read_line == ":exact") || @@ -210,32 +177,20 @@ bool symex_slice_by_tracet::parse_alphabet(std::string read_line) std::cout << "Alphabet: "; if(!alphabet_parity) std::cout << "!"; - std::cout << read_line << std::endl; + std::cout << read_line << '\n'; alphabet.insert(read_line); } return false; } -/*******************************************************************\ - -Function: parse_events - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_slice_by_tracet::parse_events(std::string read_line) { if(read_line=="") return; - bool parity=strstr(read_line.c_str(), "!")==NULL; - bool universe=strstr(read_line.c_str(), "?")!=NULL; - bool has_values=strstr(read_line.c_str(), " ")!=NULL; - std::cout << "Trace: " << read_line << std::endl; + bool parity=strstr(read_line.c_str(), "!")==nullptr; + bool universe=strstr(read_line.c_str(), "?")!=nullptr; + bool has_values=strstr(read_line.c_str(), " ")!=nullptr; + std::cout << "Trace: " << read_line << '\n'; std::vector value_v; if(has_values) { @@ -276,18 +231,6 @@ void symex_slice_by_tracet::parse_events(std::string read_line) sigma.push_back(es); } -/*******************************************************************\ - -Function: compute_ts_back - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_slice_by_tracet::compute_ts_back( symex_target_equationt &equation) { @@ -314,12 +257,12 @@ void symex_slice_by_tracet::compute_ts_back( exprt guard=i->guard; #if 0 - std::cout << "EVENT: " << event << std::endl; - std::cout << "GUARD: " << from_expr(ns, "", guard) << std::endl; + std::cout << "EVENT: " << event << '\n'; + std::cout << "GUARD: " << from_expr(ns, "", guard) << '\n'; for(size_t j=0; j < t.size(); j++) { std::cout << "t[" << j << "]=" << from_expr(ns, "", t[j]) << - std::endl; + '\n'; } #endif @@ -430,35 +373,11 @@ void symex_slice_by_tracet::compute_ts_back( } } -/*******************************************************************\ - -Function: compute_ts_fd - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_slice_by_tracet::compute_ts_fd( symex_target_equationt &equation) { } -/*******************************************************************\ - -Function: slice_SSA_steps - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_slice_by_tracet::slice_SSA_steps( symex_target_equationt &equation, std::set implications) @@ -489,7 +408,7 @@ void symex_slice_by_tracet::slice_SSA_steps( if(!guard.is_true()) potential_SSA_steps++; // it->output(ns,std::cout); - // std::cout << "-----------------" << std::endl; + // std::cout << "-----------------\n"; if((guard.id()==ID_symbol) || (guard.id() == ID_not)) { @@ -529,7 +448,7 @@ void symex_slice_by_tracet::slice_SSA_steps( } else if(guard.id()==ID_or) { - std::cout << "Guarded by an OR." << std::endl; + std::cout << "Guarded by an OR.\n"; } } @@ -568,26 +487,14 @@ void symex_slice_by_tracet::slice_SSA_steps( std::cout << "Trace slicing effectively removed " << (sliced_SSA_steps + sliced_conds) << " out of " - << equation.SSA_steps.size() << " SSA_steps." << std::endl; + << equation.SSA_steps.size() << " SSA_steps.\n"; std::cout << " (" << ((sliced_SSA_steps + sliced_conds) - trace_loc_sliced) << " out of " << (equation.SSA_steps.size()-trace_SSA_steps-location_SSA_steps) - << " non-trace, non-location SSA_steps)" << std::endl; + << " non-trace, non-location SSA_steps)\n"; } -/*******************************************************************\ - -Function: matches - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool symex_slice_by_tracet::matches( event_sett s, irep_idt event) @@ -596,18 +503,6 @@ bool symex_slice_by_tracet::matches( return ((s.second && present) || (!s.second && !present)); } -/*******************************************************************\ - -Function: assign_merges - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_slice_by_tracet::assign_merges( symex_target_equationt &equation) { @@ -630,26 +525,14 @@ void symex_slice_by_tracet::assign_merges( SSA_step.guard=t_guard.as_expr(); SSA_step.ssa_lhs=merge_sym; SSA_step.ssa_rhs.swap(merge_copy); - SSA_step.assignment_type=symex_targett::HIDDEN; + SSA_step.assignment_type=symex_targett::assignment_typet::HIDDEN; SSA_step.cond_expr=equal_exprt(SSA_step.ssa_lhs, SSA_step.ssa_rhs); - SSA_step.type=goto_trace_stept::ASSIGNMENT; + SSA_step.type=goto_trace_stept::typet::ASSIGNMENT; SSA_step.source=empty_source; } } -/*******************************************************************\ - -Function: implied_guards - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::set symex_slice_by_tracet::implied_guards(exprt e) { std::set s; @@ -732,18 +615,6 @@ std::set symex_slice_by_tracet::implied_guards(exprt e) return s; } -/*******************************************************************\ - -Function: symex_slice_by_tracet::implies_false - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool symex_slice_by_tracet::implies_false(const exprt e) { std::set imps=implied_guards(e); diff --git a/src/goto-symex/slice_by_trace.h b/src/goto-symex/slice_by_trace.h index 8223e6589e1..256930dfad7 100644 --- a/src/goto-symex/slice_by_trace.h +++ b/src/goto-symex/slice_by_trace.h @@ -6,6 +6,9 @@ Author: Alex Groce (agroce@gmail.com) \*******************************************************************/ +/// \file +/// Slicer for matching with trace files + #ifndef CPROVER_GOTO_SYMEX_SLICE_BY_TRACE_H #define CPROVER_GOTO_SYMEX_SLICE_BY_TRACE_H @@ -14,7 +17,9 @@ Author: Alex Groce (agroce@gmail.com) class symex_slice_by_tracet { public: - explicit symex_slice_by_tracet(const namespacet &_ns):ns(_ns) + explicit symex_slice_by_tracet(const namespacet &_ns): + ns(_ns), + alphabet_parity(false) { } diff --git a/src/goto-symex/symex_assign.cpp b/src/goto-symex/symex_assign.cpp index 795e1240f32..a403ff3a129 100644 --- a/src/goto-symex/symex_assign.cpp +++ b/src/goto-symex/symex_assign.cpp @@ -6,28 +6,20 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symbolic Execution + +#include "goto_symex.h" + #include #include -#include +#include -#include "goto_symex.h" #include "goto_symex_state.h" // #define USE_UPDATE -/*******************************************************************\ - -Function: goto_symext::symex_assign_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_assign_rec( statet &state, const code_assignt &code) @@ -40,18 +32,6 @@ void goto_symext::symex_assign_rec( symex_assign(state, deref_code); } -/*******************************************************************\ - -Function: goto_symext::symex_assign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_assign( statet &state, const code_assignt &code) @@ -93,39 +73,27 @@ void goto_symext::symex_assign( } else { - assignment_typet assignment_type=symex_targett::STATE; + assignment_typet assignment_type=symex_targett::assignment_typet::STATE; // Let's hide return value assignments. if(lhs.id()==ID_symbol && id2string(to_symbol_expr(lhs).get_identifier()).find( "#return_value!")!=std::string::npos) - assignment_type=symex_targett::HIDDEN; + assignment_type=symex_targett::assignment_typet::HIDDEN; // We hide if we are in a hidden function. if(state.top().hidden_function) - assignment_type=symex_targett::HIDDEN; + assignment_type=symex_targett::assignment_typet::HIDDEN; // We hide if we are executing a hidden instruction. if(state.source.pc->source_location.get_hide()) - assignment_type=symex_targett::HIDDEN; + assignment_type=symex_targett::assignment_typet::HIDDEN; guardt guard; // NOT the state guard! symex_assign_rec(state, lhs, nil_exprt(), rhs, guard, assignment_type); } } -/*******************************************************************\ - -Function: goto_symext::add_to_lhs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt goto_symext::add_to_lhs( const exprt &lhs, const exprt &what) @@ -156,18 +124,6 @@ exprt goto_symext::add_to_lhs( return new_lhs; } -/*******************************************************************\ - -Function: goto_symext::symex_assign_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_assign_rec( statet &state, const exprt &lhs, @@ -246,18 +202,6 @@ void goto_symext::symex_assign_rec( throw "assignment to `"+lhs.id_string()+"' not handled"; } -/*******************************************************************\ - -Function: goto_symext::symex_assign_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_assign_symbol( statet &state, const ssa_exprt &lhs, // L1 @@ -266,6 +210,17 @@ void goto_symext::symex_assign_symbol( guardt &guard, assignment_typet assignment_type) { + // do not assign to L1 objects that have gone out of scope -- + // pointer dereferencing may yield such objects; parameters do not + // have an L2 entry set up beforehand either, so exempt them from + // this check (all other L1 objects should have seen a declaration) + const symbolt *s; + if(!ns.lookup(lhs.get_object_name(), s) && + !s->is_parameter && + !lhs.get_level_1().empty() && + state.level2.current_count(lhs.get_identifier())==0) + return; + exprt ssa_rhs=rhs; // put assignment guard into the rhs @@ -303,7 +258,7 @@ void goto_symext::symex_assign_symbol( // do the assignment const symbolt &symbol=ns.lookup(ssa_lhs.get_original_expr()); if(symbol.is_auxiliary) - assignment_type=symex_targett::HIDDEN; + assignment_type=symex_targett::assignment_typet::HIDDEN; target.assignment( tmp_guard.as_expr(), @@ -314,18 +269,6 @@ void goto_symext::symex_assign_symbol( assignment_type); } -/*******************************************************************\ - -Function: goto_symext::symex_assign_typecast - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_assign_typecast( statet &state, const typecast_exprt &lhs, @@ -347,18 +290,6 @@ void goto_symext::symex_assign_typecast( state, lhs.op0(), new_full_lhs, rhs_typecasted, guard, assignment_type); } -/*******************************************************************\ - -Function: goto_symext::symex_assign_array - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_assign_array( statet &state, const index_exprt &lhs, @@ -415,18 +346,6 @@ void goto_symext::symex_assign_array( #endif } -/*******************************************************************\ - -Function: goto_symext::symex_assign_struct_member - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_assign_struct_member( statet &state, const member_exprt &lhs, @@ -501,18 +420,6 @@ void goto_symext::symex_assign_struct_member( #endif } -/*******************************************************************\ - -Function: goto_symext::symex_assign_if - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_assign_if( statet &state, const if_exprt &lhs, @@ -546,18 +453,6 @@ void goto_symext::symex_assign_if( } } -/*******************************************************************\ - -Function: goto_symext::symex_assign_byte_extract - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_assign_byte_extract( statet &state, const byte_extract_exprt &lhs, diff --git a/src/goto-symex/symex_atomic_section.cpp b/src/goto-symex/symex_atomic_section.cpp index 7f4e239f676..c243cafbcd4 100644 --- a/src/goto-symex/symex_atomic_section.cpp +++ b/src/goto-symex/symex_atomic_section.cpp @@ -6,19 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "goto_symex.h" - -/*******************************************************************\ - -Function: goto_symext::symex_atomic_begin - - Inputs: +/// \file +/// Symbolic Execution - Outputs: - - Purpose: - -\*******************************************************************/ +#include "goto_symex.h" void goto_symext::symex_atomic_begin(statet &state) { @@ -40,18 +31,6 @@ void goto_symext::symex_atomic_begin(statet &state) state.source); } -/*******************************************************************\ - -Function: goto_symext::symex_atomic_end - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_atomic_end(statet &state) { if(state.guard.is_false()) diff --git a/src/goto-symex/symex_builtin_functions.cpp b/src/goto-symex/symex_builtin_functions.cpp index c5bdd32d0f2..d6e9fd416d8 100644 --- a/src/goto-symex/symex_builtin_functions.cpp +++ b/src/goto-symex/symex_builtin_functions.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symbolic Execution of ANSI-C + +#include "goto_symex.h" + #include #include @@ -19,25 +24,12 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include +#include #include -#include "goto_symex.h" #include "goto_symex_state.h" -/*******************************************************************\ - -Function: goto_symext::symex_malloc - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - inline static typet c_sizeof_type_rec(const exprt &expr) { const irept &sizeof_type=expr.find(ID_C_c_sizeof_type); @@ -177,7 +169,7 @@ void goto_symext::symex_malloc( if(object_type.id()==ID_array) { - rhs.type()=pointer_typet(value_symbol.type.subtype()); + rhs.type()=pointer_type(value_symbol.type.subtype()); index_exprt index_expr(value_symbol.type.subtype()); index_expr.array()=value_symbol.symbol_expr(); index_expr.index()=from_integer(0, index_type()); @@ -186,7 +178,7 @@ void goto_symext::symex_malloc( else { rhs.op0()=value_symbol.symbol_expr(); - rhs.type()=pointer_typet(value_symbol.type); + rhs.type()=pointer_type(value_symbol.type); } if(rhs.type()!=lhs.type()) @@ -195,18 +187,6 @@ void goto_symext::symex_malloc( symex_assign_rec(state, code_assignt(lhs, rhs)); } -/*******************************************************************\ - -Function: goto_symext::symex_gcc_builtin_va_arg_next - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - irep_idt get_symbol(const exprt &src) { if(src.id()==ID_typecast) @@ -242,7 +222,7 @@ void goto_symext::symex_gcc_builtin_va_arg_next( exprt rhs=zero_initializer(lhs.type(), code.source_location(), ns); - if(id!=irep_idt()) + if(!id.empty()) { // strip last name off id to get function name std::size_t pos=id2string(id).rfind("::"); @@ -271,18 +251,6 @@ void goto_symext::symex_gcc_builtin_va_arg_next( symex_assign_rec(state, code_assignt(lhs, rhs)); } -/*******************************************************************\ - -Function: goto_symext::get_string_argument_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - irep_idt get_string_argument_rec(const exprt &src) { if(src.id()==ID_typecast) @@ -309,18 +277,6 @@ irep_idt get_string_argument_rec(const exprt &src) return ""; } -/*******************************************************************\ - -Function: goto_symext::get_string_argument - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - irep_idt get_string_argument(const exprt &src, const namespacet &ns) { exprt tmp=src; @@ -328,18 +284,6 @@ irep_idt get_string_argument(const exprt &src, const namespacet &ns) return get_string_argument_rec(tmp); } -/*******************************************************************\ - -Function: goto_symext::symex_printf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_printf( statet &state, const exprt &lhs, @@ -367,18 +311,6 @@ void goto_symext::symex_printf( state.source, "printf", format_string, args); } -/*******************************************************************\ - -Function: goto_symext::symex_input - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_input( statet &state, const codet &code) @@ -404,18 +336,6 @@ void goto_symext::symex_input( target.input(state.guard.as_expr(), state.source, input_id, args); } -/*******************************************************************\ - -Function: goto_symext::symex_output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_output( statet &state, const codet &code) @@ -441,18 +361,6 @@ void goto_symext::symex_output( target.output(state.guard.as_expr(), state.source, output_id, args); } -/*******************************************************************\ - -Function: goto_symext::symex_cpp_new - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_cpp_new( statet &state, const exprt &lhs, @@ -496,7 +404,7 @@ void goto_symext::symex_cpp_new( // make symbol expression - exprt rhs(ID_address_of, pointer_typet()); + exprt rhs(ID_address_of, code.type()); rhs.type().subtype()=code.type().subtype(); if(do_array) @@ -513,18 +421,6 @@ void goto_symext::symex_cpp_new( symex_assign_rec(state, code_assignt(lhs, rhs)); } -/*******************************************************************\ - -Function: goto_symext::symex_cpp_delete - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_cpp_delete( statet &state, const codet &code) @@ -532,18 +428,6 @@ void goto_symext::symex_cpp_delete( // bool do_array=code.get(ID_statement)==ID_cpp_delete_array; } -/*******************************************************************\ - -Function: goto_symext::symex_trace - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_trace( statet &state, const code_function_callt &code) @@ -583,18 +467,6 @@ void goto_symext::symex_trace( } } -/*******************************************************************\ - -Function: goto_symext::symex_fkt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_fkt( statet &state, const code_function_callt &code) @@ -618,18 +490,6 @@ void goto_symext::symex_fkt( #endif } -/*******************************************************************\ - -Function: goto_symext::symex_macro - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_macro( statet &state, const code_function_callt &code) diff --git a/src/goto-symex/symex_catch.cpp b/src/goto-symex/symex_catch.cpp index ffddd6314e8..c36deb71645 100644 --- a/src/goto-symex/symex_catch.cpp +++ b/src/goto-symex/symex_catch.cpp @@ -6,19 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "goto_symex.h" - -/*******************************************************************\ - -Function: goto_symext::symex_catch - - Inputs: +/// \file +/// Symbolic Execution - Outputs: - - Purpose: - -\*******************************************************************/ +#include "goto_symex.h" void goto_symext::symex_catch(statet &state) { diff --git a/src/goto-symex/symex_clean_expr.cpp b/src/goto-symex/symex_clean_expr.cpp index e3e650d7b99..a894403c819 100644 --- a/src/goto-symex/symex_clean_expr.cpp +++ b/src/goto-symex/symex_clean_expr.cpp @@ -6,26 +6,17 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symbolic Execution of ANSI-C + +#include "goto_symex.h" + #include #include #include #include -#include - -#include "goto_symex.h" - -/*******************************************************************\ - -Function: goto_symext::process_array_expr_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void goto_symext::process_array_expr_rec( exprt &expr, @@ -58,6 +49,14 @@ void goto_symext::process_array_expr_rec( expr.swap(tmp); process_array_expr_rec(expr, type); } + else if(expr.id()==ID_byte_extract_little_endian || + expr.id()==ID_byte_extract_big_endian) + { + // pick the root object + exprt tmp=to_byte_extract_expr(expr).op(); + expr.swap(tmp); + process_array_expr_rec(expr, type); + } else if(expr.id()==ID_symbol && expr.get_bool(ID_C_SSA_symbol) && to_ssa_expr(expr).get_original_expr().id()==ID_index) @@ -69,7 +68,10 @@ void goto_symext::process_array_expr_rec( } else Forall_operands(it, expr) - process_array_expr_rec(*it, it->type()); + { + typet t=it->type(); + process_array_expr_rec(*it, t); + } if(!base_type_eq(expr.type(), type, ns)) { @@ -82,18 +84,6 @@ void goto_symext::process_array_expr_rec( } } -/*******************************************************************\ - -Function: goto_symext::process_array_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::process_array_expr(exprt &expr) { // This may change the type of the expression! @@ -129,6 +119,14 @@ void goto_symext::process_array_expr(exprt &expr) expr.swap(tmp); process_array_expr(expr); } + else if(expr.id()==ID_byte_extract_little_endian || + expr.id()==ID_byte_extract_big_endian) + { + // pick the root object + exprt tmp=to_byte_extract_expr(expr).op(); + expr.swap(tmp); + process_array_expr(expr); + } else if(expr.id()==ID_symbol && expr.get_bool(ID_C_SSA_symbol) && to_ssa_expr(expr).get_original_expr().id()==ID_index) @@ -143,18 +141,6 @@ void goto_symext::process_array_expr(exprt &expr) process_array_expr(*it); } -/*******************************************************************\ - -Function: goto_symext::replace_array_equal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::replace_array_equal(exprt &expr) { if(expr.id()==ID_array_equal) @@ -180,18 +166,6 @@ void goto_symext::replace_array_equal(exprt &expr) replace_array_equal(*it); } -/*******************************************************************\ - -Function: goto_symext::clean_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::clean_expr( exprt &expr, statet &state, diff --git a/src/goto-symex/symex_dead.cpp b/src/goto-symex/symex_dead.cpp index ec9440bc5e8..eacf6d247a8 100644 --- a/src/goto-symex/symex_dead.cpp +++ b/src/goto-symex/symex_dead.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symbolic Execution + +#include "goto_symex.h" + #include #include @@ -13,20 +18,6 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "goto_symex.h" - -/*******************************************************************\ - -Function: goto_symext::symex_dead - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_dead(statet &state) { const goto_programt::instructiont &instruction=*state.source.pc; diff --git a/src/goto-symex/symex_decl.cpp b/src/goto-symex/symex_decl.cpp index b0b490b42b9..eda7144f99b 100644 --- a/src/goto-symex/symex_decl.cpp +++ b/src/goto-symex/symex_decl.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symbolic Execution + +#include "goto_symex.h" + #include #include @@ -15,20 +20,6 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "goto_symex.h" - -/*******************************************************************\ - -Function: goto_symext::symex_decl - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_decl(statet &state) { const goto_programt::instructiont &instruction=*state.source.pc; @@ -47,18 +38,6 @@ void goto_symext::symex_decl(statet &state) symex_decl(state, to_symbol_expr(code.op0())); } -/*******************************************************************\ - -Function: goto_symext::symex_decl - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_decl(statet &state, const symbol_exprt &expr) { // We increase the L2 renaming to make these non-deterministic. @@ -120,7 +99,9 @@ void goto_symext::symex_decl(statet &state, const symbol_exprt &expr) state.guard.as_expr(), ssa, state.source, - hidden?symex_targett::HIDDEN:symex_targett::STATE); + hidden? + symex_targett::assignment_typet::HIDDEN: + symex_targett::assignment_typet::STATE); assert(state.dirty); if((*state.dirty)(ssa.get_object_name()) && diff --git a/src/goto-symex/symex_dereference.cpp b/src/goto-symex/symex_dereference.cpp index 1ef9ac69962..f066ee1065f 100644 --- a/src/goto-symex/symex_dereference.cpp +++ b/src/goto-symex/symex_dereference.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symbolic Execution of ANSI-C + +#include "goto_symex.h" + #include #include #include @@ -15,23 +20,10 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include +#include -#include "goto_symex.h" #include "symex_dereference_state.h" -/*******************************************************************\ - -Function: goto_symext::dereference_rec_address_of - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::dereference_rec_address_of( exprt &expr, statet &state, @@ -72,18 +64,6 @@ void goto_symext::dereference_rec_address_of( } } -/*******************************************************************\ - -Function: goto_symext::is_index_member_symbol_if - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool goto_symext::is_index_member_symbol_if(const exprt &expr) { // Could be member, could be if, could be index. @@ -109,18 +89,7 @@ bool goto_symext::is_index_member_symbol_if(const exprt &expr) return false; } -/*******************************************************************\ - -Function: goto_symext::address_arithmetic - - Inputs: - - Outputs: - - Purpose: Evaluate an ID_address_of expression - -\*******************************************************************/ - +/// Evaluate an ID_address_of expression exprt goto_symext::address_arithmetic( const exprt &expr, statet &state, @@ -153,7 +122,7 @@ exprt goto_symext::address_arithmetic( } // do (expr.type() *)(((char *)op)+offset) - result=typecast_exprt(result, pointer_typet(char_type())); + result=typecast_exprt(result, pointer_type(char_type())); // there could be further dereferencing in the offset exprt offset=be.offset(); @@ -163,14 +132,14 @@ exprt goto_symext::address_arithmetic( // treat &array as &array[0] const typet &expr_type=ns.follow(expr.type()); - pointer_typet dest_type; + typet dest_type_subtype; if(expr_type.id()==ID_array && !keep_array) - dest_type.subtype()=expr_type.subtype(); + dest_type_subtype=expr_type.subtype(); else - dest_type.subtype()=expr_type; + dest_type_subtype=expr_type; - result=typecast_exprt(result, dest_type); + result=typecast_exprt(result, pointer_type(dest_type_subtype)); } else if(expr.id()==ID_index || expr.id()==ID_member) @@ -253,23 +222,11 @@ exprt goto_symext::address_arithmetic( const typet &expr_type=ns.follow(expr.type()); assert((expr_type.id()==ID_array && !keep_array) || - base_type_eq(pointer_typet(expr_type), result.type(), ns)); + base_type_eq(pointer_type(expr_type), result.type(), ns)); return result; } -/*******************************************************************\ - -Function: goto_symext::dereference_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::dereference_rec( exprt &expr, statet &state, @@ -297,13 +254,15 @@ void goto_symext::dereference_rec( symex_dereference_state, language_mode); - // std::cout << "**** " << from_expr(ns, "", tmp1) << std::endl; + // std::cout << "**** " << from_expr(ns, "", tmp1) << '\n'; exprt tmp2= dereference.dereference( tmp1, guard, - write?value_set_dereferencet::WRITE:value_set_dereferencet::READ); - // std::cout << "**** " << from_expr(ns, "", tmp2) << std::endl; + write? + value_set_dereferencet::modet::WRITE: + value_set_dereferencet::modet::READ); + // std::cout << "**** " << from_expr(ns, "", tmp2) << '\n'; expr.swap(tmp2); @@ -322,7 +281,7 @@ void goto_symext::dereference_rec( index_exprt index_expr=to_index_expr(expr); address_of_exprt address_of_expr(index_expr.array()); - address_of_expr.type()=pointer_typet(expr.type()); + address_of_expr.type()=pointer_type(expr.type()); dereference_exprt tmp; tmp.pointer()=plus_exprt(address_of_expr, index_expr.index()); @@ -359,7 +318,7 @@ void goto_symext::dereference_rec( to_address_of_expr(tc_op).object().type().id()==ID_array && base_type_eq( expr.type(), - pointer_typet(to_address_of_expr(tc_op).object().type().subtype()), + pointer_type(to_address_of_expr(tc_op).object().type().subtype()), ns)) { expr= @@ -382,18 +341,6 @@ void goto_symext::dereference_rec( } } -/*******************************************************************\ - -Function: goto_symext::dereference - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::dereference( exprt &expr, statet &state, diff --git a/src/goto-symex/symex_dereference_state.cpp b/src/goto-symex/symex_dereference_state.cpp index cd69913e6a2..9911ba51e7d 100644 --- a/src/goto-symex/symex_dereference_state.cpp +++ b/src/goto-symex/symex_dereference_state.cpp @@ -6,21 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Symbolic Execution of ANSI-C #include "symex_dereference_state.h" -/*******************************************************************\ - -Function: symex_dereference_statet::dereference_failure - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void symex_dereference_statet::dereference_failure( const std::string &property, @@ -29,18 +20,6 @@ void symex_dereference_statet::dereference_failure( { } -/*******************************************************************\ - -Function: symex_dereference_statet::has_failed_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool symex_dereference_statet::has_failed_symbol( const exprt &expr, const symbolt *&symbol) @@ -64,7 +43,7 @@ bool symex_dereference_statet::has_failed_symbol( !ns.lookup(failed_symbol, symbol)) { symbolt sym=*symbol; - symbolt *sym_ptr=0; + symbolt *sym_ptr=nullptr; symbol_exprt sym_expr=sym.symbol_expr(); state.rename(sym_expr, ns, goto_symex_statet::L1); sym.name=to_ssa_expr(sym_expr).get_identifier(); @@ -85,7 +64,7 @@ bool symex_dereference_statet::has_failed_symbol( !ns.lookup(failed_symbol, symbol)) { symbolt sym=*symbol; - symbolt *sym_ptr=0; + symbolt *sym_ptr=nullptr; symbol_exprt sym_expr=sym.symbol_expr(); state.rename(sym_expr, ns, goto_symex_statet::L1); sym.name=to_ssa_expr(sym_expr).get_identifier(); @@ -98,18 +77,6 @@ bool symex_dereference_statet::has_failed_symbol( return false; } -/*******************************************************************\ - -Function: symex_dereference_statet::get_value_set - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_dereference_statet::get_value_set( const exprt &expr, value_setst::valuest &value_set) @@ -123,7 +90,7 @@ void symex_dereference_statet::get_value_set( #endif #if 0 - std::cout << "E: " << from_expr(goto_symex.ns, "", expr) << std::endl; + std::cout << "E: " << from_expr(goto_symex.ns, "", expr) << '\n'; #endif #if 0 @@ -131,7 +98,7 @@ void symex_dereference_statet::get_value_set( for(value_setst::valuest::const_iterator it=value_set.begin(); it!=value_set.end(); it++) - std::cout << from_expr(goto_symex.ns, "", *it) << std::endl; + std::cout << from_expr(goto_symex.ns, "", *it) << '\n'; std::cout << "**************************\n"; #endif } diff --git a/src/goto-symex/symex_dereference_state.h b/src/goto-symex/symex_dereference_state.h index 0afaf8a696f..315afb00a70 100644 --- a/src/goto-symex/symex_dereference_state.h +++ b/src/goto-symex/symex_dereference_state.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symbolic Execution of ANSI-C + #ifndef CPROVER_GOTO_SYMEX_SYMEX_DEREFERENCE_STATE_H #define CPROVER_GOTO_SYMEX_SYMEX_DEREFERENCE_STATE_H @@ -13,18 +16,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "goto_symex.h" -/*******************************************************************\ - - Class: symex_dereference_statet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - class symex_dereference_statet: public dereference_callbackt { diff --git a/src/goto-symex/symex_function_call.cpp b/src/goto-symex/symex_function_call.cpp index 00636ae339b..06d519e4941 100644 --- a/src/goto-symex/symex_function_call.cpp +++ b/src/goto-symex/symex_function_call.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symbolic Execution of ANSI-C + +#include "goto_symex.h" + #include #include #include @@ -17,24 +22,10 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include +#include #include -#include "goto_symex.h" - -/*******************************************************************\ - -Function: goto_symext::get_unwind_recursion - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool goto_symext::get_unwind_recursion( const irep_idt &identifier, const unsigned thread_nr, @@ -43,18 +34,6 @@ bool goto_symext::get_unwind_recursion( return false; } -/*******************************************************************\ - -Function: goto_symext::parameter_assignments - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::parameter_assignments( const irep_idt function_identifier, const goto_functionst::goto_functiont &goto_function, @@ -83,7 +62,7 @@ void goto_symext::parameter_assignments( const irep_idt &identifier=parameter.get_identifier(); - if(identifier==irep_idt()) + if(identifier.empty()) throw "no identifier for function parameter"; const symbolt &symbol=ns.lookup(identifier); @@ -160,7 +139,7 @@ void goto_symext::parameter_assignments( { // These are va_arg arguments; their types may differ from call to call unsigned va_count=0; - const symbolt *va_sym=0; + const symbolt *va_sym=nullptr; while(!ns.lookup( id2string(function_identifier)+"::va_arg"+std::to_string(va_count), va_sym)) @@ -190,18 +169,6 @@ void goto_symext::parameter_assignments( } } -/*******************************************************************\ - -Function: goto_symext::symex_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_function_call( const goto_functionst &goto_functions, statet &state, @@ -219,18 +186,6 @@ void goto_symext::symex_function_call( throw "unexpected function for symex_function_call: "+function.id_string(); } -/*******************************************************************\ - -Function: goto_symext::symex_function_call_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_function_call_symbol( const goto_functionst &goto_functions, statet &state, @@ -259,18 +214,7 @@ void goto_symext::symex_function_call_symbol( symex_function_call_code(goto_functions, state, code); } -/*******************************************************************\ - -Function: goto_symext::symex_function_call_code - - Inputs: - - Outputs: - - Purpose: do function call by inlining - -\*******************************************************************/ - +/// do function call by inlining void goto_symext::symex_function_call_code( const goto_functionst &goto_functions, statet &state, @@ -310,7 +254,7 @@ void goto_symext::symex_function_call_code( state.guard.add(false_exprt()); } - state.source.pc++; + symex_transition(state); return; } @@ -332,7 +276,7 @@ void goto_symext::symex_function_call_code( symex_assign_rec(state, code); } - state.source.pc++; + symex_transition(state); return; } @@ -370,21 +314,10 @@ void goto_symext::symex_function_call_code( frame.loop_iterations[identifier].count++; state.source.is_set=true; - state.source.pc=goto_function.body.instructions.begin(); + symex_transition(state, goto_function.body.instructions.begin()); } -/*******************************************************************\ - -Function: goto_symext::pop_frame - - Inputs: - - Outputs: - - Purpose: pop one call frame - -\*******************************************************************/ - +/// pop one call frame void goto_symext::pop_frame(statet &state) { assert(!state.call_stack().empty()); @@ -393,7 +326,7 @@ void goto_symext::pop_frame(statet &state) statet::framet &frame=state.top(); // restore program counter - state.source.pc=frame.calling_location.pc; + symex_transition(state, frame.calling_location.pc); // restore L1 renaming state.level1.restore_from(frame.old_level1); @@ -424,18 +357,7 @@ void goto_symext::pop_frame(statet &state) state.pop_frame(); } -/*******************************************************************\ - -Function: goto_symext::symex_end_of_function - - Inputs: - - Outputs: - - Purpose: do function call by inlining - -\*******************************************************************/ - +/// do function call by inlining void goto_symext::symex_end_of_function(statet &state) { // first record the return @@ -446,20 +368,8 @@ void goto_symext::symex_end_of_function(statet &state) pop_frame(state); } -/*******************************************************************\ - -Function: goto_symext::locality - - Inputs: - - Outputs: - - Purpose: preserves locality of local variables of a given - function by applying L1 renaming to the local - identifiers - -\*******************************************************************/ - +/// preserves locality of local variables of a given function by applying L1 +/// renaming to the local identifiers void goto_symext::locality( const irep_idt function_identifier, statet &state, @@ -517,18 +427,6 @@ void goto_symext::locality( } } -/*******************************************************************\ - -Function: goto_symext::return_assignment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::return_assignment(statet &state) { statet::framet &frame=state.top(); diff --git a/src/goto-symex/symex_goto.cpp b/src/goto-symex/symex_goto.cpp index 8b36cfc26af..a86efc0815e 100644 --- a/src/goto-symex/symex_goto.cpp +++ b/src/goto-symex/symex_goto.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symbolic Execution + +#include "goto_symex.h" + #include #include @@ -13,20 +18,6 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "goto_symex.h" - -/*******************************************************************\ - -Function: goto_symext::symex_goto - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_goto(statet &state) { const goto_programt::instructiont &instruction=*state.source.pc; @@ -45,12 +36,8 @@ void goto_symext::symex_goto(statet &state) if(!state.guard.is_false()) target.location(state.guard.as_expr(), state.source); - // reset unwinding counter - if(instruction.is_backwards_goto()) - frame.loop_iterations[goto_programt::loop_id(state.source.pc)].count=0; - // next instruction - state.source.pc++; + symex_transition(state); return; // nothing to do } @@ -86,7 +73,7 @@ void goto_symext::symex_goto(statet &state) symex_assume(state, negated_cond); // next instruction - state.source.pc++; + symex_transition(state); return; } @@ -100,17 +87,14 @@ void goto_symext::symex_goto(statet &state) // no! loop_bound_exceeded(state, new_guard); - // reset unwinding - unwind=0; - // next instruction - state.source.pc++; + symex_transition(state); return; } if(new_guard.is_true()) { - state.source.pc=goto_target; + symex_transition(state, goto_target, true); return; // nothing else to do } } @@ -131,7 +115,7 @@ void goto_symext::symex_goto(statet &state) if(state_pc==goto_target) { - state.source.pc=goto_target; + symex_transition(state, goto_target); return; // nothing else to do } } @@ -149,7 +133,7 @@ void goto_symext::symex_goto(statet &state) goto_state_list.push_back(statet::goto_statet(state)); statet::goto_statet &new_state=goto_state_list.back(); - state.source.pc=state_pc; + symex_transition(state, state_pc, !forward); // adjust guards if(new_guard.is_true()) @@ -184,7 +168,7 @@ void goto_symext::symex_goto(statet &state) new_lhs, new_lhs, guard_symbol_expr, new_rhs, original_source, - symex_targett::GUARD); + symex_targett::assignment_typet::GUARD); guard_expr=guard_symbol_expr; guard_expr.make_not(); @@ -206,18 +190,6 @@ void goto_symext::symex_goto(statet &state) } } -/*******************************************************************\ - -Function: goto_symext::symex_step_goto - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_step_goto(statet &state, bool taken) { const goto_programt::instructiont &instruction=*state.source.pc; @@ -235,18 +207,6 @@ void goto_symext::symex_step_goto(statet &state, bool taken) target.assumption(state.guard.as_expr(), guard, state.source); } -/*******************************************************************\ - -Function: goto_symext::merge_gotos - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::merge_gotos(statet &state) { statet::framet &frame=state.top(); @@ -271,18 +231,6 @@ void goto_symext::merge_gotos(statet &state) frame.goto_state_map.erase(state_map_it); } -/*******************************************************************\ - -Function: goto_symext::merge_goto - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::merge_goto( const statet::goto_statet &goto_state, statet &state) @@ -303,18 +251,6 @@ void goto_symext::merge_goto( state.depth=std::min(state.depth, goto_state.depth); } -/*******************************************************************\ - -Function: goto_symext::merge_value_sets - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::merge_value_sets( const statet::goto_statet &src, statet &dest) @@ -328,18 +264,6 @@ void goto_symext::merge_value_sets( dest.value_set.make_union(src.value_set); } -/*******************************************************************\ - -Function: goto_symext::phi_function - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::phi_function( const statet::goto_statet &goto_state, statet &dest_state) @@ -350,6 +274,16 @@ void goto_symext::phi_function( goto_state.level2_get_variables(variables); dest_state.level2.get_variables(variables); + guardt diff_guard; + + if(!variables.empty()) + { + diff_guard=goto_state.guard; + + // this gets the diff between the guards + diff_guard-=dest_state.guard; + } + for(std::unordered_set::const_iterator it=variables.begin(); it!=variables.end(); @@ -417,12 +351,7 @@ void goto_symext::phi_function( rhs=dest_state_rhs; else { - guardt tmp_guard(goto_state.guard); - - // this gets the diff between the guards - tmp_guard-=dest_state.guard; - - rhs=if_exprt(tmp_guard.as_expr(), goto_state_rhs, dest_state_rhs); + rhs=if_exprt(diff_guard.as_expr(), goto_state_rhs, dest_state_rhs); do_simplify(rhs); } @@ -437,22 +366,10 @@ void goto_symext::phi_function( new_lhs, new_lhs, new_lhs.get_original_expr(), rhs, dest_state.source, - symex_targett::PHI); + symex_targett::assignment_typet::PHI); } } -/*******************************************************************\ - -Function: goto_symext::loop_bound_exceeded - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::loop_bound_exceeded( statet &state, const exprt &guard) @@ -492,18 +409,6 @@ void goto_symext::loop_bound_exceeded( } } -/*******************************************************************\ - -Function: goto_symext::get_unwind - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool goto_symext::get_unwind( const symex_targett::sourcet &source, unsigned unwind) diff --git a/src/goto-symex/symex_main.cpp b/src/goto-symex/symex_main.cpp index 2cb7ac09290..4fce789ad3a 100644 --- a/src/goto-symex/symex_main.cpp +++ b/src/goto-symex/symex_main.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symbolic Execution + +#include "goto_symex.h" + #include #include @@ -15,19 +20,29 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "goto_symex.h" - -/*******************************************************************\ - -Function: goto_symext::new_name - - Inputs: - - Outputs: - - Purpose: +void goto_symext::symex_transition( + statet &state, + goto_programt::const_targett to, + bool is_backwards_goto) +{ + if(!state.call_stack().empty()) + { + // initialize the loop counter of any loop we are newly entering + // upon this transition; we are entering a loop if + // 1. the transition from state.source.pc to "to" is not a backwards goto + // or + // 2. we are arriving from an outer loop + statet::framet &frame=state.top(); + const goto_programt::instructiont &instruction=*to; + for(const auto &i_e : instruction.incoming_edges) + if(i_e->is_goto() && i_e->is_backwards_goto() && + (!is_backwards_goto || + state.source.pc->location_number>i_e->location_number)) + frame.loop_iterations[goto_programt::loop_id(i_e)].count=0; + } -\*******************************************************************/ + state.source.pc=to; +} void goto_symext::new_name(symbolt &symbol) { @@ -35,18 +50,6 @@ void goto_symext::new_name(symbolt &symbol) new_symbol_table.add(symbol); } -/*******************************************************************\ - -Function: goto_symext::vcc - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::vcc( const exprt &vcc_expr, const std::string &msg, @@ -74,18 +77,6 @@ void goto_symext::vcc( target.assertion(state.guard.as_expr(), expr, msg, state.source); } -/*******************************************************************\ - -Function: goto_symext::symex_assume - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::symex_assume(statet &state, const exprt &cond) { exprt simplified_cond=cond; @@ -115,18 +106,6 @@ void goto_symext::symex_assume(statet &state, const exprt &cond) symex_atomic_end(state); } -/*******************************************************************\ - -Function: goto_symext::rewrite_quantifiers - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_symext::rewrite_quantifiers(exprt &expr, statet &state) { if(expr.id()==ID_forall) @@ -143,18 +122,7 @@ void goto_symext::rewrite_quantifiers(exprt &expr, statet &state) } } -/*******************************************************************\ - -Function: goto_symext::operator() - - Inputs: - - Outputs: - - Purpose: symex from given state - -\*******************************************************************/ - +/// symex from given state void goto_symext::operator()( statet &state, const goto_functionst &goto_functions, @@ -170,6 +138,8 @@ void goto_symext::operator()( state.symex_target=⌖ state.dirty=new dirtyt(goto_functions); + symex_transition(state, state.source.pc); + assert(state.top().end_of_function->is_end_function()); while(!state.call_stack().empty()) @@ -181,27 +151,17 @@ void goto_symext::operator()( state.source.thread_nr+1 #include @@ -14,21 +19,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include - -#include "goto_symex.h" - -/*******************************************************************\ - -Function: goto_symext::symex_other - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void goto_symext::symex_other( const goto_functionst &goto_functions, @@ -85,7 +76,8 @@ void goto_symext::symex_other( { // we ignore this for now } - else if(statement==ID_array_copy) + else if(statement==ID_array_copy || + statement==ID_array_replace) { assert(code.operands().size()==2); @@ -94,15 +86,29 @@ void goto_symext::symex_other( // we need to add dereferencing for both operands dereference_exprt d0, d1; d0.op0()=code.op0(); - d0.type()=code.op0().type().subtype(); + d0.type()=empty_typet(); d1.op0()=code.op1(); - d1.type()=code.op1().type().subtype(); + d1.type()=empty_typet(); clean_code.op0()=d0; clean_code.op1()=d1; clean_expr(clean_code.op0(), state, true); + exprt op0_offset=from_integer(0, index_type()); + if(clean_code.op0().id()==byte_extract_id() && + clean_code.op0().type().id()==ID_empty) + { + op0_offset=to_byte_extract_expr(clean_code.op0()).offset(); + clean_code.op0()=clean_code.op0().op0(); + } clean_expr(clean_code.op1(), state, false); + exprt op1_offset=from_integer(0, index_type()); + if(clean_code.op1().id()==byte_extract_id() && + clean_code.op1().type().id()==ID_empty) + { + op1_offset=to_byte_extract_expr(clean_code.op1()).offset(); + clean_code.op1()=clean_code.op1().op0(); + } process_array_expr(clean_code.op0()); clean_expr(clean_code.op0(), state, true); @@ -111,14 +117,46 @@ void goto_symext::symex_other( if(!base_type_eq(clean_code.op0().type(), - clean_code.op1().type(), ns)) + clean_code.op1().type(), ns) || + !op0_offset.is_zero() || !op1_offset.is_zero()) { byte_extract_exprt be(byte_extract_id()); - be.type()=clean_code.op0().type(); - be.op()=clean_code.op1(); - be.offset()=from_integer(0, index_type()); - clean_code.op1()=be; + if(statement==ID_array_copy) + { + be.op()=clean_code.op1(); + be.offset()=op1_offset; + be.type()=clean_code.op0().type(); + clean_code.op1()=be; + + if(!op0_offset.is_zero()) + { + byte_extract_exprt op0( + byte_extract_id(), + clean_code.op0(), + op0_offset, + clean_code.op0().type()); + clean_code.op0()=op0; + } + } + else + { + // ID_array_replace + be.op()=clean_code.op0(); + be.offset()=op0_offset; + be.type()=clean_code.op1().type(); + clean_code.op0()=be; + + if(!op1_offset.is_zero()) + { + byte_extract_exprt op1( + byte_extract_id(), + clean_code.op1(), + op1_offset, + clean_code.op1().type()); + clean_code.op1()=op1; + } + } } code_assignt assignment; @@ -135,11 +173,14 @@ void goto_symext::symex_other( // we need to add dereferencing for the first operand dereference_exprt d0; d0.op0()=code.op0(); - d0.type()=code.op0().type().subtype(); + d0.type()=empty_typet(); clean_code.op0()=d0; clean_expr(clean_code.op0(), state, true); + if(clean_code.op0().id()==byte_extract_id() && + clean_code.op0().type().id()==ID_empty) + clean_code.op0()=clean_code.op0().op0(); clean_expr(clean_code.op1(), state, false); process_array_expr(clean_code.op0()); diff --git a/src/goto-symex/symex_slice_class.h b/src/goto-symex/symex_slice_class.h index c669ded9ed2..413a0bdc472 100644 --- a/src/goto-symex/symex_slice_class.h +++ b/src/goto-symex/symex_slice_class.h @@ -6,20 +6,15 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Slicer for symex traces + #ifndef CPROVER_GOTO_SYMEX_SYMEX_SLICE_CLASS_H #define CPROVER_GOTO_SYMEX_SYMEX_SLICE_CLASS_H #include "symex_target_equation.h" #include "slice.h" -/*******************************************************************\ - - Class: symex_slicet - - Purpose: - -\*******************************************************************/ - class symex_slicet { public: diff --git a/src/goto-symex/symex_start_thread.cpp b/src/goto-symex/symex_start_thread.cpp index eb4687a1fb9..8ebed5216c1 100644 --- a/src/goto-symex/symex_start_thread.cpp +++ b/src/goto-symex/symex_start_thread.cpp @@ -6,21 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Symbolic Execution #include "goto_symex.h" -/*******************************************************************\ - -Function: goto_symext::symex_start_thread - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void goto_symext::symex_start_thread(statet &state) { @@ -76,7 +67,7 @@ void goto_symext::symex_start_thread(statet &state) // get L0 name for current thread lhs.set_level_0(t); - // setup L1 name + // set up L1 name if(!state.level1.current_names.insert( std::make_pair(lhs.get_l1_object_identifier(), std::make_pair(lhs, 0))).second) @@ -94,7 +85,12 @@ void goto_symext::symex_start_thread(statet &state) const bool record_events=state.record_events; state.record_events=false; symex_assign_symbol( - state, lhs, nil_exprt(), rhs, guard, symex_targett::HIDDEN); + state, + lhs, + nil_exprt(), + rhs, + guard, + symex_targett::assignment_typet::HIDDEN); state.record_events=record_events; } @@ -122,6 +118,11 @@ void goto_symext::symex_start_thread(statet &state) guardt guard; symex_assign_symbol( - state, lhs, nil_exprt(), rhs, guard, symex_targett::HIDDEN); + state, + lhs, + nil_exprt(), + rhs, + guard, + symex_targett::assignment_typet::HIDDEN); } } diff --git a/src/goto-symex/symex_target.cpp b/src/goto-symex/symex_target.cpp index 808ec3d2004..cc03c29eaad 100644 --- a/src/goto-symex/symex_target.cpp +++ b/src/goto-symex/symex_target.cpp @@ -6,19 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "symex_target.h" - -/*******************************************************************\ - -Function: operator < - - Inputs: +/// \file +/// Symbolic Execution - Outputs: - - Purpose: - -\*******************************************************************/ +#include "symex_target.h" bool operator<( const symex_targett::sourcet &a, diff --git a/src/goto-symex/symex_target.h b/src/goto-symex/symex_target.h index e3b94fc15b6..227599a29bf 100644 --- a/src/goto-symex/symex_target.h +++ b/src/goto-symex/symex_target.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Generate Equation using Symbolic Execution + #ifndef CPROVER_GOTO_SYMEX_SYMEX_TARGET_H #define CPROVER_GOTO_SYMEX_SYMEX_TARGET_H @@ -51,10 +54,15 @@ class symex_targett } }; - typedef enum + enum class assignment_typet { - STATE, HIDDEN, VISIBLE_ACTUAL_PARAMETER, HIDDEN_ACTUAL_PARAMETER, PHI, GUARD - } assignment_typet; + STATE, + HIDDEN, + VISIBLE_ACTUAL_PARAMETER, + HIDDEN_ACTUAL_PARAMETER, + PHI, + GUARD, + }; // read event virtual void shared_read( diff --git a/src/goto-symex/symex_target_equation.cpp b/src/goto-symex/symex_target_equation.cpp index 3cf9612e556..6627e198b71 100644 --- a/src/goto-symex/symex_target_equation.cpp +++ b/src/goto-symex/symex_target_equation.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symbolic Execution + +#include "symex_target_equation.h" + #include #include @@ -16,53 +21,17 @@ Author: Daniel Kroening, kroening@kroening.com #include #include "goto_symex_state.h" -#include "symex_target_equation.h" - -/*******************************************************************\ - -Function: symex_target_equationt::symex_target_equationt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ symex_target_equationt::symex_target_equationt( const namespacet &_ns):ns(_ns) { } -/*******************************************************************\ - -Function: symex_target_equationt::~symex_target_equationt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - symex_target_equationt::~symex_target_equationt() { } -/*******************************************************************\ - -Function: symex_target_equationt::shared_read - - Inputs: - - Outputs: - - Purpose: read from a shared variable - -\*******************************************************************/ - +/// read from a shared variable void symex_target_equationt::shared_read( const exprt &guard, const ssa_exprt &ssa_object, @@ -74,25 +43,14 @@ void symex_target_equationt::shared_read( SSA_step.guard=guard; SSA_step.ssa_lhs=ssa_object; - SSA_step.type=goto_trace_stept::SHARED_READ; + SSA_step.type=goto_trace_stept::typet::SHARED_READ; SSA_step.atomic_section_id=atomic_section_id; SSA_step.source=source; merge_ireps(SSA_step); } -/*******************************************************************\ - -Function: symex_target_equationt::shared_write - - Inputs: - - Outputs: - - Purpose: write to a sharedvariable - -\*******************************************************************/ - +/// write to a sharedvariable void symex_target_equationt::shared_write( const exprt &guard, const ssa_exprt &ssa_object, @@ -104,25 +62,14 @@ void symex_target_equationt::shared_write( SSA_step.guard=guard; SSA_step.ssa_lhs=ssa_object; - SSA_step.type=goto_trace_stept::SHARED_WRITE; + SSA_step.type=goto_trace_stept::typet::SHARED_WRITE; SSA_step.atomic_section_id=atomic_section_id; SSA_step.source=source; merge_ireps(SSA_step); } -/*******************************************************************\ - -Function: symex_target_equationt::spawn - - Inputs: - - Outputs: - - Purpose: spawn a new thread - -\*******************************************************************/ - +/// spawn a new thread void symex_target_equationt::spawn( const exprt &guard, const sourcet &source) @@ -130,24 +77,12 @@ void symex_target_equationt::spawn( SSA_steps.push_back(SSA_stept()); SSA_stept &SSA_step=SSA_steps.back(); SSA_step.guard=guard; - SSA_step.type=goto_trace_stept::SPAWN; + SSA_step.type=goto_trace_stept::typet::SPAWN; SSA_step.source=source; merge_ireps(SSA_step); } -/*******************************************************************\ - -Function: symex_target_equationt::memory_barrier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_target_equationt::memory_barrier( const exprt &guard, const sourcet &source) @@ -155,24 +90,13 @@ void symex_target_equationt::memory_barrier( SSA_steps.push_back(SSA_stept()); SSA_stept &SSA_step=SSA_steps.back(); SSA_step.guard=guard; - SSA_step.type=goto_trace_stept::MEMORY_BARRIER; + SSA_step.type=goto_trace_stept::typet::MEMORY_BARRIER; SSA_step.source=source; merge_ireps(SSA_step); } -/*******************************************************************\ - -Function: symex_target_equationt::atomic_begin - - Inputs: - - Outputs: - - Purpose: start an atomic section - -\*******************************************************************/ - +/// start an atomic section void symex_target_equationt::atomic_begin( const exprt &guard, unsigned atomic_section_id, @@ -181,25 +105,14 @@ void symex_target_equationt::atomic_begin( SSA_steps.push_back(SSA_stept()); SSA_stept &SSA_step=SSA_steps.back(); SSA_step.guard=guard; - SSA_step.type=goto_trace_stept::ATOMIC_BEGIN; + SSA_step.type=goto_trace_stept::typet::ATOMIC_BEGIN; SSA_step.atomic_section_id=atomic_section_id; SSA_step.source=source; merge_ireps(SSA_step); } -/*******************************************************************\ - -Function: symex_target_equationt::atomic_end - - Inputs: - - Outputs: - - Purpose: end an atomic section - -\*******************************************************************/ - +/// end an atomic section void symex_target_equationt::atomic_end( const exprt &guard, unsigned atomic_section_id, @@ -208,25 +121,14 @@ void symex_target_equationt::atomic_end( SSA_steps.push_back(SSA_stept()); SSA_stept &SSA_step=SSA_steps.back(); SSA_step.guard=guard; - SSA_step.type=goto_trace_stept::ATOMIC_END; + SSA_step.type=goto_trace_stept::typet::ATOMIC_END; SSA_step.atomic_section_id=atomic_section_id; SSA_step.source=source; merge_ireps(SSA_step); } -/*******************************************************************\ - -Function: symex_target_equationt::assignment - - Inputs: - - Outputs: - - Purpose: write to a variable - -\*******************************************************************/ - +/// write to a variable void symex_target_equationt::assignment( const exprt &guard, const ssa_exprt &ssa_lhs, @@ -249,26 +151,15 @@ void symex_target_equationt::assignment( SSA_step.assignment_type=assignment_type; SSA_step.cond_expr=equal_exprt(SSA_step.ssa_lhs, SSA_step.ssa_rhs); - SSA_step.type=goto_trace_stept::ASSIGNMENT; - SSA_step.hidden=(assignment_type!=STATE && - assignment_type!=VISIBLE_ACTUAL_PARAMETER); + SSA_step.type=goto_trace_stept::typet::ASSIGNMENT; + SSA_step.hidden=(assignment_type!=assignment_typet::STATE && + assignment_type!=assignment_typet::VISIBLE_ACTUAL_PARAMETER); SSA_step.source=source; merge_ireps(SSA_step); } -/*******************************************************************\ - -Function: symex_target_equationt::decl - - Inputs: - - Outputs: - - Purpose: declare a fresh variable - -\*******************************************************************/ - +/// declare a fresh variable void symex_target_equationt::decl( const exprt &guard, const ssa_exprt &ssa_lhs, @@ -284,9 +175,9 @@ void symex_target_equationt::decl( SSA_step.ssa_lhs=ssa_lhs; SSA_step.ssa_full_lhs=ssa_lhs; SSA_step.original_full_lhs=ssa_lhs.get_original_expr(); - SSA_step.type=goto_trace_stept::DECL; + SSA_step.type=goto_trace_stept::typet::DECL; SSA_step.source=source; - SSA_step.hidden=(assignment_type!=STATE); + SSA_step.hidden=(assignment_type!=assignment_typet::STATE); // the condition is trivially true, and only // there so we see the symbols @@ -295,18 +186,7 @@ void symex_target_equationt::decl( merge_ireps(SSA_step); } -/*******************************************************************\ - -Function: symex_target_equationt::dead - - Inputs: - - Outputs: - - Purpose: declare a fresh variable - -\*******************************************************************/ - +/// declare a fresh variable void symex_target_equationt::dead( const exprt &guard, const ssa_exprt &ssa_lhs, @@ -315,18 +195,7 @@ void symex_target_equationt::dead( // we currently don't record these } -/*******************************************************************\ - -Function: symex_target_equationt::location - - Inputs: - - Outputs: - - Purpose: just record a location - -\*******************************************************************/ - +/// just record a location void symex_target_equationt::location( const exprt &guard, const sourcet &source) @@ -335,24 +204,13 @@ void symex_target_equationt::location( SSA_stept &SSA_step=SSA_steps.back(); SSA_step.guard=guard; - SSA_step.type=goto_trace_stept::LOCATION; + SSA_step.type=goto_trace_stept::typet::LOCATION; SSA_step.source=source; merge_ireps(SSA_step); } -/*******************************************************************\ - -Function: symex_target_equationt::function_call - - Inputs: - - Outputs: - - Purpose: just record a location - -\*******************************************************************/ - +/// just record a location void symex_target_equationt::function_call( const exprt &guard, const irep_idt &identifier, @@ -362,25 +220,14 @@ void symex_target_equationt::function_call( SSA_stept &SSA_step=SSA_steps.back(); SSA_step.guard=guard; - SSA_step.type=goto_trace_stept::FUNCTION_CALL; + SSA_step.type=goto_trace_stept::typet::FUNCTION_CALL; SSA_step.source=source; SSA_step.identifier=identifier; merge_ireps(SSA_step); } -/*******************************************************************\ - -Function: symex_target_equationt::function_return - - Inputs: - - Outputs: - - Purpose: just record a location - -\*******************************************************************/ - +/// just record a location void symex_target_equationt::function_return( const exprt &guard, const irep_idt &identifier, @@ -390,25 +237,14 @@ void symex_target_equationt::function_return( SSA_stept &SSA_step=SSA_steps.back(); SSA_step.guard=guard; - SSA_step.type=goto_trace_stept::FUNCTION_RETURN; + SSA_step.type=goto_trace_stept::typet::FUNCTION_RETURN; SSA_step.source=source; SSA_step.identifier=identifier; merge_ireps(SSA_step); } -/*******************************************************************\ - -Function: symex_target_equationt::output - - Inputs: - - Outputs: - - Purpose: just record output - -\*******************************************************************/ - +/// just record output void symex_target_equationt::output( const exprt &guard, const sourcet &source, @@ -419,7 +255,7 @@ void symex_target_equationt::output( SSA_stept &SSA_step=SSA_steps.back(); SSA_step.guard=guard; - SSA_step.type=goto_trace_stept::OUTPUT; + SSA_step.type=goto_trace_stept::typet::OUTPUT; SSA_step.source=source; SSA_step.io_args=args; SSA_step.io_id=output_id; @@ -427,18 +263,7 @@ void symex_target_equationt::output( merge_ireps(SSA_step); } -/*******************************************************************\ - -Function: symex_target_equationt::output_fmt - - Inputs: - - Outputs: - - Purpose: just record formatted output - -\*******************************************************************/ - +/// just record formatted output void symex_target_equationt::output_fmt( const exprt &guard, const sourcet &source, @@ -450,7 +275,7 @@ void symex_target_equationt::output_fmt( SSA_stept &SSA_step=SSA_steps.back(); SSA_step.guard=guard; - SSA_step.type=goto_trace_stept::OUTPUT; + SSA_step.type=goto_trace_stept::typet::OUTPUT; SSA_step.source=source; SSA_step.io_args=args; SSA_step.io_id=output_id; @@ -460,18 +285,7 @@ void symex_target_equationt::output_fmt( merge_ireps(SSA_step); } -/*******************************************************************\ - -Function: symex_target_equationt::input - - Inputs: - - Outputs: - - Purpose: just record input - -\*******************************************************************/ - +/// just record input void symex_target_equationt::input( const exprt &guard, const sourcet &source, @@ -482,7 +296,7 @@ void symex_target_equationt::input( SSA_stept &SSA_step=SSA_steps.back(); SSA_step.guard=guard; - SSA_step.type=goto_trace_stept::INPUT; + SSA_step.type=goto_trace_stept::typet::INPUT; SSA_step.source=source; SSA_step.io_args=args; SSA_step.io_id=input_id; @@ -490,18 +304,7 @@ void symex_target_equationt::input( merge_ireps(SSA_step); } -/*******************************************************************\ - -Function: symex_target_equationt::assumption - - Inputs: - - Outputs: - - Purpose: record an assumption - -\*******************************************************************/ - +/// record an assumption void symex_target_equationt::assumption( const exprt &guard, const exprt &cond, @@ -512,24 +315,13 @@ void symex_target_equationt::assumption( SSA_step.guard=guard; SSA_step.cond_expr=cond; - SSA_step.type=goto_trace_stept::ASSUME; + SSA_step.type=goto_trace_stept::typet::ASSUME; SSA_step.source=source; merge_ireps(SSA_step); } -/*******************************************************************\ - -Function: symex_target_equationt::assertion - - Inputs: - - Outputs: - - Purpose: record an assertion - -\*******************************************************************/ - +/// record an assertion void symex_target_equationt::assertion( const exprt &guard, const exprt &cond, @@ -541,25 +333,14 @@ void symex_target_equationt::assertion( SSA_step.guard=guard; SSA_step.cond_expr=cond; - SSA_step.type=goto_trace_stept::ASSERT; + SSA_step.type=goto_trace_stept::typet::ASSERT; SSA_step.source=source; SSA_step.comment=msg; merge_ireps(SSA_step); } -/*******************************************************************\ - -Function: symex_target_equationt::goto_instruction - - Inputs: - - Outputs: - - Purpose: record a goto instruction - -\*******************************************************************/ - +/// record a goto instruction void symex_target_equationt::goto_instruction( const exprt &guard, const exprt &cond, @@ -570,24 +351,13 @@ void symex_target_equationt::goto_instruction( SSA_step.guard=guard; SSA_step.cond_expr=cond; - SSA_step.type=goto_trace_stept::GOTO; + SSA_step.type=goto_trace_stept::typet::GOTO; SSA_step.source=source; merge_ireps(SSA_step); } -/*******************************************************************\ - -Function: symex_target_equationt::constraint - - Inputs: - - Outputs: - - Purpose: record a constraint - -\*******************************************************************/ - +/// record a constraint void symex_target_equationt::constraint( const exprt &cond, const std::string &msg, @@ -599,25 +369,13 @@ void symex_target_equationt::constraint( SSA_step.guard=true_exprt(); SSA_step.cond_expr=cond; - SSA_step.type=goto_trace_stept::CONSTRAINT; + SSA_step.type=goto_trace_stept::typet::CONSTRAINT; SSA_step.source=source; SSA_step.comment=msg; merge_ireps(SSA_step); } -/*******************************************************************\ - -Function: symex_target_equationt::convert - - Inputs: converter - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_target_equationt::convert( prop_convt &prop_conv) { @@ -631,18 +389,9 @@ void symex_target_equationt::convert( convert_constraints(prop_conv); } -/*******************************************************************\ - -Function: symex_target_equationt::convert_assignments - - Inputs: decision procedure - - Outputs: - - - Purpose: converts assignments - -\*******************************************************************/ - +/// converts assignments +/// \par parameters: decision procedure +/// \return - void symex_target_equationt::convert_assignments( decision_proceduret &decision_procedure) const { @@ -653,18 +402,8 @@ void symex_target_equationt::convert_assignments( } } -/*******************************************************************\ - -Function: symex_target_equationt::convert_decls - - Inputs: converter - - Outputs: - - - Purpose: converts declarations - -\*******************************************************************/ - +/// converts declarations +/// \return - void symex_target_equationt::convert_decls( prop_convt &prop_conv) const { @@ -679,18 +418,8 @@ void symex_target_equationt::convert_decls( } } -/*******************************************************************\ - -Function: symex_target_equationt::convert_guards - - Inputs: converter - - Outputs: - - - Purpose: converts guards - -\*******************************************************************/ - +/// converts guards +/// \return - void symex_target_equationt::convert_guards( prop_convt &prop_conv) { @@ -703,18 +432,8 @@ void symex_target_equationt::convert_guards( } } -/*******************************************************************\ - -Function: symex_target_equationt::convert_assumptions - - Inputs: converter - - Outputs: - - - Purpose: converts assumptions - -\*******************************************************************/ - +/// converts assumptions +/// \return - void symex_target_equationt::convert_assumptions( prop_convt &prop_conv) { @@ -730,18 +449,8 @@ void symex_target_equationt::convert_assumptions( } } -/*******************************************************************\ - -Function: symex_target_equationt::convert_goto_instructions - - Inputs: converter - - Outputs: - - - Purpose: converts goto instructions - -\*******************************************************************/ - +/// converts goto instructions +/// \return - void symex_target_equationt::convert_goto_instructions( prop_convt &prop_conv) { @@ -757,18 +466,9 @@ void symex_target_equationt::convert_goto_instructions( } } -/*******************************************************************\ - -Function: symex_target_equationt::convert_constraints - - Inputs: decision procedure - - Outputs: - - - Purpose: converts constraints - -\*******************************************************************/ - +/// converts constraints +/// \par parameters: decision procedure +/// \return - void symex_target_equationt::convert_constraints( decision_proceduret &decision_procedure) const { @@ -784,18 +484,8 @@ void symex_target_equationt::convert_constraints( } } -/*******************************************************************\ - -Function: symex_target_equationt::convert_assertions - - Inputs: converter - - Outputs: - - - Purpose: converts assertions - -\*******************************************************************/ - +/// converts assertions +/// \return - void symex_target_equationt::convert_assertions( prop_convt &prop_conv) { @@ -861,18 +551,9 @@ void symex_target_equationt::convert_assertions( prop_conv.set_to_true(disjunction(disjuncts)); } -/*******************************************************************\ - -Function: symex_target_equationt::convert_io - - Inputs: decision procedure - - Outputs: - - - Purpose: converts I/O - -\*******************************************************************/ - +/// converts I/O +/// \par parameters: decision procedure +/// \return - void symex_target_equationt::convert_io( decision_proceduret &dec_proc) { @@ -903,18 +584,6 @@ void symex_target_equationt::convert_io( } -/*******************************************************************\ - -Function: symex_target_equationt::merge_ireps - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_target_equationt::merge_ireps(SSA_stept &SSA_step) { merge_irep(SSA_step.guard); @@ -932,18 +601,6 @@ void symex_target_equationt::merge_ireps(SSA_stept &SSA_step) // converted_io_args is merged in convert_io } -/*******************************************************************\ - -Function: symex_target_equationt::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_target_equationt::output(std::ostream &out) const { for(const auto &step : SSA_steps) @@ -953,18 +610,6 @@ void symex_target_equationt::output(std::ostream &out) const } } -/*******************************************************************\ - -Function: symex_target_equationt::SSA_stept::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_target_equationt::SSA_stept::output( const namespacet &ns, std::ostream &out) const @@ -974,97 +619,97 @@ void symex_target_equationt::SSA_stept::output( out << "Thread " << source.thread_nr; if(source.pc->source_location.is_not_nil()) - out << " " << source.pc->source_location << std::endl; + out << " " << source.pc->source_location << '\n'; else - out << std::endl; + out << '\n'; } switch(type) { - case goto_trace_stept::ASSERT: - out << "ASSERT " << from_expr(ns, "", cond_expr) << std::endl; break; - case goto_trace_stept::ASSUME: - out << "ASSUME " << from_expr(ns, "", cond_expr) << std::endl; break; - case goto_trace_stept::LOCATION: - out << "LOCATION" << std::endl; break; - case goto_trace_stept::INPUT: - out << "INPUT" << std::endl; break; - case goto_trace_stept::OUTPUT: - out << "OUTPUT" << std::endl; break; - - case goto_trace_stept::DECL: - out << "DECL" << std::endl; - out << from_expr(ns, "", ssa_lhs) << std::endl; + case goto_trace_stept::typet::ASSERT: + out << "ASSERT " << from_expr(ns, "", cond_expr) << '\n'; break; + case goto_trace_stept::typet::ASSUME: + out << "ASSUME " << from_expr(ns, "", cond_expr) << '\n'; break; + case goto_trace_stept::typet::LOCATION: + out << "LOCATION" << '\n'; break; + case goto_trace_stept::typet::INPUT: + out << "INPUT" << '\n'; break; + case goto_trace_stept::typet::OUTPUT: + out << "OUTPUT" << '\n'; break; + + case goto_trace_stept::typet::DECL: + out << "DECL" << '\n'; + out << from_expr(ns, "", ssa_lhs) << '\n'; break; - case goto_trace_stept::ASSIGNMENT: + case goto_trace_stept::typet::ASSIGNMENT: out << "ASSIGNMENT ("; switch(assignment_type) { - case HIDDEN: out << "HIDDEN"; break; - case STATE: out << "STATE"; break; - case VISIBLE_ACTUAL_PARAMETER: out << "VISIBLE_ACTUAL_PARAMETER"; break; - case HIDDEN_ACTUAL_PARAMETER: out << "HIDDEN_ACTUAL_PARAMETER"; break; - case PHI: out << "PHI"; break; - case GUARD: out << "GUARD"; break; + case assignment_typet::HIDDEN: + out << "HIDDEN"; + break; + case assignment_typet::STATE: + out << "STATE"; + break; + case assignment_typet::VISIBLE_ACTUAL_PARAMETER: + out << "VISIBLE_ACTUAL_PARAMETER"; + break; + case assignment_typet::HIDDEN_ACTUAL_PARAMETER: + out << "HIDDEN_ACTUAL_PARAMETER"; + break; + case assignment_typet::PHI: + out << "PHI"; + break; + case assignment_typet::GUARD: + out << "GUARD"; + break; default: { } } - out << ")" << std::endl; + out << ")\n"; break; - case goto_trace_stept::DEAD: - out << "DEAD" << std::endl; break; - case goto_trace_stept::FUNCTION_CALL: - out << "FUNCTION_CALL" << std::endl; break; - case goto_trace_stept::FUNCTION_RETURN: - out << "FUNCTION_RETURN" << std::endl; break; - case goto_trace_stept::CONSTRAINT: - out << "CONSTRAINT" << std::endl; break; - case goto_trace_stept::SHARED_READ: - out << "SHARED READ" << std::endl; break; - case goto_trace_stept::SHARED_WRITE: - out << "SHARED WRITE" << std::endl; break; - case goto_trace_stept::ATOMIC_BEGIN: - out << "ATOMIC_BEGIN" << std::endl; break; - case goto_trace_stept::ATOMIC_END: - out << "AUTOMIC_END" << std::endl; break; - case goto_trace_stept::SPAWN: - out << "SPAWN" << std::endl; break; - case goto_trace_stept::MEMORY_BARRIER: - out << "MEMORY_BARRIER" << std::endl; break; - case goto_trace_stept::GOTO: - out << "IF " << from_expr(ns, "", cond_expr) << " GOTO" << std::endl; break; + case goto_trace_stept::typet::DEAD: + out << "DEAD\n"; break; + case goto_trace_stept::typet::FUNCTION_CALL: + out << "FUNCTION_CALL\n"; break; + case goto_trace_stept::typet::FUNCTION_RETURN: + out << "FUNCTION_RETURN\n"; break; + case goto_trace_stept::typet::CONSTRAINT: + out << "CONSTRAINT\n"; break; + case goto_trace_stept::typet::SHARED_READ: + out << "SHARED READ\n"; break; + case goto_trace_stept::typet::SHARED_WRITE: + out << "SHARED WRITE\n"; break; + case goto_trace_stept::typet::ATOMIC_BEGIN: + out << "ATOMIC_BEGIN\n"; break; + case goto_trace_stept::typet::ATOMIC_END: + out << "AUTOMIC_END\n"; break; + case goto_trace_stept::typet::SPAWN: + out << "SPAWN\n"; break; + case goto_trace_stept::typet::MEMORY_BARRIER: + out << "MEMORY_BARRIER\n"; break; + case goto_trace_stept::typet::GOTO: + out << "IF " << from_expr(ns, "", cond_expr) << " GOTO\n"; break; default: assert(false); } if(is_assert() || is_assume() || is_assignment() || is_constraint()) - out << from_expr(ns, "", cond_expr) << std::endl; + out << from_expr(ns, "", cond_expr) << '\n'; if(is_assert() || is_constraint()) - out << comment << std::endl; + out << comment << '\n'; if(is_shared_read() || is_shared_write()) - out << from_expr(ns, "", ssa_lhs) << std::endl; + out << from_expr(ns, "", ssa_lhs) << '\n'; - out << "Guard: " << from_expr(ns, "", guard) << std::endl; + out << "Guard: " << from_expr(ns, "", guard) << '\n'; } -/*******************************************************************\ - -Function: operator << - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::ostream &operator<<( std::ostream &out, const symex_target_equationt &equation) @@ -1073,18 +718,6 @@ std::ostream &operator<<( return out; } -/*******************************************************************\ - -Function: operator << - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::ostream &operator<<( std::ostream &out, const symex_target_equationt::SSA_stept &step) diff --git a/src/goto-symex/symex_target_equation.h b/src/goto-symex/symex_target_equation.h index 855b44ee0bb..90073a84195 100644 --- a/src/goto-symex/symex_target_equation.h +++ b/src/goto-symex/symex_target_equation.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Generate Equation using Symbolic Execution + #ifndef CPROVER_GOTO_SYMEX_SYMEX_TARGET_EQUATION_H #define CPROVER_GOTO_SYMEX_SYMEX_TARGET_EQUATION_H @@ -170,34 +173,41 @@ class symex_target_equationt:public symex_targett sourcet source; goto_trace_stept::typet type; - bool is_assert() const { return type==goto_trace_stept::ASSERT; } - bool is_assume() const { return type==goto_trace_stept::ASSUME; } // NOLINTNEXTLINE(whitespace/line_length) - bool is_assignment() const { return type==goto_trace_stept::ASSIGNMENT; } - bool is_goto() const { return type==goto_trace_stept::GOTO; } + bool is_assert() const { return type==goto_trace_stept::typet::ASSERT; } + // NOLINTNEXTLINE(whitespace/line_length) + bool is_assume() const { return type==goto_trace_stept::typet::ASSUME; } + // NOLINTNEXTLINE(whitespace/line_length) + bool is_assignment() const { return type==goto_trace_stept::typet::ASSIGNMENT; } + // NOLINTNEXTLINE(whitespace/line_length) + bool is_goto() const { return type==goto_trace_stept::typet::GOTO; } + // NOLINTNEXTLINE(whitespace/line_length) + bool is_constraint() const { return type==goto_trace_stept::typet::CONSTRAINT; } + // NOLINTNEXTLINE(whitespace/line_length) + bool is_location() const { return type==goto_trace_stept::typet::LOCATION; } + // NOLINTNEXTLINE(whitespace/line_length) + bool is_output() const { return type==goto_trace_stept::typet::OUTPUT; } + // NOLINTNEXTLINE(whitespace/line_length) + bool is_decl() const { return type==goto_trace_stept::typet::DECL; } // NOLINTNEXTLINE(whitespace/line_length) - bool is_constraint() const { return type==goto_trace_stept::CONSTRAINT; } - bool is_location() const { return type==goto_trace_stept::LOCATION; } - bool is_output() const { return type==goto_trace_stept::OUTPUT; } - bool is_decl() const { return type==goto_trace_stept::DECL; } + bool is_function_call() const { return type==goto_trace_stept::typet::FUNCTION_CALL; } // NOLINTNEXTLINE(whitespace/line_length) - bool is_function_call() const { return type==goto_trace_stept::FUNCTION_CALL; } + bool is_function_return() const { return type==goto_trace_stept::typet::FUNCTION_RETURN; } // NOLINTNEXTLINE(whitespace/line_length) - bool is_function_return() const { return type==goto_trace_stept::FUNCTION_RETURN; } + bool is_shared_read() const { return type==goto_trace_stept::typet::SHARED_READ; } // NOLINTNEXTLINE(whitespace/line_length) - bool is_shared_read() const { return type==goto_trace_stept::SHARED_READ; } + bool is_shared_write() const { return type==goto_trace_stept::typet::SHARED_WRITE; } // NOLINTNEXTLINE(whitespace/line_length) - bool is_shared_write() const { return type==goto_trace_stept::SHARED_WRITE; } - bool is_spawn() const { return type==goto_trace_stept::SPAWN; } + bool is_spawn() const { return type==goto_trace_stept::typet::SPAWN; } // NOLINTNEXTLINE(whitespace/line_length) - bool is_memory_barrier() const { return type==goto_trace_stept::MEMORY_BARRIER; } + bool is_memory_barrier() const { return type==goto_trace_stept::typet::MEMORY_BARRIER; } // NOLINTNEXTLINE(whitespace/line_length) - bool is_atomic_begin() const { return type==goto_trace_stept::ATOMIC_BEGIN; } + bool is_atomic_begin() const { return type==goto_trace_stept::typet::ATOMIC_BEGIN; } // NOLINTNEXTLINE(whitespace/line_length) - bool is_atomic_end() const { return type==goto_trace_stept::ATOMIC_END; } + bool is_atomic_end() const { return type==goto_trace_stept::typet::ATOMIC_END; } // we may choose to hide - bool hidden; + bool hidden=false; exprt guard; literalt guard_literal; @@ -215,7 +225,7 @@ class symex_target_equationt:public symex_targett // for INPUT/OUTPUT irep_idt format_string, io_id; - bool formatted; + bool formatted=false; std::list io_args; std::list converted_io_args; @@ -223,13 +233,13 @@ class symex_target_equationt:public symex_targett irep_idt identifier; // for SHARED_READ/SHARED_WRITE and ATOMIC_BEGIN/ATOMIC_END - unsigned atomic_section_id; + unsigned atomic_section_id=0; // for slicing - bool ignore; + bool ignore=false; SSA_stept(): - type(goto_trace_stept::NONE), + type(goto_trace_stept::typet::NONE), hidden(false), guard(static_cast(get_nil_irep())), guard_literal(const_literal(false)), @@ -237,6 +247,7 @@ class symex_target_equationt:public symex_targett ssa_full_lhs(static_cast(get_nil_irep())), original_full_lhs(static_cast(get_nil_irep())), ssa_rhs(static_cast(get_nil_irep())), + assignment_type(assignment_typet::STATE), cond_expr(static_cast(get_nil_irep())), cond_literal(const_literal(false)), formatted(false), diff --git a/src/goto-symex/symex_throw.cpp b/src/goto-symex/symex_throw.cpp index e5091c566f2..a29ce901440 100644 --- a/src/goto-symex/symex_throw.cpp +++ b/src/goto-symex/symex_throw.cpp @@ -6,19 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "goto_symex.h" - -/*******************************************************************\ - -Function: goto_symext::symex_throw - - Inputs: +/// \file +/// Symbolic Execution - Outputs: - - Purpose: - -\*******************************************************************/ +#include "goto_symex.h" void goto_symext::symex_throw(statet &state) { diff --git a/src/java_bytecode/Makefile b/src/java_bytecode/Makefile index 1c0747903cf..677987cfc9b 100644 --- a/src/java_bytecode/Makefile +++ b/src/java_bytecode/Makefile @@ -1,4 +1,5 @@ SRC = bytecode_info.cpp \ + character_refine_preprocess.cpp \ ci_lazy_methods.cpp \ expr2java.cpp \ jar_file.cpp \ diff --git a/src/java_bytecode/bytecode_info.cpp b/src/java_bytecode/bytecode_info.cpp index 87b1942b54e..84e5040b9c8 100644 --- a/src/java_bytecode/bytecode_info.cpp +++ b/src/java_bytecode/bytecode_info.cpp @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + // http://docs.oracle.com/javase/specs/jvms/se8/html/ // http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings @@ -211,7 +212,7 @@ struct bytecode_infot const bytecode_info[]= { "return", 0xb1, ' ', 0, 0, ' ' }, // → [empty]; return void from method NOLINT(*) { "saload", 0x35, ' ', 2, 1, 's' }, // arrayref, index → value; load short from array NOLINT(*) { "sastore", 0x56, ' ', 3, 0, 's' }, // arrayref, index, value →; store short to array NOLINT(*) -{ "sipush", 0x11, 's', 0, 1, 's' }, // → value; push a short onto the stack NOLINT(*) +{ "sipush", 0x11, 's', 0, 1, 'i' }, // → value; push a short onto the stack as an integer value NOLINT(*) { "swap", 0x5f, ' ', 2, 2, ' ' }, // value2, value1 → value1, value2; swaps two top words on the stack (note that value1 and value2 must not be double or long) NOLINT(*) { "tableswitch", 0xaa, 'T', 1, 0, ' ' }, // index →; continue execution from an address in the table at offset index NOLINT(*) { "breakpoint", 0xca, ' ', 0, 0, ' ' }, // ; reserved for breakpoints in Java debuggers; should not appear in any class file NOLINT(*) diff --git a/src/java_bytecode/bytecode_info.h b/src/java_bytecode/bytecode_info.h index e378c0a18c8..08462ccf5cf 100644 --- a/src/java_bytecode/bytecode_info.h +++ b/src/java_bytecode/bytecode_info.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_JAVA_BYTECODE_BYTECODE_INFO_H #define CPROVER_JAVA_BYTECODE_BYTECODE_INFO_H diff --git a/src/java_bytecode/character_refine_preprocess.cpp b/src/java_bytecode/character_refine_preprocess.cpp new file mode 100644 index 00000000000..b7c1e1b281e --- /dev/null +++ b/src/java_bytecode/character_refine_preprocess.cpp @@ -0,0 +1,1542 @@ +/*******************************************************************\ + +Module: Preprocess a goto-programs so that calls to the java Character + library are replaced by simple expressions. + +Author: Romain Brenguier + +Date: March 2017 + +\*******************************************************************/ + +/// \file +/// Preprocess a goto-programs so that calls to the java Character library are +/// replaced by simple expressions. + +#include "character_refine_preprocess.h" + +#include +#include + +/// converts based on a function on expressions +/// \param expr_function: A reference to a function on expressions +/// \param target: A position in a goto program +codet character_refine_preprocesst::convert_char_function( + exprt (*expr_function)(const exprt &chr, const typet &type), + conversion_input &target) +{ + const code_function_callt &function_call=target; + assert(function_call.arguments().size()==1); + const exprt &arg=function_call.arguments()[0]; + const exprt &result=function_call.lhs(); + const typet &type=result.type(); + return code_assignt(result, expr_function(arg, type)); +} + +/// The returned expression is true when the first argument is in the interval +/// defined by the lower and upper bounds (included) +/// \param arg: Expression we want to bound +/// \param lower_bound: Integer lower bound +/// \param upper_bound: Integer upper bound +/// \return A Boolean expression +exprt character_refine_preprocesst::in_interval_expr( + const exprt &chr, + const mp_integer &lower_bound, + const mp_integer &upper_bound) +{ + return and_exprt( + binary_relation_exprt(chr, ID_ge, from_integer(lower_bound, chr.type())), + binary_relation_exprt(chr, ID_le, from_integer(upper_bound, chr.type()))); +} + +/// The returned expression is true when the given character is equal to one of +/// the element in the list +/// \param chr: An expression of type character +/// \param list: A list of integer representing unicode characters +/// \return A Boolean expression +exprt character_refine_preprocesst::in_list_expr( + const exprt &chr, const std::list &list) +{ + exprt::operandst ops; + for(const auto &i : list) + ops.push_back(equal_exprt(chr, from_integer(i, chr.type()))); + return disjunction(ops); +} + +/// Determines the number of char values needed to represent the specified +/// character (Unicode code point). +/// \param expr: An expression of type character +/// \param type: A type for the output +/// \return A integer expression of the given type +exprt character_refine_preprocesst::expr_of_char_count( + const exprt &chr, const typet &type) +{ + exprt u010000=from_integer(0x010000, type); + binary_relation_exprt small(chr, ID_lt, u010000); + return if_exprt(small, from_integer(1, type), from_integer(2, type)); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.charCount:(I)I +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_char_count(conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_char_count, target); +} + +/// Casts the given expression to the given type +/// \return An expression of the given type +exprt character_refine_preprocesst::expr_of_char_value( + const exprt &chr, const typet &type) +{ + return typecast_exprt(chr, type); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.charValue:()C +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_char_value(conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_char_value, target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.compare:(CC)I +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_compare(conversion_input &target) +{ + const code_function_callt &function_call=target; + assert(function_call.arguments().size()==2); + const exprt &char1=function_call.arguments()[0]; + const exprt &char2=function_call.arguments()[1]; + const exprt &result=function_call.lhs(); + const typet &type=result.type(); + binary_relation_exprt smaller(char1, ID_lt, char2); + binary_relation_exprt greater(char1, ID_gt, char2); + if_exprt expr( + smaller, + from_integer(-1, type), + if_exprt(greater, from_integer(1, type), from_integer(0, type))); + + return code_assignt(result, expr); +} + + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.digit:(CI)I +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_digit_char(conversion_input &target) +{ + const code_function_callt &function_call=target; + assert(function_call.arguments().size()==2); + const exprt &arg=function_call.arguments()[0]; + const exprt &radix=function_call.arguments()[1]; + const exprt &result=function_call.lhs(); + const typet &type=result.type(); + + // TODO: If the radix is not in the range MIN_RADIX <= radix <= MAX_RADIX or + // if the value of ch is not a valid digit in the specified radix, + // -1 is returned. + + // Case 1: The method isDigit is true of the character and the Unicode + // decimal digit value of the character (or its single-character + // decomposition) is less than the specified radix. + exprt invalid=from_integer(-1, arg.type()); + exprt c0=from_integer('0', arg.type()); + exprt latin_digit=in_interval_expr(arg, '0', '9'); + minus_exprt value1(arg, c0); + // TODO: this is only valid for latin digits + if_exprt case1( + binary_relation_exprt(value1, ID_lt, radix), value1, invalid); + + // Case 2: The character is one of the uppercase Latin letters 'A' + // through 'Z' and its code is less than radix + 'A' - 10, + // then ch - 'A' + 10 is returned. + exprt cA=from_integer('A', arg.type()); + exprt i10=from_integer(10, arg.type()); + exprt upper_case=in_interval_expr(arg, 'A', 'Z'); + plus_exprt value2(minus_exprt(arg, cA), i10); + if_exprt case2( + binary_relation_exprt(value2, ID_lt, radix), value2, invalid); + + // The character is one of the lowercase Latin letters 'a' through 'z' and + // its code is less than radix + 'a' - 10, then ch - 'a' + 10 is returned. + exprt ca=from_integer('a', arg.type()); + exprt lower_case=in_interval_expr(arg, 'a', 'z'); + plus_exprt value3(minus_exprt(arg, ca), i10); + if_exprt case3( + binary_relation_exprt(value3, ID_lt, radix), value3, invalid); + + + // The character is one of the fullwidth uppercase Latin letters A ('\uFF21') + // through Z ('\uFF3A') and its code is less than radix + '\uFF21' - 10. + // In this case, ch - '\uFF21' + 10 is returned. + exprt uFF21=from_integer(0xFF21, arg.type()); + exprt fullwidth_upper_case=in_interval_expr(arg, 0xFF21, 0xFF3A); + plus_exprt value4(minus_exprt(arg, uFF21), i10); + if_exprt case4( + binary_relation_exprt(value4, ID_lt, radix), value4, invalid); + + // The character is one of the fullwidth lowercase Latin letters a ('\uFF41') + // through z ('\uFF5A') and its code is less than radix + '\uFF41' - 10. + // In this case, ch - '\uFF41' + 10 is returned. + exprt uFF41=from_integer(0xFF41, arg.type()); + plus_exprt value5(minus_exprt(arg, uFF41), i10); + if_exprt case5( + binary_relation_exprt(value5, ID_lt, radix), value5, invalid); + + if_exprt fullwidth_cases(fullwidth_upper_case, case4, case5); + if_exprt expr( + latin_digit, + case1, + if_exprt(upper_case, case2, if_exprt(lower_case, case3, fullwidth_cases))); + typecast_exprt tc_expr(expr, type); + + return code_assignt(result, tc_expr); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.digit:(II)I +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_digit_int(conversion_input &target) +{ + return convert_digit_char(target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.forDigit:(II)I +/// +/// TODO: For now the radix argument is ignored +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_for_digit(conversion_input &target) +{ + const code_function_callt &function_call=target; + assert(function_call.arguments().size()==2); + const exprt &digit=function_call.arguments()[0]; + const exprt &result=function_call.lhs(); + const typet &type=result.type(); + + exprt d10=from_integer(10, type); + binary_relation_exprt small(digit, ID_le, d10); + plus_exprt value1(digit, from_integer('0', type)); + minus_exprt value2(plus_exprt(digit, from_integer('a', digit.type())), d10); + return code_assignt(result, if_exprt(small, value1, value2)); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.getDirectionality:(C)I +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_get_directionality_char( + conversion_input &target) +{ + // TODO: This is unimplemented for now as it requires analyzing + // the UnicodeData file to find characters directionality. + return target; +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.getDirectionality:(I)I +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_get_directionality_int( + conversion_input &target) +{ + return convert_get_directionality_char(target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.getNumericValue:(C)I +/// +/// TODO: For now this is only for ASCII characters +codet character_refine_preprocesst::convert_get_numeric_value_char( + conversion_input &target) +{ + return convert_digit_char(target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.getNumericValue:(C)I +/// +/// TODO: For now this is only for ASCII characters +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_get_numeric_value_int( + conversion_input &target) +{ + return convert_digit_int(target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.getType:(C)I +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_get_type_char( + conversion_input &target) +{ + // TODO: This is unimplemented for now as it requires analyzing + // the UnicodeData file to categorize characters. + return target; +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.getType:(I)I +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_get_type_int( + conversion_input &target) +{ + return convert_get_type_char(target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.hashCode:()I +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_hash_code(conversion_input &target) +{ + return convert_char_value(target); +} + +/// Returns the leading surrogate (a high surrogate code unit) of the surrogate +/// pair representing the specified supplementary character (Unicode code point) +/// in the UTF-16 encoding. +/// \param expr: An expression of type character +/// \param type: A type for the output +/// \return An expression of the given type +exprt character_refine_preprocesst::expr_of_high_surrogate( + const exprt &chr, const typet &type) +{ + exprt u10000=from_integer(0x010000, type); + exprt uD800=from_integer(0xD800, type); + exprt u400=from_integer(0x0400, type); + + plus_exprt high_surrogate(uD800, div_exprt(minus_exprt(chr, u10000), u400)); + return high_surrogate; +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.highSurrogate:(C)Z +codet character_refine_preprocesst::convert_high_surrogate( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_high_surrogate, target); +} + +/// Determines if the specified character is an ASCII lowercase character. +/// \param chr: An expression of type character +/// \param type: A type for the output +/// \return A Boolean expression +exprt character_refine_preprocesst::expr_of_is_ascii_lower_case( + const exprt &chr, const typet &type) +{ + return in_interval_expr(chr, 'a', 'z'); +} + +/// Determines if the specified character is an ASCII uppercase character. +/// \param expr: An expression of type character +/// \param type: A type for the output +/// \return A Boolean expression +exprt character_refine_preprocesst::expr_of_is_ascii_upper_case( + const exprt &chr, const typet &type) +{ + return in_interval_expr(chr, 'A', 'Z'); +} + +/// Determines if the specified character is a letter. +/// +/// TODO: for now this is only for ASCII characters, the +/// following unicode categories are not yet considered: +/// TITLECASE_LETTER MODIFIER_LETTER OTHER_LETTER LETTER_NUMBER +/// \param expr: An expression of type character +/// \param type: A type for the output +/// \return An expression of the given type +exprt character_refine_preprocesst::expr_of_is_letter( + const exprt &chr, const typet &type) +{ + return or_exprt( + expr_of_is_ascii_upper_case(chr, type), + expr_of_is_ascii_lower_case(chr, type)); +} + +/// Determines if the specified character (Unicode code point) is alphabetic. +/// +/// TODO: for now this is only for ASCII characters, the +/// following unicode categorise are not yet considered: +/// TITLECASE_LETTER MODIFIER_LETTER OTHER_LETTER LETTER_NUMBER +/// and contributory property Other_Alphabetic as defined by the +/// Unicode Standard. +/// \param expr: An expression of type character +/// \param type: A type for the output +/// \return An expression of the given type +exprt character_refine_preprocesst::expr_of_is_alphabetic( + const exprt &chr, const typet &type) +{ + return expr_of_is_letter(chr, type); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isAlphabetic:(I)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_alphabetic( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_is_alphabetic, target); +} + +/// Determines whether the specified character (Unicode code point) is in the +/// Basic Multilingual Plane (BMP). Such code points can be represented using a +/// single char. +/// \param expr: An expression of type character +/// \param type: A type for the output +/// \return A Boolean expression +exprt character_refine_preprocesst::expr_of_is_bmp_code_point( + const exprt &chr, const typet &type) +{ + binary_relation_exprt is_bmp(chr, ID_le, from_integer(0xFFFF, chr.type())); + return is_bmp; +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isBmpCodePoint:(I)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_bmp_code_point( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_is_bmp_code_point, target); +} + +/// Determines if a character is defined in Unicode. +/// \param expr: An expression of type character +/// \param type: A type for the output +/// \return An expression of the given type +exprt character_refine_preprocesst::expr_of_is_defined( + const exprt &chr, const typet &type) +{ + // The following intervals are undefined in unicode, according to + // the Unicode Character Database: http://www.unicode.org/Public/UCD/latest/ + exprt::operandst intervals; + intervals.push_back(in_interval_expr(chr, 0x0750, 0x077F)); + intervals.push_back(in_interval_expr(chr, 0x07C0, 0x08FF)); + intervals.push_back(in_interval_expr(chr, 0x1380, 0x139F)); + intervals.push_back(in_interval_expr(chr, 0x18B0, 0x18FF)); + intervals.push_back(in_interval_expr(chr, 0x1980, 0x19DF)); + intervals.push_back(in_interval_expr(chr, 0x1A00, 0x1CFF)); + intervals.push_back(in_interval_expr(chr, 0x1D80, 0x1DFF)); + intervals.push_back(in_interval_expr(chr, 0x2C00, 0x2E7F)); + intervals.push_back(in_interval_expr(chr, 0x2FE0, 0x2FEF)); + intervals.push_back(in_interval_expr(chr, 0x31C0, 0x31EF)); + intervals.push_back(in_interval_expr(chr, 0x9FB0, 0x9FFF)); + intervals.push_back(in_interval_expr(chr, 0xA4D0, 0xABFF)); + intervals.push_back(in_interval_expr(chr, 0xD7B0, 0xD7FF)); + intervals.push_back(in_interval_expr(chr, 0xFE10, 0xFE1F)); + intervals.push_back(in_interval_expr(chr, 0x10140, 0x102FF)); + intervals.push_back(in_interval_expr(chr, 0x104B0, 0x107FF)); + intervals.push_back(in_interval_expr(chr, 0x10840, 0x1CFFF)); + intervals.push_back(in_interval_expr(chr, 0x1D200, 0x1D2FF)); + intervals.push_back(in_interval_expr(chr, 0x1D360, 0x1D3FF)); + intervals.push_back( + binary_relation_exprt(chr, ID_ge, from_integer(0x1D800, chr.type()))); + + return not_exprt(disjunction(intervals)); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isDefined:(C)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_defined_char( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_is_defined, target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isDefined:(I)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_defined_int( + conversion_input &target) +{ + return convert_is_defined_char(target); +} + +/// Determines if the specified character is a digit. A character is a digit if +/// its general category type, provided by Character.getType(ch), is +/// DECIMAL_DIGIT_NUMBER. +/// +/// TODO: for now we only support these ranges of digits: +/// '\u0030' through '\u0039', ISO-LATIN-1 digits ('0' through '9') +/// '\u0660' through '\u0669', Arabic-Indic digits +/// '\u06F0' through '\u06F9', Extended Arabic-Indic digits +/// '\u0966' through '\u096F', Devanagari digits +/// '\uFF10' through '\uFF19', Fullwidth digits +/// Many other character ranges contain digits as well. +/// \param chr: An expression of type character +/// \param type: A type for the output +/// \return An expression of the given type +exprt character_refine_preprocesst::expr_of_is_digit( + const exprt &chr, const typet &type) +{ + exprt latin_digit=in_interval_expr(chr, '0', '9'); + exprt arabic_indic_digit=in_interval_expr(chr, 0x660, 0x669); + exprt extended_digit=in_interval_expr(chr, 0x6F0, 0x6F9); + exprt devanagari_digit=in_interval_expr(chr, 0x966, 0x96F); + exprt fullwidth_digit=in_interval_expr(chr, 0xFF10, 0xFF19); + or_exprt digit( + or_exprt(latin_digit, or_exprt(arabic_indic_digit, extended_digit)), + or_exprt(devanagari_digit, fullwidth_digit)); + return digit; +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isDigit:(C)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_digit_char( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_is_digit, target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.digit:(I)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_digit_int( + conversion_input &target) +{ + return convert_is_digit_char(target); +} + +/// Determines if the given char value is a Unicode high-surrogate code unit +/// (also known as leading-surrogate code unit). +/// \param expr: An expression of type character +/// \param type: A type for the output +/// \return A Boolean expression +exprt character_refine_preprocesst::expr_of_is_high_surrogate( + const exprt &chr, const typet &type) +{ + return in_interval_expr(chr, 0xD800, 0xDBFF); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isHighSurrogate:(C)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_high_surrogate( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_is_high_surrogate, target); +} + +/// Determines if the character is one of ignorable in a Java identifier, that +/// is, it is in one of these ranges: '\u0000' through '\u0008' '\u000E' through +/// '\u001B' '\u007F' through '\u009F' +/// +/// TODO: For now, we ignore the FORMAT general category value +/// \param expr: An expression of type character +/// \param type: A type for the output +/// \return A Boolean expression +exprt character_refine_preprocesst::expr_of_is_identifier_ignorable( + const exprt &chr, const typet &type) +{ + or_exprt ignorable( + in_interval_expr(chr, 0x0000, 0x0008), + or_exprt( + in_interval_expr(chr, 0x000E, 0x001B), + in_interval_expr(chr, 0x007F, 0x009F))); + return ignorable; +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isIdentifierIgnorable:(C)Z +/// +/// TODO: For now, we ignore the FORMAT general category value +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_identifier_ignorable_char( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_is_identifier_ignorable, target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isIdentifierIgnorable:(I)Z +/// +/// TODO: For now, we ignore the FORMAT general category value +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_identifier_ignorable_int( + conversion_input &target) +{ + return convert_is_identifier_ignorable_char(target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isIdeographic:(C)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_ideographic( + conversion_input &target) +{ + const code_function_callt &function_call=target; + assert(function_call.arguments().size()==1); + const exprt &arg=function_call.arguments()[0]; + const exprt &result=function_call.lhs(); + exprt is_ideograph=in_interval_expr(arg, 0x4E00, 0x9FFF); + return code_assignt(result, is_ideograph); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isISOControl:(C)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_ISO_control_char( + conversion_input &target) +{ + const code_function_callt &function_call=target; + assert(function_call.arguments().size()==1); + const exprt &arg=function_call.arguments()[0]; + const exprt &result=function_call.lhs(); + or_exprt iso( + in_interval_expr(arg, 0x00, 0x1F), in_interval_expr(arg, 0x7F, 0x9F)); + return code_assignt(result, iso); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isISOControl:(I)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_ISO_control_int( + conversion_input &target) +{ + return convert_is_ISO_control_char(target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isJavaIdentifierPart:(C)Z +/// +/// TODO: For now we do not allow currency symbol, connecting punctuation, +/// combining mark, non-spacing mark +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_java_identifier_part_char( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_is_unicode_identifier_part, target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method isJavaIdentifierPart:(I)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_java_identifier_part_int( + conversion_input &target) +{ + return convert_is_unicode_identifier_part_char(target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method isJavaIdentifierStart:(C)Z +/// +/// TODO: For now we only allow letters and letter numbers. +/// The java specification for this function is not precise on the +/// other characters. +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_java_identifier_start_char( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_is_unicode_identifier_start, target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method isJavaIdentifierStart:(I)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_java_identifier_start_int( + conversion_input &target) +{ + return convert_is_java_identifier_start_char(target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isJavaLetter:(C)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_java_letter( + conversion_input &target) +{ + return convert_is_java_identifier_start_char(target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method isJavaLetterOrDigit:(C)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_java_letter_or_digit( + conversion_input &target) +{ + return convert_is_java_identifier_part_char(target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isLetter:(C)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_letter_char( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_is_letter, target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isLetter:(I)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_letter_int( + conversion_input &target) +{ + return convert_is_letter_char(target); +} + +/// Determines if the specified character is a letter or digit. +/// \param chr: An expression of type character +/// \param type: A type for the output +/// \return An expression of the given type +exprt character_refine_preprocesst::expr_of_is_letter_or_digit( + const exprt &chr, const typet &type) +{ + return or_exprt(expr_of_is_letter(chr, type), expr_of_is_digit(chr, type)); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isLetterOrDigit:(C)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_letter_or_digit_char( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_is_digit, target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isLetterOrDigit:(I)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_letter_or_digit_int( + conversion_input &target) +{ + return convert_is_letter_or_digit_char(target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isLowerCase:(C)Z +/// +/// TODO: For now we only consider ASCII characters +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_lower_case_char( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_is_ascii_lower_case, target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isLowerCase:(I)Z +/// +/// TODO: For now we only consider ASCII characters +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_lower_case_int( + conversion_input &target) +{ + return convert_is_lower_case_char(target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isLowSurrogate:(I)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_low_surrogate( + conversion_input &target) +{ + const code_function_callt &function_call=target; + assert(function_call.arguments().size()==1); + const exprt &arg=function_call.arguments()[0]; + const exprt &result=function_call.lhs(); + exprt is_low_surrogate=in_interval_expr(arg, 0xDC00, 0xDFFF); + return code_assignt(result, is_low_surrogate); +} + +/// Determines whether the character is mirrored according to the Unicode +/// specification. +/// +/// TODO: For now only ASCII characters are considered +/// \param expr: An expression of type character +/// \param type: A type for the output +/// \return An expression of the given type +exprt character_refine_preprocesst::expr_of_is_mirrored( + const exprt &chr, const typet &type) +{ + return in_list_expr(chr, {0x28, 0x29, 0x3C, 0x3E, 0x5B, 0x5D, 0x7B, 0x7D}); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isMirrored:(C)Z +/// +/// TODO: For now only ASCII characters are considered +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_mirrored_char( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_is_mirrored, target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isMirrored:(I)Z +/// +/// TODO: For now only ASCII characters are considered +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_mirrored_int( + conversion_input &target) +{ + return convert_is_mirrored_char(target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isSpace:(C)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_space(conversion_input &target) +{ + return convert_is_whitespace_char(target); +} + +/// Determines if the specified character is white space according to Unicode +/// (SPACE_SEPARATOR, LINE_SEPARATOR, or PARAGRAPH_SEPARATOR) +/// \param expr: An expression of type character +/// \param type: A type for the output +/// \return A Boolean expression +exprt character_refine_preprocesst::expr_of_is_space_char( + const exprt &chr, const typet &type) +{ + std::list space_characters= + {0x20, 0x00A0, 0x1680, 0x202F, 0x205F, 0x3000, 0x2028, 0x2029}; + exprt condition0=in_list_expr(chr, space_characters); + exprt condition1=in_interval_expr(chr, 0x2000, 0x200A); + return or_exprt(condition0, condition1); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isSpaceChar:(C)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_space_char( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_is_space_char, target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isSpaceChar:(I)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_space_char_int( + conversion_input &target) +{ + return convert_is_space_char(target); +} + +/// Determines whether the specified character (Unicode code point) is in the +/// supplementary character range. +/// \param expr: An expression of type character +/// \param type: A type for the output +/// \return A Boolean expression +exprt character_refine_preprocesst::expr_of_is_supplementary_code_point( + const exprt &chr, const typet &type) +{ + return binary_relation_exprt(chr, ID_gt, from_integer(0xFFFF, chr.type())); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isSupplementaryCodePoint:(I)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_supplementary_code_point( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_is_supplementary_code_point, target); +} + +/// Determines if the given char value is a Unicode surrogate code unit. +/// \param expr: An expression of type character +/// \param type: A type for the output +/// \return A Boolean expression +exprt character_refine_preprocesst::expr_of_is_surrogate( + const exprt &chr, const typet &type) +{ + return in_interval_expr(chr, 0xD800, 0xDFFF); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isSurrogate:(C)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_surrogate( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_is_surrogate, target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isSurrogatePair:(CC)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_surrogate_pair( + conversion_input &target) +{ + const code_function_callt &function_call=target; + assert(function_call.arguments().size()==2); + const exprt &arg0=function_call.arguments()[0]; + const exprt &arg1=function_call.arguments()[1]; + const exprt &result=function_call.lhs(); + exprt is_low_surrogate=in_interval_expr(arg1, 0xDC00, 0xDFFF); + exprt is_high_surrogate=in_interval_expr(arg0, 0xD800, 0xDBFF); + return code_assignt(result, and_exprt(is_high_surrogate, is_low_surrogate)); +} + +/// Determines if the specified character is a titlecase character. +/// \param expr: An expression of type character +/// \param type: A type for the output +/// \return A Boolean expression +exprt character_refine_preprocesst::expr_of_is_title_case( + const exprt &chr, const typet &type) +{ + std::listtitle_case_chars= + {0x01C5, 0x01C8, 0x01CB, 0x01F2, 0x1FBC, 0x1FCC, 0x1FFC}; + exprt::operandst conditions; + conditions.push_back(in_list_expr(chr, title_case_chars)); + conditions.push_back(in_interval_expr(chr, 0x1F88, 0x1F8F)); + conditions.push_back(in_interval_expr(chr, 0x1F98, 0x1F9F)); + conditions.push_back(in_interval_expr(chr, 0x1FA8, 0x1FAF)); + return disjunction(conditions); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isTitleCase:(C)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_title_case_char( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_is_title_case, target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isTitleCase:(I)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_title_case_int( + conversion_input &target) +{ + return convert_is_title_case_char(target); +} + +/// Determines if the specified character is in the LETTER_NUMBER category of +/// Unicode +/// \param expr: An expression of type character +/// \param type: A type for the output +/// \return A Boolean expression +exprt character_refine_preprocesst::expr_of_is_letter_number( + const exprt &chr, const typet &type) +{ + // The following set of characters is the general category "Nl" in the + // Unicode specification. + exprt cond0=in_interval_expr(chr, 0x16EE, 0x16F0); + exprt cond1=in_interval_expr(chr, 0x2160, 0x2188); + exprt cond2=in_interval_expr(chr, 0x3021, 0x3029); + exprt cond3=in_interval_expr(chr, 0x3038, 0x303A); + exprt cond4=in_interval_expr(chr, 0xA6E6, 0xA6EF); + exprt cond5=in_interval_expr(chr, 0x10140, 0x10174); + exprt cond6=in_interval_expr(chr, 0x103D1, 0x103D5); + exprt cond7=in_interval_expr(chr, 0x12400, 0x1246E); + exprt cond8=in_list_expr(chr, {0x3007, 0x10341, 0x1034A}); + return or_exprt( + or_exprt(or_exprt(cond0, cond1), or_exprt(cond2, cond3)), + or_exprt(or_exprt(cond4, cond5), or_exprt(cond6, or_exprt(cond7, cond8)))); +} + + +/// Determines if the character may be part of a Unicode identifier. +/// +/// TODO: For now we do not allow connecting punctuation, combining mark, +/// non-spacing mark +/// \param expr: An expression of type character +/// \param type: A type for the output +/// \return A Boolean expression +exprt character_refine_preprocesst::expr_of_is_unicode_identifier_part( + const exprt &chr, const typet &type) +{ + exprt::operandst conditions; + conditions.push_back(expr_of_is_unicode_identifier_start(chr, type)); + conditions.push_back(expr_of_is_digit(chr, type)); + conditions.push_back(expr_of_is_identifier_ignorable(chr, type)); + return disjunction(conditions); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isUnicodeIdentifierPart:(C)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_unicode_identifier_part_char( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_is_unicode_identifier_part, target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isUnicodeIdentifierPart:(I)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_unicode_identifier_part_int( + conversion_input &target) +{ + return convert_is_unicode_identifier_part_char(target); +} + +/// Determines if the specified character is permissible as the first character +/// in a Unicode identifier. +/// \param chr: An expression of type character +/// \param type: A type for the output +/// \return A Boolean expression +exprt character_refine_preprocesst::expr_of_is_unicode_identifier_start( + const exprt &chr, const typet &type) +{ + return or_exprt( + expr_of_is_letter(chr, type), expr_of_is_letter_number(chr, type)); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isUnicodeIdentifierStart:(C)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_unicode_identifier_start_char( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_is_unicode_identifier_start, target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isUnicodeIdentifierStart:(I)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_unicode_identifier_start_int( + conversion_input &target) +{ + return convert_is_unicode_identifier_start_char(target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isUpperCase:(C)Z +/// +/// TODO: For now we only consider ASCII characters +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_upper_case_char( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_is_ascii_upper_case, target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isUpperCase:(I)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_upper_case_int( + conversion_input &target) +{ + return convert_is_upper_case_char(target); +} + +/// Determines whether the specified code point is a valid Unicode code point +/// value. That is, in the range of integers from 0 to 0x10FFFF +/// \param chr: An expression of type character +/// \param type: A type for the output +/// \return A Boolean expression +exprt character_refine_preprocesst::expr_of_is_valid_code_point( + const exprt &chr, const typet &type) +{ + return binary_relation_exprt(chr, ID_le, from_integer(0x10FFFF, chr.type())); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isValidCodePoint:(I)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_valid_code_point( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_is_valid_code_point, target); +} + +/// Determines if the specified character is white space according to Java. It +/// is the case when it one of the following: * a Unicode space character +/// (SPACE_SEPARATOR, LINE_SEPARATOR, or PARAGRAPH_SEPARATOR) but is not also a +/// non-breaking space ('\u00A0', '\u2007', '\u202F'). * it is one of these: +/// U+0009 U+000A U+000B U+000C U+000D U+001C U+001D U+001E U+001F +/// \param expr: An expression of type character +/// \param type: A type for the output +/// \return A Boolean expression +exprt character_refine_preprocesst::expr_of_is_whitespace( + const exprt &chr, const typet &type) +{ + exprt::operandst conditions; + std::list space_characters= + {0x20, 0x1680, 0x205F, 0x3000, 0x2028, 0x2029}; + conditions.push_back(in_list_expr(chr, space_characters)); + conditions.push_back(in_interval_expr(chr, 0x2000, 0x2006)); + conditions.push_back(in_interval_expr(chr, 0x2008, 0x200A)); + conditions.push_back(in_interval_expr(chr, 0x09, 0x0D)); + conditions.push_back(in_interval_expr(chr, 0x1C, 0x1F)); + return disjunction(conditions); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isWhitespace:(C)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_whitespace_char( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_is_whitespace, target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.isWhitespace:(I)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_is_whitespace_int( + conversion_input &target) +{ + return convert_is_whitespace_char(target); +} + +/// Returns the trailing surrogate (a low surrogate code unit) of the surrogate +/// pair representing the specified supplementary character (Unicode code point) +/// in the UTF-16 encoding. +/// \param expr: An expression of type character +/// \param type: A type for the output +/// \return A integer expression of the given type +exprt character_refine_preprocesst::expr_of_low_surrogate( + const exprt &chr, const typet &type) +{ + exprt uDC00=from_integer(0xDC00, type); + exprt u0400=from_integer(0x0400, type); + return plus_exprt(uDC00, mod_exprt(chr, u0400)); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.lowSurrogate:(I)Z +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_low_surrogate( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_low_surrogate, target); +} + +/// Returns the value obtained by reversing the order of the bytes in the +/// specified char value. +/// \param expr: An expression of type character +/// \param type: A type for the output +/// \return A character expression of the given type +exprt character_refine_preprocesst::expr_of_reverse_bytes( + const exprt &chr, const typet &type) +{ + shl_exprt first_byte(chr, from_integer(8, type)); + lshr_exprt second_byte(chr, from_integer(8, type)); + return plus_exprt(first_byte, second_byte); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.reverseBytes:(C)C +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_reverse_bytes( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_reverse_bytes, target); +} + +/// Converts the specified character (Unicode code point) to its UTF-16 +/// representation stored in a char array. If the specified code point is a BMP +/// (Basic Multilingual Plane or Plane 0) value, the resulting char array has +/// the same value as codePoint. If the specified code point is a supplementary +/// code point, the resulting char array has the corresponding surrogate pair. +/// \param expr: An expression of type character +/// \param type: A type for the output +/// \return A character array expression of the given type +exprt character_refine_preprocesst::expr_of_to_chars( + const exprt &chr, const typet &type) +{ + array_typet array_type=to_array_type(type); + const typet &char_type=array_type.subtype(); + array_exprt case1(array_type); + array_exprt case2(array_type); + exprt low_surrogate=expr_of_low_surrogate(chr, char_type); + case1.copy_to_operands(low_surrogate); + case2.move_to_operands(low_surrogate); + exprt high_surrogate=expr_of_high_surrogate(chr, char_type); + case2.move_to_operands(high_surrogate); + return if_exprt(expr_of_is_bmp_code_point(chr, type), case1, case2); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.toChars:(I)[C +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_to_chars(conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_to_chars, target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.toCodePoint:(CC)I +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_to_code_point( + conversion_input &target) +{ + const code_function_callt &function_call=target; + assert(function_call.arguments().size()==2); + const exprt &arg0=function_call.arguments()[0]; + const exprt &arg1=function_call.arguments()[1]; + const exprt &result=function_call.lhs(); + const typet &type=result.type(); + + // These operations implement the decoding of a unicode symbol encoded + // in UTF16 for the supplementary planes (above U+10000). + // The low ten bits of the first character give the bits 10 to 19 of + // code point and the low ten bits of the second give the bits 0 to 9, + // then 0x10000 is added to the result. For more explenations see: + // https://en.wikipedia.org/wiki/UTF-16 + + exprt u010000=from_integer(0x010000, type); + exprt mask10bit=from_integer(0x03FF, type); + shl_exprt m1(bitand_exprt(arg0, mask10bit), from_integer(10, type)); + bitand_exprt m2(arg1, mask10bit); + bitor_exprt pair_value(u010000, bitor_exprt(m1, m2)); + return code_assignt(result, pair_value); +} + +/// Converts the character argument to lowercase. +/// +/// TODO: For now we only consider ASCII characters but ultimately +/// we should use case mapping information from the +/// UnicodeData file +/// \param chr: An expression of type character +/// \param type: A type for the output +/// \return An expression of the given type +exprt character_refine_preprocesst::expr_of_to_lower_case( + const exprt &chr, const typet &type) +{ + minus_exprt transformed( + plus_exprt(chr, from_integer('a', type)), from_integer('A', type)); + + if_exprt res(expr_of_is_ascii_upper_case(chr, type), transformed, chr); + return res; +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.toLowerCase:(C)C +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_to_lower_case_char( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_to_lower_case, target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.toLowerCase:(I)I +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_to_lower_case_int( + conversion_input &target) +{ + return convert_to_lower_case_char(target); +} + +/// Converts the character argument to titlecase. +/// \param chr: An expression of type character +/// \param type: A type for the output +/// \return An expression of the given type +exprt character_refine_preprocesst::expr_of_to_title_case( + const exprt &chr, const typet &type) +{ + std::list increment_list={0x01C4, 0x01C7, 0x01CA, 0x01F1}; + std::list decrement_list={0x01C6, 0x01C9, 0x01CC, 0x01F3}; + exprt plus_8_interval1=in_interval_expr(chr, 0x1F80, 0x1F87); + exprt plus_8_interval2=in_interval_expr(chr, 0x1F90, 0x1F97); + exprt plus_8_interval3=in_interval_expr(chr, 0x1FA0, 0x1FA7); + std::list plus_9_list={0x1FB3, 0x1FC3, 0x1FF3}; + minus_exprt minus_1(chr, from_integer(1, type)); + plus_exprt plus_1(chr, from_integer(1, type)); + plus_exprt plus_8(chr, from_integer(8, type)); + plus_exprt plus_9(chr, from_integer(9, type)); + or_exprt plus_8_set( + plus_8_interval1, or_exprt(plus_8_interval2, plus_8_interval3)); + + if_exprt res( + in_list_expr(chr, increment_list), + plus_1, + if_exprt( + in_list_expr(chr, decrement_list), + minus_1, + if_exprt( + plus_8_set, + plus_8, + if_exprt( + in_list_expr(chr, plus_9_list), + plus_9, + chr)))); + + return res; +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.toTitleCase:(C)C +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_to_title_case_char( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_to_title_case, target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.toTitleCase:(I)I +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_to_title_case_int( + conversion_input &target) +{ + return convert_to_title_case_char(target); +} + +/// Converts the character argument to uppercase. +/// +/// TODO: For now we only consider ASCII characters but ultimately +/// we should use case mapping information from the +/// UnicodeData file +/// \param chr: An expression of type character +/// \param type: A type for the output +/// \return An expression of the given type +exprt character_refine_preprocesst::expr_of_to_upper_case( + const exprt &chr, const typet &type) +{ + minus_exprt transformed( + plus_exprt(chr, from_integer('A', type)), from_integer('a', type)); + + if_exprt res(expr_of_is_ascii_lower_case(chr, type), transformed, chr); + return res; +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.toUpperCase:(C)C +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_to_upper_case_char( + conversion_input &target) +{ + return convert_char_function( + &character_refine_preprocesst::expr_of_to_upper_case, target); +} + +/// Converts function call to an assignment of an expression corresponding to +/// the java method Character.toUpperCase:(I)I +/// \param target: a position in a goto program +codet character_refine_preprocesst::convert_to_upper_case_int( + conversion_input &target) +{ + return convert_to_upper_case_char(target); +} + +/// replace function calls to functions of the Character by an affectation if +/// possible, returns the same code otherwise. For this method to have an effect +/// initialize_conversion_table must have been called before. +/// \param code: the code of a function call +/// \return code where character function call get replaced by an simple +/// instruction +codet character_refine_preprocesst::replace_character_call( + const code_function_callt &code) const +{ + if(code.function().id()==ID_symbol) + { + const irep_idt &function_id= + to_symbol_expr(code.function()).get_identifier(); + auto it=conversion_table.find(function_id); + if(it!=conversion_table.end()) + return (it->second)(code); + } + + return code; +} + +/// fill maps with correspondance from java method names to conversion functions +void character_refine_preprocesst::initialize_conversion_table() +{ + // All methods are listed here in alphabetic order + // The ones that are not supported by this module (though they may be + // supported by the string solver) have no entry in the conversion + // table and are marked in this way: + // Not supported "java::java.lang.Character.()" + + conversion_table["java::java.lang.Character.charCount:(I)I"]= + &character_refine_preprocesst::convert_char_count; + conversion_table["java::java.lang.Character.charValue:()C"]= + &character_refine_preprocesst::convert_char_value; + + // Not supported "java::java.lang.Character.codePointAt:([CI)I + // Not supported "java::java.lang.Character.codePointAt:([CII)I" + // Not supported "java::java.lang.Character.codePointAt:" + // "(Ljava.lang.CharSequence;I)I" + // Not supported "java::java.lang.Character.codePointBefore:([CI)I" + // Not supported "java::java.lang.Character.codePointBefore:([CII)I" + // Not supported "java::java.lang.Character.codePointBefore:" + // "(Ljava.lang.CharSequence;I)I" + // Not supported "java::java.lang.Character.codePointCount:([CII)I" + // Not supported "java::java.lang.Character.codePointCount:" + // "(Ljava.lang.CharSequence;I)I" + // Not supported "java::java.lang.Character.compareTo:" + // "(Ljava.lang.Character;)I" + + conversion_table["java::java.lang.Character.compare:(CC)I"]= + &character_refine_preprocesst::convert_compare; + conversion_table["java::java.lang.Character.digit:(CI)I"]= + &character_refine_preprocesst::convert_digit_char; + conversion_table["java::java.lang.Character.digit:(II)I"]= + &character_refine_preprocesst::convert_digit_int; + + // Not supported "java::java.lang.Character.equals:(Ljava.lang.Object;)Z" + + conversion_table["java::java.lang.Character.forDigit:(II)C"]= + &character_refine_preprocesst::convert_for_digit; + conversion_table["java::java.lang.Character.getDirectionality:(C)B"]= + &character_refine_preprocesst::convert_get_directionality_char; + conversion_table["java::java.lang.Character.getDirectionality:(I)B"]= + &character_refine_preprocesst::convert_get_directionality_int; + + // Not supported "java::java.lang.Character.getName:(I)Ljava.lang.String;" + + conversion_table["java::java.lang.Character.getNumericValue:(C)I"]= + &character_refine_preprocesst::convert_get_numeric_value_char; + conversion_table["java::java.lang.Character.getNumericValue:(I)I"]= + &character_refine_preprocesst::convert_get_numeric_value_int; + conversion_table["java::java.lang.Character.getType:(C)I"]= + &character_refine_preprocesst::convert_get_type_char; + conversion_table["java::java.lang.Character.getType:(I)Z"]= + &character_refine_preprocesst::convert_get_type_int; + conversion_table["java::java.lang.Character.hashCode:()I"]= + &character_refine_preprocesst::convert_hash_code; + conversion_table["java::java.lang.Character.highSurrogate:(C)Z"]= + &character_refine_preprocesst::convert_high_surrogate; + conversion_table["java::java.lang.Character.isAlphabetic:(I)Z"]= + &character_refine_preprocesst::convert_is_alphabetic; + conversion_table["java::java.lang.Character.isBmpCodePoint:(I)Z"]= + &character_refine_preprocesst::convert_is_bmp_code_point; + conversion_table["java::java.lang.Character.isDefined:(C)Z"]= + &character_refine_preprocesst::convert_is_defined_char; + conversion_table["java::java.lang.Character.isDefined:(I)Z"]= + &character_refine_preprocesst::convert_is_defined_int; + conversion_table["java::java.lang.Character.isDigit:(C)Z"]= + &character_refine_preprocesst::convert_is_digit_char; + conversion_table["java::java.lang.Character.isDigit:(I)Z"]= + &character_refine_preprocesst::convert_is_digit_int; + conversion_table["java::java.lang.Character.isHighSurrogate:(C)Z"]= + &character_refine_preprocesst::convert_is_high_surrogate; + conversion_table["java::java.lang.Character.isIdentifierIgnorable:(C)Z"]= + &character_refine_preprocesst::convert_is_identifier_ignorable_char; + conversion_table["java::java.lang.Character.isIdentifierIgnorable:(I)Z"]= + &character_refine_preprocesst::convert_is_identifier_ignorable_int; + conversion_table["java::java.lang.Character.isIdeographic:(C)Z"]= + &character_refine_preprocesst::convert_is_ideographic; + conversion_table["java::java.lang.Character.isISOControl:(C)Z"]= + &character_refine_preprocesst::convert_is_ISO_control_char; + conversion_table["java::java.lang.Character.isISOControl:(I)Z"]= + &character_refine_preprocesst::convert_is_ISO_control_int; + conversion_table["java::java.lang.Character.isJavaIdentifierPart:(C)Z"]= + &character_refine_preprocesst::convert_is_java_identifier_part_char; + conversion_table["java::java.lang.Character.isJavaIdentifierPart:(I)Z"]= + &character_refine_preprocesst::convert_is_java_identifier_part_int; + conversion_table["java::java.lang.Character.isJavaIdentifierStart:(C)Z"]= + &character_refine_preprocesst::convert_is_java_identifier_start_char; + conversion_table["java::java.lang.Character.isJavaIdentifierStart:(I)Z"]= + &character_refine_preprocesst::convert_is_java_identifier_start_int; + conversion_table["java::java.lang.Character.isJavaLetter:(C)Z"]= + &character_refine_preprocesst::convert_is_java_letter; + conversion_table["java::java.lang.Character.isJavaLetterOrDigit:(C)Z"]= + &character_refine_preprocesst::convert_is_java_letter_or_digit; + conversion_table["java::java.lang.Character.isLetter:(C)Z"]= + &character_refine_preprocesst::convert_is_letter_char; + conversion_table["java::java.lang.Character.isLetter:(I)Z"]= + &character_refine_preprocesst::convert_is_letter_int; + conversion_table["java::java.lang.Character.isLetterOrDigit:(C)Z"]= + &character_refine_preprocesst::convert_is_letter_or_digit_char; + conversion_table["java::java.lang.Character.isLetterOrDigit:(I)Z"]= + &character_refine_preprocesst::convert_is_letter_or_digit_int; + conversion_table["java::java.lang.Character.isLowerCase:(C)Z"]= + &character_refine_preprocesst::convert_is_lower_case_char; + conversion_table["java::java.lang.Character.isLowerCase:(I)Z"]= + &character_refine_preprocesst::convert_is_lower_case_int; + conversion_table["java::java.lang.Character.isLowSurrogate:(I)Z"]= + &character_refine_preprocesst::convert_is_low_surrogate; + conversion_table["java::java.lang.Character.isMirrored:(C)Z"]= + &character_refine_preprocesst::convert_is_mirrored_char; + conversion_table["java::java.lang.Character.isMirrored:(I)Z"]= + &character_refine_preprocesst::convert_is_mirrored_int; + conversion_table["java::java.lang.Character.isSpace:(C)Z"]= + &character_refine_preprocesst::convert_is_space; + conversion_table["java::java.lang.Character.isSpaceChar:(C)Z"]= + &character_refine_preprocesst::convert_is_space_char; + conversion_table["java::java.lang.Character.isSpaceChar:(I)Z"]= + &character_refine_preprocesst::convert_is_space_char_int; + conversion_table["java::java.lang.Character.isSupplementaryCodePoint:(I)Z"]= + &character_refine_preprocesst::convert_is_supplementary_code_point; + conversion_table["java::java.lang.Character.isSurrogate:(C)Z"]= + &character_refine_preprocesst::convert_is_surrogate; + conversion_table["java::java.lang.Character.isSurrogatePair:(CC)Z"]= + &character_refine_preprocesst::convert_is_surrogate_pair; + conversion_table["java::java.lang.Character.isTitleCase:(C)Z"]= + &character_refine_preprocesst::convert_is_title_case_char; + conversion_table["java::java.lang.Character.isTitleCase:(I)Z"]= + &character_refine_preprocesst::convert_is_title_case_int; + conversion_table["java::java.lang.Character.isUnicodeIdentifierPart:(C)Z"]= + &character_refine_preprocesst::convert_is_unicode_identifier_part_char; + conversion_table["java::java.lang.Character.isUnicodeIdentifierPart:(I)Z"]= + &character_refine_preprocesst::convert_is_unicode_identifier_part_int; + conversion_table["java::java.lang.Character.isUnicodeIdentifierStart:(C)Z"]= + &character_refine_preprocesst::convert_is_unicode_identifier_start_char; + conversion_table["java::java.lang.Character.isUnicodeIdentifierStart:(I)Z"]= + &character_refine_preprocesst::convert_is_unicode_identifier_start_int; + conversion_table["java::java.lang.Character.isUpperCase:(C)Z"]= + &character_refine_preprocesst::convert_is_upper_case_char; + conversion_table["java::java.lang.Character.isUpperCase:(I)Z"]= + &character_refine_preprocesst::convert_is_upper_case_int; + conversion_table["java::java.lang.Character.isValidCodePoint:(I)Z"]= + &character_refine_preprocesst::convert_is_valid_code_point; + conversion_table["java::java.lang.Character.isWhitespace:(C)Z"]= + &character_refine_preprocesst::convert_is_whitespace_char; + conversion_table["java::java.lang.Character.isWhitespace:(I)Z"]= + &character_refine_preprocesst::convert_is_whitespace_int; + conversion_table["java::java.lang.Character.lowSurrogate:(I)Z"]= + &character_refine_preprocesst::convert_is_low_surrogate; + + // Not supported "java::java.lang.Character.offsetByCodePoints:([CIIII)I" + // Not supported "java::java.lang.Character.offsetByCodePoints:" + // "(Ljava.lang.CharacterSequence;II)I" + + conversion_table["java::java.lang.Character.reverseBytes:(C)C"]= + &character_refine_preprocesst::convert_reverse_bytes; + conversion_table["java::java.lang.Character.toChars:(I)[C"]= + &character_refine_preprocesst::convert_to_chars; + + // Not supported "java::java.lang.Character.toChars:(I[CI])I" + + conversion_table["java::java.lang.Character.toCodePoint:(CC)I"]= + &character_refine_preprocesst::convert_to_code_point; + conversion_table["java::java.lang.Character.toLowerCase:(C)C"]= + &character_refine_preprocesst::convert_to_lower_case_char; + conversion_table["java::java.lang.Character.toLowerCase:(I)I"]= + &character_refine_preprocesst::convert_to_lower_case_int; + + // Not supported "java::java.lang.Character.toString:()Ljava.lang.String;" + // Not supported "java::java.lang.Character.toString:(C)Ljava.lang.String;" + + conversion_table["java::java.lang.Character.toTitleCase:(C)C"]= + &character_refine_preprocesst::convert_to_title_case_char; + conversion_table["java::java.lang.Character.toTitleCase:(I)I"]= + &character_refine_preprocesst::convert_to_title_case_int; + conversion_table["java::java.lang.Character.toUpperCase:(C)C"]= + &character_refine_preprocesst::convert_to_upper_case_char; + conversion_table["java::java.lang.Character.toUpperCase:(I)I"]= + &character_refine_preprocesst::convert_to_upper_case_int; + + // Not supported "java::java.lang.Character.valueOf:(C)Ljava.lang.Character;" +} diff --git a/src/java_bytecode/character_refine_preprocess.h b/src/java_bytecode/character_refine_preprocess.h new file mode 100644 index 00000000000..3714aa6b9a9 --- /dev/null +++ b/src/java_bytecode/character_refine_preprocess.h @@ -0,0 +1,158 @@ +/*******************************************************************\ + +Module: Preprocess a goto-programs so that calls to the java Character + library are replaced by simple expressions. + For now support is limited to character in the ASCII range, + some methods may have incorrect specifications outside of this range. + +Author: Romain Brenguier + +Date: March 2017 + +\*******************************************************************/ + +/// \file +/// Preprocess a goto-programs so that calls to the java Character library are +/// replaced by simple expressions. For now support is limited to character in +/// the ASCII range, some methods may have incorrect specifications outside of +/// this range. + +#ifndef CPROVER_JAVA_BYTECODE_CHARACTER_REFINE_PREPROCESS_H +#define CPROVER_JAVA_BYTECODE_CHARACTER_REFINE_PREPROCESS_H + +#include +#include +#include + +class character_refine_preprocesst:public messaget +{ +public: + void initialize_conversion_table(); + codet replace_character_call(const code_function_callt &call) const; + +private: + typedef const code_function_callt &conversion_input; + typedef codet (*conversion_functiont)(conversion_input &target); + // A table tells us what method to call for each java method signature + std::unordered_map + conversion_table; + + // Conversion functions + static exprt expr_of_char_count(const exprt &chr, const typet &type); + static codet convert_char_count(conversion_input &target); + static exprt expr_of_char_value(const exprt &chr, const typet &type); + static codet convert_char_value(conversion_input &target); + static codet convert_compare(conversion_input &target); + static codet convert_digit_char(conversion_input &target); + static codet convert_digit_int(conversion_input &target); + static codet convert_for_digit(conversion_input &target); + static codet convert_get_directionality_char(conversion_input &target); + static codet convert_get_directionality_int(conversion_input &target); + static codet convert_get_numeric_value_char(conversion_input &target); + static codet convert_get_numeric_value_int(conversion_input &target); + static codet convert_get_type_char(conversion_input &target); + static codet convert_get_type_int(conversion_input &target); + static codet convert_hash_code(conversion_input &target); + static exprt expr_of_high_surrogate(const exprt &chr, const typet &type); + static codet convert_high_surrogate(conversion_input &target); + static exprt expr_of_is_alphabetic(const exprt &chr, const typet &type); + static codet convert_is_alphabetic(conversion_input &target); + static exprt expr_of_is_bmp_code_point(const exprt &chr, const typet &type); + static codet convert_is_bmp_code_point(conversion_input &target); + static exprt expr_of_is_defined(const exprt &chr, const typet &type); + static codet convert_is_defined_char(conversion_input &target); + static codet convert_is_defined_int(conversion_input &target); + static exprt expr_of_is_digit(const exprt &chr, const typet &type); + static codet convert_is_digit_char(conversion_input &target); + static codet convert_is_digit_int(conversion_input &target); + static exprt expr_of_is_high_surrogate(const exprt &chr, const typet &type); + static codet convert_is_high_surrogate(conversion_input &target); + static exprt expr_of_is_identifier_ignorable( + const exprt &chr, const typet &type); + static codet convert_is_identifier_ignorable_char(conversion_input &target); + static codet convert_is_identifier_ignorable_int(conversion_input &target); + static codet convert_is_ideographic(conversion_input &target); + static codet convert_is_ISO_control_char(conversion_input &target); + static codet convert_is_ISO_control_int(conversion_input &target); + static codet convert_is_java_identifier_part_char(conversion_input &target); + static codet convert_is_java_identifier_part_int(conversion_input &target); + static codet convert_is_java_identifier_start_char(conversion_input &target); + static codet convert_is_java_identifier_start_int(conversion_input &target); + static codet convert_is_java_letter(conversion_input &target); + static codet convert_is_java_letter_or_digit(conversion_input &target); + static exprt expr_of_is_letter(const exprt &chr, const typet &type); + static codet convert_is_letter_char(conversion_input &target); + static codet convert_is_letter_int(conversion_input &target); + static exprt expr_of_is_letter_or_digit(const exprt &chr, const typet &type); + static codet convert_is_letter_or_digit_char(conversion_input &target); + static codet convert_is_letter_or_digit_int(conversion_input &target); + static exprt expr_of_is_ascii_lower_case(const exprt &chr, const typet &type); + static codet convert_is_lower_case_char(conversion_input &target); + static codet convert_is_lower_case_int(conversion_input &target); + static codet convert_is_low_surrogate(conversion_input &target); + static exprt expr_of_is_mirrored(const exprt &chr, const typet &type); + static codet convert_is_mirrored_char(conversion_input &target); + static codet convert_is_mirrored_int(conversion_input &target); + static codet convert_is_space(conversion_input &target); + static exprt expr_of_is_space_char(const exprt &chr, const typet &type); + static codet convert_is_space_char(conversion_input &target); + static codet convert_is_space_char_int(conversion_input &target); + static exprt expr_of_is_supplementary_code_point( + const exprt &chr, const typet &type); + static codet convert_is_supplementary_code_point(conversion_input &target); + static exprt expr_of_is_surrogate(const exprt &chr, const typet &type); + static codet convert_is_surrogate(conversion_input &target); + static codet convert_is_surrogate_pair(conversion_input &target); + static exprt expr_of_is_title_case(const exprt &chr, const typet &type); + static codet convert_is_title_case_char(conversion_input &target); + static codet convert_is_title_case_int(conversion_input &target); + static exprt expr_of_is_letter_number(const exprt &chr, const typet &type); + static exprt expr_of_is_unicode_identifier_part( + const exprt &chr, const typet &type); + static codet convert_is_unicode_identifier_part_char( + conversion_input &target); + static codet convert_is_unicode_identifier_part_int(conversion_input &target); + static exprt expr_of_is_unicode_identifier_start( + const exprt &chr, const typet &type); + static codet convert_is_unicode_identifier_start_char( + conversion_input &target); + static codet convert_is_unicode_identifier_start_int( + conversion_input &target); + static exprt expr_of_is_ascii_upper_case(const exprt &chr, const typet &type); + static codet convert_is_upper_case_char(conversion_input &target); + static codet convert_is_upper_case_int(conversion_input &target); + static exprt expr_of_is_valid_code_point(const exprt &chr, const typet &type); + static codet convert_is_valid_code_point(conversion_input &target); + static exprt expr_of_is_whitespace(const exprt &chr, const typet &type); + static codet convert_is_whitespace_char(conversion_input &target); + static codet convert_is_whitespace_int(conversion_input &target); + static exprt expr_of_low_surrogate(const exprt &chr, const typet &type); + static codet convert_low_surrogate(conversion_input &target); + static exprt expr_of_reverse_bytes(const exprt &chr, const typet &type); + static codet convert_reverse_bytes(conversion_input &target); + static exprt expr_of_to_chars(const exprt &chr, const typet &type); + static codet convert_to_chars(conversion_input &target); + static codet convert_to_code_point(conversion_input &target); + static exprt expr_of_to_lower_case(const exprt &chr, const typet &type); + static codet convert_to_lower_case_char(conversion_input &target); + static codet convert_to_lower_case_int(conversion_input &target); + static exprt expr_of_to_title_case(const exprt &chr, const typet &type); + static codet convert_to_title_case_char(conversion_input &target); + static codet convert_to_title_case_int(conversion_input &target); + static exprt expr_of_to_upper_case(const exprt &chr, const typet &type); + static codet convert_to_upper_case_char(conversion_input &target); + static codet convert_to_upper_case_int(conversion_input &target); + + // Helper functions + static codet convert_char_function( + exprt (*expr_function)(const exprt &chr, const typet &type), + conversion_input &target); + static exprt in_interval_expr( + const exprt &chr, + const mp_integer &lower_bound, + const mp_integer &upper_bound); + static exprt in_list_expr( + const exprt &chr, const std::list &list); +}; + +#endif // CPROVER_JAVA_BYTECODE_CHARACTER_REFINE_PREPROCESS_H diff --git a/src/java_bytecode/ci_lazy_methods.cpp b/src/java_bytecode/ci_lazy_methods.cpp index 5cafa74ac73..d7d95e85b91 100644 --- a/src/java_bytecode/ci_lazy_methods.cpp +++ b/src/java_bytecode/ci_lazy_methods.cpp @@ -6,42 +6,28 @@ Author: Chris Smowton, chris.smowton@diffblue.com \*******************************************************************/ -#include +/// \file +/// Context-insensitive lazy methods container #include "ci_lazy_methods.h" -/*******************************************************************\ - -Function: ci_lazy_methodst::add_needed_method - - Inputs: `method_symbol_name`: method name; must exist in symbol table. - - Outputs: - - Purpose: Notes `method_symbol_name` is referenced from some reachable - function, and should therefore be elaborated. - -\*******************************************************************/ +#include +/// Notes `method_symbol_name` is referenced from some reachable function, and +/// should therefore be elaborated. +/// \par parameters: `method_symbol_name`: method name; must exist in symbol +/// table. void ci_lazy_methodst::add_needed_method(const irep_idt &method_symbol_name) { needed_methods.push_back(method_symbol_name); } -/*******************************************************************\ - -Function: java_bytecode_parsert::parse - - Inputs: `class_symbol_name`: class name; must exist in symbol table. - - Outputs: Returns true if `class_symbol_name` is new (not seen before). - - Purpose: Notes class `class_symbol_name` will be instantiated, or - a static field belonging to it will be accessed. Also notes - that its static initializer is therefore reachable. - -\*******************************************************************/ - +/// Notes class `class_symbol_name` will be instantiated, or a static field +/// belonging to it will be accessed. Also notes that its static initializer is +/// therefore reachable. +/// \par parameters: `class_symbol_name`: class name; must exist in symbol +/// table. +/// \return Returns true if `class_symbol_name` is new (not seen before). bool ci_lazy_methodst::add_needed_class(const irep_idt &class_symbol_name) { if(!needed_classes.insert(class_symbol_name).second) diff --git a/src/java_bytecode/ci_lazy_methods.h b/src/java_bytecode/ci_lazy_methods.h index 54c4664c694..e64a3f2467c 100644 --- a/src/java_bytecode/ci_lazy_methods.h +++ b/src/java_bytecode/ci_lazy_methods.h @@ -6,6 +6,9 @@ Author: Chris Smowton, chris.smowton@diffblue.com \*******************************************************************/ +/// \file +/// Context-insensitive lazy methods container + #ifndef CPROVER_JAVA_BYTECODE_CI_LAZY_METHODS_H #define CPROVER_JAVA_BYTECODE_CI_LAZY_METHODS_H diff --git a/src/java_bytecode/expr2java.cpp b/src/java_bytecode/expr2java.cpp index 6be202e1da4..38a91d4d857 100644 --- a/src/java_bytecode/expr2java.cpp +++ b/src/java_bytecode/expr2java.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +#include "expr2java.h" + #include #include @@ -19,19 +21,6 @@ Author: Daniel Kroening, kroening@cs.cmu.edu #include #include "java_types.h" -#include "expr2java.h" - -/*******************************************************************\ - -Function: expr2javat::convert_code_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ std::string expr2javat::convert_code_function_call( const code_function_callt &src, @@ -103,18 +92,6 @@ std::string expr2javat::convert_code_function_call( return dest; } -/*******************************************************************\ - -Function: expr2javat::convert_struct - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2javat::convert_struct( const exprt &src, unsigned &precedence) @@ -179,18 +156,6 @@ std::string expr2javat::convert_struct( return dest; } -/*******************************************************************\ - -Function: expr2javat::convert_constant - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2javat::convert_constant( const constant_exprt &src, unsigned &precedence) @@ -274,18 +239,6 @@ std::string expr2javat::convert_constant( return expr2ct::convert_constant(src, precedence); } -/*******************************************************************\ - -Function: expr2javat::convert_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2javat::convert_rec( const typet &src, const c_qualifierst &qualifiers, @@ -323,8 +276,8 @@ std::string expr2javat::convert_rec( const code_typet &code_type=to_code_type(src); // Java doesn't really have syntax for function types, - // so we make one up, loosley inspired by the syntax - // of lamda expressions. + // so we make one up, loosely inspired by the syntax + // of lambda expressions. std::string dest=""; @@ -360,18 +313,6 @@ std::string expr2javat::convert_rec( return expr2ct::convert_rec(src, qualifiers, declarator); } -/*******************************************************************\ - -Function: expr2javat::convert_java_this - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2javat::convert_java_this( const exprt &src, unsigned precedence) @@ -379,18 +320,6 @@ std::string expr2javat::convert_java_this( return "this"; } -/*******************************************************************\ - -Function: expr2javat::convert_java_instanceof - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2javat::convert_java_instanceof( const exprt &src, unsigned precedence) @@ -404,18 +333,6 @@ std::string expr2javat::convert_java_instanceof( return convert(src.op0())+" instanceof "+convert(src.op1().type()); } -/*******************************************************************\ - -Function: expr2javat::convert_java_new - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2javat::convert_java_new( const exprt &src, unsigned precedence) @@ -441,18 +358,6 @@ std::string expr2javat::convert_java_new( return dest; } -/*******************************************************************\ - -Function: expr2javat::convert_code_java_delete - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2javat::convert_code_java_delete( const exprt &src, unsigned indent) @@ -472,18 +377,6 @@ std::string expr2javat::convert_code_java_delete( return dest; } -/*******************************************************************\ - -Function: expr2javat::convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2javat::convert_with_precedence( const exprt &src, unsigned &precedence) @@ -519,18 +412,6 @@ std::string expr2javat::convert_with_precedence( return expr2ct::convert_with_precedence(src, precedence); } -/*******************************************************************\ - -Function: expr2javat::convert_code - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2javat::convert_code( const codet &src, unsigned indent) @@ -547,18 +428,6 @@ std::string expr2javat::convert_code( return expr2ct::convert_code(src, indent); } -/*******************************************************************\ - -Function: expr2java - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2java(const exprt &expr, const namespacet &ns) { expr2javat expr2java(ns); @@ -568,18 +437,6 @@ std::string expr2java(const exprt &expr, const namespacet &ns) return expr2java.convert(expr); } -/*******************************************************************\ - -Function: type2java - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string type2java(const typet &type, const namespacet &ns) { expr2javat expr2java(ns); diff --git a/src/java_bytecode/expr2java.h b/src/java_bytecode/expr2java.h index 4df0d240cf9..daf4efb36b8 100644 --- a/src/java_bytecode/expr2java.h +++ b/src/java_bytecode/expr2java.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ + #ifndef CPROVER_JAVA_BYTECODE_EXPR2JAVA_H #define CPROVER_JAVA_BYTECODE_EXPR2JAVA_H diff --git a/src/java_bytecode/jar_file.cpp b/src/java_bytecode/jar_file.cpp index ee08a50838a..26bb1a9de50 100644 --- a/src/java_bytecode/jar_file.cpp +++ b/src/java_bytecode/jar_file.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "jar_file.h" + #include #include #include @@ -13,20 +15,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "jar_file.h" - -/*******************************************************************\ - -Function: jar_filet::open - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jar_filet::open( java_class_loader_limitt &class_loader_limit, const std::string &filename) @@ -68,18 +56,6 @@ void jar_filet::open( } } -/*******************************************************************\ - -Function: jar_filet::~jar_filet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - jar_filet::~jar_filet() { if(mz_ok) @@ -89,18 +65,6 @@ jar_filet::~jar_filet() } } -/*******************************************************************\ - -Function: jar_filet::get_entry - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string jar_filet::get_entry(const irep_idt &name) { if(!mz_ok) @@ -130,18 +94,6 @@ std::string jar_filet::get_entry(const irep_idt &name) return dest; } -/*******************************************************************\ - -Function: jar_filet::get_manifest - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - jar_filet::manifestt jar_filet::get_manifest() { auto entry=filtered_jar.find("META-INF/MANIFEST.MF"); diff --git a/src/java_bytecode/jar_file.h b/src/java_bytecode/jar_file.h index 3ecdfc80d0f..bb0b30b918e 100644 --- a/src/java_bytecode/jar_file.h +++ b/src/java_bytecode/jar_file.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// JAR File Reading + #ifndef CPROVER_JAVA_BYTECODE_JAR_FILE_H #define CPROVER_JAVA_BYTECODE_JAR_FILE_H @@ -23,7 +26,11 @@ Author: Daniel Kroening, kroening@kroening.com class jar_filet:public messaget { public: - jar_filet():mz_ok(false) { } + jar_filet(): + mz_ok(false) + // `zip` will be initialized by open() + { + } ~jar_filet(); diff --git a/src/java_bytecode/java_bytecode_convert_class.cpp b/src/java_bytecode/java_bytecode_convert_class.cpp index 53664271993..ab4c3d50ce9 100644 --- a/src/java_bytecode/java_bytecode_convert_class.cpp +++ b/src/java_bytecode/java_bytecode_convert_class.cpp @@ -6,16 +6,21 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// JAVA Bytecode Language Conversion + +#include "java_bytecode_convert_class.h" + #ifdef DEBUG #include #endif -#include "java_bytecode_convert_class.h" #include "java_root_class.h" #include "java_types.h" #include "java_bytecode_convert_method.h" #include "java_bytecode_language.h" +#include #include #include @@ -30,13 +35,15 @@ class java_bytecode_convert_classt:public messaget size_t _max_array_length, lazy_methodst& _lazy_methods, lazy_methods_modet _lazy_methods_mode, - bool _string_refinement_enabled): + bool _string_refinement_enabled, + const character_refine_preprocesst &_character_preprocess): messaget(_message_handler), symbol_table(_symbol_table), max_array_length(_max_array_length), lazy_methods(_lazy_methods), lazy_methods_mode(_lazy_methods_mode), - string_refinement_enabled(_string_refinement_enabled) + string_refinement_enabled(_string_refinement_enabled), + character_preprocess(_character_preprocess) { } @@ -62,6 +69,7 @@ class java_bytecode_convert_classt:public messaget lazy_methodst &lazy_methods; lazy_methods_modet lazy_methods_mode; bool string_refinement_enabled; + character_refine_preprocesst character_preprocess; // conversion void convert(const classt &c); @@ -72,18 +80,6 @@ class java_bytecode_convert_classt:public messaget void add_string_type(); }; -/*******************************************************************\ - -Function: java_bytecode_convert_classt::convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_convert_classt::convert(const classt &c) { std::string qualified_classname="java::"+id2string(c.name); @@ -166,7 +162,8 @@ void java_bytecode_convert_classt::convert(const classt &c) method, symbol_table, get_message_handler(), - max_array_length); + max_array_length, + character_preprocess); } else { @@ -180,18 +177,6 @@ void java_bytecode_convert_classt::convert(const classt &c) java_root_class(*class_symbol); } -/*******************************************************************\ - -Function: java_bytecode_convert_classt::generate_class_stub - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_convert_classt::generate_class_stub( const irep_idt &class_name) { @@ -226,18 +211,6 @@ void java_bytecode_convert_classt::generate_class_stub( } } -/*******************************************************************\ - -Function: java_bytecode_convert_classt::convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_convert_classt::convert( symbolt &class_symbol, const fieldt &f) @@ -299,18 +272,6 @@ void java_bytecode_convert_classt::convert( } } -/*******************************************************************\ - -Function: java_bytecode_convert_classt::add_array_types - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_convert_classt::add_array_types() { const std::string letters="ijsbcfdza"; @@ -334,7 +295,7 @@ void java_bytecode_convert_classt::add_array_types() struct_type.components().push_back(comp1); struct_typet::componentt - comp2("data", pointer_typet(java_type_from_char(l))); + comp2("data", pointer_type(java_type_from_char(l))); struct_type.components().push_back(comp2); symbolt symbol; @@ -346,18 +307,6 @@ void java_bytecode_convert_classt::add_array_types() } } -/*******************************************************************\ - -Function: java_bytecode_convert_class - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool java_bytecode_convert_class( const java_bytecode_parse_treet &parse_tree, symbol_tablet &symbol_table, @@ -365,7 +314,8 @@ bool java_bytecode_convert_class( size_t max_array_length, lazy_methodst &lazy_methods, lazy_methods_modet lazy_methods_mode, - bool string_refinement_enabled) + bool string_refinement_enabled, + const character_refine_preprocesst &character_preprocess) { java_bytecode_convert_classt java_bytecode_convert_class( symbol_table, @@ -373,7 +323,8 @@ bool java_bytecode_convert_class( max_array_length, lazy_methods, lazy_methods_mode, - string_refinement_enabled); + string_refinement_enabled, + character_preprocess); try { @@ -398,15 +349,8 @@ bool java_bytecode_convert_class( return true; } -/*******************************************************************\ - -Function: java_bytecode_convert_classt::add_string_type - - Purpose: Implements the java.lang.String type in the case that - we provide an internal implementation. - -\*******************************************************************/ - +/// Implements the java.lang.String type in the case that we provide an internal +/// implementation. void java_bytecode_convert_classt::add_string_type() { class_typet string_type; @@ -423,7 +367,7 @@ void java_bytecode_convert_classt::add_string_type() // Use a pointer-to-unbounded-array instead of a pointer-to-char. // Saves some casting in the string refinement algorithm but may // be unnecessary. - string_type.components()[2].type()=pointer_typet( + string_type.components()[2].type()=pointer_type( array_typet(java_char_type(), infinity_exprt(java_int_type()))); string_type.add_base(symbol_typet("java::java.lang.Object")); @@ -449,9 +393,9 @@ void java_bytecode_convert_classt::add_string_type() string_equals_type.return_type()=java_boolean_type(); code_typet::parametert thisparam; thisparam.set_this(); - thisparam.type()=pointer_typet(symbol_typet(string_symbol.name)); + thisparam.type()=java_reference_type(symbol_typet(string_symbol.name)); code_typet::parametert otherparam; - otherparam.type()=pointer_typet(symbol_typet("java::java.lang.Object")); + otherparam.type()=java_reference_type(symbol_typet("java::java.lang.Object")); string_equals_type.parameters().push_back(thisparam); string_equals_type.parameters().push_back(otherparam); string_equals_symbol.type=std::move(string_equals_type); diff --git a/src/java_bytecode/java_bytecode_convert_class.h b/src/java_bytecode/java_bytecode_convert_class.h index 9ce5cc8c7cc..0c14a760eec 100644 --- a/src/java_bytecode/java_bytecode_convert_class.h +++ b/src/java_bytecode/java_bytecode_convert_class.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// JAVA Bytecode Language Conversion + #ifndef CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_CONVERT_CLASS_H #define CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_CONVERT_CLASS_H @@ -14,6 +17,7 @@ Author: Daniel Kroening, kroening@kroening.com #include "java_bytecode_parse_tree.h" #include "java_bytecode_language.h" +#include "character_refine_preprocess.h" bool java_bytecode_convert_class( const java_bytecode_parse_treet &parse_tree, @@ -22,6 +26,7 @@ bool java_bytecode_convert_class( size_t max_array_length, lazy_methodst &, lazy_methods_modet, - bool string_refinement_enabled); + bool string_refinement_enabled, + const character_refine_preprocesst &character_preprocess); #endif // CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_CONVERT_CLASS_H diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 43a2ded0af1..d97a769d59f 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -6,27 +6,33 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// JAVA Bytecode Language Conversion + #ifdef DEBUG #include #endif +#include "java_bytecode_convert_method.h" +#include "java_bytecode_convert_method_class.h" +#include "bytecode_info.h" +#include "java_types.h" + +#include +#include +#include +#include #include +#include +#include #include #include -#include -#include -#include #include #include #include -#include "java_bytecode_convert_method.h" -#include "java_bytecode_convert_method_class.h" -#include "bytecode_info.h" -#include "java_types.h" - #include #include #include @@ -108,18 +114,7 @@ exprt::operandst java_bytecode_convert_methodt::pop(std::size_t n) return operands; } -/*******************************************************************\ - -Function: java_bytecode_convert_methodt::pop_residue - -Inputs: - -Outputs: - -Purpose: removes minimum(n, stack.size()) elements from the stack - -\*******************************************************************/ - +/// removes minimum(n, stack.size()) elements from the stack void java_bytecode_convert_methodt::pop_residue(std::size_t n) { std::size_t residue_size=std::min(n, stack.size()); @@ -169,9 +164,11 @@ const exprt java_bytecode_convert_methodt::variable( size_t address, java_bytecode_convert_methodt::variable_cast_argumentt do_cast) { - irep_idt number=to_constant_expr(arg).get_value(); + mp_integer number; + bool ret=to_integer(to_constant_expr(arg), number); + CHECK_RETURN(!ret); - std::size_t number_int=safe_string2size_t(id2string(number)); + std::size_t number_int=integer2size_t(number); typet t=java_type_from_char(type_char); variablest &var_list=variables[number_int]; @@ -181,8 +178,8 @@ const exprt java_bytecode_convert_methodt::variable( if(var.symbol_expr.get_identifier().empty()) { - // an un-named local variable - irep_idt base_name="anonlocal::"+id2string(number)+type_char; + // an unnamed local variable + irep_idt base_name="anonlocal::"+std::to_string(number_int)+type_char; irep_idt identifier=id2string(current_method)+"::"+id2string(base_name); symbol_exprt result(identifier, t); @@ -199,25 +196,14 @@ const exprt java_bytecode_convert_methodt::variable( } } -/*******************************************************************\ - -Function: java_bytecode_convert_method_lazy - - Inputs: `class_symbol`: class this method belongs to - `method_identifier`: fully qualified method name, including - type signature (e.g. "x.y.z.f:(I)") - `m`: parsed method object to convert - `symbol_table`: global symbol table (will be modified) - - Outputs: - - Purpose: This creates a method symbol in the symtab, but doesn't - actually perform method conversion just yet. The caller - should call java_bytecode_convert_method later to give the - symbol/method a body. - -\*******************************************************************/ - +/// This creates a method symbol in the symtab, but doesn't actually perform +/// method conversion just yet. The caller should call +/// java_bytecode_convert_method later to give the symbol/method a body. +/// \par parameters: `class_symbol`: class this method belongs to +/// `method_identifier`: fully qualified method name, including type signature +/// (e.g. "x.y.z.f:(I)") +/// `m`: parsed method object to convert +/// `symbol_table`: global symbol table (will be modified) void java_bytecode_convert_method_lazy( const symbolt &class_symbol, const irep_idt &method_identifier, @@ -259,7 +245,8 @@ void java_bytecode_convert_method_lazy( code_typet &code_type=to_code_type(member_type); code_typet::parameterst ¶meters=code_type.parameters(); code_typet::parametert this_p; - const reference_typet object_ref_type(symbol_typet(class_symbol.name)); + const reference_typet object_ref_type= + java_reference_type(symbol_typet(class_symbol.name)); this_p.type()=object_ref_type; this_p.set_this(); parameters.insert(parameters.begin(), this_p); @@ -269,18 +256,6 @@ void java_bytecode_convert_method_lazy( symbol_table.add(method_symbol); } -/*******************************************************************\ - -Function: java_bytecode_convert_methodt::convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_convert_methodt::convert( const symbolt &class_symbol, const methodt &m) @@ -431,22 +406,10 @@ void java_bytecode_convert_methodt::convert( symbol_table.add(method_symbol); } -/*******************************************************************\ - -Function: java_bytecode_convert_methodt::get_bytecode_info - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const bytecode_infot &java_bytecode_convert_methodt::get_bytecode_info( const irep_idt &statement) { - for(const bytecode_infot *p=bytecode_info; p->mnemonic!=0; p++) + for(const bytecode_infot *p=bytecode_info; p->mnemonic!=nullptr; p++) if(statement==p->mnemonic) return *p; @@ -478,7 +441,7 @@ static member_exprt to_member(const exprt &pointer, const exprt &fieldref) symbol_typet class_type(fieldref.get(ID_class)); exprt pointer2= - typecast_exprt(pointer, pointer_typet(class_type)); + typecast_exprt(pointer, java_reference_type(class_type)); const dereference_exprt obj_deref(pointer2, class_type); @@ -517,20 +480,12 @@ codet java_bytecode_convert_methodt::get_array_bounds_check( return bounds_checks; } -/*******************************************************************\ - -Function: replace_goto_target - - Inputs: 'repl', a block of code in which to perform replacement, and - an old_label that should be replaced throughout by new_label. - - Outputs: None (side-effects on repl) - - Purpose: Find all goto statements in 'repl' that target 'old_label' - and redirect them to 'new_label'. - -\*******************************************************************/ - +/// Find all goto statements in 'repl' that target 'old_label' and redirect them +/// to 'new_label'. +/// \par parameters: 'repl', a block of code in which to perform replacement, +/// and +/// an old_label that should be replaced throughout by new_label. +/// \return None (side-effects on repl) void java_bytecode_convert_methodt::replace_goto_target( codet &repl, const irep_idt &old_label, @@ -551,27 +506,20 @@ void java_bytecode_convert_methodt::replace_goto_target( } } -/*******************************************************************\ - -Function: java_bytecode_convert_methodt::get_block_for_pcrange - - Inputs: 'tree', a code block descriptor, and 'this_block', the corresponding - actual code_blockt. 'address_start' and 'address_limit', the Java - bytecode offsets searched for. 'next_block_start_address', the - bytecode offset of tree/this_block's successor sibling, or UINT_MAX - if none exists. - - Outputs: Returns the code_blockt most closely enclosing the given address range. - - Purpose: 'tree' describes a tree of code_blockt objects; this_block is the - corresponding block (thus they are both trees with the same shape). - The caller is looking for the single block in the tree that most - closely encloses bytecode address range [address_start,address_limit). - 'next_block_start_address' is the start address of 'tree's successor - sibling and is used to determine when the range spans out of its bounds. - -\*******************************************************************/ - +/// 'tree' describes a tree of code_blockt objects; this_block is the +/// corresponding block (thus they are both trees with the same shape). The +/// caller is looking for the single block in the tree that most closely +/// encloses bytecode address range [address_start,address_limit). +/// 'next_block_start_address' is the start address of 'tree's successor sibling +/// and is used to determine when the range spans out of its bounds. +/// \par parameters: 'tree', a code block descriptor, and 'this_block', the +/// corresponding +/// actual code_blockt. 'address_start' and 'address_limit', the Java +/// bytecode offsets searched for. 'next_block_start_address', the +/// bytecode offset of tree/this_block's successor sibling, or UINT_MAX +/// if none exists. +/// \return Returns the code_blockt most closely enclosing the given address +/// range. code_blockt &java_bytecode_convert_methodt::get_block_for_pcrange( block_tree_nodet &tree, code_blockt &this_block, @@ -590,29 +538,20 @@ code_blockt &java_bytecode_convert_methodt::get_block_for_pcrange( false); } -/*******************************************************************\ - -Function: java_bytecode_convert_methodt::get_or_create_block_for_pcrange - - Inputs: See above, plus the bytecode address map 'amap' and 'allow_merge' - which is always true except when called from get_block_for_pcrange - - Outputs: See above, plus potential side-effects on 'tree' and 'this_block' - as descibed in 'Purpose' - - Purpose: As above, but this version can additionally create a new branch - in the block_tree-node and code_blockt trees to envelop the requested - address range. For example, if the tree was initially flat, with - nodes (1-10), (11-20), (21-30) and the caller asked for range 13-28, - this would build a surrounding tree node, leaving the tree of shape - (1-10), ^( (11-20), (21-30) )^, and return a reference to the - new branch highlighted with ^^. - 'tree' and 'this_block' trees are always maintained with equal - shapes. ('this_block' may additionally contain code_declt children - which are ignored for this purpose) - -\*******************************************************************/ - +/// As above, but this version can additionally create a new branch in the +/// block_tree-node and code_blockt trees to envelop the requested address +/// range. For example, if the tree was initially flat, with nodes (1-10), +/// (11-20), (21-30) and the caller asked for range 13-28, this would build a +/// surrounding tree node, leaving the tree of shape (1-10), ^( (11-20), (21-30) +/// )^, and return a reference to the new branch highlighted with ^^. 'tree' and +/// 'this_block' trees are always maintained with equal shapes. ('this_block' +/// may additionally contain code_declt children which are ignored for this +/// purpose) +/// \par parameters: See above, plus the bytecode address map 'amap' and +/// 'allow_merge' +/// which is always true except when called from get_block_for_pcrange +/// \return See above, plus potential side-effects on 'tree' and 'this_block' as +/// described in 'Purpose' code_blockt &java_bytecode_convert_methodt::get_or_create_block_for_pcrange( block_tree_nodet &tree, code_blockt &this_block, @@ -830,18 +769,6 @@ static void gather_symbol_live_ranges( } } -/*******************************************************************\ - -Function: get_bytecode_type_width - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static unsigned get_bytecode_type_width(const typet &ty) { if(ty.id()==ID_pointer) @@ -849,18 +776,6 @@ static unsigned get_bytecode_type_width(const typet &ty) return ty.get_unsigned_int(ID_width); } -/*******************************************************************\ - -Function: java_bytecode_convert_methodt::convert_instructions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - codet java_bytecode_convert_methodt::convert_instructions( const methodt &method, const code_typet &method_type) @@ -936,8 +851,9 @@ codet java_bytecode_convert_methodt::convert_instructions( { assert(!i_it->args.empty()); - const unsigned target=safe_string2unsigned( - id2string(to_constant_expr(i_it->args[0]).get_value())); + unsigned target; + bool ret=to_unsigned_integer(to_constant_expr(i_it->args[0]), target); + DATA_INVARIANT(!ret, "target expected to be unsigned integer"); targets.insert(target); a_entry.first->second.successors.push_back(target); @@ -961,8 +877,9 @@ codet java_bytecode_convert_methodt::convert_instructions( { if(is_label) { - const unsigned target=safe_string2unsigned( - id2string(to_constant_expr(arg).get_value())); + unsigned target; + bool ret=to_unsigned_integer(to_constant_expr(arg), target); + DATA_INVARIANT(!ret, "target expected to be unsigned integer"); targets.insert(target); a_entry.first->second.successors.push_back(target); } @@ -1043,9 +960,11 @@ codet java_bytecode_convert_methodt::convert_instructions( statement[statement.size()-2]=='_' && isdigit(statement[statement.size()-1])) { - arg0=constant_exprt( - std::string(id2string(statement), statement.size()-1, 1), - integer_typet()); + arg0= + from_integer( + string2integer( + std::string(id2string(statement), statement.size()-1, 1)), + java_int_type()); statement=std::string(id2string(statement), 0, statement.size()-2); } @@ -1105,7 +1024,7 @@ codet java_bytecode_convert_methodt::convert_instructions( assert(op.size()==1 && results.size()==1); code_blockt block; // TODO throw NullPointerException instead - const typecast_exprt lhs(op[0], pointer_typet(empty_typet())); + const typecast_exprt lhs(op[0], java_reference_type(empty_typet())); const exprt rhs(null_pointer_exprt(to_pointer_type(lhs.type()))); const exprt not_equal_null( binary_relation_exprt(lhs, ID_notequal, rhs)); @@ -1192,7 +1111,7 @@ codet java_bytecode_convert_methodt::convert_instructions( else code_type.set(ID_java_super_method_call, true); } - pointer_typet object_ref_type(thistype); + reference_typet object_ref_type=java_reference_type(thistype); code_typet::parametert this_p(object_ref_type); this_p.set_this(); this_p.set_base_name("this"); @@ -1282,7 +1201,10 @@ codet java_bytecode_convert_methodt::convert_instructions( } call.function().add_source_location()=loc; - c=call; + + // Replacing call if it is a function of the Character library, + // returning the same call otherwise + c=character_preprocess.replace_character_call(call); } else if(statement=="return") { @@ -1313,21 +1235,30 @@ codet java_bytecode_convert_methodt::convert_instructions( const member_exprt data_ptr( deref, "data", - pointer_typet(java_type_from_char(type_char))); + pointer_type(java_type_from_char(type_char))); plus_exprt data_plus_offset(data_ptr, op[1], data_ptr.type()); typet element_type=data_ptr.type().subtype(); const dereference_exprt element(data_plus_offset, element_type); - c=code_blockt(); + code_blockt block; + block.add_source_location()=i_it->source_location; + + save_stack_entries( + "stack_astore", + element_type, + block, + bytecode_write_typet::ARRAY_REF, + ""); + codet bounds_check= get_array_bounds_check(deref, op[1], i_it->source_location); bounds_check.add_source_location()=i_it->source_location; - c.move_to_operands(bounds_check); + block.move_to_operands(bounds_check); code_assignt array_put(element, op[2]); array_put.add_source_location()=i_it->source_location; - c.move_to_operands(array_put); - c.add_source_location()=i_it->source_location; + block.move_to_operands(array_put); + c=block; } else if(statement==patternt("?store")) { @@ -1336,12 +1267,24 @@ codet java_bytecode_convert_methodt::convert_instructions( exprt var= variable(arg0, statement[0], i_it->address, NO_CAST); + const irep_idt &var_name=to_symbol_expr(var).get_identifier(); exprt toassign=op[0]; if('a'==statement[0] && toassign.type()!=var.type()) toassign=typecast_exprt(toassign, var.type()); - c=code_assignt(var, toassign); + code_blockt block; + + save_stack_entries( + "stack_store", + toassign.type(), + block, + bytecode_write_typet::VARIABLE, + var_name); + code_assignt assign(var, toassign); + assign.add_source_location()=i_it->source_location; + block.copy_to_operands(assign); + c=block; } else if(statement==patternt("?aload")) { @@ -1357,7 +1300,7 @@ codet java_bytecode_convert_methodt::convert_instructions( const member_exprt data_ptr( deref, "data", - pointer_typet(java_type_from_char(type_char))); + pointer_type(java_type_from_char(type_char))); plus_exprt data_plus_offset(data_ptr, op[1], data_ptr.type()); typet element_type=data_ptr.type().subtype(); @@ -1392,7 +1335,7 @@ codet java_bytecode_convert_methodt::convert_instructions( // these need to be references to java.lang.String results[0]=arg0; symbol_typet string_type("java::java.lang.String"); - results[0].type()=pointer_typet(string_type); + results[0].type()=java_reference_type(string_type); } else if(arg0.id()==ID_type) { @@ -1417,16 +1360,20 @@ codet java_bytecode_convert_methodt::convert_instructions( else if(statement=="goto" || statement=="goto_w") { assert(op.empty() && results.empty()); - irep_idt number=to_constant_expr(arg0).get_value(); - code_gotot code_goto(label(number)); + mp_integer number; + bool ret=to_integer(to_constant_expr(arg0), number); + INVARIANT(!ret, "goto argument should be an integer"); + code_gotot code_goto(label(integer2string(number))); c=code_goto; } else if(statement=="jsr" || statement=="jsr_w") { // As 'goto', except we must also push the subroutine return address: assert(op.empty() && results.size()==1); - irep_idt number=to_constant_expr(arg0).get_value(); - code_gotot code_goto(label(number)); + mp_integer number; + bool ret=to_integer(to_constant_expr(arg0), number); + INVARIANT(!ret, "jsr argument should be an integer"); + code_gotot code_goto(label(integer2string(number))); c=code_goto; results[0]= from_integer( @@ -1486,9 +1433,13 @@ codet java_bytecode_convert_methodt::convert_instructions( ieee_float_spect::double_precision()); ieee_floatt value(spec); - const typet &arg_type(arg0.type()); - if(ID_integer==arg_type.id()) - value.from_integer(arg0.get_int(ID_value)); + if(arg0.type().id()!=ID_floatbv) + { + mp_integer number; + bool ret=to_integer(to_constant_expr(arg0), number); + DATA_INVARIANT(!ret, "failed to convert constant"); + value.from_integer(number); + } else value.from_expr(to_constant_expr(arg0)); @@ -1496,20 +1447,29 @@ codet java_bytecode_convert_methodt::convert_instructions( } else { - const unsigned value(arg0.get_unsigned_int(ID_value)); + mp_integer value; + bool ret=to_integer(to_constant_expr(arg0), value); + DATA_INVARIANT(!ret, "failed to convert constant"); const typet type=java_type_from_char(statement[0]); results[0]=from_integer(value, type); } } else if(statement==patternt("?ipush")) { - assert(results.size()==1); - results[0]=typecast_exprt(arg0, java_int_type()); + PRECONDITION(results.size()==1); + DATA_INVARIANT( + arg0.id()==ID_constant, + "ipush argument expected to be constant"); + results[0]=arg0; + if(arg0.type()!=java_int_type()) + results[0].make_typecast(java_int_type()); } else if(statement==patternt("if_?cmp??")) { - irep_idt number=to_constant_expr(arg0).get_value(); assert(op.size()==2 && results.empty()); + mp_integer number; + bool ret=to_integer(to_constant_expr(arg0), number); + INVARIANT(!ret, "if_?cmp?? argument should be an integer"); code_ifthenelset code_branch; const irep_idt cmp_op=get_if_cmp_operator(statement); @@ -1524,7 +1484,7 @@ codet java_bytecode_convert_methodt::convert_instructions( code_branch.cond()=condition; code_branch.cond().add_source_location()=i_it->source_location; - code_branch.then_case()=code_gotot(label(number)); + code_branch.then_case()=code_gotot(label(integer2string(number))); code_branch.then_case().add_source_location()=i_it->source_location; code_branch.add_source_location()=i_it->source_location; @@ -1541,15 +1501,17 @@ codet java_bytecode_convert_methodt::convert_instructions( statement=="ifle"?ID_le: (assert(false), ""); - irep_idt number=to_constant_expr(arg0).get_value(); assert(op.size()==1 && results.empty()); + mp_integer number; + bool ret=to_integer(to_constant_expr(arg0), number); + INVARIANT(!ret, "if?? argument should be an integer"); code_ifthenelset code_branch; code_branch.cond()= binary_relation_exprt(op[0], id, from_integer(0, op[0].type())); code_branch.cond().add_source_location()=i_it->source_location; code_branch.cond().add_source_location().set_function(method_id); - code_branch.then_case()=code_gotot(label(number)); + code_branch.then_case()=code_gotot(label(integer2string(number))); code_branch.then_case().add_source_location()=i_it->source_location; code_branch.then_case().add_source_location().set_function(method_id); code_branch.add_source_location()=i_it->source_location; @@ -1559,13 +1521,15 @@ codet java_bytecode_convert_methodt::convert_instructions( } else if(statement==patternt("ifnonnull")) { - irep_idt number=to_constant_expr(arg0).get_value(); assert(op.size()==1 && results.empty()); + mp_integer number; + bool ret=to_integer(to_constant_expr(arg0), number); + INVARIANT(!ret, "ifnonnull argument should be an integer"); code_ifthenelset code_branch; - const typecast_exprt lhs(op[0], pointer_typet(empty_typet())); + const typecast_exprt lhs(op[0], java_reference_type(empty_typet())); const exprt rhs(null_pointer_exprt(to_pointer_type(lhs.type()))); code_branch.cond()=binary_relation_exprt(lhs, ID_notequal, rhs); - code_branch.then_case()=code_gotot(label(number)); + code_branch.then_case()=code_gotot(label(integer2string(number))); code_branch.then_case().add_source_location()=i_it->source_location; code_branch.add_source_location()=i_it->source_location; @@ -1574,12 +1538,14 @@ codet java_bytecode_convert_methodt::convert_instructions( else if(statement==patternt("ifnull")) { assert(op.size()==1 && results.empty()); - irep_idt number=to_constant_expr(arg0).get_value(); + mp_integer number; + bool ret=to_integer(to_constant_expr(arg0), number); + INVARIANT(!ret, "ifnull argument should be an integer"); code_ifthenelset code_branch; - const typecast_exprt lhs(op[0], pointer_typet(empty_typet())); + const typecast_exprt lhs(op[0], java_reference_type(empty_typet())); const exprt rhs(null_pointer_exprt(to_pointer_type(lhs.type()))); code_branch.cond()=binary_relation_exprt(lhs, ID_equal, rhs); - code_branch.then_case()=code_gotot(label(number)); + code_branch.then_case()=code_gotot(label(integer2string(number))); code_branch.then_case().add_source_location()=i_it->source_location; code_branch.add_source_location()=i_it->source_location; @@ -1587,13 +1553,28 @@ codet java_bytecode_convert_methodt::convert_instructions( } else if(statement=="iinc") { + code_blockt block; + block.add_source_location()=i_it->source_location; + // search variable on stack + const exprt &locvar=variable(arg0, 'i', i_it->address, NO_CAST); + save_stack_entries( + "stack_iinc", + java_int_type(), + block, + bytecode_write_typet::VARIABLE, + to_symbol_expr(locvar).get_identifier()); + code_assignt code_assign; code_assign.lhs()= variable(arg0, 'i', i_it->address, NO_CAST); + exprt arg1_int_type=arg1; + if(arg1.type()!=java_int_type()) + arg1_int_type.make_typecast(java_int_type()); code_assign.rhs()=plus_exprt( variable(arg0, 'i', i_it->address, CAST_AS_NEEDED), - typecast_exprt(arg1, java_int_type())); - c=code_assign; + arg1_int_type); + block.copy_to_operands(code_assign); + c=block; } else if(statement==patternt("?xor")) { @@ -1628,10 +1609,16 @@ codet java_bytecode_convert_methodt::convert_instructions( const std::size_t width=type.get_size_t(ID_width); typet target=unsignedbv_typet(width); - const typecast_exprt lhs(op[0], target); - const typecast_exprt rhs(op[1], target); + exprt lhs=op[0]; + if(lhs.type()!=target) + lhs.make_typecast(target); + exprt rhs=op[1]; + if(rhs.type()!=target) + rhs.make_typecast(target); - results[0]=typecast_exprt(lshr_exprt(lhs, rhs), op[0].type()); + results[0]=lshr_exprt(lhs, rhs); + if(results[0].type()!=op[0].type()) + results[0].make_typecast(op[0].type()); } else if(statement==patternt("?add")) { @@ -1827,8 +1814,16 @@ codet java_bytecode_convert_methodt::convert_instructions( } else if(statement=="putfield") { - assert(op.size()==2 && results.size()==0); - c=code_assignt(to_member(op[0], arg0), op[1]); + assert(op.size()==2 && results.empty()); + code_blockt block; + save_stack_entries( + "stack_field", + op[1].type(), + block, + bytecode_write_typet::FIELD, + arg0.get(ID_component_name)); + block.copy_to_operands(code_assignt(to_member(op[0], arg0), op[1])); + c=block; } else if(statement=="putstatic") { @@ -1841,18 +1836,31 @@ codet java_bytecode_convert_methodt::convert_instructions( lazy_methods->add_needed_class( to_symbol_type(arg0.type()).get_identifier()); } - c=code_assignt(symbol_expr, op[0]); + code_blockt block; + block.add_source_location()=i_it->source_location; + + save_stack_entries( + "stack_static_field", + symbol_expr.type(), + block, + bytecode_write_typet::STATIC_FIELD, + symbol_expr.get_identifier()); + block.copy_to_operands(code_assignt(symbol_expr, op[0])); + c=block; } else if(statement==patternt("?2?")) // i2c etc. { assert(op.size()==1 && results.size()==1); - results[0]=typecast_exprt(op[0], java_type_from_char(statement[2])); + typet type=java_type_from_char(statement[2]); + results[0]=op[0]; + if(results[0].type()!=type) + results[0].make_typecast(type); } else if(statement=="new") { // use temporary since the stack symbol might get duplicated assert(op.empty() && results.size()==1); - const pointer_typet ref_type(arg0.type()); + const reference_typet ref_type=java_reference_type(arg0.type()); exprt java_new_expr=side_effect_exprt(ID_java_new, ref_type); if(!i_it->source_location.get_line().empty()) @@ -1860,6 +1868,7 @@ codet java_bytecode_convert_methodt::convert_instructions( const exprt tmp=tmp_variable("new", ref_type); c=code_assignt(tmp, java_new_expr); + c.add_source_location()=i_it->source_location; results[0]=tmp; } else if(statement=="newarray" || @@ -1896,7 +1905,8 @@ codet java_bytecode_convert_methodt::convert_instructions( else element_type='a'; - const pointer_typet ref_type=java_array_type(element_type); + const reference_typet ref_type= + java_array_type(element_type); side_effect_exprt java_new_array(ID_java_new_array, ref_type); java_new_array.copy_to_operands(op[0]); @@ -1930,13 +1940,16 @@ codet java_bytecode_convert_methodt::convert_instructions( { // The first argument is the type, the second argument is the number of // dimensions. The size of each dimension is on the stack. - irep_idt number=to_constant_expr(arg1).get_value(); - std::size_t dimension=safe_string2size_t(id2string(number)); + mp_integer number; + bool ret=to_integer(to_constant_expr(arg1), number); + INVARIANT(!ret, "multianewarray argument should be an integer"); + std::size_t dimension=integer2size_t(number); op=pop(dimension); assert(results.size()==1); - const pointer_typet ref_type(arg0.type()); + const reference_typet ref_type= + java_reference_type(arg0.type()); side_effect_exprt java_new_array(ID_java_new_array, ref_type); java_new_array.operands()=op; @@ -1984,7 +1997,7 @@ codet java_bytecode_convert_methodt::convert_instructions( else if(statement=="tableswitch" || statement=="lookupswitch") { - assert(op.size()==1 && results.size()==0); + assert(op.size()==1 && results.empty()); // we turn into switch-case code_switcht code_switch; @@ -2004,8 +2017,10 @@ codet java_bytecode_convert_methodt::convert_instructions( code_switch_caset code_case; code_case.add_source_location()=i_it->source_location; - irep_idt number=to_constant_expr(*a_it).get_value(); - code_case.code()=code_gotot(label(number)); + mp_integer number; + bool ret=to_integer(to_constant_expr(*a_it), number); + DATA_INVARIANT(!ret, "case label expected to be integer"); + code_case.code()=code_gotot(label(integer2string(number))); code_case.code().add_source_location()=i_it->source_location; if(a_it==i_it->args.begin()) @@ -2014,7 +2029,9 @@ codet java_bytecode_convert_methodt::convert_instructions( { instructiont::argst::const_iterator prev=a_it; prev--; - code_case.case_op()=typecast_exprt(*prev, op[0].type()); + code_case.case_op()=*prev; + if(code_case.case_op().type()!=op[0].type()) + code_case.case_op().make_typecast(op[0].type()); code_case.case_op().add_source_location()=i_it->source_location; } @@ -2051,7 +2068,7 @@ codet java_bytecode_convert_methodt::convert_instructions( code_typet type; type.return_type()=void_typet(); type.parameters().resize(1); - type.parameters()[0].type()=reference_typet(void_typet()); + type.parameters()[0].type()=java_reference_type(void_typet()); code_function_callt call; call.function()=symbol_exprt("java::monitorenter", type); call.lhs().make_nil(); @@ -2065,7 +2082,7 @@ codet java_bytecode_convert_methodt::convert_instructions( code_typet type; type.return_type()=void_typet(); type.parameters().resize(1); - type.parameters()[0].type()=reference_typet(void_typet()); + type.parameters()[0].type()=java_reference_type(void_typet()); code_function_callt call; call.function()=symbol_exprt("java::monitorexit", type); call.lhs().make_nil(); @@ -2334,7 +2351,7 @@ codet java_bytecode_convert_methodt::convert_instructions( code_labelt newlabel(label(std::to_string(address)), code_blockt()); root_block.move_to_operands(newlabel); root.branch.push_back(block_tree_nodet::get_leaf()); - assert((root.branch_addresses.size()==0 || + assert((root.branch_addresses.empty() || root.branch_addresses.back() lazy_methods) + safe_pointer lazy_methods, + const character_refine_preprocesst &character_refine) { java_bytecode_convert_methodt java_bytecode_convert_method( symbol_table, message_handler, max_array_length, - lazy_methods); + lazy_methods, + character_refine); java_bytecode_convert_method(class_symbol, method); } + +/// create temporary variables if a write instruction can have undesired side- +/// effects +void java_bytecode_convert_methodt::save_stack_entries( + const std::string &tmp_var_prefix, + const typet &tmp_var_type, + code_blockt &block, + const bytecode_write_typet write_type, + const irep_idt &identifier) +{ + for(auto &stack_entry : stack) + { + // remove typecasts if existing + while(stack_entry.id()==ID_typecast) + stack_entry=to_typecast_expr(stack_entry).op(); + + // variables or static fields and symbol -> save symbols with same id + if((write_type==bytecode_write_typet::VARIABLE || + write_type==bytecode_write_typet::STATIC_FIELD) && + stack_entry.id()==ID_symbol) + { + const symbol_exprt &var=to_symbol_expr(stack_entry); + if(var.get_identifier()==identifier) + create_stack_tmp_var(tmp_var_prefix, tmp_var_type, block, stack_entry); + } + + // array reference and dereference -> save all references on the stack + else if(write_type==bytecode_write_typet::ARRAY_REF && + stack_entry.id()==ID_dereference) + create_stack_tmp_var(tmp_var_prefix, tmp_var_type, block, stack_entry); + + // field and member access -> compare component name + else if(write_type==bytecode_write_typet::FIELD && + stack_entry.id()==ID_member) + { + const irep_idt &entry_id= + to_member_expr(stack_entry).get_component_name(); + if(entry_id==identifier) + create_stack_tmp_var(tmp_var_prefix, tmp_var_type, block, stack_entry); + } + } +} + +/// actually create a temporary variable to hold the value of a stack entry +void java_bytecode_convert_methodt::create_stack_tmp_var( + const std::string &tmp_var_prefix, + const typet &tmp_var_type, + code_blockt &block, + exprt &stack_entry) +{ + const exprt tmp_var= + tmp_variable(tmp_var_prefix, tmp_var_type); + block.copy_to_operands(code_assignt(tmp_var, stack_entry)); + stack_entry=tmp_var; +} diff --git a/src/java_bytecode/java_bytecode_convert_method.h b/src/java_bytecode/java_bytecode_convert_method.h index db6fcc729e1..abd30112031 100644 --- a/src/java_bytecode/java_bytecode_convert_method.h +++ b/src/java_bytecode/java_bytecode_convert_method.h @@ -6,12 +6,16 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// JAVA Bytecode Language Conversion + #ifndef CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_CONVERT_METHOD_H #define CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_CONVERT_METHOD_H #include #include #include +#include "character_refine_preprocess.h" #include "java_bytecode_parse_tree.h" #include "ci_lazy_methods.h" @@ -24,14 +28,16 @@ void java_bytecode_convert_method( symbol_tablet &symbol_table, message_handlert &message_handler, size_t max_array_length, - safe_pointer lazy_methods); + safe_pointer lazy_methods, + const character_refine_preprocesst &character_refine); inline void java_bytecode_convert_method( const symbolt &class_symbol, const java_bytecode_parse_treet::methodt &method, symbol_tablet &symbol_table, message_handlert &message_handler, - size_t max_array_length) + size_t max_array_length, + const character_refine_preprocesst &character_preprocess) { java_bytecode_convert_method( class_symbol, @@ -39,7 +45,8 @@ inline void java_bytecode_convert_method( symbol_table, message_handler, max_array_length, - safe_pointer::create_null()); + safe_pointer::create_null(), + character_preprocess); } void java_bytecode_convert_method_lazy( diff --git a/src/java_bytecode/java_bytecode_convert_method_class.h b/src/java_bytecode/java_bytecode_convert_method_class.h index 53467ed6a46..89e9883d63f 100644 --- a/src/java_bytecode/java_bytecode_convert_method_class.h +++ b/src/java_bytecode/java_bytecode_convert_method_class.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// JAVA Bytecode Language Conversion + #ifndef CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_CONVERT_METHOD_CLASS_H #define CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_CONVERT_METHOD_CLASS_H @@ -32,11 +35,14 @@ class java_bytecode_convert_methodt:public messaget symbol_tablet &_symbol_table, message_handlert &_message_handler, size_t _max_array_length, - safe_pointer _lazy_methods): + safe_pointer _lazy_methods, + const character_refine_preprocesst &_character_preprocess): messaget(_message_handler), symbol_table(_symbol_table), max_array_length(_max_array_length), - lazy_methods(_lazy_methods) + lazy_methods(_lazy_methods), + character_preprocess(_character_preprocess), + method_has_this(false) { } @@ -59,6 +65,7 @@ class java_bytecode_convert_methodt:public messaget irep_idt method_id; irep_idt current_method; typet method_return_type; + character_refine_preprocesst character_preprocess; public: struct holet @@ -93,11 +100,11 @@ class java_bytecode_convert_methodt:public messaget std::set used_local_names; bool method_has_this; - typedef enum instruction_sizet + enum instruction_sizet { INST_INDEX=2, INST_INDEX_CONST=3 - } instruction_sizet; + }; codet get_array_bounds_check( const exprt &arraystruct, @@ -215,6 +222,19 @@ class java_bytecode_convert_methodt:public messaget const code_typet &); const bytecode_infot &get_bytecode_info(const irep_idt &statement); + + enum class bytecode_write_typet { VARIABLE, ARRAY_REF, STATIC_FIELD, FIELD}; + void save_stack_entries( + const std::string &, + const typet &, + code_blockt &, + const bytecode_write_typet, + const irep_idt &); + void create_stack_tmp_var( + const std::string &, + const typet &, + code_blockt &, + exprt &); }; #endif diff --git a/src/java_bytecode/java_bytecode_internal_additions.cpp b/src/java_bytecode/java_bytecode_internal_additions.cpp index c0d019a4cc4..bc7715ecd9b 100644 --- a/src/java_bytecode/java_bytecode_internal_additions.cpp +++ b/src/java_bytecode/java_bytecode_internal_additions.cpp @@ -6,24 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include -#include - -#include - #include "java_bytecode_internal_additions.h" -/*******************************************************************\ - -Function: java_internal_additions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include +#include void java_internal_additions(symbol_tablet &dest) { @@ -47,7 +34,7 @@ void java_internal_additions(symbol_tablet &dest) symbolt symbol; symbol.base_name="__CPROVER_malloc_object"; symbol.name=CPROVER_PREFIX "malloc_object"; - symbol.type=pointer_typet(empty_typet()); + symbol.type=pointer_type(empty_typet()); symbol.mode=ID_C; symbol.is_lvalue=true; symbol.is_state_var=true; diff --git a/src/java_bytecode/java_bytecode_internal_additions.h b/src/java_bytecode/java_bytecode_internal_additions.h index 34c47f89414..70362d7d685 100644 --- a/src/java_bytecode/java_bytecode_internal_additions.h +++ b/src/java_bytecode/java_bytecode_internal_additions.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_INTERNAL_ADDITIONS_H #define CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_INTERNAL_ADDITIONS_H diff --git a/src/java_bytecode/java_bytecode_language.cpp b/src/java_bytecode/java_bytecode_language.cpp index 83e7e1effd4..3103e6f463f 100644 --- a/src/java_bytecode/java_bytecode_language.cpp +++ b/src/java_bytecode/java_bytecode_language.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "java_bytecode_language.h" + #include #include @@ -17,7 +19,6 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "java_bytecode_language.h" #include "java_bytecode_convert_class.h" #include "java_bytecode_convert_method.h" #include "java_bytecode_internal_additions.h" @@ -28,18 +29,9 @@ Author: Daniel Kroening, kroening@kroening.com #include "expr2java.h" -/*******************************************************************\ - -Function: java_bytecode_languaget::get_language_options - - Inputs: Command-line options - - Outputs: None - - Purpose: Consume options that are java bytecode specific. - -\*******************************************************************/ - +/// Consume options that are java bytecode specific. +/// \param Command:line options +/// \return None void java_bytecode_languaget::get_language_options(const cmdlinet &cmd) { assume_inputs_non_null=cmd.isset("java-assume-inputs-non-null"); @@ -87,52 +79,17 @@ void java_bytecode_languaget::get_language_options(const cmdlinet &cmd) java_cp_include_files=".*"; } -/*******************************************************************\ - -Function: java_bytecode_languaget::extensions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::set java_bytecode_languaget::extensions() const { return { "class", "jar" }; } -/*******************************************************************\ - -Function: java_bytecode_languaget::modules_provided - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_languaget::modules_provided(std::set &modules) { // modules.insert(translation_unit(parse_path)); } -/*******************************************************************\ - -Function: java_bytecode_languaget::preprocess - - Inputs: - - Outputs: - - Purpose: ANSI-C preprocessing - -\*******************************************************************/ - +/// ANSI-C preprocessing bool java_bytecode_languaget::preprocess( std::istream &instream, const std::string &path, @@ -142,18 +99,6 @@ bool java_bytecode_languaget::preprocess( return true; } -/*******************************************************************\ - -Function: java_bytecode_languaget::parse - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool java_bytecode_languaget::parse( std::istream &instream, const std::string &path) @@ -208,27 +153,18 @@ bool java_bytecode_languaget::parse( return false; } -/*******************************************************************\ - -Function: get_virtual_method_target - - Inputs: `needed_classes`: set of classes that can be instantiated. - Any potential callee not in this set will be ignored. - `call_basename`: unqualified function name with type - signature (e.g. "f:(I)") - `classname`: class name that may define or override a - function named `call_basename`. - `symbol_table`: global symtab - - Outputs: Returns the fully qualified name of `classname`'s definition - of `call_basename` if found and `classname` is present in - `needed_classes`, or irep_idt() otherwise. - - Purpose: Find a virtual callee, if one is defined and the callee type - is known to exist. - -\*******************************************************************/ - +/// Find a virtual callee, if one is defined and the callee type is known to +/// exist. +/// \par parameters: `needed_classes`: set of classes that can be instantiated. +/// Any potential callee not in this set will be ignored. +/// `call_basename`: unqualified function name with type signature (e.g. +/// "f:(I)") +/// `classname`: class name that may define or override a function named +/// `call_basename`. +/// `symbol_table`: global symtab +/// \return Returns the fully qualified name of `classname`'s definition of +/// `call_basename` if found and `classname` is present in `needed_classes`, +/// or irep_idt() otherwise. static irep_idt get_virtual_method_target( const std::set &needed_classes, const irep_idt &call_basename, @@ -245,27 +181,17 @@ static irep_idt get_virtual_method_target( return irep_idt(); } -/*******************************************************************\ - -Function: get_virtual_method_target - - Inputs: `c`: function call whose potential target functions should - be determined. - `needed_classes`: set of classes that can be instantiated. - Any potential callee not in this set will be ignored. - `symbol_table`: global symtab - `class_hierarchy`: global class hierarchy - - Outputs: Populates `needed_methods` with all possible `c` callees, - taking `needed_classes` into account (virtual function - overrides defined on classes that are not 'needed' are - ignored) - - Purpose: Find possible callees, excluding types that are not known - to be instantiated. - -\*******************************************************************/ - +/// Find possible callees, excluding types that are not known to be +/// instantiated. +/// \par parameters: `c`: function call whose potential target functions should +/// be determined. +/// `needed_classes`: set of classes that can be instantiated. Any potential +/// callee not in this set will be ignored. +/// `symbol_table`: global symtab +/// `class_hierarchy`: global class hierarchy +/// \return Populates `needed_methods` with all possible `c` callees, taking +/// `needed_classes` into account (virtual function overrides defined on +/// classes that are not 'needed' are ignored) static void get_virtual_method_targets( const code_function_callt &c, const std::set &needed_classes, @@ -277,9 +203,9 @@ static void get_virtual_method_targets( assert(called_function.id()==ID_virtual_function); const auto &call_class=called_function.get(ID_C_class); - assert(call_class!=irep_idt()); + assert(!call_class.empty()); const auto &call_basename=called_function.get(ID_component_name); - assert(call_basename!=irep_idt()); + assert(!call_basename.empty()); auto old_size=needed_methods.size(); @@ -292,7 +218,7 @@ static void get_virtual_method_targets( call_basename, child_class, symbol_table); - if(child_method!=irep_idt()) + if(!child_method.empty()) needed_methods.push_back(child_method); } @@ -305,7 +231,7 @@ static void get_virtual_method_targets( call_basename, parent_class_id, symbol_table); - if(parent_method!=irep_idt()) + if(!parent_method.empty()) { needed_methods.push_back(parent_method); break; @@ -340,19 +266,10 @@ static void get_virtual_method_targets( } } -/*******************************************************************\ - -Function: gather_virtual_callsites - - Inputs: `e`: expression tree to search - - Outputs: Populates `result` with pointers to each function call - within e that calls a virtual function. - - Purpose: See output - -\*******************************************************************/ - +/// See output +/// \par parameters: `e`: expression tree to search +/// \return Populates `result` with pointers to each function call within e that +/// calls a virtual function. static void gather_virtual_callsites( const exprt &e, std::vector &result) @@ -368,20 +285,11 @@ static void gather_virtual_callsites( gather_virtual_callsites(*it, result); } -/*******************************************************************\ - -Function: gather_needed_globals - - Inputs: `e`: expression tree to search - `symbol_table`: global symtab - - Outputs: Populates `needed` with global variable symbols referenced - from `e` or its children. - - Purpose: See output - -\*******************************************************************/ - +/// See output +/// \par parameters: `e`: expression tree to search +/// `symbol_table`: global symtab +/// \return Populates `needed` with global variable symbols referenced from `e` +/// or its children. static void gather_needed_globals( const exprt &e, const symbol_tablet &symbol_table, @@ -405,22 +313,13 @@ static void gather_needed_globals( gather_needed_globals(*opit, symbol_table, needed); } -/*******************************************************************\ - -Function: gather_field_types - - Inputs: `class_type`: root of class tree to search - `ns`: global namespace - - Outputs: Populates `lazy_methods` with all Java reference types - reachable starting at `class_type`. For example if - `class_type` is `symbol_typet("java::A")` and A has a B - field, then `B` (but not `A`) will noted as a needed class. - - Purpose: See output - -\*******************************************************************/ - +/// See output +/// \par parameters: `class_type`: root of class tree to search +/// `ns`: global namespace +/// \return Populates `lazy_methods` with all Java reference types reachable +/// starting at `class_type`. For example if `class_type` is +/// `symbol_typet("java::A")` and A has a B field, then `B` (but not `A`) will +/// noted as a needed class. static void gather_field_types( const typet &class_type, const namespacet &ns, @@ -444,23 +343,14 @@ static void gather_field_types( } } -/*******************************************************************\ - -Function: initialize_needed_classes - - Inputs: `entry_points`: list of fully-qualified function names that - we should assume are reachable - `ns`: global namespace - `ch`: global class hierarchy - - Outputs: Populates `lazy_methods` with all Java reference types - whose references may be passed, directly or indirectly, - to any of the functions in `entry_points`. - - Purpose: See output - -\*******************************************************************/ - +/// See output +/// \par parameters: `entry_points`: list of fully-qualified function names that +/// we should assume are reachable +/// `ns`: global namespace +/// `ch`: global class hierarchy +/// \return Populates `lazy_methods` with all Java reference types whose +/// references may be passed, directly or indirectly, to any of the functions +/// in `entry_points`. static void initialize_needed_classes( const std::vector &entry_points, const namespacet &ns, @@ -495,22 +385,13 @@ static void initialize_needed_classes( lazy_methods.add_needed_class("java::java.lang.Object"); } -/*******************************************************************\ - -Function: java_bytecode_languaget::typecheck - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool java_bytecode_languaget::typecheck( symbol_tablet &symbol_table, const std::string &module) { + if(string_refinement_enabled) + character_preprocess.initialize_conversion_table(); + // first convert all for(java_class_loadert::class_mapt::const_iterator c_it=java_class_loader.class_map.begin(); @@ -529,7 +410,8 @@ bool java_bytecode_languaget::typecheck( max_user_array_length, lazy_methods, lazy_methods_mode, - string_refinement_enabled)) + string_refinement_enabled, + character_preprocess)) return true; } @@ -550,32 +432,19 @@ bool java_bytecode_languaget::typecheck( return false; } -/*******************************************************************\ - -Function: java_bytecode_languaget::do_ci_lazy_method_conversion - - Inputs: `symbol_table`: global symbol table - `lazy_methods`: map from method names to relevant symbol - and parsed-method objects. - - Outputs: Elaborates lazily-converted methods that may be reachable - starting from the main entry point (usually provided with - the --function command-line option) (side-effect on the - symbol_table). Returns false on success. - - Purpose: Uses a simple context-insensitive ('ci') analysis to - determine which methods may be reachable from the main - entry point. In brief, static methods are reachable if we - find a callsite in another reachable site, while virtual - methods are reachable if we find a virtual callsite - targeting a compatible type *and* a constructor callsite - indicating an object of that type may be instantiated (or - evidence that an object of that type exists before the - main function is entered, such as being passed as a - parameter). - -\*******************************************************************/ - +/// Uses a simple context-insensitive ('ci') analysis to determine which methods +/// may be reachable from the main entry point. In brief, static methods are +/// reachable if we find a callsite in another reachable site, while virtual +/// methods are reachable if we find a virtual callsite targeting a compatible +/// type *and* a constructor callsite indicating an object of that type may be +/// instantiated (or evidence that an object of that type exists before the main +/// function is entered, such as being passed as a parameter). +/// \par parameters: `symbol_table`: global symbol table +/// `lazy_methods`: map from method names to relevant symbol and parsed-method +/// objects. +/// \return Elaborates lazily-converted methods that may be reachable starting +/// from the main entry point (usually provided with the --function command- +/// line option) (side-effect on the symbol_table). Returns false on success. bool java_bytecode_languaget::do_ci_lazy_method_conversion( symbol_tablet &symbol_table, lazy_methodst &lazy_methods) @@ -638,7 +507,7 @@ bool java_bytecode_languaget::do_ci_lazy_method_conversion( do { any_new_methods=false; - while(method_worklist2.size()!=0) + while(!method_worklist2.empty()) { std::swap(method_worklist1, method_worklist2); for(const auto &mname : method_worklist1) @@ -664,7 +533,8 @@ bool java_bytecode_languaget::do_ci_lazy_method_conversion( symbol_table, get_message_handler(), max_user_array_length, - safe_pointer::create_non_null(&lazy_methods)); + safe_pointer::create_non_null(&lazy_methods), + character_preprocess); gather_virtual_callsites( symbol_table.lookup(mname).value, virtual_callsites); @@ -721,22 +591,11 @@ bool java_bytecode_languaget::do_ci_lazy_method_conversion( return false; } -/*******************************************************************\ - -Function: java_bytecode_languaget::lazy_methods_provided - - Inputs: None - - Outputs: Populates `methods` with the complete list of lazy methods - that are available to convert (those which are valid - parameters for `convert_lazy_method`) - - Purpose: Provide feedback to `language_filest` so that when asked - for a lazy method, it can delegate to this instance of - java_bytecode_languaget. - -\*******************************************************************/ - +/// Provide feedback to `language_filest` so that when asked for a lazy method, +/// it can delegate to this instance of java_bytecode_languaget. +/// \return Populates `methods` with the complete list of lazy methods that are +/// available to convert (those which are valid parameters for +/// `convert_lazy_method`) void java_bytecode_languaget::lazy_methods_provided( std::set &methods) const { @@ -744,26 +603,15 @@ void java_bytecode_languaget::lazy_methods_provided( methods.insert(kv.first); } -/*******************************************************************\ - -Function: java_bytecode_languaget::convert_lazy_method - - Inputs: `id`: method ID to convert - `symtab`: global symbol table - - Outputs: Amends the symbol table entry for function `id`, which - should be a lazy method provided by this instance of - `java_bytecode_languaget`. It should initially have a nil - value. After this method completes, it will have a value - representing the method body, identical to that produced - using eager method conversion. - - Purpose: Promote a lazy-converted method (one whose type is known - but whose body hasn't been converted) into a fully- - elaborated one. - -\*******************************************************************/ - +/// Promote a lazy-converted method (one whose type is known but whose body +/// hasn't been converted) into a fully- elaborated one. +/// \par parameters: `id`: method ID to convert +/// `symtab`: global symbol table +/// \return Amends the symbol table entry for function `id`, which should be a +/// lazy method provided by this instance of `java_bytecode_languaget`. It +/// should initially have a nil value. After this method completes, it will +/// have a value representing the method body, identical to that produced +/// using eager method conversion. void java_bytecode_languaget::convert_lazy_method( const irep_idt &id, symbol_tablet &symtab) @@ -774,21 +622,10 @@ void java_bytecode_languaget::convert_lazy_method( *lazy_method_entry.second, symtab, get_message_handler(), - max_user_array_length); + max_user_array_length, + character_preprocess); } -/*******************************************************************\ - -Function: java_bytecode_languaget::final - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool java_bytecode_languaget::final( symbol_tablet &symbol_table, bool generate_start_function) @@ -817,52 +654,16 @@ bool java_bytecode_languaget::final( max_nondet_array_length)); } -/*******************************************************************\ - -Function: java_bytecode_languaget::show_parse - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_languaget::show_parse(std::ostream &out) { java_class_loader(main_class).output(out); } -/*******************************************************************\ - -Function: new_java_bytecode_language - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - languaget *new_java_bytecode_language() { return new java_bytecode_languaget; } -/*******************************************************************\ - -Function: java_bytecode_languaget::from_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool java_bytecode_languaget::from_expr( const exprt &expr, std::string &code, @@ -872,18 +673,6 @@ bool java_bytecode_languaget::from_expr( return false; } -/*******************************************************************\ - -Function: java_bytecode_languaget::from_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool java_bytecode_languaget::from_type( const typet &type, std::string &code, @@ -893,36 +682,12 @@ bool java_bytecode_languaget::from_type( return false; } -/*******************************************************************\ - -Function: java_bytecode_languaget::get_pretty_printer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::unique_ptr java_bytecode_languaget::get_pretty_printer(const namespacet &ns) { return std::unique_ptr(new expr2javat(ns)); } -/*******************************************************************\ - -Function: java_bytecode_languaget::to_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool java_bytecode_languaget::to_expr( const std::string &code, const std::string &module, @@ -970,18 +735,6 @@ bool java_bytecode_languaget::to_expr( return true; // fail for now } -/*******************************************************************\ - -Function: java_bytecode_languaget::~java_bytecode_languaget - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - java_bytecode_languaget::~java_bytecode_languaget() { } diff --git a/src/java_bytecode/java_bytecode_language.h b/src/java_bytecode/java_bytecode_language.h index a9f917ee567..c6242c3aac2 100644 --- a/src/java_bytecode/java_bytecode_language.h +++ b/src/java_bytecode/java_bytecode_language.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_LANGUAGE_H #define CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_LANGUAGE_H @@ -13,9 +14,12 @@ Author: Daniel Kroening, kroening@kroening.com #include #include "java_class_loader.h" +#include "character_refine_preprocess.h" #define MAX_NONDET_ARRAY_LENGTH_DEFAULT 5 +class symbolt; + enum lazy_methods_modet { LAZY_METHODS_MODE_EAGER, @@ -56,8 +60,11 @@ class java_bytecode_languaget:public languaget virtual ~java_bytecode_languaget(); java_bytecode_languaget(): + assume_inputs_non_null(false), max_nondet_array_length(MAX_NONDET_ARRAY_LENGTH_DEFAULT), - max_user_array_length(0) + max_user_array_length(0), + lazy_methods_mode(lazy_methods_modet::LAZY_METHODS_MODE_EAGER), + string_refinement_enabled(false) {} bool from_expr( @@ -103,6 +110,7 @@ class java_bytecode_languaget:public languaget lazy_methodst lazy_methods; lazy_methods_modet lazy_methods_mode; bool string_refinement_enabled; + character_refine_preprocesst character_preprocess; std::string java_cp_include_files; }; diff --git a/src/java_bytecode/java_bytecode_parse_tree.cpp b/src/java_bytecode/java_bytecode_parse_tree.cpp index 63fb5674f85..d7dda702683 100644 --- a/src/java_bytecode/java_bytecode_parse_tree.cpp +++ b/src/java_bytecode/java_bytecode_parse_tree.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "java_bytecode_parse_tree.h" + #include #include @@ -15,20 +17,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "expr2java.h" -#include "java_bytecode_parse_tree.h" - -/*******************************************************************\ - -Function: java_bytecode_parse_treet::swap - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_parse_treet::classt::swap( classt &other) { @@ -43,18 +31,6 @@ void java_bytecode_parse_treet::classt::swap( other.annotations.swap(annotations); } -/*******************************************************************\ - -Function: java_bytecode_parse_treet::classt::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_parse_treet::output(std::ostream &out) const { parsed_class.output(out); @@ -66,18 +42,6 @@ void java_bytecode_parse_treet::output(std::ostream &out) const out << " " << *it << '\n'; } -/*******************************************************************\ - -Function: java_bytecode_parse_treet::classt::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_parse_treet::classt::output(std::ostream &out) const { for(const auto &annotation : annotations) @@ -113,18 +77,6 @@ void java_bytecode_parse_treet::classt::output(std::ostream &out) const out << '\n'; } -/*******************************************************************\ - -Function: java_bytecode_parse_treet::annotationt::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_parse_treet::annotationt::output(std::ostream &out) const { symbol_tablet symbol_table; @@ -150,18 +102,6 @@ void java_bytecode_parse_treet::annotationt::output(std::ostream &out) const } } -/*******************************************************************\ - -Function: java_bytecode_parse_treet::annotationt::element_value_pairt::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_parse_treet::annotationt::element_value_pairt::output( std::ostream &out) const { @@ -172,18 +112,6 @@ void java_bytecode_parse_treet::annotationt::element_value_pairt::output( out << expr2java(value, ns); } -/*******************************************************************\ - -Function: java_bytecode_parse_treet::methodt::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_parse_treet::methodt::output(std::ostream &out) const { symbol_tablet symbol_table; @@ -228,7 +156,7 @@ void java_bytecode_parse_treet::methodt::output(std::ostream &out) const for(const auto &i : instructions) { - if(i.source_location.get_line()!=irep_idt()) + if(!i.source_location.get_line().empty()) out << " // " << i.source_location << '\n'; out << " " << i.address << ": "; @@ -263,18 +191,6 @@ void java_bytecode_parse_treet::methodt::output(std::ostream &out) const out << '\n'; } -/*******************************************************************\ - -Function: java_bytecode_parse_treet::fieldt::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_parse_treet::fieldt::output(std::ostream &out) const { for(const auto &annotation : annotations) diff --git a/src/java_bytecode/java_bytecode_parse_tree.h b/src/java_bytecode/java_bytecode_parse_tree.h index 4784f930beb..06b2ca5632f 100644 --- a/src/java_bytecode/java_bytecode_parse_tree.h +++ b/src/java_bytecode/java_bytecode_parse_tree.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_PARSE_TREE_H #define CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_PARSE_TREE_H diff --git a/src/java_bytecode/java_bytecode_parser.cpp b/src/java_bytecode/java_bytecode_parser.cpp index dd458860c97..cbf4ea92fb8 100644 --- a/src/java_bytecode/java_bytecode_parser.cpp +++ b/src/java_bytecode/java_bytecode_parser.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "java_bytecode_parser.h" + #include #include #include @@ -19,7 +21,6 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "java_bytecode_parser.h" #include "java_bytecode_parse_tree.h" #include "java_types.h" #include "bytecode_info.h" @@ -98,7 +99,7 @@ class java_bytecode_parsert:public parsert { // pre-hash the mnemonics, so we do this only once bytecodes.resize(256); - for(const bytecode_infot *p=bytecode_info; p->mnemonic!=0; p++) + for(const bytecode_infot *p=bytecode_info; p->mnemonic!=nullptr; p++) { assert(p->opcodeopcode].mnemonic=p->mnemonic; @@ -200,18 +201,6 @@ class java_bytecode_parsert:public parsert #define VTYPE_INFO_OBJECT 7 #define VTYPE_INFO_UNINIT 8 -/*******************************************************************\ - -Function: java_bytecode_parsert::parse - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool java_bytecode_parsert::parse() { try @@ -240,18 +229,6 @@ bool java_bytecode_parsert::parse() return false; } -/*******************************************************************\ - -Function: java_bytecode_parsert::rClassFile - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - #define ACC_PUBLIC 0x0001 #define ACC_PRIVATE 0x0002 #define ACC_PROTECTED 0x0004 @@ -329,18 +306,6 @@ void java_bytecode_parsert::rClassFile() parse_tree.loading_successful=true; } -/*******************************************************************\ - -Function: java_bytecode_parsert::get_class_refs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_parsert::get_class_refs() { // Get the class references for the benefit of a dependency @@ -383,18 +348,6 @@ void java_bytecode_parsert::get_class_refs() } } -/*******************************************************************\ - -Function: java_bytecode_parsert::get_class_refs_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_parsert::get_class_refs_rec(const typet &src) { if(src.id()==ID_code) @@ -427,18 +380,6 @@ void java_bytecode_parsert::get_class_refs_rec(const typet &src) get_class_refs_rec(src.subtype()); } -/*******************************************************************\ - -Function: java_bytecode_parsert::rconstant_pool - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_parsert::rconstant_pool() { u2 constant_pool_count=read_u2(); @@ -489,7 +430,7 @@ void java_bytecode_parsert::rconstant_pool() case CONSTANT_Long: case CONSTANT_Double: it->number=read_u8(); - // Eight-byte constants take up two entires + // Eight-byte constants take up two entries // in the constant_pool table, for annoying this programmer. if(it==constant_pool.end()) { @@ -658,18 +599,6 @@ void java_bytecode_parsert::rconstant_pool() } } -/*******************************************************************\ - -Function: java_bytecode_parsert::rinterfaces - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_parsert::rinterfaces(classt &parsed_class) { u2 interfaces_count=read_u2(); @@ -679,18 +608,6 @@ void java_bytecode_parsert::rinterfaces(classt &parsed_class) .push_back(constant(read_u2()).type().get(ID_C_base_name)); } -/*******************************************************************\ - -Function: java_bytecode_parsert::rfields - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_parsert::rfields(classt &parsed_class) { u2 fields_count=read_u2(); @@ -722,18 +639,6 @@ void java_bytecode_parsert::rfields(classt &parsed_class) } } -/*******************************************************************\ - -Function: java_bytecode_parsert::rbytecode - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - #define T_BOOLEAN 4 #define T_CHAR 5 #define T_FLOAT 6 @@ -798,7 +703,7 @@ void java_bytecode_parsert::rbytecode( case 'b': // a signed byte { s1 c=read_u1(); - instruction.args.push_back(from_integer(c, integer_typet())); + instruction.args.push_back(from_integer(c, signedbv_typet(8))); } address+=1; @@ -807,8 +712,8 @@ void java_bytecode_parsert::rbytecode( case 'o': // two byte branch offset, signed { s2 offset=read_u2(); - instruction - .args.push_back(from_integer(address+offset, integer_typet())); + instruction.args.push_back( + from_integer(address+offset, signedbv_typet(16))); } address+=2; break; @@ -816,8 +721,8 @@ void java_bytecode_parsert::rbytecode( case 'O': // four byte branch offset, signed { s4 offset=read_u4(); - instruction - .args.push_back(from_integer(address+offset, integer_typet())); + instruction.args.push_back( + from_integer(address+offset, signedbv_typet(32))); } address+=4; break; @@ -825,7 +730,7 @@ void java_bytecode_parsert::rbytecode( case 'v': // local variable index (one byte) { u1 v=read_u1(); - instruction.args.push_back(from_integer(v, integer_typet())); + instruction.args.push_back(from_integer(v, unsignedbv_typet(8))); } address+=1; break; @@ -835,17 +740,17 @@ void java_bytecode_parsert::rbytecode( if(wide_instruction) { u2 v=read_u2(); - instruction.args.push_back(from_integer(v, integer_typet())); + instruction.args.push_back(from_integer(v, unsignedbv_typet(16))); s2 c=read_u2(); - instruction.args.push_back(from_integer(c, integer_typet())); + instruction.args.push_back(from_integer(c, signedbv_typet(16))); address+=4; } else // local variable index (one byte) plus one signed byte { u1 v=read_u1(); - instruction.args.push_back(from_integer(v, integer_typet())); + instruction.args.push_back(from_integer(v, unsignedbv_typet(8))); s1 c=read_u1(); - instruction.args.push_back(from_integer(c, integer_typet())); + instruction.args.push_back(from_integer(c, signedbv_typet(8))); address+=2; } break; @@ -855,9 +760,9 @@ void java_bytecode_parsert::rbytecode( u2 c=read_u2(); instruction.args.push_back(constant(c)); u1 b1=read_u1(); - instruction.args.push_back(from_integer(b1, integer_typet())); + instruction.args.push_back(from_integer(b1, unsignedbv_typet(8))); u1 b2=read_u1(); - instruction.args.push_back(from_integer(b2, integer_typet())); + instruction.args.push_back(from_integer(b2, unsignedbv_typet(8))); } address+=4; break; @@ -871,8 +776,8 @@ void java_bytecode_parsert::rbytecode( // now default value s4 default_value=read_u4(); - instruction.args - .push_back(from_integer(base_offset+default_value, integer_typet())); + instruction.args.push_back( + from_integer(base_offset+default_value, signedbv_typet(32))); address+=4; // number of pairs @@ -883,9 +788,10 @@ void java_bytecode_parsert::rbytecode( { s4 match=read_u4(); s4 offset=read_u4(); - instruction.args.push_back(from_integer(match, integer_typet())); - instruction.args - .push_back(from_integer(base_offset+offset, integer_typet())); + instruction.args.push_back( + from_integer(match, signedbv_typet(32))); + instruction.args.push_back( + from_integer(base_offset+offset, signedbv_typet(32))); address+=8; } } @@ -900,8 +806,8 @@ void java_bytecode_parsert::rbytecode( // now default value s4 default_value=read_u4(); - instruction.args - .push_back(from_integer(base_offset+default_value, integer_typet())); + instruction.args.push_back( + from_integer(base_offset+default_value, signedbv_typet(32))); address+=4; // now low value @@ -916,9 +822,9 @@ void java_bytecode_parsert::rbytecode( for(s4 i=low_value; i<=high_value; i++) { s4 offset=read_u4(); - instruction.args.push_back(from_integer(i, integer_typet())); - instruction.args - .push_back(from_integer(base_offset+offset, integer_typet())); + instruction.args.push_back(from_integer(i, signedbv_typet(32))); + instruction.args.push_back( + from_integer(base_offset+offset, signedbv_typet(32))); address+=4; } } @@ -929,7 +835,8 @@ void java_bytecode_parsert::rbytecode( u2 c=read_u2(); // constant-pool index instruction.args.push_back(constant(c)); u1 dimensions=read_u1(); // number of dimensions - instruction.args.push_back(from_integer(dimensions, integer_typet())); + instruction.args.push_back( + from_integer(dimensions, unsignedbv_typet(8))); address+=3; } break; @@ -957,7 +864,7 @@ void java_bytecode_parsert::rbytecode( case 's': // a signed short { s2 s=read_u2(); - instruction.args.push_back(from_integer(s, integer_typet())); + instruction.args.push_back(from_integer(s, signedbv_typet(16))); } address+=2; break; @@ -975,18 +882,6 @@ void java_bytecode_parsert::rbytecode( } } -/*******************************************************************\ - -Function: java_bytecode_parsert::rmethod_attribute - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_parsert::rmethod_attribute(methodt &method) { u2 attribute_name_index=read_u2(); @@ -1055,18 +950,6 @@ void java_bytecode_parsert::rmethod_attribute(methodt &method) skip_bytes(attribute_length); } -/*******************************************************************\ - -Function: java_bytecode_parsert::rfield_attribute - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_parsert::rfield_attribute(fieldt &field) { u2 attribute_name_index=read_u2(); @@ -1083,18 +966,6 @@ void java_bytecode_parsert::rfield_attribute(fieldt &field) skip_bytes(attribute_length); } -/*******************************************************************\ - -Function: java_bytecode_parsert::rcode_attribute - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_parsert::rcode_attribute(methodt &method) { u2 attribute_name_index=read_u2(); @@ -1163,7 +1034,7 @@ void java_bytecode_parsert::rcode_attribute(methodt &method) for(size_t i=0; i #include #include #include "expr2java.h" -#include "java_bytecode_typecheck.h" - -/*******************************************************************\ - -Function: java_bytecode_typecheckt::to_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ std::string java_bytecode_typecheckt::to_string(const exprt &expr) { return expr2java(expr, ns); } -/*******************************************************************\ - -Function: java_bytecode_typecheckt::to_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string java_bytecode_typecheckt::to_string(const typet &type) { return type2java(type, ns); } -/*******************************************************************\ - -Function: java_bytecode_typecheckt::typecheck_non_type_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_typecheckt::typecheck_non_type_symbol(symbolt &symbol) { assert(!symbol.is_type); @@ -66,18 +34,6 @@ void java_bytecode_typecheckt::typecheck_non_type_symbol(symbolt &symbol) typecheck_expr(symbol.value); } -/*******************************************************************\ - -Function: java_bytecode_typecheckt::typecheck - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_typecheckt::typecheck() { // The hash table iterators are not stable, @@ -112,18 +68,6 @@ void java_bytecode_typecheckt::typecheck() } } -/*******************************************************************\ - -Function: java_bytecode_typecheck - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool java_bytecode_typecheck( symbol_tablet &symbol_table, message_handlert &message_handler, @@ -134,18 +78,6 @@ bool java_bytecode_typecheck( return java_bytecode_typecheck.typecheck_main(); } -/*******************************************************************\ - -Function: java_bytecode_typecheck - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool java_bytecode_typecheck( exprt &expr, message_handlert &message_handler, diff --git a/src/java_bytecode/java_bytecode_typecheck.h b/src/java_bytecode/java_bytecode_typecheck.h index 618b6fce44d..fa35ba5eda9 100644 --- a/src/java_bytecode/java_bytecode_typecheck.h +++ b/src/java_bytecode/java_bytecode_typecheck.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// JAVA Bytecode Language Type Checking + #ifndef CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_TYPECHECK_H #define CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_TYPECHECK_H diff --git a/src/java_bytecode/java_bytecode_typecheck_code.cpp b/src/java_bytecode/java_bytecode_typecheck_code.cpp index 788f5fa592b..431e39234f5 100644 --- a/src/java_bytecode/java_bytecode_typecheck_code.cpp +++ b/src/java_bytecode/java_bytecode_typecheck_code.cpp @@ -6,19 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "java_bytecode_typecheck.h" - -/*******************************************************************\ - -Function: java_bytecode_typecheckt::typecheck_code - - Inputs: +/// \file +/// JAVA Bytecode Conversion / Type Checking - Outputs: - - Purpose: - -\*******************************************************************/ +#include "java_bytecode_typecheck.h" void java_bytecode_typecheckt::typecheck_code(codet &code) { diff --git a/src/java_bytecode/java_bytecode_typecheck_expr.cpp b/src/java_bytecode/java_bytecode_typecheck_expr.cpp index 11e488ff7fe..c83ad680784 100644 --- a/src/java_bytecode/java_bytecode_typecheck_expr.cpp +++ b/src/java_bytecode/java_bytecode_typecheck_expr.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// JAVA Bytecode Conversion / Type Checking + +#include "java_bytecode_typecheck.h" + #include #include @@ -15,29 +20,20 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "java_bytecode_typecheck.h" #include "java_pointer_casts.h" #include "java_types.h" -/*******************************************************************\ - -Function: java_bytecode_typecheckt::typecheck_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_typecheckt::typecheck_expr(exprt &expr) { if(expr.id()==ID_code) return typecheck_code(to_code(expr)); - if(expr.id()==ID_typecast && expr.type().id()==ID_pointer) - expr=make_clean_pointer_cast(expr, expr.type(), ns); + if(expr.id()==ID_typecast && + expr.type().id()==ID_pointer) + expr=make_clean_pointer_cast( + expr, + to_pointer_type(expr.type()), + ns); // do operands recursively Forall_operands(it, expr) @@ -59,18 +55,6 @@ void java_bytecode_typecheckt::typecheck_expr(exprt &expr) typecheck_expr_member(to_member_expr(expr)); } -/*******************************************************************\ - -Function: java_bytecode_typecheckt::typecheck_expr_java_new - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_typecheckt::typecheck_expr_java_new(side_effect_exprt &expr) { assert(expr.operands().empty()); @@ -78,18 +62,6 @@ void java_bytecode_typecheckt::typecheck_expr_java_new(side_effect_exprt &expr) typecheck_type(type); } -/*******************************************************************\ - -Function: java_bytecode_typecheckt::typecheck_expr_java_new_array - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_typecheckt::typecheck_expr_java_new_array( side_effect_exprt &expr) { @@ -117,18 +89,9 @@ static std::string escape_non_alnum(const std::string &toescape) return escaped.str(); } -/*******************************************************************\ - -Function: utf16_to_array - - Inputs: `in`: wide string to convert - - Outputs: Returns a Java char array containing the same wchars. - - Purpose: Convert UCS-2 or UTF-16 to an array expression. - -\*******************************************************************/ - +/// Convert UCS-2 or UTF-16 to an array expression. +/// \par parameters: `in`: wide string to convert +/// \return Returns a Java char array containing the same wchars. static array_exprt utf16_to_array(const std::wstring &in) { const auto jchar=java_char_type(); @@ -138,18 +101,6 @@ static array_exprt utf16_to_array(const std::wstring &in) return ret; } -/*******************************************************************\ - -Function: java_bytecode_typecheckt::typecheck_expr_java_string_literal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_typecheckt::typecheck_expr_java_string_literal(exprt &expr) { const irep_idt value=expr.get(ID_value); @@ -264,18 +215,6 @@ void java_bytecode_typecheckt::typecheck_expr_java_string_literal(exprt &expr) expr=address_of_exprt(new_symbol.symbol_expr()); } -/*******************************************************************\ - -Function: java_bytecode_typecheckt::typecheck_expr_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_typecheckt::typecheck_expr_symbol(symbol_exprt &expr) { irep_idt identifier=expr.get_identifier(); @@ -324,18 +263,6 @@ void java_bytecode_typecheckt::typecheck_expr_symbol(symbol_exprt &expr) } } -/*******************************************************************\ - -Function: java_bytecode_typecheckt::typecheck_expr_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_typecheckt::typecheck_expr_member(member_exprt &expr) { // The member might be in a parent class or an opaque class, which we resolve diff --git a/src/java_bytecode/java_bytecode_typecheck_type.cpp b/src/java_bytecode/java_bytecode_typecheck_type.cpp index 647aa35a45e..aa92d9333cf 100644 --- a/src/java_bytecode/java_bytecode_typecheck_type.cpp +++ b/src/java_bytecode/java_bytecode_typecheck_type.cpp @@ -6,21 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// JAVA Bytecode Conversion / Type Checking #include "java_bytecode_typecheck.h" -/*******************************************************************\ - -Function: java_bytecode_typecheckt::typecheck_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void java_bytecode_typecheckt::typecheck_type(typet &type) { @@ -62,18 +53,6 @@ void java_bytecode_typecheckt::typecheck_type(typet &type) } } -/*******************************************************************\ - -Function: java_bytecode_typecheckt::typecheck_type_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_bytecode_typecheckt::typecheck_type_symbol(symbolt &symbol) { assert(symbol.is_type); diff --git a/src/java_bytecode/java_bytecode_vtable.cpp b/src/java_bytecode/java_bytecode_vtable.cpp index d70225d9beb..68da4c6b494 100644 --- a/src/java_bytecode/java_bytecode_vtable.cpp +++ b/src/java_bytecode/java_bytecode_vtable.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "java_bytecode_vtable.h" + #include #include @@ -16,8 +18,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "java_bytecode_vtable.h" - const char ID_virtual_name[]="virtual_name"; class is_virtual_name_equalt @@ -118,7 +118,7 @@ class java_bytecode_vtable_factoryt struct_typet::componentt entry_component; entry_component.set_name(ifc_name); entry_component.set_base_name(ifc_method->get_base_name()); - entry_component.type()=pointer_typet(implementation.type()); + entry_component.type()=pointer_type(implementation.type()); vtable_type.components().push_back(entry_component); const irep_idt &impl_name(implementation.get_name()); @@ -288,7 +288,7 @@ static void add_vtable_pointer_member( { struct_typet::componentt comp; - comp.type()=pointer_typet(symbol_typet(vt_name)); + comp.type()=pointer_type(symbol_typet(vt_name)); comp.set_name(ID_vtable_pointer); comp.set_base_name(ID_vtable_pointer); comp.set_pretty_name(ID_vtable_pointer); @@ -391,7 +391,7 @@ static exprt get_ref( if(ID_symbol==type_id) return get_ref(address_of_exprt(this_obj), target_type); assert(ID_pointer==type_id); - const typecast_exprt cast(this_obj, pointer_typet(target_type)); + const typecast_exprt cast(this_obj, pointer_type(target_type)); return dereference_exprt(cast, target_type); } @@ -436,13 +436,13 @@ exprt make_vtable_function( } const symbol_typet vtable_type(vtnamest::get_type(class_id)); - const pointer_typet vt_ptr_type(vtable_type); + const pointer_typet vt_ptr_type=pointer_type(vtable_type); const symbol_typet target_type(class_id); const exprt this_ref(get_ref(this_obj, target_type)); const typet ref_type(this_ref.type()); const member_exprt vtable_member(this_ref, ID_vtable_pointer, vt_ptr_type); const dereference_exprt vtable(vtable_member, vtable_type); // TODO: cast? - const pointer_typet func_ptr_type(func.type()); + const pointer_typet func_ptr_type=pointer_type(func.type()); const member_exprt func_ptr(vtable, func_name, func_ptr_type); const dereference_exprt virtual_func(func_ptr, func.type()); return virtual_func; diff --git a/src/java_bytecode/java_bytecode_vtable.h b/src/java_bytecode/java_bytecode_vtable.h index 3e33d408a6e..44a7f35bf1b 100644 --- a/src/java_bytecode/java_bytecode_vtable.h +++ b/src/java_bytecode/java_bytecode_vtable.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_VTABLE_H #define CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_VTABLE_H diff --git a/src/java_bytecode/java_class_loader.cpp b/src/java_bytecode/java_class_loader.cpp index fdd37c4b312..6b720f05fb6 100644 --- a/src/java_bytecode/java_class_loader.cpp +++ b/src/java_bytecode/java_class_loader.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "java_class_loader.h" + #include #include #include @@ -15,21 +17,8 @@ Author: Daniel Kroening, kroening@kroening.com #include #include "java_bytecode_parser.h" -#include "java_class_loader.h" #include "jar_file.h" -/*******************************************************************\ - -Function: java_class_loadert::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - java_bytecode_parse_treet &java_class_loadert::operator()( const irep_idt &class_name) { @@ -72,18 +61,6 @@ java_bytecode_parse_treet &java_class_loadert::operator()( return class_map[class_name]; } -/*******************************************************************\ - -Function: java_class_loadert::set_java_cp_include_files - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_class_loadert::set_java_cp_include_files( std::string &_java_cp_include_files) { @@ -91,18 +68,6 @@ void java_class_loadert::set_java_cp_include_files( jar_pool.set_message_handler(get_message_handler()); } -/*******************************************************************\ - -Function: java_class_loadert::get_parse_tree - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - java_bytecode_parse_treet &java_class_loadert::get_parse_tree( java_class_loader_limitt &class_loader_limit, const irep_idt &class_name) @@ -196,18 +161,6 @@ java_bytecode_parse_treet &java_class_loadert::get_parse_tree( return parse_tree; } -/*******************************************************************\ - -Function: java_class_loadert::load_entire_jar - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_class_loadert::load_entire_jar( java_class_loader_limitt &class_loader_limit, const std::string &file) @@ -224,18 +177,6 @@ void java_class_loadert::load_entire_jar( jar_files.pop_front(); } -/*******************************************************************\ - -Function: java_class_loadert::read_jar_file - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_class_loadert::read_jar_file( java_class_loader_limitt &class_loader_limit, const irep_idt &file) @@ -271,18 +212,6 @@ void java_class_loadert::read_jar_file( } } -/*******************************************************************\ - -Function: java_class_loadert::file_to_class_name - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string java_class_loadert::file_to_class_name(const std::string &file) { std::string result=file; @@ -310,18 +239,6 @@ std::string java_class_loadert::file_to_class_name(const std::string &file) return result; } -/*******************************************************************\ - -Function: java_class_loadert::class_name_to_file - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string java_class_loadert::class_name_to_file(const irep_idt &class_name) { std::string result=id2string(class_name); diff --git a/src/java_bytecode/java_class_loader.h b/src/java_bytecode/java_class_loader.h index c4676ff31f0..f6996fb2efd 100644 --- a/src/java_bytecode/java_class_loader.h +++ b/src/java_bytecode/java_class_loader.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_JAVA_BYTECODE_JAVA_CLASS_LOADER_H #define CPROVER_JAVA_BYTECODE_JAVA_CLASS_LOADER_H diff --git a/src/java_bytecode/java_class_loader_limit.cpp b/src/java_bytecode/java_class_loader_limit.cpp index 3a9ed66d3d5..38b9f9f6c41 100644 --- a/src/java_bytecode/java_class_loader_limit.cpp +++ b/src/java_bytecode/java_class_loader_limit.cpp @@ -6,24 +6,17 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// limit class path loading #include "java_class_loader_limit.h" -/*******************************************************************\ - -Function: java_class_loader_limitt::setup_class_load_limit - - Inputs: parameter from `java-cp-include-files` - - Outputs: - - Purpose: initializes class with either regex matcher or match set - -\*******************************************************************/ +#include +/// initializes class with either regex matcher or match set +/// \par parameters: parameter from `java-cp-include-files` void java_class_loader_limitt::setup_class_load_limit( - std::string &java_cp_include_files) + const std::string &java_cp_include_files) { if(java_cp_include_files.empty()) throw "class regexp cannot be empty"; @@ -54,18 +47,8 @@ void java_class_loader_limitt::setup_class_load_limit( } } -/*******************************************************************\ - -Function: java_class_loader_limitt::load_class_file - - Inputs: class file name - - Outputs: true if file should be loaded, else false - - Purpose: - -\*******************************************************************/ - +/// \par parameters: class file name +/// \return true if file should be loaded, else false bool java_class_loader_limitt::load_class_file(const irep_idt &file_name) { if(regex_match) diff --git a/src/java_bytecode/java_class_loader_limit.h b/src/java_bytecode/java_class_loader_limit.h index fa5e21ffd95..a9a9fb33579 100644 --- a/src/java_bytecode/java_class_loader_limit.h +++ b/src/java_bytecode/java_class_loader_limit.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// limit class path loading + #ifndef CPROVER_JAVA_BYTECODE_JAVA_CLASS_LOADER_LIMIT_H #define CPROVER_JAVA_BYTECODE_JAVA_CLASS_LOADER_LIMIT_H @@ -22,16 +25,18 @@ class java_class_loader_limitt:public messaget bool regex_match; std::smatch string_matcher; - void setup_class_load_limit(std::string &); - public: + void setup_class_load_limit(const std::string &); + +public: explicit java_class_loader_limitt( message_handlert &_message_handler, - std::string &java_cp_include_files) : - messaget(_message_handler), + const std::string &java_cp_include_files): + messaget(_message_handler), regex_match(false) { setup_class_load_limit(java_cp_include_files); } + bool load_class_file(const irep_idt &class_file_name); }; diff --git a/src/java_bytecode/java_entry_point.cpp b/src/java_bytecode/java_entry_point.cpp index 1de7a09f227..72414955785 100644 --- a/src/java_bytecode/java_entry_point.cpp +++ b/src/java_bytecode/java_entry_point.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "java_entry_point.h" + #include #include #include @@ -22,30 +24,16 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include +#include #include -#include #include -#include "java_entry_point.h" #include "java_object_factory.h" #include "java_types.h" #define INITIALIZE CPROVER_PREFIX "initialize" -/*******************************************************************\ - -Function: create_initialize - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static void create_initialize(symbol_tablet &symbol_table) { symbolt initialize; @@ -86,22 +74,9 @@ static bool should_init_symbol(const symbolt &sym) return has_prefix(id2string(sym.name), "java::java.lang.String.Literal"); } -/*******************************************************************\ - -Function: java_static_lifetime_init - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -bool java_static_lifetime_init( +void java_static_lifetime_init( symbol_tablet &symbol_table, const source_locationt &source_location, - message_handlert &message_handler, bool assume_init_pointers_not_null, unsigned max_nondet_array_length) { @@ -138,6 +113,7 @@ bool java_static_lifetime_init( } auto newsym=object_factory( sym.type, + symname, code_block, allow_null, symbol_table, @@ -173,29 +149,14 @@ bool java_static_lifetime_init( code_block.add(function_call); } } - - return false; } -/*******************************************************************\ - -Function: java_build_arguments - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt::operandst java_build_arguments( const symbolt &function, code_blockt &init_code, symbol_tablet &symbol_table, bool assume_init_pointers_not_null, - unsigned max_nondet_array_length, - message_handlert &message_handler) + unsigned max_nondet_array_length) { const code_typet::parameterst ¶meters= to_code_type(function.type).parameters(); @@ -224,27 +185,29 @@ exprt::operandst java_build_arguments( is_main=(named_main && has_correct_type); } + const code_typet::parametert &p=parameters[param_number]; + const irep_idt base_name=p.get_base_name().empty()? + ("argument#"+std::to_string(param_number)):p.get_base_name(); + bool allow_null=(!is_main) && (!is_this) && !assume_init_pointers_not_null; main_arguments[param_number]= object_factory( - parameters[param_number].type(), + p.type(), + base_name, init_code, allow_null, symbol_table, max_nondet_array_length, function.location); - const symbolt &p_symbol= - symbol_table.lookup(parameters[param_number].get_identifier()); - // record as an input codet input(ID_input); input.operands().resize(2); input.op0()= address_of_exprt( index_exprt( - string_constantt(p_symbol.base_name), + string_constantt(base_name), from_integer(0, index_type()))); input.op1()=main_arguments[param_number]; input.add_source_location()=function.location; @@ -255,18 +218,6 @@ exprt::operandst java_build_arguments( return main_arguments; } -/*******************************************************************\ - -Function: java_record_outputs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void java_record_outputs( const symbolt &function, const exprt::operandst &main_arguments, @@ -514,24 +465,14 @@ main_function_resultt get_main_symbol( return res; // give up with error } -/*******************************************************************\ - -Function: java_entry_point - - Inputs: - symbol_table - main class - message_handler - assume_init_pointers_not_null - allow pointers in initialization code to be - null - max_nondet_array_length - - Outputs: true if error occurred on entry point search - - Purpose: find entry point and create initialization code for function - -\*******************************************************************/ - +/// find entry point and create initialization code for function +/// symbol_table +/// main class +/// message_handler +/// \param assume_init_pointers_not_null: allow pointers in initialization code +/// to be null +/// max_nondet_array_length +/// \return true if error occurred on entry point search bool java_entry_point( symbol_tablet &symbol_table, const irep_idt &main_class, @@ -556,13 +497,11 @@ bool java_entry_point( create_initialize(symbol_table); - if(java_static_lifetime_init( - symbol_table, - symbol.location, - message_handler, - assume_init_pointers_not_null, - max_nondet_array_length)) - return true; + java_static_lifetime_init( + symbol_table, + symbol.location, + assume_init_pointers_not_null, + max_nondet_array_length); code_blockt init_code; @@ -617,7 +556,7 @@ bool java_entry_point( exc_symbol.is_static_lifetime=false; exc_symbol.name=id2string(symbol.name)+EXC_SUFFIX; exc_symbol.base_name=id2string(symbol.name)+EXC_SUFFIX; - exc_symbol.type=typet(ID_pointer, empty_typet()); + exc_symbol.type=java_reference_type(empty_typet()); symbol_table.add(exc_symbol); exprt::operandst main_arguments= @@ -626,8 +565,7 @@ bool java_entry_point( init_code, symbol_table, assume_init_pointers_not_null, - max_nondet_array_length, - message_handler); + max_nondet_array_length); call_main.arguments()=main_arguments; init_code.move_to_operands(call_main); diff --git a/src/java_bytecode/java_entry_point.h b/src/java_bytecode/java_entry_point.h index e6575734d80..e2d2fa3f41b 100644 --- a/src/java_bytecode/java_entry_point.h +++ b/src/java_bytecode/java_entry_point.h @@ -6,10 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_JAVA_BYTECODE_JAVA_ENTRY_POINT_H #define CPROVER_JAVA_BYTECODE_JAVA_ENTRY_POINT_H #include +#include bool java_entry_point( class symbol_tablet &symbol_table, diff --git a/src/java_bytecode/java_local_variable_table.cpp b/src/java_bytecode/java_local_variable_table.cpp index 85e9766d5ab..70b2568476a 100644 --- a/src/java_bytecode/java_local_variable_table.cpp +++ b/src/java_bytecode/java_local_variable_table.cpp @@ -6,9 +6,15 @@ Author: Chris Smowton, chris.smowton@diffblue.com \*******************************************************************/ +/// \file +/// Java local variable table processing + #include "java_bytecode_convert_method_class.h" + #include "java_types.h" +#include +#include #include #include @@ -88,7 +94,7 @@ struct procedure_local_cfg_baset< } }; -// Grab some class typdefs for brevity: +// Grab some class typedefs for brevity: typedef java_bytecode_convert_methodt::holet holet; typedef java_bytecode_convert_methodt::local_variable_with_holest @@ -141,20 +147,11 @@ struct is_predecessor_oft // Helper routines for the find-initialisers code below: -/*******************************************************************\ - -Function: gather_transitive_predecessors - - Inputs: `start`: Variable to find the predecessors of - `predecessor_map`: Map from local variables - to sets of predecessors - Outputs: `result`: populated with all transitive predecessors of - `start` found in `predecessor_map` - - Purpose: See above - -\*******************************************************************/ - +/// See above +/// `start`: Variable to find the predecessors of `predecessor_map`: Map from +/// local variables to sets of predecessors +/// \param Outputs: `result`: populated with all transitive predecessors of +/// `start` found in `predecessor_map` static void gather_transitive_predecessors( local_variable_with_holest *start, const predecessor_mapt &predecessor_map, @@ -169,20 +166,11 @@ static void gather_transitive_predecessors( gather_transitive_predecessors(pred, predecessor_map, result); } -/*******************************************************************\ - -Function: is_store_to_slot - - Inputs: `inst`: Java bytecode instruction - `slotidx`: local variable slot number - - Outputs: Returns true if `inst` is any form of store instruction - targeting slot `slotidx` - - Purpose: See above - -\*******************************************************************/ - +/// See above +/// \par parameters: `inst`: Java bytecode instruction +/// `slotidx`: local variable slot number +/// \return Returns true if `inst` is any form of store instruction targeting +/// slot `slotidx` static bool is_store_to_slot( const java_bytecode_convert_methodt::instructiont &inst, unsigned slotidx) @@ -191,37 +179,29 @@ static bool is_store_to_slot( if(!(prevstatement.size()>=1 && prevstatement.substr(1, 5)=="store")) return false; - std::string storeslot; + unsigned storeslotidx; if(inst.args.size()==1) { // Store with an argument: const auto &arg=inst.args[0]; - storeslot=id2string(to_constant_expr(arg).get_value()); + bool ret=to_unsigned_integer(to_constant_expr(arg), storeslotidx); + CHECK_RETURN(!ret); } else { // Store shorthands, like "store_0", "store_1" assert(prevstatement[6]=='_' && prevstatement.size()==8); - storeslot=prevstatement[7]; + std::string storeslot(1, prevstatement[7]); assert(isdigit(storeslot[0])); + storeslotidx=safe_string2unsigned(storeslot); } - auto storeslotidx=safe_string2unsigned(storeslot); return storeslotidx==slotidx; } -/*******************************************************************\ - -Function: maybe_add_hole - - Inputs: `from`, `to`: bounds of a gap in `var`'s live range, - inclusive and exclusive respectively - - Outputs: Adds a hole to `var`, unless it would be of zero size. - - Purpose: See above - -\*******************************************************************/ - +/// See above +/// \par parameters: `from`, `to`: bounds of a gap in `var`'s live range, +/// inclusive and exclusive respectively +/// \return Adds a hole to `var`, unless it would be of zero size. static void maybe_add_hole( local_variable_with_holest &var, unsigned from, @@ -232,22 +212,13 @@ static void maybe_add_hole( var.holes.push_back({from, to-from}); } -/*******************************************************************\ - -Function: populate_variable_address_map - - Inputs: `firstvar`-`varlimit`: range of local variable table - entries to consider - - Outputs: `live_variable_at_address` is populated with a sequence of - local variable table entry pointers, such that - `live_variable_at_address[addr]` yields the unique table - entry covering that address. Asserts if entries overlap. - - Purpose: See above - -\*******************************************************************/ - +/// See above +/// \par parameters: `firstvar`-`varlimit`: range of local variable table +/// entries to consider +/// \return `live_variable_at_address` is populated with a sequence of local +/// variable table entry pointers, such that `live_variable_at_address[addr]` +/// yields the unique table entry covering that address. Asserts if entries +/// overlap. static void populate_variable_address_map( local_variable_table_with_holest::iterator firstvar, local_variable_table_with_holest::iterator varlimit, @@ -269,32 +240,20 @@ static void populate_variable_address_map( } } -/*******************************************************************\ - -Function: populate_predecessor_map - - Inputs: `firstvar`-`varlimit`: range of local variable table - entries to consider - `live_variable_at_address`: map from bytecode address - to table entry (drawn from firstvar-varlimit) live - at that address - `amap`: map from bytecode address to instructions - - Outputs: Populates `predecessor_map` with a graph from local variable - table entries to their predecessors (table entries which - may flow together and thus may be considered the same live - range). - - Purpose: Usually a live variable range begins with a store - instruction initialising the relevant local variable slot, - but instead of or in addition to this, control flow edges - may exist from bytecode addresses that fall under a - table entry which differs, but which has the same variable - name and type descriptor. This indicates a split live - range, and will be recorded in the predecessor map. - -\*******************************************************************/ - +/// Usually a live variable range begins with a store instruction initialising +/// the relevant local variable slot, but instead of or in addition to this, +/// control flow edges may exist from bytecode addresses that fall under a table +/// entry which differs, but which has the same variable name and type +/// descriptor. This indicates a split live range, and will be recorded in the +/// predecessor map. +/// \par parameters: `firstvar`-`varlimit`: range of local variable table +/// entries to consider +/// `live_variable_at_address`: map from bytecode address to table entry (drawn +/// from firstvar-varlimit) live at that address +/// `amap`: map from bytecode address to instructions +/// \return Populates `predecessor_map` with a graph from local variable table +/// entries to their predecessors (table entries which may flow together and +/// thus may be considered the same live range). static void populate_predecessor_map( local_variable_table_with_holest::iterator firstvar, local_variable_table_with_holest::iterator varlimit, @@ -332,7 +291,7 @@ static void populate_predecessor_map( auto pred_var= (pred &merge_vars, const java_cfg_dominatorst &dominator_analysis) @@ -460,24 +409,14 @@ static unsigned get_common_dominator( throw "variable live ranges with no common dominator?"; } -/*******************************************************************\ - -Function: populate_live_range_holes - - Inputs: `merge_vars`: a set of 2+ variable table entries to merge - `expanded_live_range_start`: address where the merged - variable will be declared - - Outputs: Adds holes to `merge_into`, indicating where gaps in the - variable's live range fall. For example, if the - declaration happens at address 10 and the entries in - `merge_into` have live ranges [(20-30), (40-50)] then - holes will be added at (10-20) and (30-40). - - Purpose: See above - -\*******************************************************************/ - +/// See above +/// \par parameters: `merge_vars`: a set of 2+ variable table entries to merge +/// `expanded_live_range_start`: address where the merged variable will be +/// declared +/// \return Adds holes to `merge_into`, indicating where gaps in the variable's +/// live range fall. For example, if the declaration happens at address 10 and +/// the entries in `merge_into` have live ranges [(20-30), (40-50)] then holes +/// will be added at (10-20) and (30-40). static void populate_live_range_holes( local_variable_with_holest &merge_into, const std::set &merge_vars, @@ -500,22 +439,13 @@ static void populate_live_range_holes( } } -/*******************************************************************\ - -Function: merge_variable_table_entries - - Inputs: `merge_vars`: a set of 2+ variable table entries to merge - `dominator_analysis`: already-calculated dominator tree - - Outputs: Populates `merge_into` as a combined variable table entry, - with live range holes if the `merge_vars` entries do not - cover a contiguous address range, beginning the combined - live range at the common dominator of all `merge_vars`. - - Purpose: See above - -\*******************************************************************/ - +/// See above +/// \par parameters: `merge_vars`: a set of 2+ variable table entries to merge +/// `dominator_analysis`: already-calculated dominator tree +/// \return Populates `merge_into` as a combined variable table entry, with live +/// range holes if the `merge_vars` entries do not cover a contiguous address +/// range, beginning the combined live range at the common dominator of all +/// `merge_vars`. static void merge_variable_table_entries( local_variable_with_holest &merge_into, const std::set &merge_vars, @@ -559,28 +489,17 @@ static void merge_variable_table_entries( v->var.length=0; } -/*******************************************************************\ - -Function: find_initialisers_for_slot - - Inputs: `firstvar`-`varlimit`: sequence of variable table entries, - all of which should concern the same slot index. - `amap`: Map from bytecode address to instruction - - Outputs: Side-effect: merges variable table entries which flow into - one another (e.g. there are branches from one live range - to another without re-initialising the local slot). - - Purpose: Given a sequence of users of the same local variable slot, - this figures out which ones are related by control flow, - and combines them into a single entry with holes, such that - after combination we can create a single - declaration per variable table entry, - placed at the live range's start address, which may - be moved back so that the declaration dominates all uses. - -\*******************************************************************/ - +/// Given a sequence of users of the same local variable slot, this figures out +/// which ones are related by control flow, and combines them into a single +/// entry with holes, such that after combination we can create a single +/// declaration per variable table entry, placed at the live range's start +/// address, which may be moved back so that the declaration dominates all uses. +/// \par parameters: `firstvar`-`varlimit`: sequence of variable table entries, +/// all of which should concern the same slot index. +/// `amap`: Map from bytecode address to instruction +/// \return Side-effect: merges variable table entries which flow into one +/// another (e.g. there are branches from one live range to another without +/// re-initialising the local slot). void java_bytecode_convert_methodt::find_initialisers_for_slot( local_variable_table_with_holest::iterator firstvar, local_variable_table_with_holest::iterator varlimit, @@ -647,23 +566,13 @@ void java_bytecode_convert_methodt::find_initialisers_for_slot( } } -/*******************************************************************\ - -Function: walk_to_next_index - - Inputs: `it1` and `it2`, which are iterators into the same vector, - of which `itend` is the end() iterator. - - Outputs: Moves `it1` and `it2` to delimit a sequence of variable - table entries with slot index equal to it2->var.index - on entering this function, or to both equal itend if - it2==itend on entry. - - Purpose: Walk a vector, a contiguous block of entries with equal - slot index at a time. - -\*******************************************************************/ - +/// Walk a vector, a contiguous block of entries with equal slot index at a +/// time. +/// \par parameters: `it1` and `it2`, which are iterators into the same vector, +/// of which `itend` is the end() iterator. +/// \return Moves `it1` and `it2` to delimit a sequence of variable table +/// entries with slot index equal to it2->var.index on entering this function, +/// or to both equal itend if it2==itend on entry. static void walk_to_next_index( local_variable_table_with_holest::iterator &it1, local_variable_table_with_holest::iterator &it2, @@ -682,21 +591,12 @@ static void walk_to_next_index( it1=old_it2; } -/*******************************************************************\ - -Function: find_initialisers - - Inputs: `vars`: Local variable table - `amap`: Map from bytecode index to instruction - `dominator_analysis`: Already computed dominator tree for - the Java function described by `amap` - - Outputs: Combines entries in `vars` which flow together - - Purpose: See `find_initialisers_for_slot` above for more detail. - -\*******************************************************************/ - +/// See `find_initialisers_for_slot` above for more detail. +/// \par parameters: `vars`: Local variable table +/// `amap`: Map from bytecode index to instruction +/// `dominator_analysis`: Already computed dominator tree for the Java function +/// described by `amap` +/// \return Combines entries in `vars` which flow together void java_bytecode_convert_methodt::find_initialisers( local_variable_table_with_holest &vars, const address_mapt &amap, @@ -715,18 +615,9 @@ void java_bytecode_convert_methodt::find_initialisers( find_initialisers_for_slot(it1, it2, amap, dominator_analysis); } -/*******************************************************************\ - -Function: cleanup_var_table - - Inputs: `vars_with_holes`: variable table - - Outputs: Removes zero-size entries from `vars_with_holes` - - Purpose: See above - -\*******************************************************************/ - +/// See above +/// \par parameters: `vars_with_holes`: variable table +/// \return Removes zero-size entries from `vars_with_holes` static void cleanup_var_table( std::vector &vars_with_holes) { @@ -749,22 +640,12 @@ static void cleanup_var_table( vars_with_holes.resize(vars_with_holes.size()-toremove); } -/*******************************************************************\ - -Function: setup_local_variables - - Inputs: `m`: Java method - `amap`: Map from bytecode indices to instructions in `m` - - Outputs: Populates `this->vars_with_holes` equal to - `this->local_variable_table`, only with variable table - entries that flow together combined. - Also symbol-table registers all locals. - - Purpose: See `find_initialisers_for_slot` above for more detail. - -\*******************************************************************/ - +/// See `find_initialisers_for_slot` above for more detail. +/// \par parameters: `m`: Java method +/// `amap`: Map from bytecode indices to instructions in `m` +/// \return Populates `this->vars_with_holes` equal to +/// `this->local_variable_table`, only with variable table entries that flow +/// together combined. Also symbol-table registers all locals. void java_bytecode_convert_methodt::setup_local_variables( const methodt &m, const address_mapt &amap) @@ -827,22 +708,12 @@ void java_bytecode_convert_methodt::setup_local_variables( } } -/*******************************************************************\ - -Function: find_variable_for_slot - - Inputs: `address`: Address to find a variable table entry for - `var_list`: List of candidates that use the slot we're - interested in - - Outputs: Returns the list entry covering this address (taking live - range holes into account), or creates/returns an anonymous - variable entry if nothing covers `address`. - - Purpose: See above - -\*******************************************************************/ - +/// See above +/// \par parameters: `address`: Address to find a variable table entry for +/// `var_list`: List of candidates that use the slot we're interested in +/// \return Returns the list entry covering this address (taking live range +/// holes into account), or creates/returns an anonymous variable entry if +/// nothing covers `address`. const java_bytecode_convert_methodt::variablet & java_bytecode_convert_methodt::find_variable_for_slot( size_t address, diff --git a/src/java_bytecode/java_object_factory.cpp b/src/java_bytecode/java_object_factory.cpp index 34f5495bb85..a903483aa4c 100644 --- a/src/java_bytecode/java_object_factory.cpp +++ b/src/java_bytecode/java_object_factory.cpp @@ -6,12 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "java_object_factory.h" + #include #include #include #include -#include +#include #include #include #include @@ -20,22 +22,11 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "java_object_factory.h" +#include + #include "java_types.h" #include "java_utils.h" -/*******************************************************************\ - -Function: new_tmp_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static symbolt &new_tmp_symbol( symbol_tablet &symbol_table, const source_locationt &loc, @@ -51,18 +42,8 @@ static symbolt &new_tmp_symbol( symbol_table); } -/*******************************************************************\ - -Function: get_nondet_bool - - Inputs: Desired type (C_bool or plain bool) - - Outputs: nondet expr of that type - - Purpose: - -\*******************************************************************/ - +/// \par parameters: Desired type (C_bool or plain bool) +/// \return nondet expr of that type static exprt get_nondet_bool(const typet &type) { // We force this to 0 and 1 and won't consider @@ -72,20 +53,39 @@ static exprt get_nondet_bool(const typet &type) class java_object_factoryt { - code_blockt &init_code; + std::vector &symbols_created; + const source_locationt &loc; std::unordered_set recursion_set; bool assume_non_null; size_t max_nondet_array_length; symbol_tablet &symbol_table; namespacet ns; + code_assignt get_null_assignment( + const exprt &expr, + const pointer_typet &ptr_type); + + void gen_pointer_target_init( + code_blockt &assignments, + const exprt &expr, + const typet &target_type, + bool create_dynamic_objects); + + void allocate_nondet_length_array( + code_blockt &assignments, + const exprt &lhs, + const exprt &max_length_expr, + const typet &element_type); + public: java_object_factoryt( - code_blockt &_init_code, + std::vector &_symbols_created, + const source_locationt &loc, bool _assume_non_null, size_t _max_nondet_array_length, symbol_tablet &_symbol_table): - init_code(_init_code), + symbols_created(_symbols_created), + loc(loc), assume_non_null(_assume_non_null), max_nondet_array_length(_max_nondet_array_length), symbol_table(_symbol_table), @@ -93,39 +93,50 @@ class java_object_factoryt {} exprt allocate_object( + code_blockt &assignments, const exprt &, const typet &, - const source_locationt &, bool create_dynamic_objects); - void gen_nondet_array_init(const exprt &expr, const source_locationt &); + void gen_nondet_array_init( + code_blockt &assignments, + const exprt &expr); void gen_nondet_init( + code_blockt &assignments, const exprt &expr, bool is_sub, irep_idt class_identifier, - const source_locationt &loc, bool create_dynamic_objects, bool override=false, const typet &override_type=empty_typet()); -}; - -/*******************************************************************\ - -Function: java_object_factoryt::allocate_object - - Inputs: - Outputs: - - Purpose: +private: + void gen_nondet_pointer_init( + code_blockt &assignments, + const exprt &expr, + const irep_idt &class_identifier, + bool create_dynamic_objects, + const pointer_typet &pointer_type); -\*******************************************************************/ + void gen_nondet_struct_init( + code_blockt &assignments, + const exprt &expr, + bool is_sub, + irep_idt class_identifier, + bool create_dynamic_objects, + const struct_typet &struct_type); +}; +/// \param assignments: The code block to add code to +/// \param target_expr: The expression which we are allocating a symbol for +/// \param allocate_type: +/// \param create_dynamic_objects: Whether to create a symbol with static +/// lifetime or exprt java_object_factoryt::allocate_object( + code_blockt &assignments, const exprt &target_expr, const typet &allocate_type, - const source_locationt &loc, bool create_dynamic_objects) { const typet &allocate_type_resolved=ns.follow(allocate_type); @@ -134,7 +145,7 @@ exprt java_object_factoryt::allocate_object( if(!create_dynamic_objects) { symbolt &aux_symbol=new_tmp_symbol(symbol_table, loc, allocate_type); - aux_symbol.is_static_lifetime=true; + symbols_created.push_back(&aux_symbol); exprt object=aux_symbol.symbol_expr(); exprt aoe=address_of_exprt(object); @@ -142,7 +153,7 @@ exprt java_object_factoryt::allocate_object( aoe=typecast_exprt(aoe, target_expr.type()); code_assignt code(target_expr, aoe); code.add_source_location()=loc; - init_code.copy_to_operands(code); + assignments.copy_to_operands(code); return aoe; } else @@ -156,7 +167,7 @@ exprt java_object_factoryt::allocate_object( // malloc expression exprt malloc_expr=side_effect_exprt(ID_malloc); malloc_expr.copy_to_operands(object_size); - typet result_type=pointer_typet(allocate_type); + typet result_type=pointer_type(allocate_type); malloc_expr.type()=result_type; // Create a symbol for the malloc expression so we can initialize // without having to do it potentially through a double-deref, which @@ -164,18 +175,19 @@ exprt java_object_factoryt::allocate_object( symbolt &malloc_sym=new_tmp_symbol( symbol_table, loc, - pointer_typet(allocate_type), + pointer_type(allocate_type), "malloc_site"); + symbols_created.push_back(&malloc_sym); code_assignt assign=code_assignt(malloc_sym.symbol_expr(), malloc_expr); code_assignt &malloc_assign=assign; malloc_assign.add_source_location()=loc; - init_code.copy_to_operands(malloc_assign); + assignments.copy_to_operands(malloc_assign); malloc_expr=malloc_sym.symbol_expr(); if(cast_needed) malloc_expr=typecast_exprt(malloc_expr, target_expr.type()); code_assignt code(target_expr, malloc_expr); code.add_source_location()=loc; - init_code.copy_to_operands(code); + assignments.copy_to_operands(code); return malloc_sym.symbol_expr(); } else @@ -184,223 +196,296 @@ exprt java_object_factoryt::allocate_object( null_pointer_exprt null_pointer_expr(to_pointer_type(target_expr.type())); code_assignt code(target_expr, null_pointer_expr); code.add_source_location()=loc; - init_code.copy_to_operands(code); + assignments.copy_to_operands(code); return exprt(); } } } -/*******************************************************************\ +/// Adds an instruction to `init_code` null-initialising `expr`. +/// \par parameters: `expr`: pointer-typed lvalue expression to initialise +/// `ptr_type`: pointer type to write +code_assignt java_object_factoryt::get_null_assignment( + const exprt &expr, + const pointer_typet &ptr_type) +{ + null_pointer_exprt null_pointer_expr(ptr_type); + code_assignt code(expr, null_pointer_expr); + code.add_source_location()=loc; + return code; +} -Function: java_object_factoryt::gen_nondet_init +/// Initialises an object tree rooted at `expr`, allocating child objects as +/// necessary and nondet-initialising their members, or if MUST_UPDATE_IN_PLACE +/// is set, re-initialising already-allocated objects. +/// \par parameters: `expr`: pointer-typed lvalue expression to initialise +/// `target_type`: structure type to initialise, which may not match *expr (for +/// example, expr might be void*) +/// `create_dynamic_objects`: if true, use malloc to allocate objects; otherwise +/// generate fresh static symbols. +/// `update_in_place`: NO_UPDATE_IN_PLACE: initialise `expr` from scratch +/// MUST_UPDATE_IN_PLACE: reinitialise an existing object MAY_UPDATE_IN_PLACE: +/// invalid input +void java_object_factoryt::gen_pointer_target_init( + code_blockt &assignments, + const exprt &expr, + const typet &target_type, + bool create_dynamic_objects) +{ + if(target_type.id()==ID_struct && + has_prefix( + id2string(to_struct_type(target_type).get_tag()), + "java::array[")) + { + gen_nondet_array_init( + assignments, + expr); + } + else + { + exprt target; + target=allocate_object( + assignments, + expr, + target_type, + create_dynamic_objects); + exprt init_expr; + if(target.id()==ID_address_of) + init_expr=target.op0(); + else + init_expr= + dereference_exprt(target, target.type().subtype()); + gen_nondet_init( + assignments, + init_expr, + false, + "", + create_dynamic_objects, + false, + typet()); + } +} - Inputs: - expr - - is_sub - - class_identifier - - loc - - create_dynamic_objects - - override - Ignore the LHS' real type. Used at the moment for - reference arrays, which are implemented as void* - arrays but should be init'd as their true type with - appropriate casts. - override_type - Type to use if ignoring the LHS' real type +/// Initialises a primitive or object tree rooted at `expr`, of type pointer. It +/// allocates child objects as necessary and nondet-initialising their members, +/// \param assignments - the code block we are building with +/// initilisation code +/// \param expr: lvalue expression to initialise +/// \param class_identifier - the name of the class so we can identify +/// special cases where a null pointer is not applicable. +/// \param create_dynamic_objects: if true, use malloc to allocate objects; +/// otherwise generate fresh static symbols. +/// \param pointer_type - The type of the pointer we are initalising +void java_object_factoryt::gen_nondet_pointer_init( + code_blockt &assignments, + const exprt &expr, + const irep_idt &class_identifier, + bool create_dynamic_objects, + const pointer_typet &pointer_type) +{ + const typet &subtype=ns.follow(pointer_type.subtype()); - Outputs: + if(subtype.id()==ID_struct) + { + const struct_typet &struct_type=to_struct_type(subtype); + const irep_idt struct_tag=struct_type.get_tag(); + // set to null if found in recursion set and not a sub-type + if(recursion_set.find(struct_tag)!=recursion_set.end() && + struct_tag==class_identifier) + { + assignments.copy_to_operands( + get_null_assignment(expr, pointer_type)); + return; + } + } - Purpose: + code_blockt non_null_inst; + gen_pointer_target_init( + non_null_inst, + expr, + subtype, + create_dynamic_objects); -\*******************************************************************/ + if(assume_non_null) + { + // Add the following code to assignments: + // = ; + assignments.append(non_null_inst); + } + else + { + // if(NONDET(_Bool) + // { + // = + // } + // else + // { + // > + // } + auto set_null_inst=get_null_assignment(expr, pointer_type); + + code_ifthenelset null_check; + null_check.cond()=side_effect_expr_nondett(bool_typet()); + null_check.then_case()=set_null_inst; + null_check.else_case()=non_null_inst; + + assignments.add(null_check); + } +} -void java_object_factoryt::gen_nondet_init( +/// Initialises an object tree rooted at `expr`, allocating child objects as +/// necessary and nondet-initialising their members. +/// \param assignments: The code block to append the new +/// instructions to +/// \param expr: pointer-typed lvalue expression to initialise +/// \param is_sub: If true, `expr` is a substructure of a larger object, which +/// in Java necessarily means a base class. not match *expr (for example, expr +/// might be void*) +/// \param class_identifier: clsid to initialise @java.lang.Object. +/// @class_identifier +/// \param create_dynamic_objects: if true, use malloc to allocate objects; +/// otherwise generate fresh static symbols. +/// \param struct_type - The type of the struct we are initalising +void java_object_factoryt::gen_nondet_struct_init( + code_blockt &assignments, const exprt &expr, bool is_sub, irep_idt class_identifier, - const source_locationt &loc, bool create_dynamic_objects, - bool override, - const typet &override_type) + const struct_typet &struct_type) { - const typet &type= - override ? ns.follow(override_type) : ns.follow(expr.type()); + typedef struct_typet::componentst componentst; - if(type.id()==ID_pointer) + const irep_idt struct_tag=struct_type.get_tag(); + + const componentst &components=struct_type.components(); + + if(!is_sub) + class_identifier=struct_tag; + + recursion_set.insert(struct_tag); + + for(const auto &component : components) { - // dereferenced type - const pointer_typet &pointer_type=to_pointer_type(type); - const typet &subtype=ns.follow(pointer_type.subtype()); + const typet &component_type=component.type(); + irep_idt name=component.get_name(); - if(subtype.id()==ID_struct) + member_exprt me(expr, name, component_type); + + if(name=="@class_identifier") { - const struct_typet &struct_type=to_struct_type(subtype); - const irep_idt struct_tag=struct_type.get_tag(); - // set to null if found in recursion set and not a sub-type - if(recursion_set.find(struct_tag)!=recursion_set.end() && - struct_tag==class_identifier) - { - // make null - null_pointer_exprt null_pointer_expr(pointer_type); - code_assignt code(expr, null_pointer_expr); - code.add_source_location()=loc; - init_code.copy_to_operands(code); - - return; - } + irep_idt qualified_clsid="java::"+as_string(class_identifier); + constant_exprt ci(qualified_clsid, string_typet()); + code_assignt code(me, ci); + code.add_source_location()=loc; + assignments.copy_to_operands(code); } - - code_labelt set_null_label; - code_labelt init_done_label; - - if(!assume_non_null) + else if(name=="@lock") { - auto set_null_inst= - code_assignt(expr, null_pointer_exprt(pointer_type)); - set_null_inst.add_source_location()=loc; - - static size_t synthetic_constructor_count=0; - std::string fresh_label= - "post_synthetic_malloc_"+std::to_string(++synthetic_constructor_count); - set_null_label=code_labelt(fresh_label, set_null_inst); - - init_done_label=code_labelt(fresh_label+"_init_done", code_skipt()); - - code_ifthenelset null_check; - exprt null_return=from_integer(0, c_bool_typet(1)); - null_check.cond()= - notequal_exprt(get_nondet_bool(c_bool_typet(1)), null_return); - null_check.then_case()=code_gotot(fresh_label); - init_code.move_to_operands(null_check); + code_assignt code(me, from_integer(0, me.type())); + code.add_source_location()=loc; + assignments.copy_to_operands(code); } - - if(java_is_array_type(subtype)) - gen_nondet_array_init(expr, loc); else { - exprt allocated= - allocate_object(expr, subtype, loc, create_dynamic_objects); - exprt init_expr; - if(allocated.id()==ID_address_of) - init_expr=allocated.op0(); - else - init_expr=dereference_exprt(allocated, allocated.type().subtype()); + INVARIANT(!name.empty(), "Each component of a struct must have a name"); + + bool _is_sub=name[0]=='@'; + gen_nondet_init( - init_expr, - false, - "", - loc, + assignments, + me, + _is_sub, + class_identifier, create_dynamic_objects); } + } + recursion_set.erase(struct_tag); +} - if(!assume_non_null) - { - init_code.copy_to_operands(code_gotot(init_done_label.get_label())); - init_code.move_to_operands(set_null_label); - init_code.move_to_operands(init_done_label); - } +/// Creates a nondet for expr, including calling itself recursively to make +/// appropriate symbols to point to if expr is a pointer or struct +/// \param expr: The expression which we are generating a non-determinate value +/// for +/// \param is_sub: +/// \param class_identifier: +/// \param create_dynamic_objects: If true, allocate variables on the heap +/// \param override: Ignore the LHS' real type. Used at the moment for reference +/// arrays, which are implemented as void* arrays but should be init'd as +/// their true type with appropriate casts. +/// \param override_type: Type to use if ignoring the LHS' real type +void java_object_factoryt::gen_nondet_init( + code_blockt &assignments, + const exprt &expr, + bool is_sub, + irep_idt class_identifier, + bool create_dynamic_objects, + bool override, + const typet &override_type) +{ + const typet &type= + override ? ns.follow(override_type) : ns.follow(expr.type()); + + if(type.id()==ID_pointer) + { + // dereferenced type + const pointer_typet &pointer_type=to_pointer_type(type); + gen_nondet_pointer_init( + assignments, + expr, + class_identifier, + create_dynamic_objects, + pointer_type); } else if(type.id()==ID_struct) { - typedef struct_typet::componentst componentst; - const struct_typet &struct_type=to_struct_type(type); - const irep_idt struct_tag=struct_type.get_tag(); - - const componentst &components=struct_type.components(); - - if(!is_sub) - class_identifier=struct_tag; - - recursion_set.insert(struct_tag); - assert(!recursion_set.empty()); - - for(const auto &component : components) - { - const typet &component_type=component.type(); - irep_idt name=component.get_name(); - - member_exprt me(expr, name, component_type); - - if(name=="@class_identifier") - { - irep_idt qualified_clsid="java::"+as_string(class_identifier); - constant_exprt ci(qualified_clsid, string_typet()); - code_assignt code(me, ci); - code.add_source_location()=loc; - init_code.copy_to_operands(code); - } - else if(name=="@lock") - { - code_assignt code(me, from_integer(0, me.type())); - code.add_source_location()=loc; - init_code.copy_to_operands(code); - } - else - { - assert(!name.empty()); - - bool _is_sub=name[0]=='@'; -#if 0 - irep_idt _class_identifier= - _is_sub?(class_identifier.empty()?struct_tag:class_identifier):""; -#endif - - gen_nondet_init( - me, - _is_sub, - class_identifier, - loc, - create_dynamic_objects); - } - } - recursion_set.erase(struct_tag); + gen_nondet_struct_init( + assignments, + expr, + is_sub, + class_identifier, + create_dynamic_objects, + struct_type); } else { - side_effect_expr_nondett se=side_effect_expr_nondett(type); + exprt rhs=type.id()==ID_c_bool? + get_nondet_bool(type): + side_effect_expr_nondett(type); + code_assignt assign(expr, rhs); + assign.add_source_location()=loc; - code_assignt code(expr, se); - code.add_source_location()=loc; - init_code.copy_to_operands(code); + assignments.copy_to_operands(assign); } } -/*******************************************************************\ - -Function: java_object_factoryt::gen_nondet_array_init - - Inputs: - - Outputs: - - Purpose: create code to initialize a Java array with size - `max_nondet_array_length`, loop over elements and initialize - them - -\*******************************************************************/ - -void java_object_factoryt::gen_nondet_array_init( - const exprt &expr, - const source_locationt &loc) +/// Allocates a fresh array. Single-use at the moment, but useful to keep +/// as a separate function for downstream branches. +/// \par parameters: `lhs`, symbol to assign the new array structure +/// `max_length_expr`, maximum length of the new array (minimum is fixed at zero +/// for now) +/// `element_type`, actual element type of the array (the array for all +/// reference types will have void* type, but this will be annotated as the +/// true member type) +/// \return Appends instructions to `assignments` +void java_object_factoryt::allocate_nondet_length_array( + code_blockt &assignments, + const exprt &lhs, + const exprt &max_length_expr, + const typet &element_type) { - assert(expr.type().id()==ID_pointer); - const typet &type=ns.follow(expr.type().subtype()); - const struct_typet &struct_type=to_struct_type(type); - assert(expr.type().subtype().id()==ID_symbol); - const typet &element_type= - static_cast(expr.type().subtype().find(ID_C_element_type)); - - auto max_length_expr=from_integer(max_nondet_array_length, java_int_type()); - - typet allocate_type; symbolt &length_sym=new_tmp_symbol( symbol_table, loc, java_int_type(), "nondet_array_length"); + symbols_created.push_back(&length_sym); const auto &length_sym_expr=length_sym.symbol_expr(); // Initialize array with some undetermined length: - gen_nondet_init(length_sym_expr, false, irep_idt(), loc, false); + gen_nondet_init(assignments, length_sym_expr, false, irep_idt(), false); // Insert assumptions to bound its length: binary_relation_exprt @@ -409,24 +494,47 @@ void java_object_factoryt::gen_nondet_array_init( assume2(length_sym_expr, ID_le, max_length_expr); code_assumet assume_inst1(assume1); code_assumet assume_inst2(assume2); - init_code.move_to_operands(assume_inst1); - init_code.move_to_operands(assume_inst2); + assignments.move_to_operands(assume_inst1); + assignments.move_to_operands(assume_inst2); - side_effect_exprt java_new_array(ID_java_new_array, expr.type()); + side_effect_exprt java_new_array(ID_java_new_array, lhs.type()); java_new_array.copy_to_operands(length_sym_expr); + java_new_array.set(ID_length_upper_bound, max_length_expr); java_new_array.type().subtype().set(ID_C_element_type, element_type); - codet assign=code_assignt(expr, java_new_array); + codet assign=code_assignt(lhs, java_new_array); assign.add_source_location()=loc; - init_code.copy_to_operands(assign); - - exprt init_array_expr= - member_exprt( - dereference_exprt(expr, expr.type().subtype()), - "data", - struct_type.components()[2].type()); - if(init_array_expr.type()!=pointer_typet(element_type)) + assignments.copy_to_operands(assign); +} + +/// create code to initialize a Java array with size `max_nondet_array_length`, +/// loop over elements and initialize them +void java_object_factoryt::gen_nondet_array_init( + code_blockt &assignments, + const exprt &expr) +{ + assert(expr.type().id()==ID_pointer); + const typet &type=ns.follow(expr.type().subtype()); + const struct_typet &struct_type=to_struct_type(type); + assert(expr.type().subtype().id()==ID_symbol); + const typet &element_type= + static_cast(expr.type().subtype().find(ID_C_element_type)); + + auto max_length_expr=from_integer(max_nondet_array_length, java_int_type()); + + allocate_nondet_length_array( + assignments, + expr, + max_length_expr, + element_type); + + dereference_exprt deref_expr(expr, expr.type().subtype()); + const auto &comps=struct_type.components(); + exprt length_expr=member_exprt(deref_expr, "length", comps[1].type()); + exprt init_array_expr=member_exprt(deref_expr, "data", comps[2].type()); + + if(init_array_expr.type()!=pointer_type(element_type)) init_array_expr= - typecast_exprt(init_array_expr, pointer_typet(element_type)); + typecast_exprt(init_array_expr, pointer_type(element_type)); // Interpose a new symbol, as the goto-symex stage can't handle array indexing // via a cast. @@ -435,38 +543,40 @@ void java_object_factoryt::gen_nondet_array_init( loc, init_array_expr.type(), "array_data_init"); + symbols_created.push_back(&array_init_symbol); const auto &array_init_symexpr=array_init_symbol.symbol_expr(); codet data_assign=code_assignt(array_init_symexpr, init_array_expr); data_assign.add_source_location()=loc; - init_code.copy_to_operands(data_assign); + assignments.copy_to_operands(data_assign); // Emit init loop for(array_init_iter=0; array_init_iter!=array.length; // ++array_init_iter) init(array[array_init_iter]); symbolt &counter=new_tmp_symbol( symbol_table, loc, - length_sym_expr.type(), + length_expr.type(), "array_init_iter"); + symbols_created.push_back(&counter); exprt counter_expr=counter.symbol_expr(); exprt java_zero=from_integer(0, java_int_type()); - init_code.copy_to_operands(code_assignt(counter_expr, java_zero)); + assignments.copy_to_operands(code_assignt(counter_expr, java_zero)); std::string head_name=as_string(counter.base_name)+"_header"; code_labelt init_head_label(head_name, code_skipt()); code_gotot goto_head(head_name); - init_code.move_to_operands(init_head_label); + assignments.move_to_operands(init_head_label); std::string done_name=as_string(counter.base_name)+"_done"; code_labelt init_done_label(done_name, code_skipt()); code_gotot goto_done(done_name); code_ifthenelset done_test; - done_test.cond()=equal_exprt(counter_expr, length_sym_expr); + done_test.cond()=equal_exprt(counter_expr, length_expr); done_test.then_case()=goto_done; - init_code.move_to_operands(done_test); + assignments.move_to_operands(done_test); // Add a redundant if(counter == max_length) break that is easier for the // unwinder to understand. @@ -474,17 +584,17 @@ void java_object_factoryt::gen_nondet_array_init( max_test.cond()=equal_exprt(counter_expr, max_length_expr); max_test.then_case()=goto_done; - init_code.move_to_operands(max_test); + assignments.move_to_operands(max_test); exprt arraycellref=dereference_exprt( plus_exprt(array_init_symexpr, counter_expr, array_init_symexpr.type()), array_init_symexpr.type().subtype()); gen_nondet_init( + assignments, arraycellref, false, irep_idt(), - loc, true, true, element_type); @@ -492,61 +602,63 @@ void java_object_factoryt::gen_nondet_array_init( exprt java_one=from_integer(1, java_int_type()); code_assignt incr(counter_expr, plus_exprt(counter_expr, java_one)); - init_code.move_to_operands(incr); - init_code.move_to_operands(goto_head); - init_code.move_to_operands(init_done_label); + assignments.move_to_operands(incr); + assignments.move_to_operands(goto_head); + assignments.move_to_operands(init_done_label); } -/*******************************************************************\ - -Function: object_factory - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt object_factory( const typet &type, + const irep_idt base_name, code_blockt &init_code, bool allow_null, symbol_tablet &symbol_table, size_t max_nondet_array_length, const source_locationt &loc) { - if(type.id()==ID_pointer) - { - symbolt &aux_symbol=new_tmp_symbol( - symbol_table, - loc, - type); - aux_symbol.is_static_lifetime=true; + irep_idt identifier=id2string(goto_functionst::entry_point())+ + "::"+id2string(base_name); - exprt object=aux_symbol.symbol_expr(); + auxiliary_symbolt main_symbol; + main_symbol.mode=ID_java; + main_symbol.is_static_lifetime=false; + main_symbol.name=identifier; + main_symbol.base_name=base_name; + main_symbol.type=type; + main_symbol.location=loc; - java_object_factoryt state( - init_code, - !allow_null, - max_nondet_array_length, - symbol_table); - state.gen_nondet_init( - object, - false, - "", - loc, - false); + exprt object=main_symbol.symbol_expr(); - return object; - } - else if(type.id()==ID_c_bool) + symbolt *main_symbol_ptr; + bool moving_symbol_failed=symbol_table.move(main_symbol, main_symbol_ptr); + assert(!moving_symbol_failed); + + std::vector symbols_created; + symbols_created.push_back(main_symbol_ptr); + + java_object_factoryt state( + symbols_created, + loc, + !allow_null, + max_nondet_array_length, + symbol_table); + code_blockt assignments; + state.gen_nondet_init( + assignments, + object, + false, + "", + false); + + // Add the following code to init_code for each symbol that's been created: + // ; + for(const symbolt * const symbol_ptr : symbols_created) { - // We force this to 0 and 1 and won't consider - // other values. - return get_nondet_bool(type); + code_declt decl(symbol_ptr->symbol_expr()); + decl.add_source_location()=loc; + init_code.add(decl); } - else - return side_effect_expr_nondett(type); + + init_code.append(assignments); + return object; } diff --git a/src/java_bytecode/java_object_factory.h b/src/java_bytecode/java_object_factory.h index 01e0205df71..cefd152f10d 100644 --- a/src/java_bytecode/java_object_factory.h +++ b/src/java_bytecode/java_object_factory.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_JAVA_BYTECODE_JAVA_OBJECT_FACTORY_H #define CPROVER_JAVA_BYTECODE_JAVA_OBJECT_FACTORY_H @@ -15,6 +16,7 @@ Author: Daniel Kroening, kroening@kroening.com exprt object_factory( const typet &type, + const irep_idt base_name, code_blockt &init_code, bool allow_null, symbol_tablet &symbol_table, diff --git a/src/java_bytecode/java_pointer_casts.cpp b/src/java_bytecode/java_pointer_casts.cpp index 174bad0a9b1..26b42e0bd31 100644 --- a/src/java_bytecode/java_pointer_casts.cpp +++ b/src/java_bytecode/java_pointer_casts.cpp @@ -6,24 +6,17 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include -#include -#include +/// \file +/// JAVA Pointer Casts #include "java_pointer_casts.h" -/*******************************************************************\ - -Function: clean_deref - - Inputs: pointer - - Outputs: dereferenced pointer - - Purpose: dereference pointer expression - -\*******************************************************************/ +#include +#include +#include +/// dereference pointer expression +/// \return dereferenced pointer static exprt clean_deref(const exprt &ptr) { return ptr.id()==ID_address_of @@ -31,19 +24,9 @@ static exprt clean_deref(const exprt &ptr) : dereference_exprt(ptr, ptr.type().subtype()); } -/*******************************************************************\ - -Function: find_superclass_with_type - - Inputs: pointer - target type to search - - Outputs: true iff a super class with target type is found - - Purpose: - -\*******************************************************************/ - +/// \par parameters: pointer +/// target type to search +/// \return true iff a super class with target type is found bool find_superclass_with_type( exprt &ptr, const typet &target_type, @@ -77,18 +60,8 @@ bool find_superclass_with_type( } -/*******************************************************************\ - -Function: look_through_casts - - Inputs: input expression - - Outputs: recursively search target of typecast - - Purpose: - -\*******************************************************************/ - +/// \par parameters: input expression +/// \return recursively search target of typecast static const exprt &look_through_casts(const exprt &in) { if(in.id()==ID_typecast) @@ -101,31 +74,19 @@ static const exprt &look_through_casts(const exprt &in) } -/*******************************************************************\ - -Function: make_clean_pointer_cast - - Inputs: raw pointer - target type - namespace - - Outputs: cleaned up typecast expression - - Purpose: - -\*******************************************************************/ - +/// \par parameters: raw pointer +/// target type +/// namespace +/// \return cleaned up typecast expression exprt make_clean_pointer_cast( const exprt &rawptr, - const typet &target_type, + const pointer_typet &target_type, const namespacet &ns) { - assert( - target_type.id()==ID_pointer && - "Non-pointer target in make_clean_pointer_cast?"); - const exprt &ptr=look_through_casts(rawptr); + PRECONDITION(ptr.type().id()==ID_pointer); + if(ptr.type()==target_type) return ptr; diff --git a/src/java_bytecode/java_pointer_casts.h b/src/java_bytecode/java_pointer_casts.h index 7b5d23a3c8a..80c4bb0a4f5 100644 --- a/src/java_bytecode/java_pointer_casts.h +++ b/src/java_bytecode/java_pointer_casts.h @@ -6,9 +6,17 @@ Author: DiffBlue \*******************************************************************/ +/// \file +/// JAVA Pointer Casts + #ifndef CPROVER_JAVA_BYTECODE_JAVA_POINTER_CASTS_H #define CPROVER_JAVA_BYTECODE_JAVA_POINTER_CASTS_H +class exprt; +class typet; +class pointer_typet; +class namespacet; + bool find_superclass_with_type( exprt &ptr, const typet &target_type, @@ -16,7 +24,7 @@ bool find_superclass_with_type( exprt make_clean_pointer_cast( const exprt &ptr, - const typet &target_type, + const pointer_typet &target_type, const namespacet &ns); #endif // CPROVER_JAVA_BYTECODE_JAVA_POINTER_CASTS_H diff --git a/src/java_bytecode/java_root_class.cpp b/src/java_bytecode/java_root_class.cpp index db6c810182a..f3353c48d1a 100644 --- a/src/java_bytecode/java_root_class.cpp +++ b/src/java_bytecode/java_root_class.cpp @@ -6,11 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "java_root_class.h" + #include #include #include "java_types.h" -#include "java_root_class.h" /******************************************************************* diff --git a/src/java_bytecode/java_root_class.h b/src/java_bytecode/java_root_class.h index e0ce4f7dddc..fcdb11333db 100644 --- a/src/java_bytecode/java_root_class.h +++ b/src/java_bytecode/java_root_class.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_JAVA_BYTECODE_JAVA_ROOT_CLASS_H #define CPROVER_JAVA_BYTECODE_JAVA_ROOT_CLASS_H diff --git a/src/java_bytecode/java_types.cpp b/src/java_bytecode/java_types.cpp index 735a2a0dbfb..ae8d64d102f 100644 --- a/src/java_bytecode/java_types.cpp +++ b/src/java_bytecode/java_types.cpp @@ -6,163 +6,56 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "java_types.h" + #include #include #include +#include #include #include -#include "java_types.h" - -/*******************************************************************\ - -Function: java_int_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet java_int_type() { return signedbv_typet(32); } -/*******************************************************************\ - -Function: java_void_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet java_void_type() { return void_typet(); } -/*******************************************************************\ - -Function: java_long_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet java_long_type() { return signedbv_typet(64); } -/*******************************************************************\ - -Function: java_short_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet java_short_type() { return signedbv_typet(16); } -/*******************************************************************\ - -Function: java_byte_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet java_byte_type() { return signedbv_typet(8); } -/*******************************************************************\ - -Function: java_char_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet java_char_type() { return unsignedbv_typet(16); } -/*******************************************************************\ - -Function: java_float_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet java_float_type() { return ieee_float_spect::single_precision().to_type(); } -/*******************************************************************\ - -Function: java_double_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet java_double_type() { return ieee_float_spect::double_precision().to_type(); } -/*******************************************************************\ - -Function: java_boolean_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet java_boolean_type() { // The Java standard doesn't really prescribe the width @@ -171,36 +64,17 @@ typet java_boolean_type() return c_bool_typet(8); } -/*******************************************************************\ - -Function: java_reference_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - reference_typet java_reference_type(const typet &subtype) { - return reference_typet(subtype); + return to_reference_type(reference_type(subtype)); } -/*******************************************************************\ - -Function: java_array_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +reference_typet java_lang_object_type() +{ + return java_reference_type(symbol_typet("java::java.lang.Object")); +} -pointer_typet java_array_type(const char subtype) +reference_typet java_array_type(const char subtype) { std::string subtype_str; @@ -226,38 +100,14 @@ pointer_typet java_array_type(const char subtype) symbol_type.set(ID_C_base_name, class_name); symbol_type.set(ID_C_element_type, java_type_from_char(subtype)); - return pointer_typet(symbol_type); + return java_reference_type(symbol_type); } -/*******************************************************************\ - -Function: is_reference_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool is_reference_type(const char t) { return 'a' == t; } -/*******************************************************************\ - -Function: java_type_from_char - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet java_type_from_char(char t) { switch(t) @@ -276,19 +126,7 @@ typet java_type_from_char(char t) } } -/*******************************************************************\ - -Function: java_bytecode_promotion - - Inputs: - - Outputs: - - Purpose: Java does not support byte/short return types. - These are always promoted. - -\*******************************************************************/ - +/// Java does not support byte/short return types. These are always promoted. typet java_bytecode_promotion(const typet &type) { if(type==java_boolean_type() || @@ -300,19 +138,7 @@ typet java_bytecode_promotion(const typet &type) return type; } -/*******************************************************************\ - -Function: java_bytecode_promotion - - Inputs: - - Outputs: - - Purpose: Java does not support byte/short return types. - These are always promoted. - -\*******************************************************************/ - +/// Java does not support byte/short return types. These are always promoted. exprt java_bytecode_promotion(const exprt &expr) { typet new_type=java_bytecode_promotion(expr.type()); @@ -323,18 +149,6 @@ exprt java_bytecode_promotion(const exprt &expr) return typecast_exprt(expr, new_type); } -/*******************************************************************\ - -Function: java_type_from_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet java_type_from_string(const std::string &src) { if(src.empty()) @@ -435,18 +249,6 @@ typet java_type_from_string(const std::string &src) } } -/*******************************************************************\ - -Function: java_char_from_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - char java_char_from_type(const typet &type) { const irep_idt &id=type.id(); @@ -479,18 +281,6 @@ char java_char_from_type(const typet &type) return 'a'; } -/*******************************************************************\ - -Function: java_classname - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - // java/lang/Object -> java.lang.Object static std::string slash_to_dot(const std::string &src) { @@ -501,18 +291,6 @@ static std::string slash_to_dot(const std::string &src) return result; } -/*******************************************************************\ - -Function: java_classname - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - symbol_typet java_classname(const std::string &id) { if(!id.empty() && id[0]=='[') diff --git a/src/java_bytecode/java_types.h b/src/java_bytecode/java_types.h index e283a5acf23..43b24bb6934 100644 --- a/src/java_bytecode/java_types.h +++ b/src/java_bytecode/java_types.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_JAVA_BYTECODE_JAVA_TYPES_H #define CPROVER_JAVA_BYTECODE_JAVA_TYPES_H @@ -21,9 +22,10 @@ typet java_float_type(); typet java_double_type(); typet java_boolean_type(); reference_typet java_reference_type(const typet &subtype); +reference_typet java_lang_object_type(); symbol_typet java_classname(const std::string &); -pointer_typet java_array_type(const char subtype); +reference_typet java_array_type(const char subtype); bool is_reference_type(char t); diff --git a/src/java_bytecode/java_utils.cpp b/src/java_bytecode/java_utils.cpp index 2e84c77f870..6611b359f00 100644 --- a/src/java_bytecode/java_utils.cpp +++ b/src/java_bytecode/java_utils.cpp @@ -6,11 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "java_utils.h" + #include #include -#include "java_utils.h" - bool java_is_array_type(const typet &type) { if(type.id()!=ID_struct) diff --git a/src/java_bytecode/java_utils.h b/src/java_bytecode/java_utils.h index ec7e6a9ad8e..4231c15a185 100644 --- a/src/java_bytecode/java_utils.h +++ b/src/java_bytecode/java_utils.h @@ -6,11 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #ifndef CPROVER_JAVA_BYTECODE_JAVA_UTILS_H #define CPROVER_JAVA_BYTECODE_JAVA_UTILS_H +#include + bool java_is_array_type(const typet &type); #endif // CPROVER_JAVA_BYTECODE_JAVA_UTILS_H diff --git a/src/jsil/Makefile b/src/jsil/Makefile index 60e907197a5..61380167d05 100644 --- a/src/jsil/Makefile +++ b/src/jsil/Makefile @@ -37,6 +37,8 @@ jsil_y.tab.h: jsil_y.tab.cpp jsil_lex.yy.cpp: scanner.l $(LEX) -Pyyjsil -o$@ scanner.l +generated_files: jsil_lex.yy.cpp jsil_y.tab.cpp jsil_y.tab.h + # extra dependencies jsil_y.tab$(OBJEXT): jsil_y.tab.cpp jsil_y.tab.h jsil_lex.yy$(OBJEXT): jsil_y.tab.cpp jsil_lex.yy.cpp jsil_y.tab.h diff --git a/src/jsil/expr2jsil.cpp b/src/jsil/expr2jsil.cpp index 3bb9b410221..4f5631ce10c 100644 --- a/src/jsil/expr2jsil.cpp +++ b/src/jsil/expr2jsil.cpp @@ -6,23 +6,12 @@ Author: Michael Tautschnig, tautschn@amazon.com \*******************************************************************/ -#include +/// \file +/// Jsil Language #include "expr2jsil.h" #include "expr2jsil_class.h" -/*******************************************************************\ - -Function: expr2jsil - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string expr2jsil(const exprt &expr, const namespacet &ns) { expr2jsilt expr2jsil(ns); @@ -32,18 +21,6 @@ std::string expr2jsil(const exprt &expr, const namespacet &ns) return expr2jsil.convert(expr); } -/*******************************************************************\ - -Function: type2jsil - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string type2jsil(const typet &type, const namespacet &ns) { expr2jsilt expr2jsil(ns); diff --git a/src/jsil/expr2jsil.h b/src/jsil/expr2jsil.h index b1b41df2198..f8f99620380 100644 --- a/src/jsil/expr2jsil.h +++ b/src/jsil/expr2jsil.h @@ -6,6 +6,9 @@ Author: Michael Tautschnig, tautschn@amazon.com \*******************************************************************/ +/// \file +/// Jsil Language + #ifndef CPROVER_JSIL_EXPR2JSIL_H #define CPROVER_JSIL_EXPR2JSIL_H diff --git a/src/jsil/expr2jsil_class.h b/src/jsil/expr2jsil_class.h index 1ce743c4414..a0907f57401 100644 --- a/src/jsil/expr2jsil_class.h +++ b/src/jsil/expr2jsil_class.h @@ -7,6 +7,9 @@ Author: Michael Tautschnig, tautschn@amazon.com \*******************************************************************/ +/// \file +/// Jsil Language + #ifndef CPROVER_JSIL_EXPR2JSIL_CLASS_H #define CPROVER_JSIL_EXPR2JSIL_CLASS_H @@ -17,16 +20,6 @@ class expr2jsilt:public expr2ct public: explicit expr2jsilt(const namespacet &_ns):expr2ct(_ns) { } - virtual std::string convert(const exprt &src) - { - return expr2ct::convert(src); - } - - virtual std::string convert(const typet &src) - { - return expr2ct::convert(src); - } - protected: }; diff --git a/src/jsil/jsil_convert.cpp b/src/jsil/jsil_convert.cpp index 4e013b6f34e..328a1c76223 100644 --- a/src/jsil/jsil_convert.cpp +++ b/src/jsil/jsil_convert.cpp @@ -6,11 +6,15 @@ Author: Michael Tautschnig, tautschn@amazon.com \*******************************************************************/ +/// \file +/// Jsil Language Conversion + +#include "jsil_convert.h" + #include #include #include "jsil_parse_tree.h" -#include "jsil_convert.h" class jsil_convertt:public messaget { @@ -31,18 +35,6 @@ class jsil_convertt:public messaget bool convert_code(const symbolt &symbol, codet &code); }; -/*******************************************************************\ - -Function: jsil_convertt::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool jsil_convertt::operator()(const jsil_parse_treet &parse_tree) { for(jsil_parse_treet::itemst::const_iterator @@ -74,18 +66,6 @@ bool jsil_convertt::operator()(const jsil_parse_treet &parse_tree) return false; } -/*******************************************************************\ - -Function: jsil_convertt::convert_code - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool jsil_convertt::convert_code(const symbolt &symbol, codet &code) { if(code.get_statement()==ID_block) @@ -137,18 +117,6 @@ bool jsil_convertt::convert_code(const symbolt &symbol, codet &code) return false; } -/*******************************************************************\ - -Function: jsil_convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool jsil_convert( const jsil_parse_treet &parse_tree, symbol_tablet &symbol_table, diff --git a/src/jsil/jsil_convert.h b/src/jsil/jsil_convert.h index 7c50b694ecd..601d64e1b35 100644 --- a/src/jsil/jsil_convert.h +++ b/src/jsil/jsil_convert.h @@ -6,6 +6,9 @@ Author: Michael Tautschnig, tautschn@amazon.com \*******************************************************************/ +/// \file +/// Jsil Language Conversion + #ifndef CPROVER_JSIL_JSIL_CONVERT_H #define CPROVER_JSIL_JSIL_CONVERT_H diff --git a/src/jsil/jsil_entry_point.cpp b/src/jsil/jsil_entry_point.cpp index 4959326bf02..2f4d88e1bb3 100644 --- a/src/jsil/jsil_entry_point.cpp +++ b/src/jsil/jsil_entry_point.cpp @@ -6,6 +6,11 @@ Author: Michael Tautschnig, tautschn@amazon.com \*******************************************************************/ +/// \file +/// Jsil Language + +#include "jsil_entry_point.h" + #include #include #include @@ -15,22 +20,8 @@ Author: Michael Tautschnig, tautschn@amazon.com #include -#include "jsil_entry_point.h" - #define INITIALIZE CPROVER_PREFIX "initialize" -/*******************************************************************\ - -Function: create_initialize - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static void create_initialize(symbol_tablet &symbol_table) { symbolt initialize; @@ -58,18 +49,6 @@ static void create_initialize(symbol_tablet &symbol_table) throw "failed to add " CPROVER_PREFIX "initialize"; } -/*******************************************************************\ - -Function: jsil_entry_point - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool jsil_entry_point( symbol_tablet &symbol_table, message_handlert &message_handler) diff --git a/src/jsil/jsil_entry_point.h b/src/jsil/jsil_entry_point.h index c374d395626..fd9453769da 100644 --- a/src/jsil/jsil_entry_point.h +++ b/src/jsil/jsil_entry_point.h @@ -6,6 +6,9 @@ Author: Michael Tautschnig, tautschn@amazon.com \*******************************************************************/ +/// \file +/// Jsil Language + #ifndef CPROVER_JSIL_JSIL_ENTRY_POINT_H #define CPROVER_JSIL_JSIL_ENTRY_POINT_H diff --git a/src/jsil/jsil_internal_additions.cpp b/src/jsil/jsil_internal_additions.cpp index 9f583fbb56b..af963454e25 100644 --- a/src/jsil/jsil_internal_additions.cpp +++ b/src/jsil/jsil_internal_additions.cpp @@ -6,28 +6,19 @@ Author: Michael Tautschnig, tautschn@amazon.com \*******************************************************************/ +/// \file +/// Jsil Language + +#include "jsil_internal_additions.h" + #include #include #include -#include +#include #include "jsil_types.h" -#include "jsil_internal_additions.h" - -/*******************************************************************\ - -Function: jsil_internal_additions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_internal_additions(symbol_tablet &dest) { // add __CPROVER_rounding_mode @@ -52,7 +43,7 @@ void jsil_internal_additions(symbol_tablet &dest) symbolt symbol; symbol.base_name="__CPROVER_malloc_object"; symbol.name=CPROVER_PREFIX "malloc_object"; - symbol.type=pointer_typet(empty_typet()); + symbol.type=pointer_type(empty_typet()); symbol.mode=ID_C; symbol.is_lvalue=true; symbol.is_state_var=true; @@ -90,7 +81,7 @@ void jsil_internal_additions(symbol_tablet &dest) dest.add(symbol); } - // add empty symbol used for decl statemements + // add empty symbol used for decl statements { symbolt symbol; diff --git a/src/jsil/jsil_internal_additions.h b/src/jsil/jsil_internal_additions.h index f57cc098189..1aed9edd692 100644 --- a/src/jsil/jsil_internal_additions.h +++ b/src/jsil/jsil_internal_additions.h @@ -6,6 +6,9 @@ Author: Michael Tautschnig, tautschn@amazon.com \*******************************************************************/ +/// \file +/// Jsil Language + #ifndef CPROVER_JSIL_JSIL_INTERNAL_ADDITIONS_H #define CPROVER_JSIL_JSIL_INTERNAL_ADDITIONS_H diff --git a/src/jsil/jsil_language.cpp b/src/jsil/jsil_language.cpp index a7469ef3b7a..7bcd682a70d 100644 --- a/src/jsil/jsil_language.cpp +++ b/src/jsil/jsil_language.cpp @@ -6,6 +6,11 @@ Author: Michael Tautschnig, tautschn@amazon.com \*******************************************************************/ +/// \file +/// Jsil Language + +#include "jsil_language.h" + #include #include @@ -17,54 +22,17 @@ Author: Michael Tautschnig, tautschn@amazon.com #include "jsil_parser.h" #include "jsil_typecheck.h" -#include "jsil_language.h" - -/*******************************************************************\ - -Function: jsil_languaget::extensions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::set jsil_languaget::extensions() const { return { "jsil" }; } -/*******************************************************************\ - -Function: jsil_languaget::modules_provided - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_languaget::modules_provided(std::set &modules) { modules.insert(get_base_name(parse_path, true)); } -/*******************************************************************\ - -Function: jsil_languaget::interfaces - - Inputs: - - Outputs: - - Purpose: Adding symbols for all procedure declarations - -\*******************************************************************/ - +/// Adding symbols for all procedure declarations bool jsil_languaget::interfaces(symbol_tablet &symbol_table) { if(jsil_convert(parse_tree, symbol_table, get_message_handler())) @@ -74,18 +42,6 @@ bool jsil_languaget::interfaces(symbol_tablet &symbol_table) return false; } -/*******************************************************************\ - -Function: jsil_languaget::preprocess - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool jsil_languaget::preprocess( std::istream &instream, const std::string &path, @@ -95,18 +51,6 @@ bool jsil_languaget::preprocess( return true; } -/*******************************************************************\ - -Function: jsil_languaget::parse - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool jsil_languaget::parse( std::istream &instream, const std::string &path) @@ -132,18 +76,7 @@ bool jsil_languaget::parse( return result; } -/*******************************************************************\ - -Function: jsil_languaget::typecheck - - Inputs: - - Outputs: - - Purpose: Converting from parse tree and type checking. - -\*******************************************************************/ - +/// Converting from parse tree and type checking. bool jsil_languaget::typecheck( symbol_tablet &symbol_table, const std::string &module) @@ -154,18 +87,6 @@ bool jsil_languaget::typecheck( return false; } -/*******************************************************************\ - -Function: jsil_languaget::final - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool jsil_languaget::final( symbol_tablet &symbol_table, bool generate_start_function) @@ -181,52 +102,16 @@ bool jsil_languaget::final( return false; } -/*******************************************************************\ - -Function: jsil_languaget::show_parse - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_languaget::show_parse(std::ostream &out) { parse_tree.output(out); } -/*******************************************************************\ - -Function: new_jsil_language - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - languaget *new_jsil_language() { return new jsil_languaget; } -/*******************************************************************\ - -Function: jsil_languaget::from_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool jsil_languaget::from_expr( const exprt &expr, std::string &code, @@ -236,18 +121,6 @@ bool jsil_languaget::from_expr( return false; } -/*******************************************************************\ - -Function: jsil_languaget::from_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool jsil_languaget::from_type( const typet &type, std::string &code, @@ -257,36 +130,12 @@ bool jsil_languaget::from_type( return false; } -/*******************************************************************\ - -Function: jsil_languaget::get_pretty_printer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::unique_ptr jsil_languaget::get_pretty_printer(const namespacet &ns) { return std::unique_ptr(new expr2jsilt(ns)); } -/*******************************************************************\ - -Function: jsil_languaget::to_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool jsil_languaget::to_expr( const std::string &code, const std::string &module, @@ -331,18 +180,6 @@ bool jsil_languaget::to_expr( return result; } -/*******************************************************************\ - -Function: jsil_languaget::~jsil_languaget - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - jsil_languaget::~jsil_languaget() { } diff --git a/src/jsil/jsil_language.h b/src/jsil/jsil_language.h index 72e9be1639f..1727aadb6c7 100644 --- a/src/jsil/jsil_language.h +++ b/src/jsil/jsil_language.h @@ -6,6 +6,9 @@ Author: Michael Tautschnig, tautschn@amazon.com \*******************************************************************/ +/// \file +/// Jsil Language + #ifndef CPROVER_JSIL_JSIL_LANGUAGE_H #define CPROVER_JSIL_JSIL_LANGUAGE_H diff --git a/src/jsil/jsil_parse_tree.cpp b/src/jsil/jsil_parse_tree.cpp index 874e36ccef6..093a62f4fb9 100644 --- a/src/jsil/jsil_parse_tree.cpp +++ b/src/jsil/jsil_parse_tree.cpp @@ -6,23 +6,14 @@ Author: Michael Tautschnig, tautschn@amazon.com \*******************************************************************/ -#include - -#include "jsil_types.h" +/// \file +/// Jsil Language #include "jsil_parse_tree.h" -/*******************************************************************\ - -Function: insert_at_label - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include "jsil_types.h" static bool insert_at_label( const codet &code, @@ -49,18 +40,6 @@ static bool insert_at_label( return true; } -/*******************************************************************\ - -Function: jsil_declarationt::to_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_declarationt::to_symbol(symbolt &symbol) const { symbol.clear(); @@ -101,18 +80,6 @@ void jsil_declarationt::to_symbol(symbolt &symbol) const symbol.value.swap(code); } -/*******************************************************************\ - -Function: jsil_declarationt::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_declarationt::output(std::ostream &out) const { out << "Declarator: " << find(ID_declarator).pretty() << "\n"; @@ -121,18 +88,6 @@ void jsil_declarationt::output(std::ostream &out) const out << "Value: " << find(ID_value).pretty() << "\n"; } -/*******************************************************************\ - -Function: jsil_parse_treet::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_parse_treet::output(std::ostream &out) const { for(itemst::const_iterator diff --git a/src/jsil/jsil_parse_tree.h b/src/jsil/jsil_parse_tree.h index 5a83cf18e8b..55ee57de51b 100644 --- a/src/jsil/jsil_parse_tree.h +++ b/src/jsil/jsil_parse_tree.h @@ -6,6 +6,9 @@ Author: Michael Tautschnig, tautschn@amazon.com \*******************************************************************/ +/// \file +/// Jsil Language + #ifndef CPROVER_JSIL_JSIL_PARSE_TREE_H #define CPROVER_JSIL_JSIL_PARSE_TREE_H diff --git a/src/jsil/jsil_parser.cpp b/src/jsil/jsil_parser.cpp index e6d17c1e13c..de11bc731e8 100644 --- a/src/jsil/jsil_parser.cpp +++ b/src/jsil/jsil_parser.cpp @@ -6,22 +6,13 @@ Author: Michael Tautschnig, tautschn@amazon.com \*******************************************************************/ +/// \file +/// Jsil Language + #include "jsil_parser.h" jsil_parsert jsil_parser; -/*******************************************************************\ - -Function: yyjsilerror - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - extern char *yyjsiltext; int yyjsilerror(const std::string &error) diff --git a/src/jsil/jsil_parser.h b/src/jsil/jsil_parser.h index 7cf55a32f69..2aad7767e34 100644 --- a/src/jsil/jsil_parser.h +++ b/src/jsil/jsil_parser.h @@ -6,6 +6,9 @@ Author: Michael Tautschnig, tautschn@amazon.com \*******************************************************************/ +/// \file +/// Jsil Language + #ifndef CPROVER_JSIL_JSIL_PARSER_H #define CPROVER_JSIL_JSIL_PARSER_H diff --git a/src/jsil/jsil_typecheck.cpp b/src/jsil/jsil_typecheck.cpp index a644f1acf99..81ebf82f87b 100644 --- a/src/jsil/jsil_typecheck.cpp +++ b/src/jsil/jsil_typecheck.cpp @@ -6,6 +6,11 @@ Author: Michael Tautschnig, tautschn@amazon.com \*******************************************************************/ +/// \file +/// Jsil Language + +#include "jsil_typecheck.h" + #include #include #include @@ -13,71 +18,22 @@ Author: Michael Tautschnig, tautschn@amazon.com #include "expr2jsil.h" #include "jsil_types.h" -#include "jsil_typecheck.h" - -/*******************************************************************\ - -Function: java_bytecode_typecheckt::to_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string jsil_typecheckt::to_string(const exprt &expr) { return expr2jsil(expr, ns); } -/*******************************************************************\ - -Function: java_bytecode_typecheckt::to_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string jsil_typecheckt::to_string(const typet &type) { return type2jsil(type, ns); } -/*******************************************************************\ - -Function: jsil_typecheckt::add_prefix - - Inputs: - - Outputs: - - Purpose: Prefix parameters and variables with a procedure name - -\*******************************************************************/ - +/// Prefix parameters and variables with a procedure name irep_idt jsil_typecheckt::add_prefix(const irep_idt &ds) { return id2string(proc_name) + "::" + id2string(ds); } -/*******************************************************************\ - -Function: jsil_typecheckt::update_expr_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::update_expr_type(exprt &expr, const typet &type) { expr.type()=type; @@ -100,18 +56,6 @@ void jsil_typecheckt::update_expr_type(exprt &expr, const typet &type) } } -/*******************************************************************\ - -Function: jsil_typecheckt::make_type_compatible - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::make_type_compatible( exprt &expr, const typet &type, @@ -151,18 +95,6 @@ void jsil_typecheckt::make_type_compatible( } } -/*******************************************************************\ - -Function: jsil_typecheckt::typecheck_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_type(typet &type) { if(type.id()==ID_code) @@ -201,18 +133,6 @@ void jsil_typecheckt::typecheck_type(typet &type) } } -/*******************************************************************\ - -Function: jsil_typecheckt::typecheck_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_expr(exprt &expr) { // first do sub-nodes @@ -222,36 +142,12 @@ void jsil_typecheckt::typecheck_expr(exprt &expr) typecheck_expr_main(expr); } -/*******************************************************************\ - -Function: jsil_typecheckt::typecheck_expr_operands - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_expr_operands(exprt &expr) { Forall_operands(it, expr) typecheck_expr(*it); } -/*******************************************************************\ - -Function: jsil_typecheckt::typecheck_expr_main - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_expr_main(exprt &expr) { if(expr.id()==ID_code) @@ -369,18 +265,6 @@ void jsil_typecheckt::typecheck_expr_main(exprt &expr) } } -/*******************************************************************\ - -Function: jsil_typecheckt::typecheck_expr_side_effect_throw - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_expr_side_effect_throw( side_effect_expr_throwt &expr) { @@ -390,18 +274,6 @@ void jsil_typecheckt::typecheck_expr_side_effect_throw( typecheck_symbol_expr(s); } -/*******************************************************************\ - -Function: jsil_typecheckt::typecheck_expr_constant - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_expr_constant(exprt &expr) { if(expr.id()==ID_null) @@ -412,18 +284,6 @@ void jsil_typecheckt::typecheck_expr_constant(exprt &expr) expr.type()=jsil_empty_type(); } -/*******************************************************************\ - -Function: jsil_typecheck_baset::typecheck_expr_proto_field - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_expr_proto_field(exprt &expr) { if(expr.operands().size()!=2) @@ -440,18 +300,6 @@ void jsil_typecheckt::typecheck_expr_proto_field(exprt &expr) expr.type()=jsil_value_or_empty_type(); } -/*******************************************************************\ - -Function: jsil_typecheck_baset::typecheck_expr_proto_field - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_expr_proto_obj(exprt &expr) { if(expr.operands().size()!=2) @@ -468,18 +316,6 @@ void jsil_typecheckt::typecheck_expr_proto_obj(exprt &expr) expr.type()=bool_typet(); } -/*******************************************************************\ - -Function: jsil_typecheck_baset::typecheck_expr_delete - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_expr_delete(exprt &expr) { if(expr.operands().size()!=2) @@ -496,18 +332,6 @@ void jsil_typecheckt::typecheck_expr_delete(exprt &expr) expr.type()=bool_typet(); } -/*******************************************************************\ - -Function: jsil_typecheck_baset::typecheck_expr_hasfield - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_expr_index(exprt &expr) { if(expr.operands().size()!=2) @@ -528,18 +352,6 @@ void jsil_typecheckt::typecheck_expr_index(exprt &expr) expr.type()=jsil_value_type(); } -/*******************************************************************\ - -Function: jsil_typecheck_baset::typecheck_expr_hasfield - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_expr_has_field(exprt &expr) { if(expr.operands().size()!=2) @@ -556,18 +368,6 @@ void jsil_typecheckt::typecheck_expr_has_field(exprt &expr) expr.type()=bool_typet(); } -/*******************************************************************\ - -Function: jsil_typecheck_baset::typecheck_expr_field - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_expr_field(exprt &expr) { if(expr.operands().size()!=1) @@ -583,18 +383,6 @@ void jsil_typecheckt::typecheck_expr_field(exprt &expr) expr.type()=string_typet(); } -/*******************************************************************\ - -Function: jsil_typecheck_baset::typecheck_expr_base - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_expr_base(exprt &expr) { if(expr.operands().size()!=1) @@ -610,18 +398,6 @@ void jsil_typecheckt::typecheck_expr_base(exprt &expr) expr.type()=jsil_value_type(); } -/*******************************************************************\ - -Function: jsil_typecheck_baset::typecheck_expr_ref - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_expr_ref(exprt &expr) { if(expr.operands().size()!=3) @@ -652,18 +428,6 @@ void jsil_typecheckt::typecheck_expr_ref(exprt &expr) } } -/*******************************************************************\ - -Function: jsil_typecheck_baset::typecheck_expr_concatenation - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_expr_concatenation(exprt &expr) { if(expr.operands().size()!=2) @@ -680,18 +444,6 @@ void jsil_typecheckt::typecheck_expr_concatenation(exprt &expr) expr.type()=string_typet(); } -/*******************************************************************\ - -Function: jsil_typecheck_baset::typecheck_expr_subtype - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_expr_subtype(exprt &expr) { if(expr.operands().size()!=2) @@ -708,18 +460,6 @@ void jsil_typecheckt::typecheck_expr_subtype(exprt &expr) expr.type()=bool_typet(); } -/*******************************************************************\ - -Function: jsil_typecheck_baset::typecheck_expr_binary_boolean - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_expr_binary_boolean(exprt &expr) { if(expr.operands().size()!=2) @@ -736,18 +476,6 @@ void jsil_typecheckt::typecheck_expr_binary_boolean(exprt &expr) expr.type()=bool_typet(); } -/*******************************************************************\ - -Function: jsil_typecheck_baset::typecheck_expr_binary_arith - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_expr_binary_arith(exprt &expr) { if(expr.operands().size()!=2) @@ -765,18 +493,6 @@ void jsil_typecheckt::typecheck_expr_binary_arith(exprt &expr) expr.type()=floatbv_typet(); } -/*******************************************************************\ - -Function: jsil_typecheck_baset::typecheck_exp_binary_equal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_exp_binary_equal(exprt &expr) { if(expr.operands().size()!=2) @@ -792,18 +508,6 @@ void jsil_typecheckt::typecheck_exp_binary_equal(exprt &expr) expr.type()=bool_typet(); } -/*******************************************************************\ - -Function: jsil_typecheck_baset::typecheck_expr_binary_compare - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_expr_binary_compare(exprt &expr) { if(expr.operands().size()!=2) @@ -820,18 +524,6 @@ void jsil_typecheckt::typecheck_expr_binary_compare(exprt &expr) expr.type()=bool_typet(); } -/*******************************************************************\ - -Function: jsil_typecheck_baset::typecheck_expr_unary_boolean - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_expr_unary_boolean(exprt &expr) { if(expr.operands().size()!=1) @@ -847,18 +539,6 @@ void jsil_typecheckt::typecheck_expr_unary_boolean(exprt &expr) expr.type()=bool_typet(); } -/*******************************************************************\ - -Function: jsil_typecheck_baset::typecheck_expr_unary_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_expr_unary_string(exprt &expr) { if(expr.operands().size()!=1) @@ -874,18 +554,6 @@ void jsil_typecheckt::typecheck_expr_unary_string(exprt &expr) expr.type()=floatbv_typet(); } -/*******************************************************************\ - -Function: jsil_typecheck_baset::typecheck_expr_unary_num - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_expr_unary_num(exprt &expr) { if(expr.operands().size()!=1) @@ -899,18 +567,6 @@ void jsil_typecheckt::typecheck_expr_unary_num(exprt &expr) make_type_compatible(expr.op0(), floatbv_typet(), true); } -/*******************************************************************\ - -Function: jsil_typecheckt::typecheck_symbol_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_symbol_expr(symbol_exprt &symbol_expr) { irep_idt identifier=symbol_expr.get_identifier(); @@ -989,18 +645,6 @@ void jsil_typecheckt::typecheck_symbol_expr(symbol_exprt &symbol_expr) } } -/*******************************************************************\ - -Function: jsil_typecheckt::typecheck_code - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_code(codet &code) { const irep_idt &statement=code.get_statement(); @@ -1049,54 +693,18 @@ void jsil_typecheckt::typecheck_code(codet &code) } } -/*******************************************************************\ - -Function: jsil_typecheckt::typecheck_return - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_return(code_returnt &code) { if(code.has_return_value()) typecheck_expr(code.return_value()); } -/*******************************************************************\ - -Function: jsil_typecheckt::typecheck_block - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_block(codet &code) { Forall_operands(it, code) typecheck_code(to_code(*it)); } -/*******************************************************************\ - -Function: jsil_typecheckt::typecheck_try_catch - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_try_catch(code_try_catcht &code) { // A special case of try catch with one catch clause @@ -1115,18 +723,6 @@ void jsil_typecheckt::typecheck_try_catch(code_try_catcht &code) typecheck_code(code.get_catch_code(0)); } -/*******************************************************************\ - -Function: jsil_typecheckt::typecheck_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_function_call( code_function_callt &call) { @@ -1229,18 +825,6 @@ void jsil_typecheckt::typecheck_function_call( } } -/*******************************************************************\ - -Function: jsil_typecheckt::typecheck_ifthenelse - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_ifthenelse(code_ifthenelset &code) { exprt &cond=code.cond(); @@ -1253,18 +837,6 @@ void jsil_typecheckt::typecheck_ifthenelse(code_ifthenelset &code) typecheck_code(to_code(code.else_case())); } -/*******************************************************************\ - -Function: jsil_typecheckt::typecheck_assign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck_assign(code_assignt &code) { typecheck_expr(code.op0()); @@ -1273,20 +845,9 @@ void jsil_typecheckt::typecheck_assign(code_assignt &code) make_type_compatible(code.op0(), code.op1().type(), false); } -/*******************************************************************\ - -Function: java_bytecode_typecheckt::typecheck_non_type_symbol - - Inputs: any symbol - - Outputs: - - Purpose: typecheking procedure declaration; any other symbols - should have been typechecked during typecheking of procedure - declaration - -\*******************************************************************/ - +/// typechecking procedure declaration; any other symbols should have been +/// typechecked during typechecking of procedure declaration +/// \par parameters: any symbol void jsil_typecheckt::typecheck_non_type_symbol(symbolt &symbol) { assert(!symbol.is_type); @@ -1319,18 +880,6 @@ void jsil_typecheckt::typecheck_non_type_symbol(symbolt &symbol) } } -/*******************************************************************\ - -Function: java_bytecode_typecheckt::typecheck - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsil_typecheckt::typecheck() { // The hash table iterators are not stable, @@ -1361,18 +910,6 @@ void jsil_typecheckt::typecheck() } } -/*******************************************************************\ - -Function: jsil_typecheck - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool jsil_typecheck( symbol_tablet &symbol_table, message_handlert &message_handler) @@ -1381,23 +918,14 @@ bool jsil_typecheck( return jsil_typecheck.typecheck_main(); } -/*******************************************************************\ - -Function: jsil_typecheck - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool jsil_typecheck( exprt &expr, message_handlert &message_handler, const namespacet &ns) { + const unsigned errors_before= + message_handler.get_message_count(messaget::M_ERROR); + symbol_tablet symbol_table; jsil_typecheckt jsil_typecheck( @@ -1424,5 +952,5 @@ bool jsil_typecheck( jsil_typecheck.error() << e << messaget::eom; } - return jsil_typecheck.get_error_found(); + return message_handler.get_message_count(messaget::M_ERROR)!=errors_before; } diff --git a/src/jsil/jsil_typecheck.h b/src/jsil/jsil_typecheck.h index 68988a80273..bca8bde2089 100644 --- a/src/jsil/jsil_typecheck.h +++ b/src/jsil/jsil_typecheck.h @@ -6,6 +6,9 @@ Author: Michael Tautschnig, tautschn@amazon.com \*******************************************************************/ +/// \file +/// Jsil Language + #ifndef CPROVER_JSIL_JSIL_TYPECHECK_H #define CPROVER_JSIL_JSIL_TYPECHECK_H @@ -15,7 +18,7 @@ Author: Michael Tautschnig, tautschn@amazon.com #include #include - +class symbol_exprt; class codet; bool jsil_typecheck( diff --git a/src/jsil/jsil_types.cpp b/src/jsil/jsil_types.cpp index ffccfd16bbe..12a76787149 100644 --- a/src/jsil/jsil_types.cpp +++ b/src/jsil/jsil_types.cpp @@ -6,21 +6,12 @@ Author: Daiva Naudziuniene, daivan@amazon.com \*******************************************************************/ -#include +/// \file +/// Jsil Language #include "jsil_types.h" -/*******************************************************************\ - -Function: jsil_any_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include typet jsil_any_type() { @@ -31,18 +22,6 @@ typet jsil_any_type() }); } -/*******************************************************************\ - -Function: jsil_value_or_empty_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet jsil_value_or_empty_type() { return jsil_union_typet({ // NOLINT(whitespace/braces) @@ -51,18 +30,6 @@ typet jsil_value_or_empty_type() }); } -/*******************************************************************\ - -Function: jsil_value_or_reference_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet jsil_value_or_reference_type() { return jsil_union_typet({ // NOLINT(whitespace/braces) @@ -71,18 +38,6 @@ typet jsil_value_or_reference_type() }); } -/*******************************************************************\ - -Function: jsil_value_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet jsil_value_type() { return jsil_union_typet({ // NOLINT(whitespace/braces) @@ -93,18 +48,6 @@ typet jsil_value_type() }); } -/*******************************************************************\ - -Function: jsil_prim_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet jsil_prim_type() { return jsil_union_typet({ // NOLINT(whitespace/braces) @@ -114,18 +57,6 @@ typet jsil_prim_type() }); } -/*******************************************************************\ - -Function: jsil_reference_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet jsil_reference_type() { return jsil_union_typet({ // NOLINT(whitespace/braces) @@ -134,52 +65,16 @@ typet jsil_reference_type() }); } -/*******************************************************************\ - -Function: jsil_member_reference_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet jsil_member_reference_type() { return typet("jsil_member_reference_type"); } -/*******************************************************************\ - -Function: jsil_variable_reference_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet jsil_variable_reference_type() { return typet("jsil_variable_reference_type"); } -/*******************************************************************\ - -Function: jsil_object_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet jsil_object_type() { return jsil_union_typet({ // NOLINT(whitespace/braces) @@ -188,120 +83,36 @@ typet jsil_object_type() }); } -/*******************************************************************\ - -Function: jsil_user_object_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet jsil_user_object_type() { return typet("jsil_user_object_type"); } -/*******************************************************************\ - -Function: jsil_builtin_object_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet jsil_builtin_object_type() { return typet("jsil_builtin_object_type"); } -/*******************************************************************\ - -Function: jsil_null_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet jsil_null_type() { return typet("jsil_null_type"); } -/*******************************************************************\ - -Function: jsil_undefined_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet jsil_undefined_type() { return typet("jsil_undefined_type"); } -/*******************************************************************\ - -Function: jsil_kind - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet jsil_kind() { return typet("jsil_kind"); } -/*******************************************************************\ - -Function: jsil_empty_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet jsil_empty_type() { return typet("jsil_empty_type"); } -/*******************************************************************\ - -Function: jsil_is_subtype - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool jsil_is_subtype(const typet &type1, const typet &type2) { if(type2.id()==ID_union) @@ -317,54 +128,18 @@ bool jsil_is_subtype(const typet &type1, const typet &type2) return type1.id()==type2.id(); } -/*******************************************************************\ - -Function: jsil_incompatible_types - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool jsil_incompatible_types(const typet &type1, const typet &type2) { return jsil_union_typet(type1).intersect_with( jsil_union_typet(type2)).components().empty(); } -/*******************************************************************\ - -Function: jsil_union - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet jsil_union(const typet &type1, const typet &type2) { return jsil_union_typet(type1) .union_with(jsil_union_typet(type2)).to_type(); } -/*******************************************************************\ - -Function: compare_components - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool compare_components( const union_typet::componentt &comp1, const union_typet::componentt &comp2) @@ -372,18 +147,6 @@ bool compare_components( return comp1.type().id() &types): union_typet() { @@ -402,18 +165,6 @@ jsil_union_typet::jsil_union_typet(const std::vector &types): std::sort(elements.begin(), elements.end(), compare_components); } -/*******************************************************************\ - -Function: jsil_union_typet::union_with - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - jsil_union_typet jsil_union_typet::union_with( const jsil_union_typet &other) const { @@ -431,17 +182,6 @@ jsil_union_typet jsil_union_typet::union_with( return result; } -/*******************************************************************\ - -Function: jsil_union_typet::intersect_with - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ jsil_union_typet jsil_union_typet::intersect_with( const jsil_union_typet &other) const { @@ -459,18 +199,6 @@ jsil_union_typet jsil_union_typet::intersect_with( return result; } -/*******************************************************************\ - -Function: jsil_union_typet::is_subtype - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool jsil_union_typet::is_subtype(const jsil_union_typet &other) const { auto it=components().begin(); @@ -504,18 +232,6 @@ bool jsil_union_typet::is_subtype(const jsil_union_typet &other) const return true; } -/*******************************************************************\ - -Function: jsil_union_typet::to_type() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const typet &jsil_union_typet::to_type() const { auto &elements=components(); diff --git a/src/jsil/jsil_types.h b/src/jsil/jsil_types.h index b27be7f3219..b3b5a159b40 100644 --- a/src/jsil/jsil_types.h +++ b/src/jsil/jsil_types.h @@ -6,6 +6,9 @@ Author: Daiva Naudziuniene, daivan@amazon.com \*******************************************************************/ +/// \file +/// Jsil Language + #ifndef CPROVER_JSIL_JSIL_TYPES_H #define CPROVER_JSIL_JSIL_TYPES_H diff --git a/src/json/json_parser.cpp b/src/json/json_parser.cpp index 04c6d7dbfde..fb244a10f9b 100644 --- a/src/json/json_parser.cpp +++ b/src/json/json_parser.cpp @@ -6,23 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "json_parser.h" -json_parsert json_parser; - -/*******************************************************************\ - -Function: parse_json - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +json_parsert json_parser; // 'do it all' function bool parse_json( @@ -48,18 +36,6 @@ bool parse_json( return result; } -/*******************************************************************\ - -Function: parse_json - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - // 'do it all' function bool parse_json( const std::string &filename, diff --git a/src/json/json_parser.h b/src/json/json_parser.h index 2983d2542a5..d3d28aa6fa2 100644 --- a/src/json/json_parser.h +++ b/src/json/json_parser.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_JSON_JSON_PARSER_H #define CPROVER_JSON_JSON_PARSER_H diff --git a/src/langapi/Makefile b/src/langapi/Makefile index 12bc2a2f784..5d650c55c8b 100644 --- a/src/langapi/Makefile +++ b/src/langapi/Makefile @@ -1,6 +1,5 @@ SRC = language_ui.cpp \ language_util.cpp \ - languages.cpp \ mode.cpp \ # Empty last line INCLUDES= -I .. diff --git a/src/langapi/language_ui.cpp b/src/langapi/language_ui.cpp index 10816f055c5..dd6f7b63e26 100644 --- a/src/langapi/language_ui.cpp +++ b/src/langapi/language_ui.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +#include "language_ui.h" + #include #include #include @@ -15,59 +17,24 @@ Author: Daniel Kroening, kroening@cs.cmu.edu #include #include -#include "language_ui.h" #include "mode.h" -/*******************************************************************\ - -Function: language_uit::language_uit - - Inputs: - - Outputs: - - Purpose: Constructor - -\*******************************************************************/ - +/// Constructor language_uit::language_uit( const cmdlinet &cmdline, ui_message_handlert &_ui_message_handler): - ui_message_handler(_ui_message_handler), _cmdline(cmdline), + ui_message_handler(_ui_message_handler), generate_start_function(true) { set_message_handler(ui_message_handler); } -/*******************************************************************\ - -Function: language_uit::~language_uit - - Inputs: - - Outputs: - - Purpose: Destructor - -\*******************************************************************/ - +/// Destructor language_uit::~language_uit() { } -/*******************************************************************\ - -Function: language_uit::parse() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool language_uit::parse() { for(unsigned i=0; i<_cmdline.args.size(); i++) @@ -79,18 +46,6 @@ bool language_uit::parse() return false; } -/*******************************************************************\ - -Function: language_uit::parse() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool language_uit::parse(const std::string &filename) { #ifdef _MSC_VER @@ -114,9 +69,12 @@ bool language_uit::parse(const std::string &filename) lf.filename=filename; lf.language=get_language_from_filename(filename); - if(lf.language==NULL) + if(lf.language==nullptr) { - error("failed to figure out type of file", filename); + source_locationt location; + location.set_file(filename); + error().source_location=location; + error() << "failed to figure out type of file" << eom; return true; } @@ -128,8 +86,8 @@ bool language_uit::parse(const std::string &filename) if(language.parse(infile, filename)) { - if(get_ui()==ui_message_handlert::PLAIN) - std::cerr << "PARSING ERROR" << std::endl; + if(get_ui()==ui_message_handlert::uit::PLAIN) + std::cerr << "PARSING ERROR\n"; return true; } @@ -139,18 +97,6 @@ bool language_uit::parse(const std::string &filename) return false; } -/*******************************************************************\ - -Function: language_uit::typecheck - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool language_uit::typecheck() { status() << "Converting" << eom; @@ -166,18 +112,6 @@ bool language_uit::typecheck() return false; } -/*******************************************************************\ - -Function: language_uit::final - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool language_uit::final() { language_files.set_message_handler(*message_handler); @@ -191,27 +125,15 @@ bool language_uit::final() return false; } -/*******************************************************************\ - -Function: language_uit::show_symbol_table - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void language_uit::show_symbol_table(bool brief) { switch(get_ui()) { - case ui_message_handlert::PLAIN: + case ui_message_handlert::uit::PLAIN: show_symbol_table_plain(std::cout, brief); break; - case ui_message_handlert::XML_UI: + case ui_message_handlert::uit::XML_UI: show_symbol_table_xml_ui(brief); break; @@ -220,41 +142,17 @@ void language_uit::show_symbol_table(bool brief) } } -/*******************************************************************\ - -Function: language_uit::show_symbol_table_xml_ui - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void language_uit::show_symbol_table_xml_ui(bool brief) { error() << "cannot show symbol table in this format" << eom; } -/*******************************************************************\ - -Function: language_uit::show_symbol_table_plain - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void language_uit::show_symbol_table_plain( std::ostream &out, bool brief) { if(!brief) - out << '\n' << "Symbols:" << '\n' << std::endl; + out << "\nSymbols:\n\n"; // we want to sort alphabetically std::set symbols; @@ -275,7 +173,7 @@ void language_uit::show_symbol_table_plain( else { ptr=get_language_from_mode(symbol.mode); - if(ptr==NULL) + if(ptr==nullptr) throw "symbol "+id2string(symbol.name)+" has unknown mode"; } @@ -290,7 +188,7 @@ void language_uit::show_symbol_table_plain( if(brief) { - out << symbol.name << " " << type_str << std::endl; + out << symbol.name << " " << type_str << '\n'; continue; } diff --git a/src/langapi/language_ui.h b/src/langapi/language_ui.h index c9cf36cec2b..ce61cbdbdec 100644 --- a/src/langapi/language_ui.h +++ b/src/langapi/language_ui.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ + #ifndef CPROVER_LANGAPI_LANGUAGE_UI_H #define CPROVER_LANGAPI_LANGUAGE_UI_H @@ -48,10 +49,9 @@ class language_uit:public messaget return ui_message_handler.get_ui(); } - ui_message_handlert &ui_message_handler; - protected: const cmdlinet &_cmdline; + ui_message_handlert &ui_message_handler; bool generate_start_function; }; diff --git a/src/langapi/language_util.cpp b/src/langapi/language_util.cpp index fcd639827b7..9d7095ad07a 100644 --- a/src/langapi/language_util.cpp +++ b/src/langapi/language_util.cpp @@ -1,10 +1,7 @@ -/*******************************************************************\ +// Copyright 2016-2017 DiffBlue Limited. All Rights Reserved. -Module: -Author: Daniel Kroening, kroening@cs.cmu.edu - -\*******************************************************************/ +#include "language_util.h" #include @@ -14,21 +11,8 @@ Author: Daniel Kroening, kroening@cs.cmu.edu #include #include "pretty_printer.h" -#include "language_util.h" #include "mode.h" -/*******************************************************************\ - -Function: get_language - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static languaget* get_language( const namespacet &ns, const irep_idt &identifier) @@ -42,7 +26,7 @@ static languaget* get_language( languaget *ptr=get_language_from_mode(symbol->mode); - if(ptr==NULL) + if(ptr==nullptr) throw "symbol `"+id2string(symbol->name)+ "' has unknown mode '"+id2string(symbol->mode)+"'"; @@ -51,73 +35,49 @@ static languaget* get_language( std::vector registered_pretty_printers; -/*******************************************************************\ - -Function: register_global_pretty_printer - - Inputs: `new_printer`: factory method returning - `unique_ptr` - - Outputs: - - Purpose: This registers a custom pretty-printer for use printing - expressions with `from_expr` and `from_type` also defined - in language_util.h. The function given should allocate - an instance of the printer and return a unique_ptr that - disposes of it appropriately (so if allocated with `new`, - ordinary `std::unique_ptr` will do the trick). - `from_expr` and `from_type` will always build a stack of - printer classes of the form: - L -> C1 -> C2 ... Cn -> X - - L is the language frontend pretty-printer associated - with an expression, C1 ... Cn are instances of the registered - custom printers in order of registration, and X is the fallback - irep-to-lisp printer `norep_pretty_printert`. The -> arrows - represent `next_pretty_printer` fields used to defer printing - of expressions a particular printer can't handle; all printers - in the stack also get `top_pretty_printer` set to point at L, - which they should use when printing subexpressions to give - the whole stack a chance to provide a representation. - - Note at present language custom printers such as `expr2javat` - are subclasses of `expr2ct` rather than using this deferral - mechanism; thus even when a Java expression is being printed - there is still only one L in the stack, rather than - expr2javat -> expr2ct -> C1 ... Cn -> X - as one might expect. The language printers (in particular - expr2ct) always assume they are at the top of the stack - (so top_pretty_printer == this), and will need adapting if - we want to e.g. place a custom printer *above* expr2ct - in the future. - -\*******************************************************************/ - +/// This registers a custom pretty-printer for use printing expressions with +/// `from_expr` and `from_type` also defined in language_util.h. The function +/// given should allocate an instance of the printer and return a unique_ptr +/// that disposes of it appropriately (so if allocated with `new`, ordinary +/// `std::unique_ptr` will do the trick). `from_expr` and `from_type` will +/// always build a stack of printer classes of the form: L -> C1 -> C2 ... Cn -> +/// X +/// +/// L is the language frontend pretty-printer associated +/// with an expression, C1 ... Cn are instances of the registered +/// custom printers in order of registration, and X is the fallback +/// irep-to-lisp printer `norep_pretty_printert`. The -> arrows +/// represent `next_pretty_printer` fields used to defer printing +/// of expressions a particular printer can't handle; all printers +/// in the stack also get `top_pretty_printer` set to point at L, +/// which they should use when printing subexpressions to give +/// the whole stack a chance to provide a representation. +/// +/// Note at present language custom printers such as `expr2javat` +/// are subclasses of `expr2ct` rather than using this deferral +/// mechanism; thus even when a Java expression is being printed +/// there is still only one L in the stack, rather than +/// expr2javat -> expr2ct -> C1 ... Cn -> X +/// as one might expect. The language printers (in particular +/// expr2ct) always assume they are at the top of the stack +/// (so top_pretty_printer == this), and will need adapting if +/// we want to e.g. place a custom printer *above* expr2ct +/// in the future. +/// \param `new_printer`: factory method returning `unique_ptr` void register_global_pretty_printer(pretty_printer_factoryt new_printer) { registered_pretty_printers.push_back(new_printer); } -/*******************************************************************\ - -Function: get_pretty_printer_stack - - Inputs: `ns`: namespace - `language_printer`: pointer to instance of a pretty-printer - that should be placed at the head of the printer stack. - - Outputs: - - Purpose: (See `register_global_pretty_printer` above for context) - Takes a reference to language-specific pretty-printer L, - instantiates custom printers C1 .. Cn if any have been - registered, creates the fallback norep pretty-printer X, - and sets their next_ and top_pretty_printer pointers. - A vector of unique pointers is returned whose back member - is the head of the stack (L, in the notation used above). - -\*******************************************************************/ - +/// (See `register_global_pretty_printer` above for context) Takes a reference +/// to language-specific pretty-printer L, instantiates custom printers C1 .. Cn +/// if any have been registered, creates the fallback norep pretty-printer X, +/// and sets their next_ and top_pretty_printer pointers. A vector of unique +/// pointers is returned whose back member is the head of the stack (L, in the +/// notation used above). +/// \param `ns`: namespace +/// \param `language_printer`: pointer to instance of a pretty-printer that +/// should be placed at the head of the printer stack. static std::vector> get_pretty_printer_stack( const namespacet &ns, std::unique_ptr language_printer) @@ -142,24 +102,14 @@ static std::vector> get_pretty_printer_stack( return ret; } -/*******************************************************************\ - -Function: from_expr - - Inputs: `ns`: global namespace - `identifier`: symbol-table identifier associated with `expr` - or the empty string if none - `expr`: expression to print - - Outputs: Returns pretty-printed string equivalent of `expr`. - - Purpose: Pretty-prints an expression. If custom pretty-printers have - been registered they will be instantiated and may take part - in printing `expr`; see `register_global_pretty_printer` for - details. - -\*******************************************************************/ - +/// Pretty-prints an expression. If custom pretty-printers have been registered +/// they will be instantiated and may take part in printing `expr`; see +/// `register_global_pretty_printer` for details. +/// \param `ns`: global namespace +/// \param `identifier`: symbol-table identifier associated with `expr` or the +/// empty string if none +/// \param `expr`: expression to print +/// \return Returns pretty-printed string equivalent of `expr`. std::string from_expr( const namespacet &ns, const irep_idt &identifier, @@ -170,24 +120,14 @@ std::string from_expr( return printers.back()->convert(expr); } -/*******************************************************************\ - -Function: from_type - - Inputs: `ns`: global namespace - `identifier`: symbol-table identifier associated with `type` - or the empty string if none - `type`: type to print - - Outputs: Returns pretty-printed string equivalent of `type`. - - Purpose: Pretty-prints an type. If custom pretty-printers have - been registered they will be instantiated and may take part - in printing `type`; see `register_global_pretty_printer` for - details. - -\*******************************************************************/ - +/// Pretty-prints an type. If custom pretty-printers have been registered they +/// will be instantiated and may take part in printing `type`; see +/// `register_global_pretty_printer` for details. +/// \param `ns`: global namespace +/// \param `identifier`: symbol-table identifier associated with `type` or the +/// empty string if none +/// \param `type`: type to print +/// \return Returns pretty-printed string equivalent of `type`. std::string from_type( const namespacet &ns, const irep_idt &identifier, @@ -198,18 +138,6 @@ std::string from_type( return printers.back()->convert(type); } -/*******************************************************************\ - -Function: type_to_name - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string type_to_name( const namespacet &ns, const irep_idt &identifier, @@ -223,54 +151,18 @@ std::string type_to_name( return result; } -/*******************************************************************\ - -Function: from_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string from_expr(const exprt &expr) { symbol_tablet symbol_table; return from_expr(namespacet(symbol_table), "", expr); } -/*******************************************************************\ - -Function: from_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string from_type(const typet &type) { symbol_tablet symbol_table; return from_type(namespacet(symbol_table), "", type); } -/*******************************************************************\ - -Function: to_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt to_expr( const namespacet &ns, const irep_idt &identifier, @@ -278,6 +170,9 @@ exprt to_expr( { std::unique_ptr p(get_language(ns, identifier)); + null_message_handlert null_message_handler; + p->set_message_handler(null_message_handler); + const symbolt &symbol=ns.lookup(identifier); exprt expr; @@ -288,18 +183,6 @@ exprt to_expr( return expr; } -/*******************************************************************\ - -Function: type_to_name - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string type_to_name(const typet &type) { symbol_tablet symbol_table; diff --git a/src/langapi/language_util.h b/src/langapi/language_util.h index dd538c0b128..44517857085 100644 --- a/src/langapi/language_util.h +++ b/src/langapi/language_util.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ + #ifndef CPROVER_LANGAPI_LANGUAGE_UTIL_H #define CPROVER_LANGAPI_LANGUAGE_UTIL_H diff --git a/src/langapi/languages.cpp b/src/langapi/languages.cpp deleted file mode 100644 index 31ab9d37e7a..00000000000 --- a/src/langapi/languages.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/*******************************************************************\ - -Module: - -Author: Daniel Kroening, kroening@cs.cmu.edu - -\*******************************************************************/ - -#include "languages.h" - -/*******************************************************************\ - -Function: languagest::languagest - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -languagest::languagest(const namespacet &_ns, languaget *_language):ns(_ns) -{ - language=_language; -} - -/*******************************************************************\ - -Function: languagest::~languagest - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -languagest::~languagest() -{ - delete language; -} diff --git a/src/langapi/languages.h b/src/langapi/languages.h deleted file mode 100644 index 0c8dda97ada..00000000000 --- a/src/langapi/languages.h +++ /dev/null @@ -1,47 +0,0 @@ -/*******************************************************************\ - -Module: - -Author: Daniel Kroening, kroening@cs.cmu.edu - -\*******************************************************************/ - -#ifndef CPROVER_LANGAPI_LANGUAGES_H -#define CPROVER_LANGAPI_LANGUAGES_H - -#include - -class languagest -{ -public: - // conversion of expressions - - bool from_expr(const exprt &expr, std::string &code) - { - return language->from_expr(expr, code, ns); - } - - bool from_type(const typet &type, std::string &code) - { - return language->from_type(type, code, ns); - } - - bool to_expr( - const std::string &code, - const std::string &module, - exprt &expr) - { - return language->to_expr(code, module, expr, ns); - } - - // constructor / destructor - - languagest(const namespacet &_ns, languaget *_language); - virtual ~languagest(); - -protected: - const namespacet &ns; - languaget *language; -}; - -#endif // CPROVER_LANGAPI_LANGUAGES_H diff --git a/src/langapi/mode.cpp b/src/langapi/mode.cpp index 525a9519afd..2c3a852b73a 100644 --- a/src/langapi/mode.cpp +++ b/src/langapi/mode.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ +#include "mode.h" + #include #include #include @@ -16,8 +18,6 @@ Author: Daniel Kroening, kroening@cs.cmu.edu #include -#include "mode.h" - struct language_entryt { language_factoryt factory; @@ -28,18 +28,6 @@ struct language_entryt typedef std::list languagest; languagest languages; -/*******************************************************************\ - -Function: register_language - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void register_language(language_factoryt factory) { languages.push_back(language_entryt()); @@ -49,18 +37,6 @@ void register_language(language_factoryt factory) languages.back().mode=l->id(); } -/*******************************************************************\ - -Function: get_language_from_mode - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - languaget *get_language_from_mode(const irep_idt &mode) { for(languagest::const_iterator it=languages.begin(); @@ -69,33 +45,21 @@ languaget *get_language_from_mode(const irep_idt &mode) if(mode==it->mode) return it->factory(); - return NULL; + return nullptr; } -/*******************************************************************\ - -Function: get_language_from_filename - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - languaget *get_language_from_filename(const std::string &filename) { std::size_t ext_pos=filename.rfind('.'); if(ext_pos==std::string::npos) - return NULL; + return nullptr; std::string extension= std::string(filename, ext_pos+1, std::string::npos); if(extension=="") - return NULL; + return nullptr; for(languagest::const_iterator l_it=languages.begin(); @@ -115,21 +79,9 @@ languaget *get_language_from_filename(const std::string &filename) #endif } - return NULL; + return nullptr; } -/*******************************************************************\ - -Function: get_default_language - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - languaget *get_default_language() { assert(!languages.empty()); diff --git a/src/langapi/mode.h b/src/langapi/mode.h index 5e0f8cf83f6..e8cf679d0e2 100644 --- a/src/langapi/mode.h +++ b/src/langapi/mode.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ + #ifndef CPROVER_LANGAPI_MODE_H #define CPROVER_LANGAPI_MODE_H diff --git a/src/langapi/pretty_printer.h b/src/langapi/pretty_printer.h index a9684533b21..40ab4ec6ef0 100644 --- a/src/langapi/pretty_printer.h +++ b/src/langapi/pretty_printer.h @@ -6,6 +6,9 @@ Author: Chris Smowton, chris.smowton@diffblue.com \*******************************************************************/ +/// \file +/// Generic expression / type pretty-printer + #ifndef CPROVER_LANGAPI_PRETTY_PRINTER_H #define CPROVER_LANGAPI_PRETTY_PRINTER_H diff --git a/src/linking/linking.cpp b/src/linking/linking.cpp index 173d5b2cf4c..cdd8c2df8d8 100644 --- a/src/linking/linking.cpp +++ b/src/linking/linking.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// ANSI-C Linking + +#include "linking.h" + #include #include @@ -19,21 +24,8 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "linking.h" #include "linking_class.h" -/*******************************************************************\ - -Function: linkingt::expr_to_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string linkingt::expr_to_string( const namespacet &ns, const irep_idt &identifier, @@ -42,18 +34,6 @@ std::string linkingt::expr_to_string( return from_expr(ns, identifier, expr); } -/*******************************************************************\ - -Function: linkingt::type_to_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string linkingt::type_to_string( const namespacet &ns, const irep_idt &identifier, @@ -62,18 +42,6 @@ std::string linkingt::type_to_string( return from_type(ns, identifier, type); } -/*******************************************************************\ - -Function: follow_tags_symbols - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static const typet &follow_tags_symbols( const namespacet &ns, const typet &type) @@ -90,18 +58,6 @@ static const typet &follow_tags_symbols( return type; } -/*******************************************************************\ - -Function: linkingt::type_to_string_verbose - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string linkingt::type_to_string_verbose( const namespacet &ns, const symbolt &symbol, @@ -156,18 +112,6 @@ std::string linkingt::type_to_string_verbose( return type_to_string(ns, symbol.name, type); } -/*******************************************************************\ - -Function: linkingt::detailed_conflict_report - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void linkingt::detailed_conflict_report_rec( const symbolt &old_symbol, const symbolt &new_symbol, @@ -422,18 +366,6 @@ void linkingt::detailed_conflict_report_rec( #endif } -/*******************************************************************\ - -Function: linkingt::link_error - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void linkingt::link_error( const symbolt &old_symbol, const symbolt &new_symbol, @@ -454,18 +386,6 @@ void linkingt::link_error( throw 0; } -/*******************************************************************\ - -Function: linkingt::link_warning - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void linkingt::link_warning( const symbolt &old_symbol, const symbolt &new_symbol, @@ -484,18 +404,6 @@ void linkingt::link_warning( << type_to_string_verbose(ns, new_symbol) << eom; } -/*******************************************************************\ - -Function: linkingt::rename - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - irep_idt linkingt::rename(const irep_idt id) { unsigned cnt=0; @@ -520,18 +428,6 @@ irep_idt linkingt::rename(const irep_idt id) } } -/*******************************************************************\ - -Function: linkingt::needs_renaming_non_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool linkingt::needs_renaming_non_type( const symbolt &old_symbol, const symbolt &new_symbol) @@ -546,18 +442,6 @@ bool linkingt::needs_renaming_non_type( return false; } -/*******************************************************************\ - -Function: linkingt::duplicate_code_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void linkingt::duplicate_code_symbol( symbolt &old_symbol, symbolt &new_symbol) @@ -593,10 +477,16 @@ void linkingt::duplicate_code_symbol( } // handle (incomplete) function prototypes else if(base_type_eq(old_t.return_type(), new_t.return_type(), ns) && - ((old_t.parameters().empty() && old_t.has_ellipsis()) || - (new_t.parameters().empty() && new_t.has_ellipsis()))) + ((old_t.parameters().empty() && + old_t.has_ellipsis() && + old_symbol.value.is_nil()) || + (new_t.parameters().empty() && + new_t.has_ellipsis() && + new_symbol.value.is_nil()))) { - if(old_t.parameters().empty() && old_t.has_ellipsis()) + if(old_t.parameters().empty() && + old_t.has_ellipsis() && + old_symbol.value.is_nil()) { old_symbol.type=new_symbol.type; old_symbol.location=new_symbol.location; @@ -830,6 +720,7 @@ void linkingt::duplicate_code_symbol( old_symbol.value=new_symbol.value; old_symbol.type=new_symbol.type; // for parameter identifiers old_symbol.is_weak=new_symbol.is_weak; + old_symbol.location=new_symbol.location; old_symbol.is_macro=new_symbol.is_macro; } else if(to_code_type(old_symbol.type).get_inlined()) @@ -853,18 +744,6 @@ void linkingt::duplicate_code_symbol( } } -/*******************************************************************\ - -Function: linkingt::adjust_object_type_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool linkingt::adjust_object_type_rec( const typet &t1, const typet &t2, @@ -1019,18 +898,6 @@ bool linkingt::adjust_object_type_rec( return true; } -/*******************************************************************\ - -Function: linkingt::adjust_object_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool linkingt::adjust_object_type( const symbolt &old_symbol, const symbolt &new_symbol, @@ -1046,18 +913,6 @@ bool linkingt::adjust_object_type( return result; } -/*******************************************************************\ - -Function: linkingt::duplicate_object_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void linkingt::duplicate_object_symbol( symbolt &old_symbol, symbolt &new_symbol) @@ -1093,6 +948,8 @@ void linkingt::duplicate_object_symbol( } else if(set_to_new) old_symbol.type=new_symbol.type; + + object_type_updates.insert(old_symbol.name, old_symbol.symbol_expr()); } // care about initializers @@ -1142,18 +999,6 @@ void linkingt::duplicate_object_symbol( } } -/*******************************************************************\ - -Function: linkingt::duplicate_non_type_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void linkingt::duplicate_non_type_symbol( symbolt &old_symbol, symbolt &new_symbol) @@ -1183,18 +1028,6 @@ void linkingt::duplicate_non_type_symbol( old_symbol.is_extern=old_symbol.is_extern && new_symbol.is_extern; } -/*******************************************************************\ - -Function: linkingt::duplicate_type_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void linkingt::duplicate_type_symbol( symbolt &old_symbol, symbolt &new_symbol) @@ -1272,18 +1105,6 @@ void linkingt::duplicate_type_symbol( "unexpected difference between type symbols"); } -/*******************************************************************\ - -Function: linkingt::needs_renaming_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool linkingt::needs_renaming_type( const symbolt &old_symbol, const symbolt &new_symbol) @@ -1328,18 +1149,6 @@ bool linkingt::needs_renaming_type( return true; // different } -/*******************************************************************\ - -Function: linkingt::do_type_dependencies - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void linkingt::do_type_dependencies(id_sett &needs_to_be_renamed) { // Any type that uses a symbol that will be renamed also @@ -1395,18 +1204,6 @@ void linkingt::do_type_dependencies(id_sett &needs_to_be_renamed) } } -/*******************************************************************\ - -Function: linkingt::rename_symbols - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void linkingt::rename_symbols(const id_sett &needs_to_be_renamed) { namespacet src_ns(src_symbol_table); @@ -1439,18 +1236,6 @@ void linkingt::rename_symbols(const id_sett &needs_to_be_renamed) } } -/*******************************************************************\ - -Function: linkingt::copy_symbols - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void linkingt::copy_symbols() { // First apply the renaming @@ -1501,19 +1286,16 @@ void linkingt::copy_symbols() else duplicate_non_type_symbol(old_symbol, new_symbol); } -} - -/*******************************************************************\ -Function: linkingt::typecheck - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ + // Apply type updates to initializers + Forall_symbols(s_it, main_symbol_table.symbols) + { + if(!s_it->second.is_type && + !s_it->second.is_macro && + s_it->second.value.is_not_nil()) + object_type_updates(s_it->second.value); + } +} void linkingt::typecheck() { @@ -1551,18 +1333,6 @@ void linkingt::typecheck() copy_symbols(); } -/*******************************************************************\ - -Function: linking - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool linking( symbol_tablet &dest_symbol_table, symbol_tablet &new_symbol_table, diff --git a/src/linking/linking.h b/src/linking/linking.h index 22b54e55613..b565a65231e 100644 --- a/src/linking/linking.h +++ b/src/linking/linking.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// ANSI-C Linking + #ifndef CPROVER_LINKING_LINKING_H #define CPROVER_LINKING_LINKING_H diff --git a/src/linking/linking_class.h b/src/linking/linking_class.h index dba9481f3ab..d3fa633af2f 100644 --- a/src/linking/linking_class.h +++ b/src/linking/linking_class.h @@ -6,11 +6,15 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// ANSI-C Linking + #ifndef CPROVER_LINKING_LINKING_CLASS_H #define CPROVER_LINKING_LINKING_CLASS_H #include #include +#include #include #include @@ -31,6 +35,7 @@ class linkingt:public typecheckt virtual void typecheck(); rename_symbolt rename_symbol; + replace_symbolt object_type_updates; protected: typedef std::unordered_set id_sett; diff --git a/src/linking/remove_internal_symbols.cpp b/src/linking/remove_internal_symbols.cpp index 5b4a7b13625..4755515200e 100644 --- a/src/linking/remove_internal_symbols.cpp +++ b/src/linking/remove_internal_symbols.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening \*******************************************************************/ +/// \file +/// Remove symbols that are internal only + +#include "remove_internal_symbols.h" + #include #include #include @@ -13,20 +18,6 @@ Author: Daniel Kroening #include #include -#include "remove_internal_symbols.h" - -/*******************************************************************\ - -Function: get_symbols_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void get_symbols_rec( const namespacet &ns, const symbolt &symbol, @@ -70,25 +61,15 @@ void get_symbols_rec( } } -/*******************************************************************\ - -Function: remove_internal_symbols - - Inputs: symbol table - - Outputs: symbol table, with internal symbols removed - - Purpose: A symbol is EXPORTED if it is a - * non-static function with body that is not extern inline - * symbol used in an EXPORTED symbol - * type used in an EXPORTED symbol - - Read - http://gcc.gnu.org/ml/gcc/2006-11/msg00006.html - on "extern inline" - -\*******************************************************************/ - +/// A symbol is EXPORTED if it is a * non-static function with body that is not +/// extern inline * symbol used in an EXPORTED symbol * type used in an EXPORTED +/// symbol +/// +/// Read +/// http://gcc.gnu.org/ml/gcc/2006-11/msg00006.html +/// on "extern inline" +/// \par parameters: symbol table +/// \return symbol table, with internal symbols removed void remove_internal_symbols( symbol_tablet &symbol_table) { diff --git a/src/linking/remove_internal_symbols.h b/src/linking/remove_internal_symbols.h index 40711162e73..f9d8a465162 100644 --- a/src/linking/remove_internal_symbols.h +++ b/src/linking/remove_internal_symbols.h @@ -6,6 +6,9 @@ Author: Daniel Kroening \*******************************************************************/ +/// \file +/// Remove symbols that are internal only + #ifndef CPROVER_LINKING_REMOVE_INTERNAL_SYMBOLS_H #define CPROVER_LINKING_REMOVE_INTERNAL_SYMBOLS_H diff --git a/src/linking/static_lifetime_init.cpp b/src/linking/static_lifetime_init.cpp index 29f5005d685..2cacc49b032 100644 --- a/src/linking/static_lifetime_init.cpp +++ b/src/linking/static_lifetime_init.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "static_lifetime_init.h" + #include #include @@ -16,25 +18,12 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include +#include #include -#include "static_lifetime_init.h" #include "zero_initializer.h" -/*******************************************************************\ - -Function: static_lifetime_init - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool static_lifetime_init( symbol_tablet &symbol_table, const source_locationt &source_location, @@ -156,7 +145,6 @@ bool static_lifetime_init( // call designated "initialization" functions - #if 0 for(const std::string &id : symbols) { const symbolt &symbol=ns.lookup(id); @@ -170,7 +158,6 @@ bool static_lifetime_init( dest.move_to_operands(function_call); } } - #endif return false; } diff --git a/src/linking/static_lifetime_init.h b/src/linking/static_lifetime_init.h index da9543addf6..0955fc1f57c 100644 --- a/src/linking/static_lifetime_init.h +++ b/src/linking/static_lifetime_init.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_LINKING_STATIC_LIFETIME_INIT_H #define CPROVER_LINKING_STATIC_LIFETIME_INIT_H diff --git a/src/linking/zero_initializer.cpp b/src/linking/zero_initializer.cpp index 9e96c48480b..4e6963b6fc3 100644 --- a/src/linking/zero_initializer.cpp +++ b/src/linking/zero_initializer.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Linking: Zero Initialization + +#include "zero_initializer.h" + #include #include @@ -15,11 +20,9 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include +#include #include -#include "zero_initializer.h" - class zero_initializert:public messaget { public: @@ -56,18 +59,6 @@ class zero_initializert:public messaget const source_locationt &source_location); }; -/*******************************************************************\ - -Function: zero_initializert::zero_initializer_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt zero_initializert::zero_initializer_rec( const typet &type, const source_locationt &source_location) @@ -319,18 +310,6 @@ exprt zero_initializert::zero_initializer_rec( } } -/*******************************************************************\ - -Function: zero_initializer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt zero_initializer( const typet &type, const source_locationt &source_location, @@ -341,18 +320,6 @@ exprt zero_initializer( return z_i(type, source_location); } -/*******************************************************************\ - -Function: zero_initializer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt zero_initializer( const typet &type, const source_locationt &source_location, diff --git a/src/linking/zero_initializer.h b/src/linking/zero_initializer.h index 766fdf26784..3bb440b8b74 100644 --- a/src/linking/zero_initializer.h +++ b/src/linking/zero_initializer.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Linking: Zero Initialization + #ifndef CPROVER_LINKING_ZERO_INITIALIZER_H #define CPROVER_LINKING_ZERO_INITIALIZER_H diff --git a/src/memory-models/mm2cpp.cpp b/src/memory-models/mm2cpp.cpp index bc3eb0d9e18..65d74b89cf5 100644 --- a/src/memory-models/mm2cpp.cpp +++ b/src/memory-models/mm2cpp.cpp @@ -6,12 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "mm2cpp.h" + #include #include -#include "mm2cpp.h" - class mm2cppt { public: @@ -32,18 +32,6 @@ class mm2cppt void check_acyclic(const exprt &, unsigned indent); }; -/*******************************************************************\ - -Function: mm2cppt::text2c - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string mm2cppt::text2c(const irep_idt &src) { std::string result; @@ -61,18 +49,6 @@ std::string mm2cppt::text2c(const irep_idt &src) return result; } -/*******************************************************************\ - -Function: mm2cppt::check_acyclic - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void mm2cppt::check_acyclic(const exprt &expr, unsigned indent) { if(expr.id()==ID_symbol) @@ -154,18 +130,6 @@ void mm2cppt::check_acyclic(const exprt &expr, unsigned indent) throw "acyclic cannot do "+expr.id_string(); } -/*******************************************************************\ - -Function: mm2cppt::instruction2cpp - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void mm2cppt::instruction2cpp(const codet &code, unsigned indent) { const irep_idt &statement=code.get_statement(); @@ -216,18 +180,6 @@ void mm2cppt::instruction2cpp(const codet &code, unsigned indent) } } -/*******************************************************************\ - -Function: mm2cpp - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void mm2cppt::operator()(const irept &instruction) { out << "// Generated by mmcc\n"; @@ -248,18 +200,6 @@ void mm2cppt::operator()(const irept &instruction) out << '\n'; } -/*******************************************************************\ - -Function: mm2cpp - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void mm2cpp( const irep_idt &model_name, const irept &instruction, diff --git a/src/memory-models/mm2cpp.h b/src/memory-models/mm2cpp.h index 1d6c45ee2b7..99d43d15ccb 100644 --- a/src/memory-models/mm2cpp.h +++ b/src/memory-models/mm2cpp.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_MEMORY_MODELS_MM2CPP_H #define CPROVER_MEMORY_MODELS_MM2CPP_H diff --git a/src/memory-models/mm_parser.cpp b/src/memory-models/mm_parser.cpp index e631543489a..15b0aee55d3 100644 --- a/src/memory-models/mm_parser.cpp +++ b/src/memory-models/mm_parser.cpp @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #include "mm_parser.h" mm_parsert mm_parser; diff --git a/src/memory-models/mm_parser.h b/src/memory-models/mm_parser.h index 11240cf8786..847e31687cf 100644 --- a/src/memory-models/mm_parser.h +++ b/src/memory-models/mm_parser.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_MEMORY_MODELS_MM_PARSER_H #define CPROVER_MEMORY_MODELS_MM_PARSER_H diff --git a/src/memory-models/mmcc_main.cpp b/src/memory-models/mmcc_main.cpp index a30d45515d5..962c5bbf527 100644 --- a/src/memory-models/mmcc_main.cpp +++ b/src/memory-models/mmcc_main.cpp @@ -6,21 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// mmcc Main Module #include "mmcc_parse_options.h" -/*******************************************************************\ - -Function: main / wmain - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include #ifdef _MSC_VER int wmain(int argc, const wchar_t **argv_wide) diff --git a/src/memory-models/mmcc_parse_options.cpp b/src/memory-models/mmcc_parse_options.cpp index 859393f9726..8fae9244839 100644 --- a/src/memory-models/mmcc_parse_options.cpp +++ b/src/memory-models/mmcc_parse_options.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// mmcc Command Line Option Processing + +#include "mmcc_parse_options.h" + #include #include @@ -15,42 +20,18 @@ Author: Daniel Kroening, kroening@kroening.com #include "mm_parser.h" #include "mm2cpp.h" -#include "mmcc_parse_options.h" - -/*******************************************************************\ - -Function: mmcc_parse_optionst::mmcc_parse_optionst - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ mmcc_parse_optionst::mmcc_parse_optionst(int argc, const char **argv): parse_options_baset(MMCC_OPTIONS, argc, argv) { } -/*******************************************************************\ - -Function: mmcc_parse_optionst::doit - - Inputs: - - Outputs: - - Purpose: invoke main modules - -\*******************************************************************/ - +/// invoke main modules int mmcc_parse_optionst::doit() { if(cmdline.isset("version")) { - std::cout << CBMC_VERSION << std::endl; + std::cout << CBMC_VERSION << '\n'; return 0; } @@ -68,7 +49,7 @@ int mmcc_parse_optionst::doit() return convert(in, cmdline.args[0]); } - else if(cmdline.args.size()==0) + else if(cmdline.args.empty()) { return convert(std::cin, "stdin"); } @@ -92,18 +73,6 @@ int mmcc_parse_optionst::doit() return 0; } -/*******************************************************************\ - -Function: mmcc_parse_optionst::convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - int mmcc_parse_optionst::convert( std::istream &in, const std::string &file) @@ -125,18 +94,7 @@ int mmcc_parse_optionst::convert( return 0; } -/*******************************************************************\ - -Function: mmcc_parse_optionst::help - - Inputs: - - Outputs: - - Purpose: display command line help - -\*******************************************************************/ - +/// display command line help void mmcc_parse_optionst::help() { std::cout << diff --git a/src/memory-models/mmcc_parse_options.h b/src/memory-models/mmcc_parse_options.h index 07745b47944..357ae91df20 100644 --- a/src/memory-models/mmcc_parse_options.h +++ b/src/memory-models/mmcc_parse_options.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// mmcc Command Line Option Processing + #ifndef CPROVER_MEMORY_MODELS_MMCC_PARSE_OPTIONS_H #define CPROVER_MEMORY_MODELS_MMCC_PARSE_OPTIONS_H diff --git a/src/musketeer/cycles_visitor.cpp b/src/musketeer/cycles_visitor.cpp index c5fc1402311..08bbe4bea96 100644 --- a/src/musketeer/cycles_visitor.cpp +++ b/src/musketeer/cycles_visitor.cpp @@ -6,10 +6,14 @@ Author: Vincent Nimal \*******************************************************************/ +/// \file +/// cycles visitor for computing edges involved for fencing + +#include "cycles_visitor.h" + #include #include -#include "cycles_visitor.h" #include "fence_inserter.h" class instrumentert; @@ -17,18 +21,6 @@ class instrumentert; /* implemented: BTWN1, BTWN4 */ #define BTWN1 -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* po^+ /\ U{C_1, ..., C_n} \/ delays */ void cycles_visitort::po_edges(std::set &edges) { @@ -253,18 +245,6 @@ void cycles_visitort::po_edges(std::set &edges) } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* C_j /\ po^+ /\ poWR */ void cycles_visitort::powr_constraint( const event_grapht::critical_cyclet &C_j, @@ -275,8 +255,9 @@ void cycles_visitort::powr_constraint( for(std::set::iterator e_i=C_j.unsafe_pairs.begin(); e_i!=C_j.unsafe_pairs.end(); ++e_i) { - if(e_i->is_po && (graph[e_i->first].operation==abstract_eventt::Write - && graph[e_i->second].operation==abstract_eventt::Read)) + if(e_i->is_po && + (graph[e_i->first].operation==abstract_eventt::operationt::Write && + graph[e_i->second].operation==abstract_eventt::operationt::Read)) { if( edges.insert(fence_inserter.add_edge(*e_i)).second ) ++fence_inserter.constraints_number; @@ -284,18 +265,6 @@ void cycles_visitort::powr_constraint( } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* C_j /\ po^+ /\ poWW */ void cycles_visitort::poww_constraint( const event_grapht::critical_cyclet &C_j, @@ -306,8 +275,9 @@ void cycles_visitort::poww_constraint( for(std::set::iterator e_i=C_j.unsafe_pairs.begin(); e_i!=C_j.unsafe_pairs.end(); ++e_i) { - if(e_i->is_po && (graph[e_i->first].operation==abstract_eventt::Write - && graph[e_i->second].operation==abstract_eventt::Write)) + if(e_i->is_po && + (graph[e_i->first].operation==abstract_eventt::operationt::Write && + graph[e_i->second].operation==abstract_eventt::operationt::Write)) { if( edges.insert(fence_inserter.add_edge(*e_i)).second ) ++fence_inserter.constraints_number; @@ -315,18 +285,6 @@ void cycles_visitort::poww_constraint( } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* C_j /\ po^+ /\ poRW */ void cycles_visitort::porw_constraint( const event_grapht::critical_cyclet &C_j, @@ -337,8 +295,9 @@ void cycles_visitort::porw_constraint( for(std::set::iterator e_i=C_j.unsafe_pairs.begin(); e_i!=C_j.unsafe_pairs.end(); ++e_i) { - if(e_i->is_po && (graph[e_i->first].operation==abstract_eventt::Read - && graph[e_i->second].operation==abstract_eventt::Write)) + if(e_i->is_po && + (graph[e_i->first].operation==abstract_eventt::operationt::Read && + graph[e_i->second].operation==abstract_eventt::operationt::Write)) { if( edges.insert(fence_inserter.add_edge(*e_i)).second ) ++fence_inserter.constraints_number; @@ -346,18 +305,6 @@ void cycles_visitort::porw_constraint( } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* C_j /\ po^+ /\ poRR */ void cycles_visitort::porr_constraint( const event_grapht::critical_cyclet &C_j, @@ -368,8 +315,9 @@ void cycles_visitort::porr_constraint( for(std::set::iterator e_i=C_j.unsafe_pairs.begin(); e_i!=C_j.unsafe_pairs.end(); ++e_i) { - if(e_i->is_po && (graph[e_i->first].operation==abstract_eventt::Read - && graph[e_i->second].operation==abstract_eventt::Read)) + if(e_i->is_po && + (graph[e_i->first].operation==abstract_eventt::operationt::Read && + graph[e_i->second].operation==abstract_eventt::operationt::Read)) { if( edges.insert(fence_inserter.add_edge(*e_i)).second ) ++fence_inserter.constraints_number; @@ -377,18 +325,6 @@ void cycles_visitort::porr_constraint( } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* C_j /\ comWR */ void cycles_visitort::com_constraint( const event_grapht::critical_cyclet &C_j, @@ -400,8 +336,8 @@ void cycles_visitort::com_constraint( it!=C_j.unsafe_pairs.end(); ++it) { - if(egraph[it->first].operation==abstract_eventt::Write - && egraph[it->second].operation==abstract_eventt::Read + if(egraph[it->first].operation==abstract_eventt::operationt::Write + && egraph[it->second].operation==abstract_eventt::operationt::Read && egraph[it->first].thread!=egraph[it->second].thread) if( edges.insert(fence_inserter.add_invisible_edge(*it)).second ) ++fence_inserter.constraints_number; @@ -412,7 +348,7 @@ void cycles_visitort::com_constraint( std::list::const_iterator e_it=C_j.begin(); std::list::const_iterator next_it=e_it; - assert(C_j.size()>0); + assert(!C_j.empty()); ++next_it; for(; next_it!=C_j.end() && e_it!=C_j.end(); ++e_it, ++next_it) { diff --git a/src/musketeer/cycles_visitor.h b/src/musketeer/cycles_visitor.h index f125b511668..0b9b122eed8 100644 --- a/src/musketeer/cycles_visitor.h +++ b/src/musketeer/cycles_visitor.h @@ -6,6 +6,9 @@ Author: Vincent Nimal \*******************************************************************/ +/// \file +/// cycles visitor for computing edges involved for fencing + #ifndef CPROVER_MUSKETEER_CYCLES_VISITOR_H #define CPROVER_MUSKETEER_CYCLES_VISITOR_H diff --git a/src/musketeer/fence_assert.cpp b/src/musketeer/fence_assert.cpp index 06bea8537fc..d44faf74689 100644 --- a/src/musketeer/fence_assert.cpp +++ b/src/musketeer/fence_assert.cpp @@ -7,19 +7,10 @@ Author: Vincent Nimal \*******************************************************************/ -#include "fence_assert.h" - -/*******************************************************************\ - -Function: - - Inputs: +/// \file +/// ILP construction for cycles affecting user-assertions and resolution - Outputs: - - Purpose: - -\*******************************************************************/ +#include "fence_assert.h" bool fence_assert_insertert::find_assert( const event_grapht::critical_cyclet &cycle) const @@ -28,18 +19,6 @@ bool fence_assert_insertert::find_assert( return true; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void fence_assert_insertert::process_cycles_selection() { for(std::set::const_iterator diff --git a/src/musketeer/fence_assert.h b/src/musketeer/fence_assert.h index 7e18e1f8e56..bc21b8b5319 100644 --- a/src/musketeer/fence_assert.h +++ b/src/musketeer/fence_assert.h @@ -7,6 +7,9 @@ Author: Vincent Nimal \*******************************************************************/ +/// \file +/// ILP construction for cycles affecting user-assertions and resolution + #ifndef CPROVER_MUSKETEER_FENCE_ASSERT_H #define CPROVER_MUSKETEER_FENCE_ASSERT_H diff --git a/src/musketeer/fence_inserter.cpp b/src/musketeer/fence_inserter.cpp index 20236dfb956..cd1aaa910f5 100644 --- a/src/musketeer/fence_inserter.cpp +++ b/src/musketeer/fence_inserter.cpp @@ -6,6 +6,11 @@ Author: Vincent Nimal \*******************************************************************/ +/// \file +/// ILP construction for all cycles and resolution + +#include "fence_inserter.h" + #include #include @@ -16,23 +21,10 @@ Author: Vincent Nimal #include #endif -#include "fence_inserter.h" #include "ilp.h" class abstract_eventt; -/*******************************************************************\ - -Function: fence_insertert::fence_cost - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - unsigned fence_insertert::fence_cost(fence_typet f) const { switch(f) @@ -52,18 +44,6 @@ unsigned fence_insertert::fence_cost(fence_typet f) const return 0; } -/*******************************************************************\ - -Function: fence_insertert::compute - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void fence_insertert::compute() { compute_fence_options(); @@ -76,18 +56,6 @@ void fence_insertert::compute() instrumenter.message.result() << "no cycle concerned" << messaget::eom; } -/*******************************************************************\ - -Function: fence_insertert::preprocess - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void fence_insertert::preprocess() { process_cycles_selection(); @@ -239,18 +207,6 @@ void fence_insertert::preprocess() } } -/*******************************************************************\ - -Function: fence_insertert::mip_set_var - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void inline fence_insertert::mip_set_var( ilpt &ilp, unsigned &i) @@ -353,18 +309,6 @@ void inline fence_insertert::mip_set_var( #endif } -/*******************************************************************\ - -Function: fence_insertert::mip_set_cst - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void inline fence_insertert::mip_set_cst(ilpt &ilp, unsigned &i) { #ifdef HAVE_GLPK @@ -459,18 +403,6 @@ void inline fence_insertert::mip_set_cst(ilpt &ilp, unsigned &i) #endif } -/*******************************************************************\ - -Function: fence_insertert::mip_fill_matrix - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void inline fence_insertert::mip_fill_matrix( ilpt &ilp, unsigned &i, @@ -768,18 +700,6 @@ void inline fence_insertert::mip_fill_matrix( #endif } -/*******************************************************************\ - -Function: fence_insertert::solve() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void fence_insertert::solve() { #ifdef HAVE_GLPK @@ -889,35 +809,11 @@ void fence_insertert::solve() #endif } -/*******************************************************************\ - -Function: fence_insertert::import_freq - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void fence_insertert::import_freq() { /* TODO */ } -/*******************************************************************\ - -Function: fence_insertert::print_to_file - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void fence_insertert::print_to_file() { /* removes redundant (due to several call to the same fenced function) */ @@ -931,7 +827,7 @@ void fence_insertert::print_to_file() s << to_string(it->second) << "|" << first.source_location.get_file() << "|" << first.source_location.get_line() << "|" - << first.source_location.get_column() << std::endl; + << first.source_location.get_column() << '\n'; non_redundant_display.insert(s.str()); } @@ -944,18 +840,6 @@ void fence_insertert::print_to_file() results.close(); } -/*******************************************************************\ - -Function: fence_insertert::print_to_file_2 - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* prints final results */ void fence_insertert::print_to_file_2() { @@ -972,7 +856,7 @@ void fence_insertert::print_to_file_2() s << to_string(it->second) << "|" << first.source_location.get_file() << "|" << first.source_location.get_line() << "|" << second.source_location.get_file() - << "|" << second.source_location.get_line() << std::endl; + << "|" << second.source_location.get_line() << '\n'; non_redundant_display.insert(s.str()); } @@ -985,18 +869,6 @@ void fence_insertert::print_to_file_2() results.close(); } -/*******************************************************************\ - -Function: fence_insertert::print_to_file_3 - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* prints final results */ void fence_insertert::print_to_file_3() { @@ -1018,7 +890,7 @@ void fence_insertert::print_to_file_3() << second.source_location.get_file() << "|" << second.source_location.get_function() << "|" << second.source_location.get_line() - << "|" << second.variable << std::endl; + << "|" << second.variable << '\n'; non_redundant_display.insert(s.str()); } catch(std::string s) @@ -1038,18 +910,6 @@ void fence_insertert::print_to_file_3() results.close(); } -/*******************************************************************\ - -Function: fence_insertert::print_to_file_4 - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* prints final results */ void fence_insertert::print_to_file_4() { @@ -1074,7 +934,7 @@ void fence_insertert::print_to_file_4() << second.source_location.get_function() << "|" << second.source_location.get_line() << "|" << second.variable << "|" - << get_type(second.variable).get("#c_type") << std::endl; + << get_type(second.variable).get("#c_type") << '\n'; non_redundant_display.insert(s.str()); } catch (std::string s) @@ -1094,18 +954,6 @@ void fence_insertert::print_to_file_4() results.close(); } -/*******************************************************************\ - -Function: fence_insertert::to_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string fence_insertert::to_string(fence_typet f) const { switch(f) @@ -1119,35 +967,11 @@ std::string fence_insertert::to_string(fence_typet f) const assert(0); } -/*******************************************************************\ - -Function: fence_inserter::col_to_var - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - inline unsigned fence_insertert::col_to_var(unsigned u) const { return (u-u%fence_options)/fence_options+(u%fence_options!=0?1:0); } -/*******************************************************************\ - -Function: fence_insertert::col_to_fence - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - inline fence_insertert::fence_typet fence_insertert::col_to_fence(unsigned u) const { @@ -1162,18 +986,6 @@ inline fence_insertert::fence_typet fence_insertert::col_to_fence(unsigned u) assert(0); } -/*******************************************************************\ - -Function: fence_insertert::var_fence_to_col - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - inline unsigned fence_insertert::var_fence_to_col(fence_typet f, unsigned var) const { @@ -1188,18 +1000,6 @@ inline unsigned fence_insertert::var_fence_to_col(fence_typet f, unsigned var) assert(0); } -/*******************************************************************\ - -Function: fence_insertert::compute_fence_options - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void fence_insertert::compute_fence_options() { switch(model) @@ -1218,18 +1018,6 @@ void fence_insertert::compute_fence_options() } } -/*******************************************************************\ - -Function: fence_insertert::print_vars - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void fence_insertert::print_vars() const { instrumenter.message.statistics() @@ -1249,18 +1037,6 @@ void fence_insertert::print_vars() const << messaget::eom; } -/*******************************************************************\ - -Function: fence_insertert::get_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet fence_insertert::get_type(const irep_idt &id) { std::string copy=id2string(id); @@ -1306,18 +1082,6 @@ typet fence_insertert::get_type(const irep_idt &id) } } -/*******************************************************************\ - -Function: fence_insertert::type_component - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet fence_insertert::type_component( std::list::const_iterator it, std::list::const_iterator end, diff --git a/src/musketeer/fence_inserter.h b/src/musketeer/fence_inserter.h index 8f5e6286407..e24a32dbc11 100644 --- a/src/musketeer/fence_inserter.h +++ b/src/musketeer/fence_inserter.h @@ -6,6 +6,9 @@ Author: Vincent Nimal \*******************************************************************/ +/// \file +/// ILP construction for all cycles and resolution + #ifndef CPROVER_MUSKETEER_FENCE_INSERTER_H #define CPROVER_MUSKETEER_FENCE_INSERTER_H @@ -61,7 +64,7 @@ class fence_insertert instrumentert &instrumenter; - /* normal variables used almost everytime */ + /// normal variables used almost every time std::map &map_to_e; std::map &map_from_e; unsigned add_edge(const edget &e) { return var.add_edge(e); } @@ -70,11 +73,11 @@ class fence_insertert return invisible_var.add_edge(e); } - /* number of contraints */ + /// number of constraints std::size_t constraints_number; const memory_modelt model; - /* to retrieve the concrete graph edges involved in the (abstract) cycles */ + /// to retrieve the concrete graph edges involved in the (abstract) cycles const_graph_visitort const_graph_visitor; protected: @@ -100,7 +103,7 @@ class fence_insertert void preprocess(); void solve(); - typedef enum {Fence=0, Dp=1, Lwfence=2, Branching=3, Ctlfence=4} fence_typet; + enum fence_typet { Fence=0, Dp=1, Lwfence=2, Branching=3, Ctlfence=4 }; virtual unsigned fence_cost(fence_typet e) const; std::string to_string(fence_typet f) const; diff --git a/src/musketeer/fence_shared.cpp b/src/musketeer/fence_shared.cpp index 61d3651baf1..4dc970c513d 100644 --- a/src/musketeer/fence_shared.cpp +++ b/src/musketeer/fence_shared.cpp @@ -6,6 +6,8 @@ Author: Vincent Nimal \*******************************************************************/ +#include "fence_shared.h" + #include #include #include @@ -23,14 +25,12 @@ Author: Vincent Nimal #include // #include -#include "fence_shared.h" - #ifdef LOCAL_MAY #include #endif #define OUTPUT(s, fence, file, line, id, type) \ - s<::const_iterator diff --git a/src/musketeer/fence_user_def.h b/src/musketeer/fence_user_def.h index 1f95a4c84cf..04a1236fd46 100644 --- a/src/musketeer/fence_user_def.h +++ b/src/musketeer/fence_user_def.h @@ -7,6 +7,9 @@ Author: Vincent Nimal \*******************************************************************/ +/// \file +/// ILP construction for cycles containing user-placed fences and resolution + #ifndef CPROVER_MUSKETEER_FENCE_USER_DEF_H #define CPROVER_MUSKETEER_FENCE_USER_DEF_H diff --git a/src/musketeer/fencer.cpp b/src/musketeer/fencer.cpp index 4fc213908d4..f62917df4e6 100644 --- a/src/musketeer/fencer.cpp +++ b/src/musketeer/fencer.cpp @@ -6,6 +6,11 @@ Author: Vincent Nimal \*******************************************************************/ +/// \file +/// Fence inference: Main + +#include "fencer.h" + #include #include @@ -16,19 +21,6 @@ Author: Vincent Nimal #include "fence_inserter.h" #include "fence_user_def.h" #include "fence_assert.h" -#include "fencer.h" - -/*******************************************************************\ - -Function: fencer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ void fence_weak_memory( memory_modelt model, @@ -120,7 +112,7 @@ void fence_weak_memory( << " cycles found" << messaget::eom; /* if no cycle, no need to instrument */ - if(instrumenter.set_of_cycles.size() == 0) + if(instrumenter.set_of_cycles.empty()) { message.result() << "program safe -- no need to place additional fences" diff --git a/src/musketeer/fencer.h b/src/musketeer/fencer.h index cc28d439497..b15cb631971 100644 --- a/src/musketeer/fencer.h +++ b/src/musketeer/fencer.h @@ -6,6 +6,9 @@ Author: Vincent Nimal \*******************************************************************/ +/// \file +/// Fence inference + #ifndef CPROVER_MUSKETEER_FENCER_H #define CPROVER_MUSKETEER_FENCER_H diff --git a/src/musketeer/graph_visitor.cpp b/src/musketeer/graph_visitor.cpp index d7f94938819..87fe14e0cbf 100644 --- a/src/musketeer/graph_visitor.cpp +++ b/src/musketeer/graph_visitor.cpp @@ -6,24 +6,16 @@ Author: Vincent Nimal \*******************************************************************/ -#include "fence_inserter.h" +/// \file +/// graph visitor for computing edges involved for fencing + #include "graph_visitor.h" +#include "fence_inserter.h" + /* implemented: BTWN1, BTWN4 */ #define BTWN1 -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void const_graph_visitort::graph_explore( event_grapht &egraph, event_idt next, @@ -44,7 +36,7 @@ void const_graph_visitort::graph_explore( edges.insert(fence_inserter.add_edge(edget(*it, *next_it))); } } - else if(egraph.po_out(next).size()==0) + else if(egraph.po_out(next).empty()) { /* this path is not connecting a to b => return */ } @@ -66,18 +58,6 @@ void const_graph_visitort::graph_explore( } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void const_graph_visitort::const_graph_explore( event_grapht &egraph, event_idt next, @@ -97,7 +77,7 @@ void const_graph_visitort::const_graph_explore( fence_inserter.add_edge(edget(*it, *next_it)); } } - else if(egraph.po_out(next).size()==0) + else if(egraph.po_out(next).empty()) { /* this path is not connecting a to b => return */ } @@ -119,18 +99,6 @@ void const_graph_visitort::const_graph_explore( } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void const_graph_visitort::graph_explore_BC( event_grapht &egraph, event_idt next, @@ -139,7 +107,7 @@ void const_graph_visitort::graph_explore_BC( bool porw) { /* TODO: restricts to C_1 U ... U C_n for perf improvement */ - assert(old_path.size()>0); + assert(!old_path.empty()); fence_inserter.instrumenter.message.debug() << "(BC) explore " << old_path.front() @@ -162,7 +130,7 @@ void const_graph_visitort::graph_explore_BC( break; } - if(egraph.po_out(next).size()==0 || no_other_pos) + if(egraph.po_out(next).empty() || no_other_pos) { /* inserts all the pos collected from old_path in edges */ std::list::const_iterator it=old_path.begin(); @@ -173,8 +141,8 @@ void const_graph_visitort::graph_explore_BC( const abstract_eventt &e1=egraph[*it]; const abstract_eventt &e2=egraph[*next_it]; if(!porw || - (e1.operation==abstract_eventt::Read && - e2.operation==abstract_eventt::Write)) + (e1.operation==abstract_eventt::operationt::Read && + e2.operation==abstract_eventt::operationt::Write)) edges.insert(fence_inserter.add_edge(edget(*it, *next_it))); } assert(it!=old_path.end()); @@ -193,18 +161,6 @@ void const_graph_visitort::graph_explore_BC( } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void const_graph_visitort::const_graph_explore_BC( event_grapht &egraph, event_idt next, @@ -229,7 +185,7 @@ void const_graph_visitort::const_graph_explore_BC( break; } - if(egraph.po_out(next).size()==0 || no_other_pos) + if(egraph.po_out(next).empty() || no_other_pos) { /* inserts all the pos collected from old_path in edges */ std::list::const_iterator it=old_path.begin(); @@ -239,8 +195,8 @@ void const_graph_visitort::const_graph_explore_BC( { const abstract_eventt &e1=egraph[*it]; const abstract_eventt &e2=egraph[*next_it]; - if((e1.operation==abstract_eventt::Read - && e2.operation==abstract_eventt::Write)) + if((e1.operation==abstract_eventt::operationt::Read && + e2.operation==abstract_eventt::operationt::Write)) fence_inserter.add_edge(edget(*it, *next_it)); } // NEW @@ -260,18 +216,6 @@ void const_graph_visitort::const_graph_explore_BC( } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void const_graph_visitort::graph_explore_AC( event_grapht &egraph, event_idt next, @@ -301,7 +245,7 @@ void const_graph_visitort::graph_explore_AC( break; } - if(egraph.po_in(next).size()==0 || no_other_pos) + if(egraph.po_in(next).empty() || no_other_pos) { /* inserts all the pos collected from old_path in edges */ std::list::const_iterator it=old_path.begin(); @@ -312,8 +256,8 @@ void const_graph_visitort::graph_explore_AC( const abstract_eventt &e1=egraph[*next_it]; const abstract_eventt &e2=egraph[*it]; if(!porw || - (e1.operation==abstract_eventt::Read && - e2.operation==abstract_eventt::Write)) + (e1.operation==abstract_eventt::operationt::Read && + e2.operation==abstract_eventt::operationt::Write)) edges.insert(fence_inserter.add_edge(edget(*next_it, *it))); } assert(it!=old_path.end()); @@ -332,18 +276,6 @@ void const_graph_visitort::graph_explore_AC( } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void const_graph_visitort::const_graph_explore_AC( event_grapht &egraph, event_idt next, @@ -369,7 +301,7 @@ void const_graph_visitort::const_graph_explore_AC( } /* if beginning of the thread */ - if(egraph.po_in(next).size()==0 || no_other_pos) + if(egraph.po_in(next).empty() || no_other_pos) { /* inserts all the pos collected from old_path in edges */ std::list::const_iterator it=old_path.begin(); @@ -379,8 +311,8 @@ void const_graph_visitort::const_graph_explore_AC( { const abstract_eventt &e1=egraph[*next_it]; const abstract_eventt &e2=egraph[*it]; - if(e1.operation==abstract_eventt::Read && - e2.operation==abstract_eventt::Write) + if(e1.operation==abstract_eventt::operationt::Read && + e2.operation==abstract_eventt::operationt::Write) fence_inserter.add_edge(edget(*next_it, *it)); } // NEW @@ -400,18 +332,6 @@ void const_graph_visitort::const_graph_explore_AC( } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void const_graph_visitort::PT( const edget &e, std::set &edges) @@ -427,7 +347,7 @@ void const_graph_visitort::PT( #ifdef BTWN1 event_grapht &egraph=fence_inserter.instrumenter.egraph; - /* all the pos inbetween */ + /// all the pos in between for(wmm_grapht::edgest::const_iterator next_it=egraph.po_out(e.first).begin(); next_it!=egraph.po_out(e.first).end(); @@ -454,18 +374,8 @@ void const_graph_visitort::PT( edges.insert(fence_inserter.map_from_e[e]); } -/*******************************************************************\ - -Function: - - Inputs: e in comWR /\ C_j (invisible variables) - - Outputs: e's in po /\ C (problem variables) - - Purpose: - -\*******************************************************************/ - +/// \par parameters: e in comWR /\ C_j (invisible variables) +/// \return e's in po /\ C (problem variables) void const_graph_visitort::CT( const edget &edge, std::set &edges) @@ -478,9 +388,13 @@ void const_graph_visitort::CT( assert(test_first.operation!=test_second.operation); const event_idt first= - (test_first.operation==abstract_eventt::Write?edge.first:edge.second); + (test_first.operation==abstract_eventt::operationt::Write? + edge.first: + edge.second); const event_idt second= - (test_second.operation==abstract_eventt::Read?edge.second:edge.first); + (test_second.operation==abstract_eventt::operationt::Read? + edge.second: + edge.first); /* TODO: AC + restricts to C_1 U ... U C_n */ visited_nodes.clear(); @@ -515,18 +429,8 @@ void const_graph_visitort::CT( } } -/*******************************************************************\ - -Function: - - Inputs: e in comWR /\ C_j (invisible variables) - - Outputs: e's in poRW/\ C (problem variables) - - Purpose: - -\*******************************************************************/ - +/// \par parameters: e in comWR /\ C_j (invisible variables) +/// \return e's in poRW/\ C (problem variables) void const_graph_visitort::CT_not_powr( const edget &edge, std::set &edges) @@ -539,9 +443,13 @@ void const_graph_visitort::CT_not_powr( assert(test_first.operation!=test_second.operation); const event_idt first= - (test_first.operation==abstract_eventt::Write?edge.first:edge.second); + (test_first.operation==abstract_eventt::operationt::Write? + edge.first: + edge.second); const event_idt second= - (test_second.operation==abstract_eventt::Read?edge.second:edge.first); + (test_second.operation==abstract_eventt::operationt::Read? + edge.second: + edge.first); /* TODO: AC + restricts to C_1 U ... U C_n */ visited_nodes.clear(); diff --git a/src/musketeer/graph_visitor.h b/src/musketeer/graph_visitor.h index 0574cae885f..2df40b7e1d3 100644 --- a/src/musketeer/graph_visitor.h +++ b/src/musketeer/graph_visitor.h @@ -6,6 +6,9 @@ Author: Vincent Nimal \*******************************************************************/ +/// \file +/// graph visitor for computing edges involved for fencing + #ifndef CPROVER_MUSKETEER_GRAPH_VISITOR_H #define CPROVER_MUSKETEER_GRAPH_VISITOR_H diff --git a/src/musketeer/ilp.h b/src/musketeer/ilp.h index cecc47fb0a8..b8cbe4e9202 100644 --- a/src/musketeer/ilp.h +++ b/src/musketeer/ilp.h @@ -6,6 +6,9 @@ Author: Vincent Nimal \*******************************************************************/ +/// \file +/// ILP structure + #ifdef HAVE_GLPK #include #endif diff --git a/src/musketeer/infer_mode.h b/src/musketeer/infer_mode.h index 426653a1622..66ab97cdf36 100644 --- a/src/musketeer/infer_mode.h +++ b/src/musketeer/infer_mode.h @@ -6,14 +6,15 @@ \*******************************************************************/ + #ifndef CPROVER_MUSKETEER_INFER_MODE_H #define CPROVER_MUSKETEER_INFER_MODE_H -typedef enum +enum infer_modet { INFER=0, USER_DEF=1, USER_ASSERT=2 -} infer_modet; +}; #endif // CPROVER_MUSKETEER_INFER_MODE_H diff --git a/src/musketeer/languages.cpp b/src/musketeer/languages.cpp index 92ceefa1a72..8ae85e2e27a 100644 --- a/src/musketeer/languages.cpp +++ b/src/musketeer/languages.cpp @@ -6,23 +6,14 @@ Module: Language Registration \*******************************************************************/ -#include - -#include +/// \file +/// Language Registration #include "musketeer_parse_options.h" -/*******************************************************************\ - -Function: goto_instrument_parse_optionst::register_languages - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include void goto_fence_inserter_parse_optionst::register_languages() { diff --git a/src/musketeer/musketeer_main.cpp b/src/musketeer/musketeer_main.cpp index 238283400f8..b233c0080a0 100644 --- a/src/musketeer/musketeer_main.cpp +++ b/src/musketeer/musketeer_main.cpp @@ -6,19 +6,10 @@ Author: Vincent Nimal \*******************************************************************/ -#include "musketeer_parse_options.h" - -/*******************************************************************\ - -Function: main - - Inputs: +/// \file +/// Main Module - Outputs: - - Purpose: - -\*******************************************************************/ +#include "musketeer_parse_options.h" int main(int argc, const char **argv) { diff --git a/src/musketeer/musketeer_parse_options.cpp b/src/musketeer/musketeer_parse_options.cpp index ae40a2f2318..ace73687432 100644 --- a/src/musketeer/musketeer_parse_options.cpp +++ b/src/musketeer/musketeer_parse_options.cpp @@ -6,6 +6,11 @@ Module: Main Module \*******************************************************************/ +/// \file +/// Main Module + +#include "musketeer_parse_options.h" + #include #include #include @@ -39,25 +44,12 @@ Module: Main Module #include "propagate_const_function_pointers.h" #include "version.h" -#include "musketeer_parse_options.h" #include "fencer.h" #include "fence_shared.h" #include "pensieve.h" #include "replace_async.h" #include "infer_mode.h" -/*******************************************************************\ - -Function: goto_fence_inserter_parse_optionst::set_verbosity - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_fence_inserter_parse_optionst::set_verbosity() { unsigned int v=8; // default @@ -72,23 +64,12 @@ void goto_fence_inserter_parse_optionst::set_verbosity() ui_message_handler.set_verbosity(v); } -/*******************************************************************\ - -Function: goto_fence_inserter_parse_optionst::doit - - Inputs: - - Outputs: - - Purpose: invoke main modules - -\*******************************************************************/ - +/// invoke main modules int goto_fence_inserter_parse_optionst::doit() { if(cmdline.isset("version")) { - std::cout << MUSKETEER_VERSION << std::endl; + std::cout << MUSKETEER_VERSION << '\n'; return 0; } @@ -150,18 +131,6 @@ int goto_fence_inserter_parse_optionst::doit() } } -/*******************************************************************\ - -Function: goto_fence_inserter_parse_optionst::get_goto_program - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_fence_inserter_parse_optionst::get_goto_program( goto_functionst &goto_functions) { @@ -174,18 +143,6 @@ void goto_fence_inserter_parse_optionst::get_goto_program( config.set_from_symbol_table(symbol_table); } -/*******************************************************************\ - -Function: goto_fence_inserter_parse_optionst::instrument_goto_program - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_fence_inserter_parse_optionst::instrument_goto_program( goto_functionst &goto_functions) { @@ -435,18 +392,7 @@ void goto_fence_inserter_parse_optionst::instrument_goto_program( label_properties(goto_functions); } -/*******************************************************************\ - -Function: goto_fence_inserter_parse_optionst::help - - Inputs: - - Outputs: - - Purpose: display command line help - -\*******************************************************************/ - +/// display command line help void goto_fence_inserter_parse_optionst::help() { std::cout << diff --git a/src/musketeer/musketeer_parse_options.h b/src/musketeer/musketeer_parse_options.h index ca93c9de488..13d0a07ef19 100644 --- a/src/musketeer/musketeer_parse_options.h +++ b/src/musketeer/musketeer_parse_options.h @@ -6,6 +6,9 @@ Module: Command Line Parsing \*******************************************************************/ +/// \file +/// Command Line Parsing + #ifndef CPROVER_MUSKETEER_MUSKETEER_PARSE_OPTIONS_H #define CPROVER_MUSKETEER_MUSKETEER_PARSE_OPTIONS_H diff --git a/src/musketeer/pensieve.cpp b/src/musketeer/pensieve.cpp index 649182e1696..d46397f74a3 100644 --- a/src/musketeer/pensieve.cpp +++ b/src/musketeer/pensieve.cpp @@ -6,6 +6,8 @@ Author: Vincent Nimal \*******************************************************************/ +#include "pensieve.h" + #include #include #include @@ -14,20 +16,6 @@ Author: Vincent Nimal #include #include -#include "pensieve.h" - -/*******************************************************************\ - -Function: fencer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void fence_pensieve( value_setst &value_sets, symbol_tablet &symbol_table, diff --git a/src/musketeer/pensieve.h b/src/musketeer/pensieve.h index 298919f182f..9513a26c433 100644 --- a/src/musketeer/pensieve.h +++ b/src/musketeer/pensieve.h @@ -6,6 +6,9 @@ Author: Vincent Nimal \*******************************************************************/ +/// \file +/// Fence insertion following criteria of Pensieve (PPoPP'05) + #ifndef CPROVER_MUSKETEER_PENSIEVE_H #define CPROVER_MUSKETEER_PENSIEVE_H diff --git a/src/musketeer/propagate_const_function_pointers.cpp b/src/musketeer/propagate_const_function_pointers.cpp index 0fb2f0aad18..eca3648c285 100644 --- a/src/musketeer/propagate_const_function_pointers.cpp +++ b/src/musketeer/propagate_const_function_pointers.cpp @@ -6,6 +6,11 @@ Author: Vincent Nimal \*******************************************************************/ +/// \file +/// Constant Function Pointer Propagation + +#include "propagate_const_function_pointers.h" + #include #include #include @@ -20,8 +25,6 @@ Author: Vincent Nimal #include #include -#include "propagate_const_function_pointers.h" - class const_function_pointer_propagationt { protected: @@ -140,25 +143,15 @@ class const_function_pointer_propagationt } }; -/*******************************************************************\ - -Function: - - Inputs: 'it' pointing to the callsite to update, 'function' the function - actually called, 'stack_scope' the place where the constant was - defined in the call stack - - Outputs: - - Purpose: - -\*******************************************************************/ - +/// \par parameters: 'it' pointing to the callsite to update, 'function' the +/// function +/// actually called, 'stack_scope' the place where the constant was +/// defined in the call stack void const_function_pointer_propagationt::dup_caller_and_inline_callee( const symbol_exprt &const_function, unsigned stack_scope) { - assert(callsite_stack.size()>0); + assert(!callsite_stack.empty()); /* for the reconstruction of the {call,callsite}_stacks after the duplication */ @@ -216,8 +209,7 @@ void const_function_pointer_propagationt::dup_caller_and_inline_callee( it!=function_dup.body.instructions.end(); ++it) it->function=function_new_id; - assert(goto_functions.function_map[function_new_id]. - body.instructions.size()>0); + assert(goto_functions.function_map[function_new_id].body.empty()); /* removes in definition the argument leading to the const_function */ code_typet::parameterst &args=function_dup.type.parameters(); @@ -316,7 +308,7 @@ void const_function_pointer_propagationt::dup_caller_and_inline_callee( { } - message.debug() << "callsite targetted: " << (*callsite)->source_location + message.debug() << "callsite targeted: " << (*callsite)->source_location << " function: " << const_function.get_identifier() << messaget::eom; assert(it->source_location==(*callsite)->source_location); @@ -341,19 +333,8 @@ void const_function_pointer_propagationt::dup_caller_and_inline_callee( callsite_stack.swap(new_callsite_stack); } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: adds const pointers (instantiated here or propagated) passed - as arguments in the map - -\*******************************************************************/ - +/// adds const pointers (instantiated here or propagated) passed as arguments in +/// the map void const_function_pointer_propagationt::arg_stackt::add_args( const symbol_exprt &const_function, goto_programt::instructionst::iterator it) @@ -431,18 +412,6 @@ void const_function_pointer_propagationt::arg_stackt::add_args( } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void const_function_pointer_propagationt::arg_stackt::remove_args() { /* remove the parameter names */ @@ -453,18 +422,6 @@ void const_function_pointer_propagationt::arg_stackt::remove_args() } } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void const_function_pointer_propagationt::propagate( const irep_idt &function_id) { @@ -585,18 +542,6 @@ void const_function_pointer_propagationt::propagate( functions_met.erase(function_id); } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void propagate_const_function_pointers( symbol_tablet &symbol_table, goto_functionst &goto_functions, diff --git a/src/musketeer/propagate_const_function_pointers.h b/src/musketeer/propagate_const_function_pointers.h index 0749a1ac4bd..af1b5497b41 100644 --- a/src/musketeer/propagate_const_function_pointers.h +++ b/src/musketeer/propagate_const_function_pointers.h @@ -6,6 +6,9 @@ Author: Vincent Nimal \*******************************************************************/ +/// \file +/// Constant Function Pointer Propagation + #ifndef CPROVER_MUSKETEER_PROPAGATE_CONST_FUNCTION_POINTERS_H #define CPROVER_MUSKETEER_PROPAGATE_CONST_FUNCTION_POINTERS_H diff --git a/src/musketeer/replace_async.h b/src/musketeer/replace_async.h index 6ef0b710860..9f3a85e1159 100644 --- a/src/musketeer/replace_async.h +++ b/src/musketeer/replace_async.h @@ -8,6 +8,7 @@ Date: December 2013 \*******************************************************************/ + #ifndef CPROVER_MUSKETEER_REPLACE_ASYNC_H #define CPROVER_MUSKETEER_REPLACE_ASYNC_H diff --git a/src/path-symex/build_goto_trace.cpp b/src/path-symex/build_goto_trace.cpp index 9116e802742..eefb5361f5c 100644 --- a/src/path-symex/build_goto_trace.cpp +++ b/src/path-symex/build_goto_trace.cpp @@ -6,20 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "build_goto_trace.h" - -/*******************************************************************\ - -Function: build_goto_trace - - Inputs: +/// \file +/// Build Goto Trace from State History - Outputs: - - Purpose: follow state history to build a goto trace - -\*******************************************************************/ +#include "build_goto_trace.h" +/// follow state history to build a goto trace void build_goto_trace( const path_symex_statet &state, const decision_proceduret &decision_procedure, @@ -49,48 +41,48 @@ void build_goto_trace( switch(instruction.type) { case ASSIGN: - trace_step.type=goto_trace_stept::ASSIGNMENT; + trace_step.type=goto_trace_stept::typet::ASSIGNMENT; trace_step.full_lhs=step.full_lhs; trace_step.full_lhs_value=decision_procedure.get(step.ssa_lhs); break; case DECL: - trace_step.type=goto_trace_stept::DECL; + trace_step.type=goto_trace_stept::typet::DECL; trace_step.full_lhs=step.full_lhs; trace_step.lhs_object=ssa_exprt(step.full_lhs); trace_step.full_lhs_value=decision_procedure.get(step.ssa_lhs); break; case DEAD: - trace_step.type=goto_trace_stept::DEAD; + trace_step.type=goto_trace_stept::typet::DEAD; break; case ASSUME: - trace_step.type=goto_trace_stept::ASSUME; + trace_step.type=goto_trace_stept::typet::ASSUME; break; case FUNCTION_CALL: - trace_step.type=goto_trace_stept::FUNCTION_CALL; + trace_step.type=goto_trace_stept::typet::FUNCTION_CALL; break; case END_FUNCTION: - trace_step.type=goto_trace_stept::FUNCTION_RETURN; + trace_step.type=goto_trace_stept::typet::FUNCTION_RETURN; break; case START_THREAD: - trace_step.type=goto_trace_stept::SPAWN; + trace_step.type=goto_trace_stept::typet::SPAWN; break; case ATOMIC_BEGIN: - trace_step.type=goto_trace_stept::ATOMIC_BEGIN; + trace_step.type=goto_trace_stept::typet::ATOMIC_BEGIN; break; case ATOMIC_END: - trace_step.type=goto_trace_stept::ATOMIC_END; + trace_step.type=goto_trace_stept::typet::ATOMIC_END; break; default: - trace_step.type=goto_trace_stept::LOCATION; + trace_step.type=goto_trace_stept::typet::LOCATION; } goto_trace.add_step(trace_step); @@ -108,12 +100,12 @@ void build_goto_trace( trace_step.pc=state.get_instruction(); trace_step.thread_nr=state.get_current_thread(); trace_step.step_nr=step_nr; - trace_step.type=goto_trace_stept::ASSERT; + trace_step.type=goto_trace_stept::typet::ASSERT; const irep_idt &comment= instruction.source_location.get_comment(); - if(comment!=irep_idt()) + if(!comment.empty()) trace_step.comment=id2string(comment); else trace_step.comment="assertion"; diff --git a/src/path-symex/build_goto_trace.h b/src/path-symex/build_goto_trace.h index e6fd1a6d493..beb1a0e609d 100644 --- a/src/path-symex/build_goto_trace.h +++ b/src/path-symex/build_goto_trace.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Build Goto Trace from Path Symex History + // NOLINT(build/header_guard) as this file is also symlinked #ifndef CPROVER_PATH_SYMEX_BUILD_GOTO_TRACE_H #define CPROVER_PATH_SYMEX_BUILD_GOTO_TRACE_H diff --git a/src/path-symex/loc_ref.h b/src/path-symex/loc_ref.h index 9a8ea0dc341..56cbb7b19b5 100644 --- a/src/path-symex/loc_ref.h +++ b/src/path-symex/loc_ref.h @@ -6,10 +6,13 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Program Locations + #ifndef CPROVER_PATH_SYMEX_LOC_REF_H #define CPROVER_PATH_SYMEX_LOC_REF_H -#include +#include class loc_reft { diff --git a/src/path-symex/locs.cpp b/src/path-symex/locs.cpp index fa8e9c4cbbd..8827605768d 100644 --- a/src/path-symex/locs.cpp +++ b/src/path-symex/locs.cpp @@ -6,19 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "locs.h" - -/*******************************************************************\ - -Function: locst::locst - - Inputs: - - Outputs: - - Purpose: +/// \file +/// Program Locations -\*******************************************************************/ +#include "locs.h" locst::locst( const namespacet &_ns): @@ -26,18 +17,6 @@ locst::locst( { } -/*******************************************************************\ - -Function: locst::build - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void locst::build(const goto_functionst &goto_functions) { // build locations @@ -102,18 +81,6 @@ void locst::build(const goto_functionst &goto_functions) } } -/*******************************************************************\ - -Function: locst::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void locst::output(std::ostream &out) const { irep_idt function; diff --git a/src/path-symex/locs.h b/src/path-symex/locs.h index 7f626a1d2bf..67f52da1584 100644 --- a/src/path-symex/locs.h +++ b/src/path-symex/locs.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// CFG made of Program Locations, built from goto_functionst + #ifndef CPROVER_PATH_SYMEX_LOCS_H #define CPROVER_PATH_SYMEX_LOCS_H diff --git a/src/path-symex/path_replay.cpp b/src/path-symex/path_replay.cpp index 9dcb0a0c920..6044692839c 100644 --- a/src/path-symex/path_replay.cpp +++ b/src/path-symex/path_replay.cpp @@ -6,19 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "path_replay.h" - -/*******************************************************************\ - -Function: path_replayt::get_branches - - Inputs: +/// \file +/// Dense Data Structure for Path Replay - Outputs: - - Purpose: - -\*******************************************************************/ +#include "path_replay.h" void get_branches(path_symex_step_reft history) { diff --git a/src/path-symex/path_replay.h b/src/path-symex/path_replay.h index 70861e8e5a8..27b6359af9e 100644 --- a/src/path-symex/path_replay.h +++ b/src/path-symex/path_replay.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Dense Data Structure for Path Replay + #ifndef CPROVER_PATH_SYMEX_PATH_REPLAY_H #define CPROVER_PATH_SYMEX_PATH_REPLAY_H diff --git a/src/path-symex/path_symex.cpp b/src/path-symex/path_symex.cpp index eb58b330ab6..043ac0fb05c 100644 --- a/src/path-symex/path_symex.cpp +++ b/src/path-symex/path_symex.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Concrete Symbolic Transformer + +#include "path_symex.h" + #include #include #include @@ -13,31 +18,18 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include -#include +#include #include #include -#include "path_symex.h" #include "path_symex_class.h" #ifdef DEBUG #include #endif -/*******************************************************************\ - -Function: path_symext::propagate - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool path_symext::propagate(const exprt &src) { // propagate things that are 'simple enough' @@ -97,18 +89,6 @@ bool path_symext::propagate(const exprt &src) } } -/*******************************************************************\ - -Function: path_symext::assign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void path_symext::assign( path_symex_statet &state, const exprt &lhs, @@ -152,18 +132,6 @@ void path_symext::assign( assign_rec(state, _guard, ssa_lhs, ssa_rhs); } -/*******************************************************************\ - -Function: path_symext::symex_malloc - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - inline static typet c_sizeof_type_rec(const exprt &expr) { const irept &sizeof_type=expr.find(ID_C_c_sizeof_type); @@ -281,7 +249,7 @@ void path_symext::symex_malloc( if(object_type.id()==ID_array) { - rhs.type()=pointer_typet(value_symbol.type.subtype()); + rhs.type()=pointer_type(value_symbol.type.subtype()); index_exprt index_expr(value_symbol.type.subtype()); index_expr.array()=value_symbol.symbol_expr(); index_expr.index()=from_integer(0, index_type()); @@ -290,7 +258,7 @@ void path_symext::symex_malloc( else { rhs.op0()=value_symbol.symbol_expr(); - rhs.type()=pointer_typet(value_symbol.type); + rhs.type()=pointer_type(value_symbol.type); } if(rhs.type()!=lhs.type()) @@ -300,18 +268,6 @@ void path_symext::symex_malloc( } -/*******************************************************************\ - -Function: get_old_va_symb - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static irep_idt get_old_va_symbol( const path_symex_statet &state, const exprt &src) @@ -329,18 +285,6 @@ static irep_idt get_old_va_symbol( return irep_idt(); } -/*******************************************************************\ - -Function: path_symext::symex_va_arg_next - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void path_symext::symex_va_arg_next( path_symex_statet &state, const exprt &lhs, @@ -400,18 +344,6 @@ void path_symext::symex_va_arg_next( assign(state, lhs, rhs); } -/*******************************************************************\ - -Function: path_symext::assign_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void path_symext::assign_rec( path_symex_statet &state, exprt::operandst &guard, @@ -421,8 +353,8 @@ void path_symext::assign_rec( // const typet &ssa_lhs_type=state.var_map.ns.follow(ssa_lhs.type()); #ifdef DEBUG - std::cout << "assign_rec: " << ssa_lhs.pretty() << std::endl; - // std::cout << "ssa_lhs_type: " << ssa_lhs_type.id() << std::endl; + std::cout << "assign_rec: " << ssa_lhs.pretty() << '\n'; + // std::cout << "ssa_lhs_type: " << ssa_lhs_type.id() << '\n'; #endif if(ssa_lhs.id()==ID_symbol) @@ -435,8 +367,8 @@ void path_symext::assign_rec( #ifdef DEBUG const irep_idt &ssa_identifier=symbol_expr.get_identifier(); - std::cout << "SSA symbol identifier: " << ssa_identifier << std::endl; - std::cout << "full identifier: " << full_identifier << std::endl; + std::cout << "SSA symbol identifier: " << ssa_identifier << '\n'; + std::cout << "full identifier: " << full_identifier << '\n'; #endif var_mapt::var_infot &var_info=state.var_map[full_identifier]; @@ -447,7 +379,7 @@ void path_symext::assign_rec( symbol_exprt new_lhs=var_info.ssa_symbol(); #ifdef DEBUG - std::cout << "new_lhs: " << new_lhs.get_identifier() << std::endl; + std::cout << "new_lhs: " << new_lhs.get_identifier() << '\n'; #endif // record new state of lhs @@ -469,8 +401,8 @@ void path_symext::assign_rec( if(!base_type_eq(ssa_rhs.type(), new_lhs.type(), state.var_map.ns)) { #ifdef DEBUG - std::cout << "ssa_rhs: " << ssa_rhs.pretty() << std::endl; - std::cout << "new_lhs: " << new_lhs.pretty() << std::endl; + std::cout << "ssa_rhs: " << ssa_rhs.pretty() << '\n'; + std::cout << "new_lhs: " << new_lhs.pretty() << '\n'; #endif throw "assign_rec got different types"; } @@ -490,10 +422,18 @@ void path_symext::assign_rec( var_state.value=propagate(ssa_rhs)?ssa_rhs:nil_exprt(); } } + else if(ssa_lhs.id()==ID_typecast) + { + // dereferencing might yield a typecast + const exprt &new_lhs=to_typecast_expr(ssa_lhs).op(); + typecast_exprt new_rhs(ssa_rhs, new_lhs.type()); + + assign_rec(state, guard, new_lhs, new_rhs); + } else if(ssa_lhs.id()==ID_member) { #ifdef DEBUG - std::cout << "assign_rec ID_member" << std::endl; + std::cout << "assign_rec ID_member\n"; #endif const member_exprt &ssa_lhs_member_expr=to_member_expr(ssa_lhs); @@ -532,7 +472,7 @@ void path_symext::assign_rec( else if(ssa_lhs.id()==ID_index) { #ifdef DEBUG - std::cout << "assign_rec ID_index" << std::endl; + std::cout << "assign_rec ID_index\n"; #endif throw "unexpected array index on lhs"; @@ -540,7 +480,7 @@ void path_symext::assign_rec( else if(ssa_lhs.id()==ID_dereference) { #ifdef DEBUG - std::cout << "assign_rec ID_dereference" << std::endl; + std::cout << "assign_rec ID_dereference\n"; #endif throw "unexpected dereference on lhs"; @@ -548,7 +488,7 @@ void path_symext::assign_rec( else if(ssa_lhs.id()==ID_if) { #ifdef DEBUG - std::cout << "assign_rec ID_if" << std::endl; + std::cout << "assign_rec ID_if\n"; #endif const if_exprt &lhs_if_expr=to_if_expr(ssa_lhs); @@ -568,7 +508,7 @@ void path_symext::assign_rec( ssa_lhs.id()==ID_byte_extract_big_endian) { #ifdef DEBUG - std::cout << "assign_rec ID_byte_extract" << std::endl; + std::cout << "assign_rec ID_byte_extract\n"; #endif const byte_extract_exprt &byte_extract_expr= @@ -609,14 +549,30 @@ void path_symext::assign_rec( assert(operands.size()==components.size()); - for(std::size_t i=0; i &further_states) { #ifdef DEBUG - std::cout << "function_call_rec: " << function.pretty() << std::endl; + std::cout << "function_call_rec: " << function.pretty() << '\n'; #endif if(function.id()==ID_symbol) @@ -780,7 +718,7 @@ void path_symext::function_call_rec( const code_typet::parametert &function_parameter=function_parameters[i]; irep_idt identifier=function_parameter.get_identifier(); - if(identifier==irep_idt()) + if(identifier.empty()) throw "function_call " + id2string(function_identifier) + " no identifier for function parameter"; @@ -874,18 +812,6 @@ void path_symext::function_call_rec( throw "TODO: function_call "+function.id_string(); } -/*******************************************************************\ - -Function: path_symext::return_from_function - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void path_symext::return_from_function(path_symex_statet &state) { path_symex_statet::threadt &thread=state.threads[state.get_current_thread()]; @@ -921,18 +847,6 @@ void path_symext::return_from_function(path_symex_statet &state) } } -/*******************************************************************\ - -Function: path_symext::set_return_value - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void path_symext::set_return_value( path_symex_statet &state, const exprt &v) @@ -945,18 +859,6 @@ void path_symext::set_return_value( thread.call_stack.back().return_rhs=v; } -/*******************************************************************\ - -Function: path_symext::do_goto - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void path_symext::do_goto( path_symex_statet &state, std::list &further_states) @@ -986,7 +888,7 @@ void path_symext::do_goto( if(!guard.is_false()) { // branch taken case - // copy the state into 'furhter_states' + // copy the state into 'further_states' further_states.push_back(state); further_states.back().record_step(); state.history->branch=stept::BRANCH_TAKEN; @@ -1002,18 +904,6 @@ void path_symext::do_goto( state.history->guard=negated_guard; } -/*******************************************************************\ - -Function: path_symext::do_goto - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void path_symext::do_goto( path_symex_statet &state, bool taken) @@ -1050,18 +940,6 @@ void path_symext::do_goto( } } -/*******************************************************************\ - -Function: path_symext::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void path_symext::operator()( path_symex_statet &state, std::list &further_states) @@ -1073,7 +951,7 @@ void path_symext::operator()( std::cout << "path_symext::operator(): " << state.pc() << " " << instruction.type - << std::endl; + << '\n'; #endif switch(instruction.type) @@ -1224,18 +1102,6 @@ void path_symext::operator()( } } -/*******************************************************************\ - -Function: path_symext::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void path_symext::operator()(path_symex_statet &state) { std::list further_states; @@ -1244,18 +1110,6 @@ void path_symext::operator()(path_symex_statet &state) throw "path_symext got unexpected further states"; } -/*******************************************************************\ - -Function: path_symex - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void path_symex( path_symex_statet &state, std::list &further_states) @@ -1264,36 +1118,12 @@ void path_symex( path_symex(state, further_states); } -/*******************************************************************\ - -Function: path_symex - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void path_symex(path_symex_statet &state) { path_symext path_symex; path_symex(state); } -/*******************************************************************\ - -Function: path_symex_goto - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void path_symex_goto( path_symex_statet &state, bool taken) @@ -1302,18 +1132,6 @@ void path_symex_goto( path_symex.do_goto(state, taken); } -/*******************************************************************\ - -Function: path_symex_assert_fail - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void path_symex_assert_fail(path_symex_statet &state) { path_symext path_symex; diff --git a/src/path-symex/path_symex.h b/src/path-symex/path_symex.h index 731ea87608e..cc7a8912783 100644 --- a/src/path-symex/path_symex.h +++ b/src/path-symex/path_symex.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Concrete Symbolic Transformer + // NOLINT(build/header_guard) as this file is also symlinked #ifndef CPROVER_PATH_SYMEX_PATH_SYMEX_H #define CPROVER_PATH_SYMEX_PATH_SYMEX_H diff --git a/src/path-symex/path_symex_class.h b/src/path-symex/path_symex_class.h index 4eec3d4ff4c..933b871e9fa 100644 --- a/src/path-symex/path_symex_class.h +++ b/src/path-symex/path_symex_class.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Concrete Symbolic Transformer + #ifndef CPROVER_PATH_SYMEX_PATH_SYMEX_CLASS_H #define CPROVER_PATH_SYMEX_PATH_SYMEX_CLASS_H diff --git a/src/path-symex/path_symex_history.cpp b/src/path-symex/path_symex_history.cpp index 7829f72c67a..618dbbce332 100644 --- a/src/path-symex/path_symex_history.cpp +++ b/src/path-symex/path_symex_history.cpp @@ -6,25 +6,16 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - -#include - -#include +/// \file +/// History of path-based symbolic simulator #include "path_symex_history.h" -/*******************************************************************\ - -Function: path_symex_stept::output - - Inputs: - - Outputs: +#include - Purpose: +#include -\*******************************************************************/ +#include void path_symex_stept::output(std::ostream &out) const { @@ -45,18 +36,6 @@ void path_symex_stept::output(std::ostream &out) const out << "\n"; } -/*******************************************************************\ - -Function: path_symex_stept::convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void path_symex_stept::convert(decision_proceduret &dest) const { if(ssa_rhs.is_not_nil()) @@ -66,18 +45,6 @@ void path_symex_stept::convert(decision_proceduret &dest) const dest << guard; } -/*******************************************************************\ - -Function: path_symex_step_reft::build_history - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void path_symex_step_reft::build_history( std::vector &dest) const { diff --git a/src/path-symex/path_symex_history.h b/src/path-symex/path_symex_history.h index 3847138dc71..18b90beffa9 100644 --- a/src/path-symex/path_symex_history.h +++ b/src/path-symex/path_symex_history.h @@ -6,12 +6,16 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// History for path-based symbolic simulator + #ifndef CPROVER_PATH_SYMEX_PATH_SYMEX_HISTORY_H #define CPROVER_PATH_SYMEX_PATH_SYMEX_HISTORY_H #include #include +#include #include #include "loc_ref.h" @@ -32,7 +36,7 @@ class path_symex_step_reft } path_symex_step_reft(): - index(std::numeric_limits::max()), history(0) + index(std::numeric_limits::max()), history(nullptr) { } @@ -43,7 +47,8 @@ class path_symex_step_reft path_symex_historyt &get_history() const { - assert(history!=0); + INVARIANT_STRUCTURED( + history!=nullptr, nullptr_exceptiont, "history is null"); return *history; } @@ -55,7 +60,7 @@ class path_symex_step_reft void generate_successor(); - // build a forward-traversible version of the history + // build a forward-traversable version of the history void build_history(std::vector &dest) const; protected: @@ -108,6 +113,7 @@ class path_symex_stept path_symex_stept(): branch(NON_BRANCH), + thread_nr(0), guard(nil_exprt()), ssa_rhs(nil_exprt()), full_lhs(nil_exprt()), @@ -151,7 +157,8 @@ class path_symex_historyt inline void path_symex_step_reft::generate_successor() { - assert(history!=0); + INVARIANT_STRUCTURED( + history!=nullptr, nullptr_exceptiont, "history is null"); path_symex_step_reft old=*this; index=history->step_container.size(); history->step_container.push_back(path_symex_stept()); @@ -166,7 +173,8 @@ inline path_symex_step_reft &path_symex_step_reft::operator--() inline path_symex_stept &path_symex_step_reft::get() const { - assert(history!=0); + INVARIANT_STRUCTURED( + history!=nullptr, nullptr_exceptiont, "history is null"); assert(!is_nil()); return history->step_container[index]; } diff --git a/src/path-symex/path_symex_state.cpp b/src/path-symex/path_symex_state.cpp index 3dfc319d6d6..fe663da5b7c 100644 --- a/src/path-symex/path_symex_state.cpp +++ b/src/path-symex/path_symex_state.cpp @@ -6,35 +6,26 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// State of path-based symbolic simulator + +#include "path_symex_state.h" + #include #include #include -#include +#include #include #include -#include "path_symex_state.h" - #ifdef DEBUG #include #include #endif -/*******************************************************************\ - -Function: initial_state - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - path_symex_statet initial_state( var_mapt &var_map, const locst &locs, @@ -50,82 +41,28 @@ path_symex_statet initial_state( return s; } -/*******************************************************************\ - -Function: path_symex_statet::get_pc - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -loc_reft path_symex_statet::get_pc() const -{ - assert(current_threadreturn_location << std::endl; - out << std::endl; + out << " " << it->return_location << '\n'; + out << '\n'; } -/*******************************************************************\ - -Function: path_symex_statet::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void path_symex_statet::output(std::ostream &out) const { for(unsigned t=0; t + #include "locs.h" #include "var_map.h" #include "path_symex_history.h" @@ -108,11 +113,9 @@ struct path_symex_statet current_thread=_thread; } - loc_reft get_pc() const; - goto_programt::const_targett get_instruction() const { - return locs[get_pc()].target; + return locs[pc()].target; } bool is_executable() const @@ -142,6 +145,7 @@ struct path_symex_statet loc_reft pc() const { + PRECONDITION(current_thread #include #include -#include "path_symex_state.h" - #ifdef DEBUG #include #include #endif -/*******************************************************************\ - -Function: path_symex_statet::read - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt path_symex_statet::read(const exprt &src, bool propagate) { #ifdef DEBUG - // std::cout << "path_symex_statet::read " << src.pretty() << std::endl; + // std::cout << "path_symex_statet::read " << src.pretty() << '\n'; #endif // This has three phases! @@ -49,29 +40,17 @@ exprt path_symex_statet::read(const exprt &src, bool propagate) exprt tmp5=simplify_expr(tmp4, var_map.ns); #ifdef DEBUG - // std::cout << " ==> " << tmp.pretty() << std::endl; + // std::cout << " ==> " << tmp.pretty() << '\n'; #endif return tmp5; } -/*******************************************************************\ - -Function: path_symex_statet::expand_structs_and_arrays - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt path_symex_statet::expand_structs_and_arrays(const exprt &src) { #ifdef DEBUG std::cout << "expand_structs_and_arrays: " - << from_expr(var_map.ns, "", src) << std::endl; + << from_expr(var_map.ns, "", src) << '\n'; #endif const typet &src_type=var_map.ns.follow(src.type()); @@ -180,18 +159,6 @@ exprt path_symex_statet::expand_structs_and_arrays(const exprt &src) return src; } -/*******************************************************************\ - -Function: path_symex_statet::array_theory - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt path_symex_statet::array_theory(const exprt &src, bool propagate) { // top-level constant-sized arrays only right now @@ -244,25 +211,13 @@ exprt path_symex_statet::array_theory(const exprt &src, bool propagate) return src; } -/*******************************************************************\ - -Function: path_symex_statet::instantiate_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt path_symex_statet::instantiate_rec( const exprt &src, bool propagate) { #ifdef DEBUG std::cout << "instantiate_rec: " - << from_expr(var_map.ns, "", src) << std::endl; + << from_expr(var_map.ns, "", src) << '\n'; #endif // check whether this is a symbol(.member|[index])* @@ -292,7 +247,14 @@ exprt path_symex_statet::instantiate_rec( { irep_idt id="symex::nondet"+std::to_string(var_map.nondet_count); var_map.nondet_count++; - return symbol_exprt(id, src.type()); + + auxiliary_symbolt nondet_symbol; + nondet_symbol.name=id; + nondet_symbol.base_name=id; + nondet_symbol.type=src.type(); + var_map.new_symbols.add(nondet_symbol); + + return nondet_symbol.symbol_expr(); } else throw "instantiate_rec: unexpected side effect "+id2string(statement); @@ -348,18 +310,6 @@ exprt path_symex_statet::instantiate_rec( return src2; } -/*******************************************************************\ - -Function: path_symex_statet::read_symbol_member_index - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt path_symex_statet::read_symbol_member_index( const exprt &src, bool propagate) @@ -416,7 +366,7 @@ exprt path_symex_statet::read_symbol_member_index( suffix="."+id2string(member_expr.get_component_name())+suffix; } else - return nil_exprt(); // includes unions, deliberatley + return nil_exprt(); // includes unions, deliberately } else if(current.id()==ID_index) { @@ -451,7 +401,7 @@ exprt path_symex_statet::read_symbol_member_index( #ifdef DEBUG std::cout << "read_symbol_member_index_rec " << identifier - << " var_info " << var_info.full_identifier << std::endl; + << " var_info " << var_info.full_identifier << '\n'; #endif // warning: reference is not stable @@ -464,7 +414,7 @@ exprt path_symex_statet::read_symbol_member_index( else { // we do some SSA symbol - if(var_state.ssa_symbol.get_identifier()==irep_idt()) + if(var_state.ssa_symbol.get_identifier().empty()) { // produce one var_state.ssa_symbol=var_info.ssa_symbol(); @@ -474,18 +424,6 @@ exprt path_symex_statet::read_symbol_member_index( } } -/*******************************************************************\ - -Function: path_symex_statet::is_symbol_member_index - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool path_symex_statet::is_symbol_member_index(const exprt &src) const { const typet final_type=src.type(); @@ -499,7 +437,7 @@ bool path_symex_statet::is_symbol_member_index(const exprt &src) const // the loop avoids recursion while(true) { - const exprt *next=0; + const exprt *next=nullptr; if(current->id()==ID_symbol) { @@ -521,7 +459,7 @@ bool path_symex_statet::is_symbol_member_index(const exprt &src) const next=&(member_expr.struct_op()); } else - return false; // includes unions, deliberatley + return false; // includes unions, deliberately } else if(current->id()==ID_index) { @@ -534,23 +472,11 @@ bool path_symex_statet::is_symbol_member_index(const exprt &src) const return false; // next round - assert(next!=0); + INVARIANT_STRUCTURED(next!=nullptr, nullptr_exceptiont, "next is null"); current=next; } } -/*******************************************************************\ - -Function: path_symex_statet::array_index_as_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string path_symex_statet::array_index_as_string(const exprt &src) const { exprt tmp=simplify_expr(src, var_map.ns); @@ -562,18 +488,6 @@ std::string path_symex_statet::array_index_as_string(const exprt &src) const return "[*]"; } -/*******************************************************************\ - -Function: path_symex_statet::dereference_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt path_symex_statet::dereference_rec( const exprt &src, bool propagate) @@ -610,24 +524,12 @@ exprt path_symex_statet::dereference_rec( return src2; } -/*******************************************************************\ - -Function: path_symex_statet::instantiate_rec_address - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt path_symex_statet::instantiate_rec_address( const exprt &src, bool propagate) { #ifdef DEBUG - std::cout << "instantiate_rec_address: " << src.id() << std::endl; + std::cout << "instantiate_rec_address: " << src.id() << '\n'; #endif if(src.id()==ID_symbol) @@ -687,7 +589,7 @@ exprt path_symex_statet::instantiate_rec_address( { // this shouldn't really happen #ifdef DEBUG - std::cout << "SRC: " << src.pretty() << std::endl; + std::cout << "SRC: " << src.pretty() << '\n'; #endif throw "address of unexpected `"+src.id_string()+"'"; } diff --git a/src/path-symex/var_map.cpp b/src/path-symex/var_map.cpp index d981cf1cca9..96d079c48ff 100644 --- a/src/path-symex/var_map.cpp +++ b/src/path-symex/var_map.cpp @@ -6,32 +6,23 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Variable Numbering + +#include "var_map.h" + #include #include #include #include -#include "var_map.h" - -/*******************************************************************\ - -Function: var_mapt::var_infot::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - var_mapt::var_infot &var_mapt::operator()( const irep_idt &symbol, const irep_idt &suffix, const typet &type) { - assert(symbol!=irep_idt()); + assert(!symbol.empty()); std::string full_identifier= id2string(symbol)+id2string(suffix); @@ -53,18 +44,6 @@ var_mapt::var_infot &var_mapt::operator()( return result.first->second; } -/*******************************************************************\ - -Function: var_mapt::var_infot::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void var_mapt::var_infot::output(std::ostream &out) const { out << "full_identifier: " << full_identifier << "\n"; @@ -89,18 +68,6 @@ void var_mapt::var_infot::output(std::ostream &out) const out << "\n"; } -/*******************************************************************\ - -Function: var_mapt::init - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void var_mapt::init(var_infot &var_info) { if(has_prefix(id2string(var_info.symbol), "symex_dynamic::")) @@ -117,7 +84,7 @@ void var_mapt::init(var_infot &var_info) } else { - const symbolt *symbol=0; + const symbolt *symbol=nullptr; if(ns.lookup(var_info.symbol, symbol)) throw "var_mapt::init identifier \"" +id2string(var_info.full_identifier) @@ -141,36 +108,12 @@ void var_mapt::init(var_infot &var_info) var_info.number=local_count++; } -/*******************************************************************\ - -Function: var_mapt::var_infot::ssa_identifier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - irep_idt var_mapt::var_infot::ssa_identifier() const { return id2string(full_identifier)+ "#"+std::to_string(ssa_counter); } -/*******************************************************************\ - -Function: var_mapt::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void var_mapt::output(std::ostream &out) const { for(id_mapt::const_iterator diff --git a/src/path-symex/var_map.h b/src/path-symex/var_map.h index cb5c7c7d9f5..09511174cab 100644 --- a/src/path-symex/var_map.h +++ b/src/path-symex/var_map.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Variable Numbering + #ifndef CPROVER_PATH_SYMEX_VAR_MAP_H #define CPROVER_PATH_SYMEX_VAR_MAP_H @@ -14,12 +17,18 @@ Author: Daniel Kroening, kroening@kroening.com #include #include +#include +#include class var_mapt { public: explicit var_mapt(const namespacet &_ns): - ns(_ns), shared_count(0), local_count(0), nondet_count(0), dynamic_count(0) + ns(_ns.get_symbol_table(), new_symbols), + shared_count(0), + local_count(0), + nondet_count(0), + dynamic_count(0) { } @@ -89,7 +98,8 @@ class var_mapt void init(var_infot &var_info); - const namespacet &ns; + const namespacet ns; + symbol_tablet new_symbols; void output(std::ostream &) const; diff --git a/src/pointer-analysis/add_failed_symbols.cpp b/src/pointer-analysis/add_failed_symbols.cpp index 0a8f757a6d8..e8da3c0d773 100644 --- a/src/pointer-analysis/add_failed_symbols.cpp +++ b/src/pointer-analysis/add_failed_symbols.cpp @@ -6,41 +6,20 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include -#include -#include +/// \file +/// Pointer Dereferencing #include "add_failed_symbols.h" -/*******************************************************************\ - -Function: failed_symbol_id - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include +#include irep_idt failed_symbol_id(const irep_idt &id) { return id2string(id)+"$object"; } -/*******************************************************************\ - -Function: add_failed_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void add_failed_symbol(symbolt &symbol, symbol_tablet &symbol_table) { if(!symbol.is_lvalue) @@ -70,18 +49,6 @@ void add_failed_symbol(symbolt &symbol, symbol_tablet &symbol_table) } } -/*******************************************************************\ - -Function: add_failed_symbols - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void add_failed_symbols(symbol_tablet &symbol_table) { // the symbol table iterators are not stable, and @@ -102,18 +69,6 @@ void add_failed_symbols(symbol_tablet &symbol_table) } } -/*******************************************************************\ - -Function: get_failed_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt get_failed_symbol( const symbol_exprt &expr, const namespacet &ns) @@ -121,7 +76,7 @@ exprt get_failed_symbol( const symbolt &symbol=ns.lookup(expr); irep_idt failed_symbol_id=symbol.type.get(ID_C_failed_symbol); - if(failed_symbol_id==irep_idt()) + if(failed_symbol_id.empty()) return nil_exprt(); const symbolt &failed_symbol=ns.lookup(failed_symbol_id); diff --git a/src/pointer-analysis/add_failed_symbols.h b/src/pointer-analysis/add_failed_symbols.h index ce1a3b97c9a..2ae2228f564 100644 --- a/src/pointer-analysis/add_failed_symbols.h +++ b/src/pointer-analysis/add_failed_symbols.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Pointer Dereferencing + #ifndef CPROVER_POINTER_ANALYSIS_ADD_FAILED_SYMBOLS_H #define CPROVER_POINTER_ANALYSIS_ADD_FAILED_SYMBOLS_H diff --git a/src/pointer-analysis/dereference.cpp b/src/pointer-analysis/dereference.cpp index 8638dff9e67..aaf33ca18de 100644 --- a/src/pointer-analysis/dereference.cpp +++ b/src/pointer-analysis/dereference.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symbolic Execution of ANSI-C + +#include "dereference.h" + #ifdef DEBUG #include #include @@ -18,22 +23,10 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include - -#include "dereference.h" - -/*******************************************************************\ - -Function: dereferencet::operator() - - Inputs: expression, to be dereferenced - - Outputs: returns object after dereferencing - - Purpose: - -\*******************************************************************/ +#include +/// \par parameters: expression, to be dereferenced +/// \return returns object after dereferencing exprt dereferencet::operator()(const exprt &pointer) { if(pointer.type().id()!=ID_pointer) @@ -44,7 +37,7 @@ exprt dereferencet::operator()(const exprt &pointer) const typet &type=pointer.type().subtype(); #ifdef DEBUG - std::cout << "DEREF: " << from_expr(ns, "", pointer) << std::endl; + std::cout << "DEREF: " << from_expr(ns, "", pointer) << '\n'; #endif return dereference_rec( @@ -53,18 +46,6 @@ exprt dereferencet::operator()(const exprt &pointer) type); } -/*******************************************************************\ - -Function: dereferencet::read_object - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt dereferencet::read_object( const exprt &object, const exprt &offset, @@ -169,18 +150,6 @@ exprt dereferencet::read_object( return binary_exprt(object, byte_extract_id(), simplified_offset, dest_type); } -/*******************************************************************\ - -Function: dereferencet::dereference_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt dereferencet::dereference_rec( const exprt &address, const exprt &offset, @@ -235,18 +204,6 @@ exprt dereferencet::dereference_rec( } } -/*******************************************************************\ - -Function: dereferencet::dereference_if - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt dereferencet::dereference_if( const if_exprt &expr, const exprt &offset, @@ -259,18 +216,6 @@ exprt dereferencet::dereference_if( return if_exprt(expr.cond(), true_case, false_case); } -/*******************************************************************\ - -Function: dereferencet::dereference_plus - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt dereferencet::dereference_plus( const exprt &expr, const exprt &offset, @@ -306,18 +251,6 @@ exprt dereferencet::dereference_plus( return dereference_rec(pointer, new_offset, type); } -/*******************************************************************\ - -Function: dereferencet::dereference_typecast - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt dereferencet::dereference_typecast( const typecast_exprt &expr, const exprt &offset, @@ -342,7 +275,7 @@ exprt dereferencet::dereference_typecast( plus_exprt(offset, typecast_exprt(op, offset.type())); exprt new_typecast= - typecast_exprt(integer, pointer_typet(type)); + typecast_exprt(integer, pointer_type(type)); return dereference_exprt(new_typecast, type); } @@ -350,18 +283,6 @@ exprt dereferencet::dereference_typecast( throw "dereferencet: unexpected cast"; } -/*******************************************************************\ - -Function: dereferencet::type_compatible - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool dereferencet::type_compatible( const typet &object_type, const typet &dereference_type) const @@ -379,7 +300,7 @@ bool dereferencet::type_compatible( { if(to_struct_type(dereference_type).is_prefix_of( to_struct_type(object_type))) - return true; // ok, dreference_type is a prefix of object_type + return true; // ok, dereference_type is a prefix of object_type } // any code is ok diff --git a/src/pointer-analysis/dereference.h b/src/pointer-analysis/dereference.h index 5036f702cde..968395b604f 100644 --- a/src/pointer-analysis/dereference.h +++ b/src/pointer-analysis/dereference.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Pointer Dereferencing + #ifndef CPROVER_POINTER_ANALYSIS_DEREFERENCE_H #define CPROVER_POINTER_ANALYSIS_DEREFERENCE_H diff --git a/src/pointer-analysis/dereference_callback.cpp b/src/pointer-analysis/dereference_callback.cpp index c13e2f359e4..a28a51892e1 100644 --- a/src/pointer-analysis/dereference_callback.cpp +++ b/src/pointer-analysis/dereference_callback.cpp @@ -6,19 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "dereference_callback.h" - -/*******************************************************************\ - -Function: dereference_callbackt::~dereference_callbackt - - Inputs: +/// \file +/// Pointer Dereferencing - Outputs: - - Purpose: - -\*******************************************************************/ +#include "dereference_callback.h" dereference_callbackt::~dereference_callbackt() { diff --git a/src/pointer-analysis/dereference_callback.h b/src/pointer-analysis/dereference_callback.h index 9d9d1b69449..d02ea726f4b 100644 --- a/src/pointer-analysis/dereference_callback.h +++ b/src/pointer-analysis/dereference_callback.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Pointer Dereferencing + #ifndef CPROVER_POINTER_ANALYSIS_DEREFERENCE_CALLBACK_H #define CPROVER_POINTER_ANALYSIS_DEREFERENCE_CALLBACK_H diff --git a/src/pointer-analysis/dynamic_object_name.cpp b/src/pointer-analysis/dynamic_object_name.cpp index 0446a15eb4d..58cf50c23c7 100644 --- a/src/pointer-analysis/dynamic_object_name.cpp +++ b/src/pointer-analysis/dynamic_object_name.cpp @@ -10,6 +10,9 @@ Date: April 2017 \*******************************************************************/ +/// \file +/// Dynamic object name + #include "dynamic_object_name.h" // We use std::string concatenation regularly with this string diff --git a/src/pointer-analysis/dynamic_object_name.h b/src/pointer-analysis/dynamic_object_name.h index ade83d59e02..e2d42a4f828 100644 --- a/src/pointer-analysis/dynamic_object_name.h +++ b/src/pointer-analysis/dynamic_object_name.h @@ -10,6 +10,9 @@ Date: April 2017 \*******************************************************************/ +/// \file +/// Dynamic object name + #ifndef CPROVER_POINTER_ANALYSIS_DYNAMIC_OBJECT_NAME_H #define CPROVER_POINTER_ANALYSIS_DYNAMIC_OBJECT_NAME_H @@ -19,23 +22,12 @@ Date: April 2017 extern const std::string prefix_dynamic_object; -/*******************************************************************\ - -Function: get_dynamic_object_name - - Inputs: dynamic_object: The dynamic-object. - - Outputs: The name of the dynamic-object, composed of the - "value_set::dynamic_object", - it's instance, - and the keyword "most_recent_allocation" or - "any_allocation". - - Purpose: To generate a name for dynamic-objects suitable for use - in the LHS of value-set maps. - -\*******************************************************************/ - +/// To generate a name for dynamic-objects suitable for use in the LHS of value- +/// set maps. +/// \param dynamic_object: The dynamic-object. +/// \return The name of the dynamic-object, composed of the +/// "value_set::dynamic_object", it's instance, and the keyword +/// "most_recent_allocation" or "any_allocation". inline std::string get_dynamic_object_name( const dynamic_object_exprt &dynamic_object) { diff --git a/src/pointer-analysis/goto_program_dereference.cpp b/src/pointer-analysis/goto_program_dereference.cpp index 2ccce3f7a47..857f9e722fc 100644 --- a/src/pointer-analysis/goto_program_dereference.cpp +++ b/src/pointer-analysis/goto_program_dereference.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Dereferencing Operations on GOTO Programs + +#include "goto_program_dereference.h" + #include #include #include @@ -13,20 +18,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "goto_program_dereference.h" - -/*******************************************************************\ - -Function: goto_program_dereferencet::has_failed_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool goto_program_dereferencet::has_failed_symbol( const exprt &expr, const symbolt *&symbol) @@ -41,7 +32,7 @@ bool goto_program_dereferencet::has_failed_symbol( const irep_idt &failed_symbol= ptr_symbol.type.get("#failed_symbol"); - if(failed_symbol==irep_idt()) + if(failed_symbol.empty()) return false; return !ns.lookup(failed_symbol, symbol); @@ -50,18 +41,6 @@ bool goto_program_dereferencet::has_failed_symbol( return false; } -/*******************************************************************\ - -Function: goto_program_dereferencet::is_valid_object - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool goto_program_dereferencet::is_valid_object( const irep_idt &identifier) { @@ -84,18 +63,6 @@ bool goto_program_dereferencet::is_valid_object( return false; } -/*******************************************************************\ - -Function: goto_program_dereferencet::dereference_failure - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_program_dereferencet::dereference_failure( const std::string &property, const std::string &msg, @@ -125,18 +92,6 @@ void goto_program_dereferencet::dereference_failure( } } -/*******************************************************************\ - -Function: goto_program_dereferencet::dereference_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_program_dereferencet::dereference_rec( exprt &expr, guardt &guard, @@ -162,7 +117,7 @@ void goto_program_dereferencet::dereference_rec( op.pretty(); if(dereference.has_dereference(op)) - dereference_rec(op, guard, value_set_dereferencet::READ); + dereference_rec(op, guard, value_set_dereferencet::modet::READ); if(expr.id()==ID_or) { @@ -191,7 +146,7 @@ void goto_program_dereferencet::dereference_rec( throw msg; } - dereference_rec(expr.op0(), guard, value_set_dereferencet::READ); + dereference_rec(expr.op0(), guard, value_set_dereferencet::modet::READ); bool o1=dereference.has_dereference(expr.op1()); bool o2=dereference.has_dereference(expr.op2()); @@ -274,18 +229,6 @@ void goto_program_dereferencet::dereference_rec( } } -/*******************************************************************\ - -Function: goto_program_dereferencet::get_value_set - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_program_dereferencet::get_value_set( const exprt &expr, value_setst::valuest &dest) @@ -293,18 +236,6 @@ void goto_program_dereferencet::get_value_set( value_sets.get_values(current_target, expr, dest); } -/*******************************************************************\ - -Function: goto_program_dereferencet::dereference_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_program_dereferencet::dereference_expr( exprt &expr, const bool checks_only, @@ -321,18 +252,6 @@ void goto_program_dereferencet::dereference_expr( dereference_rec(expr, guard, mode); } -/*******************************************************************\ - -Function: goto_program_dereferencet::dereference_program - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_program_dereferencet::dereference_program( goto_programt &goto_program, bool checks_only) @@ -357,18 +276,6 @@ void goto_program_dereferencet::dereference_program( } } -/*******************************************************************\ - -Function: goto_program_dereferencet::dereference - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_program_dereferencet::dereference_program( goto_functionst &goto_functions, bool checks_only) @@ -380,18 +287,6 @@ void goto_program_dereferencet::dereference_program( dereference_program(it->second.body, checks_only); } -/*******************************************************************\ - -Function: goto_program_dereferencet::dereference - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_program_dereferencet::dereference_instruction( goto_programt::targett target, bool checks_only) @@ -402,15 +297,17 @@ void goto_program_dereferencet::dereference_instruction( #endif goto_programt::instructiont &i=*target; - dereference_expr(i.guard, checks_only, value_set_dereferencet::READ); + dereference_expr(i.guard, checks_only, value_set_dereferencet::modet::READ); if(i.is_assign()) { if(i.code.operands().size()!=2) throw "assignment expects two operands"; - dereference_expr(i.code.op0(), checks_only, value_set_dereferencet::WRITE); - dereference_expr(i.code.op1(), checks_only, value_set_dereferencet::READ); + dereference_expr( + i.code.op0(), checks_only, value_set_dereferencet::modet::WRITE); + dereference_expr( + i.code.op1(), checks_only, value_set_dereferencet::modet::READ); } else if(i.is_function_call()) { @@ -418,17 +315,21 @@ void goto_program_dereferencet::dereference_instruction( if(function_call.lhs().is_not_nil()) dereference_expr( - function_call.lhs(), checks_only, value_set_dereferencet::WRITE); + function_call.lhs(), + checks_only, + value_set_dereferencet::modet::WRITE); dereference_expr( - function_call.function(), checks_only, value_set_dereferencet::READ); + function_call.function(), + checks_only, + value_set_dereferencet::modet::READ); dereference_expr( - function_call.op2(), checks_only, value_set_dereferencet::READ); + function_call.op2(), checks_only, value_set_dereferencet::modet::READ); } else if(i.is_return()) { Forall_operands(it, i.code) - dereference_expr(*it, checks_only, value_set_dereferencet::READ); + dereference_expr(*it, checks_only, value_set_dereferencet::modet::READ); } else if(i.is_other()) { @@ -439,28 +340,18 @@ void goto_program_dereferencet::dereference_instruction( if(i.code.operands().size()!=1) throw "expression expects one operand"; - dereference_expr(i.code.op0(), checks_only, value_set_dereferencet::READ); + dereference_expr( + i.code.op0(), checks_only, value_set_dereferencet::modet::READ); } else if(statement==ID_printf) { Forall_operands(it, i.code) - dereference_expr(*it, checks_only, value_set_dereferencet::READ); + dereference_expr( + *it, checks_only, value_set_dereferencet::modet::READ); } } } -/*******************************************************************\ - -Function: goto_program_dereferencet::dereference - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_program_dereferencet::dereference_expression( goto_programt::const_targett target, exprt &expr) @@ -470,57 +361,21 @@ void goto_program_dereferencet::dereference_expression( valid_local_variables=&target->local_variables; #endif - dereference_expr(expr, false, value_set_dereferencet::READ); + dereference_expr(expr, false, value_set_dereferencet::modet::READ); } -/*******************************************************************\ - -Function: goto_program_dereferencet::pointer_checks - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_program_dereferencet::pointer_checks( goto_programt &goto_program) { dereference_program(goto_program, true); } -/*******************************************************************\ - -Function: goto_program_dereferencet::pointer_checks - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void goto_program_dereferencet::pointer_checks( goto_functionst &goto_functions) { dereference_program(goto_functions, true); } -/*******************************************************************\ - -Function: remove_pointers - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void remove_pointers( goto_programt &goto_program, symbol_tablet &symbol_table, @@ -536,18 +391,6 @@ void remove_pointers( goto_program_dereference.dereference_program(goto_program); } -/*******************************************************************\ - -Function: remove_pointers - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void remove_pointers( goto_functionst &goto_functions, symbol_tablet &symbol_table, @@ -564,18 +407,6 @@ void remove_pointers( goto_program_dereference.dereference_program(it->second.body); } -/*******************************************************************\ - -Function: pointer_checks - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void pointer_checks( goto_programt &goto_program, symbol_tablet &symbol_table, @@ -588,18 +419,6 @@ void pointer_checks( goto_program_dereference.pointer_checks(goto_program); } -/*******************************************************************\ - -Function: pointer_checks - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void pointer_checks( goto_functionst &goto_functions, symbol_tablet &symbol_table, @@ -612,18 +431,6 @@ void pointer_checks( goto_program_dereference.pointer_checks(goto_functions); } -/*******************************************************************\ - -Function: dereference - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dereference( goto_programt::const_targett target, exprt &expr, diff --git a/src/pointer-analysis/goto_program_dereference.h b/src/pointer-analysis/goto_program_dereference.h index 33904035fdc..5f2a76083ab 100644 --- a/src/pointer-analysis/goto_program_dereference.h +++ b/src/pointer-analysis/goto_program_dereference.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Value Set + #ifndef CPROVER_POINTER_ANALYSIS_GOTO_PROGRAM_DEREFERENCE_H #define CPROVER_POINTER_ANALYSIS_GOTO_PROGRAM_DEREFERENCE_H @@ -83,7 +86,9 @@ class goto_program_dereferencet:protected dereference_callbackt const bool checks_only, const value_set_dereferencet::modet mode); +#if 0 const std::set *valid_local_variables; +#endif source_locationt dereference_location; goto_programt::const_targett current_target; diff --git a/src/pointer-analysis/object_numbering.h b/src/pointer-analysis/object_numbering.h index beddfb76ab6..6e731bd072c 100644 --- a/src/pointer-analysis/object_numbering.h +++ b/src/pointer-analysis/object_numbering.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Value Set + #ifndef CPROVER_POINTER_ANALYSIS_OBJECT_NUMBERING_H #define CPROVER_POINTER_ANALYSIS_OBJECT_NUMBERING_H diff --git a/src/pointer-analysis/pointer_offset_sum.cpp b/src/pointer-analysis/pointer_offset_sum.cpp index e0fa65ab519..ba6a17d2074 100644 --- a/src/pointer-analysis/pointer_offset_sum.cpp +++ b/src/pointer-analysis/pointer_offset_sum.cpp @@ -6,19 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "pointer_offset_sum.h" - -/*******************************************************************\ - -Function: pointer_offset_sum - - Inputs: +/// \file +/// Pointer Analysis - Outputs: - - Purpose: - -\*******************************************************************/ +#include "pointer_offset_sum.h" exprt pointer_offset_sum(const exprt &a, const exprt &b) { diff --git a/src/pointer-analysis/pointer_offset_sum.h b/src/pointer-analysis/pointer_offset_sum.h index c5569cf1685..e4e6dc238ff 100644 --- a/src/pointer-analysis/pointer_offset_sum.h +++ b/src/pointer-analysis/pointer_offset_sum.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Pointer Dereferencing + #ifndef CPROVER_POINTER_ANALYSIS_POINTER_OFFSET_SUM_H #define CPROVER_POINTER_ANALYSIS_POINTER_OFFSET_SUM_H diff --git a/src/pointer-analysis/rewrite_index.cpp b/src/pointer-analysis/rewrite_index.cpp index 61e10530738..cc7011f1ed5 100644 --- a/src/pointer-analysis/rewrite_index.cpp +++ b/src/pointer-analysis/rewrite_index.cpp @@ -6,22 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Pointer Dereferencing #include "rewrite_index.h" -/*******************************************************************\ - -Function: rewrite_index - - Inputs: - - Outputs: - - Purpose: rewrite a[i] to *(a+i) - -\*******************************************************************/ +#include +/// rewrite a[i] to *(a+i) dereference_exprt rewrite_index(const index_exprt &index_expr) { dereference_exprt result; diff --git a/src/pointer-analysis/rewrite_index.h b/src/pointer-analysis/rewrite_index.h index ee5f3b9bbfa..26cf5b19513 100644 --- a/src/pointer-analysis/rewrite_index.h +++ b/src/pointer-analysis/rewrite_index.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Pointer Dereferencing + #ifndef CPROVER_POINTER_ANALYSIS_REWRITE_INDEX_H #define CPROVER_POINTER_ANALYSIS_REWRITE_INDEX_H diff --git a/src/pointer-analysis/show_value_sets.cpp b/src/pointer-analysis/show_value_sets.cpp index c0b87599ca4..ce555e2dd02 100644 --- a/src/pointer-analysis/show_value_sets.cpp +++ b/src/pointer-analysis/show_value_sets.cpp @@ -6,24 +6,16 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - -#include +/// \file +/// Show Value Sets -#include "value_set_analysis.h" #include "show_value_sets.h" -/*******************************************************************\ - -Function: show_value_sets - - Inputs: - - Outputs: +#include - Purpose: +#include -\*******************************************************************/ +#include "value_set_analysis.h" void show_value_sets( ui_message_handlert::uit ui, @@ -32,15 +24,15 @@ void show_value_sets( { switch(ui) { - case ui_message_handlert::XML_UI: + case ui_message_handlert::uit::XML_UI: { xmlt xml; convert(goto_functions, value_set_analysis, xml); - std::cout << xml << std::endl; + std::cout << xml << '\n'; } break; - case ui_message_handlert::PLAIN: + case ui_message_handlert::uit::PLAIN: value_set_analysis.output(goto_functions, std::cout); break; @@ -50,18 +42,6 @@ void show_value_sets( } } -/*******************************************************************\ - -Function: show_value_sets - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void show_value_sets( ui_message_handlert::uit ui, const goto_programt &goto_program, @@ -69,15 +49,15 @@ void show_value_sets( { switch(ui) { - case ui_message_handlert::XML_UI: + case ui_message_handlert::uit::XML_UI: { xmlt xml; convert(goto_program, value_set_analysis, xml); - std::cout << xml << std::endl; + std::cout << xml << '\n'; } break; - case ui_message_handlert::PLAIN: + case ui_message_handlert::uit::PLAIN: value_set_analysis.output(goto_program, std::cout); break; diff --git a/src/pointer-analysis/show_value_sets.h b/src/pointer-analysis/show_value_sets.h index a33e6976562..82005aec9ad 100644 --- a/src/pointer-analysis/show_value_sets.h +++ b/src/pointer-analysis/show_value_sets.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Show Value Sets + #ifndef CPROVER_POINTER_ANALYSIS_SHOW_VALUE_SETS_H #define CPROVER_POINTER_ANALYSIS_SHOW_VALUE_SETS_H diff --git a/src/pointer-analysis/value_set.cpp b/src/pointer-analysis/value_set.cpp index 1def54bfab1..8fa18437afd 100644 --- a/src/pointer-analysis/value_set.cpp +++ b/src/pointer-analysis/value_set.cpp @@ -1,10 +1,12 @@ -/*******************************************************************\ +// Copyright 2016-2017 DiffBlue Limited. All Rights Reserved. -Module: Value Set +/// \file +/// Value Set -Author: Daniel Kroening, kroening@kroening.com +/// \file +/// Value Set -\*******************************************************************/ +#include "value_set.h" #include #include @@ -19,32 +21,19 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include +#include #ifdef DEBUG #include #include #endif -#include "value_set.h" #include "add_failed_symbols.h" #include "dynamic_object_name.h" const value_sett::object_map_dt value_sett::object_map_dt::blank; object_numberingt value_sett::object_numbering; -/*******************************************************************\ - -Function: value_sett::field_sensitive - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_sett::field_sensitive( const irep_idt &id, const typet &type, @@ -60,18 +49,6 @@ bool value_sett::field_sensitive( return ns.follow(type).id()==ID_struct; } -/*******************************************************************\ - -Function: value_sett::insert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - value_sett::entryt &value_sett::get_entry( const entryt &e, const typet &type, @@ -90,18 +67,6 @@ value_sett::entryt &value_sett::get_entry( return r.first->second; } -/*******************************************************************\ - -Function: value_sett::insert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_sett::insert( object_mapt &dest, unsigned n, @@ -127,18 +92,6 @@ bool value_sett::insert( } } -/*******************************************************************\ - -Function: value_sett::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_sett::output( const namespacet &ns, std::ostream &out) const @@ -235,22 +188,10 @@ void value_sett::output( } } - out << " } " << std::endl; + out << " } \n"; } } -/*******************************************************************\ - -Function: value_sett::to_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt value_sett::to_expr(object_map_dt::const_iterator it) const { const exprt &object=object_numbering[it->first]; @@ -271,18 +212,6 @@ exprt value_sett::to_expr(object_map_dt::const_iterator it) const return od; } -/*******************************************************************\ - -Function: value_sett::make_union - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_sett::make_union(const value_sett::valuest &new_values) { bool result=false; @@ -322,18 +251,6 @@ bool value_sett::make_union(const value_sett::valuest &new_values) return result; } -/*******************************************************************\ - -Function: value_sett::make_union - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_sett::make_union(object_mapt &dest, const object_mapt &src) const { bool result=false; @@ -349,18 +266,6 @@ bool value_sett::make_union(object_mapt &dest, const object_mapt &src) const return result; } -/*******************************************************************\ - -Function: value_sett::eval_pointer_offset - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_sett::eval_pointer_offset( exprt &expr, const namespacet &ns) const @@ -397,7 +302,7 @@ bool value_sett::eval_pointer_offset( if(mod && ptr_offset!=previous_offset) return false; - new_expr=from_integer(ptr_offset, index_type()); + new_expr=from_integer(ptr_offset, expr.type()); previous_offset=ptr_offset; mod=true; } @@ -414,18 +319,6 @@ bool value_sett::eval_pointer_offset( return mod; } -/*******************************************************************\ - -Function: value_sett::get_value_set - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_sett::get_value_set( const exprt &expr, value_setst::valuest &dest, @@ -443,22 +336,10 @@ void value_sett::get_value_set( #if 0 for(value_setst::valuest::const_iterator it=dest.begin(); it!=dest.end(); it++) - std::cout << "GET_VALUE_SET: " << from_expr(ns, "", *it) << std::endl; + std::cout << "GET_VALUE_SET: " << from_expr(ns, "", *it) << '\n'; #endif } -/*******************************************************************\ - -Function: value_sett::get_value_set - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_sett::get_value_set( const exprt &expr, object_mapt &dest, @@ -472,18 +353,6 @@ void value_sett::get_value_set( get_value_set_rec(tmp, dest, "", tmp.type(), ns); } -/*******************************************************************\ - -Function: value_sett::get_value_set_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_sett::get_value_set_rec( const exprt &expr, object_mapt &dest, @@ -493,7 +362,7 @@ void value_sett::get_value_set_rec( { #if 0 std::cout << "GET_VALUE_SET_REC EXPR: " << from_expr(ns, "", expr) << "\n"; - std::cout << "GET_VALUE_SET_REC SUFFIX: " << suffix << std::endl; + std::cout << "GET_VALUE_SET_REC SUFFIX: " << suffix << '\n'; #endif const typet &expr_type=ns.follow(expr.type()); @@ -676,7 +545,7 @@ void value_sett::get_value_set_rec( get_value_set_rec(expr.op0(), tmp, suffix, original_type, ns); - if(tmp.read().size()==0) + if(tmp.read().empty()) { // if not, throw in integer insert(dest, exprt(ID_integer_address, unsigned_char_type())); @@ -728,10 +597,23 @@ void value_sett::get_value_set_rec( if(i_is_set) { - i*=pointer_offset_size(ptr_operand.type().subtype(), ns); + typet pointer_sub_type=ptr_operand.type().subtype(); + if(pointer_sub_type.id()==ID_empty) + pointer_sub_type=char_type(); + + mp_integer size=pointer_offset_size(pointer_sub_type, ns); - if(expr.id()==ID_minus) - i.negate(); + if(size<=0) + { + i_is_set=false; + } + else + { + i*=size; + + if(expr.id()==ID_minus) + i.negate(); + } } get_value_set_rec( @@ -890,7 +772,7 @@ void value_sett::get_value_set_rec( } else if(expr.id()==ID_array) { - // an array constructur, possibly containing addresses + // an array constructor, possibly containing addresses forall_operands(it, expr) get_value_set_rec(*it, dest, suffix, original_type, ns); } @@ -994,7 +876,7 @@ void value_sett::get_value_set_rec( else { #if 0 - std::cout << "WARNING: not doing " << expr.id() << std::endl; + std::cout << "WARNING: not doing " << expr.id() << '\n'; #endif } @@ -1012,18 +894,6 @@ void value_sett::get_value_set_rec( #endif } -/*******************************************************************\ - -Function: value_sett::dereference_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_sett::dereference_rec( const exprt &src, exprt &dest) const @@ -1042,18 +912,6 @@ void value_sett::dereference_rec( dest=src; } -/*******************************************************************\ - -Function: value_sett::get_reference_set - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_sett::get_reference_set( const exprt &expr, value_setst::valuest &dest, @@ -1069,26 +927,16 @@ void value_sett::get_reference_set( dest.push_back(to_expr(it)); } -/*******************************************************************\ - -Function: strip_casts - - Inputs: `e`: expression to strip - `ns`: global namespace - `target_type_raw`: if in the course of stripping casts we - end up at an expression with this type, stop stripping. - - Outputs: Side-effect on `e`: remove typecasts and address-of-first- - struct-member expressions until either we find an underlying - expression of type `target_type_raw`, or we run out of - strippable expressions. - - Purpose: Cleanly cast `e` to a given type if possible, avoiding the - possibility of ever-expanding towers of typecasts (either - explict or via taking address of first member). - -\*******************************************************************/ - +/// Cleanly cast `e` to a given type if possible, avoiding the possibility of +/// ever-expanding towers of typecasts (either explict or via taking address of +/// first member). +/// \param `e`: expression to strip +/// \param `ns`: global namespace +/// \param `target_type_raw`: if in the course of stripping casts we end up at +/// an expression with this type, stop stripping. +/// \return Side-effect on `e`: remove typecasts and address-of-first- struct- +/// member expressions until either we find an underlying expression of type +/// `target_type_raw`, or we run out of strippable expressions. static void strip_casts( exprt &e, const namespacet &ns, @@ -1116,18 +964,6 @@ static void strip_casts( } } -/*******************************************************************\ - -Function: value_sett::get_reference_set_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_sett::get_reference_set_rec( const exprt &expr, object_mapt &dest, @@ -1135,7 +971,7 @@ void value_sett::get_reference_set_rec( { #if 0 std::cout << "GET_REFERENCE_SET_REC EXPR: " << from_expr(ns, "", expr) - << std::endl; + << '\n'; #endif if(expr.id()==ID_symbol || @@ -1161,7 +997,7 @@ void value_sett::get_reference_set_rec( #if 0 for(expr_sett::const_iterator it=value_set.begin(); it!=value_set.end(); it++) - std::cout << "VALUE_SET: " << from_expr(ns, "", *it) << std::endl; + std::cout << "VALUE_SET: " << from_expr(ns, "", *it) << '\n'; #endif return; @@ -1211,7 +1047,14 @@ void value_sett::get_reference_set_rec( } else if(!to_integer(offset, i) && o.offset_is_zero()) - o.offset=i*pointer_offset_size(array_type.subtype(), ns); + { + mp_integer size=pointer_offset_size(array_type.subtype(), ns); + + if(size<=0) + o.offset_is_set=false; + else + o.offset=i*size; + } else o.offset_is_set=false; @@ -1292,18 +1135,6 @@ void value_sett::get_reference_set_rec( insert(dest, exprt(ID_unknown, expr.type())); } -/*******************************************************************\ - -Function: value_sett::assign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_sett::assign( const exprt &lhs, const exprt &rhs, @@ -1312,8 +1143,8 @@ void value_sett::assign( bool add_to_sets) { #if 0 - std::cout << "ASSIGN LHS: " << from_expr(ns, "", lhs) << std::endl; - std::cout << "ASSIGN RHS: " << from_expr(ns, "", rhs) << std::endl; + std::cout << "ASSIGN LHS: " << from_expr(ns, "", lhs) << '\n'; + std::cout << "ASSIGN RHS: " << from_expr(ns, "", rhs) << '\n'; output(ns, std::cout); #endif @@ -1425,18 +1256,6 @@ void value_sett::assign( } } -/*******************************************************************\ - -Function: value_sett::do_free - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_sett::do_free( const exprt &op, const namespacet &ns) @@ -1524,18 +1343,6 @@ void value_sett::do_free( } } -/*******************************************************************\ - -Function: value_sett::assign_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_sett::assign_rec( const exprt &lhs, const object_mapt &values_rhs, @@ -1544,16 +1351,16 @@ void value_sett::assign_rec( bool add_to_sets) { #if 0 - std::cout << "ASSIGN_REC LHS: " << from_expr(ns, "", lhs) << std::endl; - std::cout << "ASSIGN_REC LHS ID: " << lhs.id() << std::endl; - std::cout << "ASSIGN_REC SUFFIX: " << suffix << std::endl; + std::cout << "ASSIGN_REC LHS: " << from_expr(ns, "", lhs) << '\n'; + std::cout << "ASSIGN_REC LHS ID: " << lhs.id() << '\n'; + std::cout << "ASSIGN_REC SUFFIX: " << suffix << '\n'; for(object_map_dt::const_iterator it=values_rhs.read().begin(); it!=values_rhs.read().end(); it++) std::cout << "ASSIGN_REC RHS: " << - from_expr(ns, "", object_numbering[it->first]) << std::endl; - std::cout << std::endl; + from_expr(ns, "", object_numbering[it->first]) << '\n'; + std::cout << '\n'; #endif if(lhs.id()==ID_symbol) @@ -1665,18 +1472,6 @@ void value_sett::assign_rec( throw "assign NYI: `"+lhs.id_string()+"'"; } -/*******************************************************************\ - -Function: value_sett::do_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_sett::do_function_call( const irep_idt &function, const exprt::operandst &arguments, @@ -1723,18 +1518,6 @@ void value_sett::do_function_call( // we could delete the dummy_arg_* now. } -/*******************************************************************\ - -Function: value_sett::do_end_function - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_sett::do_end_function( const exprt &lhs, const namespacet &ns) @@ -1747,18 +1530,6 @@ void value_sett::do_end_function( assign(lhs, rhs, ns, false, false); } -/*******************************************************************\ - -Function: value_sett::apply_code - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_sett::apply_code( const codet &code, const namespacet &ns) @@ -1820,7 +1591,7 @@ void value_sett::apply_code( } else if(statement==ID_expression) { - // can be ignored, we don't expect sideeffects here + // can be ignored, we don't expect side effects here } else if(statement=="cpp_delete" || statement=="cpp_delete[]") @@ -1867,6 +1638,9 @@ void value_sett::apply_code( else if(statement==ID_array_copy) { } + else if(statement==ID_array_replace) + { + } else if(statement==ID_assume) { guard(to_code_assume(code).op0(), ns); @@ -1886,23 +1660,11 @@ void value_sett::apply_code( } else { - // std::cerr << code.pretty() << std::endl; + // std::cerr << code.pretty() << '\n'; throw "value_sett: unexpected statement: "+id2string(statement); } } -/*******************************************************************\ - -Function: value_sett::guard - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_sett::guard( const exprt &expr, const namespacet &ns) @@ -1937,18 +1699,6 @@ void value_sett::guard( } } -/*******************************************************************\ - -Function: value_sett::make_member - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt value_sett::make_member( const exprt &src, const irep_idt &component_name, diff --git a/src/pointer-analysis/value_set.h b/src/pointer-analysis/value_set.h index 2f359e4130d..edb98a71afd 100644 --- a/src/pointer-analysis/value_set.h +++ b/src/pointer-analysis/value_set.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Value Set + #ifndef CPROVER_POINTER_ANALYSIS_VALUE_SET_H #define CPROVER_POINTER_ANALYSIS_VALUE_SET_H @@ -165,13 +168,13 @@ class value_sett valuest values; - // true = added s.th. new + // true = added something new bool make_union(object_mapt &dest, const object_mapt &src) const; - // true = added s.th. new + // true = added something new bool make_union(const valuest &new_values); - // true = added s.th. new + // true = added something new bool make_union(const value_sett &new_values) { return make_union(new_values.values); diff --git a/src/pointer-analysis/value_set_analysis.cpp b/src/pointer-analysis/value_set_analysis.cpp index 6dd8fff785e..dc03dfc0b04 100644 --- a/src/pointer-analysis/value_set_analysis.cpp +++ b/src/pointer-analysis/value_set_analysis.cpp @@ -6,24 +6,15 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include -#include - -#include +/// \file +/// Value Set Propagation #include "value_set_analysis.h" -/*******************************************************************\ - -Function: convert - - Inputs: - - Outputs: - - Purpose: +#include +#include -\*******************************************************************/ +#include void convert( const goto_functionst &goto_functions, @@ -43,18 +34,6 @@ void convert( } } -/*******************************************************************\ - -Function: convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void convert( const goto_programt &goto_program, const value_set_analysist &value_set_analysis, diff --git a/src/pointer-analysis/value_set_analysis.h b/src/pointer-analysis/value_set_analysis.h index 22dd4a98169..2d344b679ed 100644 --- a/src/pointer-analysis/value_set_analysis.h +++ b/src/pointer-analysis/value_set_analysis.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Value Set Propagation + #ifndef CPROVER_POINTER_ANALYSIS_VALUE_SET_ANALYSIS_H #define CPROVER_POINTER_ANALYSIS_VALUE_SET_ANALYSIS_H @@ -59,7 +62,7 @@ class value_set_analysis_baset: if(location==previous_location) continue; - if(location.is_nil() || location.get_file()==irep_idt()) + if(location.is_nil() || location.get_file().empty()) continue; // find value set @@ -116,8 +119,8 @@ class value_set_analysis_baset: Inputs: The set of expressions to check. - Outputs: true, if it contains only one expression and - that expression is a symbol, + Outputs: true, if it contains only one expression and + that expression is a symbol, false, otherwise. Purpose: Get whether a set of expressions can have a strong update diff --git a/src/pointer-analysis/value_set_analysis_fi.cpp b/src/pointer-analysis/value_set_analysis_fi.cpp index 3ed2a07bc7d..dee9db9ad94 100644 --- a/src/pointer-analysis/value_set_analysis_fi.cpp +++ b/src/pointer-analysis/value_set_analysis_fi.cpp @@ -7,6 +7,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Value Set Propagation (Flow Insensitive) + +#include "value_set_analysis_fi.h" + #include #include #include @@ -14,20 +19,6 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "value_set_analysis_fi.h" - -/*******************************************************************\ - -Function: value_set_analysis_fit::initialize - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_analysis_fit::initialize( const goto_programt &goto_program) { @@ -35,18 +26,6 @@ void value_set_analysis_fit::initialize( add_vars(goto_program); } -/*******************************************************************\ - -Function: value_set_analysis_fit::initialize - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_analysis_fit::initialize( const goto_functionst &goto_functions) { @@ -54,18 +33,6 @@ void value_set_analysis_fit::initialize( add_vars(goto_functions); } -/*******************************************************************\ - -Function: value_set_analysis_fit::add_vars - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_analysis_fit::add_vars( const goto_programt &goto_program) { @@ -114,18 +81,6 @@ void value_set_analysis_fit::add_vars( } } -/*******************************************************************\ - -Function: value_set_analysis_fit::get_entries - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_analysis_fit::get_entries( const symbolt &symbol, std::list &dest) @@ -133,18 +88,6 @@ void value_set_analysis_fit::get_entries( get_entries_rec(symbol.name, "", symbol.type, dest); } -/*******************************************************************\ - -Function: value_set_analysis_fit::get_entries - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_analysis_fit::get_entries_rec( const irep_idt &identifier, const std::string &suffix, @@ -182,18 +125,6 @@ void value_set_analysis_fit::get_entries_rec( } } -/*******************************************************************\ - -Function: value_set_analysis_fit::add_vars - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_analysis_fit::add_vars( const goto_functionst &goto_functions) { @@ -221,18 +152,6 @@ void value_set_analysis_fit::add_vars( } } -/*******************************************************************\ - -Function: value_set_analysis_fit::get_globals - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_analysis_fit::get_globals( std::list &dest) { @@ -243,18 +162,6 @@ void value_set_analysis_fit::get_globals( get_entries(it->second, dest); } -/*******************************************************************\ - -Function: value_set_analysis_fit::check_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_set_analysis_fit::check_type(const typet &type) { if(type.id()==ID_pointer) diff --git a/src/pointer-analysis/value_set_analysis_fi.h b/src/pointer-analysis/value_set_analysis_fi.h index e1c8f320cab..da50d27357c 100644 --- a/src/pointer-analysis/value_set_analysis_fi.h +++ b/src/pointer-analysis/value_set_analysis_fi.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Value Set Propagation (flow insensitive) + #ifndef CPROVER_POINTER_ANALYSIS_VALUE_SET_ANALYSIS_FI_H #define CPROVER_POINTER_ANALYSIS_VALUE_SET_ANALYSIS_FI_H diff --git a/src/pointer-analysis/value_set_analysis_fivr.cpp b/src/pointer-analysis/value_set_analysis_fivr.cpp index 0180768250c..9b46f458896 100644 --- a/src/pointer-analysis/value_set_analysis_fivr.cpp +++ b/src/pointer-analysis/value_set_analysis_fivr.cpp @@ -7,6 +7,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Value Set Propagation (Flow Insensitive) + +#include "value_set_analysis_fivr.h" + #include #include #include @@ -14,20 +19,6 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "value_set_analysis_fivr.h" - -/*******************************************************************\ - -Function: value_set_analysis_fivrt::initialize - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_analysis_fivrt::initialize( const goto_programt &goto_program) { @@ -35,18 +26,6 @@ void value_set_analysis_fivrt::initialize( add_vars(goto_program); } -/*******************************************************************\ - -Function: value_set_analysis_fivrt::initialize - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_analysis_fivrt::initialize( const goto_functionst &goto_functions) { @@ -54,18 +33,6 @@ void value_set_analysis_fivrt::initialize( add_vars(goto_functions); } -/*******************************************************************\ - -Function: value_set_analysis_fivrt::add_vars - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_analysis_fivrt::add_vars( const goto_programt &goto_program) { @@ -104,18 +71,6 @@ void value_set_analysis_fivrt::add_vars( } } -/*******************************************************************\ - -Function: value_set_analysis_fivrt::get_entries - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_analysis_fivrt::get_entries( const symbolt &symbol, std::list &dest) @@ -123,18 +78,6 @@ void value_set_analysis_fivrt::get_entries( get_entries_rec(symbol.name, "", symbol.type, dest); } -/*******************************************************************\ - -Function: value_set_analysis_fivrt::get_entries - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_analysis_fivrt::get_entries_rec( const irep_idt &identifier, const std::string &suffix, @@ -172,18 +115,6 @@ void value_set_analysis_fivrt::get_entries_rec( } } -/*******************************************************************\ - -Function: value_set_analysis_fivrt::add_vars - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_analysis_fivrt::add_vars( const goto_functionst &goto_functions) { @@ -211,18 +142,6 @@ void value_set_analysis_fivrt::add_vars( } } -/*******************************************************************\ - -Function: value_set_analysis_fivrt::get_globals - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_analysis_fivrt::get_globals( std::list &dest) { @@ -233,18 +152,6 @@ void value_set_analysis_fivrt::get_globals( get_entries(it->second, dest); } -/*******************************************************************\ - -Function: value_set_analysis_fivrt::check_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_set_analysis_fivrt::check_type(const typet &type) { if(type.id()==ID_pointer) diff --git a/src/pointer-analysis/value_set_analysis_fivr.h b/src/pointer-analysis/value_set_analysis_fivr.h index e6e30cfb456..d583379ab0e 100644 --- a/src/pointer-analysis/value_set_analysis_fivr.h +++ b/src/pointer-analysis/value_set_analysis_fivr.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Value Set Propagation + #ifndef CPROVER_POINTER_ANALYSIS_VALUE_SET_ANALYSIS_FIVR_H #define CPROVER_POINTER_ANALYSIS_VALUE_SET_ANALYSIS_FIVR_H @@ -47,11 +50,11 @@ class value_set_analysis_fivrt: { forall_goto_program_instructions(it, goto_program) { - out << "**** " << it->source_location << std::endl; + out << "**** " << it->source_location << '\n'; output(it, out); - out << std::endl; + out << '\n'; goto_program.output_instruction(ns, "", out, it); - out << std::endl; + out << '\n'; } } diff --git a/src/pointer-analysis/value_set_analysis_fivrns.cpp b/src/pointer-analysis/value_set_analysis_fivrns.cpp index 1b7d2422186..63870eb7432 100644 --- a/src/pointer-analysis/value_set_analysis_fivrns.cpp +++ b/src/pointer-analysis/value_set_analysis_fivrns.cpp @@ -7,6 +7,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Value Set Propagation (Flow Insensitive, Validity Regions) + +#include "value_set_analysis_fivrns.h" + #include #include #include @@ -14,20 +19,6 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "value_set_analysis_fivrns.h" - -/*******************************************************************\ - -Function: value_set_analysis_fivrnst::initialize - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_analysis_fivrnst::initialize( const goto_programt &goto_program) { @@ -35,18 +26,6 @@ void value_set_analysis_fivrnst::initialize( add_vars(goto_program); } -/*******************************************************************\ - -Function: value_set_analysis_fivrnst::initialize - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_analysis_fivrnst::initialize( const goto_functionst &goto_functions) { @@ -54,18 +33,6 @@ void value_set_analysis_fivrnst::initialize( add_vars(goto_functions); } -/*******************************************************************\ - -Function: value_set_analysis_fivrnst::add_vars - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_analysis_fivrnst::add_vars( const goto_programt &goto_program) { @@ -104,18 +71,6 @@ void value_set_analysis_fivrnst::add_vars( } } -/*******************************************************************\ - -Function: value_set_analysis_fivrnst::get_entries - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_analysis_fivrnst::get_entries( const symbolt &symbol, std::list &dest) @@ -123,18 +78,6 @@ void value_set_analysis_fivrnst::get_entries( get_entries_rec(symbol.name, "", symbol.type, dest); } -/*******************************************************************\ - -Function: value_set_analysis_fivrnst::get_entries - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_analysis_fivrnst::get_entries_rec( const irep_idt &identifier, const std::string &suffix, @@ -172,18 +115,6 @@ void value_set_analysis_fivrnst::get_entries_rec( } } -/*******************************************************************\ - -Function: value_set_analysis_fivrnst::add_vars - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_analysis_fivrnst::add_vars( const goto_functionst &goto_functions) { @@ -211,18 +142,6 @@ void value_set_analysis_fivrnst::add_vars( } } -/*******************************************************************\ - -Function: value_set_analysis_fivrnst::get_globals - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_analysis_fivrnst::get_globals( std::list &dest) { @@ -233,18 +152,6 @@ void value_set_analysis_fivrnst::get_globals( get_entries(it->second, dest); } -/*******************************************************************\ - -Function: value_set_analysis_fivrnst::check_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_set_analysis_fivrnst::check_type(const typet &type) { if(type.id()==ID_pointer) diff --git a/src/pointer-analysis/value_set_analysis_fivrns.h b/src/pointer-analysis/value_set_analysis_fivrns.h index b4d45524db2..a5fd4fd3fcd 100644 --- a/src/pointer-analysis/value_set_analysis_fivrns.h +++ b/src/pointer-analysis/value_set_analysis_fivrns.h @@ -7,6 +7,9 @@ Author: Daniel Kroening, kroening@kroening.com, \*******************************************************************/ +/// \file +/// Value Set Analysis (Flow Insensitive, Validity Regions) + #ifndef CPROVER_POINTER_ANALYSIS_VALUE_SET_ANALYSIS_FIVRNS_H #define CPROVER_POINTER_ANALYSIS_VALUE_SET_ANALYSIS_FIVRNS_H @@ -49,11 +52,11 @@ class value_set_analysis_fivrnst: { forall_goto_program_instructions(it, goto_program) { - out << "**** " << it->source_location << std::endl; + out << "**** " << it->source_location << '\n'; output(it, out); - out << std::endl; + out << '\n'; goto_program.output_instruction(ns, "", out, it); - out << std::endl; + out << '\n'; } } diff --git a/src/pointer-analysis/value_set_dereference.cpp b/src/pointer-analysis/value_set_dereference.cpp index 04598ac67fa..87712e13bee 100644 --- a/src/pointer-analysis/value_set_dereference.cpp +++ b/src/pointer-analysis/value_set_dereference.cpp @@ -6,12 +6,18 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symbolic Execution of ANSI-C + +#include "value_set_dereference.h" + #ifdef DEBUG #include #endif #include +#include #include #include #include @@ -28,49 +34,24 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include +#include -#include #include #include #include -#include "value_set_dereference.h" #include "pointer_offset_sum.h" // global data, horrible unsigned int value_set_dereferencet::invalid_counter=0; -/*******************************************************************\ - -Function: value_set_dereferencet::has_dereference - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_set_dereferencet::has_dereference(const exprt &expr) { return has_subexpr(expr, ID_dereference); } -/*******************************************************************\ - -Function: value_set_dereferencet::get_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const exprt &value_set_dereferencet::get_symbol(const exprt &expr) { if(expr.id()==ID_member || expr.id()==ID_index) @@ -79,19 +60,9 @@ const exprt &value_set_dereferencet::get_symbol(const exprt &expr) return expr; } -/*******************************************************************\ - -Function: value_set_dereferencet::dereference - - Inputs: expression dest, to be dereferenced under given guard, - and given mode - - Outputs: returns pointer after dereferencing - - Purpose: - -\*******************************************************************/ - +/// \par parameters: expression dest, to be dereferenced under given guard, +/// and given mode +/// \return returns pointer after dereferencing exprt value_set_dereferencet::dereference( const exprt &pointer, const guardt &guard, @@ -122,7 +93,7 @@ exprt value_set_dereferencet::dereference( const typet &type=pointer.type().subtype(); #if 0 - std::cout << "DEREF: " << from_expr(ns, "", pointer) << std::endl; + std::cout << "DEREF: " << from_expr(ns, "", pointer) << '\n'; #endif // collect objects the pointer may point to @@ -135,7 +106,7 @@ exprt value_set_dereferencet::dereference( it=points_to_set.begin(); it!=points_to_set.end(); it++) - std::cout << "P: " << from_expr(ns, "", *it) << std::endl; + std::cout << "P: " << from_expr(ns, "", *it) << '\n'; #endif // get the values of these @@ -151,7 +122,7 @@ exprt value_set_dereferencet::dereference( #if 0 std::cout << "V: " << from_expr(ns, "", value.pointer_guard) << " --> "; - std::cout << from_expr(ns, "", value.value) << std::endl; + std::cout << from_expr(ns, "", value.value) << '\n'; #endif values.push_back(value); @@ -235,25 +206,12 @@ exprt value_set_dereferencet::dereference( } #if 0 - std::cout << "R: " << from_expr(ns, "", value) << std::endl - << std::endl; + std::cout << "R: " << from_expr(ns, "", value) << "\n\n"; #endif return value; } -/*******************************************************************\ - -Function: value_set_dereferencet::dereference_type_compare - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_set_dereferencet::dereference_type_compare( const typet &object_type, const typet &dereference_type) const @@ -282,23 +240,20 @@ bool value_set_dereferencet::dereference_type_compare( object_type.id()==ID_code) return true; + // bitvectors of same width are ok + if((dereference_type.id()==ID_signedbv || + dereference_type.id()==ID_unsignedbv) && + (object_type.id()==ID_signedbv || + object_type.id()==ID_unsignedbv) && + to_bitvector_type(dereference_type).get_width()== + to_bitvector_type(object_type).get_width()) + return true; + // really different return false; } -/*******************************************************************\ - -Function: value_set_dereferencet::invalid_pointer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_dereferencet::invalid_pointer( const exprt &pointer, const guardt &guard) @@ -316,18 +271,6 @@ void value_set_dereferencet::invalid_pointer( tmp_guard); } -/*******************************************************************\ - -Function: value_set_dereferencet::build_reference_to - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - value_set_dereferencet::valuet value_set_dereferencet::build_reference_to( const exprt &what, const modet mode, @@ -353,7 +296,7 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to( const exprt &object=o.object(); #if 0 - std::cout << "O: " << from_expr(ns, "", root_object) << std::endl; + std::cout << "O: " << from_expr(ns, "", root_object) << '\n'; #endif valuet result; @@ -468,9 +411,6 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to( const symbolt &memory_symbol=ns.lookup(CPROVER_PREFIX "memory"); exprt symbol_expr=symbol_exprt(memory_symbol.name, memory_symbol.type); - exprt pointer_offset=unary_exprt( - ID_pointer_offset, pointer_expr, index_type()); - if(base_type_eq( ns.follow(memory_symbol.type).subtype(), dereference_type, ns)) @@ -478,14 +418,22 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to( // Types match already, what a coincidence! // We can use an index expression. - exprt index_expr=index_exprt(symbol_expr, pointer_offset); + exprt index_expr=index_exprt(symbol_expr, pointer_offset(pointer_expr)); index_expr.type()=ns.follow(memory_symbol.type).subtype(); result.value=index_expr; } + else if(dereference_type_compare( + ns.follow(memory_symbol.type).subtype(), + dereference_type)) + { + exprt index_expr=index_exprt(symbol_expr, pointer_offset(pointer_expr)); + index_expr.type()=ns.follow(memory_symbol.type).subtype(); + result.value=typecast_exprt(index_expr, dereference_type); + } else { // We need to use byte_extract. - // Won't do this without a committment to an endianness. + // Won't do this without a commitment to an endianness. if(config.ansi_c.endianness==configt::ansi_ct::endiannesst::NO_ENDIANNESS) { @@ -493,7 +441,8 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to( else { exprt byte_extract(byte_extract_id(), dereference_type); - byte_extract.copy_to_operands(symbol_expr, pointer_offset); + byte_extract.copy_to_operands( + symbol_expr, pointer_offset(pointer_expr)); result.value=byte_extract; } } @@ -554,12 +503,14 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to( if(o.offset().is_constant()) offset=o.offset(); else - offset=unary_exprt(ID_pointer_offset, pointer_expr, index_type()); + offset=pointer_offset(pointer_expr); exprt adjusted_offset; // are we doing a byte? mp_integer element_size= + dereference_type.id()==ID_empty? + pointer_offset_size(char_type(), ns): pointer_offset_size(dereference_type, ns); if(element_size==1) @@ -567,6 +518,10 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to( // no need to adjust offset adjusted_offset=offset; } + else if(element_size<=0) + { + throw "unknown or invalid type size of:\n"+dereference_type.pretty(); + } else { exprt element_size_expr= @@ -604,8 +559,7 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to( result.value=o.root_object(); // this is relative to the root object - const exprt offset= - unary_exprt(ID_pointer_offset, pointer_expr, index_type()); + const exprt offset=pointer_offset(pointer_expr); if(memory_model(result.value, dereference_type, tmp_guard, offset)) { @@ -634,18 +588,6 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to( return result; } -/*******************************************************************\ - -Function: value_set_dereferencet::valid_check - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_dereferencet::valid_check( const exprt &object, const guardt &guard, @@ -660,7 +602,7 @@ void value_set_dereferencet::valid_check( { // always valid, but can't write - if(mode==WRITE) + if(mode==modet::WRITE) { dereference_callback.dereference_failure( "pointer dereference", @@ -698,18 +640,6 @@ void value_set_dereferencet::valid_check( } } -/*******************************************************************\ - -Function: value_set_dereferencet::bounds_check - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_dereferencet::bounds_check( const index_exprt &expr, const guardt &guard) @@ -783,18 +713,6 @@ void value_set_dereferencet::bounds_check( } } -/*******************************************************************\ - -Function: value_set_dereferencet::memory_model - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - inline static unsigned bv_width( const typet &type, const namespacet &ns) @@ -859,23 +777,11 @@ bool value_set_dereferencet::memory_model( return memory_model_conversion(value, to_type, guard, offset); } - // otherwise, we will stich it together from bytes + // otherwise, we will stitch it together from bytes return memory_model_bytes(value, to_type, guard, offset); } -/*******************************************************************\ - -Function: value_set_dereferencet::memory_model_conversion - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_set_dereferencet::memory_model_conversion( exprt &value, const typet &to_type, @@ -903,18 +809,6 @@ bool value_set_dereferencet::memory_model_conversion( return true; } -/*******************************************************************\ - -Function: value_set_dereferencet::memory_model_bytes - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_set_dereferencet::memory_model_bytes( exprt &value, const typet &to_type, @@ -927,7 +821,7 @@ bool value_set_dereferencet::memory_model_bytes( if(from_type.id()==ID_code || to_type.id()==ID_code) return false; - // We won't do this without a committment to an endianness. + // We won't do this without a commitment to an endianness. if(config.ansi_c.endianness==configt::ansi_ct::endiannesst::NO_ENDIANNESS) return false; @@ -965,10 +859,24 @@ bool value_set_dereferencet::memory_model_bytes( { // upper bound { - mp_integer from_width=pointer_offset_size(from_type, ns); - mp_integer to_width=pointer_offset_size(to_type, ns); - - exprt bound=from_integer(from_width-to_width, offset.type()); + exprt from_width=size_of_expr(from_type, ns); + INVARIANT( + from_width.is_not_nil(), + "unknown or invalid type size:\n"+from_type.pretty()); + + exprt to_width= + to_type.id()==ID_empty? + from_integer(0, size_type()):size_of_expr(to_type, ns); + INVARIANT( + to_width.is_not_nil(), + "unknown or invalid type size:\n"+to_type.pretty()); + INVARIANT( + from_width.type()==to_width.type(), + "type mismatch on result of size_of_expr"); + + minus_exprt bound(from_width, to_width); + if(bound.type()!=offset.type()) + bound.make_typecast(offset.type()); binary_relation_exprt offset_upper_bound(offset, ID_gt, bound); diff --git a/src/pointer-analysis/value_set_dereference.h b/src/pointer-analysis/value_set_dereference.h index d797d37a23d..4687d671ec6 100644 --- a/src/pointer-analysis/value_set_dereference.h +++ b/src/pointer-analysis/value_set_dereference.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Pointer Dereferencing + #ifndef CPROVER_POINTER_ANALYSIS_VALUE_SET_DEREFERENCE_H #define CPROVER_POINTER_ANALYSIS_VALUE_SET_DEREFERENCE_H @@ -48,7 +51,7 @@ class value_set_dereferencet virtual ~value_set_dereferencet() { } - typedef enum { READ, WRITE } modet; + enum class modet { READ, WRITE }; /*! * The method 'dereference' dereferences the diff --git a/src/pointer-analysis/value_set_domain.h b/src/pointer-analysis/value_set_domain.h index c1aeacf7811..2d77db775a7 100644 --- a/src/pointer-analysis/value_set_domain.h +++ b/src/pointer-analysis/value_set_domain.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Value Set + #ifndef CPROVER_POINTER_ANALYSIS_VALUE_SET_DOMAIN_H #define CPROVER_POINTER_ANALYSIS_VALUE_SET_DOMAIN_H diff --git a/src/pointer-analysis/value_set_domain_fi.cpp b/src/pointer-analysis/value_set_domain_fi.cpp index a5d0668fe90..09bc21174f5 100644 --- a/src/pointer-analysis/value_set_domain_fi.cpp +++ b/src/pointer-analysis/value_set_domain_fi.cpp @@ -7,21 +7,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Value Set Domain (Flow Insensitive) #include "value_set_domain_fi.h" -/*******************************************************************\ - -Function: value_set_domain_fit::transform - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include bool value_set_domain_fit::transform( const namespacet &ns, @@ -35,7 +26,7 @@ bool value_set_domain_fit::transform( // std::cout << "transforming: " << // from_l->function << " " << from_l->location_number << " to " << -// to_l->function << " " << to_l->location_number << std::endl; +// to_l->function << " " << to_l->location_number << '\n'; switch(from_l->type) { diff --git a/src/pointer-analysis/value_set_domain_fi.h b/src/pointer-analysis/value_set_domain_fi.h index ebcb9008f4c..24e2ac1be2c 100644 --- a/src/pointer-analysis/value_set_domain_fi.h +++ b/src/pointer-analysis/value_set_domain_fi.h @@ -7,6 +7,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Value Set (Flow Insensitive) + #ifndef CPROVER_POINTER_ANALYSIS_VALUE_SET_DOMAIN_FI_H #define CPROVER_POINTER_ANALYSIS_VALUE_SET_DOMAIN_FI_H diff --git a/src/pointer-analysis/value_set_domain_fivr.cpp b/src/pointer-analysis/value_set_domain_fivr.cpp index 51e63dfb91f..27fec810fcc 100644 --- a/src/pointer-analysis/value_set_domain_fivr.cpp +++ b/src/pointer-analysis/value_set_domain_fivr.cpp @@ -7,21 +7,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Value Set Domain (Flow Insensitive, Sharing, Validity Regions) #include "value_set_domain_fivr.h" -/*******************************************************************\ - -Function: value_set_domain_fivrt::transform - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include bool value_set_domain_fivrt::transform( const namespacet &ns, @@ -34,7 +25,7 @@ bool value_set_domain_fivrt::transform( #if 0 std::cout << "Transforming: " << from_l->function << " " << from_l->location_number << " to " << - to_l->function << " " << to_l->location_number << std::endl; + to_l->function << " " << to_l->location_number << '\n'; #endif switch(from_l->type) diff --git a/src/pointer-analysis/value_set_domain_fivr.h b/src/pointer-analysis/value_set_domain_fivr.h index e1f82153191..4ecb8879517 100644 --- a/src/pointer-analysis/value_set_domain_fivr.h +++ b/src/pointer-analysis/value_set_domain_fivr.h @@ -7,6 +7,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Value Set (Flow Insensitive, Sharing, Validity Regions) + #ifndef CPROVER_POINTER_ANALYSIS_VALUE_SET_DOMAIN_FIVR_H #define CPROVER_POINTER_ANALYSIS_VALUE_SET_DOMAIN_FIVR_H diff --git a/src/pointer-analysis/value_set_domain_fivrns.cpp b/src/pointer-analysis/value_set_domain_fivrns.cpp index 8c8ef147dfa..c2ae1e81771 100644 --- a/src/pointer-analysis/value_set_domain_fivrns.cpp +++ b/src/pointer-analysis/value_set_domain_fivrns.cpp @@ -7,21 +7,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Value Set Domain (Flow Insensitive, Validity Regions) #include "value_set_domain_fivrns.h" -/*******************************************************************\ - -Function: value_set_domain_fivrnst::transform - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include bool value_set_domain_fivrnst::transform( const namespacet &ns, @@ -34,7 +25,7 @@ bool value_set_domain_fivrnst::transform( #if 0 std::cout << "Transforming: " << from_l->function << " " << from_l->location_number << " to " << - to_l->function << " " << to_l->location_number << std::endl; + to_l->function << " " << to_l->location_number << '\n'; #endif switch(from_l->type) diff --git a/src/pointer-analysis/value_set_domain_fivrns.h b/src/pointer-analysis/value_set_domain_fivrns.h index 62d4aeedc3e..4e7827e4617 100644 --- a/src/pointer-analysis/value_set_domain_fivrns.h +++ b/src/pointer-analysis/value_set_domain_fivrns.h @@ -7,6 +7,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Value Set Domain (Flow Insensitive, Validity Regions) + #ifndef CPROVER_POINTER_ANALYSIS_VALUE_SET_DOMAIN_FIVRNS_H #define CPROVER_POINTER_ANALYSIS_VALUE_SET_DOMAIN_FIVRNS_H diff --git a/src/pointer-analysis/value_set_fi.cpp b/src/pointer-analysis/value_set_fi.cpp index c66aa7004d7..3dce128d557 100644 --- a/src/pointer-analysis/value_set_fi.cpp +++ b/src/pointer-analysis/value_set_fi.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Value Set (Flow Insensitive, Sharing) + +#include "value_set_fi.h" + #include #include @@ -18,9 +23,8 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include +#include -#include "value_set_fi.h" #include "dynamic_object_name.h" const value_set_fit::object_map_dt value_set_fit::object_map_dt::blank; @@ -39,18 +43,6 @@ static const char *alloc_adapter_prefix="alloc_adaptor::"; (it)!=(map).end(); \ (it)++) -/*******************************************************************\ - -Function: value_set_fit::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fit::output( const namespacet &ns, std::ostream &out) const @@ -145,53 +137,29 @@ void value_set_fit::output( } } -/*******************************************************************\ - -Function: value_set_fit::flatten - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fit::flatten( const entryt &e, object_mapt &dest) const { #if 0 - std::cout << "FLATTEN: " << e.identifier << e.suffix << std::endl; + std::cout << "FLATTEN: " << e.identifier << e.suffix << '\n'; #endif flatten_seent seen; flatten_rec(e, dest, seen); #if 0 - std::cout << "FLATTEN: Done." << std::endl; + std::cout << "FLATTEN: Done.\n"; #endif } -/*******************************************************************\ - -Function: value_set_fit::flatten_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fit::flatten_rec( const entryt &e, object_mapt &dest, flatten_seent &seen) const { #if 0 - std::cout << "FLATTEN_REC: " << e.identifier << e.suffix << std::endl; + std::cout << "FLATTEN_REC: " << e.identifier << e.suffix << '\n'; #endif std::string identifier = id2string(e.identifier); @@ -256,18 +224,6 @@ void value_set_fit::flatten_rec( seen.erase(identifier + e.suffix); } -/*******************************************************************\ - -Function: value_set_fit::to_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt value_set_fit::to_expr(object_map_dt::const_iterator it) const { const exprt &object=object_numbering[it->first]; @@ -288,18 +244,6 @@ exprt value_set_fit::to_expr(object_map_dt::const_iterator it) const return od; } -/*******************************************************************\ - -Function: value_set_fit::make_union - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_set_fit::make_union(const value_set_fit::valuest &new_values) { assert(0); @@ -339,18 +283,6 @@ bool value_set_fit::make_union(const value_set_fit::valuest &new_values) return result; } -/*******************************************************************\ - -Function: value_set_fit::make_union - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_set_fit::make_union(object_mapt &dest, const object_mapt &src) const { bool result=false; @@ -364,18 +296,6 @@ bool value_set_fit::make_union(object_mapt &dest, const object_mapt &src) const return result; } -/*******************************************************************\ - -Function: value_set_fit::get_value_set - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fit::get_value_set( const exprt &expr, std::list &value_set, @@ -434,22 +354,10 @@ void value_set_fit::get_value_set( #if 0 for(expr_sett::const_iterator it=value_set.begin(); it!=value_set.end(); it++) - std::cout << "GET_VALUE_SET: " << from_expr(ns, "", *it) << std::endl; + std::cout << "GET_VALUE_SET: " << from_expr(ns, "", *it) << '\n'; #endif } -/*******************************************************************\ - -Function: value_set_fit::get_value_set - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fit::get_value_set( const exprt &expr, object_mapt &dest, @@ -462,18 +370,6 @@ void value_set_fit::get_value_set( get_value_set_rec(tmp, dest, "", tmp.type(), ns, recset); } -/*******************************************************************\ - -Function: value_set_fit::get_value_set_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fit::get_value_set_rec( const exprt &expr, object_mapt &dest, @@ -484,9 +380,9 @@ void value_set_fit::get_value_set_rec( { #if 0 std::cout << "GET_VALUE_SET_REC EXPR: " << from_expr(ns, "", expr) - << std::endl; - std::cout << "GET_VALUE_SET_REC SUFFIX: " << suffix << std::endl; - std::cout << std::endl; + << '\n'; + std::cout << "GET_VALUE_SET_REC SUFFIX: " << suffix << '\n'; + std::cout << '\n'; #endif if(expr.type().id()=="#REF#") @@ -656,18 +552,18 @@ void value_set_fit::get_value_set_rec( if(expr.type().id()==ID_pointer) { // find the pointer operand - const exprt *ptr_operand=NULL; + const exprt *ptr_operand=nullptr; forall_operands(it, expr) if(it->type().id()==ID_pointer) { - if(ptr_operand==NULL) + if(ptr_operand==nullptr) ptr_operand=&(*it); else throw "more than one pointer operand in pointer arithmetic"; } - if(ptr_operand==NULL) + if(ptr_operand==nullptr) throw "pointer type sum expected to have pointer operand"; object_mapt pointer_expr_set; @@ -764,7 +660,7 @@ void value_set_fit::get_value_set_rec( else if(expr.id()==ID_array_of || expr.id()==ID_array) { - // an array constructur, possibly containing addresses + // an array constructor, possibly containing addresses forall_operands(it, expr) get_value_set_rec(*it, dest, suffix, original_type, ns, recursion_set); } @@ -787,18 +683,6 @@ void value_set_fit::get_value_set_rec( insert(dest, exprt(ID_unknown, original_type)); } -/*******************************************************************\ - -Function: value_set_fit::dereference_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fit::dereference_rec( const exprt &src, exprt &dest) const @@ -817,18 +701,6 @@ void value_set_fit::dereference_rec( dest=src; } -/*******************************************************************\ - -Function: value_set_fit::get_reference_set - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fit::get_reference_set( const exprt &expr, expr_sett &dest, @@ -878,18 +750,6 @@ void value_set_fit::get_reference_set( } } -/*******************************************************************\ - -Function: value_set_fit::get_reference_set_sharing - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fit::get_reference_set_sharing( const exprt &expr, expr_sett &dest, @@ -902,18 +762,6 @@ void value_set_fit::get_reference_set_sharing( dest.insert(to_expr(it)); } -/*******************************************************************\ - -Function: value_set_fit::get_reference_set_sharing_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fit::get_reference_set_sharing_rec( const exprt &expr, object_mapt &dest, @@ -921,7 +769,7 @@ void value_set_fit::get_reference_set_sharing_rec( { #if 0 std::cout << "GET_REFERENCE_SET_REC EXPR: " << from_expr(ns, "", expr) - << std::endl; + << '\n'; #endif if(expr.type().id()=="#REF#") @@ -996,7 +844,7 @@ void value_set_fit::get_reference_set_sharing_rec( for(expr_sett::const_iterator it=value_set.begin(); it!=value_set.end(); it++) - std::cout << "VALUE_SET: " << from_expr(ns, "", *it) << std::endl; + std::cout << "VALUE_SET: " << from_expr(ns, "", *it) << '\n'; #endif return; @@ -1112,26 +960,14 @@ void value_set_fit::get_reference_set_sharing_rec( insert(dest, exprt(ID_unknown, expr.type())); } -/*******************************************************************\ - -Function: value_set_fit::assign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fit::assign( const exprt &lhs, const exprt &rhs, const namespacet &ns) { #if 0 - std::cout << "ASSIGN LHS: " << from_expr(ns, "", lhs) << std::endl; - std::cout << "ASSIGN RHS: " << from_expr(ns, "", rhs) << std::endl; + std::cout << "ASSIGN LHS: " << from_expr(ns, "", lhs) << '\n'; + std::cout << "ASSIGN RHS: " << from_expr(ns, "", rhs) << '\n'; #endif if(rhs.id()==ID_if) @@ -1287,18 +1123,6 @@ void value_set_fit::assign( } } -/*******************************************************************\ - -Function: value_set_fit::do_free - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fit::do_free( const exprt &op, const namespacet &ns) @@ -1382,18 +1206,6 @@ void value_set_fit::do_free( } } -/*******************************************************************\ - -Function: value_set_fit::assign_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fit::assign_rec( const exprt &lhs, const object_mapt &values_rhs, @@ -1402,12 +1214,12 @@ void value_set_fit::assign_rec( assign_recursion_sett &recursion_set) { #if 0 - std::cout << "ASSIGN_REC LHS: " << from_expr(ns, "", lhs) << std::endl; - std::cout << "ASSIGN_REC SUFFIX: " << suffix << std::endl; + std::cout << "ASSIGN_REC LHS: " << from_expr(ns, "", lhs) << '\n'; + std::cout << "ASSIGN_REC SUFFIX: " << suffix << '\n'; for(object_map_dt::const_iterator it=values_rhs.read().begin(); it!=values_rhs.read().end(); it++) - std::cout << "ASSIGN_REC RHS: " << to_expr(it) << std::endl; + std::cout << "ASSIGN_REC RHS: " << to_expr(it) << '\n'; #endif if(lhs.type().id()=="#REF#") @@ -1541,18 +1353,6 @@ void value_set_fit::assign_rec( throw "assign NYI: `"+lhs.id_string()+"'"; } -/*******************************************************************\ - -Function: value_set_fit::do_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fit::do_function_call( const irep_idt &function, const exprt::operandst &arguments, @@ -1602,18 +1402,6 @@ void value_set_fit::do_function_call( } } -/*******************************************************************\ - -Function: value_set_fit::do_end_function - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fit::do_end_function( const exprt &lhs, const namespacet &ns) @@ -1627,18 +1415,6 @@ void value_set_fit::do_end_function( assign(lhs, rhs, ns); } -/*******************************************************************\ - -Function: value_set_fit::apply_code - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fit::apply_code( const exprt &code, const namespacet &ns) @@ -1682,7 +1458,7 @@ void value_set_fit::apply_code( } else if(statement==ID_expression) { - // can be ignored, we don't expect sideeffects here + // can be ignored, we don't expect side effects here } else if(statement==ID_cpp_delete || statement==ID_cpp_delete_array) @@ -1727,7 +1503,9 @@ void value_set_fit::apply_code( else if(statement==ID_fence) { } - else if(statement==ID_array_copy) + else if(statement==ID_array_copy || + statement==ID_array_replace || + statement==ID_array_set) { } else if(statement==ID_input || statement==ID_output) diff --git a/src/pointer-analysis/value_set_fi.h b/src/pointer-analysis/value_set_fi.h index c268e6394c9..6298dce5dd5 100644 --- a/src/pointer-analysis/value_set_fi.h +++ b/src/pointer-analysis/value_set_fi.h @@ -7,6 +7,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Value Set (Flow Insensitive, Sharing) + #ifndef CPROVER_POINTER_ANALYSIS_VALUE_SET_FI_H #define CPROVER_POINTER_ANALYSIS_VALUE_SET_FI_H @@ -25,7 +28,10 @@ Author: Daniel Kroening, kroening@kroening.com class value_set_fit { public: - value_set_fit() + value_set_fit(): + changed(false) + // to_function, to_target_index are set by set_to() + // from_function, from_target_index are set by set_from() { } @@ -236,13 +242,13 @@ class value_set_fit bool changed; - // true = added s.th. new + // true = added something new bool make_union(object_mapt &dest, const object_mapt &src) const; - // true = added s.th. new + // true = added something new bool make_union(const valuest &new_values); - // true = added s.th. new + // true = added something new bool make_union(const value_set_fit &new_values) { return make_union(new_values.values); diff --git a/src/pointer-analysis/value_set_fivr.cpp b/src/pointer-analysis/value_set_fivr.cpp index 51da72fa875..137ecbcbfe6 100644 --- a/src/pointer-analysis/value_set_fivr.cpp +++ b/src/pointer-analysis/value_set_fivr.cpp @@ -7,6 +7,11 @@ Author: Daniel Kroening, kroening@kroening.com, \*******************************************************************/ +/// \file +/// Value Set (Flow Insensitive, Sharing, Validity Regions) + +#include "value_set_fivr.h" + #include #include @@ -19,9 +24,8 @@ Author: Daniel Kroening, kroening@kroening.com, #include #include -#include +#include -#include "value_set_fivr.h" #include "dynamic_object_name.h" const value_set_fivrt::object_map_dt value_set_fivrt::object_map_dt::blank; @@ -52,18 +56,6 @@ static const char *alloc_adapter_prefix="alloc_adaptor::"; (it)++) \ if((map).is_valid_at((it)->first, from_function, from_target_index)) /* NOLINT(*) */ -/*******************************************************************\ - -Function: value_set_fivrt::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrt::output( const namespacet &ns, std::ostream &out) const @@ -114,7 +106,7 @@ void value_set_fivrt::output( } out << display_name << "={ "; - if(object_map.read().size()!=0) + if(!object_map.read().empty()) out << "\n "; std::size_t width=0; @@ -183,7 +175,7 @@ void value_set_fivrt::output( if(vr != object_map.read().validity_ranges.end()) { if(vr->second.empty()) - std::cout << " Empty validity record" << std::endl; + std::cout << " Empty validity record\n"; else { for(object_map_dt::vrange_listt::const_iterator vit = @@ -197,13 +189,13 @@ void value_set_fivrt::output( from_target_index>=vit->from && from_target_index<=vit->to) out << " (*)"; - out << std::endl; + out << '\n'; } } } else { - out << " No validity information" << std::endl; + out << " No validity information\n"; } #endif @@ -222,46 +214,22 @@ void value_set_fivrt::output( } } -/*******************************************************************\ - -Function: value_set_fivrt::flatten - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrt::flatten( const entryt &e, object_mapt &dest) const { #if 0 - std::cout << "FLATTEN: " << e.identifier << e.suffix << std::endl; + std::cout << "FLATTEN: " << e.identifier << e.suffix << '\n'; #endif flatten_seent seen; flatten_rec(e, dest, seen, from_function, from_target_index); #if 0 - std::cout << "FLATTEN: Done." << std::endl; + std::cout << "FLATTEN: Done.\n"; #endif } -/*******************************************************************\ - -Function: value_set_fivrt::flatten_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrt::flatten_rec( const entryt &e, object_mapt &dest, @@ -270,7 +238,7 @@ void value_set_fivrt::flatten_rec( unsigned at_index) const { #if 0 - std::cout << "FLATTEN_REC: " << e.identifier << e.suffix << std::endl; + std::cout << "FLATTEN_REC: " << e.identifier << e.suffix << '\n'; #endif std::string identifier=id2string(e.identifier); @@ -377,18 +345,6 @@ void value_set_fivrt::flatten_rec( seen.erase(identifier + e.suffix); } -/*******************************************************************\ - -Function: value_set_fivrt::to_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt value_set_fivrt::to_expr(object_map_dt::const_iterator it) const { const exprt &object=object_numbering[it->first]; @@ -409,18 +365,6 @@ exprt value_set_fivrt::to_expr(object_map_dt::const_iterator it) const return od; } -/*******************************************************************\ - -Function: value_set_fivrt::make_union - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_set_fivrt::make_union( object_mapt &dest, const object_mapt &src) const @@ -436,18 +380,6 @@ bool value_set_fivrt::make_union( return result; } -/*******************************************************************\ - -Function: value_set_fivrnst::make_valid_union - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_set_fivrt::make_valid_union( object_mapt &dest, const object_mapt &src) const @@ -463,18 +395,6 @@ bool value_set_fivrt::make_valid_union( return result; } -/*******************************************************************\ - -Function: value_set_fivrt::copy_objects - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrt::copy_objects( object_mapt &dest, const object_mapt &src) const @@ -489,18 +409,6 @@ void value_set_fivrt::copy_objects( } } -/*******************************************************************\ - -Function: value_set_fivrt::get_value_set - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrt::get_value_set( const exprt &expr, std::list &value_set, @@ -561,22 +469,10 @@ void value_set_fivrt::get_value_set( for(std::list::const_iterator it=value_set.begin(); it!=value_set.end(); it++) - std::cout << "GET_VALUE_SET: " << from_expr(ns, "", *it) << std::endl; + std::cout << "GET_VALUE_SET: " << from_expr(ns, "", *it) << '\n'; #endif } -/*******************************************************************\ - -Function: value_set_fivrt::get_value_set - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrt::get_value_set( const exprt &expr, object_mapt &dest, @@ -589,18 +485,6 @@ void value_set_fivrt::get_value_set( get_value_set_rec(tmp, dest, "", tmp.type(), ns, recset); } -/*******************************************************************\ - -Function: value_set_fivrt::get_value_set_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrt::get_value_set_rec( const exprt &expr, object_mapt &dest, @@ -610,9 +494,9 @@ void value_set_fivrt::get_value_set_rec( gvs_recursion_sett &recursion_set) const { #if 0 - std::cout << "GET_VALUE_SET_REC EXPR: " << expr << std::endl; - std::cout << "GET_VALUE_SET_REC SUFFIX: " << suffix << std::endl; - std::cout << std::endl; + std::cout << "GET_VALUE_SET_REC EXPR: " << expr << '\n'; + std::cout << "GET_VALUE_SET_REC SUFFIX: " << suffix << '\n'; + std::cout << '\n'; #endif if(expr.type().id()=="#REF#") @@ -786,18 +670,18 @@ void value_set_fivrt::get_value_set_rec( if(expr.type().id()==ID_pointer) { // find the pointer operand - const exprt *ptr_operand=NULL; + const exprt *ptr_operand=nullptr; forall_operands(it, expr) if(it->type().id()==ID_pointer) { - if(ptr_operand==NULL) + if(ptr_operand==nullptr) ptr_operand=&(*it); else throw "more than one pointer operand in pointer arithmetic"; } - if(ptr_operand==NULL) + if(ptr_operand==nullptr) throw "pointer type sum expected to have pointer operand"; object_mapt pointer_expr_set; @@ -913,18 +797,6 @@ void value_set_fivrt::get_value_set_rec( insert_from(dest, exprt(ID_unknown, original_type)); } -/*******************************************************************\ - -Function: value_set_fivrt::dereference_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrt::dereference_rec( const exprt &src, exprt &dest) const @@ -943,18 +815,6 @@ void value_set_fivrt::dereference_rec( dest=src; } -/*******************************************************************\ - -Function: value_set_fivrt::get_reference_set - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrt::get_reference_set( const exprt &expr, expr_sett &dest, @@ -1004,18 +864,6 @@ void value_set_fivrt::get_reference_set( } } -/*******************************************************************\ - -Function: value_set_fivrt::get_reference_set_sharing - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrt::get_reference_set_sharing( const exprt &expr, expr_sett &dest, @@ -1028,18 +876,6 @@ void value_set_fivrt::get_reference_set_sharing( dest.insert(to_expr(it)); } -/*******************************************************************\ - -Function: value_set_fivrt::get_reference_set_sharing_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrt::get_reference_set_sharing_rec( const exprt &expr, object_mapt &dest, @@ -1047,7 +883,7 @@ void value_set_fivrt::get_reference_set_sharing_rec( { #if 0 std::cout << "GET_REFERENCE_SET_REC EXPR: " << from_expr(ns, "", expr) - << std::endl; + << '\n'; #endif if(expr.type().id()=="#REF#") @@ -1122,7 +958,7 @@ void value_set_fivrt::get_reference_set_sharing_rec( for(expr_sett::const_iterator it=value_set.begin(); it!=value_set.end(); it++) - std::cout << "VALUE_SET: " << from_expr(ns, "", *it) << std::endl; + std::cout << "VALUE_SET: " << from_expr(ns, "", *it) << '\n'; #endif return; @@ -1240,18 +1076,6 @@ void value_set_fivrt::get_reference_set_sharing_rec( insert_from(dest, exprt(ID_unknown, expr.type())); } -/*******************************************************************\ - -Function: value_set_fivrt::assign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrt::assign( const exprt &lhs, const exprt &rhs, @@ -1259,9 +1083,9 @@ void value_set_fivrt::assign( bool add_to_sets) { #if 0 - std::cout << "ASSIGN LHS: " << lhs << std::endl; - std::cout << "ASSIGN LTYPE: " << ns.follow(lhs.type()) << std::endl; - std::cout << "ASSIGN RHS: " << from_expr(ns, "", rhs) << std::endl; + std::cout << "ASSIGN LHS: " << lhs << '\n'; + std::cout << "ASSIGN LTYPE: " << ns.follow(lhs.type()) << '\n'; + std::cout << "ASSIGN RHS: " << from_expr(ns, "", rhs) << '\n'; #endif if(rhs.id()==ID_if) @@ -1370,7 +1194,7 @@ void value_set_fivrt::assign( if(rhs.id()==ID_array_of) { assert(rhs.operands().size()==1); -// std::cout << "AOF: " << rhs.op0() << std::endl; +// std::cout << "AOF: " << rhs.op0() << '\n'; assign(lhs_index, rhs.op0(), ns, add_to_sets); } else if(rhs.id()==ID_array || @@ -1411,18 +1235,6 @@ void value_set_fivrt::assign( } } -/*******************************************************************\ - -Function: value_set_fivrt::do_free - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrt::do_free( const exprt &op, const namespacet &ns) @@ -1510,18 +1322,6 @@ void value_set_fivrt::do_free( } } -/*******************************************************************\ - -Function: value_set_fivrt::assign_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrt::assign_rec( const exprt &lhs, const object_mapt &values_rhs, @@ -1531,12 +1331,12 @@ void value_set_fivrt::assign_rec( bool add_to_sets) { #if 0 - std::cout << "ASSIGN_REC LHS: " << lhs << std::endl; - std::cout << "ASSIGN_REC SUFFIX: " << suffix << std::endl; + std::cout << "ASSIGN_REC LHS: " << lhs << '\n'; + std::cout << "ASSIGN_REC SUFFIX: " << suffix << '\n'; for(object_map_dt::const_iterator it=values_rhs.read().begin(); it!=values_rhs.read().end(); it++) - std::cout << "ASSIGN_REC RHS: " << to_expr(it) << std::endl; + std::cout << "ASSIGN_REC RHS: " << to_expr(it) << '\n'; #endif if(lhs.type().id()=="#REF#") @@ -1693,18 +1493,6 @@ void value_set_fivrt::assign_rec( throw "assign NYI: `"+lhs.id_string()+"'"; } -/*******************************************************************\ - -Function: value_set_fivrt::do_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrt::do_function_call( const irep_idt &function, const exprt::operandst &arguments, @@ -1733,7 +1521,7 @@ void value_set_fivrt::do_function_call( "argument$"+std::to_string(i); add_var(identifier, ""); exprt dummy_lhs=symbol_exprt(identifier, arguments[i].type()); -// std::cout << arguments[i] << std::endl; +// std::cout << arguments[i] << '\n'; assign(dummy_lhs, arguments[i], ns, true); @@ -1772,18 +1560,6 @@ void value_set_fivrt::do_function_call( } } -/*******************************************************************\ - -Function: value_set_fivrt::do_end_function - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrt::do_end_function( const exprt &lhs, const namespacet &ns) @@ -1797,18 +1573,6 @@ void value_set_fivrt::do_end_function( assign(lhs, rhs, ns); } -/*******************************************************************\ - -Function: value_set_fivrt::apply_code - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrt::apply_code( const exprt &code, const namespacet &ns) @@ -1852,7 +1616,7 @@ void value_set_fivrt::apply_code( } else if(statement==ID_expression) { - // can be ignored, we don't expect sideeffects here + // can be ignored, we don't expect side effects here } else if(statement==ID_cpp_delete || statement==ID_cpp_delete_array) @@ -1905,18 +1669,6 @@ void value_set_fivrt::apply_code( "value_set_fivrt: unexpected statement: "+id2string(statement); } -/*******************************************************************\ - -Function: value_set_fivrt::insert_to - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_set_fivrt::insert_to( object_mapt &dest, unsigned n, @@ -1925,7 +1677,7 @@ bool value_set_fivrt::insert_to( object_map_dt &map=dest.write(); if(map.find(n)==map.end()) { -// std::cout << "NEW(" << n << "): " << object_numbering[n] << std::endl; +// std::cout << "NEW(" << n << "): " << object_numbering[n] << '\n'; // new map[n]=object; map.set_valid_at(n, to_function, to_target_index); @@ -1933,7 +1685,7 @@ bool value_set_fivrt::insert_to( } else { -// std::cout << "UPD " << n << std::endl; +// std::cout << "UPD " << n << '\n'; objectt &old=map[n]; bool res=map.set_valid_at(n, to_function, to_target_index); @@ -1958,18 +1710,6 @@ bool value_set_fivrt::insert_to( } } -/*******************************************************************\ - -Function: value_set_fivrt::insert_from - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_set_fivrt::insert_from( object_mapt &dest, unsigned n, @@ -1978,7 +1718,7 @@ bool value_set_fivrt::insert_from( object_map_dt &map=dest.write(); if(map.find(n)==map.end()) { -// std::cout << "NEW(" << n << "): " << object_numbering[n] << std::endl; +// std::cout << "NEW(" << n << "): " << object_numbering[n] << '\n'; // new map[n]=object; map.set_valid_at(n, from_function, from_target_index); @@ -1986,7 +1726,7 @@ bool value_set_fivrt::insert_from( } else { -// std::cout << "UPD " << n << std::endl; +// std::cout << "UPD " << n << '\n'; objectt &old=map[n]; bool res=map.set_valid_at(n, from_function, from_target_index); @@ -2011,18 +1751,6 @@ bool value_set_fivrt::insert_from( } } -/*******************************************************************\ - -Function: value_set_fivrt::object_map_dt::set_valid_at - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_set_fivrt::object_map_dt::set_valid_at( unsigned inx, const validity_ranget &vr) @@ -2036,18 +1764,6 @@ bool value_set_fivrt::object_map_dt::set_valid_at( return res; } -/*******************************************************************\ - -Function: value_set_fivrt::object_map_dt::set_valid_at - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_set_fivrt::object_map_dt::set_valid_at( unsigned inx, unsigned f, @@ -2119,18 +1835,6 @@ bool value_set_fivrt::object_map_dt::set_valid_at( return true; } -/*******************************************************************\ - -Function: value_set_fivrt::object_map_dt::is_valid_at - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_set_fivrt::object_map_dt::is_valid_at( unsigned inx, unsigned f, @@ -2138,7 +1842,7 @@ bool value_set_fivrt::object_map_dt::is_valid_at( { #if 0 std::cout << "IS_VALID_AT: " << inx << ", " << f << ", line " << line << - std::endl; + '\n'; #endif validity_rangest::const_iterator vrs=validity_ranges.find(inx); @@ -2161,18 +1865,6 @@ bool value_set_fivrt::object_map_dt::is_valid_at( return false; } -/*******************************************************************\ - -Function: value_set_fivrt::recursive_find - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_set_fivrt::recursive_find( const irep_idt &ident, const object_mapt &rhs, @@ -2212,18 +1904,6 @@ bool value_set_fivrt::recursive_find( return false; } -/*******************************************************************\ - -Function: value_set_fivrt::handover - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_set_fivrt::handover(void) { bool changed=false; @@ -2240,7 +1920,7 @@ bool value_set_fivrt::handover(void) if(t_it==temporary_values.end()) { -// std::cout << "OLD VALUES FOR: " << ident << std::endl; +// std::cout << "OLD VALUES FOR: " << ident << '\n'; Forall_valid_objects(o_it, state_map.write()) { if(state_map.write().set_valid_at(o_it->first, @@ -2250,7 +1930,7 @@ bool value_set_fivrt::handover(void) } else { -// std::cout << "NEW VALUES FOR: " << ident << std::endl; +// std::cout << "NEW VALUES FOR: " << ident << '\n'; if(make_union(state_map, t_it->second.object_map)) changed=true; } diff --git a/src/pointer-analysis/value_set_fivr.h b/src/pointer-analysis/value_set_fivr.h index ea3f82ac603..eb392928786 100644 --- a/src/pointer-analysis/value_set_fivr.h +++ b/src/pointer-analysis/value_set_fivr.h @@ -7,6 +7,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Value Set (Flow Insensitive, Sharing, Validity Regions) + #ifndef CPROVER_POINTER_ANALYSIS_VALUE_SET_FIVR_H #define CPROVER_POINTER_ANALYSIS_VALUE_SET_FIVR_H @@ -84,12 +87,13 @@ class value_set_fivrt typedef objmapt::iterator iterator; const_iterator find(unsigned k) { return objmap.find(k); } - iterator begin(void) { return objmap.begin(); } - const_iterator begin(void) const { return objmap.begin(); } - iterator end(void) { return objmap.end(); } - const_iterator end(void) const { return objmap.end(); } - size_t size(void) const { return objmap.size(); } - void clear(void) { objmap.clear(); validity_ranges.clear(); } + iterator begin() { return objmap.begin(); } + const_iterator begin() const { return objmap.begin(); } + iterator end() { return objmap.end(); } + const_iterator end() const { return objmap.end(); } + size_t size() const { return objmap.size(); } + bool empty() const { return objmap.empty(); } + void clear() { objmap.clear(); validity_ranges.clear(); } objectt &operator[](unsigned k) { @@ -112,7 +116,7 @@ class value_set_fivrt unsigned function; unsigned from, to; - validity_ranget(void): + validity_ranget(): function(0), from(0), to(0) { } @@ -303,7 +307,7 @@ class value_set_fivrt valuest values; valuest temporary_values; - // true = added s.th. new + // true = added something new bool make_union( object_mapt &dest, const object_mapt &src) const; @@ -320,7 +324,7 @@ class value_set_fivrt const exprt &code, const namespacet &ns); - bool handover(void); + bool handover(); void assign( const exprt &lhs, diff --git a/src/pointer-analysis/value_set_fivrns.cpp b/src/pointer-analysis/value_set_fivrns.cpp index 98657fc092d..9771581dd7d 100644 --- a/src/pointer-analysis/value_set_fivrns.cpp +++ b/src/pointer-analysis/value_set_fivrns.cpp @@ -7,6 +7,11 @@ Author: Daniel Kroening, kroening@kroening.com, \*******************************************************************/ +/// \file +/// Value Set (Flow Insensitive, Validity Regions) + +#include "value_set_fivrns.h" + #include #include @@ -19,9 +24,8 @@ Author: Daniel Kroening, kroening@kroening.com, #include #include -#include +#include -#include "value_set_fivrns.h" #include "dynamic_object_name.h" const value_set_fivrnst::object_map_dt value_set_fivrnst::object_map_dt::blank; @@ -52,18 +56,6 @@ static const char *alloc_adapter_prefix="alloc_adaptor::"; (it)++) \ if((map).is_valid_at((it)->first, from_function, from_target_index)) /* NOLINT(*) */ -/*******************************************************************\ - -Function: value_set_fivrnst::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrnst::output( const namespacet &ns, std::ostream &out) const @@ -75,18 +67,6 @@ void value_set_fivrnst::output( output_entry(v_it->second, ns, out); } -/*******************************************************************\ - -Function: value_set_fivrnst::output_entry - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrnst::output_entry( const entryt &e, const namespacet &ns, @@ -117,7 +97,7 @@ void value_set_fivrnst::output_entry( const object_mapt &object_map=e.object_map; out << display_name << " = { "; - if(object_map.read().size()!=0) + if(!object_map.read().empty()) out << "\n "; std::size_t width=0; @@ -183,7 +163,7 @@ void value_set_fivrnst::output_entry( if(vr != object_map.read().validity_ranges.end()) { if(vr->second.empty()) - std::cout << " Empty validity record" << std::endl; + std::cout << " Empty validity record\n"; else { for(object_map_dt::vrange_listt::const_iterator vit = @@ -197,13 +177,13 @@ void value_set_fivrnst::output_entry( from_target_index>=vit->from && from_target_index<=vit->to) out << " (*)"; - out << std::endl; + out << '\n'; } } } else { - out << " No validity information" << std::endl; + out << " No validity information\n"; } #endif @@ -221,18 +201,6 @@ void value_set_fivrnst::output_entry( out << " } \n"; } -/*******************************************************************\ - -Function: value_set_fivrnst::to_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt value_set_fivrnst::to_expr(object_map_dt::const_iterator it) const { const exprt &object=object_numbering[it->first]; @@ -253,18 +221,6 @@ exprt value_set_fivrnst::to_expr(object_map_dt::const_iterator it) const return od; } -/*******************************************************************\ - -Function: value_set_fivrnst::make_union - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_set_fivrnst::make_union( object_mapt &dest, const object_mapt &src) const @@ -280,18 +236,6 @@ bool value_set_fivrnst::make_union( return result; } -/*******************************************************************\ - -Function: value_set_fivrnst::make_valid_union - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_set_fivrnst::make_valid_union( object_mapt &dest, const object_mapt &src) const @@ -307,18 +251,6 @@ bool value_set_fivrnst::make_valid_union( return result; } -/*******************************************************************\ - -Function: value_set_fivrnst::copy_objects - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrnst::copy_objects( object_mapt &dest, const object_mapt &src) const @@ -333,18 +265,6 @@ void value_set_fivrnst::copy_objects( } } -/*******************************************************************\ - -Function: value_set_fivrnst::get_value_set - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrnst::get_value_set( const exprt &expr, std::list &value_set, @@ -359,22 +279,10 @@ void value_set_fivrnst::get_value_set( #if 0 for(std::list::const_iterator it=value_set.begin(); it!=value_set.end(); it++) - std::cout << "GET_VALUE_SET: " << from_expr(ns, "", *it) << std::endl; + std::cout << "GET_VALUE_SET: " << from_expr(ns, "", *it) << '\n'; #endif } -/*******************************************************************\ - -Function: value_set_fivrnst::get_value_set - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrnst::get_value_set( const exprt &expr, object_mapt &dest, @@ -386,18 +294,6 @@ void value_set_fivrnst::get_value_set( get_value_set_rec(tmp, dest, "", tmp.type(), ns); } -/*******************************************************************\ - -Function: value_set_fivrnst::get_value_set_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrnst::get_value_set_rec( const exprt &expr, object_mapt &dest, @@ -406,9 +302,9 @@ void value_set_fivrnst::get_value_set_rec( const namespacet &ns) const { #if 0 - std::cout << "GET_VALUE_SET_REC EXPR: " << expr << std::endl; - std::cout << "GET_VALUE_SET_REC SUFFIX: " << suffix << std::endl; - std::cout << std::endl; + std::cout << "GET_VALUE_SET_REC EXPR: " << expr << '\n'; + std::cout << "GET_VALUE_SET_REC SUFFIX: " << suffix << '\n'; + std::cout << '\n'; #endif if(expr.id()==ID_unknown || expr.id()==ID_invalid) @@ -560,18 +456,18 @@ void value_set_fivrnst::get_value_set_rec( if(expr.type().id()==ID_pointer) { // find the pointer operand - const exprt *ptr_operand=NULL; + const exprt *ptr_operand=nullptr; forall_operands(it, expr) if(it->type().id()==ID_pointer) { - if(ptr_operand==NULL) + if(ptr_operand==nullptr) ptr_operand=&(*it); else throw "more than one pointer operand in pointer arithmetic"; } - if(ptr_operand==NULL) + if(ptr_operand==nullptr) throw "pointer type sum expected to have pointer operand"; object_mapt pointer_expr_set; @@ -687,18 +583,6 @@ void value_set_fivrnst::get_value_set_rec( insert_from(dest, exprt(ID_unknown, original_type)); } -/*******************************************************************\ - -Function: value_set_fivrnst::dereference_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrnst::dereference_rec( const exprt &src, exprt &dest) const @@ -717,18 +601,6 @@ void value_set_fivrnst::dereference_rec( dest=src; } -/*******************************************************************\ - -Function: value_set_fivrnst::get_reference_set - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrnst::get_reference_set( const exprt &expr, expr_sett &dest, @@ -741,18 +613,6 @@ void value_set_fivrnst::get_reference_set( dest.insert(to_expr(it)); } -/*******************************************************************\ - -Function: value_set_fivrnst::get_reference_set_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrnst::get_reference_set_rec( const exprt &expr, object_mapt &dest, @@ -760,7 +620,7 @@ void value_set_fivrnst::get_reference_set_rec( { #if 0 std::cout << "GET_REFERENCE_SET_REC EXPR: " << from_expr(ns, "", expr) - << std::endl; + << '\n'; #endif if(expr.id()==ID_symbol || @@ -785,7 +645,7 @@ void value_set_fivrnst::get_reference_set_rec( #if 0 for(expr_sett::const_iterator it=value_set.begin(); it!=value_set.end(); it++) - std::cout << "VALUE_SET: " << from_expr(ns, "", *it) << std::endl; + std::cout << "VALUE_SET: " << from_expr(ns, "", *it) << '\n'; #endif return; @@ -903,18 +763,6 @@ void value_set_fivrnst::get_reference_set_rec( insert_from(dest, exprt(ID_unknown, expr.type())); } -/*******************************************************************\ - -Function: value_set_fivrnst::assign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrnst::assign( const exprt &lhs, const exprt &rhs, @@ -922,9 +770,9 @@ void value_set_fivrnst::assign( bool add_to_sets) { #if 0 - std::cout << "ASSIGN LHS: " << lhs << std::endl; - std::cout << "ASSIGN LTYPE: " << ns.follow(lhs.type()) << std::endl; - std::cout << "ASSIGN RHS: " << from_expr(ns, "", rhs) << std::endl; + std::cout << "ASSIGN LHS: " << lhs << '\n'; + std::cout << "ASSIGN LTYPE: " << ns.follow(lhs.type()) << '\n'; + std::cout << "ASSIGN RHS: " << from_expr(ns, "", rhs) << '\n'; #endif if(rhs.id()==ID_if) @@ -1033,7 +881,7 @@ void value_set_fivrnst::assign( if(rhs.id()==ID_array_of) { assert(rhs.operands().size()==1); -// std::cout << "AOF: " << rhs.op0() << std::endl; +// std::cout << "AOF: " << rhs.op0() << '\n'; assign(lhs_index, rhs.op0(), ns, add_to_sets); } else if(rhs.id()==ID_array || @@ -1073,18 +921,6 @@ void value_set_fivrnst::assign( } } -/*******************************************************************\ - -Function: value_set_fivrnst::do_free - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrnst::do_free( const exprt &op, const namespacet &ns) @@ -1169,18 +1005,6 @@ void value_set_fivrnst::do_free( } } -/*******************************************************************\ - -Function: value_set_fivrnst::assign_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrnst::assign_rec( const exprt &lhs, const object_mapt &values_rhs, @@ -1189,12 +1013,12 @@ void value_set_fivrnst::assign_rec( bool add_to_sets) { #if 0 - std::cout << "ASSIGN_REC LHS: " << lhs << std::endl; - std::cout << "ASSIGN_REC SUFFIX: " << suffix << std::endl; + std::cout << "ASSIGN_REC LHS: " << lhs << '\n'; + std::cout << "ASSIGN_REC SUFFIX: " << suffix << '\n'; for(object_map_dt::const_iterator it=values_rhs.read().begin(); it!=values_rhs.read().end(); it++) - std::cout << "ASSIGN_REC RHS: " << to_expr(it) << std::endl; + std::cout << "ASSIGN_REC RHS: " << to_expr(it) << '\n'; #endif if(lhs.id()==ID_symbol) @@ -1320,18 +1144,6 @@ void value_set_fivrnst::assign_rec( throw "assign NYI: `"+lhs.id_string()+"'"; } -/*******************************************************************\ - -Function: value_set_fivrnst::do_function_call - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrnst::do_function_call( const irep_idt &function, const exprt::operandst &arguments, @@ -1360,7 +1172,7 @@ void value_set_fivrnst::do_function_call( "argument$"+std::to_string(i); add_var(identifier, ""); exprt dummy_lhs=symbol_exprt(identifier, arguments[i].type()); -// std::cout << arguments[i] << std::endl; +// std::cout << arguments[i] << '\n'; assign(dummy_lhs, arguments[i], ns, true); @@ -1399,18 +1211,6 @@ void value_set_fivrnst::do_function_call( } } -/*******************************************************************\ - -Function: value_set_fivrnst::do_end_function - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrnst::do_end_function( const exprt &lhs, const namespacet &ns) @@ -1426,18 +1226,6 @@ void value_set_fivrnst::do_end_function( assign(lhs, rhs, ns); } -/*******************************************************************\ - -Function: value_set_fivrnst::apply_code - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void value_set_fivrnst::apply_code( const exprt &code, const namespacet &ns) @@ -1481,7 +1269,7 @@ void value_set_fivrnst::apply_code( } else if(statement==ID_expression) { - // can be ignored, we don't expect sideeffects here + // can be ignored, we don't expect side effects here } else if(statement==ID_cpp_delete || statement==ID_cpp_delete_array) @@ -1537,18 +1325,6 @@ void value_set_fivrnst::apply_code( } } -/*******************************************************************\ - -Function: value_set_fivrnst::insert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_set_fivrnst::insert_to( object_mapt &dest, unsigned n, @@ -1557,7 +1333,7 @@ bool value_set_fivrnst::insert_to( object_map_dt &map = dest.write(); if(map.find(n)==map.end()) { -// std::cout << "NEW(" << n << "): " << object_numbering[n] << std::endl; +// std::cout << "NEW(" << n << "): " << object_numbering[n] << '\n'; // new map[n]=object; map.set_valid_at(n, to_function, to_target_index); @@ -1565,7 +1341,7 @@ bool value_set_fivrnst::insert_to( } else { -// std::cout << "UPD " << n << std::endl; +// std::cout << "UPD " << n << '\n'; objectt &old=map[n]; bool res = map.set_valid_at(n, to_function, to_target_index); @@ -1590,18 +1366,6 @@ bool value_set_fivrnst::insert_to( } } -/*******************************************************************\ - -Function: value_set_fivrnst::insert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_set_fivrnst::insert_from( object_mapt &dest, unsigned n, @@ -1610,7 +1374,7 @@ bool value_set_fivrnst::insert_from( object_map_dt &map = dest.write(); if(map.find(n)==map.end()) { -// std::cout << "NEW(" << n << "): " << object_numbering[n] << std::endl; +// std::cout << "NEW(" << n << "): " << object_numbering[n] << '\n'; // new map[n]=object; map.set_valid_at(n, from_function, from_target_index); @@ -1618,7 +1382,7 @@ bool value_set_fivrnst::insert_from( } else { -// std::cout << "UPD " << n << std::endl; +// std::cout << "UPD " << n << '\n'; objectt &old=map[n]; bool res = map.set_valid_at(n, from_function, from_target_index); @@ -1643,18 +1407,6 @@ bool value_set_fivrnst::insert_from( } } -/*******************************************************************\ - -Function: value_set_fivrnst::object_map_dt::set_valid_at - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_set_fivrnst::object_map_dt::set_valid_at( unsigned inx, unsigned f, @@ -1726,18 +1478,6 @@ bool value_set_fivrnst::object_map_dt::set_valid_at( return true; } -/*******************************************************************\ - -Function: value_set_fivrnst::object_map_dt::is_valid_at - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool value_set_fivrnst::object_map_dt::is_valid_at( unsigned inx, unsigned f, @@ -1745,7 +1485,7 @@ bool value_set_fivrnst::object_map_dt::is_valid_at( { #if 0 std::cout << "IS_VALID_AT: " << inx << ", " << f << ", line " << line << - std::endl; + '\n'; #endif validity_rangest::const_iterator vrs = validity_ranges.find(inx); @@ -1769,19 +1509,7 @@ bool value_set_fivrnst::object_map_dt::is_valid_at( return false; } -/*******************************************************************\ - -Function: value_set_fivrnst::handover - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -bool value_set_fivrnst::handover(void) +bool value_set_fivrnst::handover() { bool changed=false; @@ -1797,10 +1525,10 @@ bool value_set_fivrnst::handover(void) if(t_it==temporary_values.end()) { -// std::cout << "OLD VALUES FOR: " << ident << std::endl; +// std::cout << "OLD VALUES FOR: " << ident << '\n'; Forall_valid_objects(o_it, state_map.write()) { -// std::cout << "STILL VALID: " << to_expr(o_it) << std::endl; +// std::cout << "STILL VALID: " << to_expr(o_it) << '\n'; if(state_map.write().set_valid_at(o_it->first, to_function, to_target_index)) changed = true; @@ -1808,7 +1536,7 @@ bool value_set_fivrnst::handover(void) } else { -// std::cout << "NEW VALUES FOR: " << ident << std::endl; +// std::cout << "NEW VALUES FOR: " << ident << '\n'; if(make_union(state_map, t_it->second.object_map)) changed = true; } diff --git a/src/pointer-analysis/value_set_fivrns.h b/src/pointer-analysis/value_set_fivrns.h index 89c987b85a6..dc8264caa02 100644 --- a/src/pointer-analysis/value_set_fivrns.h +++ b/src/pointer-analysis/value_set_fivrns.h @@ -7,6 +7,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Value Set (Flow Insensitive, Validity Regions) + #ifndef CPROVER_POINTER_ANALYSIS_VALUE_SET_FIVRNS_H #define CPROVER_POINTER_ANALYSIS_VALUE_SET_FIVRNS_H @@ -85,12 +88,13 @@ class value_set_fivrnst typedef objmapt::iterator iterator; const_iterator find(unsigned k) { return objmap.find(k); } - iterator begin(void) { return objmap.begin(); } - const_iterator begin(void) const { return objmap.begin(); } - iterator end(void) { return objmap.end(); } - const_iterator end(void) const { return objmap.end(); } - size_t size(void) const { return objmap.size(); } - void clear(void) { objmap.clear(); validity_ranges.clear(); } + iterator begin() { return objmap.begin(); } + const_iterator begin() const { return objmap.begin(); } + iterator end() { return objmap.end(); } + const_iterator end() const { return objmap.end(); } + size_t size() const { return objmap.size(); } + bool empty() const { return objmap.empty(); } + void clear() { objmap.clear(); validity_ranges.clear(); } objectt &operator[](unsigned k) { @@ -113,7 +117,7 @@ class value_set_fivrnst unsigned function; unsigned from, to; - validity_ranget(void): + validity_ranget(): function(0), from(0), to(0) { } @@ -300,7 +304,7 @@ class value_set_fivrnst valuest values; valuest temporary_values; - // true = added s.th. new + // true = added something new bool make_union( object_mapt &dest, const object_mapt &src) const; @@ -317,7 +321,7 @@ class value_set_fivrnst const exprt &code, const namespacet &ns); - bool handover(void); + bool handover(); void assign( const exprt &lhs, diff --git a/src/pointer-analysis/value_sets.h b/src/pointer-analysis/value_sets.h index 5e39997b7e1..e230f72ebe7 100644 --- a/src/pointer-analysis/value_sets.h +++ b/src/pointer-analysis/value_sets.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Value Set Propagation + #ifndef CPROVER_POINTER_ANALYSIS_VALUE_SETS_H #define CPROVER_POINTER_ANALYSIS_VALUE_SETS_H diff --git a/src/solvers/cvc/cvc_conv.cpp b/src/solvers/cvc/cvc_conv.cpp index 55c1815b182..356a9af1fd4 100644 --- a/src/solvers/cvc/cvc_conv.cpp +++ b/src/solvers/cvc/cvc_conv.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "cvc_conv.h" + #include #include #include @@ -20,20 +22,6 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "cvc_conv.h" - -/*******************************************************************\ - -Function: cvc_convt::print_assignment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_convt::print_assignment(std::ostream &out) const { // Boolean stuff @@ -44,18 +32,6 @@ void cvc_convt::print_assignment(std::ostream &out) const // others } -/*******************************************************************\ - -Function: cvc_convt::l_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt cvc_convt::l_get(literalt l) const { if(l.is_true()) @@ -66,18 +42,6 @@ tvt cvc_convt::l_get(literalt l) const return tvt(boolean_assignment[l.var_no()]^l.sign()); } -/*******************************************************************\ - -Function: cvc_convt::convert_binary_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_convt::convert_binary_expr(const exprt &expr, const exprt &op) { unsigned to_width= @@ -159,18 +123,6 @@ void cvc_convt::convert_binary_expr(const exprt &expr, const exprt &op) } } -/*******************************************************************\ - -Function: cvc_convt::convert_constant_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_convt::convert_constant_expr(const exprt &expr) { if(expr.type().id()==ID_unsignedbv || @@ -255,18 +207,6 @@ void cvc_convt::convert_constant_expr(const exprt &expr) throw "unknown constant: "+expr.type().id_string(); } -/*******************************************************************\ - -Function: cvc_convt::convert_plus_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_convt::convert_plus_expr(const exprt &expr) { if(expr.operands().size()>=2) @@ -323,18 +263,6 @@ void cvc_convt::convert_plus_expr(const exprt &expr) assert(false); } -/*******************************************************************\ - -Function: cvc_convt::convert_typecast_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_convt::convert_typecast_expr(const exprt &expr) { assert(expr.operands().size()==1); @@ -373,18 +301,6 @@ void cvc_convt::convert_typecast_expr(const exprt &expr) throw "todo typecast4 ? -> "+expr.type().id_string(); } -/*******************************************************************\ - -Function: cvc_convt::convert_struct_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_convt::convert_struct_expr(const exprt &expr) { out << "(# "; @@ -411,18 +327,6 @@ void cvc_convt::convert_struct_expr(const exprt &expr) out << " #)"; } -/*******************************************************************\ - -Function: cvc_convt::convert_equality_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_convt::convert_equality_expr(const exprt &expr) { assert(expr.operands().size()==2); @@ -453,18 +357,6 @@ void cvc_convt::convert_equality_expr(const exprt &expr) } } -/*******************************************************************\ - -Function: cvc_convt::convert_comparison_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_convt::convert_comparison_expr(const exprt &expr) { assert(expr.operands().size()==2); @@ -512,18 +404,6 @@ void cvc_convt::convert_comparison_expr(const exprt &expr) } } -/*******************************************************************\ - -Function: cvc_convt::convert_minus_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_convt::convert_minus_expr(const exprt &expr) { if(expr.operands().size()==2) @@ -548,18 +428,6 @@ void cvc_convt::convert_minus_expr(const exprt &expr) assert(false); } -/*******************************************************************\ - -Function: cvc_convt::convert_with_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_convt::convert_with_expr(const exprt &expr) { assert(expr.operands().size()>=1); @@ -603,18 +471,6 @@ void cvc_convt::convert_with_expr(const exprt &expr) } } -/*******************************************************************\ - -Function: cvc_convt::convert_literal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_convt::convert_literal(const literalt l) { if(l==const_literal(false)) @@ -631,18 +487,6 @@ void cvc_convt::convert_literal(const literalt l) out << ")"; } -/*******************************************************************\ - -Function: cvc_convt::bin_zero - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string cvc_convt::bin_zero(unsigned bits) { assert(bits!=0); @@ -655,18 +499,6 @@ std::string cvc_convt::bin_zero(unsigned bits) return result; } -/*******************************************************************\ - -Function: cvc_convt::cvc_pointer_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string cvc_convt::cvc_pointer_type() { assert(config.ansi_c.pointer_width!=0); @@ -674,36 +506,12 @@ std::string cvc_convt::cvc_pointer_type() std::to_string(config.ansi_c.pointer_width)+") #]"; } -/*******************************************************************\ - -Function: cvc_convt::array_index_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string cvc_convt::array_index_type() { return std::string("BITVECTOR(")+ std::to_string(32)+")"; } -/*******************************************************************\ - -Function: cvc_convt::gen_array_index_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet cvc_convt::gen_array_index_type() { typet t(ID_signedbv); @@ -711,35 +519,11 @@ typet cvc_convt::gen_array_index_type() return t; } -/*******************************************************************\ - -Function: cvc_convt::array_index - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string cvc_convt::array_index(unsigned i) { return "0bin"+integer2binary(i, config.ansi_c.int_width); } -/*******************************************************************\ - -Function: cvc_convt::convert_array_index - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_convt::convert_array_index(const exprt &expr) { if(expr.type()==gen_array_index_type()) @@ -754,18 +538,6 @@ void cvc_convt::convert_array_index(const exprt &expr) } } -/*******************************************************************\ - -Function: cvc_convt::convert_address_of_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_convt::convert_address_of_rec(const exprt &expr) { if(expr.id()==ID_symbol || @@ -835,6 +607,7 @@ void cvc_convt::convert_address_of_rec(const exprt &expr) to_struct_type(struct_op.type()), component_name, ns); + assert(offset>=0); typet index_type(ID_unsignedbv); index_type.set(ID_width, config.ansi_c.pointer_width); @@ -851,18 +624,6 @@ void cvc_convt::convert_address_of_rec(const exprt &expr) throw "don't know how to take address of: "+expr.id_string(); } -/*******************************************************************\ - -Function: cvc_convt::convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt cvc_convt::convert(const exprt &expr) { if(expr.type().id()!=ID_bool) @@ -895,23 +656,11 @@ literalt cvc_convt::convert(const exprt &expr) convert_literal(l); out << " <=> ("; convert_expr(expr); - out << ");" << std::endl << std::endl; + out << ");\n\n"; return l; } -/*******************************************************************\ - -Function: cvc_convt::convert_identifier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_convt::convert_identifier(const std::string &identifier) { for(std::string::const_iterator @@ -948,18 +697,6 @@ void cvc_convt::convert_identifier(const std::string &identifier) } } -/*******************************************************************\ - -Function: cvc_convt::convert_as_bv - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_convt::convert_as_bv(const exprt &expr) { if(expr.type().id()==ID_bool) @@ -979,35 +716,11 @@ void cvc_convt::convert_as_bv(const exprt &expr) convert_expr(expr); } -/*******************************************************************\ - -Function: cvc_convt::convert_array_value - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_convt::convert_array_value(const exprt &expr) { convert_as_bv(expr); } -/*******************************************************************\ - -Function: cvc_convt::convert_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_convt::convert_expr(const exprt &expr) { const exprt::operandst &op=expr.operands(); @@ -1446,18 +1159,6 @@ void cvc_convt::convert_expr(const exprt &expr) throw "convert_expr: "+expr.id_string()+" is unsupported"; } -/*******************************************************************\ - -Function: cvc_convt::set_to - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_convt::set_to(const exprt &expr, bool value) { if(value && expr.id()==ID_and) @@ -1467,7 +1168,7 @@ void cvc_convt::set_to(const exprt &expr, bool value) return; } - out << "%% set_to " << (value?"true":"false") << std::endl; + out << "%% set_to " << (value?"true":"false") << '\n'; if(expr.id()==ID_equal && value) { @@ -1497,7 +1198,7 @@ void cvc_convt::set_to(const exprt &expr, bool value) out << " = "; convert_expr(expr.op1()); - out << ";" << std::endl << std::endl; + out << ";\n\n"; return; } } @@ -1516,21 +1217,9 @@ void cvc_convt::set_to(const exprt &expr, bool value) if(!value) out << ")"; - out << ";" << std::endl << std::endl; + out << ";\n\n"; } -/*******************************************************************\ - -Function: cvc_convt::find_symbols - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_convt::find_symbols(const exprt &expr) { find_symbols(expr.type()); @@ -1554,7 +1243,7 @@ void cvc_convt::find_symbols(const exprt &expr) convert_identifier(id2string(identifier)); out << ": "; convert_type(expr.type()); - out << ";" << std::endl; + out << ";\n"; } } else if(expr.id()==ID_nondet_symbol) @@ -1573,23 +1262,11 @@ void cvc_convt::find_symbols(const exprt &expr) convert_identifier(id2string(identifier)); out << ": "; convert_type(expr.type()); - out << ";" << std::endl; + out << ";\n"; } } } -/*******************************************************************\ - -Function: cvc_convt::convert_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_convt::convert_type(const typet &type) { if(type.id()==ID_array) @@ -1662,18 +1339,6 @@ void cvc_convt::convert_type(const typet &type) throw "unsupported type: "+type.id_string(); } -/*******************************************************************\ - -Function: cvc_convt::find_symbols - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_convt::find_symbols(const typet &type) { if(type.id()==ID_array) diff --git a/src/solvers/cvc/cvc_conv.h b/src/solvers/cvc/cvc_conv.h index 7f1c37b5ee2..c3fc7dbe182 100644 --- a/src/solvers/cvc/cvc_conv.h +++ b/src/solvers/cvc/cvc_conv.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_CVC_CVC_CONV_H #define CPROVER_SOLVERS_CVC_CVC_CONV_H diff --git a/src/solvers/cvc/cvc_dec.cpp b/src/solvers/cvc/cvc_dec.cpp index b7fd3a2c3e2..cdb83e67afa 100644 --- a/src/solvers/cvc/cvc_dec.cpp +++ b/src/solvers/cvc/cvc_dec.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "cvc_dec.h" + #include #include #include // for system() @@ -27,20 +29,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "cvc_dec.h" - -/*******************************************************************\ - -Function: cvc_temp_filet::cvc_temp_filet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - cvc_temp_filet::cvc_temp_filet() { temp_out_filename="cvc_dec_out_"+std::to_string(getpid())+".tmp"; @@ -50,18 +38,6 @@ cvc_temp_filet::cvc_temp_filet() std::ios_base::out | std::ios_base::trunc); } -/*******************************************************************\ - -Function: cvc_temp_filet::~cvc_temp_filet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - cvc_temp_filet::~cvc_temp_filet() { temp_out.close(); @@ -73,22 +49,10 @@ cvc_temp_filet::~cvc_temp_filet() unlink(temp_result_filename.c_str()); } -/*******************************************************************\ - -Function: cvc_dect::dec_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - decision_proceduret::resultt cvc_dect::dec_solve() { - out << "QUERY FALSE;" << std::endl; - out << "COUNTERMODEL;" << std::endl; + out << "QUERY FALSE;\n"; + out << "COUNTERMODEL;\n"; temp_out.close(); @@ -106,18 +70,6 @@ decision_proceduret::resultt cvc_dect::dec_solve() return read_cvcl_result(); } -/*******************************************************************\ - -Function: cvc_dect::read_assert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_dect::read_assert(std::istream &in, std::string &line) { // strip ASSERT @@ -150,8 +102,7 @@ void cvc_dect::read_assert(std::istream &in, std::string &line) std::string value=std::string(line, pos, pos2-pos); #if 0 - std::cout << ">" << identifier << "< = >" << value << "<"; - std::cout << std::endl; + std::cout << ">" << identifier << "< = >" << value << "<\n"; #endif } else @@ -178,18 +129,6 @@ void cvc_dect::read_assert(std::istream &in, std::string &line) } } -/*******************************************************************\ - -Function: cvc_dect::read_cvcl_result - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - decision_proceduret::resultt cvc_dect::read_cvcl_result() { std::ifstream in(temp_result_filename.c_str()); @@ -209,13 +148,13 @@ decision_proceduret::resultt cvc_dect::read_cvcl_result() read_assert(in, line); } - return D_SATISFIABLE; + return resultt::D_SATISFIABLE; } else if(has_prefix(line, "Valid.")) - return D_UNSATISFIABLE; + return resultt::D_UNSATISFIABLE; } error() << "Unexpected result from CVC-Lite" << eom; - return D_ERROR; + return resultt::D_ERROR; } diff --git a/src/solvers/cvc/cvc_dec.h b/src/solvers/cvc/cvc_dec.h index e819edc2755..66f5e77c43a 100644 --- a/src/solvers/cvc/cvc_dec.h +++ b/src/solvers/cvc/cvc_dec.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_CVC_CVC_DEC_H #define CPROVER_SOLVERS_CVC_CVC_DEC_H diff --git a/src/solvers/cvc/cvc_prop.cpp b/src/solvers/cvc/cvc_prop.cpp index 27c499620ea..7a02bd65335 100644 --- a/src/solvers/cvc/cvc_prop.cpp +++ b/src/solvers/cvc/cvc_prop.cpp @@ -6,200 +6,79 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include -#include - - #include "cvc_prop.h" -/*******************************************************************\ - -Function: cvc_propt::cvc_propt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include explicit cvc_propt::cvc_propt(std::ostream &_out):out(_out) { _no_variables=0; } -/*******************************************************************\ - -Function: cvc_propt::~cvc_propt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - cvc_propt::~cvc_propt() { } -/*******************************************************************\ - -Function: cvc_propt::land - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_propt::land(literalt a, literalt b, literalt o) { - out << "%% land" << std::endl; + out << "%% land\n"; out << "ASSERT (" << cvc_literal(a) << " AND " << cvc_literal(b) << ") <=> " << cvc_literal(o) - << ";" << std::endl << std::endl; + << ";\n\n"; } -/*******************************************************************\ - -Function: cvc_propt::lor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_propt::lor(literalt a, literalt b, literalt o) { - out << "%% lor" << std::endl; + out << "%% lor\n"; out << "ASSERT (" << cvc_literal(a) << " OR " << cvc_literal(b) << ") <=> " << cvc_literal(o) - << ";" << std::endl << std::endl; + << ";\n\n"; } -/*******************************************************************\ - -Function: cvc_propt::lxor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_propt::lxor(literalt a, literalt b, literalt o) { - out << "%% lxor" << std::endl; + out << "%% lxor\n"; out << "ASSERT (" << cvc_literal(a) << " XOR " << cvc_literal(b) << ") <=> " << cvc_literal(o) - << ";" << std::endl << std::endl; + << ";\n\n"; } -/*******************************************************************\ - -Function: cvc_propt::lnand - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_propt::lnand(literalt a, literalt b, literalt o) { - out << "%% lnand" << std::endl; + out << "%% lnand\n"; out << "ASSERT (NOT (" << cvc_literal(a) << " AND " << cvc_literal(b) << ")) <=> " << cvc_literal(o) - << ";" << std::endl << std::endl; + << ";\n\n"; } -/*******************************************************************\ - -Function: cvc_propt::lnor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_propt::lnor(literalt a, literalt b, literalt o) { - out << "%% lnor" << std::endl; + out << "%% lnor\n"; out << "ASSERT (NOT (" << cvc_literal(a) << " OR " << cvc_literal(b) << ")) <=> " << cvc_literal(o) - << ";" << std::endl << std::endl; + << ";\n\n"; } -/*******************************************************************\ - -Function: cvc_propt::lequal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_propt::lequal(literalt a, literalt b, literalt o) { - out << "%% lequal" << std::endl; + out << "%% lequal\n"; out << "ASSERT (" << cvc_literal(a) << " <=> " << cvc_literal(b) << ") <=> " << cvc_literal(o) - << ";" << std::endl << std::endl; + << ";\n\n"; } -/*******************************************************************\ - -Function: cvc_propt::limplies - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_propt::limplies(literalt a, literalt b, literalt o) { - out << "%% limplies" << std::endl; + out << "%% limplies\n"; out << "ASSERT (" << cvc_literal(a) << " => " << cvc_literal(b) << ") <=> " << cvc_literal(o) - << ";" << std::endl << std::endl; + << ";\n\n"; } -/*******************************************************************\ - -Function: cvc_propt::land - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt cvc_propt::land(const bvt &bv) { - out << "%% land" << std::endl; + out << "%% land\n"; literalt literal=def_cvc_literal(); @@ -210,26 +89,14 @@ literalt cvc_propt::land(const bvt &bv) out << cvc_literal(*it); } - out << ";" << std::endl << std::endl; + out << ";\n\n"; return literal; } -/*******************************************************************\ - -Function: cvc_propt::lor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt cvc_propt::lor(const bvt &bv) { - out << "%% lor" << std::endl; + out << "%% lor\n"; literalt literal=def_cvc_literal(); @@ -240,23 +107,11 @@ literalt cvc_propt::lor(const bvt &bv) out << cvc_literal(*it); } - out << ";" << std::endl << std::endl; + out << ";\n\n"; return literal; } -/*******************************************************************\ - -Function: cvc_propt::lxor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt cvc_propt::lxor(const bvt &bv) { if(bv.empty()) @@ -274,18 +129,6 @@ literalt cvc_propt::lxor(const bvt &bv) return literal; } -/*******************************************************************\ - -Function: cvc_propt::land - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt cvc_propt::land(literalt a, literalt b) { if(a==const_literal(true)) @@ -299,28 +142,15 @@ literalt cvc_propt::land(literalt a, literalt b) if(a==b) return a; - out << "%% land" << std::endl; + out << "%% land\n"; literalt o=def_cvc_literal(); - out << cvc_literal(a) << " AND " << cvc_literal(b) << ";" - << std::endl << std::endl; + out << cvc_literal(a) << " AND " << cvc_literal(b) << ";\n\n"; return o; } -/*******************************************************************\ - -Function: cvc_propt::lor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt cvc_propt::lor(literalt a, literalt b) { if(a==const_literal(false)) @@ -334,28 +164,15 @@ literalt cvc_propt::lor(literalt a, literalt b) if(a==b) return a; - out << "%% lor" << std::endl; + out << "%% lor\n"; literalt o=def_cvc_literal(); - out << cvc_literal(a) << " OR " << cvc_literal(b) << ";" - << std::endl << std::endl; + out << cvc_literal(a) << " OR " << cvc_literal(b) << ";\n\n"; return o; } -/*******************************************************************\ - -Function: cvc_propt::lxor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt cvc_propt::lxor(literalt a, literalt b) { if(a==const_literal(false)) @@ -367,96 +184,35 @@ literalt cvc_propt::lxor(literalt a, literalt b) if(b==const_literal(true)) return !a; - out << "%% lxor" << std::endl; + out << "%% lxor\n"; literalt o=def_cvc_literal(); - out << cvc_literal(a) << " XOR " << cvc_literal(b) << ";" - << std::endl << std::endl; + out << cvc_literal(a) << " XOR " << cvc_literal(b) << ";\n\n"; return o; } -/*******************************************************************\ - -Function: cvc_propt::lnand - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt cvc_propt::lnand(literalt a, literalt b) { return !land(a, b); } -/*******************************************************************\ - -Function: cvc_propt::lnor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt cvc_propt::lnor(literalt a, literalt b) { return !lor(a, b); } -/*******************************************************************\ - -Function: cvc_propt::lequal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt cvc_propt::lequal(literalt a, literalt b) { return !lxor(a, b); } -/*******************************************************************\ - -Function: cvc_propt::limplies - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt cvc_propt::limplies(literalt a, literalt b) { return lor(!a, b); } -/*******************************************************************\ - -Function: cvc_propt::lselect - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt cvc_propt::lselect(literalt a, literalt b, literalt c) { if(a==const_literal(true)) @@ -466,51 +222,26 @@ literalt cvc_propt::lselect(literalt a, literalt b, literalt c) if(b==c) return b; - out << "%% lselect" << std::endl; + out << "%% lselect\n"; literalt o=def_cvc_literal(); out << "IF " << cvc_literal(a) << " THEN " << cvc_literal(b) << " ELSE " - << cvc_literal(c) << " ENDIF;" - << std::endl << std::endl; + << cvc_literal(c) << " ENDIF;\n\n"; return o; } -/*******************************************************************\ - -Function: cvc_propt::new_variable - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt cvc_propt::new_variable() { - out << "l" << _no_variables << ": BOOLEAN;" << std::endl; + out << "l" << _no_variables << ": BOOLEAN;\n"; literalt l; l.set(_no_variables, false); _no_variables++; return l; } -/*******************************************************************\ - -Function: cvc_propt::def_cvc_literal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt cvc_propt::def_cvc_literal() { out << "l" << _no_variables << ": BOOLEAN = "; @@ -520,18 +251,6 @@ literalt cvc_propt::def_cvc_literal() return l; } -/*******************************************************************\ - -Function: cvc_propt::lcnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cvc_propt::lcnf(const bvt &bv) { if(bv.empty()) @@ -555,7 +274,7 @@ void cvc_propt::lcnf(const bvt &bv) assert(!new_bv.empty()); - out << "%% lcnf" << std::endl; + out << "%% lcnf\n"; out << "ASSERT "; for(bvt::const_iterator it=new_bv.begin(); it!=new_bv.end(); it++) @@ -565,21 +284,9 @@ void cvc_propt::lcnf(const bvt &bv) out << cvc_literal(*it); } - out << ";" << std::endl << std::endl; + out << ";\n\n"; } -/*******************************************************************\ - -Function: cvc_propt::cvc_literal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string cvc_propt::cvc_literal(literalt l) { if(l==const_literal(false)) @@ -593,20 +300,8 @@ std::string cvc_propt::cvc_literal(literalt l) return "l"+std::to_string(l.var_no()); } -/*******************************************************************\ - -Function: cvc_propt::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - propt::resultt cvc_propt::prop_solve() { - out << "QUERY FALSE;" << std::endl; + out << "QUERY FALSE;\n"; return P_ERROR; } diff --git a/src/solvers/cvc/cvc_prop.h b/src/solvers/cvc/cvc_prop.h index cc83906a3f7..82786e0a2bb 100644 --- a/src/solvers/cvc/cvc_prop.h +++ b/src/solvers/cvc/cvc_prop.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_CVC_CVC_PROP_H #define CPROVER_SOLVERS_CVC_CVC_PROP_H diff --git a/src/solvers/dplib/dplib_conv.cpp b/src/solvers/dplib/dplib_conv.cpp index d9d7eefbb11..a87cd0c25a2 100644 --- a/src/solvers/dplib/dplib_conv.cpp +++ b/src/solvers/dplib/dplib_conv.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "dplib_conv.h" + #include #include @@ -19,20 +21,6 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "dplib_conv.h" - -/*******************************************************************\ - -Function: dplib_convt::bin_zero - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string dplib_convt::bin_zero(unsigned bits) { assert(bits!=0); @@ -41,18 +29,6 @@ std::string dplib_convt::bin_zero(unsigned bits) return result; } -/*******************************************************************\ - -Function: dplib_convt::dplib_pointer_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string dplib_convt::dplib_pointer_type() { assert(config.ansi_c.pointer_width!=0); @@ -60,35 +36,11 @@ std::string dplib_convt::dplib_pointer_type() std::to_string(config.ansi_c.pointer_width)+") #]"; } -/*******************************************************************\ - -Function: dplib_convt::array_index_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string dplib_convt::array_index_type() { return std::string("SIGNED [")+std::to_string(32)+"]"; } -/*******************************************************************\ - -Function: dplib_convt::gen_array_index_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet dplib_convt::gen_array_index_type() { typet t(ID_signedbv); @@ -96,35 +48,11 @@ typet dplib_convt::gen_array_index_type() return t; } -/*******************************************************************\ - -Function: dplib_convt::array_index - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string dplib_convt::array_index(unsigned i) { return "0bin"+integer2binary(i, config.ansi_c.int_width); } -/*******************************************************************\ - -Function: dplib_convt::convert_array_index - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dplib_convt::convert_array_index(const exprt &expr) { if(expr.type()==gen_array_index_type()) @@ -139,18 +67,6 @@ void dplib_convt::convert_array_index(const exprt &expr) } } -/*******************************************************************\ - -Function: dplib_convt::convert_address_of_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dplib_convt::convert_address_of_rec(const exprt &expr) { if(expr.id()==ID_symbol || @@ -218,6 +134,7 @@ void dplib_convt::convert_address_of_rec(const exprt &expr) mp_integer offset=member_offset(ns, to_struct_type(struct_op.type()), component_name); + assert(offset>=0); typet index_type(ID_unsignedbv); index_type.set(ID_width, config.ansi_c.pointer_width); @@ -234,21 +151,9 @@ void dplib_convt::convert_address_of_rec(const exprt &expr) throw "don't know how to take address of: "+expr.id_string(); } -/*******************************************************************\ - -Function: dplib_convt::convert_rest - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt dplib_convt::convert_rest(const exprt &expr) { - // dplib_prop.out << "%% E: " << expr << std::endl; + // dplib_prop.out << "%% E: " << expr << '\n'; literalt l=prop.new_variable(); @@ -262,24 +167,12 @@ literalt dplib_convt::convert_rest(const exprt &expr) convert_dplib_expr(expr.op0()); dplib_prop.out << ((expr.id()==ID_equal)?"=":"/="); convert_dplib_expr(expr.op1()); - dplib_prop.out << ");" << std::endl; + dplib_prop.out << ");\n"; } return l; } -/*******************************************************************\ - -Function: dplib_convt::convert_identifier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dplib_convt::convert_identifier(const std::string &identifier) { for(std::string::const_iterator @@ -316,18 +209,6 @@ void dplib_convt::convert_identifier(const std::string &identifier) } } -/*******************************************************************\ - -Function: dplib_convt::convert_as_bv - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dplib_convt::convert_as_bv(const exprt &expr) { if(expr.type().id()==ID_bool) @@ -340,35 +221,11 @@ void dplib_convt::convert_as_bv(const exprt &expr) convert_dplib_expr(expr); } -/*******************************************************************\ - -Function: dplib_convt::convert_array_value - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dplib_convt::convert_array_value(const exprt &expr) { convert_as_bv(expr); } -/*******************************************************************\ - -Function: dplib_convt::convert_dplib_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dplib_convt::convert_dplib_expr(const exprt &expr) { if(expr.id()==ID_symbol) @@ -1105,18 +962,6 @@ void dplib_convt::convert_dplib_expr(const exprt &expr) throw "convert_dplib_expr: "+expr.id_string()+" is unsupported"; } -/*******************************************************************\ - -Function: dplib_convt::set_to - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dplib_convt::set_to(const exprt &expr, bool value) { if(value && expr.id()==ID_and) @@ -1129,7 +974,7 @@ void dplib_convt::set_to(const exprt &expr, bool value) if(value && expr.is_true()) return; - dplib_prop.out << "// set_to " << (value?"true":"false") << std::endl; + dplib_prop.out << "// set_to " << (value?"true":"false") << '\n'; if(expr.id()==ID_equal && value) { @@ -1159,7 +1004,7 @@ void dplib_convt::set_to(const exprt &expr, bool value) dplib_prop.out << " = "; convert_dplib_expr(expr.op1()); - dplib_prop.out << ";" << std::endl << std::endl; + dplib_prop.out << ";\n\n"; return; } } @@ -1178,21 +1023,9 @@ void dplib_convt::set_to(const exprt &expr, bool value) if(!value) dplib_prop.out << ")"; - dplib_prop.out << ";" << std::endl << std::endl; + dplib_prop.out << ";\n\n"; } -/*******************************************************************\ - -Function: dplib_convt::find_symbols - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dplib_convt::find_symbols(const exprt &expr) { find_symbols(expr.type()); @@ -1216,7 +1049,7 @@ void dplib_convt::find_symbols(const exprt &expr) convert_identifier(id2string(identifier)); dplib_prop.out << ": "; convert_dplib_type(expr.type()); - dplib_prop.out << ";" << std::endl; + dplib_prop.out << ";\n"; } } else if(expr.id()==ID_nondet_symbol) @@ -1235,23 +1068,11 @@ void dplib_convt::find_symbols(const exprt &expr) convert_identifier(id2string(identifier)); dplib_prop.out << ": "; convert_dplib_type(expr.type()); - dplib_prop.out << ";" << std::endl; + dplib_prop.out << ";\n"; } } } -/*******************************************************************\ - -Function: dplib_convt::convert_dplib_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dplib_convt::convert_dplib_type(const typet &type) { if(type.id()==ID_array) @@ -1335,18 +1156,6 @@ void dplib_convt::convert_dplib_type(const typet &type) throw "unsupported type: "+type.id_string(); } -/*******************************************************************\ - -Function: dplib_convt::find_symbols - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dplib_convt::find_symbols(const typet &type) { if(type.id()==ID_array) diff --git a/src/solvers/dplib/dplib_conv.h b/src/solvers/dplib/dplib_conv.h index a4f2f0558f4..74034d6c1e2 100644 --- a/src/solvers/dplib/dplib_conv.h +++ b/src/solvers/dplib/dplib_conv.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_DPLIB_DPLIB_CONV_H #define CPROVER_SOLVERS_DPLIB_DPLIB_CONV_H diff --git a/src/solvers/dplib/dplib_dec.cpp b/src/solvers/dplib/dplib_dec.cpp index 66369bdc1ff..111805276ba 100644 --- a/src/solvers/dplib/dplib_dec.cpp +++ b/src/solvers/dplib/dplib_dec.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "dplib_dec.h" + #include #include @@ -26,20 +28,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "dplib_dec.h" - -/*******************************************************************\ - -Function: dplib_temp_filet::dplib_temp_filet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - dplib_temp_filet::dplib_temp_filet() { temp_out_filename="dplib_dec_out_"+std::to_string(getpid())+".tmp"; @@ -49,18 +37,6 @@ dplib_temp_filet::dplib_temp_filet() std::ios_base::out | std::ios_base::trunc); } -/*******************************************************************\ - -Function: dplib_temp_filet::~dplib_temp_filet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - dplib_temp_filet::~dplib_temp_filet() { temp_out.close(); @@ -72,22 +48,10 @@ dplib_temp_filet::~dplib_temp_filet() unlink(temp_result_filename.c_str()); } -/*******************************************************************\ - -Function: dplib_dect::dec_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - decision_proceduret::resultt dplib_dect::dec_solve() { - dplib_prop.out << "QUERY FALSE;" << std::endl; - dplib_prop.out << "COUNTERMODEL;" << std::endl; + dplib_prop.out << "QUERY FALSE;\n"; + dplib_prop.out << "COUNTERMODEL;\n"; post_process(); @@ -107,18 +71,6 @@ decision_proceduret::resultt dplib_dect::dec_solve() return read_dplib_result(); } -/*******************************************************************\ - -Function: dplib_dect::read_assert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dplib_dect::read_assert(std::istream &in, std::string &line) { // strip ASSERT @@ -151,8 +103,7 @@ void dplib_dect::read_assert(std::istream &in, std::string &line) std::string value=std::string(line, pos, pos2-pos); #if 0 - std::cout << ">" << identifier << "< = >" << value << "<"; - std::cout << std::endl; + std::cout << ">" << identifier << "< = >" << value << "<\n"; #endif } else @@ -178,18 +129,6 @@ void dplib_dect::read_assert(std::istream &in, std::string &line) } } -/*******************************************************************\ - -Function: dplib_dect::read_dplib_result - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - decision_proceduret::resultt dplib_dect::read_dplib_result() { std::ifstream in(temp_result_filename.c_str()); diff --git a/src/solvers/dplib/dplib_dec.h b/src/solvers/dplib/dplib_dec.h index 6f722569ec4..ca481518a80 100644 --- a/src/solvers/dplib/dplib_dec.h +++ b/src/solvers/dplib/dplib_dec.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_DPLIB_DPLIB_DEC_H #define CPROVER_SOLVERS_DPLIB_DPLIB_DEC_H diff --git a/src/solvers/dplib/dplib_prop.cpp b/src/solvers/dplib/dplib_prop.cpp index 5153b6874de..a0111b3b8fc 100644 --- a/src/solvers/dplib/dplib_prop.cpp +++ b/src/solvers/dplib/dplib_prop.cpp @@ -6,24 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - -#include - - #include "dplib_prop.h" -/*******************************************************************\ - -Function: dplib_propt::dplib_propt - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include dplib_propt::dplib_propt(std::ostream &_out):out(_out) { @@ -31,161 +18,65 @@ dplib_propt::dplib_propt(std::ostream &_out):out(_out) _no_variables=1; } -/*******************************************************************\ - -Function: dplib_propt::land - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dplib_propt::land(literalt a, literalt b, literalt o) { - out << "// land" << std::endl; + out << "// land\n"; out << "AXIOM (" << dplib_literal(a) << " & " << dplib_literal(b) << ") <=> " << dplib_literal(o) - << ";" << std::endl << std::endl; + << ";\n\n"; } -/*******************************************************************\ - -Function: dplib_propt::lor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dplib_propt::lor(literalt a, literalt b, literalt o) { - out << "// lor" << std::endl; + out << "// lor\n"; out << "AXIOM (" << dplib_literal(a) << " | " << dplib_literal(b) << ") <=> " << dplib_literal(o) - << ";" << std::endl << std::endl; + << ";\n\n"; } -/*******************************************************************\ - -Function: dplib_propt::lxor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dplib_propt::lxor(literalt a, literalt b, literalt o) { - out << "// lxor" << std::endl; + out << "// lxor\n"; out << "AXIOM (" << dplib_literal(a) << " <=> " << dplib_literal(b) << ") <=> !" << dplib_literal(o) - << ";" << std::endl << std::endl; + << ";\n\n"; } -/*******************************************************************\ - -Function: dplib_propt::lnand - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dplib_propt::lnand(literalt a, literalt b, literalt o) { - out << "// lnand" << std::endl; + out << "// lnand\n"; out << "AXIOM (" << dplib_literal(a) << " & " << dplib_literal(b) << ") <=> !" << dplib_literal(o) - << ";" << std::endl << std::endl; + << ";\n\n"; } -/*******************************************************************\ - -Function: dplib_propt::lnor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dplib_propt::lnor(literalt a, literalt b, literalt o) { - out << "// lnor" << std::endl; + out << "// lnor\n"; out << "AXIOM (" << dplib_literal(a) << " | " << dplib_literal(b) << ") <=> !" << dplib_literal(o) - << ";" << std::endl << std::endl; + << ";\n\n"; } -/*******************************************************************\ - -Function: dplib_propt::lequal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dplib_propt::lequal(literalt a, literalt b, literalt o) { - out << "// lequal" << std::endl; + out << "// lequal\n"; out << "AXIOM (" << dplib_literal(a) << " <=> " << dplib_literal(b) << ") <=> " << dplib_literal(o) - << ";" << std::endl << std::endl; + << ";\n\n"; } -/*******************************************************************\ - -Function: dplib_propt::limplies - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dplib_propt::limplies(literalt a, literalt b, literalt o) { - out << "// limplies" << std::endl; + out << "// limplies\n"; out << "AXIOM (" << dplib_literal(a) << " => " << dplib_literal(b) << ") <=> " << dplib_literal(o) - << ";" << std::endl << std::endl; + << ";\n\n"; } -/*******************************************************************\ - -Function: dplib_propt::land - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt dplib_propt::land(const bvt &bv) { - out << "// land" << std::endl; + out << "// land\n"; literalt literal=def_dplib_literal(); @@ -196,26 +87,14 @@ literalt dplib_propt::land(const bvt &bv) out << dplib_literal(*it); } - out << std::endl << std::endl; + out << "\n\n"; return literal; } -/*******************************************************************\ - -Function: dplib_propt::lor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt dplib_propt::lor(const bvt &bv) { - out << "// lor" << std::endl; + out << "// lor\n"; literalt literal=def_dplib_literal(); @@ -226,23 +105,11 @@ literalt dplib_propt::lor(const bvt &bv) out << dplib_literal(*it); } - out << std::endl << std::endl; + out << "\n\n"; return literal; } -/*******************************************************************\ - -Function: dplib_propt::lxor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt dplib_propt::lxor(const bvt &bv) { if(bv.empty()) @@ -260,18 +127,6 @@ literalt dplib_propt::lxor(const bvt &bv) return literal; } -/*******************************************************************\ - -Function: dplib_propt::land - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt dplib_propt::land(literalt a, literalt b) { if(a==const_literal(true)) @@ -287,23 +142,11 @@ literalt dplib_propt::land(literalt a, literalt b) literalt o=def_dplib_literal(); out << dplib_literal(a) << " & " << dplib_literal(b) - << ";" << std::endl << std::endl; + << ";\n\n"; return o; } -/*******************************************************************\ - -Function: dplib_propt::lor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt dplib_propt::lor(literalt a, literalt b) { if(a==const_literal(false)) @@ -319,23 +162,11 @@ literalt dplib_propt::lor(literalt a, literalt b) literalt o=def_dplib_literal(); out << dplib_literal(a) << " | " << dplib_literal(b) - << ";" << std::endl << std::endl; + << ";\n\n"; return o; } -/*******************************************************************\ - -Function: dplib_propt::lxor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt dplib_propt::lxor(literalt a, literalt b) { if(a==const_literal(false)) @@ -349,91 +180,31 @@ literalt dplib_propt::lxor(literalt a, literalt b) literalt o=def_dplib_literal(); out << "!(" << dplib_literal(a) << " <-> " << dplib_literal(b) - << ");" << std::endl << std::endl; + << ");\n\n"; return o; } -/*******************************************************************\ - -Function: dplib_propt::lnand - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt dplib_propt::lnand(literalt a, literalt b) { return !land(a, b); } -/*******************************************************************\ - -Function: dplib_propt::lnor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt dplib_propt::lnor(literalt a, literalt b) { return !lor(a, b); } -/*******************************************************************\ - -Function: dplib_propt::lequal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt dplib_propt::lequal(literalt a, literalt b) { return !lxor(a, b); } -/*******************************************************************\ - -Function: dplib_propt::limplies - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt dplib_propt::limplies(literalt a, literalt b) { return lor(!a, b); } -/*******************************************************************\ - -Function: dplib_propt::lselect - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt dplib_propt::lselect(literalt a, literalt b, literalt c) { if(a==const_literal(true)) @@ -443,51 +214,26 @@ literalt dplib_propt::lselect(literalt a, literalt b, literalt c) if(b==c) return b; - out << "// lselect" << std::endl; + out << "// lselect\n"; literalt o=def_dplib_literal(); out << "IF " << dplib_literal(a) << " THEN " << dplib_literal(b) << " ELSE " - << dplib_literal(c) << " ENDIF;" - << std::endl << std::endl; + << dplib_literal(c) << " ENDIF;\n\n"; return o; } -/*******************************************************************\ - -Function: dplib_propt::new_variable - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt dplib_propt::new_variable() { _no_variables++; - out << "l" << _no_variables << ": boolean;" << std::endl; + out << "l" << _no_variables << ": boolean;\n"; literalt l; l.set(_no_variables, false); return l; } -/*******************************************************************\ - -Function: dplib_propt::def_dplib_literal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt dplib_propt::def_dplib_literal() { _no_variables++; @@ -497,18 +243,6 @@ literalt dplib_propt::def_dplib_literal() return l; } -/*******************************************************************\ - -Function: dplib_propt::lcnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dplib_propt::lcnf(const bvt &bv) { if(bv.empty()) @@ -532,7 +266,7 @@ void dplib_propt::lcnf(const bvt &bv) assert(!new_bv.empty()); - out << "// lcnf" << std::endl; + out << "// lcnf\n"; out << "AXIOM "; for(bvt::const_iterator it=new_bv.begin(); it!=new_bv.end(); it++) @@ -542,21 +276,9 @@ void dplib_propt::lcnf(const bvt &bv) out << dplib_literal(*it); } - out << ";" << std::endl << std::endl; + out << ";\n\n"; } -/*******************************************************************\ - -Function: dplib_propt::dplib_literal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string dplib_propt::dplib_literal(literalt l) { if(l==const_literal(false)) @@ -570,36 +292,12 @@ std::string dplib_propt::dplib_literal(literalt l) return "l"+std::to_string(l.var_no()); } -/*******************************************************************\ - -Function: dplib_propt::finish - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dplib_propt::finish() { // we want satisfiability - out << "THEOREM false;" << std::endl; + out << "THEOREM false;\n"; } -/*******************************************************************\ - -Function: dplib_propt::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - propt::resultt dplib_propt::prop_solve() { finish(); diff --git a/src/solvers/dplib/dplib_prop.h b/src/solvers/dplib/dplib_prop.h index 7aec9d47980..89441646093 100644 --- a/src/solvers/dplib/dplib_prop.h +++ b/src/solvers/dplib/dplib_prop.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_DPLIB_DPLIB_PROP_H #define CPROVER_SOLVERS_DPLIB_DPLIB_PROP_H diff --git a/src/solvers/flattening/arrays.cpp b/src/solvers/flattening/arrays.cpp index 9f72a8e3475..82d82c0b3e9 100644 --- a/src/solvers/flattening/arrays.cpp +++ b/src/solvers/flattening/arrays.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "arrays.h" + #include #include @@ -19,20 +21,6 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "arrays.h" - -/*******************************************************************\ - -Function: arrayst::arrayst - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - arrayst::arrayst( const namespacet &_ns, propt &_prop):equalityt(_ns, _prop) @@ -41,18 +29,6 @@ arrayst::arrayst( incremental_cache = false; // for incremental solving } -/*******************************************************************\ - -Function: arrayst::record_array_index - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void arrayst::record_array_index(const index_exprt &index) { // we are not allowed to put the index directly in the @@ -63,18 +39,6 @@ void arrayst::record_array_index(const index_exprt &index) update_indices.insert(number); } -/*******************************************************************\ - -Function: arrayst::record_array_equality - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt arrayst::record_array_equality( const equal_exprt &equality) { @@ -84,7 +48,7 @@ literalt arrayst::record_array_equality( // check types if(!base_type_eq(op0.type(), op1.type(), ns)) { - std::cout << equality.pretty() << std::endl; + std::cout << equality.pretty() << '\n'; throw "record_array_equality got equality without matching types"; } @@ -103,18 +67,6 @@ literalt arrayst::record_array_equality( return array_equalities.back().l; } -/*******************************************************************\ - -Function: arrayst::collect_indices - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void arrayst::collect_indices() { for(std::size_t i=0; if1)], - *it); + add_array_constraints_equality( + index_map[arrays.find_number(equality.f1)], + equality); // update_index_map should not be necessary here } @@ -373,24 +276,12 @@ void arrayst::add_array_constraints() add_array_Ackermann_constraints(); } -/*******************************************************************\ - -Function: arrayst::add_array_Ackermann_constraints - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void arrayst::add_array_Ackermann_constraints() { // this is quadratic! #if 0 - std::cout << "arrays.size(): " << arrays.size() << std::endl; + std::cout << "arrays.size(): " << arrays.size() << '\n'; #endif // iterate over arrays @@ -399,7 +290,7 @@ void arrayst::add_array_Ackermann_constraints() const index_sett &index_set=index_map[arrays.find_number(i)]; #if 0 - std::cout << "index_set.size(): " << index_set.size() << std::endl; + std::cout << "index_set.size(): " << index_set.size() << '\n'; #endif // iterate over indices, 2x! @@ -430,10 +321,8 @@ void arrayst::add_array_Ackermann_constraints() if(indices_equal_lit!=const_literal(false)) { - index_exprt index_expr1; - index_expr1.type()=ns.follow(arrays[i].type()).subtype(); - index_expr1.array()=arrays[i]; - index_expr1.index()=*i1; + const typet &subtype=ns.follow(arrays[i].type()).subtype(); + index_exprt index_expr1(arrays[i], *i1, subtype); index_exprt index_expr2=index_expr1; index_expr2.index()=*i2; @@ -441,7 +330,7 @@ void arrayst::add_array_Ackermann_constraints() equal_exprt values_equal(index_expr1, index_expr2); // add constraint - lazy_constraintt lazy(ARRAY_ACKERMANN, + lazy_constraintt lazy(lazy_typet::ARRAY_ACKERMANN, or_exprt(literal_exprt(!indices_equal_lit), values_equal)); add_array_constraint(lazy, true); // added lazily @@ -453,18 +342,7 @@ void arrayst::add_array_Ackermann_constraints() } } -/*******************************************************************\ - -Function: arrayst::update_index_map - - Inputs: - - Outputs: - - Purpose: merge the indices into the root - -\*******************************************************************/ - +/// merge the indices into the root void arrayst::update_index_map(std::size_t i) { if(arrays.is_root_number(i)) @@ -495,64 +373,39 @@ void arrayst::update_index_map(bool update_all) } else { - for(std::set::const_iterator - it=update_indices.begin(); - it!=update_indices.end(); it++) - update_index_map(*it); + for(const auto &index : update_indices) + update_index_map(index); + update_indices.clear(); } #ifdef DEBUG // print index sets - for(index_mapt::const_iterator - i1=index_map.begin(); - i1!=index_map.end(); - i1++) - for(index_sett::const_iterator - i2=i1->second.begin(); - i2!=i1->second.end(); - i2++) - std::cout << "Index set (" << i1->first << " = " - << arrays.find_number(i1->first) << " = " - << from_expr(ns, "", arrays[arrays.find_number(i1->first)]) + for(const auto &index_entry : index_map) + for(const auto &index : index_entry.second) + std::cout << "Index set (" << index_entry.first << " = " + << arrays.find_number(index_entry.first) << " = " + << from_expr(ns, "", + arrays[arrays.find_number(index_entry.first)]) << "): " - << from_expr(ns, "", *i2) << std::endl; - std::cout << "-----" << std::endl; + << from_expr(ns, "", index) << '\n'; + std::cout << "-----\n"; #endif } -/*******************************************************************\ - -Function: arrayst::add_array_constraints - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void arrayst::add_array_constraints( +void arrayst::add_array_constraints_equality( const index_sett &index_set, const array_equalityt &array_equality) { // add constraints x=y => x[i]=y[i] - for(index_sett::const_iterator - it=index_set.begin(); - it!=index_set.end(); - it++) + for(const auto &index : index_set) { - index_exprt index_expr1; - index_expr1.type()=ns.follow(array_equality.f1.type()).subtype(); - index_expr1.array()=array_equality.f1; - index_expr1.index()=*it; + const typet &subtype1=ns.follow(array_equality.f1.type()).subtype(); + index_exprt index_expr1(array_equality.f1, index, subtype1); - index_exprt index_expr2; - index_expr2.type()=ns.follow(array_equality.f2.type()).subtype(); - index_expr2.array()=array_equality.f2; - index_expr2.index()=*it; + const typet &subtype2=ns.follow(array_equality.f2.type()).subtype(); + index_exprt index_expr2(array_equality.f2, index, subtype2); assert(index_expr1.type()==index_expr2.type()); @@ -569,18 +422,6 @@ void arrayst::add_array_constraints( } } -/*******************************************************************\ - -Function: arrayst::add_array_constraints - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void arrayst::add_array_constraints( const index_sett &index_set, const exprt &expr) @@ -616,25 +457,16 @@ void arrayst::add_array_constraints( assert(expr.operands().size()==1); // add a[i]=b[i] - for(index_sett::const_iterator - it=index_set.begin(); - it!=index_set.end(); - it++) + for(const auto &index : index_set) { - index_exprt index_expr1; - index_expr1.type()=ns.follow(expr.type()).subtype(); - index_expr1.array()=expr; - index_expr1.index()=*it; - - index_exprt index_expr2; - index_expr2.type()=ns.follow(expr.type()).subtype(); - index_expr2.array()=expr.op0(); - index_expr2.index()=*it; + const typet &subtype=ns.follow(expr.type()).subtype(); + index_exprt index_expr1(expr, index, subtype); + index_exprt index_expr2(expr.op0(), index, subtype); assert(index_expr1.type()==index_expr2.type()); // add constraint - lazy_constraintt lazy(ARRAY_TYPECAST, + lazy_constraintt lazy(lazy_typet::ARRAY_TYPECAST, equal_exprt(index_expr1, index_expr2)); add_array_constraint(lazy, false); // added immediately } @@ -648,18 +480,6 @@ void arrayst::add_array_constraints( expr.id_string()+"'"; } -/*******************************************************************\ - -Function: arrayst::add_array_constraints_with - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void arrayst::add_array_constraints_with( const index_sett &index_set, const with_exprt &expr) @@ -671,31 +491,24 @@ void arrayst::add_array_constraints_with( const exprt &value=expr.new_value(); { - index_exprt index_expr; - index_expr.type()=ns.follow(expr.type()).subtype(); - index_expr.array()=expr; - index_expr.index()=index; + index_exprt index_expr(expr, index, ns.follow(expr.type()).subtype()); if(index_expr.type()!=value.type()) { - std::cout << expr.pretty() << std::endl; + std::cout << expr.pretty() << '\n'; assert(false); } - lazy_constraintt lazy(ARRAY_WITH, equal_exprt(index_expr, value)); + lazy_constraintt lazy( + lazy_typet::ARRAY_WITH, equal_exprt(index_expr, value)); add_array_constraint(lazy, false); // added immediately } // use other array index applications for "else" case // add constraint x[I]=y[I] for I!=i - for(index_sett::const_iterator - it=index_set.begin(); - it!=index_set.end(); - it++) + for(auto other_index : index_set) { - exprt other_index=*it; - if(other_index!=index) { // we first build the guard @@ -707,22 +520,14 @@ void arrayst::add_array_constraints_with( if(guard_lit!=const_literal(true)) { - index_exprt index_expr1; - index_expr1.type()=ns.follow(expr.type()).subtype(); - index_expr1.array()=expr; - index_expr1.index()=other_index; - - index_exprt index_expr2; - index_expr2.type()=ns.follow(expr.type()).subtype(); - index_expr2.array()=expr.op0(); - index_expr2.index()=other_index; - - assert(index_expr1.type()==index_expr2.type()); + const typet &subtype=ns.follow(expr.type()).subtype(); + index_exprt index_expr1(expr, other_index, subtype); + index_exprt index_expr2(expr.op0(), other_index, subtype); equal_exprt equality_expr(index_expr1, index_expr2); // add constraint - lazy_constraintt lazy(ARRAY_WITH, or_exprt(equality_expr, + lazy_constraintt lazy(lazy_typet::ARRAY_WITH, or_exprt(equality_expr, literal_exprt(guard_lit))); add_array_constraint(lazy, false); // added immediately @@ -742,18 +547,6 @@ void arrayst::add_array_constraints_with( } } -/*******************************************************************\ - -Function: arrayst::add_array_constraints_update - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void arrayst::add_array_constraints_update( const index_sett &index_set, const update_exprt &expr) @@ -766,14 +559,11 @@ void arrayst::add_array_constraints_update( const exprt &value=expr.new_value(); { - index_exprt index_expr; - index_expr.type()=ns.follow(expr.type()).subtype(); - index_expr.array()=expr; - index_expr.index()=index; + index_exprt index_expr(expr, index, ns.follow(expr.type()).subtype()); if(index_expr.type()!=value.type()) { - std::cout << expr.pretty() << std::endl; + std::cout << expr.pretty() << '\n'; assert(false); } @@ -783,13 +573,8 @@ void arrayst::add_array_constraints_update( // use other array index applications for "else" case // add constraint x[I]=y[I] for I!=i - for(index_sett::const_iterator - it=index_set.begin(); - it!=index_set.end(); - it++) + for(auto other_index : index_set) { - exprt other_index=*it; - if(other_index!=index) { // we first build the guard @@ -801,17 +586,9 @@ void arrayst::add_array_constraints_update( if(guard_lit!=const_literal(true)) { - index_exprt index_expr1; - index_expr1.type()=ns.follow(expr.type()).subtype(); - index_expr1.array()=expr; - index_expr1.index()=other_index; - - index_exprt index_expr2; - index_expr2.type()=ns.follow(expr.type()).subtype(); - index_expr2.array()=expr.op0(); - index_expr2.index()=other_index; - - assert(index_expr1.type()==index_expr2.type()); + const typet &subtype=ns.follow(expr.type()).subtype(); + index_exprt index_expr1(expr, other_index, subtype); + index_exprt index_expr2(expr.op0(), other_index, subtype); equal_exprt equality_expr(index_expr1, index_expr2); @@ -829,18 +606,6 @@ void arrayst::add_array_constraints_update( #endif } -/*******************************************************************\ - -Function: arrayst::add_array_constraints_array_of - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void arrayst::add_array_constraints_array_of( const index_sett &index_set, const array_of_exprt &expr) @@ -849,36 +614,20 @@ void arrayst::add_array_constraints_array_of( // get other array index applications // and add constraint x[i]=v - for(index_sett::const_iterator - it=index_set.begin(); - it!=index_set.end(); - it++) + for(const auto &index : index_set) { - index_exprt index_expr; - index_expr.type()=ns.follow(expr.type()).subtype(); - index_expr.array()=expr; - index_expr.index()=*it; + const typet &subtype=ns.follow(expr.type()).subtype(); + index_exprt index_expr(expr, index, subtype); assert(base_type_eq(index_expr.type(), expr.op0().type(), ns)); // add constraint - lazy_constraintt lazy(ARRAY_OF, equal_exprt(index_expr, expr.op0())); + lazy_constraintt lazy( + lazy_typet::ARRAY_OF, equal_exprt(index_expr, expr.op0())); add_array_constraint(lazy, false); // added immediately } } -/*******************************************************************\ - -Function: arrayst::add_array_constraints_if - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void arrayst::add_array_constraints_if( const index_sett &index_set, const if_exprt &expr) @@ -892,25 +641,14 @@ void arrayst::add_array_constraints_if( // first do true case - for(index_sett::const_iterator - it=index_set.begin(); - it!=index_set.end(); - it++) + for(const auto &index : index_set) { - index_exprt index_expr1; - index_expr1.type()=ns.follow(expr.type()).subtype(); - index_expr1.array()=expr; - index_expr1.index()=*it; - - index_exprt index_expr2; - index_expr2.type()=ns.follow(expr.type()).subtype(); - index_expr2.array()=expr.true_case(); - index_expr2.index()=*it; - - assert(index_expr1.type()==index_expr2.type()); + const typet subtype=ns.follow(expr.type()).subtype(); + index_exprt index_expr1(expr, index, subtype); + index_exprt index_expr2(expr.true_case(), index, subtype); // add implication - lazy_constraintt lazy(ARRAY_IF, + lazy_constraintt lazy(lazy_typet::ARRAY_IF, or_exprt(literal_exprt(!cond_lit), equal_exprt(index_expr1, index_expr2))); add_array_constraint(lazy, false); // added immediately @@ -921,26 +659,17 @@ void arrayst::add_array_constraints_if( } // now the false case - for(index_sett::const_iterator - it=index_set.begin(); - it!=index_set.end(); - it++) + for(const auto &index : index_set) { - index_exprt index_expr1; - index_expr1.type()=ns.follow(expr.type()).subtype(); - index_expr1.array()=expr; - index_expr1.index()=*it; - - index_exprt index_expr2; - index_expr2.type()=ns.follow(expr.type()).subtype(); - index_expr2.array()=expr.false_case(); - index_expr2.index()=*it; - - assert(index_expr1.type()==index_expr2.type()); + const typet subtype=ns.follow(expr.type()).subtype(); + index_exprt index_expr1(expr, index, subtype); + index_exprt index_expr2(expr.false_case(), index, subtype); // add implication - lazy_constraintt lazy(ARRAY_IF, or_exprt(literal_exprt(cond_lit), - equal_exprt(index_expr1, index_expr2))); + lazy_constraintt lazy( + lazy_typet::ARRAY_IF, + or_exprt(literal_exprt(cond_lit), + equal_exprt(index_expr1, index_expr2))); add_array_constraint(lazy, false); // added immediately #if 0 // old code for adding, not significantly faster diff --git a/src/solvers/flattening/arrays.h b/src/solvers/flattening/arrays.h index 51a0799187a..a5434c3e48f 100644 --- a/src/solvers/flattening/arrays.h +++ b/src/solvers/flattening/arrays.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Theory of Arrays with Extensionality + #ifndef CPROVER_SOLVERS_FLATTENING_ARRAYS_H #define CPROVER_SOLVERS_FLATTENING_ARRAYS_H @@ -68,14 +71,15 @@ class arrayst:public equalityt index_mapt index_map; // adds array constraints lazily - typedef enum lazy_type + enum class lazy_typet { ARRAY_ACKERMANN, ARRAY_WITH, ARRAY_IF, ARRAY_OF, ARRAY_TYPECAST - } lazy_typet; + }; + struct lazy_constraintt { lazy_typet type; @@ -101,8 +105,6 @@ class arrayst:public equalityt const index_sett &index_set, const array_equalityt &array_equality); void add_array_constraints( const index_sett &index_set, const exprt &expr); - void add_array_constraints( - const index_sett &index_set, const array_equalityt &array_equality); void add_array_constraints_if( const index_sett &index_set, const if_exprt &exprt); void add_array_constraints_with( diff --git a/src/solvers/flattening/boolbv.cpp b/src/solvers/flattening/boolbv.cpp index aaa63e69fd2..58b09b0d1bb 100644 --- a/src/solvers/flattening/boolbv.cpp +++ b/src/solvers/flattening/boolbv.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "boolbv.h" + #include #include #include @@ -22,23 +24,10 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "boolbv.h" #include "boolbv_type.h" #include "../floatbv/float_utils.h" -/*******************************************************************\ - -Function: boolbvt::literal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool boolbvt::literal( const exprt &expr, const std::size_t bit, @@ -123,18 +112,6 @@ bool boolbvt::literal( throw "found no literal for expression"; } -/*******************************************************************\ - -Function: boolbvt::convert_bv - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const bvt &boolbvt::convert_bv(const exprt &expr) { // check cache first @@ -165,18 +142,6 @@ const bvt &boolbvt::convert_bv(const exprt &expr) return cache_result.first->second; } -/*******************************************************************\ - -Function: boolbvt::conversion_failed - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt boolbvt::conversion_failed(const exprt &expr) { ignoring(expr); @@ -186,18 +151,6 @@ bvt boolbvt::conversion_failed(const exprt &expr) return prop.new_variables(width); } -/*******************************************************************\ - -Function: boolbvt::convert_bitvector - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt boolbvt::convert_bitvector(const exprt &expr) { if(expr.type().id()==ID_bool) @@ -354,18 +307,6 @@ bvt boolbvt::convert_bitvector(const exprt &expr) return conversion_failed(expr); } -/*******************************************************************\ - -Function: boolbvt::convert_lambda - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt boolbvt::convert_lambda(const exprt &expr) { std::size_t width=boolbv_width(expr.type()); @@ -413,18 +354,6 @@ bvt boolbvt::convert_lambda(const exprt &expr) return bv; } -/*******************************************************************\ - -Function: boolbvt::convert_bv_literals - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt boolbvt::convert_bv_literals(const exprt &expr) { std::size_t width=boolbv_width(expr.type()); @@ -446,18 +375,6 @@ bvt boolbvt::convert_bv_literals(const exprt &expr) return bv; } -/*******************************************************************\ - -Function: boolbvt::convert_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt boolbvt::convert_symbol(const exprt &expr) { const typet &type=expr.type(); @@ -493,18 +410,6 @@ bvt boolbvt::convert_symbol(const exprt &expr) } -/*******************************************************************\ - -Function: boolbvt::convert_function_application - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt boolbvt::convert_function_application( const function_application_exprt &expr) { @@ -516,18 +421,6 @@ bvt boolbvt::convert_function_application( } -/*******************************************************************\ - -Function: boolbvt::convert_rest - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt boolbvt::convert_rest(const exprt &expr) { if(expr.type().id()!=ID_bool) @@ -608,7 +501,7 @@ literalt boolbvt::convert_rest(const exprt &expr) const bvt &bv=convert_bv(operands[0]); - if(bv.size()<1) + if(bv.empty()) throw "sign operator takes one non-empty operand"; if(operands[0].type().id()==ID_signedbv) @@ -694,18 +587,6 @@ literalt boolbvt::convert_rest(const exprt &expr) return SUB::convert_rest(expr); } -/*******************************************************************\ - -Function: boolbvt::boolbv_set_equality_to_true - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool boolbvt::boolbv_set_equality_to_true(const equal_exprt &expr) { if(!equality_propagation) @@ -737,18 +618,6 @@ bool boolbvt::boolbv_set_equality_to_true(const equal_exprt &expr) return true; } -/*******************************************************************\ - -Function: boolbvt::set_to - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void boolbvt::set_to(const exprt &expr, bool value) { if(expr.type().id()!=ID_bool) @@ -770,18 +639,6 @@ void boolbvt::set_to(const exprt &expr, bool value) return SUB::set_to(expr, value); } -/*******************************************************************\ - -Function: boolbvt::make_bv_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void boolbvt::make_bv_expr(const typet &type, const bvt &bv, exprt &dest) { dest=exprt(ID_bv_literals, type); @@ -793,18 +650,6 @@ void boolbvt::make_bv_expr(const typet &type, const bvt &bv, exprt &dest) bv_sub[i].id(std::to_string(bv[i].get())); } -/*******************************************************************\ - -Function: boolbvt::make_bv_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void boolbvt::make_free_bv_expr(const typet &type, exprt &dest) { std::size_t width=boolbv_width(type); @@ -825,18 +670,6 @@ void boolbvt::make_free_bv_expr(const typet &type, exprt &dest) make_bv_expr(type, bv, dest); } -/*******************************************************************\ - -Function: boolbvt::is_unbounded_array - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool boolbvt::is_unbounded_array(const typet &type) const { if(type.id()==ID_symbol) @@ -845,7 +678,7 @@ bool boolbvt::is_unbounded_array(const typet &type) const if(type.id()!=ID_array) return false; - if(unbounded_array==U_ALL) + if(unbounded_array==unbounded_arrayt::U_ALL) return true; const exprt &size=to_array_type(type).size(); @@ -854,25 +687,13 @@ bool boolbvt::is_unbounded_array(const typet &type) const if(to_integer(size, s)) return true; - if(unbounded_array==U_AUTO) + if(unbounded_array==unbounded_arrayt::U_AUTO) if(s>1000) // magic number! return true; return false; } -/*******************************************************************\ - -Function: boolbvt::print_assignment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void boolbvt::print_assignment(std::ostream &out) const { for(boolbv_mapt::mappingt::const_iterator it=map.mapping.begin(); @@ -884,18 +705,6 @@ void boolbvt::print_assignment(std::ostream &out) const } } -/*******************************************************************\ - -Function: boolbvt::build_offset_map - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void boolbvt::build_offset_map(const struct_typet &src, offset_mapt &dest) { const struct_typet::componentst &components= diff --git a/src/solvers/flattening/boolbv.h b/src/solvers/flattening/boolbv.h index a092be8c3af..f015e96097b 100644 --- a/src/solvers/flattening/boolbv.h +++ b/src/solvers/flattening/boolbv.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_FLATTENING_BOOLBV_H #define CPROVER_SOLVERS_FLATTENING_BOOLBV_H @@ -34,7 +35,7 @@ class boolbvt:public arrayst const namespacet &_ns, propt &_prop): arrayst(_ns, _prop), - unbounded_array(U_NONE), + unbounded_array(unbounded_arrayt::U_NONE), boolbv_width(_ns), bv_utils(_prop), functions(*this), @@ -71,7 +72,7 @@ class boolbvt:public arrayst using arrayst::literal; - typedef enum { U_NONE, U_ALL, U_AUTO } unbounded_arrayt; + enum class unbounded_arrayt { U_NONE, U_ALL, U_AUTO }; unbounded_arrayt unbounded_array; mp_integer get_value(const bvt &bv) diff --git a/src/solvers/flattening/boolbv_abs.cpp b/src/solvers/flattening/boolbv_abs.cpp index 0a9f7a9c4a5..7f10b724ed1 100644 --- a/src/solvers/flattening/boolbv_abs.cpp +++ b/src/solvers/flattening/boolbv_abs.cpp @@ -6,25 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "boolbv.h" + #include -#include "boolbv.h" #include "boolbv_type.h" #include "../floatbv/float_utils.h" -/*******************************************************************\ - -Function: boolbvt::convert_abs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt boolbvt::convert_abs(const exprt &expr) { std::size_t width=boolbv_width(expr.type()); @@ -46,13 +35,13 @@ bvt boolbvt::convert_abs(const exprt &expr) bvtypet bvtype=get_bvtype(expr.type()); - if(bvtype==IS_FIXED || - bvtype==IS_SIGNED || - bvtype==IS_UNSIGNED) + if(bvtype==bvtypet::IS_FIXED || + bvtype==bvtypet::IS_SIGNED || + bvtype==bvtypet::IS_UNSIGNED) { return bv_utils.absolute_value(op_bv); } - else if(bvtype==IS_FLOAT) + else if(bvtype==bvtypet::IS_FLOAT) { float_utilst float_utils(prop, to_floatbv_type(expr.type())); return float_utils.abs(op_bv); diff --git a/src/solvers/flattening/boolbv_add_sub.cpp b/src/solvers/flattening/boolbv_add_sub.cpp index 38a7effc5af..0486874d6d2 100644 --- a/src/solvers/flattening/boolbv_add_sub.cpp +++ b/src/solvers/flattening/boolbv_add_sub.cpp @@ -6,26 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "boolbv.h" + #include #include -#include "boolbv.h" - #include "../floatbv/float_utils.h" -/*******************************************************************\ - -Function: boolbvt::convert_add_sub - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt boolbvt::convert_add_sub(const exprt &expr) { const typet &type=ns.follow(expr.type()); @@ -53,7 +41,7 @@ bvt boolbvt::convert_add_sub(const exprt &expr) if(op0.type()!=type) { - std::cerr << expr.pretty() << std::endl; + std::cerr << expr.pretty() << '\n'; throw "add/sub with mixed types"; } @@ -74,8 +62,8 @@ bvt boolbvt::convert_add_sub(const exprt &expr) bv_utilst::representationt rep= (arithmetic_type.id()==ID_signedbv || - arithmetic_type.id()==ID_fixedbv)?bv_utilst::SIGNED: - bv_utilst::UNSIGNED; + arithmetic_type.id()==ID_fixedbv)?bv_utilst::representationt::SIGNED: + bv_utilst::representationt::UNSIGNED; for(exprt::operandst::const_iterator it=operands.begin()+1; @@ -83,7 +71,7 @@ bvt boolbvt::convert_add_sub(const exprt &expr) { if(it->type()!=type) { - std::cerr << expr.pretty() << std::endl; + std::cerr << expr.pretty() << '\n'; throw "add/sub with mixed types"; } diff --git a/src/solvers/flattening/boolbv_array.cpp b/src/solvers/flattening/boolbv_array.cpp index e6a44279684..b96639a6d40 100644 --- a/src/solvers/flattening/boolbv_array.cpp +++ b/src/solvers/flattening/boolbv_array.cpp @@ -6,19 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "boolbv.h" - -/*******************************************************************\ - -Function: boolbvt::convert_array - - Inputs: - Outputs: - - Purpose: - -\*******************************************************************/ +#include "boolbv.h" bvt boolbvt::convert_array(const exprt &expr) { diff --git a/src/solvers/flattening/boolbv_array_of.cpp b/src/solvers/flattening/boolbv_array_of.cpp index 74056d2df50..2c01f095638 100644 --- a/src/solvers/flattening/boolbv_array_of.cpp +++ b/src/solvers/flattening/boolbv_array_of.cpp @@ -6,22 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include -#include - #include "boolbv.h" -/*******************************************************************\ - -Function: boolbvt::convert_array_of - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include bvt boolbvt::convert_array_of(const array_of_exprt &expr) { @@ -36,7 +24,14 @@ bvt boolbvt::convert_array_of(const array_of_exprt &expr) std::size_t width=boolbv_width(array_type); if(width==0) - return conversion_failed(expr); + { + // A zero-length array is acceptable; + // an element with unknown size is not. + if(boolbv_width(array_type.subtype())==0) + return conversion_failed(expr); + else + return bvt(); + } const exprt &array_size=array_type.size(); diff --git a/src/solvers/flattening/boolbv_bitwise.cpp b/src/solvers/flattening/boolbv_bitwise.cpp index 52d48b19c77..9eda6eafcd9 100644 --- a/src/solvers/flattening/boolbv_bitwise.cpp +++ b/src/solvers/flattening/boolbv_bitwise.cpp @@ -6,19 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "boolbv.h" - -/*******************************************************************\ - -Function: boolbvt::convert_bitwise - - Inputs: - Outputs: - - Purpose: - -\*******************************************************************/ +#include "boolbv.h" bvt boolbvt::convert_bitwise(const exprt &expr) { diff --git a/src/solvers/flattening/boolbv_bv_rel.cpp b/src/solvers/flattening/boolbv_bv_rel.cpp index 901cd31fa04..37f3dbadd3c 100644 --- a/src/solvers/flattening/boolbv_bv_rel.cpp +++ b/src/solvers/flattening/boolbv_bv_rel.cpp @@ -6,25 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "boolbv.h" + #include -#include "boolbv.h" #include "boolbv_type.h" #include "../floatbv/float_utils.h" -/*******************************************************************\ - -Function: boolbvt::convert_bv_rel - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt boolbvt::convert_bv_rel(const exprt &expr) { const exprt::operandst &operands=expr.operands(); @@ -44,32 +33,33 @@ literalt boolbvt::convert_bv_rel(const exprt &expr) if(bv0.size()==bv1.size() && !bv0.empty() && bvtype0==bvtype1) { - if(bvtype0==IS_FLOAT) + if(bvtype0==bvtypet::IS_FLOAT) { float_utilst float_utils(prop, to_floatbv_type(op0.type())); if(rel==ID_le) - return float_utils.relation(bv0, float_utilst::LE, bv1); + return float_utils.relation(bv0, float_utilst::relt::LE, bv1); else if(rel==ID_lt) - return float_utils.relation(bv0, float_utilst::LT, bv1); + return float_utils.relation(bv0, float_utilst::relt::LT, bv1); else if(rel==ID_ge) - return float_utils.relation(bv0, float_utilst::GE, bv1); + return float_utils.relation(bv0, float_utilst::relt::GE, bv1); else if(rel==ID_gt) - return float_utils.relation(bv0, float_utilst::GT, bv1); + return float_utils.relation(bv0, float_utilst::relt::GT, bv1); else return SUB::convert_rest(expr); } else if((op0.type().id()==ID_range && op1.type()==op0.type()) || - bvtype0==IS_SIGNED || - bvtype0==IS_UNSIGNED || - bvtype0==IS_FIXED) + bvtype0==bvtypet::IS_SIGNED || + bvtype0==bvtypet::IS_UNSIGNED || + bvtype0==bvtypet::IS_FIXED) { literalt literal; bv_utilst::representationt rep= - ((bvtype0==IS_SIGNED) || (bvtype0==IS_FIXED))?bv_utilst::SIGNED: - bv_utilst::UNSIGNED; + ((bvtype0==bvtypet::IS_SIGNED) || (bvtype0==bvtypet::IS_FIXED))? + bv_utilst::representationt::SIGNED: + bv_utilst::representationt::UNSIGNED; #if 1 @@ -95,8 +85,8 @@ literalt boolbvt::convert_bv_rel(const exprt &expr) return literal; #endif } - else if((bvtype0==IS_VERILOG_SIGNED || - bvtype0==IS_VERILOG_UNSIGNED) && + else if((bvtype0==bvtypet::IS_VERILOG_SIGNED || + bvtype0==bvtypet::IS_VERILOG_UNSIGNED) && op0.type()==op1.type()) { // extract number bits @@ -111,7 +101,7 @@ literalt boolbvt::convert_bv_rel(const exprt &expr) for(std::size_t i=0; i #include @@ -13,21 +15,8 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "boolbv.h" #include "flatten_byte_operators.h" -/*******************************************************************\ - -Function: map_bv - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt map_bv(const endianness_mapt &map, const bvt &src) { assert(map.number_of_bits()==src.size()); @@ -45,18 +34,6 @@ bvt map_bv(const endianness_mapt &map, const bvt &src) return result; } -/*******************************************************************\ - -Function: boolbvt::convert_byte_extract - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt boolbvt::convert_byte_extract(const byte_extract_exprt &expr) { if(expr.operands().size()!=2) diff --git a/src/solvers/flattening/boolbv_byte_update.cpp b/src/solvers/flattening/boolbv_byte_update.cpp index 7ff0408a661..5446a0498cf 100644 --- a/src/solvers/flattening/boolbv_byte_update.cpp +++ b/src/solvers/flattening/boolbv_byte_update.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "boolbv.h" + #include #include @@ -13,20 +15,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "boolbv.h" - -/*******************************************************************\ - -Function: boolbvt::convert_byte_update - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt boolbvt::convert_byte_update(const byte_update_exprt &expr) { if(expr.operands().size()!=3) diff --git a/src/solvers/flattening/boolbv_case.cpp b/src/solvers/flattening/boolbv_case.cpp index 6a56f35fa7f..6434f216178 100644 --- a/src/solvers/flattening/boolbv_case.cpp +++ b/src/solvers/flattening/boolbv_case.cpp @@ -6,21 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "boolbv.h" -/*******************************************************************\ - -Function: boolbvt::convert_case - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include bvt boolbvt::convert_case(const exprt &expr) { @@ -64,10 +52,9 @@ bvt boolbvt::convert_case(const exprt &expr) if(compare_bv.size()!=op.size()) { std::cerr << "compare operand: " << compare_bv.size() - << std::endl - << "operand: " << op.size() << std::endl + << "\noperand: " << op.size() << '\n' << it->pretty() - << std::endl; + << '\n'; throw "size of compare operand does not match"; } @@ -84,10 +71,9 @@ bvt boolbvt::convert_case(const exprt &expr) if(bv.size()!=op.size()) { std::cerr << "result size: " << bv.size() - << std::endl - << "operand: " << op.size() << std::endl + << "\noperand: " << op.size() << '\n' << it->pretty() - << std::endl; + << '\n'; throw "size of value operand does not match"; } diff --git a/src/solvers/flattening/boolbv_complex.cpp b/src/solvers/flattening/boolbv_complex.cpp index 3d5407537a2..833795be842 100644 --- a/src/solvers/flattening/boolbv_complex.cpp +++ b/src/solvers/flattening/boolbv_complex.cpp @@ -6,19 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "boolbv.h" - -/*******************************************************************\ - -Function: boolbvt::convert_complex - - Inputs: - - Outputs: - - Purpose: -\*******************************************************************/ +#include "boolbv.h" bvt boolbvt::convert_complex(const exprt &expr) { @@ -56,18 +45,6 @@ bvt boolbvt::convert_complex(const exprt &expr) return conversion_failed(expr); } -/*******************************************************************\ - -Function: boolbvt::convert_complex_real - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt boolbvt::convert_complex_real(const exprt &expr) { std::size_t width=boolbv_width(expr.type()); @@ -86,18 +63,6 @@ bvt boolbvt::convert_complex_real(const exprt &expr) return bv; } -/*******************************************************************\ - -Function: boolbvt::convert_complex_imag - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt boolbvt::convert_complex_imag(const exprt &expr) { std::size_t width=boolbv_width(expr.type()); diff --git a/src/solvers/flattening/boolbv_concatenation.cpp b/src/solvers/flattening/boolbv_concatenation.cpp index ef3896053fe..73a2a1b922b 100644 --- a/src/solvers/flattening/boolbv_concatenation.cpp +++ b/src/solvers/flattening/boolbv_concatenation.cpp @@ -6,19 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "boolbv.h" - -/*******************************************************************\ - -Function: boolbvt::convert_concatenation - - Inputs: - Outputs: - - Purpose: - -\*******************************************************************/ +#include "boolbv.h" bvt boolbvt::convert_concatenation(const exprt &expr) { diff --git a/src/solvers/flattening/boolbv_cond.cpp b/src/solvers/flattening/boolbv_cond.cpp index 4e966a69440..514c1e817f3 100644 --- a/src/solvers/flattening/boolbv_cond.cpp +++ b/src/solvers/flattening/boolbv_cond.cpp @@ -6,21 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "boolbv.h" -/*******************************************************************\ - -Function: boolbvt::convert_cond - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include bvt boolbvt::convert_cond(const exprt &expr) { @@ -66,10 +54,9 @@ bvt boolbvt::convert_cond(const exprt &expr) if(bv.size()!=op.size()) { std::cerr << "result size: " << bv.size() - << std::endl - << "operand: " << op.size() << std::endl + << "\noperand: " << op.size() << '\n' << it->pretty() - << std::endl; + << '\n'; throw "size of value operand does not match"; } diff --git a/src/solvers/flattening/boolbv_constant.cpp b/src/solvers/flattening/boolbv_constant.cpp index ebeb3a5a1db..612cee9d63c 100644 --- a/src/solvers/flattening/boolbv_constant.cpp +++ b/src/solvers/flattening/boolbv_constant.cpp @@ -6,19 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "boolbv.h" - -/*******************************************************************\ - -Function: boolbvt::convert_constant - - Inputs: - Outputs: - - Purpose: - -\*******************************************************************/ +#include "boolbv.h" bvt boolbvt::convert_constant(const constant_exprt &expr) { diff --git a/src/solvers/flattening/boolbv_constraint_select_one.cpp b/src/solvers/flattening/boolbv_constraint_select_one.cpp index c6c9b53bd50..64ba997d395 100644 --- a/src/solvers/flattening/boolbv_constraint_select_one.cpp +++ b/src/solvers/flattening/boolbv_constraint_select_one.cpp @@ -6,19 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "boolbv.h" - -/*******************************************************************\ - -Function: boolbvt::convert_constraint_select_one - - Inputs: - Outputs: - - Purpose: - -\*******************************************************************/ +#include "boolbv.h" bvt boolbvt::convert_constraint_select_one(const exprt &expr) { diff --git a/src/solvers/flattening/boolbv_div.cpp b/src/solvers/flattening/boolbv_div.cpp index 367cf727704..d8c0581fce5 100644 --- a/src/solvers/flattening/boolbv_div.cpp +++ b/src/solvers/flattening/boolbv_div.cpp @@ -6,21 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "boolbv.h" -/*******************************************************************\ - -Function: boolbvt::convert_div - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include bvt boolbvt::convert_div(const div_exprt &expr) { @@ -59,7 +47,7 @@ bvt boolbvt::convert_div(const div_exprt &expr) op0.insert(op0.begin(), zeros.begin(), zeros.end()); op1=bv_utils.sign_extension(op1, op1.size()+fraction_bits); - bv_utils.divider(op0, op1, res, rem, bv_utilst::SIGNED); + bv_utils.divider(op0, op1, res, rem, bv_utilst::representationt::SIGNED); // cut it down again res.resize(width); @@ -67,8 +55,8 @@ bvt boolbvt::convert_div(const div_exprt &expr) else { bv_utilst::representationt rep= - expr.type().id()==ID_signedbv?bv_utilst::SIGNED: - bv_utilst::UNSIGNED; + expr.type().id()==ID_signedbv?bv_utilst::representationt::SIGNED: + bv_utilst::representationt::UNSIGNED; bv_utils.divider(op0, op1, res, rem, rep); } diff --git a/src/solvers/flattening/boolbv_equality.cpp b/src/solvers/flattening/boolbv_equality.cpp index 53cbb624815..95a379a5a95 100644 --- a/src/solvers/flattening/boolbv_equality.cpp +++ b/src/solvers/flattening/boolbv_equality.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "boolbv.h" + #include #include @@ -14,26 +16,13 @@ Author: Daniel Kroening, kroening@kroening.com #include #include "flatten_byte_operators.h" -#include "boolbv.h" - -/*******************************************************************\ - -Function: boolbvt::convert_equality - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ literalt boolbvt::convert_equality(const equal_exprt &expr) { if(!base_type_eq(expr.lhs().type(), expr.rhs().type(), ns)) { - std::cout << "######### lhs: " << expr.lhs().pretty() << std::endl; - std::cout << "######### rhs: " << expr.rhs().pretty() << std::endl; + std::cout << "######### lhs: " << expr.lhs().pretty() << '\n'; + std::cout << "######### rhs: " << expr.rhs().pretty() << '\n'; throw "equality without matching types"; } @@ -56,10 +45,10 @@ literalt boolbvt::convert_equality(const equal_exprt &expr) if(bv0.size()!=bv1.size()) { - std::cerr << "lhs: " << expr.lhs().pretty() << std::endl; - std::cerr << "lhs size: " << bv0.size() << std::endl; - std::cerr << "rhs: " << expr.rhs().pretty() << std::endl; - std::cerr << "rhs size: " << bv1.size() << std::endl; + std::cerr << "lhs: " << expr.lhs().pretty() << '\n'; + std::cerr << "lhs size: " << bv0.size() << '\n'; + std::cerr << "rhs: " << expr.rhs().pretty() << '\n'; + std::cerr << "rhs size: " << bv1.size() << '\n'; throw "unexpected size mismatch on equality"; } @@ -73,18 +62,6 @@ literalt boolbvt::convert_equality(const equal_exprt &expr) return bv_utils.equal(bv0, bv1); } -/*******************************************************************\ - -Function: boolbvt::convert_verilog_case_equality - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt boolbvt::convert_verilog_case_equality( const binary_relation_exprt &expr) { @@ -93,8 +70,8 @@ literalt boolbvt::convert_verilog_case_equality( if(!base_type_eq(expr.lhs().type(), expr.rhs().type(), ns)) { - std::cout << "######### lhs: " << expr.lhs().pretty() << std::endl; - std::cout << "######### rhs: " << expr.rhs().pretty() << std::endl; + std::cout << "######### lhs: " << expr.lhs().pretty() << '\n'; + std::cout << "######### rhs: " << expr.rhs().pretty() << '\n'; throw "verilog_case_equality without matching types"; } @@ -103,10 +80,10 @@ literalt boolbvt::convert_verilog_case_equality( if(bv0.size()!=bv1.size()) { - std::cerr << "lhs: " << expr.lhs().pretty() << std::endl; - std::cerr << "lhs size: " << bv0.size() << std::endl; - std::cerr << "rhs: " << expr.rhs().pretty() << std::endl; - std::cerr << "rhs size: " << bv1.size() << std::endl; + std::cerr << "lhs: " << expr.lhs().pretty() << '\n'; + std::cerr << "lhs size: " << bv0.size() << '\n'; + std::cerr << "rhs: " << expr.rhs().pretty() << '\n'; + std::cerr << "rhs size: " << bv1.size() << '\n'; throw "unexpected size mismatch on verilog_case_equality"; } diff --git a/src/solvers/flattening/boolbv_extractbit.cpp b/src/solvers/flattening/boolbv_extractbit.cpp index cdccc52f578..f24b8a1394a 100644 --- a/src/solvers/flattening/boolbv_extractbit.cpp +++ b/src/solvers/flattening/boolbv_extractbit.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "boolbv.h" + #include #include @@ -13,20 +15,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "boolbv.h" - -/*******************************************************************\ - -Function: boolbvt::convert_extractbit - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt boolbvt::convert_extractbit(const extractbit_exprt &expr) { const exprt::operandst &operands=expr.operands(); diff --git a/src/solvers/flattening/boolbv_extractbits.cpp b/src/solvers/flattening/boolbv_extractbits.cpp index 5bf2ac0f4c4..4f549139feb 100644 --- a/src/solvers/flattening/boolbv_extractbits.cpp +++ b/src/solvers/flattening/boolbv_extractbits.cpp @@ -6,21 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "boolbv.h" -/*******************************************************************\ - -Function: boolbvt::convert_extractbits - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include bvt boolbvt::convert_extractbits(const extractbits_exprt &expr) { @@ -29,15 +17,6 @@ bvt boolbvt::convert_extractbits(const extractbits_exprt &expr) if(width==0) return conversion_failed(expr); - const irep_idt &type_id=expr.type().id(); - - if(type_id!=ID_signedbv && - type_id!=ID_unsignedbv && - type_id!=ID_c_enum && - type_id!=ID_c_enum_tag && - type_id!=ID_bv) - return conversion_failed(expr); - if(expr.operands().size()!=3) { error().source_location=expr.find_source_location(); diff --git a/src/solvers/flattening/boolbv_floatbv_op.cpp b/src/solvers/flattening/boolbv_floatbv_op.cpp index e4926dc617e..d6609691df2 100644 --- a/src/solvers/flattening/boolbv_floatbv_op.cpp +++ b/src/solvers/flattening/boolbv_floatbv_op.cpp @@ -6,27 +6,15 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "boolbv.h" + #include #include #include -#include "boolbv.h" - #include "../floatbv/float_utils.h" -/*******************************************************************\ - -Function: boolbvt::convert_floatbv_typecast - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt boolbvt::convert_floatbv_typecast(const floatbv_typecast_exprt &expr) { const exprt &op0=expr.op(); // number to convert @@ -84,18 +72,6 @@ bvt boolbvt::convert_floatbv_typecast(const floatbv_typecast_exprt &expr) return conversion_failed(expr); } -/*******************************************************************\ - -Function: boolbvt::convert_floatbv_op - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt boolbvt::convert_floatbv_op(const exprt &expr) { const exprt::operandst &operands=expr.operands(); @@ -115,7 +91,7 @@ bvt boolbvt::convert_floatbv_op(const exprt &expr) if(op0.type()!=type || op1.type()!=type) { - std::cerr << expr.pretty() << std::endl; + std::cerr << expr.pretty() << '\n'; throw "float op with mixed types"; } diff --git a/src/solvers/flattening/boolbv_get.cpp b/src/solvers/flattening/boolbv_get.cpp index 943ef98b19c..a0f86997e12 100644 --- a/src/solvers/flattening/boolbv_get.cpp +++ b/src/solvers/flattening/boolbv_get.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "boolbv.h" + #include #include @@ -14,21 +16,8 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "boolbv.h" #include "boolbv_type.h" -/*******************************************************************\ - -Function: boolbvt::get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt boolbvt::get(const exprt &expr) const { if(expr.id()==ID_symbol || @@ -76,18 +65,6 @@ exprt boolbvt::get(const exprt &expr) const return SUB::get(expr); } -/*******************************************************************\ - -Function: boolbvt::bv_get_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt boolbvt::bv_get_rec( const bvt &bv, const std::vector &unknown, @@ -119,7 +96,7 @@ exprt boolbvt::bv_get_rec( bvtypet bvtype=get_bvtype(type); - if(bvtype==IS_UNKNOWN) + if(bvtype==bvtypet::IS_UNKNOWN) { if(type.id()==ID_array) { @@ -265,7 +242,7 @@ exprt boolbvt::bv_get_rec( switch(bvtype) { - case IS_UNKNOWN: + case bvtypet::IS_UNKNOWN: if(type.id()==ID_string) { mp_integer int_value=binary2integer(value, false); @@ -279,7 +256,7 @@ exprt boolbvt::bv_get_rec( } break; - case IS_RANGE: + case bvtypet::IS_RANGE: { mp_integer int_value=binary2integer(value, false); mp_integer from=string2integer(type.get_string(ID_from)); @@ -291,7 +268,7 @@ exprt boolbvt::bv_get_rec( break; default: - case IS_C_ENUM: + case bvtypet::IS_C_ENUM: constant_exprt value_expr(type); value_expr.set_value(value); return value_expr; @@ -300,18 +277,6 @@ exprt boolbvt::bv_get_rec( return nil_exprt(); } -/*******************************************************************\ - -Function: boolbvt::bv_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt boolbvt::bv_get(const bvt &bv, const typet &type) const { std::vector unknown; @@ -319,18 +284,6 @@ exprt boolbvt::bv_get(const bvt &bv, const typet &type) const return bv_get_rec(bv, unknown, 0, type); } -/*******************************************************************\ - -Function: boolbvt::bv_get_cache - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt boolbvt::bv_get_cache(const exprt &expr) const { if(expr.type().id()==ID_bool) // boolean? @@ -344,18 +297,6 @@ exprt boolbvt::bv_get_cache(const exprt &expr) const return bv_get(it->second, expr.type()); } -/*******************************************************************\ - -Function: boolbvt::bv_get_unbounded_array - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt boolbvt::bv_get_unbounded_array(const exprt &expr) const { // first, try to get size @@ -473,18 +414,6 @@ exprt boolbvt::bv_get_unbounded_array(const exprt &expr) const return result; } -/*******************************************************************\ - -Function: boolbvt::get_value - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - mp_integer boolbvt::get_value( const bvt &bv, std::size_t offset, diff --git a/src/solvers/flattening/boolbv_ieee_float_rel.cpp b/src/solvers/flattening/boolbv_ieee_float_rel.cpp index bbdea7aea13..c7297d26792 100644 --- a/src/solvers/flattening/boolbv_ieee_float_rel.cpp +++ b/src/solvers/flattening/boolbv_ieee_float_rel.cpp @@ -6,25 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "boolbv.h" + #include -#include "boolbv.h" #include "boolbv_type.h" #include "../floatbv/float_utils.h" -/*******************************************************************\ - -Function: boolbvt::convert_ieee_float_rel - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt boolbvt::convert_ieee_float_rel(const exprt &expr) { const exprt::operandst &operands=expr.operands(); @@ -42,14 +31,14 @@ literalt boolbvt::convert_ieee_float_rel(const exprt &expr) const bvt &bv1=convert_bv(op1); if(bv0.size()==bv1.size() && !bv0.empty() && - bvtype0==IS_FLOAT && bvtype1==IS_FLOAT) + bvtype0==bvtypet::IS_FLOAT && bvtype1==bvtypet::IS_FLOAT) { float_utilst float_utils(prop, to_floatbv_type(op0.type())); if(rel==ID_ieee_float_equal) - return float_utils.relation(bv0, float_utilst::EQ, bv1); + return float_utils.relation(bv0, float_utilst::relt::EQ, bv1); else if(rel==ID_ieee_float_notequal) - return !float_utils.relation(bv0, float_utilst::EQ, bv1); + return !float_utils.relation(bv0, float_utilst::relt::EQ, bv1); else return SUB::convert_rest(expr); } diff --git a/src/solvers/flattening/boolbv_if.cpp b/src/solvers/flattening/boolbv_if.cpp index 97563633c5b..a569036ff36 100644 --- a/src/solvers/flattening/boolbv_if.cpp +++ b/src/solvers/flattening/boolbv_if.cpp @@ -6,19 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "boolbv.h" - -/*******************************************************************\ - -Function: boolbvt::convert_if - - Inputs: - Outputs: - - Purpose: - -\*******************************************************************/ +#include "boolbv.h" bvt boolbvt::convert_if(const if_exprt &expr) { diff --git a/src/solvers/flattening/boolbv_index.cpp b/src/solvers/flattening/boolbv_index.cpp index ec1ef27dd98..ff63fedf14e 100644 --- a/src/solvers/flattening/boolbv_index.cpp +++ b/src/solvers/flattening/boolbv_index.cpp @@ -6,26 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "boolbv.h" + #include #include #include #include -#include "boolbv.h" - -/*******************************************************************\ - -Function: boolbvt::convert_index - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt boolbvt::convert_index(const index_exprt &expr) { if(expr.id()!=ID_index) @@ -301,18 +289,7 @@ bvt boolbvt::convert_index(const index_exprt &expr) return bv; } -/*******************************************************************\ - -Function: boolbvt::convert_index - - Inputs: - - Outputs: - - Purpose: index operator with constant index - -\*******************************************************************/ - +/// index operator with constant index bvt boolbvt::convert_index( const exprt &array, const mp_integer &index) diff --git a/src/solvers/flattening/boolbv_map.cpp b/src/solvers/flattening/boolbv_map.cpp index 6c6e647a31c..7e5c069cd64 100644 --- a/src/solvers/flattening/boolbv_map.cpp +++ b/src/solvers/flattening/boolbv_map.cpp @@ -6,29 +6,18 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "boolbv_map.h" + #include #include "../prop/prop.h" -#include "boolbv_map.h" #include "boolbv_width.h" #ifdef DEBUG #include #endif -/*******************************************************************\ - -Function: boolbv_mapt::map_entryt::get_value - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string boolbv_mapt::map_entryt::get_value(const propt &prop) const { std::string result; @@ -57,18 +46,6 @@ std::string boolbv_mapt::map_entryt::get_value(const propt &prop) const return result; } -/*******************************************************************\ - -Function: boolbv_mapt::get_map_entry - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - boolbv_mapt::map_entryt &boolbv_mapt::get_map_entry( const irep_idt &identifier, const typet &type) @@ -95,18 +72,6 @@ boolbv_mapt::map_entryt &boolbv_mapt::get_map_entry( return map_entry; } -/*******************************************************************\ - -Function: boolbv_mapt::show - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void boolbv_mapt::show() const { for(mappingt::const_iterator it=mapping.begin(); @@ -116,18 +81,6 @@ void boolbv_mapt::show() const } } -/*******************************************************************\ - -Function: boolbv_mapt::get_literals - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void boolbv_mapt::get_literals( const irep_idt &identifier, const typet &type, @@ -160,23 +113,11 @@ void boolbv_mapt::get_literals( #ifdef DEBUG std::cout << "NEW: " << identifier << ":" << bit - << "=" << l << std::endl; + << "=" << l << '\n'; #endif } } -/*******************************************************************\ - -Function: boolbv_mapt::set_literals - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void boolbv_mapt::set_literals( const irep_idt &identifier, const typet &type, diff --git a/src/solvers/flattening/boolbv_map.h b/src/solvers/flattening/boolbv_map.h index 1f2b7458f93..7059da0ae78 100644 --- a/src/solvers/flattening/boolbv_map.h +++ b/src/solvers/flattening/boolbv_map.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_FLATTENING_BOOLBV_MAP_H #define CPROVER_SOLVERS_FLATTENING_BOOLBV_MAP_H @@ -42,7 +43,7 @@ class boolbv_mapt class map_entryt { public: - map_entryt():width(0), bvtype(IS_UNKNOWN) + map_entryt():width(0), bvtype(bvtypet::IS_UNKNOWN) { } diff --git a/src/solvers/flattening/boolbv_member.cpp b/src/solvers/flattening/boolbv_member.cpp index c5c0a697e1e..0f01e2be959 100644 --- a/src/solvers/flattening/boolbv_member.cpp +++ b/src/solvers/flattening/boolbv_member.cpp @@ -6,23 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "boolbv.h" + #include #include #include - -#include "boolbv.h" - -/*******************************************************************\ - -Function: boolbvt::convert_member - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include bvt boolbvt::convert_member(const member_exprt &expr) { @@ -36,7 +25,7 @@ bvt boolbvt::convert_member(const member_exprt &expr) return convert_bv( byte_extract_exprt(byte_extract_id(), struct_op, - from_integer(0, integer_typet()), + from_integer(0, index_type()), expr.type())); } else if(struct_op_type.id()==ID_struct) diff --git a/src/solvers/flattening/boolbv_mod.cpp b/src/solvers/flattening/boolbv_mod.cpp index 5ba8f5da37e..1692fbc6a2f 100644 --- a/src/solvers/flattening/boolbv_mod.cpp +++ b/src/solvers/flattening/boolbv_mod.cpp @@ -6,19 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "boolbv.h" - -/*******************************************************************\ - -Function: boolbvt::convert_mod - - Inputs: - Outputs: - - Purpose: - -\*******************************************************************/ +#include "boolbv.h" bvt boolbvt::convert_mod(const mod_exprt &expr) { @@ -43,8 +32,8 @@ bvt boolbvt::convert_mod(const mod_exprt &expr) throw "mod got mixed-type operands"; bv_utilst::representationt rep= - expr.type().id()==ID_signedbv?bv_utilst::SIGNED: - bv_utilst::UNSIGNED; + expr.type().id()==ID_signedbv?bv_utilst::representationt::SIGNED: + bv_utilst::representationt::UNSIGNED; const bvt &op0=convert_bv(expr.op0()); const bvt &op1=convert_bv(expr.op1()); diff --git a/src/solvers/flattening/boolbv_mult.cpp b/src/solvers/flattening/boolbv_mult.cpp index 52ead55629d..15803b7ead5 100644 --- a/src/solvers/flattening/boolbv_mult.cpp +++ b/src/solvers/flattening/boolbv_mult.cpp @@ -6,21 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "boolbv.h" -/*******************************************************************\ - -Function: boolbvt::convert_mult - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include bvt boolbvt::convert_mult(const exprt &expr) { @@ -84,8 +72,8 @@ bvt boolbvt::convert_mult(const exprt &expr) throw "multiplication with mixed types"; bv_utilst::representationt rep= - expr.type().id()==ID_signedbv?bv_utilst::SIGNED: - bv_utilst::UNSIGNED; + expr.type().id()==ID_signedbv?bv_utilst::representationt::SIGNED: + bv_utilst::representationt::UNSIGNED; bv=convert_bv(op0); diff --git a/src/solvers/flattening/boolbv_not.cpp b/src/solvers/flattening/boolbv_not.cpp index a5d0b2e4468..e88955b10f6 100644 --- a/src/solvers/flattening/boolbv_not.cpp +++ b/src/solvers/flattening/boolbv_not.cpp @@ -6,25 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "boolbv.h" - -/*******************************************************************\ - -Function: boolbvt::convert_not - - Inputs: - Outputs: - - Purpose: - -\*******************************************************************/ +#include "boolbv.h" bvt boolbvt::convert_not(const not_exprt &expr) { const bvt &op_bv=convert_bv(expr.op()); - if(op_bv.size()<1) + if(op_bv.empty()) throw "not operator takes one non-empty operand"; const typet &op_type=expr.op().type(); diff --git a/src/solvers/flattening/boolbv_onehot.cpp b/src/solvers/flattening/boolbv_onehot.cpp index d6af04966f8..168185e00f8 100644 --- a/src/solvers/flattening/boolbv_onehot.cpp +++ b/src/solvers/flattening/boolbv_onehot.cpp @@ -6,19 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "boolbv.h" - -/*******************************************************************\ - -Function: boolbvt::convert_onehot - - Inputs: - Outputs: - - Purpose: - -\*******************************************************************/ +#include "boolbv.h" literalt boolbvt::convert_onehot(const unary_exprt &expr) { diff --git a/src/solvers/flattening/boolbv_overflow.cpp b/src/solvers/flattening/boolbv_overflow.cpp index 87c513ae5db..33dd61bca33 100644 --- a/src/solvers/flattening/boolbv_overflow.cpp +++ b/src/solvers/flattening/boolbv_overflow.cpp @@ -6,25 +6,13 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "boolbv.h" + #include #include #include -#include "boolbv.h" - -/*******************************************************************\ - -Function: boolbvt::convert_overflow - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt boolbvt::convert_overflow(const exprt &expr) { const exprt::operandst &operands=expr.operands(); @@ -42,8 +30,8 @@ literalt boolbvt::convert_overflow(const exprt &expr) return SUB::convert_rest(expr); bv_utilst::representationt rep= - expr.op0().type().id()==ID_signedbv?bv_utilst::SIGNED: - bv_utilst::UNSIGNED; + expr.op0().type().id()==ID_signedbv?bv_utilst::representationt::SIGNED: + bv_utilst::representationt::UNSIGNED; return expr.id()==ID_overflow_minus? bv_utils.overflow_sub(bv0, bv1, rep): @@ -65,8 +53,8 @@ literalt boolbvt::convert_overflow(const exprt &expr) throw "operand size mismatch on overflow-*"; bv_utilst::representationt rep= - operands[0].type().id()==ID_signedbv?bv_utilst::SIGNED: - bv_utilst::UNSIGNED; + operands[0].type().id()==ID_signedbv?bv_utilst::representationt::SIGNED: + bv_utilst::representationt::UNSIGNED; if(operands[0].type()!=operands[1].type()) throw "operand type mismatch on overflow-*"; @@ -81,7 +69,7 @@ literalt boolbvt::convert_overflow(const exprt &expr) bvt result=bv_utils.multiplier(bv0, bv1, rep); - if(rep==bv_utilst::UNSIGNED) + if(rep==bv_utilst::representationt::UNSIGNED) { bvt bv_overflow; bv_overflow.reserve(old_size); diff --git a/src/solvers/flattening/boolbv_power.cpp b/src/solvers/flattening/boolbv_power.cpp index b31a9ed9e46..e9967a46860 100644 --- a/src/solvers/flattening/boolbv_power.cpp +++ b/src/solvers/flattening/boolbv_power.cpp @@ -6,19 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "boolbv.h" - -/*******************************************************************\ - -Function: boolbvt::convert_power - - Inputs: - Outputs: - - Purpose: - -\*******************************************************************/ +#include "boolbv.h" bvt boolbvt::convert_power(const binary_exprt &expr) { @@ -40,7 +29,7 @@ bvt boolbvt::convert_power(const binary_exprt &expr) bv_utils.equal(op0, bv_utils.build_constant(2, op0.size())); bvt one=bv_utils.build_constant(1, width); - bvt shift=bv_utils.shift(one, bv_utilst::LEFT, op1); + bvt shift=bv_utils.shift(one, bv_utilst::shiftt::LEFT, op1); bvt nondet=prop.new_variables(width); diff --git a/src/solvers/flattening/boolbv_quantifier.cpp b/src/solvers/flattening/boolbv_quantifier.cpp index 7cfc7f9e03e..23f8857f80d 100644 --- a/src/solvers/flattening/boolbv_quantifier.cpp +++ b/src/solvers/flattening/boolbv_quantifier.cpp @@ -6,27 +6,15 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "boolbv.h" + #include #include #include #include -#include "boolbv.h" - -/*******************************************************************\ - -Function: expr_eq - - Inputs: - - Outputs: - - Purpose: A method to detect equivalence between experts that can - contain typecast - -\*******************************************************************/ - +/// A method to detect equivalence between experts that can contain typecast bool expr_eq(const exprt &expr1, const exprt &expr2) { exprt e1=expr1, e2=expr2; @@ -37,20 +25,9 @@ bool expr_eq(const exprt &expr1, const exprt &expr2) return e1==e2; } -/*******************************************************************\ - -Function: get_quantifier_var_min - - Inputs: - - Outputs: - - Purpose: To obtain the min value for the quantifier variable - of the specified forall/exists operator. The min variable - is in the form of "!(var_expr > constant)". - -\*******************************************************************/ - +/// To obtain the min value for the quantifier variable of the specified +/// forall/exists operator. The min variable is in the form of "!(var_expr > +/// constant)". exprt get_quantifier_var_min( const exprt &var_expr, const exprt &quantifier_expr) @@ -97,19 +74,8 @@ exprt get_quantifier_var_min( return res; } -/*******************************************************************\ - -Function: get_quantifier_var_max - - Inputs: - - Outputs: - - Purpose: To obtain the max value for the quantifier variable - of the specified forall/exists operator. - -\*******************************************************************/ - +/// To obtain the max value for the quantifier variable of the specified +/// forall/exists operator. exprt get_quantifier_var_max( const exprt &var_expr, const exprt &quantifier_expr) @@ -171,18 +137,6 @@ exprt get_quantifier_var_max( return res; } -/*******************************************************************\ - -Function: instantiate_quantifier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool instantiate_quantifier(exprt &expr, const namespacet &ns) { @@ -247,18 +201,6 @@ bool instantiate_quantifier(exprt &expr, return res; } -/*******************************************************************\ - -Function: boolbvt::convert_quantifier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt boolbvt::convert_quantifier(const exprt &src) { exprt expr(src); @@ -275,18 +217,6 @@ literalt boolbvt::convert_quantifier(const exprt &src) return l; } -/*******************************************************************\ - -Function: boolbvt::post_process_quantifiers - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void boolbvt::post_process_quantifiers() { std::set instances; diff --git a/src/solvers/flattening/boolbv_reduction.cpp b/src/solvers/flattening/boolbv_reduction.cpp index e863657066b..8472a16cc5c 100644 --- a/src/solvers/flattening/boolbv_reduction.cpp +++ b/src/solvers/flattening/boolbv_reduction.cpp @@ -6,25 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "boolbv.h" - -/*******************************************************************\ - -Function: boolbvt::convert_reduction - - Inputs: - Outputs: - - Purpose: - -\*******************************************************************/ +#include "boolbv.h" literalt boolbvt::convert_reduction(const unary_exprt &expr) { const bvt &op_bv=convert_bv(expr.op()); - if(op_bv.size()<1) + if(op_bv.empty()) throw "reduction operators take one non-empty operand"; enum { O_OR, O_AND, O_XOR } op; @@ -60,23 +49,11 @@ literalt boolbvt::convert_reduction(const unary_exprt &expr) return l; } -/*******************************************************************\ - -Function: boolbvt::convert_bv_reduction - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt boolbvt::convert_bv_reduction(const unary_exprt &expr) { const bvt &op_bv=convert_bv(expr.op()); - if(op_bv.size()<1) + if(op_bv.empty()) throw "reduction operators take one non-empty operand"; enum { O_OR, O_AND, O_XOR } op; diff --git a/src/solvers/flattening/boolbv_replication.cpp b/src/solvers/flattening/boolbv_replication.cpp index 5983a1ae759..c7368cc1830 100644 --- a/src/solvers/flattening/boolbv_replication.cpp +++ b/src/solvers/flattening/boolbv_replication.cpp @@ -6,21 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "boolbv.h" -/*******************************************************************\ - -Function: boolbvt::convert_replication - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include bvt boolbvt::convert_replication(const replication_exprt &expr) { diff --git a/src/solvers/flattening/boolbv_shift.cpp b/src/solvers/flattening/boolbv_shift.cpp index c0821ded925..596d51067e2 100644 --- a/src/solvers/flattening/boolbv_shift.cpp +++ b/src/solvers/flattening/boolbv_shift.cpp @@ -6,23 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - -#include - #include "boolbv.h" -/*******************************************************************\ - -Function: boolbvt::convert_shift - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include bvt boolbvt::convert_shift(const binary_exprt &expr) { @@ -53,11 +41,11 @@ bvt boolbvt::convert_shift(const binary_exprt &expr) bv_utilst::shiftt shift; if(expr.id()==ID_shl) - shift=bv_utilst::LEFT; + shift=bv_utilst::shiftt::LEFT; else if(expr.id()==ID_ashr) - shift=bv_utilst::ARIGHT; + shift=bv_utilst::shiftt::ARIGHT; else if(expr.id()==ID_lshr) - shift=bv_utilst::LRIGHT; + shift=bv_utilst::shiftt::LRIGHT; else throw "unexpected shift operator"; diff --git a/src/solvers/flattening/boolbv_struct.cpp b/src/solvers/flattening/boolbv_struct.cpp index e1b0b29593a..e1dbe90601f 100644 --- a/src/solvers/flattening/boolbv_struct.cpp +++ b/src/solvers/flattening/boolbv_struct.cpp @@ -6,22 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include -#include - #include "boolbv.h" -/*******************************************************************\ - -Function: boolbvt::convert_struct - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include bvt boolbvt::convert_struct(const struct_exprt &expr) { diff --git a/src/solvers/flattening/boolbv_type.cpp b/src/solvers/flattening/boolbv_type.cpp index df4d5e9a815..fc65dde98f8 100644 --- a/src/solvers/flattening/boolbv_type.cpp +++ b/src/solvers/flattening/boolbv_type.cpp @@ -6,46 +6,35 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "boolbv_type.h" - -/*******************************************************************\ - -Function: get_bvtype - - Inputs: - Outputs: - - Purpose: - -\*******************************************************************/ +#include "boolbv_type.h" bvtypet get_bvtype(const typet &type) { if(type.id()==ID_signedbv) - return IS_SIGNED; + return bvtypet::IS_SIGNED; else if(type.id()==ID_unsignedbv) - return IS_UNSIGNED; + return bvtypet::IS_UNSIGNED; else if(type.id()==ID_c_bool) - return IS_C_BOOL; + return bvtypet::IS_C_BOOL; else if(type.id()==ID_c_enum || type.id()==ID_c_enum_tag || type.id()==ID_incomplete_c_enum) - return IS_C_ENUM; + return bvtypet::IS_C_ENUM; else if(type.id()==ID_floatbv) - return IS_FLOAT; + return bvtypet::IS_FLOAT; else if(type.id()==ID_fixedbv) - return IS_FIXED; + return bvtypet::IS_FIXED; else if(type.id()==ID_bv) - return IS_BV; + return bvtypet::IS_BV; else if(type.id()==ID_verilog_signedbv) - return IS_VERILOG_SIGNED; + return bvtypet::IS_VERILOG_SIGNED; else if(type.id()==ID_verilog_unsignedbv) - return IS_VERILOG_UNSIGNED; + return bvtypet::IS_VERILOG_UNSIGNED; else if(type.id()==ID_range) - return IS_RANGE; + return bvtypet::IS_RANGE; else if(type.id()==ID_c_bit_field) - return IS_C_BIT_FIELD; + return bvtypet::IS_C_BIT_FIELD; - return IS_UNKNOWN; + return bvtypet::IS_UNKNOWN; } diff --git a/src/solvers/flattening/boolbv_type.h b/src/solvers/flattening/boolbv_type.h index 71b55f7c9e1..0c4e97b639b 100644 --- a/src/solvers/flattening/boolbv_type.h +++ b/src/solvers/flattening/boolbv_type.h @@ -6,18 +6,19 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_FLATTENING_BOOLBV_TYPE_H #define CPROVER_SOLVERS_FLATTENING_BOOLBV_TYPE_H #include // new stuff -typedef enum +enum class bvtypet { IS_BV, IS_SIGNED, IS_UNSIGNED, IS_FLOAT, IS_FIXED, IS_C_BOOL, IS_VERILOG_SIGNED, IS_VERILOG_UNSIGNED, IS_RANGE, IS_UNKNOWN, IS_C_ENUM, IS_C_BIT_FIELD -} bvtypet; +}; bvtypet get_bvtype(const typet &type); diff --git a/src/solvers/flattening/boolbv_typecast.cpp b/src/solvers/flattening/boolbv_typecast.cpp index 5ffcd763f74..ecd2522532c 100644 --- a/src/solvers/flattening/boolbv_typecast.cpp +++ b/src/solvers/flattening/boolbv_typecast.cpp @@ -6,28 +6,17 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "boolbv.h" + #include #include -#include "boolbv.h" #include "boolbv_type.h" #include "c_bit_field_replacement_type.h" #include "../floatbv/float_utils.h" -/*******************************************************************\ - -Function: boolbvt::convert_bv_typecast - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt boolbvt::convert_bv_typecast(const typecast_exprt &expr) { const typet &expr_type=ns.follow(expr.type()); @@ -43,18 +32,6 @@ bvt boolbvt::convert_bv_typecast(const typecast_exprt &expr) return bv; } -/*******************************************************************\ - -Function: boolbvt::type_conversion - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool boolbvt::type_conversion( const typet &src_type, const bvt &src, const typet &dest_type, bvt &dest) @@ -62,7 +39,7 @@ bool boolbvt::type_conversion( bvtypet dest_bvtype=get_bvtype(dest_type); bvtypet src_bvtype=get_bvtype(src_type); - if(src_bvtype==IS_C_BIT_FIELD) + if(src_bvtype==bvtypet::IS_C_BIT_FIELD) return type_conversion( c_bit_field_replacement_type(to_c_bit_field_type(src_type), ns), @@ -70,7 +47,7 @@ bool boolbvt::type_conversion( dest_type, dest); - if(dest_bvtype==IS_C_BIT_FIELD) + if(dest_bvtype==bvtypet::IS_C_BIT_FIELD) return type_conversion( src_type, @@ -144,10 +121,10 @@ bool boolbvt::type_conversion( switch(dest_bvtype) { - case IS_RANGE: - if(src_bvtype==IS_UNSIGNED || - src_bvtype==IS_SIGNED || - src_bvtype==IS_C_BOOL) + case bvtypet::IS_RANGE: + if(src_bvtype==bvtypet::IS_UNSIGNED || + src_bvtype==bvtypet::IS_SIGNED || + src_bvtype==bvtypet::IS_C_BOOL) { mp_integer dest_from=to_range_type(dest_type).get_from(); @@ -161,7 +138,7 @@ bool boolbvt::type_conversion( return false; } } - else if(src_bvtype==IS_RANGE) // range to range + else if(src_bvtype==bvtypet::IS_RANGE) // range to range { mp_integer src_from=to_range_type(src_type).get_from(); mp_integer dest_from=to_range_type(dest_type).get_from(); @@ -186,30 +163,30 @@ bool boolbvt::type_conversion( } break; - case IS_FLOAT: // to float + case bvtypet::IS_FLOAT: // to float { float_utilst float_utils(prop); switch(src_bvtype) { - case IS_FLOAT: // float to float + case bvtypet::IS_FLOAT: // float to float // we don't have a rounding mode here, // which is why we refuse. break; - case IS_SIGNED: // signed to float - case IS_C_ENUM: + case bvtypet::IS_SIGNED: // signed to float + case bvtypet::IS_C_ENUM: float_utils.spec=ieee_float_spect(to_floatbv_type(dest_type)); dest=float_utils.from_signed_integer(src); return false; - case IS_UNSIGNED: // unsigned to float - case IS_C_BOOL: // _Bool to float + case bvtypet::IS_UNSIGNED: // unsigned to float + case bvtypet::IS_C_BOOL: // _Bool to float float_utils.spec=ieee_float_spect(to_floatbv_type(dest_type)); dest=float_utils.from_unsigned_integer(src); return false; - case IS_BV: + case bvtypet::IS_BV: assert(src_width==dest_width); dest=src; return false; @@ -236,8 +213,8 @@ bool boolbvt::type_conversion( } break; - case IS_FIXED: - if(src_bvtype==IS_FIXED) + case bvtypet::IS_FIXED: + if(src_bvtype==bvtypet::IS_FIXED) { // fixed to fixed @@ -278,16 +255,16 @@ bool boolbvt::type_conversion( return false; } - else if(src_bvtype==IS_BV) + else if(src_bvtype==bvtypet::IS_BV) { assert(src_width==dest_width); dest=src; return false; } - else if(src_bvtype==IS_UNSIGNED || - src_bvtype==IS_SIGNED || - src_bvtype==IS_C_BOOL || - src_bvtype==IS_C_ENUM) + else if(src_bvtype==bvtypet::IS_UNSIGNED || + src_bvtype==bvtypet::IS_SIGNED || + src_bvtype==bvtypet::IS_C_BOOL || + src_bvtype==bvtypet::IS_C_ENUM) { // integer to fixed @@ -305,7 +282,7 @@ bool boolbvt::type_conversion( l=src[i]; else { - if(src_bvtype==IS_SIGNED || src_bvtype==IS_C_ENUM) + if(src_bvtype==bvtypet::IS_SIGNED || src_bvtype==bvtypet::IS_C_ENUM) l=src[src_width-1]; // sign extension else l=const_literal(false); // zero extension @@ -336,17 +313,17 @@ bool boolbvt::type_conversion( } break; - case IS_UNSIGNED: - case IS_SIGNED: - case IS_C_ENUM: + case bvtypet::IS_UNSIGNED: + case bvtypet::IS_SIGNED: + case bvtypet::IS_C_ENUM: switch(src_bvtype) { - case IS_FLOAT: // float to integer + case bvtypet::IS_FLOAT: // float to integer // we don't have a rounding mode here, // which is why we refuse. break; - case IS_FIXED: // fixed to integer + case bvtypet::IS_FIXED: // fixed to integer { std::size_t op_fraction_bits= to_fixedbv_type(src_type).get_fraction_bits(); @@ -357,7 +334,7 @@ bool boolbvt::type_conversion( dest.push_back(src[i+op_fraction_bits]); else { - if(dest_bvtype==IS_SIGNED) + if(dest_bvtype==bvtypet::IS_SIGNED) dest.push_back(src[src_width-1]); // sign extension else dest.push_back(const_literal(false)); // zero extension @@ -377,17 +354,17 @@ bool boolbvt::type_conversion( return false; } - case IS_UNSIGNED: // integer to integer - case IS_SIGNED: - case IS_C_ENUM: - case IS_C_BOOL: + case bvtypet::IS_UNSIGNED: // integer to integer + case bvtypet::IS_SIGNED: + case bvtypet::IS_C_ENUM: + case bvtypet::IS_C_BOOL: { // We do sign extension for any source type // that is signed, independently of the // destination type. // E.g., ((short)(ulong)(short)-1)==-1 bool sign_extension= - src_bvtype==IS_SIGNED || src_bvtype==IS_C_ENUM; + src_bvtype==bvtypet::IS_SIGNED || src_bvtype==bvtypet::IS_C_ENUM; for(std::size_t i=0; i -#include "boolbv.h" #include "boolbv_type.h" #include "../floatbv/float_utils.h" -/*******************************************************************\ - -Function: boolbvt::convert_unary_minus - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt boolbvt::convert_unary_minus(const unary_exprt &expr) { const typet &type=ns.follow(expr.type()); @@ -52,7 +41,7 @@ bvt boolbvt::convert_unary_minus(const unary_exprt &expr) if(op_width==0 || op_width!=width) return conversion_failed(expr); - if(bvtype==IS_UNKNOWN && + if(bvtype==bvtypet::IS_UNKNOWN && (type.id()==ID_vector || type.id()==ID_complex)) { const typet &subtype=ns.follow(type.subtype()); @@ -98,21 +87,21 @@ bvt boolbvt::convert_unary_minus(const unary_exprt &expr) return bv; } - else if(bvtype==IS_FIXED && op_bvtype==IS_FIXED) + else if(bvtype==bvtypet::IS_FIXED && op_bvtype==bvtypet::IS_FIXED) { if(no_overflow) return bv_utils.negate_no_overflow(op_bv); else return bv_utils.negate(op_bv); } - else if(bvtype==IS_FLOAT && op_bvtype==IS_FLOAT) + else if(bvtype==bvtypet::IS_FLOAT && op_bvtype==bvtypet::IS_FLOAT) { assert(!no_overflow); float_utilst float_utils(prop, to_floatbv_type(expr.type())); return float_utils.negate(op_bv); } - else if((op_bvtype==IS_SIGNED || op_bvtype==IS_UNSIGNED) && - (bvtype==IS_SIGNED || bvtype==IS_UNSIGNED)) + else if((op_bvtype==bvtypet::IS_SIGNED || op_bvtype==bvtypet::IS_UNSIGNED) && + (bvtype==bvtypet::IS_SIGNED || bvtype==bvtypet::IS_UNSIGNED)) { if(no_overflow) prop.l_set_to(bv_utils.overflow_negate(op_bv), false); diff --git a/src/solvers/flattening/boolbv_union.cpp b/src/solvers/flattening/boolbv_union.cpp index 92ac97d0c2c..9432741019a 100644 --- a/src/solvers/flattening/boolbv_union.cpp +++ b/src/solvers/flattening/boolbv_union.cpp @@ -6,24 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "boolbv.h" + #include #include #include -#include "boolbv.h" - -/*******************************************************************\ - -Function: boolbvt::convert_union - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt boolbvt::convert_union(const union_exprt &expr) { std::size_t width=boolbv_width(expr.type()); diff --git a/src/solvers/flattening/boolbv_update.cpp b/src/solvers/flattening/boolbv_update.cpp index 2b485781f6b..e48e5990f07 100644 --- a/src/solvers/flattening/boolbv_update.cpp +++ b/src/solvers/flattening/boolbv_update.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "boolbv.h" + #include #include #include @@ -13,21 +15,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include - -#include "boolbv.h" - -/*******************************************************************\ - -Function: boolbvt::convert_update - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include bvt boolbvt::convert_update(const exprt &expr) { @@ -53,18 +41,6 @@ bvt boolbvt::convert_update(const exprt &expr) return bv; } -/*******************************************************************\ - -Function: boolbvt::convert_update_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void boolbvt::convert_update_rec( const exprt::operandst &designators, std::size_t d, diff --git a/src/solvers/flattening/boolbv_vector.cpp b/src/solvers/flattening/boolbv_vector.cpp index 499b79abe7b..07b5397111d 100644 --- a/src/solvers/flattening/boolbv_vector.cpp +++ b/src/solvers/flattening/boolbv_vector.cpp @@ -6,19 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "boolbv.h" - -/*******************************************************************\ - -Function: boolbvt::convert_vector - - Inputs: - Outputs: - - Purpose: - -\*******************************************************************/ +#include "boolbv.h" bvt boolbvt::convert_vector(const exprt &expr) { diff --git a/src/solvers/flattening/boolbv_width.cpp b/src/solvers/flattening/boolbv_width.cpp index b52ea11fc8a..a61be58ad7f 100644 --- a/src/solvers/flattening/boolbv_width.cpp +++ b/src/solvers/flattening/boolbv_width.cpp @@ -6,58 +6,22 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "boolbv_width.h" + #include #include #include #include -#include "boolbv_width.h" - -/*******************************************************************\ - -Function: boolbv_widtht::boolbv_widtht - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - boolbv_widtht::boolbv_widtht(const namespacet &_ns):ns(_ns) { } -/*******************************************************************\ - -Function: boolbv_widtht::~boolbv_widtht - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - boolbv_widtht::~boolbv_widtht() { } -/*******************************************************************\ - -Function: boolbv_widtht::get_entry - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const boolbv_widtht::entryt &boolbv_widtht::get_entry(const typet &type) const { // check cache first @@ -252,18 +216,6 @@ const boolbv_widtht::entryt &boolbv_widtht::get_entry(const typet &type) const return entry; } -/*******************************************************************\ - -Function: boolbv_widtht::get_member - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const boolbv_widtht::membert &boolbv_widtht::get_member( const struct_typet &type, const irep_idt &member) const diff --git a/src/solvers/flattening/boolbv_width.h b/src/solvers/flattening/boolbv_width.h index 6014dd7b198..d25115b3a83 100644 --- a/src/solvers/flattening/boolbv_width.h +++ b/src/solvers/flattening/boolbv_width.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_FLATTENING_BOOLBV_WIDTH_H #define CPROVER_SOLVERS_FLATTENING_BOOLBV_WIDTH_H diff --git a/src/solvers/flattening/boolbv_with.cpp b/src/solvers/flattening/boolbv_with.cpp index d98cd6be3b9..b3a8170d8f5 100644 --- a/src/solvers/flattening/boolbv_with.cpp +++ b/src/solvers/flattening/boolbv_with.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "boolbv.h" + #include #include #include @@ -13,20 +15,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "boolbv.h" - -/*******************************************************************\ - -Function: boolbvt::convert_with - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt boolbvt::convert_with(const exprt &expr) { if(expr.operands().size()<3) @@ -48,7 +36,13 @@ bvt boolbvt::convert_with(const exprt &expr) std::size_t width=boolbv_width(expr.type()); if(width==0) - return conversion_failed(expr); + { + // A zero-length array is acceptable: + if(expr.type().id()==ID_array && boolbv_width(expr.type().subtype())!=0) + return bvt(); + else + return conversion_failed(expr); + } if(bv.size()!=width) { @@ -77,18 +71,6 @@ bvt boolbvt::convert_with(const exprt &expr) return bv; } -/*******************************************************************\ - -Function: boolbvt::convert_with - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void boolbvt::convert_with( const typet &type, const exprt &op1, @@ -119,18 +101,6 @@ void boolbvt::convert_with( throw 0; } -/*******************************************************************\ - -Function: boolbvt::convert_with_array - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void boolbvt::convert_with_array( const array_typet &type, const exprt &op1, @@ -200,18 +170,6 @@ void boolbvt::convert_with_array( } } -/*******************************************************************\ - -Function: boolbvt::convert_with_bv - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void boolbvt::convert_with_bv( const typet &type, const exprt &op1, @@ -244,18 +202,6 @@ void boolbvt::convert_with_bv( } } -/*******************************************************************\ - -Function: boolbvt::convert_with - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void boolbvt::convert_with_struct( const struct_typet &type, const exprt &op1, @@ -312,18 +258,6 @@ void boolbvt::convert_with_struct( } } -/*******************************************************************\ - -Function: boolbvt::convert_with_union - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void boolbvt::convert_with_union( const union_typet &type, const exprt &op1, diff --git a/src/solvers/flattening/bv_minimize.cpp b/src/solvers/flattening/bv_minimize.cpp index 9798f129ff8..5bc26cee316 100644 --- a/src/solvers/flattening/bv_minimize.cpp +++ b/src/solvers/flattening/bv_minimize.cpp @@ -6,23 +6,11 @@ Author: Georg Weissenbacher, georg.weissenbacher@inf.ethz.ch \*******************************************************************/ -#include - -#include - #include "bv_minimize.h" -/*******************************************************************\ - -Function: bv_minimizet::add_objective - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include void bv_minimizet::add_objective( prop_minimizet &prop_minimize, @@ -66,18 +54,6 @@ void bv_minimizet::add_objective( } } -/*******************************************************************\ - -Function: bv_minimizet::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bv_minimizet::operator()(const minimization_listt &symbols) { // build bit-wise objective function diff --git a/src/solvers/flattening/bv_minimize.h b/src/solvers/flattening/bv_minimize.h index 03ba354e0d8..c6c8023501b 100644 --- a/src/solvers/flattening/bv_minimize.h +++ b/src/solvers/flattening/bv_minimize.h @@ -11,6 +11,9 @@ Purpose: Find a satisfying assignment that minimizes a given set \*******************************************************************/ +/// \file +/// SAT-optimizer for minimizing expressions + #ifndef CPROVER_SOLVERS_FLATTENING_BV_MINIMIZE_H #define CPROVER_SOLVERS_FLATTENING_BV_MINIMIZE_H diff --git a/src/solvers/flattening/bv_pointers.cpp b/src/solvers/flattening/bv_pointers.cpp index 777d51ba104..9ecb81c9846 100644 --- a/src/solvers/flattening/bv_pointers.cpp +++ b/src/solvers/flattening/bv_pointers.cpp @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "bv_pointers.h" + +#include #include #include #include @@ -13,20 +16,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "bv_pointers.h" - -/*******************************************************************\ - -Function: bv_pointerst::convert_rest - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt bv_pointerst::convert_rest(const exprt &expr) { if(expr.type().id()!=ID_bool) @@ -92,25 +81,14 @@ literalt bv_pointerst::convert_rest(const exprt &expr) const bvt &bv0=convert_bv(operands[0]); const bvt &bv1=convert_bv(operands[1]); - return bv_utils.rel(bv0, expr.id(), bv1, bv_utilst::UNSIGNED); + return bv_utils.rel( + bv0, expr.id(), bv1, bv_utilst::representationt::UNSIGNED); } } return SUB::convert_rest(expr); } -/*******************************************************************\ - -Function: bv_pointerst::bv_pointerst - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bv_pointerst::bv_pointerst( const namespacet &_ns, propt &_prop): @@ -122,18 +100,6 @@ bv_pointerst::bv_pointerst( bits=config.ansi_c.pointer_width; } -/*******************************************************************\ - -Function: bv_pointerst::convert_address_of_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool bv_pointerst::convert_address_of_rec( const exprt &expr, bvt &bv) @@ -184,6 +150,7 @@ bool bv_pointerst::convert_address_of_rec( // get size mp_integer size= pointer_offset_size(array_type.subtype(), ns); + assert(size>0); offset_arithmetic(bv, size, index); assert(bv.size()==bits); @@ -204,6 +171,7 @@ bool bv_pointerst::convert_address_of_rec( mp_integer offset=member_offset( to_struct_type(struct_op_type), member_expr.get_component_name(), ns); + assert(offset>=0); // add offset offset_arithmetic(bv, offset); @@ -246,23 +214,14 @@ bool bv_pointerst::convert_address_of_rec( return true; } -/*******************************************************************\ - -Function: bv_pointerst::convert_pointer_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt bv_pointerst::convert_pointer_type(const exprt &expr) { if(!is_ptr(expr.type())) throw "convert_pointer_type got non-pointer type"; + // make sure the config hasn't been changed + assert(bits==config.ansi_c.pointer_width); + if(expr.id()==ID_symbol) { const irep_idt &identifier=to_symbol_expr(expr).get_identifier(); @@ -374,7 +333,12 @@ bvt bv_pointerst::convert_pointer_type(const exprt &expr) count++; bv=convert_bv(*it); assert(bv.size()==bits); - size=pointer_offset_size(it->type().subtype(), ns); + + typet pointer_sub_type=it->type().subtype(); + if(pointer_sub_type.id()==ID_empty) + pointer_sub_type=char_type(); + size=pointer_offset_size(pointer_sub_type, ns); + assert(size>0); } } @@ -399,8 +363,8 @@ bvt bv_pointerst::convert_pointer_type(const exprt &expr) } bv_utilst::representationt rep= - it->type().id()==ID_signedbv?bv_utilst::SIGNED: - bv_utilst::UNSIGNED; + it->type().id()==ID_signedbv?bv_utilst::representationt::SIGNED: + bv_utilst::representationt::UNSIGNED; bvt op=convert_bv(*it); @@ -448,6 +412,7 @@ bvt bv_pointerst::convert_pointer_type(const exprt &expr) mp_integer element_size= pointer_offset_size(expr.op0().type().subtype(), ns); + assert(element_size>0); offset_arithmetic(bv, element_size, neg_op1); @@ -477,18 +442,6 @@ bvt bv_pointerst::convert_pointer_type(const exprt &expr) return conversion_failed(expr); } -/*******************************************************************\ - -Function: bv_pointerst::convert_bitvector - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt bv_pointerst::convert_bitvector(const exprt &expr) { if(is_ptr(expr.type())) @@ -516,12 +469,14 @@ bvt bv_pointerst::convert_bitvector(const exprt &expr) mp_integer element_size= pointer_offset_size(expr.op0().type().subtype(), ns); + assert(element_size>0); if(element_size!=1) { bvt element_size_bv= bv_utils.build_constant(element_size, bv.size()); - bv=bv_utils.divider(bv, element_size_bv, bv_utilst::SIGNED); + bv=bv_utils.divider( + bv, element_size_bv, bv_utilst::representationt::SIGNED); } return bv; @@ -601,18 +556,6 @@ bvt bv_pointerst::convert_bitvector(const exprt &expr) return SUB::convert_bitvector(expr); } -/*******************************************************************\ - -Function: bv_pointerst::bv_get_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt bv_pointerst::bv_get_rec( const bvt &bv, const std::vector &unknown, @@ -667,18 +610,6 @@ exprt bv_pointerst::bv_get_rec( return result; } -/*******************************************************************\ - -Function: bv_pointerst::encode - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bv_pointerst::encode(std::size_t addr, bvt &bv) { bv.resize(bits); @@ -692,18 +623,6 @@ void bv_pointerst::encode(std::size_t addr, bvt &bv) bv[offset_bits+i]=const_literal((addr&(std::size_t(1)< - -#include - #include "bv_utils.h" -/*******************************************************************\ - -Function: bv_utilst::build_constant - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include bvt bv_utilst::build_constant(const mp_integer &n, std::size_t width) { @@ -35,18 +23,6 @@ bvt bv_utilst::build_constant(const mp_integer &n, std::size_t width) return result; } -/*******************************************************************\ - -Function: bv_utilst::is_one - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt bv_utilst::is_one(const bvt &bv) { assert(!bv.empty()); @@ -56,18 +32,6 @@ literalt bv_utilst::is_one(const bvt &bv) return prop.land(is_zero(tmp), bv[0]); } -/*******************************************************************\ - -Function: bv_utilst::set_equal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bv_utilst::set_equal(const bvt &a, const bvt &b) { assert(a.size()==b.size()); @@ -75,18 +39,6 @@ void bv_utilst::set_equal(const bvt &a, const bvt &b) prop.set_equal(a[i], b[i]); } -/*******************************************************************\ - -Function: bv_utilst::extract - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt bv_utilst::extract(const bvt &a, std::size_t first, std::size_t last) { // preconditions @@ -103,18 +55,6 @@ bvt bv_utilst::extract(const bvt &a, std::size_t first, std::size_t last) return result; } -/*******************************************************************\ - -Function: bv_utilst::extract_msb - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt bv_utilst::extract_msb(const bvt &a, std::size_t n) { // preconditions @@ -127,18 +67,6 @@ bvt bv_utilst::extract_msb(const bvt &a, std::size_t n) return result; } -/*******************************************************************\ - -Function: bv_utilst::extract_lsb - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt bv_utilst::extract_lsb(const bvt &a, std::size_t n) { // preconditions @@ -149,18 +77,6 @@ bvt bv_utilst::extract_lsb(const bvt &a, std::size_t n) return result; } -/*******************************************************************\ - -Function: bv_utilst::concatenate - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt bv_utilst::concatenate(const bvt &a, const bvt &b) const { bvt result; @@ -176,18 +92,7 @@ bvt bv_utilst::concatenate(const bvt &a, const bvt &b) const return result; } -/*******************************************************************\ - -Function: bv_utilst::select - - Inputs: - - Outputs: - - Purpose: If s is true, selects a otherwise selects b - -\*******************************************************************/ - +/// If s is true, selects a otherwise selects b bvt bv_utilst::select(literalt s, const bvt &a, const bvt &b) { assert(a.size()==b.size()); @@ -201,18 +106,6 @@ bvt bv_utilst::select(literalt s, const bvt &a, const bvt &b) return result; } -/*******************************************************************\ - -Function: bv_utilst::extension - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt bv_utilst::extension( const bvt &bv, std::size_t new_size, @@ -225,7 +118,7 @@ bvt bv_utilst::extension( assert(old_size!=0); literalt extend_with= - (rep==SIGNED && !bv.empty())?bv[old_size-1]: + (rep==representationt::SIGNED && !bv.empty())?bv[old_size-1]: const_literal(false); for(std::size_t i=old_size; i=0 if // x is negative, always representable, and @@ -612,9 +402,9 @@ literalt bv_utilst::overflow_sub( return prop.lselect(op1_is_int_min, !op0_is_negative, - overflow_add(op0, negate(op1), SIGNED)); + overflow_add(op0, negate(op1), representationt::SIGNED)); } - else if(rep==UNSIGNED) + else if(rep==representationt::UNSIGNED) { // overflow is simply _negated_ carry-out return !carry_out(op0, inverted(op1), const_literal(true)); @@ -623,18 +413,6 @@ literalt bv_utilst::overflow_sub( assert(false); } -/*******************************************************************\ - -Function: bv_utilst::adder_no_overflow - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bv_utilst::adder_no_overflow( bvt &sum, const bvt &op, @@ -643,7 +421,7 @@ void bv_utilst::adder_no_overflow( { const bvt tmp_op=subtract?inverted(op):op; - if(rep==SIGNED) + if(rep==representationt::SIGNED) { // an overflow occurs if the signs of the two operands are the same // and the sign of the sum is the opposite @@ -659,7 +437,7 @@ void bv_utilst::adder_no_overflow( prop.l_set_to_false( prop.land(sign_the_same, prop.lxor(sum[sum.size()-1], old_sign))); } - else if(rep==UNSIGNED) + else if(rep==representationt::UNSIGNED) { literalt carry_out; adder(sum, tmp_op, const_literal(subtract), carry_out); @@ -669,18 +447,6 @@ void bv_utilst::adder_no_overflow( assert(false); } -/*******************************************************************\ - -Function: bv_utilst::adder_no_overflow - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bv_utilst::adder_no_overflow(bvt &sum, const bvt &op) { literalt carry_out=const_literal(false); @@ -690,18 +456,6 @@ void bv_utilst::adder_no_overflow(bvt &sum, const bvt &op) prop.l_set_to_false(carry_out); // enforce no overflow } -/*******************************************************************\ - -Function: bv_utilst::shift - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt bv_utilst::shift(const bvt &op, const shiftt s, const bvt &dist) { std::size_t d=1, width=op.size(); @@ -723,18 +477,6 @@ bvt bv_utilst::shift(const bvt &op, const shiftt s, const bvt &dist) return result; } -/*******************************************************************\ - -Function: bv_utilst::shift - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt bv_utilst::shift(const bvt &src, const shiftt s, std::size_t dist) { bvt result; @@ -746,15 +488,15 @@ bvt bv_utilst::shift(const bvt &src, const shiftt s, std::size_t dist) switch(s) { - case LEFT: + case shiftt::LEFT: l=(dist<=i?src[i-dist]:const_literal(false)); break; - case ARIGHT: + case shiftt::ARIGHT: l=(i+dist &pps) { assert(!pps.empty()); @@ -953,18 +611,6 @@ bvt bv_utilst::wallace_tree(const std::vector &pps) } } -/*******************************************************************\ - -Function: bv_utilst::unsigned_multiplier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt bv_utilst::unsigned_multiplier(const bvt &_op0, const bvt &_op1) { #if 1 @@ -1035,18 +681,6 @@ bvt bv_utilst::unsigned_multiplier(const bvt &_op0, const bvt &_op1) #endif } -/*******************************************************************\ - -Function: bv_utilst::unsigned_multiplier_no_overflow - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt bv_utilst::unsigned_multiplier_no_overflow( const bvt &op0, const bvt &op1) @@ -1086,18 +720,6 @@ bvt bv_utilst::unsigned_multiplier_no_overflow( return product; } -/*******************************************************************\ - -Function: bv_utilst::signed_multiplier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt bv_utilst::signed_multiplier(const bvt &op0, const bvt &op1) { if(op0.empty() || op1.empty()) @@ -1116,18 +738,6 @@ bvt bv_utilst::signed_multiplier(const bvt &op0, const bvt &op1) return cond_negate(result, result_sign); } -/*******************************************************************\ - -Function: bv_utilst::cond_negate - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt bv_utilst::cond_negate(const bvt &bv, const literalt cond) { bvt neg_bv=negate(bv); @@ -1141,36 +751,12 @@ bvt bv_utilst::cond_negate(const bvt &bv, const literalt cond) return result; } -/*******************************************************************\ - -Function: bv_utilst::absolute_value - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt bv_utilst::absolute_value(const bvt &bv) { assert(!bv.empty()); return cond_negate(bv, bv[bv.size()-1]); } -/*******************************************************************\ - -Function: bv_utilst::cond_negate_no_overflow - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt bv_utilst::cond_negate_no_overflow(const bvt &bv, literalt cond) { prop.l_set_to( @@ -1180,18 +766,6 @@ bvt bv_utilst::cond_negate_no_overflow(const bvt &bv, literalt cond) return cond_negate(bv, cond); } -/*******************************************************************\ - -Function: bv_utilst::signed_multiplier_no_overflow - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt bv_utilst::signed_multiplier_no_overflow( const bvt &op0, const bvt &op1) @@ -1214,18 +788,6 @@ bvt bv_utilst::signed_multiplier_no_overflow( return cond_negate_no_overflow(result, result_sign); } -/*******************************************************************\ - -Function: bv_utilst::multiplier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt bv_utilst::multiplier( const bvt &op0, const bvt &op1, @@ -1233,24 +795,12 @@ bvt bv_utilst::multiplier( { switch(rep) { - case SIGNED: return signed_multiplier(op0, op1); - case UNSIGNED: return unsigned_multiplier(op0, op1); + case representationt::SIGNED: return signed_multiplier(op0, op1); + case representationt::UNSIGNED: return unsigned_multiplier(op0, op1); default: assert(false); } } -/*******************************************************************\ - -Function: bv_utilst::multiplier_no_overflow - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt bv_utilst::multiplier_no_overflow( const bvt &op0, const bvt &op1, @@ -1258,24 +808,14 @@ bvt bv_utilst::multiplier_no_overflow( { switch(rep) { - case SIGNED: return signed_multiplier_no_overflow(op0, op1); - case UNSIGNED: return unsigned_multiplier_no_overflow(op0, op1); + case representationt::SIGNED: + return signed_multiplier_no_overflow(op0, op1); + case representationt::UNSIGNED: + return unsigned_multiplier_no_overflow(op0, op1); default: assert(false); } } -/*******************************************************************\ - -Function: bv_utilst::signed_divider - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bv_utilst::signed_divider( const bvt &op0, const bvt &op1, @@ -1311,18 +851,6 @@ void bv_utilst::signed_divider( rem[i]=prop.lselect(sign_0, neg_rem[i], rem[i]); } -/*******************************************************************\ - -Function: bv_utilst::divider - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bv_utilst::divider( const bvt &op0, const bvt &op1, @@ -1334,24 +862,14 @@ void bv_utilst::divider( switch(rep) { - case SIGNED: signed_divider(op0, op1, result, remainer); break; - case UNSIGNED: unsigned_divider(op0, op1, result, remainer); break; + case representationt::SIGNED: + signed_divider(op0, op1, result, remainer); break; + case representationt::UNSIGNED: + unsigned_divider(op0, op1, result, remainer); break; default: assert(false); } } -/*******************************************************************\ - -Function: bv_utilst::unsigned_divider - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bv_utilst::unsigned_divider( const bvt &op0, const bvt &op1, @@ -1427,30 +945,23 @@ void bv_utilst::unsigned_divider( // op1!=0 => rem < op1 prop.l_set_to_true( - prop.limplies(is_not_zero, lt_or_le(false, rem, op1, UNSIGNED))); + prop.limplies( + is_not_zero, lt_or_le(false, rem, op1, representationt::UNSIGNED))); // op1!=0 => res <= op0 prop.l_set_to_true( - prop.limplies(is_not_zero, lt_or_le(true, res, op0, UNSIGNED))); + prop.limplies( + is_not_zero, lt_or_le(true, res, op0, representationt::UNSIGNED))); } #ifdef COMPACT_EQUAL_CONST // TODO : use for lt_or_le as well -/*******************************************************************\ - -Function: bv_utilst::equal_const_rec - - Inputs: A bit-vector of a variable that is to be registered. - - Outputs: None. - - Purpose: The equal_const optimisation will be used on this bit-vector. - -\*******************************************************************/ - +/// The equal_const optimisation will be used on this bit-vector. +/// \par parameters: A bit-vector of a variable that is to be registered. +/// \return None. void bv_utilst::equal_const_register(const bvt &var) { assert(!is_constant(var)); @@ -1459,21 +970,12 @@ void bv_utilst::equal_const_register(const bvt &var) } -/*******************************************************************\ - -Function: bv_utilst::equal_const_rec - - Inputs: Bit-vectors for a variable and a const to compare, note that - to avoid significant amounts of copying these are mutable and consumed. - - Outputs: The literal that is true if and only if all the bits in var - and const are equal. - - Purpose: The obvious recursive comparison, the interesting thing is - that it is cached so the literals are shared between constants. - -\*******************************************************************/ - +/// The obvious recursive comparison, the interesting thing is that it is cached +/// so the literals are shared between constants. +/// \param Bit:vectors for a variable and a const to compare, note that +/// to avoid significant amounts of copying these are mutable and consumed. +/// \return The literal that is true if and only if all the bits in var and +/// const are equal. literalt bv_utilst::equal_const_rec(bvt &var, bvt &constant) { std::size_t size = var.size(); @@ -1516,24 +1018,14 @@ literalt bv_utilst::equal_const_rec(bvt &var, bvt &constant) } } -/*******************************************************************\ - -Function: bv_utilst::equal_const - - Inputs: Bit-vectors for a variable and a const to compare. - - Outputs: The literal that is true if and only if they are equal. - - Purpose: An experimental encoding, aimed primarily at variable - position access to constant arrays. These generate a lot of - comparisons of the form var = small_const . It will introduce some - additional literals and for variables that have only a few - comparisons with constants this may result in a net increase in - formula size. It is hoped that a 'sufficently advanced preprocessor' - will remove these. - -\*******************************************************************/ - +/// An experimental encoding, aimed primarily at variable position access to +/// constant arrays. These generate a lot of comparisons of the form var = +/// small_const . It will introduce some additional literals and for variables +/// that have only a few comparisons with constants this may result in a net +/// increase in formula size. It is hoped that a 'sufficently advanced +/// preprocessor' will remove these. +/// \param Bit:vectors for a variable and a const to compare. +/// \return The literal that is true if and only if they are equal. literalt bv_utilst::equal_const(const bvt &var, const bvt &constant) { std::size_t size = constant.size(); @@ -1591,18 +1083,9 @@ literalt bv_utilst::equal_const(const bvt &var, const bvt &constant) #endif -/*******************************************************************\ - -Function: bv_utilst::equal - - Inputs: Bit-vectors for the two things to compare. - - Outputs: The literal that is true if and only if they are equal. - - Purpose: Bit-blasting ID_equal and use in other encodings. - -\*******************************************************************/ - +/// Bit-blasting ID_equal and use in other encodings. +/// \param Bit:vectors for the two things to compare. +/// \return The literal that is true if and only if they are equal. literalt bv_utilst::equal(const bvt &op0, const bvt &op1) { assert(op0.size()==op1.size()); @@ -1627,20 +1110,10 @@ literalt bv_utilst::equal(const bvt &op0, const bvt &op1) return prop.land(equal_bv); } -/*******************************************************************\ - -Function: bv_utilst::lt_or_le - - Inputs: bvts for each input and whether they are signed and whether - a model of < or <= is required. - - Outputs: A literalt that models the value of the comparison. - - Purpose: To provide a bitwise model of < or <=. - -\*******************************************************************/ - - +/// To provide a bitwise model of < or <=. +/// \par parameters: bvts for each input and whether they are signed and whether +/// a model of < or <= is required. +/// \return A literalt that models the value of the comparison. /* Some clauses are not needed for correctness but they remove models (effectively setting "don't care" bits) and so may be worth including.*/ @@ -1753,9 +1226,9 @@ literalt bv_utilst::lt_or_le( literalt result; - if(rep==SIGNED) + if(rep==representationt::SIGNED) result=prop.lxor(prop.lequal(top0, top1), carry); - else if(rep==UNSIGNED) + else if(rep==representationt::UNSIGNED) result=!carry; else assert(false); @@ -1767,18 +1240,6 @@ literalt bv_utilst::lt_or_le( } } -/*******************************************************************\ - -Function: bv_utilst::unsigned_less_than - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt bv_utilst::unsigned_less_than( const bvt &op0, const bvt &op1) @@ -1791,37 +1252,13 @@ literalt bv_utilst::unsigned_less_than( #endif } -/*******************************************************************\ - -Function: bv_utilst::signed_less_than - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt bv_utilst::signed_less_than( const bvt &bv0, const bvt &bv1) { - return lt_or_le(false, bv0, bv1, SIGNED); + return lt_or_le(false, bv0, bv1, representationt::SIGNED); } -/*******************************************************************\ - -Function: bv_utilst::rel - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt bv_utilst::rel( const bvt &bv0, irep_idt id, @@ -1844,18 +1281,6 @@ literalt bv_utilst::rel( assert(false); } -/*******************************************************************\ - -Function: bv_utilst::is_constant - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool bv_utilst::is_constant(const bvt &bv) { forall_literals(it, bv) @@ -1865,18 +1290,6 @@ bool bv_utilst::is_constant(const bvt &bv) return true; } -/*******************************************************************\ - -Function: bv_utilst::cond_implies_equal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bv_utilst::cond_implies_equal( literalt cond, const bvt &a, @@ -1900,18 +1313,6 @@ void bv_utilst::cond_implies_equal( return; } -/*******************************************************************\ - -Function: bv_utilst::verilog_bv_has_x_or_z - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt bv_utilst::verilog_bv_has_x_or_z(const bvt &src) { bvt odd_bits; @@ -1927,18 +1328,6 @@ literalt bv_utilst::verilog_bv_has_x_or_z(const bvt &src) return prop.lor(odd_bits); } -/*******************************************************************\ - -Function: bv_utilst::verilog_bv_normal_bits - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt bv_utilst::verilog_bv_normal_bits(const bvt &src) { bvt even_bits; diff --git a/src/solvers/flattening/bv_utils.h b/src/solvers/flattening/bv_utils.h index b14fc96b3c4..0dc828a773d 100644 --- a/src/solvers/flattening/bv_utils.h +++ b/src/solvers/flattening/bv_utils.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_FLATTENING_BV_UTILS_H #define CPROVER_SOLVERS_FLATTENING_BV_UTILS_H @@ -27,7 +28,7 @@ class bv_utilst public: explicit bv_utilst(propt &_prop):prop(_prop) { } - typedef enum { SIGNED, UNSIGNED } representationt; + enum class representationt { SIGNED, UNSIGNED }; bvt build_constant(const mp_integer &i, std::size_t width); @@ -67,7 +68,7 @@ class bv_utilst literalt overflow_sub(const bvt &op0, const bvt &op1, representationt rep); literalt carry_out(const bvt &op0, const bvt &op1, literalt carry_in); - typedef enum { LEFT, LRIGHT, ARIGHT } shiftt; + enum class shiftt { LEFT, LRIGHT, ARIGHT }; bvt shift(const bvt &op, const shiftt shift, std::size_t distance); bvt shift(const bvt &op, const shiftt shift, const bvt &distance); @@ -173,12 +174,12 @@ class bv_utilst bvt sign_extension(const bvt &bv, std::size_t new_size) { - return extension(bv, new_size, SIGNED); + return extension(bv, new_size, representationt::SIGNED); } bvt zero_extension(const bvt &bv, std::size_t new_size) { - return extension(bv, new_size, UNSIGNED); + return extension(bv, new_size, representationt::UNSIGNED); } bvt zeros(std::size_t new_size) const diff --git a/src/solvers/flattening/c_bit_field_replacement_type.cpp b/src/solvers/flattening/c_bit_field_replacement_type.cpp index 5a81dc085d5..8e103425433 100644 --- a/src/solvers/flattening/c_bit_field_replacement_type.cpp +++ b/src/solvers/flattening/c_bit_field_replacement_type.cpp @@ -6,19 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "c_bit_field_replacement_type.h" - -/*******************************************************************\ - -Function: c_bit_field_replacement_type - - Inputs: - Outputs: - - Purpose: - -\*******************************************************************/ +#include "c_bit_field_replacement_type.h" typet c_bit_field_replacement_type( const c_bit_field_typet &src, diff --git a/src/solvers/flattening/c_bit_field_replacement_type.h b/src/solvers/flattening/c_bit_field_replacement_type.h index 6f0f78e2c8c..cc139e96836 100644 --- a/src/solvers/flattening/c_bit_field_replacement_type.h +++ b/src/solvers/flattening/c_bit_field_replacement_type.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_FLATTENING_C_BIT_FIELD_REPLACEMENT_TYPE_H #define CPROVER_SOLVERS_FLATTENING_C_BIT_FIELD_REPLACEMENT_TYPE_H diff --git a/src/solvers/flattening/equality.cpp b/src/solvers/flattening/equality.cpp index 63ca7e2e147..79890ab8979 100644 --- a/src/solvers/flattening/equality.cpp +++ b/src/solvers/flattening/equality.cpp @@ -6,25 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "equality.h" + #ifdef DEBUG #include #endif -#include "equality.h" #include "bv_utils.h" -/*******************************************************************\ - -Function: equalityt::equality - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt equalityt::equality(const exprt &e1, const exprt &e2) { if(e1second); } -/*******************************************************************\ - -Function: equalityt::add_equality_constraints - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void equalityt::add_equality_constraints(const typestructt &typestruct) { std::size_t no_elements=typestruct.elements.size(); diff --git a/src/solvers/flattening/equality.h b/src/solvers/flattening/equality.h index 3bb1f74d8de..c4f11f4cd5c 100644 --- a/src/solvers/flattening/equality.h +++ b/src/solvers/flattening/equality.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_FLATTENING_EQUALITY_H #define CPROVER_SOLVERS_FLATTENING_EQUALITY_H diff --git a/src/solvers/flattening/flatten_byte_operators.cpp b/src/solvers/flattening/flatten_byte_operators.cpp index 68ad4b9197e..1d431c083c4 100644 --- a/src/solvers/flattening/flatten_byte_operators.cpp +++ b/src/solvers/flattening/flatten_byte_operators.cpp @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include #include #include #include @@ -13,26 +14,185 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include +#include +#include #include "flatten_byte_operators.h" -/*******************************************************************\ +/// rewrite an object into its individual bytes +/// \par parameters: src object to unpack +/// little_endian true, iff assumed endianness is little-endian +/// max_bytes if not nil, use as upper bound of the number of bytes to unpack +/// ns namespace for type lookups +/// \return array of bytes in the sequence found in memory +static exprt unpack_rec( + const exprt &src, + bool little_endian, + const exprt &max_bytes, + const namespacet &ns, + bool unpack_byte_array=false) +{ + array_exprt array( + array_typet(unsignedbv_typet(8), from_integer(0, size_type()))); -Function: flatten_byte_extract + // endianness_mapt should be the point of reference for mapping out + // endianness, but we need to work on elements here instead of + // individual bits - Inputs: + const typet &type=ns.follow(src.type()); - Outputs: + if(type.id()==ID_array) + { + const array_typet &array_type=to_array_type(type); + const typet &subtype=array_type.subtype(); - Purpose: rewrite byte extraction from an array to byte extraction - from a concatenation of array index expressions + mp_integer element_width=pointer_offset_bits(subtype, ns); + // this probably doesn't really matter + #if 0 + if(element_width<=0) + throw "cannot unpack array with non-constant element width:\n"+ + type.pretty(); + else if(element_width%8!=0) + throw "cannot unpack array of non-byte aligned elements:\n"+ + type.pretty(); + #endif + + if(!unpack_byte_array && element_width==8) + return src; + + mp_integer num_elements; + if(to_integer(max_bytes, num_elements) && + to_integer(array_type.size(), num_elements)) + throw "cannot unpack array of non-const size:\n"+type.pretty(); + + // all array members will have the same structure; do this just + // once and then replace the dummy symbol by a suitable index + // expression in the loop below + symbol_exprt dummy(ID_C_incomplete, subtype); + exprt sub=unpack_rec(dummy, little_endian, max_bytes, ns, true); + + for(mp_integer i=0; i <... 8bits ...> + // + // An array {0, 1} will be encoded as bvt bv={0,1}, i.e., bv[1]==1 + // concatenation(0, 1) will yield a bvt bv={1,0}, i.e., bv[1]==0 + // + // The semantics of byte_extract(endianness, op, offset, T) is: + // interpret ((char*)&op)+offset as the endianness-ordered storage + // of an object of type T at address ((char*)&op)+offset + // For some T x, byte_extract(endianness, x, 0, T) must yield x. + // + // byte_extract for a composite type T or an array will interpret + // the individual subtypes with suitable endianness; the overall + // order of components is not affected by endianness. + // + // Examples: + // unsigned char A[4]; + // byte_extract_little_endian(A, 0, unsigned short) requests that + // A[0],A[1] be interpreted as the storage of an unsigned short with + // A[1] being the most-significant byte; byte_extract_big_endian for + // the same operands will select A[0] as the most-significant byte. + // + // int A[2] = {0x01020304,0xDEADBEEF} + // byte_extract_big_endian(A, 0, short) should yield 0x0102 + // byte_extract_little_endian(A, 0, short) should yield 0x0304 + // To obtain this we first compute byte arrays while taking into + // account endianness: + // big-endian byte representation: {01,02,03,04,DE,AB,BE,EF} + // little-endian byte representation: {04,03,02,01,EF,BE,AB,DE} + // We extract the relevant bytes starting from ((char*)A)+0: + // big-endian: {01,02}; little-endian: {04,03} + // Finally we place them in the appropriate byte order as indicated + // by endianness: + // big-endian: (short)concatenation(01,02)=0x0102 + // little-endian: (short)concatenation(03,04)=0x0304 + assert(src.operands().size()==2); bool little_endian; @@ -44,149 +204,137 @@ exprt flatten_byte_extract( else assert(false); - mp_integer size_bits=pointer_offset_bits(src.type(), ns); - if(size_bits<0) - throw "byte_extract flatting with non-constant size: "+src.pretty(); + // determine an upper bound of the number of bytes we might need + exprt upper_bound=size_of_expr(src.type(), ns); + if(upper_bound.is_not_nil()) + upper_bound= + simplify_expr( + plus_exprt( + upper_bound, + typecast_exprt(src.offset(), upper_bound.type())), + ns); - if(src.op0().type().id()==ID_array) - { - const exprt &root=src.op0(); - const exprt &offset=src.op1(); + byte_extract_exprt unpacked(src); + unpacked.op()= + unpack_rec(src.op(), little_endian, upper_bound, ns); + + const typet &type=ns.follow(src.type()); - const array_typet &array_type=to_array_type(root.type()); + if(type.id()==ID_array) + { + const array_typet &array_type=to_array_type(type); const typet &subtype=array_type.subtype(); mp_integer element_width=pointer_offset_bits(subtype, ns); - if(element_width<0) // failed - throw "failed to flatten array with unknown element width"; - - mp_integer num_elements= - size_bits/element_width+((size_bits%element_width==0)?0:1); - - const typet &offset_type=ns.follow(offset.type()); - - // byte-array? - if(element_width==8) + mp_integer num_elements; + // TODO: consider ways of dealing with arrays of unknown subtype + // size or with a subtype size that does not fit byte boundaries + if(element_width>0 && element_width%8==0 && + to_integer(array_type.size(), num_elements)) { - // get 'width'-many bytes, and concatenate - std::size_t width_bytes=integer2unsigned(num_elements); - exprt::operandst op; - op.reserve(width_bytes); + array_exprt array(array_type); - for(std::size_t i=0; i=2 - { - concatenation_exprt concatenation(src.type()); - concatenation.operands().swap(op); - return concatenation; + array.copy_to_operands(flatten_byte_extract(tmp, ns)); } - } - else // non-byte array - { - // add an extra element as the access need not be aligned with - // element boundaries and could thus stretch over extra elements - ++num_elements; - assert(element_width!=0); + return array; + } + } + else if(type.id()==ID_struct) + { + const struct_typet &struct_type=to_struct_type(type); + const struct_typet::componentst &components=struct_type.components(); - // compute new root and offset - concatenation_exprt concat( - unsignedbv_typet(integer2unsigned(element_width*num_elements))); + bool failed=false; + struct_exprt s(struct_type); - assert(element_width%8==0); - exprt first_index= - div_exprt(offset, from_integer(element_width/8, offset_type)); + for(const auto &comp : components) + { + mp_integer element_width=pointer_offset_bits(comp.type(), ns); - // byte extract will do the appropriate mapping, thus MSB comes - // last here (as opposed to the above, where no further byte - // extract is involved) - for(mp_integer i=0; i=2 + { + concatenation_exprt concatenation(src.type()); + concatenation.operands().swap(op); + return concatenation; + } +} exprt flatten_byte_update( const byte_update_exprt &src, @@ -197,6 +345,8 @@ exprt flatten_byte_update( mp_integer element_size= pointer_offset_size(src.op2().type(), ns); + if(element_size<0) + throw "byte_update of unknown width:\n"+src.pretty(); const typet &t=ns.follow(src.op0().type()); @@ -378,9 +528,9 @@ exprt flatten_byte_update( t.id()==ID_pointer) { // do a shift, mask and OR - std::size_t width=integer2size_t(pointer_offset_size(t, ns)*8); - - assert(width!=0); + mp_integer type_width=pointer_offset_bits(t, ns); + assert(type_width>0); + std::size_t width=integer2size_t(type_width); if(element_size*8>width) throw "flatten_byte_update to update element that is too large"; @@ -441,18 +591,6 @@ exprt flatten_byte_update( } } -/*******************************************************************\ - -Function: flatten_byte_update - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt flatten_byte_update( const byte_update_exprt &src, const namespacet &ns) @@ -460,18 +598,6 @@ exprt flatten_byte_update( return flatten_byte_update(src, ns, false); } -/*******************************************************************\ - -Function: has_byte_operators - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool has_byte_operator(const exprt &src) { if(src.id()==ID_byte_update_little_endian || @@ -487,18 +613,6 @@ bool has_byte_operator(const exprt &src) return false; } -/*******************************************************************\ - -Function: flatten_byte_operators - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt flatten_byte_operators( const exprt &src, const namespacet &ns) diff --git a/src/solvers/flattening/flatten_byte_operators.h b/src/solvers/flattening/flatten_byte_operators.h index 03bdd47f357..678827905a5 100644 --- a/src/solvers/flattening/flatten_byte_operators.h +++ b/src/solvers/flattening/flatten_byte_operators.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_FLATTENING_FLATTEN_BYTE_OPERATORS_H #define CPROVER_SOLVERS_FLATTENING_FLATTEN_BYTE_OPERATORS_H diff --git a/src/solvers/flattening/functions.cpp b/src/solvers/flattening/functions.cpp index 6b23229c958..181d901fd5e 100644 --- a/src/solvers/flattening/functions.cpp +++ b/src/solvers/flattening/functions.cpp @@ -6,25 +6,13 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "functions.h" + #include #include #include -#include "functions.h" - -/*******************************************************************\ - -Function: functionst::record - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void functionst::record( const function_application_exprt &function_application) { @@ -32,18 +20,6 @@ void functionst::record( insert(function_application); } -/*******************************************************************\ - -Function: functionst::add_function_constraints - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void functionst::add_function_constraints() { for(function_mapt::const_iterator it= @@ -53,18 +29,6 @@ void functionst::add_function_constraints() add_function_constraints(it->second); } -/*******************************************************************\ - -Function: functionst::add_function_constraints - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt functionst::arguments_equal(const exprt::operandst &o1, const exprt::operandst &o2) { @@ -91,18 +55,6 @@ exprt functionst::arguments_equal(const exprt::operandst &o1, return and_expr; } -/*******************************************************************\ - -Function: functionst::add_function_constraints - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void functionst::add_function_constraints(const function_infot &info) { // Do Ackermann's function reduction. diff --git a/src/solvers/flattening/functions.h b/src/solvers/flattening/functions.h index 1708862e946..0403e34189f 100644 --- a/src/solvers/flattening/functions.h +++ b/src/solvers/flattening/functions.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Uninterpreted Functions + #ifndef CPROVER_SOLVERS_FLATTENING_FUNCTIONS_H #define CPROVER_SOLVERS_FLATTENING_FUNCTIONS_H diff --git a/src/solvers/flattening/pointer_logic.cpp b/src/solvers/flattening/pointer_logic.cpp index c2b9d1175d0..1018dfca2b7 100644 --- a/src/solvers/flattening/pointer_logic.cpp +++ b/src/solvers/flattening/pointer_logic.cpp @@ -6,27 +6,19 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Pointer Logic + +#include "pointer_logic.h" + #include #include +#include #include #include #include -#include "pointer_logic.h" - -/*******************************************************************\ - -Function: pointer_logict::is_dynamic_object - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool pointer_logict::is_dynamic_object(const exprt &expr) const { if(expr.type().get_bool("#dynamic")) @@ -40,18 +32,6 @@ bool pointer_logict::is_dynamic_object(const exprt &expr) const return false; } -/*******************************************************************\ - -Function: pointer_logict::get_dynamic_objects - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void pointer_logict::get_dynamic_objects(std::vector &o) const { o.clear(); @@ -65,18 +45,6 @@ void pointer_logict::get_dynamic_objects(std::vector &o) const o.push_back(nr); } -/*******************************************************************\ - -Function: pointer_logict::add_object - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::size_t pointer_logict::add_object(const exprt &expr) { // remove any index/member @@ -95,18 +63,6 @@ std::size_t pointer_logict::add_object(const exprt &expr) return objects.number(expr); } -/*******************************************************************\ - -Function: pointer_logict::pointer_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt pointer_logict::pointer_expr( std::size_t object, const typet &type) const @@ -115,18 +71,6 @@ exprt pointer_logict::pointer_expr( return pointer_expr(pointer, type); } -/*******************************************************************\ - -Function: pointer_logict::pointer_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt pointer_logict::pointer_expr( const pointert &pointer, const typet &type) const @@ -144,7 +88,7 @@ exprt pointer_logict::pointer_expr( constant_exprt null(type); null.set_value(ID_NULL); return plus_exprt(null, - from_integer(pointer.offset, integer_typet())); + from_integer(pointer.offset, pointer_diff_type())); } } else if(pointer.object==invalid_object) // INVALID? @@ -178,18 +122,6 @@ exprt pointer_logict::pointer_expr( return result; } -/*******************************************************************\ - -Function: pointer_logict::object_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt pointer_logict::object_rec( const mp_integer &offset, const typet &pointer_type, @@ -200,7 +132,7 @@ exprt pointer_logict::object_rec( mp_integer size= pointer_offset_size(src.type().subtype(), ns); - if(size==0) + if(size<=0) return src; mp_integer index=offset/size; @@ -234,6 +166,7 @@ exprt pointer_logict::object_rec( const typet &subtype=it->type(); mp_integer sub_size=pointer_offset_size(subtype, ns); + assert(sub_size>0); mp_integer new_offset=current_offset+sub_size; if(new_offset>offset) @@ -260,18 +193,6 @@ exprt pointer_logict::object_rec( return src; } -/*******************************************************************\ - -Function: pointer_logict::pointer_logict - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - pointer_logict::pointer_logict(const namespacet &_ns):ns(_ns) { // add NULL @@ -282,18 +203,6 @@ pointer_logict::pointer_logict(const namespacet &_ns):ns(_ns) invalid_object=objects.number(exprt("INVALID")); } -/*******************************************************************\ - -Function: pointer_logict::~pointer_logict - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - pointer_logict::~pointer_logict() { } diff --git a/src/solvers/flattening/pointer_logic.h b/src/solvers/flattening/pointer_logic.h index bcf18ca69f7..07193819358 100644 --- a/src/solvers/flattening/pointer_logic.h +++ b/src/solvers/flattening/pointer_logic.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Pointer Logic + #ifndef CPROVER_SOLVERS_FLATTENING_POINTER_LOGIC_H #define CPROVER_SOLVERS_FLATTENING_POINTER_LOGIC_H @@ -15,6 +18,8 @@ Author: Daniel Kroening, kroening@kroening.com #define BV_ADDR_BITS 8 +class namespacet; + class pointer_logict { public: diff --git a/src/solvers/floatbv/float_approximation.cpp b/src/solvers/floatbv/float_approximation.cpp index 08e65162647..6a70b5f5091 100644 --- a/src/solvers/floatbv/float_approximation.cpp +++ b/src/solvers/floatbv/float_approximation.cpp @@ -6,38 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "float_approximation.h" -/*******************************************************************\ - -Function: float_approximationt::~float_approximationt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include float_approximationt::~float_approximationt() { } -/*******************************************************************\ - -Function: float_approximationt::round_fraction - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void float_approximationt::normalization_shift(bvt &fraction, bvt &exponent) { // this thing is quadratic! @@ -87,18 +63,6 @@ void float_approximationt::normalization_shift(bvt &fraction, bvt &exponent) exponent=new_exponent; } -/*******************************************************************\ - -Function: float_approximationt::overapproximating_left_shift - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt float_approximationt::overapproximating_left_shift( const bvt &src, unsigned dist) { diff --git a/src/solvers/floatbv/float_approximation.h b/src/solvers/floatbv/float_approximation.h index c0a266b8fb6..daaaac8c7f3 100644 --- a/src/solvers/floatbv/float_approximation.h +++ b/src/solvers/floatbv/float_approximation.h @@ -6,6 +6,9 @@ Module: Floating Point with under/over-approximation \*******************************************************************/ +/// \file +/// Floating Point with under/over-approximation + #ifndef CPROVER_SOLVERS_FLOATBV_FLOAT_APPROXIMATION_H #define CPROVER_SOLVERS_FLOATBV_FLOAT_APPROXIMATION_H diff --git a/src/solvers/floatbv/float_bv.cpp b/src/solvers/floatbv/float_bv.cpp index 6a0e37fc1d8..b1810b85d0e 100644 --- a/src/solvers/floatbv/float_bv.cpp +++ b/src/solvers/floatbv/float_bv.cpp @@ -6,26 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "float_bv.h" + #include #include #include #include -#include "float_bv.h" - -/*******************************************************************\ - -Function: float_bvt::convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::convert(const exprt &expr) { if(expr.id()==ID_abs) @@ -94,52 +82,28 @@ exprt float_bvt::convert(const exprt &expr) else if(expr.id()==ID_isnormal) return isnormal(expr.op0(), get_spec(expr.op0())); else if(expr.id()==ID_lt) - return relation(expr.op0(), LT, expr.op1(), get_spec(expr.op0())); + return relation(expr.op0(), relt::LT, expr.op1(), get_spec(expr.op0())); else if(expr.id()==ID_gt) - return relation(expr.op0(), GT, expr.op1(), get_spec(expr.op0())); + return relation(expr.op0(), relt::GT, expr.op1(), get_spec(expr.op0())); else if(expr.id()==ID_le) - return relation(expr.op0(), LE, expr.op1(), get_spec(expr.op0())); + return relation(expr.op0(), relt::LE, expr.op1(), get_spec(expr.op0())); else if(expr.id()==ID_ge) - return relation(expr.op0(), GE, expr.op1(), get_spec(expr.op0())); + return relation(expr.op0(), relt::GE, expr.op1(), get_spec(expr.op0())); else if(expr.id()==ID_sign) return sign_bit(expr.op0()); return nil_exprt(); } -/*******************************************************************\ - -Function: float_bvt::get_spec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - ieee_float_spect float_bvt::get_spec(const exprt &expr) { const floatbv_typet &type=to_floatbv_type(expr.type()); return ieee_float_spect(type); } -/*******************************************************************\ - -Function: float_bvt::abs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::abs(const exprt &op, const ieee_float_spect &spec) { - // we mask away the sign bit, which is the most significand bit + // we mask away the sign bit, which is the most significant bit std::string mask_str(spec.width(), '1'); mask_str[0]='0'; @@ -148,18 +112,6 @@ exprt float_bvt::abs(const exprt &op, const ieee_float_spect &spec) return bitand_exprt(op, mask); } -/*******************************************************************\ - -Function: float_bvt::negation - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::negation(const exprt &op, const ieee_float_spect &spec) { // we flip the sign bit with an xor @@ -171,18 +123,6 @@ exprt float_bvt::negation(const exprt &op, const ieee_float_spect &spec) return bitxor_exprt(op, mask); } -/*******************************************************************\ - -Function: float_bvt::is_equal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::is_equal( const exprt &src0, const exprt &src1, @@ -205,23 +145,11 @@ exprt float_bvt::is_equal( not_exprt(nan)); } -/*******************************************************************\ - -Function: float_bvt::is_zero - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::is_zero( const exprt &src, const ieee_float_spect &spec) { - // we mask away the sign bit, which is the most significand bit + // we mask away the sign bit, which is the most significant bit const floatbv_typet &type=to_floatbv_type(src.type()); std::size_t width=type.get_width(); @@ -236,18 +164,6 @@ exprt float_bvt::is_zero( return equal_exprt(bitand_exprt(src, mask), z.to_expr()); } -/*******************************************************************\ - -Function: float_bvt::exponent_all_ones - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::exponent_all_ones( const exprt &src, const ieee_float_spect &spec) @@ -257,18 +173,6 @@ exprt float_bvt::exponent_all_ones( return equal_exprt(exponent, all_ones); } -/*******************************************************************\ - -Function: float_bvt::exponent_all_zeros - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::exponent_all_zeros( const exprt &src, const ieee_float_spect &spec) @@ -278,18 +182,6 @@ exprt float_bvt::exponent_all_zeros( return equal_exprt(exponent, all_zeros); } -/*******************************************************************\ - -Function: float_bvt::fraction_all_zeros - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::fraction_all_zeros( const exprt &src, const ieee_float_spect &spec) @@ -300,18 +192,6 @@ exprt float_bvt::fraction_all_zeros( return equal_exprt(fraction, all_zeros); } -/*******************************************************************\ - -Function: float_bvt::rounding_mode_bitst::get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void float_bvt::rounding_mode_bitst::get(const exprt &rm) { exprt round_to_even_const=from_integer(ieee_floatt::ROUND_TO_EVEN, rm.type()); @@ -327,18 +207,6 @@ void float_bvt::rounding_mode_bitst::get(const exprt &rm) round_to_zero=equal_exprt(rm, round_to_zero_const); } -/*******************************************************************\ - -Function: float_bvt::sign_bit - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::sign_bit(const exprt &op) { const bitvector_typet &bv_type=to_bitvector_type(op.type()); @@ -346,18 +214,6 @@ exprt float_bvt::sign_bit(const exprt &op) return extractbit_exprt(op, width-1); } -/*******************************************************************\ - -Function: float_bvt::from_signed_integer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::from_signed_integer( const exprt &src, const exprt &rm, @@ -382,18 +238,6 @@ exprt float_bvt::from_signed_integer( return rounder(result, rm, spec); } -/*******************************************************************\ - -Function: float_bvt::from_unsigned_integer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::from_unsigned_integer( const exprt &src, const exprt &rm, @@ -416,18 +260,6 @@ exprt float_bvt::from_unsigned_integer( return rounder(result, rm, spec); } -/*******************************************************************\ - -Function: float_bvt::to_signed_integer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::to_signed_integer( const exprt &src, std::size_t dest_width, @@ -437,18 +269,6 @@ exprt float_bvt::to_signed_integer( return to_integer(src, dest_width, true, rm, spec); } -/*******************************************************************\ - -Function: float_bvt::to_unsigned_integer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::to_unsigned_integer( const exprt &src, std::size_t dest_width, @@ -458,18 +278,6 @@ exprt float_bvt::to_unsigned_integer( return to_integer(src, dest_width, false, rm, spec); } -/*******************************************************************\ - -Function: float_bvt::to_integer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::to_integer( const exprt &src, std::size_t dest_width, @@ -518,18 +326,6 @@ exprt float_bvt::to_integer( return result; } -/*******************************************************************\ - -Function: float_bvt::conversion - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::conversion( const exprt &src, const exprt &rm, @@ -595,18 +391,6 @@ exprt float_bvt::conversion( } } -/*******************************************************************\ - -Function: float_bvt::isnormal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::isnormal( const exprt &src, const ieee_float_spect &spec) @@ -616,18 +400,7 @@ exprt float_bvt::isnormal( not_exprt(exponent_all_ones(src, spec))); } -/*******************************************************************\ - -Function: float_bvt::subtract_exponents - - Inputs: - - Outputs: - - Purpose: Subtracts the exponents - -\*******************************************************************/ - +/// Subtracts the exponents exprt float_bvt::subtract_exponents( const unbiased_floatt &src1, const unbiased_floatt &src2) @@ -648,18 +421,6 @@ exprt float_bvt::subtract_exponents( return minus_exprt(extended_exponent1, extended_exponent2); } -/*******************************************************************\ - -Function: float_bvt::add_sub - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::add_sub( bool subtract, const exprt &op0, @@ -807,18 +568,7 @@ exprt float_bvt::add_sub( return rounder(result, rm, spec); } -/*******************************************************************\ - -Function: float_bvt::limit_distance - - Inputs: - - Outputs: - - Purpose: Limits the shift distance - -\*******************************************************************/ - +/// Limits the shift distance exprt float_bvt::limit_distance( const exprt &dist, mp_integer limit) @@ -845,18 +595,6 @@ exprt float_bvt::limit_distance( unsignedbv_typet(nb_bits).largest_expr()); } -/*******************************************************************\ - -Function: float_bvt::mul - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::mul( const exprt &src1, const exprt &src2, @@ -912,18 +650,6 @@ exprt float_bvt::mul( return rounder(result, rm, spec); } -/*******************************************************************\ - -Function: float_bvt::div - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::div( const exprt &src1, const exprt &src2, @@ -960,7 +686,7 @@ exprt float_bvt::div( // is there a remainder? exprt have_remainder=notequal_exprt(rem, from_integer(0, rem.type())); - // we throw this into the result, as least-significand bit, + // we throw this into the result, as least-significant bit, // to get the right rounding decision result.fraction= concatenation_exprt( @@ -1016,30 +742,18 @@ exprt float_bvt::div( return rounder(result, rm, spec); } -/*******************************************************************\ - -Function: float_bvt::relation - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::relation( const exprt &src1, relt rel, const exprt &src2, const ieee_float_spect &spec) { - if(rel==GT) - return relation(src2, LT, src1, spec); // swapped - else if(rel==GE) - return relation(src2, LE, src1, spec); // swapped + if(rel==relt::GT) + return relation(src2, relt::LT, src1, spec); // swapped + else if(rel==relt::GE) + return relation(src2, relt::LE, src1, spec); // swapped - assert(rel==EQ || rel==LT || rel==LE); + assert(rel==relt::EQ || rel==relt::LT || rel==relt::LE); // special cases: -0 and 0 are equal exprt is_zero1=is_zero(src1, spec); @@ -1051,7 +765,7 @@ exprt float_bvt::relation( exprt isnan2=isnan(src2, spec); exprt nan=or_exprt(isnan1, isnan2); - if(rel==LT || rel==LE) + if(rel==relt::LT || rel==relt::LE) { exprt bitwise_equal=equal_exprt(src1, src2); @@ -1081,7 +795,7 @@ exprt float_bvt::relation( sign_bit(src1), less_than2); - if(rel==LT) + if(rel==relt::LT) { exprt and_bv(ID_and, bool_typet()); and_bv.copy_to_operands(less_than3); @@ -1092,7 +806,7 @@ exprt float_bvt::relation( return and_bv; } - else if(rel==LE) + else if(rel==relt::LE) { exprt or_bv(ID_or, bool_typet()); or_bv.copy_to_operands(less_than3); @@ -1104,7 +818,7 @@ exprt float_bvt::relation( else assert(false); } - else if(rel==EQ) + else if(rel==relt::EQ) { exprt bitwise_equal=equal_exprt(src1, src2); @@ -1119,18 +833,6 @@ exprt float_bvt::relation( return false_exprt(); } -/*******************************************************************\ - -Function: float_bvt::isinf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::isinf( const exprt &src, const ieee_float_spect &spec) @@ -1140,18 +842,6 @@ exprt float_bvt::isinf( fraction_all_zeros(src, spec)); } -/*******************************************************************\ - -Function: float_bvt::isfinite - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::isfinite( const exprt &src, const ieee_float_spect &spec) @@ -1159,18 +849,7 @@ exprt float_bvt::isfinite( return not_exprt(or_exprt(isinf(src, spec), isnan(src, spec))); } -/*******************************************************************\ - -Function: float_bvt::get_exponent - - Inputs: - - Outputs: - - Purpose: Gets the unbiased exponent in a floating-point bit-vector - -\*******************************************************************/ - +/// Gets the unbiased exponent in a floating-point bit-vector exprt float_bvt::get_exponent( const exprt &src, const ieee_float_spect &spec) @@ -1180,19 +859,7 @@ exprt float_bvt::get_exponent( unsignedbv_typet(spec.e)); } -/*******************************************************************\ - -Function: float_bvt::get_fraction - - Inputs: - - Outputs: - - Purpose: Gets the fraction without hidden bit in a floating-point - bit-vector src - -\*******************************************************************/ - +/// Gets the fraction without hidden bit in a floating-point bit-vector src exprt float_bvt::get_fraction( const exprt &src, const ieee_float_spect &spec) @@ -1202,18 +869,6 @@ exprt float_bvt::get_fraction( unsignedbv_typet(spec.f)); } -/*******************************************************************\ - -Function: float_bvt::isnan - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::isnan( const exprt &src, const ieee_float_spect &spec) @@ -1222,19 +877,7 @@ exprt float_bvt::isnan( not_exprt(fraction_all_zeros(src, spec))); } -/*******************************************************************\ - -Function: float_bvt::normalization_shift - - Inputs: - - Outputs: - - Purpose: normalize fraction/exponent pair - returns 'zero' if fraction is zero - -\*******************************************************************/ - +/// normalize fraction/exponent pair returns 'zero' if fraction is zero void float_bvt::normalization_shift( exprt &fraction, exprt &exponent) @@ -1283,19 +926,7 @@ void float_bvt::normalization_shift( exponent=minus_exprt(exponent, exponent_delta); } -/*******************************************************************\ - -Function: float_bvt::denormalization_shift - - Inputs: - - Outputs: - - Purpose: make sure exponent is not too small; - the exponent is unbiased - -\*******************************************************************/ - +/// make sure exponent is not too small; the exponent is unbiased void float_bvt::denormalization_shift( exprt &fraction, exprt &exponent, @@ -1375,18 +1006,6 @@ void float_bvt::denormalization_shift( exponent); } -/*******************************************************************\ - -Function: float_bvt::rounder - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::rounder( const unbiased_floatt &src, const exprt &rm, @@ -1431,18 +1050,7 @@ exprt float_bvt::rounder( return pack(bias(result, spec), spec); } -/*******************************************************************\ - -Function: float_bvt::fraction_rounding_decision - - Inputs: - - Outputs: - - Purpose: rounding decision for fraction using sticky bit - -\*******************************************************************/ - +/// rounding decision for fraction using sticky bit exprt float_bvt::fraction_rounding_decision( const std::size_t dest_bits, const exprt sign, @@ -1506,18 +1114,6 @@ exprt float_bvt::fraction_rounding_decision( false_exprt())))); // otherwise zero } -/*******************************************************************\ - -Function: float_bvt::round_fraction - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void float_bvt::round_fraction( unbiased_floatt &result, const rounding_mode_bitst &rounding_mode_bits, @@ -1628,18 +1224,6 @@ void float_bvt::round_fraction( } } -/*******************************************************************\ - -Function: float_bvt::round_exponent - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void float_bvt::round_exponent( unbiased_floatt &result, const rounding_mode_bitst &rounding_mode_bits, @@ -1714,18 +1298,7 @@ void float_bvt::round_exponent( } } -/*******************************************************************\ - -Function: float_bvt::bias - - Inputs: - - Outputs: - - Purpose: takes an unbiased float, and applies the bias - -\*******************************************************************/ - +/// takes an unbiased float, and applies the bias float_bvt::biased_floatt float_bvt::bias( const unbiased_floatt &src, const ieee_float_spect &spec) @@ -1759,18 +1332,6 @@ float_bvt::biased_floatt float_bvt::bias( return result; } -/*******************************************************************\ - -Function: float_bvt::add_bias - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::add_bias( const exprt &src, const ieee_float_spect &spec) @@ -1781,18 +1342,6 @@ exprt float_bvt::add_bias( from_integer(spec.bias(), t)); } -/*******************************************************************\ - -Function: float_bvt::sub_bias - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::sub_bias( const exprt &src, const ieee_float_spect &spec) @@ -1803,18 +1352,6 @@ exprt float_bvt::sub_bias( from_integer(spec.bias(), t)); } -/*******************************************************************\ - -Function: float_bvt::unpack - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - float_bvt::unbiased_floatt float_bvt::unpack( const exprt &src, const ieee_float_spect &spec) @@ -1848,18 +1385,6 @@ float_bvt::unbiased_floatt float_bvt::unpack( return result; } -/*******************************************************************\ - -Function: float_bvt::pack - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::pack( const biased_floatt &src, const ieee_float_spect &spec) @@ -1895,18 +1420,6 @@ exprt float_bvt::pack( spec.to_type()); } -/*******************************************************************\ - -Function: float_bvt::sticky_right_shift - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt float_bvt::sticky_right_shift( const exprt &op, const exprt &dist, diff --git a/src/solvers/floatbv/float_bv.h b/src/solvers/floatbv/float_bv.h index 74f31f8dc00..f9a58ba2695 100644 --- a/src/solvers/floatbv/float_bv.h +++ b/src/solvers/floatbv/float_bv.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_FLOATBV_FLOAT_BV_H #define CPROVER_SOLVERS_FLOATBV_FLOAT_BV_H @@ -93,7 +94,7 @@ class float_bvt const ieee_float_spect &dest_spec); // relations - typedef enum { LT, LE, EQ, GT, GE } relt; + enum class relt { LT, LE, EQ, GT, GE }; exprt relation( const exprt &, relt rel, diff --git a/src/solvers/floatbv/float_utils.cpp b/src/solvers/floatbv/float_utils.cpp index a772ae0b8a7..6dd36849af8 100644 --- a/src/solvers/floatbv/float_utils.cpp +++ b/src/solvers/floatbv/float_utils.cpp @@ -6,25 +6,13 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "float_utils.h" + #include #include #include -#include "float_utils.h" - -/*******************************************************************\ - -Function: float_utilst::set_rounding_mode - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void float_utilst::set_rounding_mode(const bvt &src) { bvt round_to_even= @@ -42,18 +30,6 @@ void float_utilst::set_rounding_mode(const bvt &src) rounding_mode_bits.round_to_zero=bv_utils.equal(src, round_to_zero); } -/*******************************************************************\ - -Function: float_utilst::from_signed_integer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt float_utilst::from_signed_integer(const bvt &src) { unbiased_floatt result; @@ -72,18 +48,6 @@ bvt float_utilst::from_signed_integer(const bvt &src) return rounder(result); } -/*******************************************************************\ - -Function: float_utilst::from_unsigned_integer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt float_utilst::from_unsigned_integer(const bvt &src) { unbiased_floatt result; @@ -101,18 +65,6 @@ bvt float_utilst::from_unsigned_integer(const bvt &src) return rounder(result); } -/*******************************************************************\ - -Function: float_utilst::to_signed_integer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt float_utilst::to_signed_integer( const bvt &src, std::size_t dest_width) @@ -120,18 +72,6 @@ bvt float_utilst::to_signed_integer( return to_integer(src, dest_width, true); } -/*******************************************************************\ - -Function: float_utilst::to_unsigned_integer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt float_utilst::to_unsigned_integer( const bvt &src, std::size_t dest_width) @@ -139,18 +79,6 @@ bvt float_utilst::to_unsigned_integer( return to_integer(src, dest_width, false); } -/*******************************************************************\ - -Function: float_utilst::to_integer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt float_utilst::to_integer( const bvt &src, std::size_t dest_width, @@ -177,7 +105,8 @@ bvt float_utilst::to_integer( bvt offset=bv_utils.build_constant(fraction.size()-1, unpacked.exponent.size()); bvt distance=bv_utils.sub(offset, unpacked.exponent); - bvt shift_result=bv_utils.shift(fraction, bv_utilst::LRIGHT, distance); + bvt shift_result=bv_utils.shift( + fraction, bv_utilst::shiftt::LRIGHT, distance); // if the exponent is negative, we have zero anyways bvt result=shift_result; @@ -209,18 +138,6 @@ bvt float_utilst::to_integer( throw "unsupported rounding mode"; } -/*******************************************************************\ - -Function: float_utilst::build_constant - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt float_utilst::build_constant(const ieee_floatt &src) { unbiased_floatt result; @@ -234,18 +151,6 @@ bvt float_utilst::build_constant(const ieee_floatt &src) return pack(bias(result)); } -/*******************************************************************\ - -Function: float_utilst::conversion - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt float_utilst::conversion( const bvt &src, const ieee_float_spect &dest_spec) @@ -313,18 +218,6 @@ bvt float_utilst::conversion( } } -/*******************************************************************\ - -Function: float_utilst::is_normal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt float_utilst::is_normal(const bvt &src) { return prop.land( @@ -332,18 +225,7 @@ literalt float_utilst::is_normal(const bvt &src) !exponent_all_ones(src)); } -/*******************************************************************\ - -Function: float_utilst::subtract_exponents - - Inputs: - - Outputs: - - Purpose: Subtracts the exponents - -\*******************************************************************/ - +/// Subtracts the exponents bvt float_utilst::subtract_exponents( const unbiased_floatt &src1, const unbiased_floatt &src2) @@ -360,18 +242,6 @@ bvt float_utilst::subtract_exponents( return bv_utils.sub(extended_exponent1, extended_exponent2); } -/*******************************************************************\ - -Function: float_utilst::add_sub - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt float_utilst::add_sub( const bvt &src1, const bvt &src2, @@ -513,18 +383,7 @@ bvt float_utilst::add_sub( return rounder(result); } -/*******************************************************************\ - -Function: float_utilst::limit_distance - - Inputs: - - Outputs: - - Purpose: Limits the shift distance - -\*******************************************************************/ - +/// Limits the shift distance bvt float_utilst::limit_distance( const bvt &dist, mp_integer limit) @@ -548,18 +407,6 @@ bvt float_utilst::limit_distance( return result; } -/*******************************************************************\ - -Function: float_utilst::mul - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt float_utilst::mul(const bvt &src1, const bvt &src2) { // unpack @@ -612,18 +459,6 @@ bvt float_utilst::mul(const bvt &src1, const bvt &src2) return rounder(result); } -/*******************************************************************\ - -Function: float_utilst::div - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt float_utilst::div(const bvt &src1, const bvt &src2) { // unpack @@ -703,18 +538,6 @@ bvt float_utilst::div(const bvt &src1, const bvt &src2) return rounder(result); } -/*******************************************************************\ - -Function: float_utilst::rem - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt float_utilst::rem(const bvt &src1, const bvt &src2) { /* The semantics of floating-point remainder implemented as below @@ -730,18 +553,6 @@ bvt float_utilst::rem(const bvt &src1, const bvt &src2) return sub(src1, mul(div(src1, src2), src2)); } -/*******************************************************************\ - -Function: float_utilst::negate - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt float_utilst::negate(const bvt &src) { bvt result=src; @@ -751,18 +562,6 @@ bvt float_utilst::negate(const bvt &src) return result; } -/*******************************************************************\ - -Function: float_utilst::abs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt float_utilst::abs(const bvt &src) { bvt result=src; @@ -771,29 +570,17 @@ bvt float_utilst::abs(const bvt &src) return result; } -/*******************************************************************\ - -Function: float_utilst::relation - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt float_utilst::relation( const bvt &src1, relt rel, const bvt &src2) { - if(rel==GT) - return relation(src2, LT, src1); // swapped - else if(rel==GE) - return relation(src2, LE, src1); // swapped + if(rel==relt::GT) + return relation(src2, relt::LT, src1); // swapped + else if(rel==relt::GE) + return relation(src2, relt::LE, src1); // swapped - assert(rel==EQ || rel==LT || rel==LE); + assert(rel==relt::EQ || rel==relt::LT || rel==relt::LE); // special cases: -0 and 0 are equal literalt is_zero1=is_zero(src1); @@ -805,7 +592,7 @@ literalt float_utilst::relation( literalt is_NaN2=is_NaN(src2); literalt NaN=prop.lor(is_NaN1, is_NaN2); - if(rel==LT || rel==LE) + if(rel==relt::LT || rel==relt::LE) { literalt bitwise_equal=bv_utils.equal(src1, src2); @@ -828,7 +615,7 @@ literalt float_utilst::relation( sign_bit(src1), less_than2); - if(rel==LT) + if(rel==relt::LT) { bvt and_bv; and_bv.push_back(less_than3); @@ -838,7 +625,7 @@ literalt float_utilst::relation( return prop.land(and_bv); } - else if(rel==LE) + else if(rel==relt::LE) { bvt or_bv; or_bv.push_back(less_than3); @@ -850,7 +637,7 @@ literalt float_utilst::relation( else assert(false); } - else if(rel==EQ) + else if(rel==relt::EQ) { literalt bitwise_equal=bv_utils.equal(src1, src2); @@ -865,18 +652,6 @@ literalt float_utilst::relation( return const_literal(false); } -/*******************************************************************\ - -Function: float_utilst::is_zero - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt float_utilst::is_zero(const bvt &src) { assert(!src.empty()); @@ -886,18 +661,6 @@ literalt float_utilst::is_zero(const bvt &src) return bv_utils.is_zero(all_but_sign); } -/*******************************************************************\ - -Function: float_utilst::is_plus_inf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt float_utilst::is_plus_inf(const bvt &src) { bvt and_bv; @@ -907,18 +670,6 @@ literalt float_utilst::is_plus_inf(const bvt &src) return prop.land(and_bv); } -/*******************************************************************\ - -Function: float_utilst::infinity - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt float_utilst::is_infinity(const bvt &src) { return prop.land( @@ -926,53 +677,18 @@ literalt float_utilst::is_infinity(const bvt &src) fraction_all_zeros(src)); } -/*******************************************************************\ - -Function: float_utilst::get_exponent - - Inputs: - - Outputs: - - Purpose: Gets the unbiased exponent in a floating-point bit-vector - -\*******************************************************************/ - +/// Gets the unbiased exponent in a floating-point bit-vector bvt float_utilst::get_exponent(const bvt &src) { return bv_utils.extract(src, spec.f, spec.f+spec.e-1); } -/*******************************************************************\ - -Function: float_utilst::get_fraction - - Inputs: - - Outputs: - - Purpose: Gets the fraction without hidden bit in a floating-point - bit-vector src - -\*******************************************************************/ - +/// Gets the fraction without hidden bit in a floating-point bit-vector src bvt float_utilst::get_fraction(const bvt &src) { return bv_utils.extract(src, 0, spec.f-1); } -/*******************************************************************\ - -Function: float_utilst::is_minus_inf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt float_utilst::is_minus_inf(const bvt &src) { bvt and_bv; @@ -982,36 +698,12 @@ literalt float_utilst::is_minus_inf(const bvt &src) return prop.land(and_bv); } -/*******************************************************************\ - -Function: float_utilst::is_NaN - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt float_utilst::is_NaN(const bvt &src) { return prop.land(exponent_all_ones(src), !fraction_all_zeros(src)); } -/*******************************************************************\ - -Function: float_utilst::exponent_all_ones - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt float_utilst::exponent_all_ones(const bvt &src) { bvt exponent=src; @@ -1025,18 +717,6 @@ literalt float_utilst::exponent_all_ones(const bvt &src) return bv_utils.is_all_ones(exponent); } -/*******************************************************************\ - -Function: float_utilst::exponent_all_zeros - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt float_utilst::exponent_all_zeros(const bvt &src) { bvt exponent=src; @@ -1050,18 +730,6 @@ literalt float_utilst::exponent_all_zeros(const bvt &src) return bv_utils.is_zero(exponent); } -/*******************************************************************\ - -Function: float_utilst::fraction_all_zeros - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt float_utilst::fraction_all_zeros(const bvt &src) { // does not include hidden bit @@ -1071,19 +739,7 @@ literalt float_utilst::fraction_all_zeros(const bvt &src) return bv_utils.is_zero(tmp); } -/*******************************************************************\ - -Function: float_utilst::normalization_shift - - Inputs: - - Outputs: - - Purpose: normalize fraction/exponent pair - returns 'zero' if fraction is zero - -\*******************************************************************/ - +/// normalize fraction/exponent pair returns 'zero' if fraction is zero void float_utilst::normalization_shift(bvt &fraction, bvt &exponent) { #if 0 @@ -1153,7 +809,7 @@ void float_utilst::normalization_shift(bvt &fraction, bvt &exponent) // If so, shift the zeros out left by 'distance'. // Otherwise, leave as is. const bvt shifted= - bv_utils.shift(fraction, bv_utilst::LEFT, distance); + bv_utils.shift(fraction, bv_utilst::shiftt::LEFT, distance); fraction= bv_utils.select(prefix_is_zero, shifted, fraction); @@ -1168,19 +824,7 @@ void float_utilst::normalization_shift(bvt &fraction, bvt &exponent) #endif } -/*******************************************************************\ - -Function: float_utilst::denormalization_shift - - Inputs: - - Outputs: - - Purpose: make sure exponent is not too small; - the exponent is unbiased - -\*******************************************************************/ - +/// make sure exponent is not too small; the exponent is unbiased void float_utilst::denormalization_shift(bvt &fraction, bvt &exponent) { mp_integer bias=spec.bias(); @@ -1249,18 +893,6 @@ void float_utilst::denormalization_shift(bvt &fraction, bvt &exponent) exponent); } -/*******************************************************************\ - -Function: float_utilst::rounder - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt float_utilst::rounder(const unbiased_floatt &src) { // incoming: some fraction (with explicit 1), @@ -1301,18 +933,7 @@ bvt float_utilst::rounder(const unbiased_floatt &src) return pack(bias(result)); } -/*******************************************************************\ - -Function: float_utilst::fraction_rounding_decision - - Inputs: - - Outputs: - - Purpose: rounding decision for fraction using sticky bit - -\*******************************************************************/ - +/// rounding decision for fraction using sticky bit literalt float_utilst::fraction_rounding_decision( const std::size_t dest_bits, const literalt sign, @@ -1370,18 +991,6 @@ literalt float_utilst::fraction_rounding_decision( prop.new_variable())))); // otherwise non-det } -/*******************************************************************\ - -Function: float_utilst::round_fraction - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void float_utilst::round_fraction(unbiased_floatt &result) { std::size_t fraction_size=spec.f+1; @@ -1474,18 +1083,6 @@ void float_utilst::round_fraction(unbiased_floatt &result) } } -/*******************************************************************\ - -Function: float_utilst::round_exponent - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void float_utilst::round_exponent(unbiased_floatt &result) { // do we need to enlarge the exponent? @@ -1551,18 +1148,7 @@ void float_utilst::round_exponent(unbiased_floatt &result) } } -/*******************************************************************\ - -Function: float_utilst::bias - - Inputs: - - Outputs: - - Purpose: takes an unbiased float, and applies the bias - -\*******************************************************************/ - +/// takes an unbiased float, and applies the bias float_utilst::biased_floatt float_utilst::bias(const unbiased_floatt &src) { biased_floatt result; @@ -1592,18 +1178,6 @@ float_utilst::biased_floatt float_utilst::bias(const unbiased_floatt &src) return result; } -/*******************************************************************\ - -Function: float_utilst::add_bias - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt float_utilst::add_bias(const bvt &src) { assert(src.size()==spec.e); @@ -1613,18 +1187,6 @@ bvt float_utilst::add_bias(const bvt &src) bv_utils.build_constant(spec.bias(), spec.e)); } -/*******************************************************************\ - -Function: float_utilst::sub_bias - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt float_utilst::sub_bias(const bvt &src) { assert(src.size()==spec.e); @@ -1634,18 +1196,6 @@ bvt float_utilst::sub_bias(const bvt &src) bv_utils.build_constant(spec.bias(), spec.e)); } -/*******************************************************************\ - -Function: float_utilst::unpack - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - float_utilst::unbiased_floatt float_utilst::unpack(const bvt &src) { assert(src.size()==spec.width()); @@ -1675,18 +1225,6 @@ float_utilst::unbiased_floatt float_utilst::unpack(const bvt &src) return result; } -/*******************************************************************\ - -Function: float_utilst::pack - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt float_utilst::pack(const biased_floatt &src) { assert(src.fraction.size()==spec.f); @@ -1718,18 +1256,6 @@ bvt float_utilst::pack(const biased_floatt &src) return result; } -/*******************************************************************\ - -Function: float_utilst::get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - ieee_floatt float_utilst::get(const bvt &src) const { mp_integer int_value=0; @@ -1744,18 +1270,6 @@ ieee_floatt float_utilst::get(const bvt &src) const return result; } -/*******************************************************************\ - -Function: float_utilst::sticky_right_shift - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt float_utilst::sticky_right_shift( const bvt &op, const bvt &dist, @@ -1769,7 +1283,7 @@ bvt float_utilst::sticky_right_shift( { if(dist[stage]!=const_literal(false)) { - bvt tmp=bv_utils.shift(result, bv_utilst::LRIGHT, d); + bvt tmp=bv_utils.shift(result, bv_utilst::shiftt::LRIGHT, d); bvt lost_bits; @@ -1791,18 +1305,6 @@ bvt float_utilst::sticky_right_shift( return result; } -/*******************************************************************\ - -Function: float_utilst::debug1 - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt float_utilst::debug1( const bvt &src1, const bvt &src2) @@ -1810,18 +1312,6 @@ bvt float_utilst::debug1( return src1; } -/*******************************************************************\ - -Function: float_utilst::debug1 - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt float_utilst::debug2( const bvt &op0, const bvt &op1) diff --git a/src/solvers/floatbv/float_utils.h b/src/solvers/floatbv/float_utils.h index daa9609cba7..8d5e935b21a 100644 --- a/src/solvers/floatbv/float_utils.h +++ b/src/solvers/floatbv/float_utils.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_FLOATBV_FLOAT_UTILS_H #define CPROVER_SOLVERS_FLOATBV_FLOAT_UTILS_H @@ -132,7 +133,7 @@ class float_utilst bvt conversion(const bvt &src, const ieee_float_spect &dest_spec); // relations - typedef enum { LT, LE, EQ, GT, GE } relt; + enum class relt { LT, LE, EQ, GT, GE }; literalt relation(const bvt &src1, relt rel, const bvt &src2); // constants diff --git a/src/solvers/miniBDD/example.cpp b/src/solvers/miniBDD/example.cpp index 2dddc990d5a..3307c7722df 100644 --- a/src/solvers/miniBDD/example.cpp +++ b/src/solvers/miniBDD/example.cpp @@ -7,10 +7,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// A minimalistic BDD library, following Bryant's original paper and Andersen's +/// lecture notes #include "miniBDD.h" +#include + int main() { miniBDD::mgr mgr; diff --git a/src/solvers/miniBDD/miniBDD.cpp b/src/solvers/miniBDD/miniBDD.cpp index 756a9dc6e52..4c00b1de85b 100644 --- a/src/solvers/miniBDD/miniBDD.cpp +++ b/src/solvers/miniBDD/miniBDD.cpp @@ -7,17 +7,22 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// A minimalistic BDD library, following Bryant's original paper and Andersen's +/// lecture notes + +#include "miniBDD.h" + #include #include -#include "miniBDD.h" - #define forall_nodes(it) for(nodest::const_iterator it=nodes.begin(); \ it!=nodes.end(); it++) void mini_bdd_nodet::remove_reference() { + // NOLINTNEXTLINE(build/deprecated) assert(reference_counter!=0); reference_counter--; @@ -190,20 +195,23 @@ class mini_bdd_applyt mini_bddt operator()(const mini_bddt &x, const mini_bddt &y) { - return APP(x, y); + return APP_non_rec(x, y); } protected: bool (*fkt)(bool, bool); - mini_bddt APP(const mini_bddt &x, const mini_bddt &y); + mini_bddt APP_rec(const mini_bddt &x, const mini_bddt &y); + mini_bddt APP_non_rec(const mini_bddt &x, const mini_bddt &y); typedef std::map, mini_bddt> Gt; Gt G; }; -mini_bddt mini_bdd_applyt::APP(const mini_bddt &x, const mini_bddt &y) +mini_bddt mini_bdd_applyt::APP_rec(const mini_bddt &x, const mini_bddt &y) { + // NOLINTNEXTLINE(build/deprecated) assert(x.is_initialized() && y.is_initialized()); + // NOLINTNEXTLINE(build/deprecated) assert(x.node->mgr==y.node->mgr); // dynamic programming @@ -220,22 +228,134 @@ mini_bddt mini_bdd_applyt::APP(const mini_bddt &x, const mini_bddt &y) u=mini_bddt(fkt(x.is_true(), y.is_true())?mgr->True():mgr->False()); else if(x.var()==y.var()) u=mgr->mk(x.var(), - APP(x.low(), y.low()), - APP(x.high(), y.high())); + APP_rec(x.low(), y.low()), + APP_rec(x.high(), y.high())); else if(x.var()mk(x.var(), - APP(x.low(), y), - APP(x.high(), y)); + APP_rec(x.low(), y), + APP_rec(x.high(), y)); else /* x.var() > y.var() */ u=mgr->mk(y.var(), - APP(x, y.low()), - APP(x, y.high())); + APP_rec(x, y.low()), + APP_rec(x, y.high())); G[key]=u; return u; } +mini_bddt mini_bdd_applyt::APP_non_rec( + const mini_bddt &_x, + const mini_bddt &_y) +{ + struct stack_elementt + { + stack_elementt( + mini_bddt &_result, + const mini_bddt &_x, + const mini_bddt &_y): + result(_result), x(_x), y(_y), + key(x.node_number(), y.node_number()), + var(0), phase(phaset::INIT) { } + mini_bddt &result, x, y, lr, hr; + std::pair key; + unsigned var; + enum class phaset { INIT, FINISH } phase; + }; + + mini_bddt u; // return value + + std::stack stack; + stack.push(stack_elementt(u, _x, _y)); + + while(!stack.empty()) + { + auto &t=stack.top(); + const mini_bddt &x=t.x; + const mini_bddt &y=t.y; + // NOLINTNEXTLINE(build/deprecated) + assert(x.is_initialized() && y.is_initialized()); + // NOLINTNEXTLINE(build/deprecated) + assert(x.node->mgr==y.node->mgr); + + switch(t.phase) + { + case stack_elementt::phaset::INIT: + { + // dynamic programming + Gt::const_iterator G_it=G.find(t.key); + if(G_it!=G.end()) + { + t.result=G_it->second; + stack.pop(); + } + else + { + if(x.is_constant() && y.is_constant()) + { + bool result_truth=fkt(x.is_true(), y.is_true()); + const mini_bdd_mgrt &mgr=*x.node->mgr; + t.result=result_truth?mgr.True():mgr.False(); + stack.pop(); + } + else if(x.var()==y.var()) + { + t.var=x.var(); + t.phase=stack_elementt::phaset::FINISH; + // NOLINTNEXTLINE(build/deprecated) + assert(x.low().var()>t.var); + // NOLINTNEXTLINE(build/deprecated) + assert(y.low().var()>t.var); + // NOLINTNEXTLINE(build/deprecated) + assert(x.high().var()>t.var); + // NOLINTNEXTLINE(build/deprecated) + assert(y.high().var()>t.var); + stack.push(stack_elementt(t.lr, x.low(), y.low())); + stack.push(stack_elementt(t.hr, x.high(), y.high())); + } + else if(x.var()t.var); + // NOLINTNEXTLINE(build/deprecated) + assert(x.high().var()>t.var); + stack.push(stack_elementt(t.lr, x.low(), y)); + stack.push(stack_elementt(t.hr, x.high(), y)); + } + else /* x.var() > y.var() */ + { + t.var=y.var(); + t.phase=stack_elementt::phaset::FINISH; + // NOLINTNEXTLINE(build/deprecated) + assert(y.low().var()>t.var); + // NOLINTNEXTLINE(build/deprecated) + assert(y.high().var()>t.var); + stack.push(stack_elementt(t.lr, x, y.low())); + stack.push(stack_elementt(t.hr, x, y.high())); + } + } + } + break; + + case stack_elementt::phaset::FINISH: + { + mini_bdd_mgrt *mgr=x.node->mgr; + t.result=mgr->mk(t.var, t.lr, t.hr); + G[t.key]=t.result; + stack.pop(); + } + break; + } + } + + // NOLINTNEXTLINE(build/deprecated) + assert(u.is_initialized()); + + return u; +} + bool equal_fkt(bool x, bool y) { return x==y; @@ -258,6 +378,8 @@ mini_bddt mini_bddt::operator^(const mini_bddt &other) const mini_bddt mini_bddt::operator!() const { + // NOLINTNEXTLINE(build/deprecated) + assert(is_initialized()); return node->mgr->True()^*this; } @@ -299,7 +421,12 @@ mini_bddt mini_bdd_mgrt::mk( const mini_bddt &low, const mini_bddt &high) { + // NOLINTNEXTLINE(build/deprecated) assert(var<=var_table.size()); + // NOLINTNEXTLINE(build/deprecated) + assert(low.var()>var); + // NOLINTNEXTLINE(build/deprecated) + assert(high.var()>var); if(low.node_number()==high.node_number()) return low; @@ -336,14 +463,20 @@ mini_bddt mini_bdd_mgrt::mk( } bool mini_bdd_mgrt::reverse_keyt::operator<( - const mini_bdd_mgrt::reverse_keyt &other) const + const mini_bdd_mgrt::reverse_keyt &y) const { - if(varother.var || low>other.low) + else if(x.var>y.var) return false; - - return highy.low) + return false; + else + return x.highmgr; diff --git a/src/solvers/miniBDD/miniBDD.h b/src/solvers/miniBDD/miniBDD.h index aab378edbae..2187ceb5979 100644 --- a/src/solvers/miniBDD/miniBDD.h +++ b/src/solvers/miniBDD/miniBDD.h @@ -7,6 +7,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// A minimalistic BDD library, following Bryant's original paper and Andersen's +/// lecture notes + #ifndef CPROVER_SOLVERS_MINIBDD_MINIBDD_H #define CPROVER_SOLVERS_MINIBDD_MINIBDD_H @@ -51,7 +55,7 @@ class mini_bddt unsigned node_number() const; void clear(); - bool is_initialized() const { return node!=0; } + bool is_initialized() const { return node!=nullptr; } // internal explicit mini_bddt(class mini_bdd_nodet *_node); @@ -120,7 +124,7 @@ class mini_bdd_mgrt reverse_keyt( unsigned _var, const mini_bddt &_low, const mini_bddt &_high); - bool operator<(const reverse_keyt &other) const; + bool operator<(const reverse_keyt &) const; }; typedef std::map reverse_mapt; diff --git a/src/solvers/miniBDD/miniBDD.inc b/src/solvers/miniBDD/miniBDD.inc index 091725ed333..a2077ab95f1 100644 --- a/src/solvers/miniBDD/miniBDD.inc +++ b/src/solvers/miniBDD/miniBDD.inc @@ -2,7 +2,7 @@ // inline functions -inline mini_bddt::mini_bddt():node(0) +inline mini_bddt::mini_bddt():node(nullptr) { } @@ -82,7 +82,7 @@ inline void mini_bddt::clear() if(is_initialized()) { node->remove_reference(); - node=NULL; + node=nullptr; } } diff --git a/src/solvers/module.md b/src/solvers/module.md new file mode 100644 index 00000000000..98eeae6719e --- /dev/null +++ b/src/solvers/module.md @@ -0,0 +1,49 @@ +\ingroup module_hidden +\defgroup module_solvers SAT/SMT Encoding and Decision Procedure + +\author Kareem Khazem + +\section sat-smt-encoding SAT/SMT Encoding + +In the \ref solvers directory. + +**Key classes:** +* \ref literalt +* \ref boolbvt +* \ref propt + +\dot +digraph G { + node [shape=box]; + rankdir="LR"; + 1 [shape=none, label=""]; + 2 [label="goto conversion"]; + 3 [shape=none, label=""]; + 1 -> 2 [label="equations"]; + 2 -> 3 [label="propositional variables as bitvectors, constraints"]; +} +\enddot + + +--- + +\section decision-procedure Decision Procedure + +In the \ref solvers directory. + +**Key classes:** +* symex_target_equationt +* \ref propt +* \ref bmct + +\dot +digraph G { + node [shape=box]; + rankdir="LR"; + 1 [shape=none, label=""]; + 2 [label="goto conversion"]; + 3 [shape=none, label=""]; + 1 -> 2 [label="propositional variables as bitvectors, constraints"]; + 2 -> 3 [label="solutions"]; +} +\enddot diff --git a/src/solvers/prop/aig.cpp b/src/solvers/prop/aig.cpp index 791436646f9..a164b379db0 100644 --- a/src/solvers/prop/aig.cpp +++ b/src/solvers/prop/aig.cpp @@ -6,76 +6,28 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "aig.h" + #include #include #include -#include "aig.h" - -/*******************************************************************\ - -Function: aigt::label - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string aigt::label(nodest::size_type v) const { return "var("+std::to_string(v)+")"; } -/*******************************************************************\ - -Function: aigt::dot_label - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string aigt::dot_label(nodest::size_type v) const { return "var("+std::to_string(v)+")"; } -/*******************************************************************\ - -Function: aigt::get_terminals - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void aigt::get_terminals(terminalst &terminals) const { for(nodest::size_type n=0; n #include -#include "aig_prop.h" - // Tries to compact AIGs corresponding to xor and equality // Needed to match the performance of the native CNF back-end. #define USE_AIG_COMPACT @@ -19,18 +19,6 @@ Author: Daniel Kroening, kroening@kroening.com // native CNF back-end. #define USE_PG -/*******************************************************************\ - -Function: aig_prop_baset::land - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt aig_prop_baset::land(const bvt &bv) { literalt literal=const_literal(true); @@ -43,18 +31,6 @@ literalt aig_prop_baset::land(const bvt &bv) return literal; } -/*******************************************************************\ - -Function: aig_prop_baset::lor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt aig_prop_baset::lor(const bvt &bv) { literalt literal=const_literal(true); @@ -67,18 +43,6 @@ literalt aig_prop_baset::lor(const bvt &bv) return neg(literal); } -/*******************************************************************\ - -Function: aig_prop_baset::lxor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt aig_prop_baset::lxor(const bvt &bv) { literalt literal=const_literal(false); @@ -89,18 +53,6 @@ literalt aig_prop_baset::lxor(const bvt &bv) return literal; } -/*******************************************************************\ - -Function: aig_prop_baset::land - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt aig_prop_baset::land(literalt a, literalt b) { if(a.is_true() || b.is_false()) @@ -116,35 +68,11 @@ literalt aig_prop_baset::land(literalt a, literalt b) return dest.new_and_node(a, b); } -/*******************************************************************\ - -Function: aig_prop_baset::lor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt aig_prop_baset::lor(literalt a, literalt b) { return neg(land(neg(a), neg(b))); // De Morgan's } -/*******************************************************************\ - -Function: aig_prop_baset::lxor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt aig_prop_baset::lxor(literalt a, literalt b) { if(a.is_false()) @@ -166,86 +94,26 @@ literalt aig_prop_baset::lxor(literalt a, literalt b) return lor(land(a, neg(b)), land(neg(a), b)); } -/*******************************************************************\ - -Function: aig_prop_baset::lnand - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt aig_prop_baset::lnand(literalt a, literalt b) { return !land(a, b); } -/*******************************************************************\ - -Function: aig_prop_baset::lnor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt aig_prop_baset::lnor(literalt a, literalt b) { return !lor(a, b); } -/*******************************************************************\ - -Function: aig_prop_baset::lequal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt aig_prop_baset::lequal(literalt a, literalt b) { return !lxor(a, b); } -/*******************************************************************\ - -Function: aig_prop_baset::limplies - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt aig_prop_baset::limplies(literalt a, literalt b) { return lor(neg(a), b); } -/*******************************************************************\ - -Function: aig_prop_baset::lselect - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt aig_prop_baset::lselect(literalt a, literalt b, literalt c) { // a?b:c=(a AND b) OR (/a AND c) if(a.is_true()) @@ -261,18 +129,6 @@ literalt aig_prop_baset::lselect(literalt a, literalt b, literalt c) return lor(land(a, b), land(neg(a), c)); } -/*******************************************************************\ - -Function: aig_prop_baset::set_equal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void aig_prop_baset::set_equal(literalt a, literalt b) { #ifdef USE_AIG_COMPACT @@ -288,35 +144,11 @@ void aig_prop_baset::set_equal(literalt a, literalt b) #endif } -/*******************************************************************\ - -Function: aig_prop_solvert::l_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt aig_prop_solvert::l_get(literalt a) const { return solver.l_get(a); } -/*******************************************************************\ - -Function: aig_prop_solvert::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - propt::resultt aig_prop_solvert::prop_solve() { status() << "converting AIG, " @@ -326,18 +158,9 @@ propt::resultt aig_prop_solvert::prop_solve() return solver.prop_solve(); } -/*******************************************************************\ - -Function: aig_prop_solvert::compute_phase - - Inputs: Two vectors of bools of size aig.nodes.size() - - Outputs: These vectors filled in with per node phase information - - Purpose: Compute the phase information needed for Plaisted-Greenbaum encoding - -\*******************************************************************/ - +/// Compute the phase information needed for Plaisted-Greenbaum encoding +/// \par parameters: Two vectors of bools of size aig.nodes.size() +/// \return These vectors filled in with per node phase information void aig_prop_solvert::compute_phase( std::vector &n_pos, std::vector &n_neg) @@ -400,18 +223,9 @@ void aig_prop_solvert::compute_phase( } -/*******************************************************************\ - -Function: aig_prop_solvert::usage_count - - Inputs: Two vectors of unsigned of size aig.nodes.size() - - Outputs: These vectors filled in with per node usage information - - Purpose: Compact encoding for single usage variable - -\*******************************************************************/ - +/// Compact encoding for single usage variable +/// \par parameters: Two vectors of unsigned of size aig.nodes.size() +/// \return These vectors filled in with per node usage information void aig_prop_solvert::usage_count( std::vector &p_usage_count, std::vector &n_usage_count) @@ -519,18 +333,10 @@ void aig_prop_solvert::usage_count( #endif } -/*******************************************************************\ - -Function: aig_prop_solvert::convert_node - - Inputs: The node to convert, the phases required and the usage counts. - - Outputs: The node converted to CNF in the solver object. - - Purpose: Convert one AIG node, including special handling of a couple of cases - -\*******************************************************************/ - +/// Convert one AIG node, including special handling of a couple of cases +/// \par parameters: The node to convert, the phases required and the usage +/// counts. +/// \return The node converted to CNF in the solver object. void aig_prop_solvert::convert_node( unsigned n, const aigt::nodet &node, @@ -742,18 +548,6 @@ void aig_prop_solvert::convert_node( } } -/*******************************************************************\ - -Function: aig_prop_solvert::convert_aig - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void aig_prop_solvert::convert_aig() { // 1. Do variables diff --git a/src/solvers/prop/aig_prop.h b/src/solvers/prop/aig_prop.h index d88b5e86a9e..335f224747c 100644 --- a/src/solvers/prop/aig_prop.h +++ b/src/solvers/prop/aig_prop.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_PROP_AIG_PROP_H #define CPROVER_SOLVERS_PROP_AIG_PROP_H @@ -57,7 +58,7 @@ class aig_prop_baset:public propt { assert(0); return tvt::unknown(); } resultt prop_solve() override - { assert(0); return P_ERROR; } + { assert(0); return resultt::P_ERROR; } protected: aigt &dest; diff --git a/src/solvers/prop/bdd_expr.cpp b/src/solvers/prop/bdd_expr.cpp index 91e06dfb08a..2a5b4ffa786 100644 --- a/src/solvers/prop/bdd_expr.cpp +++ b/src/solvers/prop/bdd_expr.cpp @@ -6,24 +6,15 @@ Author: Michael Tautschnig, michael.tautschnig@qmul.ac.uk \*******************************************************************/ -#include - -#include -#include +/// \file +/// Conversion between exprt and miniBDD #include "bdd_expr.h" -/*******************************************************************\ - -Function: bdd_exprt::from_expr_rec - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include +#include mini_bddt bdd_exprt::from_expr_rec(const exprt &expr) { @@ -103,35 +94,11 @@ mini_bddt bdd_exprt::from_expr_rec(const exprt &expr) } } -/*******************************************************************\ - -Function: bdd_exprt::from_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bdd_exprt::from_expr(const exprt &expr) { root=from_expr_rec(expr); } -/*******************************************************************\ - -Function: bdd_exprt::as_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt bdd_exprt::as_expr(const mini_bddt &r) const { if(r.is_constant()) @@ -168,18 +135,6 @@ exprt bdd_exprt::as_expr(const mini_bddt &r) const return if_exprt(n_expr, as_expr(r.high()), as_expr(r.low())); } -/*******************************************************************\ - -Function: bdd_exprt::as_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt bdd_exprt::as_expr() const { if(!root.is_initialized()) diff --git a/src/solvers/prop/bdd_expr.h b/src/solvers/prop/bdd_expr.h index 3c35aa5dc21..c462a17e669 100644 --- a/src/solvers/prop/bdd_expr.h +++ b/src/solvers/prop/bdd_expr.h @@ -6,6 +6,9 @@ Author: Michael Tautschnig, michael.tautschnig@qmul.ac.uk \*******************************************************************/ +/// \file +/// Conversion between exprt and miniBDD + #ifndef CPROVER_SOLVERS_PROP_BDD_EXPR_H #define CPROVER_SOLVERS_PROP_BDD_EXPR_H diff --git a/src/solvers/prop/cover_goals.cpp b/src/solvers/prop/cover_goals.cpp index 699177b25ad..aaf494169ed 100644 --- a/src/solvers/prop/cover_goals.cpp +++ b/src/solvers/prop/cover_goals.cpp @@ -6,39 +6,20 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Cover a set of goals incrementally -#include "literal_expr.h" #include "cover_goals.h" -/*******************************************************************\ - -Function: cover_goalst::~cover_goalst - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include "literal_expr.h" cover_goalst::~cover_goalst() { } -/*******************************************************************\ - -Function: cover_goalst::mark - - Inputs: - - Outputs: - - Purpose: Mark goals that are covered - -\*******************************************************************/ - +/// Mark goals that are covered void cover_goalst::mark() { // notify observers @@ -58,18 +39,7 @@ void cover_goalst::mark() } } -/*******************************************************************\ - -Function: cover_goalst::constaint - - Inputs: - - Outputs: - - Purpose: Build clause - -\*******************************************************************/ - +/// Build clause void cover_goalst::constraint() { exprt::operandst disjuncts; @@ -88,18 +58,7 @@ void cover_goalst::constraint() prop_conv.set_to_true(disjunction(disjuncts)); } -/*******************************************************************\ - -Function: cover_goalst::freeze_goal_variables - - Inputs: - - Outputs: - - Purpose: Build clause - -\*******************************************************************/ - +/// Build clause void cover_goalst::freeze_goal_variables() { for(std::list::const_iterator @@ -110,18 +69,7 @@ void cover_goalst::freeze_goal_variables() prop_conv.set_frozen(g_it->condition); } -/*******************************************************************\ - -Function: cover_goalst::operator() - - Inputs: - - Outputs: - - Purpose: Try to cover all goals - -\*******************************************************************/ - +/// Try to cover all goals decision_proceduret::resultt cover_goalst::operator()() { _iterations=_number_covered=0; @@ -142,10 +90,10 @@ decision_proceduret::resultt cover_goalst::operator()() switch(dec_result) { - case decision_proceduret::D_UNSATISFIABLE: // DONE + case decision_proceduret::resultt::D_UNSATISFIABLE: // DONE return dec_result; - case decision_proceduret::D_SATISFIABLE: + case decision_proceduret::resultt::D_SATISFIABLE: // mark the goals we got, and notify observers mark(); break; @@ -155,8 +103,8 @@ decision_proceduret::resultt cover_goalst::operator()() return dec_result; } } - while(dec_result==decision_proceduret::D_SATISFIABLE && + while(dec_result==decision_proceduret::resultt::D_SATISFIABLE && number_covered() +/// \file +/// Literals #include "literal.h" -/*******************************************************************\ - -Function: operator << - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include std::ostream &operator << (std::ostream &out, literalt l) { diff --git a/src/solvers/prop/literal.h b/src/solvers/prop/literal.h index 694f5701a12..24e62ba599a 100644 --- a/src/solvers/prop/literal.h +++ b/src/solvers/prop/literal.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_PROP_LITERAL_H #define CPROVER_SOLVERS_PROP_LITERAL_H diff --git a/src/solvers/prop/literal_expr.h b/src/solvers/prop/literal_expr.h index b76c23b0ba5..c37553615d0 100644 --- a/src/solvers/prop/literal_expr.h +++ b/src/solvers/prop/literal_expr.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_PROP_LITERAL_EXPR_H #define CPROVER_SOLVERS_PROP_LITERAL_EXPR_H diff --git a/src/solvers/prop/minimize.cpp b/src/solvers/prop/minimize.cpp index 693e0ef0d59..c28ab411bf3 100644 --- a/src/solvers/prop/minimize.cpp +++ b/src/solvers/prop/minimize.cpp @@ -6,23 +6,16 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Minimize some target function incrementally -#include "literal_expr.h" #include "minimize.h" -/*******************************************************************\ - -Function: prop_minimizet::objective - - Inputs: - - Outputs: - - Purpose: Add an objective +#include -\*******************************************************************/ +#include "literal_expr.h" +/// Add an objective void prop_minimizet::objective( const literalt condition, const weightt weight) @@ -39,18 +32,7 @@ void prop_minimizet::objective( } } -/*******************************************************************\ - -Function: prop_minimizet::fix - - Inputs: - - Outputs: - - Purpose: Fix objectives that are satisfied - -\*******************************************************************/ - +/// Fix objectives that are satisfied void prop_minimizet::fix_objectives() { std::vector &entry=current->second; @@ -75,19 +57,7 @@ void prop_minimizet::fix_objectives() assert(found); } -/*******************************************************************\ - -Function: prop_minimizet::constaint - - Inputs: - - Outputs: - - Purpose: Build constraints that require us to improve on - at least one goal, greedily. - -\*******************************************************************/ - +/// Build constraints that require us to improve on at least one goal, greedily. literalt prop_minimizet::constraint() { std::vector &entry=current->second; @@ -119,18 +89,7 @@ literalt prop_minimizet::constraint() } } -/*******************************************************************\ - -Function: prop_minimizet::operator() - - Inputs: - - Outputs: - - Purpose: Try to cover all objectives - -\*******************************************************************/ - +/// Try to cover all objectives void prop_minimizet::operator()() { // we need to use assumptions @@ -155,7 +114,7 @@ void prop_minimizet::operator()() literalt c=constraint(); if(c.is_false()) - dec_result=decision_proceduret::D_UNSATISFIABLE; + dec_result=decision_proceduret::resultt::D_UNSATISFIABLE; else { _iterations++; @@ -167,11 +126,11 @@ void prop_minimizet::operator()() switch(dec_result) { - case decision_proceduret::D_UNSATISFIABLE: + case decision_proceduret::resultt::D_UNSATISFIABLE: last_was_SAT=false; break; - case decision_proceduret::D_SATISFIABLE: + case decision_proceduret::resultt::D_SATISFIABLE: last_was_SAT=true; fix_objectives(); // fix the ones we got break; @@ -183,7 +142,7 @@ void prop_minimizet::operator()() } } } - while(dec_result!=decision_proceduret::D_UNSATISFIABLE); + while(dec_result!=decision_proceduret::resultt::D_UNSATISFIABLE); } if(!last_was_SAT) diff --git a/src/solvers/prop/minimize.h b/src/solvers/prop/minimize.h index f546f8442ee..30e5e89f19c 100644 --- a/src/solvers/prop/minimize.h +++ b/src/solvers/prop/minimize.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// SAT Minimizer + #ifndef CPROVER_SOLVERS_PROP_MINIMIZE_H #define CPROVER_SOLVERS_PROP_MINIMIZE_H @@ -15,20 +18,16 @@ Author: Daniel Kroening, kroening@kroening.com #include "prop_conv.h" -/*******************************************************************\ - - Class: prop_minimizet - - Purpose: Computes a satisfying assignment of minimal cost - according to a const function using incremental SAT - -\*******************************************************************/ - +/// Computes a satisfying assignment of minimal cost according to a const +/// function using incremental SAT class prop_minimizet:public messaget { public: explicit prop_minimizet(prop_convt &_prop_conv): + _iterations(0), + _number_satisfied(0), _number_objectives(0), + _value(0), prop_conv(_prop_conv) { } diff --git a/src/solvers/prop/prop.cpp b/src/solvers/prop/prop.cpp index cb17cc9ce11..bfa3a005915 100644 --- a/src/solvers/prop/prop.cpp +++ b/src/solvers/prop/prop.cpp @@ -6,92 +6,36 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "prop.h" -/*******************************************************************\ - -Function: propt::set_equal - - Inputs: - - Outputs: - - Purpose: asserts a==b in the propositional formula - -\*******************************************************************/ +#include +/// asserts a==b in the propositional formula void propt::set_equal(literalt a, literalt b) { lcnf(a, !b); lcnf(!a, b); } -/*******************************************************************\ - -Function: propt::set_assignment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void propt::set_assignment(literalt a, bool value) { assert(false); } -/*******************************************************************\ - -Function: propt::copy_assignment_from - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void propt::copy_assignment_from(const propt &src) { assert(false); } -/*******************************************************************\ - -Function: propt::is_in_conflict - - Inputs: - - Outputs: true iff the given literal is part of the final conflict - - Purpose: - -\*******************************************************************/ - +/// \return true iff the given literal is part of the final conflict bool propt::is_in_conflict(literalt l) const { assert(false); return false; } -/*******************************************************************\ - -Function: propt::new_variables - - Inputs: width - - Outputs: bitvector - - Purpose: generates a bitvector of given width with new variables - -\*******************************************************************/ - +/// generates a bitvector of given width with new variables +/// \return bitvector bvt propt::new_variables(std::size_t width) { bvt result; diff --git a/src/solvers/prop/prop.h b/src/solvers/prop/prop.h index 6f58faef3b0..e48674d5c57 100644 --- a/src/solvers/prop/prop.h +++ b/src/solvers/prop/prop.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_PROP_PROP_H #define CPROVER_SOLVERS_PROP_PROP_H @@ -90,7 +91,7 @@ class propt:public messaget, public prop_assignmentt // solving virtual const std::string solver_text()=0; - typedef enum { P_SATISFIABLE, P_UNSATISFIABLE, P_ERROR } resultt; + enum class resultt { P_SATISFIABLE, P_UNSATISFIABLE, P_ERROR }; virtual resultt prop_solve()=0; // satisfying assignment, from prop_assignmentt diff --git a/src/solvers/prop/prop_assignment.cpp b/src/solvers/prop/prop_assignment.cpp index f191a4c6c55..31eb4089559 100644 --- a/src/solvers/prop/prop_assignment.cpp +++ b/src/solvers/prop/prop_assignment.cpp @@ -6,19 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "prop_assignment.h" - -/*******************************************************************\ - -Function: prop_assignmentt::~prop_assignmentt - - Inputs: - Outputs: - - Purpose: - -\*******************************************************************/ +#include "prop_assignment.h" prop_assignmentt::~prop_assignmentt() { diff --git a/src/solvers/prop/prop_assignment.h b/src/solvers/prop/prop_assignment.h index 0de6dcdc4ef..63c32d4bda4 100644 --- a/src/solvers/prop/prop_assignment.h +++ b/src/solvers/prop/prop_assignment.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_PROP_PROP_ASSIGNMENT_H #define CPROVER_SOLVERS_PROP_PROP_ASSIGNMENT_H diff --git a/src/solvers/prop/prop_conv.cpp b/src/solvers/prop/prop_conv.cpp index 33a572191c0..734d11a6806 100644 --- a/src/solvers/prop/prop_conv.cpp +++ b/src/solvers/prop/prop_conv.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "prop_conv.h" + #include #include #include @@ -15,73 +17,25 @@ Author: Daniel Kroening, kroening@kroening.com #include #include "prop.h" -#include "prop_conv.h" #include "literal_expr.h" -/*******************************************************************\ - -Function: prop_convt::is_in_conflict - - Inputs: - - Outputs: - - Purpose: determine whether a variable is in the final conflict - -\*******************************************************************/ - +/// determine whether a variable is in the final conflict bool prop_convt::is_in_conflict(literalt l) const { assert(false); return false; } -/*******************************************************************\ - -Function: prop_convt::set_assumptions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void prop_convt::set_assumptions(const bvt &) { assert(false); } -/*******************************************************************\ - -Function: prop_convt::set_frozen - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void prop_convt::set_frozen(const literalt) { assert(false); } -/*******************************************************************\ - -Function: prop_convt::set_frozen - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void prop_convt::set_frozen(const bvt &bv) { for(unsigned i=0; i result= @@ -153,18 +83,7 @@ literalt prop_conv_solvert::get_literal(const irep_idt &identifier) return literal; } -/*******************************************************************\ - -Function: prop_conv_solvert::get_bool - - Inputs: - - Outputs: - - Purpose: get a boolean value from counter example if not valid - -\*******************************************************************/ - +/// get a boolean value from counter example if not valid bool prop_conv_solvert::get_bool(const exprt &expr, tvt &value) const { // trivial cases @@ -253,18 +172,6 @@ bool prop_conv_solvert::get_bool(const exprt &expr, tvt &value) const return false; } -/*******************************************************************\ - -Function: prop_conv_solvert::convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt prop_conv_solvert::convert(const exprt &expr) { if(!use_cache || @@ -293,24 +200,12 @@ literalt prop_conv_solvert::convert(const exprt &expr) prop.set_frozen(literal); #if 0 - std::cout << literal << "=" << expr << std::endl; + std::cout << literal << "=" << expr << '\n'; #endif return literal; } -/*******************************************************************\ - -Function: prop_conv_solvert::convert_bool - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt prop_conv_solvert::convert_bool(const exprt &expr) { if(expr.type().id()!=ID_bool) @@ -439,18 +334,6 @@ literalt prop_conv_solvert::convert_bool(const exprt &expr) return convert_rest(expr); } -/*******************************************************************\ - -Function: prop_conv_solvert::convert_rest - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt prop_conv_solvert::convert_rest(const exprt &expr) { // fall through @@ -458,18 +341,6 @@ literalt prop_conv_solvert::convert_rest(const exprt &expr) return prop.new_variable(); } -/*******************************************************************\ - -Function: prop_conv_solvert::set_equality_to_true - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool prop_conv_solvert::set_equality_to_true(const equal_exprt &expr) { if(!equality_propagation) @@ -497,18 +368,6 @@ bool prop_conv_solvert::set_equality_to_true(const equal_exprt &expr) return true; } -/*******************************************************************\ - -Function: prop_conv_solvert::set_to - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void prop_conv_solvert::set_to(const exprt &expr, bool value) { if(expr.type().id()!=ID_bool) @@ -556,7 +415,7 @@ void prop_conv_solvert::set_to(const exprt &expr, bool value) // Special case for a CNF-clause, // i.e., a constraint that's a disjunction. - if(expr.operands().size()>0) + if(!expr.operands().empty()) { bvt bv; bv.reserve(expr.operands().size()); @@ -608,91 +467,41 @@ void prop_conv_solvert::set_to(const exprt &expr, bool value) prop.l_set_to(convert(expr), value); } -/*******************************************************************\ - -Function: prop_conv_solvert::ignoring - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void prop_conv_solvert::ignoring(const exprt &expr) { // fall through - std::string msg="warning: ignoring "+expr.pretty(); - - print(2, msg); + warning() << "warning: ignoring " << expr.pretty() << eom; } -/*******************************************************************\ - -Function: prop_conv_solvert::post_process - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void prop_conv_solvert::post_process() { } -/*******************************************************************\ - -Function: prop_conv_solvert::solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - decision_proceduret::resultt prop_conv_solvert::dec_solve() { // post-processing isn't incremental yet if(!post_processing_done) { - print(8, "Post-processing"); + statistics() << "Post-processing" << eom; post_process(); post_processing_done=true; } - print(7, "Solving with "+prop.solver_text()); + statistics() << "Solving with " << prop.solver_text() << eom; propt::resultt result=prop.prop_solve(); switch(result) { - case propt::P_SATISFIABLE: return D_SATISFIABLE; - case propt::P_UNSATISFIABLE: return D_UNSATISFIABLE; - default: return D_ERROR; + case propt::resultt::P_SATISFIABLE: return resultt::D_SATISFIABLE; + case propt::resultt::P_UNSATISFIABLE: return resultt::D_UNSATISFIABLE; + default: return resultt::D_ERROR; } - return D_ERROR; + return resultt::D_ERROR; } -/*******************************************************************\ - -Function: prop_conv_solvert::get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt prop_conv_solvert::get(const exprt &expr) const { tvt value; @@ -719,18 +528,6 @@ exprt prop_conv_solvert::get(const exprt &expr) const return tmp; } -/*******************************************************************\ - -Function: prop_conv_solvert::print_assignment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void prop_conv_solvert::print_assignment(std::ostream &out) const { for(symbolst::const_iterator it=symbols.begin(); diff --git a/src/solvers/prop/prop_conv.h b/src/solvers/prop/prop_conv.h index 5f3cf35c2c8..9d59fb06cf5 100644 --- a/src/solvers/prop/prop_conv.h +++ b/src/solvers/prop/prop_conv.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_PROP_PROP_CONV_H #define CPROVER_SOLVERS_PROP_PROP_CONV_H diff --git a/src/solvers/prop/prop_conv_store.cpp b/src/solvers/prop/prop_conv_store.cpp index 19e290ce5ea..5ac16b8ff25 100644 --- a/src/solvers/prop/prop_conv_store.cpp +++ b/src/solvers/prop/prop_conv_store.cpp @@ -6,46 +6,22 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "prop_conv_store.h" -/*******************************************************************\ - -Function: prop_conv_storet::set_to - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void prop_conv_storet::set_to(const exprt &expr, bool value) { constraintt &constraint=constraints.add_constraint(); - constraint.type=constraintt::SET_TO; + constraint.type=constraintt::typet::SET_TO; constraint.expr=expr; constraint.value=value; } -/*******************************************************************\ - -Function: prop_conv_storet::convert_rest - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt prop_conv_storet::convert(const exprt &expr) { constraintt &constraint=constraints.add_constraint(); - constraint.type=constraintt::CONVERT; + constraint.type=constraintt::typet::CONVERT; constraint.expr=expr; #if 0 constraint.literal=prop.new_variable(); @@ -53,18 +29,6 @@ literalt prop_conv_storet::convert(const exprt &expr) return constraint.literal; } -/*******************************************************************\ - -Function: prop_conv_storet::constraintst::replay - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void prop_conv_storet::constraintst::replay(prop_convt &dest) const { for(constraint_listt::const_iterator @@ -74,18 +38,6 @@ void prop_conv_storet::constraintst::replay(prop_convt &dest) const it->replay(dest); } -/*******************************************************************\ - -Function: prop_conv_storet::constraintst::print - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void prop_conv_storet::constraintst::print(std::ostream &out) const { for(constraint_listt::const_iterator @@ -95,27 +47,15 @@ void prop_conv_storet::constraintst::print(std::ostream &out) const it->print(out); } -/*******************************************************************\ - -Function: prop_conv_storet::constraintt::replay - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void prop_conv_storet::constraintt::replay(prop_convt &dest) const { switch(type) { - case SET_TO: + case typet::SET_TO: dest.set_to(expr, value); break; - case CONVERT: + case typet::CONVERT: // dest.prop.set_equal(dest.convert_rest(expr), literal); break; @@ -124,28 +64,16 @@ void prop_conv_storet::constraintt::replay(prop_convt &dest) const } } -/*******************************************************************\ - -Function: prop_conv_storet::constraintt::print - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void prop_conv_storet::constraintt::print(std::ostream &out) const { switch(type) { - case SET_TO: + case typet::SET_TO: out << "SET_TO " << (value?"TRUE":"FALSE") << ": "; out << expr.pretty() << "\n"; break; - case CONVERT: + case typet::CONVERT: out << "CONVERT(" << literal.dimacs() << "): "; out << expr.pretty() << "\n"; break; diff --git a/src/solvers/prop/prop_conv_store.h b/src/solvers/prop/prop_conv_store.h index 74ee286926d..334b191949c 100644 --- a/src/solvers/prop/prop_conv_store.h +++ b/src/solvers/prop/prop_conv_store.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_PROP_PROP_CONV_STORE_H #define CPROVER_SOLVERS_PROP_PROP_CONV_STORE_H @@ -20,7 +21,7 @@ class prop_conv_storet:public prop_convt struct constraintt { - typedef enum { NONE, CONVERT, SET_TO } typet; + enum class typet { NONE, CONVERT, SET_TO }; typet type; exprt expr; diff --git a/src/solvers/prop/prop_wrapper.h b/src/solvers/prop/prop_wrapper.h index d21b2e85a4e..3cbff0b0835 100644 --- a/src/solvers/prop/prop_wrapper.h +++ b/src/solvers/prop/prop_wrapper.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_PROP_PROP_WRAPPER_H #define CPROVER_SOLVERS_PROP_PROP_WRAPPER_H diff --git a/src/solvers/qbf/qbf_bdd_core.cpp b/src/solvers/qbf/qbf_bdd_core.cpp index 9fa58639ad0..d0bef9244c7 100644 --- a/src/solvers/qbf/qbf_bdd_core.cpp +++ b/src/solvers/qbf/qbf_bdd_core.cpp @@ -6,6 +6,8 @@ Author: CM Wintersteiger \*******************************************************************/ +#include + #include #include @@ -14,25 +16,11 @@ Author: CM Wintersteiger #include -#include - #include // CUDD Library /*! \cond */ // FIX FOR THE CUDD LIBRARY -/*******************************************************************\ - -Function: DD::getNode - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - inline DdNode *DD::getNode() const { return node; @@ -42,35 +30,11 @@ inline DdNode *DD::getNode() const #include "qbf_bdd_core.h" -/*******************************************************************\ - -Function: qbf_bdd_certificatet::qbf_bdd_certificatet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - qbf_bdd_certificatet::qbf_bdd_certificatet(void) : qdimacs_coret() { bdd_manager=new Cudd(0, 0); } -/*******************************************************************\ - -Function: qbf_bdd_certificatet::~qbf_bdd_certificatet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - qbf_bdd_certificatet::~qbf_bdd_certificatet(void) { for(const BDD* model : model_bdds) @@ -84,18 +48,6 @@ qbf_bdd_certificatet::~qbf_bdd_certificatet(void) bdd_manager=NULL; } -/*******************************************************************\ - -Function: qbf_bdd_certificatet::new_variable - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt qbf_bdd_certificatet::new_variable(void) { literalt l=qdimacs_coret::new_variable(); @@ -106,36 +58,12 @@ literalt qbf_bdd_certificatet::new_variable(void) return l; } -/*******************************************************************\ - -Function: qbf_bdd_coret::qbf_bdd_coret - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - qbf_bdd_coret::qbf_bdd_coret() : qbf_bdd_certificatet() { matrix=new BDD(); *matrix=bdd_manager->bddOne(); } -/*******************************************************************\ - -Function: qbf_bdd_coret::~qbf_bdd_coret - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - qbf_bdd_coret::~qbf_bdd_coret() { for(const BDD* variable : bdd_variable_map) @@ -152,53 +80,17 @@ qbf_bdd_coret::~qbf_bdd_coret() } } -/*******************************************************************\ - -Function: qbf_bdd_coret::l_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt qbf_bdd_coret::l_get(literalt a) const { assert(false); return tvt(false); } -/*******************************************************************\ - -Function: qbf_bdd_coret::solver_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::string qbf_bdd_coret::solver_text() { return "QBF/BDD/CORE"; } -/*******************************************************************\ - -Function: qbf_bdd_coret::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - propt::resultt qbf_bdd_coret::prop_solve() { { @@ -220,7 +112,7 @@ propt::resultt qbf_bdd_coret::prop_solve() { #if 0 std::cout << "BDD E: " << var << ", " << - matrix->nodeCount() << " nodes" << std::endl; + matrix->nodeCount() << " nodes\n"; #endif BDD *model=new BDD(); @@ -236,7 +128,7 @@ propt::resultt qbf_bdd_coret::prop_solve() { #if 0 std::cout << "BDD A: " << var << ", " << - matrix->nodeCount() << " nodes" << std::endl; + matrix->nodeCount() << " nodes\n"; #endif *matrix=matrix->UnivAbstract(*bdd_variable_map[var]); @@ -259,52 +151,16 @@ propt::resultt qbf_bdd_coret::prop_solve() return P_ERROR; } -/*******************************************************************\ - -Function: qbf_bdd_coret::is_in_core - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool qbf_bdd_coret::is_in_core(literalt l) const { throw "nyi"; } -/*******************************************************************\ - -Function: qbf_bdd_coret::m_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - qdimacs_coret::modeltypet qbf_bdd_coret::m_get(literalt a) const { throw "nyi"; } -/*******************************************************************\ - -Function: qbf_bdd_coret::new_variable - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt qbf_bdd_coret::new_variable() { literalt res=qbf_bdd_certificatet::new_variable(); @@ -317,18 +173,6 @@ literalt qbf_bdd_coret::new_variable() return res; } -/*******************************************************************\ - -Function: qbf_bdd_coret::lcnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void qbf_bdd_coret::lcnf(const bvt &bv) { bvt new_bv; @@ -351,18 +195,6 @@ void qbf_bdd_coret::lcnf(const bvt &bv) *matrix&=clause; } -/*******************************************************************\ - -Function: qbf_bdd_coret::lor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt qbf_bdd_coret::lor(literalt a, literalt b) { literalt nl=new_variable(); @@ -380,18 +212,6 @@ literalt qbf_bdd_coret::lor(literalt a, literalt b) return nl; } -/*******************************************************************\ - -Function: qbf_bdd_coret::lor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt qbf_bdd_coret::lor(const bvt &bv) { for(const literalt &literal : bv) @@ -419,18 +239,6 @@ literalt qbf_bdd_coret::lor(const bvt &bv) return nl; } -/*******************************************************************\ - -Function: qbf_bdd_coret::compress_certificate - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void qbf_bdd_coret::compress_certificate(void) { status() << "Compressing Certificate" << eom; @@ -459,18 +267,6 @@ void qbf_bdd_coret::compress_certificate(void) } } -/*******************************************************************\ - -Function: qbf_bdd_certificatet::f_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const exprt qbf_bdd_certificatet::f_get(literalt l) { quantifiert q; @@ -510,7 +306,7 @@ const exprt qbf_bdd_certificatet::f_get(literalt l) if(it!=function_cache.end()) { #if 0 - std::cout << "CACHE HIT for " << l.dimacs() << std::endl; + std::cout << "CACHE HIT for " << l.dimacs() << '\n'; #endif if(l.sign()) @@ -525,7 +321,7 @@ const exprt qbf_bdd_certificatet::f_get(literalt l) BDD &model=*model_bdds[l.var_no()]; #if 0 - std::cout << "Model " << l.var_no() << std::endl; + std::cout << "Model " << l.var_no() << '\n'; model.PrintMinterm(); #endif @@ -547,7 +343,7 @@ const exprt qbf_bdd_certificatet::f_get(literalt l) std::cout << "CUBE: "; for(signed i=0; iReadSize(); i++) std::cout << cube[i]; - std::cout << std::endl; + std::cout << '\n'; #endif for(signed i=0; iReadSize(); i++) @@ -592,18 +388,6 @@ const exprt qbf_bdd_certificatet::f_get(literalt l) } } -/*******************************************************************\ - -Function: qbf_bdd_certificatet::l_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt qbf_bdd_certificatet::l_get(literalt a) const { const BDD &model=*model_bdds[a.var_no()]; diff --git a/src/solvers/qbf/qbf_bdd_core.h b/src/solvers/qbf/qbf_bdd_core.h index 4c9d3e6fd2d..d309bf143c2 100644 --- a/src/solvers/qbf/qbf_bdd_core.h +++ b/src/solvers/qbf/qbf_bdd_core.h @@ -6,6 +6,7 @@ Author: CM Wintersteiger \*******************************************************************/ + #ifndef CPROVER_SOLVERS_QBF_QBF_BDD_CORE_H #define CPROVER_SOLVERS_QBF_QBF_BDD_CORE_H diff --git a/src/solvers/qbf/qbf_core.h b/src/solvers/qbf/qbf_core.h index 79758f83daa..9a214441a77 100644 --- a/src/solvers/qbf/qbf_core.h +++ b/src/solvers/qbf/qbf_core.h @@ -7,6 +7,7 @@ Author: Daniel Kroening, kroening@kroening.com, \*******************************************************************/ + #ifndef CPROVER_SOLVERS_QBF_QBF_CORE_H #define CPROVER_SOLVERS_QBF_QBF_CORE_H diff --git a/src/solvers/qbf/qbf_quantor.cpp b/src/solvers/qbf/qbf_quantor.cpp index 27ecdf95920..ab187e20ada 100644 --- a/src/solvers/qbf/qbf_quantor.cpp +++ b/src/solvers/qbf/qbf_quantor.cpp @@ -6,91 +6,31 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "qbf_quantor.h" + #include #include #include -#include "qbf_quantor.h" - -/*******************************************************************\ - -Function: qbf_quantort::qbf_quantort - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - qbf_quantort::qbf_quantort() { } -/*******************************************************************\ - -Function: qbf_quantort::~qbf_quantort - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - qbf_quantort::~qbf_quantort() { } -/*******************************************************************\ - -Function: qbf_quantort::l_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt qbf_quantort::l_get(literalt a) const { assert(false); return tvt::unknown(); } -/*******************************************************************\ - -Function: qbf_quantort::solver_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::string qbf_quantort::solver_text() { return "Quantor"; } -/*******************************************************************\ - -Function: qbf_quantort::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - propt::resultt qbf_quantort::prop_solve() { { @@ -148,20 +88,20 @@ propt::resultt qbf_quantort::prop_solve() if(!result_found) { messaget::error() << "Quantor failed: unknown result" << eom; - return P_ERROR; + return resultt::P_ERROR; } } if(result) { messaget::status() << "Quantor: TRUE" << eom; - return P_SATISFIABLE; + return resultt::P_SATISFIABLE; } else { messaget::status() << "Quantor: FALSE" << eom; - return P_UNSATISFIABLE; + return resultt::P_UNSATISFIABLE; } - return P_ERROR; + return resultt::P_ERROR; } diff --git a/src/solvers/qbf/qbf_quantor.h b/src/solvers/qbf/qbf_quantor.h index e5f302fbea8..a6b8ec05d66 100644 --- a/src/solvers/qbf/qbf_quantor.h +++ b/src/solvers/qbf/qbf_quantor.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_QBF_QBF_QUANTOR_H #define CPROVER_SOLVERS_QBF_QBF_QUANTOR_H diff --git a/src/solvers/qbf/qbf_qube.cpp b/src/solvers/qbf/qbf_qube.cpp index f32d77d3370..9953fbc922b 100644 --- a/src/solvers/qbf/qbf_qube.cpp +++ b/src/solvers/qbf/qbf_qube.cpp @@ -6,98 +6,38 @@ Author: CM Wintersteiger \*******************************************************************/ +#include "qbf_qube.h" + #include #include #include -#include "qbf_qube.h" - -/*******************************************************************\ - -Function: qbf_qubet::qbf_qubet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - qbf_qubet::qbf_qubet() { // skizzo crashes on broken lines break_lines=false; } -/*******************************************************************\ - -Function: qbf_qubet::~qbf_qubet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - qbf_qubet::~qbf_qubet() { } -/*******************************************************************\ - -Function: qbf_qubet::l_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt qbf_qubet::l_get(literalt a) const { assert(false); return tvt(false); } -/*******************************************************************\ - -Function: qbf_qubet::solver_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::string qbf_qubet::solver_text() { return "QuBE"; } -/*******************************************************************\ - -Function: qbf_qubet::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - propt::resultt qbf_qubet::prop_solve() { // sKizzo crashes on empty instances if(no_clauses()==0) - return P_SATISFIABLE; + return resultt::P_SATISFIABLE; { messaget::status() << @@ -156,20 +96,20 @@ propt::resultt qbf_qubet::prop_solve() if(!result_found) { messaget::error() << "QuBE failed: unknown result" << eom; - return P_ERROR; + return resultt::P_ERROR; } } if(result) { messaget::status() << "QuBE: TRUE" << eom; - return P_SATISFIABLE; + return resultt::P_SATISFIABLE; } else { messaget::status() << "QuBE: FALSE" << eom; - return P_UNSATISFIABLE; + return resultt::P_UNSATISFIABLE; } - return P_ERROR; + return resultt::P_ERROR; } diff --git a/src/solvers/qbf/qbf_qube.h b/src/solvers/qbf/qbf_qube.h index 10331e09fee..062e664cb48 100644 --- a/src/solvers/qbf/qbf_qube.h +++ b/src/solvers/qbf/qbf_qube.h @@ -6,6 +6,7 @@ Author: CM Wintersteiger \*******************************************************************/ + #ifndef CPROVER_SOLVERS_QBF_QBF_QUBE_H #define CPROVER_SOLVERS_QBF_QBF_QUBE_H diff --git a/src/solvers/qbf/qbf_qube_core.cpp b/src/solvers/qbf/qbf_qube_core.cpp index e9593a1702e..e14dda75f60 100644 --- a/src/solvers/qbf/qbf_qube_core.cpp +++ b/src/solvers/qbf/qbf_qube_core.cpp @@ -6,81 +6,34 @@ Author: CM Wintersteiger \*******************************************************************/ +#include "qbf_qube_core.h" + #include #include #include +#include #include -#include "qbf_qube_core.h" - -/*******************************************************************\ - -Function: qbf_qube_coret::qbf_qube_coret - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - qbf_qube_coret::qbf_qube_coret() : qdimacs_coret() { break_lines=false; qbf_tmp_file="qube.qdimacs"; } -/*******************************************************************\ - -Function: qbf_qube_coret::~qbf_qube_coret - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - qbf_qube_coret::~qbf_qube_coret() { } -/*******************************************************************\ - -Function: qbf_qube_coret::solver_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::string qbf_qube_coret::solver_text() { return "QuBE w/ toplevel assignments"; } -/*******************************************************************\ - -Function: qbf_qube_coret::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - propt::resultt qbf_qube_coret::prop_solve() { if(no_clauses()==0) - return P_SATISFIABLE; + return resultt::P_SATISFIABLE; { messaget::status() << "QuBE: " @@ -146,54 +99,41 @@ propt::resultt qbf_qube_coret::prop_solve() if(!result_found) { messaget::error() << "QuBE failed: unknown result" << eom; - return P_ERROR; + return resultt::P_ERROR; } } - remove(result_tmp_file.c_str()); - remove(qbf_tmp_file.c_str()); + int remove_result=remove(result_tmp_file.c_str()); + if(remove_result!=0) + { + messaget::error() << "Remove failed: " << std::strerror(errno) << eom; + return resultt::P_ERROR; + } + + remove_result=remove(qbf_tmp_file.c_str()); + if(remove_result!=0) + { + messaget::error() << "Remove failed: " << std::strerror(errno) << eom; + return resultt::P_ERROR; + } if(result) { messaget::status() << "QuBE: TRUE" << eom; - return P_SATISFIABLE; + return resultt::P_SATISFIABLE; } else { messaget::status() << "QuBE: FALSE" << eom; - return P_UNSATISFIABLE; + return resultt::P_UNSATISFIABLE; } } -/*******************************************************************\ - -Function: qbf_qube_coret::is_in_core - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool qbf_qube_coret::is_in_core(literalt l) const { throw "not supported"; } -/*******************************************************************\ - -Function: qbf_qube_coret::m_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - qdimacs_coret::modeltypet qbf_qube_coret::m_get(literalt a) const { throw "not supported"; diff --git a/src/solvers/qbf/qbf_qube_core.h b/src/solvers/qbf/qbf_qube_core.h index 348d9492015..29d68088e5c 100644 --- a/src/solvers/qbf/qbf_qube_core.h +++ b/src/solvers/qbf/qbf_qube_core.h @@ -6,6 +6,7 @@ Author: CM Wintersteiger \*******************************************************************/ + #ifndef CPROVER_SOLVERS_QBF_QBF_QUBE_CORE_H #define CPROVER_SOLVERS_QBF_QBF_QUBE_CORE_H diff --git a/src/solvers/qbf/qbf_skizzo.cpp b/src/solvers/qbf/qbf_skizzo.cpp index 27837ef57b8..55813caf564 100644 --- a/src/solvers/qbf/qbf_skizzo.cpp +++ b/src/solvers/qbf/qbf_skizzo.cpp @@ -6,98 +6,38 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "qbf_skizzo.h" + #include #include #include -#include "qbf_skizzo.h" - -/*******************************************************************\ - -Function: qbf_skizzot::qbf_skizzot - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - qbf_skizzot::qbf_skizzot() { // skizzo crashes on broken lines break_lines=false; } -/*******************************************************************\ - -Function: qbf_skizzot::~qbf_skizzot - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - qbf_skizzot::~qbf_skizzot() { } -/*******************************************************************\ - -Function: qbf_skizzot::l_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt qbf_skizzot::l_get(literalt a) const { assert(false); return tvt(false); } -/*******************************************************************\ - -Function: qbf_skizzot::solver_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::string qbf_skizzot::solver_text() { return "Skizzo"; } -/*******************************************************************\ - -Function: qbf_skizzot::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - propt::resultt qbf_skizzot::prop_solve() { // sKizzo crashes on empty instances if(no_clauses()==0) - return P_SATISFIABLE; + return resultt::P_SATISFIABLE; { messaget::status() << @@ -156,20 +96,20 @@ propt::resultt qbf_skizzot::prop_solve() if(!result_found) { messaget::error() << "Skizzo failed: unknown result" << eom; - return P_ERROR; + return resultt::P_ERROR; } } if(result) { messaget::status() << "Skizzo: TRUE" << eom; - return P_SATISFIABLE; + return resultt::P_SATISFIABLE; } else { messaget::status() << "Skizzo: FALSE" << eom; - return P_UNSATISFIABLE; + return resultt::P_UNSATISFIABLE; } - return P_ERROR; + return resultt::P_ERROR; } diff --git a/src/solvers/qbf/qbf_skizzo.h b/src/solvers/qbf/qbf_skizzo.h index bfc21ca4d43..62bf604582e 100644 --- a/src/solvers/qbf/qbf_skizzo.h +++ b/src/solvers/qbf/qbf_skizzo.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_QBF_QBF_SKIZZO_H #define CPROVER_SOLVERS_QBF_QBF_SKIZZO_H diff --git a/src/solvers/qbf/qbf_skizzo_core.cpp b/src/solvers/qbf/qbf_skizzo_core.cpp index 0b79ca216a6..5940347d43a 100644 --- a/src/solvers/qbf/qbf_skizzo_core.cpp +++ b/src/solvers/qbf/qbf_skizzo_core.cpp @@ -6,6 +6,7 @@ Author: CM Wintersteiger \*******************************************************************/ + #include #include @@ -16,18 +17,6 @@ Author: CM Wintersteiger /*! \cond */ // FIX FOR THE CUDD LIBRARY -/*******************************************************************\ - -Function: DD::getNode - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - inline DdNode *DD::getNode() const { return node; @@ -38,18 +27,6 @@ inline DdNode *DD::getNode() const #include "qbf_skizzo_core.h" -/*******************************************************************\ - -Function: qbf_skizzo_coret::qbf_skizzo_coret - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - qbf_skizzo_coret::qbf_skizzo_coret(): qbf_bdd_certificatet() { @@ -58,51 +35,15 @@ qbf_skizzo_coret::qbf_skizzo_coret(): qbf_tmp_file="sKizzo.qdimacs"; } -/*******************************************************************\ - -Function: qbf_skizzo_coret::~qbf_skizzo_coret - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - qbf_skizzo_coret::~qbf_skizzo_coret() { } -/*******************************************************************\ - -Function: qbf_skizzo_coret::solver_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::string qbf_skizzo_coret::solver_text() { return "Skizzo/Core"; } -/*******************************************************************\ - -Function: qbf_skizzo_coret::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - propt::resultt qbf_skizzo_coret::prop_solve() { // sKizzo crashes on empty instances @@ -189,52 +130,16 @@ propt::resultt qbf_skizzo_coret::prop_solve() } } -/*******************************************************************\ - -Function: qbf_skizzo_coret::is_in_core - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool qbf_skizzo_coret::is_in_core(literalt l) const { throw "nyi"; } -/*******************************************************************\ - -Function: qbf_skizzo_coret::m_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - qdimacs_coret::modeltypet qbf_skizzo_coret::m_get(literalt a) const { throw "nyi"; } -/*******************************************************************\ - -Function: qbf_skizzo_coret::get_certificate - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool qbf_skizzo_coret::get_certificate(void) { std::string result_tmp_file="ozziKs.out"; diff --git a/src/solvers/qbf/qbf_skizzo_core.h b/src/solvers/qbf/qbf_skizzo_core.h index 6ffa06c9c84..28a42d5f5d6 100644 --- a/src/solvers/qbf/qbf_skizzo_core.h +++ b/src/solvers/qbf/qbf_skizzo_core.h @@ -6,6 +6,7 @@ Author: CM Wintersteiger \*******************************************************************/ + #ifndef CPROVER_SOLVERS_QBF_QBF_SKIZZO_CORE_H #define CPROVER_SOLVERS_QBF_QBF_SKIZZO_CORE_H diff --git a/src/solvers/qbf/qbf_squolem.cpp b/src/solvers/qbf/qbf_squolem.cpp index a869603a737..97ab3ebb5ed 100644 --- a/src/solvers/qbf/qbf_squolem.cpp +++ b/src/solvers/qbf/qbf_squolem.cpp @@ -6,89 +6,31 @@ Author: CM Wintersteiger \*******************************************************************/ +/// \file +/// Squolem Backend #include "qbf_squolem.h" -/*******************************************************************\ - -Function: qbf_squolemt::qbf_squolemt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - qbf_squolemt::qbf_squolemt(): early_decision(false) { } -/*******************************************************************\ - -Function: qbf_squolemt::~qbf_squolemt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - qbf_squolemt::~qbf_squolemt() { squolem.reset(); } -/*******************************************************************\ - -Function: qbf_squolemt::l_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt qbf_squolemt::l_get(literalt a) const { assert(false); } -/*******************************************************************\ - -Function: qbf_squolemt::solver_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::string qbf_squolemt::solver_text() { return "Squolem"; } -/*******************************************************************\ - -Function: qbf_squolemt::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - propt::resultt qbf_squolemt::prop_solve() { { @@ -126,18 +68,6 @@ propt::resultt qbf_squolemt::prop_solve() return P_ERROR; } -/*******************************************************************\ - -Function: qbf_squolemt::lcnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void qbf_squolemt::lcnf(const bvt &bv) { if(early_decision) @@ -167,18 +97,6 @@ void qbf_squolemt::lcnf(const bvt &bv) early_decision=true; } -/*******************************************************************\ - -Function: qbf_squolemt::add_quantifier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void qbf_squolemt::add_quantifier(const quantifiert &quantifier) { squolem.quantifyVariableInner( @@ -188,36 +106,12 @@ void qbf_squolemt::add_quantifier(const quantifiert &quantifier) qdimacs_cnft::add_quantifier(quantifier); // necessary? } -/*******************************************************************\ - -Function: qbf_squolemt::set_no_variables - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void qbf_squolemt::set_no_variables(unsigned no) { squolem.setLastVariable(no+1); cnft::set_no_variables(no); } -/*******************************************************************\ - -Function: qbf_squolemt::set_quantifier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void qbf_squolemt::set_quantifier( const quantifiert::typet type, const literalt l) diff --git a/src/solvers/qbf/qbf_squolem.h b/src/solvers/qbf/qbf_squolem.h index 1780528fb32..7210436fd4c 100644 --- a/src/solvers/qbf/qbf_squolem.h +++ b/src/solvers/qbf/qbf_squolem.h @@ -6,6 +6,9 @@ Author: CM Wintersteiger \*******************************************************************/ +/// \file +/// Squolem Backend + #ifndef CPROVER_SOLVERS_QBF_QBF_SQUOLEM_H #define CPROVER_SOLVERS_QBF_QBF_SQUOLEM_H diff --git a/src/solvers/qbf/qbf_squolem_core.cpp b/src/solvers/qbf/qbf_squolem_core.cpp index 00229cd8fee..04f5c7ae3c6 100644 --- a/src/solvers/qbf/qbf_squolem_core.cpp +++ b/src/solvers/qbf/qbf_squolem_core.cpp @@ -6,44 +6,23 @@ Author: CM Wintersteiger \*******************************************************************/ -#include - -#include -#include - -#include // uint type for indices +/// \file +/// Squolem Backend (with proofs) #include "qbf_squolem_core.h" -/*******************************************************************\ - -Function: qbf_squolem_coret::qbf_squolem_coret - - Inputs: - - Outputs: +#include - Purpose: +#include +#include -\*******************************************************************/ +#include // uint type for indices qbf_squolem_coret::qbf_squolem_coret() : squolem(NULL) { setup(); } -/*******************************************************************\ - -Function: qbf_squolem_coret::setup - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void qbf_squolem_coret::setup(void) { quantifiers.clear(); @@ -65,18 +44,6 @@ void qbf_squolem_coret::setup(void) // squolem->options.set_predictOnLiteralBound(true); } -/*******************************************************************\ - -Function: qbf_squolem_coret::reset - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void qbf_squolem_coret::reset(void) { squolem->reset(); @@ -85,18 +52,6 @@ void qbf_squolem_coret::reset(void) setup(); } -/*******************************************************************\ - -Function: qbf_squolem_coret::~qbf_squolem_coret - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - qbf_squolem_coret::~qbf_squolem_coret() { squolem->reset(); @@ -104,18 +59,6 @@ qbf_squolem_coret::~qbf_squolem_coret() squolem=NULL; } -/*******************************************************************\ - -Function: qbf_squolem_coret::l_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt qbf_squolem_coret::l_get(literalt a) const { if(a.is_true()) @@ -131,35 +74,11 @@ tvt qbf_squolem_coret::l_get(literalt a) const return tvt(tvt::tv_enumt::TV_UNKNOWN); } -/*******************************************************************\ - -Function: qbf_squolem_coret::solver_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::string qbf_squolem_coret::solver_text() { return "Squolem (Certifying)"; } -/*******************************************************************\ - -Function: qbf_squolem_coret::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - propt::resultt qbf_squolem_coret::prop_solve() { { @@ -187,35 +106,11 @@ propt::resultt qbf_squolem_coret::prop_solve() return P_ERROR; } -/*******************************************************************\ - -Function: qbf_squolem_coret::is_in_core - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool qbf_squolem_coret::is_in_core(literalt l) const { return squolem->inCore(l.var_no()); } -/*******************************************************************\ - -Function: qbf_squolem_coret::m_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - qbf_squolem_coret::modeltypet qbf_squolem_coret::m_get(literalt a) const { if(squolem->modelIsTrue(a.var_no())) @@ -228,18 +123,6 @@ qbf_squolem_coret::modeltypet qbf_squolem_coret::m_get(literalt a) const return M_DONTCARE; } -/*******************************************************************\ - -Function: qbf_squolem_coret::lcnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void qbf_squolem_coret::lcnf(const bvt &bv) { if(early_decision) @@ -269,18 +152,6 @@ void qbf_squolem_coret::lcnf(const bvt &bv) early_decision=true; } -/*******************************************************************\ - -Function: qbf_squolem_coret::add_quantifier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void qbf_squolem_coret::add_quantifier(const quantifiert &quantifier) { squolem->quantifyVariableInner( @@ -290,36 +161,12 @@ void qbf_squolem_coret::add_quantifier(const quantifiert &quantifier) qdimacs_cnft::add_quantifier(quantifier); // necessary? } -/*******************************************************************\ - -Function: qbf_squolem_coret::set_no_variables - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void qbf_squolem_coret::set_no_variables(unsigned no) { squolem->setLastVariable(no+1); cnft::set_no_variables(no); } -/*******************************************************************\ - -Function: qbf_squolem_coret::set_quantifier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void qbf_squolem_coret::set_quantifier( const quantifiert::typet type, const literalt l) @@ -328,52 +175,16 @@ void qbf_squolem_coret::set_quantifier( squolem->requantifyVariable(l.var_no(), type==quantifiert::UNIVERSAL); } -/*******************************************************************\ - -Function: qbf_squolem_coret::set_debug_filename - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void qbf_squolem_coret::set_debug_filename(const std::string &str) { squolem->options.set_debugFilename(str.c_str()); } -/*******************************************************************\ - -Function: qbf_squolem_coret::write_qdimacs_cnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void qbf_squolem_coret::write_qdimacs_cnf(std::ostream &out) { squolem->saveQCNF(out); } -/*******************************************************************\ - -Function: qbf_squolem_coret::f_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const exprt qbf_squolem_coret::f_get(literalt l) { if(squolem->isUniversal(l.var_no())) @@ -403,7 +214,7 @@ const exprt qbf_squolem_coret::f_get(literalt l) if(it!=function_cache.end()) { #if 0 - std::cout << "CACHE HIT for " << l.dimacs() << std::endl; + std::cout << "CACHE HIT for " << l.dimacs() << '\n'; #endif if(l.sign()) @@ -435,18 +246,6 @@ const exprt qbf_squolem_coret::f_get(literalt l) } } -/*******************************************************************\ - -Function: qbf_squolem_coret::f_get_cnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const exprt qbf_squolem_coret::f_get_cnf(WitnessStack *wsp) { Clause *p=wsp->negWits; @@ -478,7 +277,7 @@ const exprt qbf_squolem_coret::f_get_cnf(WitnessStack *wsp) } #if 0 - std::cout << "CLAUSE: " << clause << std::endl; + std::cout << "CLAUSE: " << clause << '\n'; #endif operands.push_back(clause); @@ -489,18 +288,6 @@ const exprt qbf_squolem_coret::f_get_cnf(WitnessStack *wsp) return and_exprt(operands); } -/*******************************************************************\ - -Function: qbf_squolem_coret::f_get_dnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const exprt qbf_squolem_coret::f_get_dnf(WitnessStack *wsp) { Clause *p=wsp->posWits; @@ -534,7 +321,7 @@ const exprt qbf_squolem_coret::f_get_dnf(WitnessStack *wsp) } #if 0 - std::cout << "CUBE: " << cube << std::endl; + std::cout << "CUBE: " << cube << '\n'; #endif operands.push_back(cube); diff --git a/src/solvers/qbf/qbf_squolem_core.h b/src/solvers/qbf/qbf_squolem_core.h index 3c6e96252b4..f00e00a79ac 100644 --- a/src/solvers/qbf/qbf_squolem_core.h +++ b/src/solvers/qbf/qbf_squolem_core.h @@ -6,6 +6,9 @@ Author: CM Wintersteiger \*******************************************************************/ +/// \file +/// Squolem Backend (with Proofs) + #ifndef CPROVER_SOLVERS_QBF_QBF_SQUOLEM_CORE_H #define CPROVER_SOLVERS_QBF_QBF_SQUOLEM_CORE_H diff --git a/src/solvers/qbf/qdimacs_cnf.cpp b/src/solvers/qbf/qdimacs_cnf.cpp index 380f31ec12a..11638606d65 100644 --- a/src/solvers/qbf/qdimacs_cnf.cpp +++ b/src/solvers/qbf/qdimacs_cnf.cpp @@ -6,22 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include -#include - #include "qdimacs_cnf.h" -/*******************************************************************\ - -Function: qdimacs_cnft::write_qdimacs_cnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include void qdimacs_cnft::write_qdimacs_cnf(std::ostream &out) { @@ -30,18 +18,6 @@ void qdimacs_cnft::write_qdimacs_cnf(std::ostream &out) write_clauses(out); } -/*******************************************************************\ - -Function: qdimacs_cnft::write_prefix - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void qdimacs_cnft::write_prefix(std::ostream &out) const { std::vector quantified; @@ -62,11 +38,11 @@ void qdimacs_cnft::write_prefix(std::ostream &out) const switch(quantifier.type) { - case quantifiert::UNIVERSAL: + case quantifiert::typet::UNIVERSAL: out << "a"; break; - case quantifiert::EXISTENTIAL: + case quantifiert::typet::EXISTENTIAL: out << "e"; break; @@ -74,7 +50,7 @@ void qdimacs_cnft::write_prefix(std::ostream &out) const assert(false); } - out << " " << quantifier.var_no << " 0" << std::endl; + out << " " << quantifier.var_no << " 0\n"; } // variables that are not quantified @@ -82,38 +58,14 @@ void qdimacs_cnft::write_prefix(std::ostream &out) const for(std::size_t i=1; i(type)<<24); } }; @@ -71,12 +72,12 @@ class qdimacs_cnft:public dimacs_cnft void add_existential_quantifier(const literalt l) { - add_quantifier(quantifiert(quantifiert::EXISTENTIAL, l)); + add_quantifier(quantifiert(quantifiert::typet::EXISTENTIAL, l)); } void add_universal_quantifier(const literalt l) { - add_quantifier(quantifiert(quantifiert::UNIVERSAL, l)); + add_quantifier(quantifiert(quantifiert::typet::UNIVERSAL, l)); } bool is_quantified(const literalt l) const; diff --git a/src/solvers/qbf/qdimacs_core.cpp b/src/solvers/qbf/qdimacs_core.cpp index 3ffb8ec6db2..e729d8ece58 100644 --- a/src/solvers/qbf/qdimacs_core.cpp +++ b/src/solvers/qbf/qdimacs_core.cpp @@ -6,22 +6,10 @@ Author: CM Wintersteiger \*******************************************************************/ -#include -#include - #include "qdimacs_core.h" -/*******************************************************************\ - -Function: qdimacs_coret::simplify_extractbits - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include void qdimacs_coret::simplify_extractbits(exprt &expr) const { @@ -75,7 +63,7 @@ void qdimacs_coret::simplify_extractbits(exprt &expr) const value_string[value.to_ulong()]='1'; #if 0 - std::cout << "[" << value << "]=1" << std::endl; + std::cout << "[" << value << "]=1\n"; #endif continue; @@ -100,7 +88,7 @@ void qdimacs_coret::simplify_extractbits(exprt &expr) const new_operands.push_back(equality_exprt(it->first, new_value)); #if 0 - std::cout << "FINAL: " << value_string << std::endl; + std::cout << "FINAL: " << value_string << '\n'; #endif expr.operands()=new_operands; diff --git a/src/solvers/qbf/qdimacs_core.h b/src/solvers/qbf/qdimacs_core.h index 4f4a7c70a18..5cb144585f2 100644 --- a/src/solvers/qbf/qdimacs_core.h +++ b/src/solvers/qbf/qdimacs_core.h @@ -6,6 +6,7 @@ Author: CM Wintersteiger \*******************************************************************/ + #ifndef CPROVER_SOLVERS_QBF_QDIMACS_CORE_H #define CPROVER_SOLVERS_QBF_QDIMACS_CORE_H @@ -21,7 +22,7 @@ class qdimacs_coret:public qdimacs_cnft virtual tvt l_get(literalt a) const=0; virtual bool is_in_core(literalt l) const=0; - typedef enum { M_TRUE, M_FALSE, M_DONTCARE, M_COMPLEX } modeltypet; + enum modeltypet { M_TRUE, M_FALSE, M_DONTCARE, M_COMPLEX }; virtual modeltypet m_get(literalt a) const=0; typedef std::pair symbol_mapt; diff --git a/src/solvers/refinement/bv_refinement.h b/src/solvers/refinement/bv_refinement.h index cc96bfccf45..d1e72e227b3 100644 --- a/src/solvers/refinement/bv_refinement.h +++ b/src/solvers/refinement/bv_refinement.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Abstraction Refinement Loop + #ifndef CPROVER_SOLVERS_REFINEMENT_BV_REFINEMENT_H #define CPROVER_SOLVERS_REFINEMENT_BV_REFINEMENT_H @@ -48,7 +51,11 @@ class bv_refinementt:public bv_pointerst struct approximationt { public: - explicit approximationt(std::size_t _id_nr):id_nr(_id_nr) + explicit approximationt(std::size_t _id_nr): + no_operands(0), + under_state(0), + over_state(0), + id_nr(_id_nr) { } @@ -64,10 +71,6 @@ class bv_refinementt:public bv_pointerst // the kind of under- or over-approximation unsigned under_state, over_state; - approximationt():under_state(0), over_state(0) - { - } - std::string as_string() const; void add_over_assumption(literalt l); diff --git a/src/solvers/refinement/bv_refinement_loop.cpp b/src/solvers/refinement/bv_refinement_loop.cpp index 228de631637..2429cf2138d 100644 --- a/src/solvers/refinement/bv_refinement_loop.cpp +++ b/src/solvers/refinement/bv_refinement_loop.cpp @@ -6,30 +6,20 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - -#include - #include "bv_refinement.h" -/*******************************************************************\ - -Function: bv_refinementt::bv_refinementt - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include bv_refinementt::bv_refinementt( const namespacet &_ns, propt &_prop): bv_pointerst(_ns, _prop), max_node_refinement(5), do_array_refinement(true), - do_arithmetic_refinement(true) + do_arithmetic_refinement(true), + progress(false), + ui(ui_message_handlert::uit::PLAIN) { // check features we need assert(prop.has_set_assumptions()); @@ -37,34 +27,10 @@ bv_refinementt::bv_refinementt( assert(prop.has_is_in_conflict()); } -/*******************************************************************\ - -Function: bv_refinementt::~bv_refinementt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bv_refinementt::~bv_refinementt() { } -/*******************************************************************\ - -Function: bv_refinementt::dec_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - decision_proceduret::resultt bv_refinementt::dec_solve() { // do the usual post-processing @@ -83,7 +49,7 @@ decision_proceduret::resultt bv_refinementt::dec_solve() status() << "BV-Refinement: iteration " << iteration << eom; // output the very same information in a structured fashion - if(ui==ui_message_handlert::XML_UI) + if(ui==ui_message_handlert::uit::XML_UI) { xmlt xml("refinement-iteration"); xml.data=std::to_string(iteration); @@ -92,27 +58,27 @@ decision_proceduret::resultt bv_refinementt::dec_solve() switch(prop_solve()) { - case D_SATISFIABLE: + case resultt::D_SATISFIABLE: check_SAT(); if(!progress) { status() << "BV-Refinement: got SAT, and it simulates => SAT" << eom; status() << "Total iterations: " << iteration << eom; - return D_SATISFIABLE; + return resultt::D_SATISFIABLE; } else status() << "BV-Refinement: got SAT, and it is spurious, refining" << eom; break; - case D_UNSATISFIABLE: + case resultt::D_UNSATISFIABLE: check_UNSAT(); if(!progress) { status() << "BV-Refinement: got UNSAT, and the proof passes => UNSAT" << eom; status() << "Total iterations: " << iteration << eom; - return D_UNSATISFIABLE; + return resultt::D_UNSATISFIABLE; } else status() << "BV-Refinement: got UNSAT, and the proof fails, refining" @@ -120,23 +86,11 @@ decision_proceduret::resultt bv_refinementt::dec_solve() break; default: - return D_ERROR; + return resultt::D_ERROR; } } } -/*******************************************************************\ - -Function: bv_refinementt::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - decision_proceduret::resultt bv_refinementt::prop_solve() { // this puts the underapproximations into effect @@ -161,24 +115,12 @@ decision_proceduret::resultt bv_refinementt::prop_solve() switch(result) { - case propt::P_SATISFIABLE: return D_SATISFIABLE; - case propt::P_UNSATISFIABLE: return D_UNSATISFIABLE; - default: return D_ERROR; + case propt::resultt::P_SATISFIABLE: return resultt::D_SATISFIABLE; + case propt::resultt::P_UNSATISFIABLE: return resultt::D_UNSATISFIABLE; + default: return resultt::D_ERROR; } } -/*******************************************************************\ - -Function: bv_refinementt::check_SAT - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bv_refinementt::check_SAT() { progress=false; @@ -192,18 +134,6 @@ void bv_refinementt::check_SAT() check_SAT(*a_it); } -/*******************************************************************\ - -Function: bv_refinementt::check_UNSAT - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bv_refinementt::check_UNSAT() { progress=false; @@ -215,18 +145,6 @@ void bv_refinementt::check_UNSAT() check_UNSAT(*a_it); } -/*******************************************************************\ - -Function: bv_refinementt::set_to - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bv_refinementt::set_to(const exprt &expr, bool value) { #if 0 @@ -239,24 +157,12 @@ void bv_refinementt::set_to(const exprt &expr, bool value) if(expr.id()=="=" && expr.operands().size()==2) forall_operands(it, expr.op1()) std::cout << " " << it->id() << "@" << it->type().id(); - std::cout << std::endl; + std::cout << '\n'; #else SUB::set_to(expr, value); #endif } -/*******************************************************************\ - -Function: bv_refinementt::set_assumptions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bv_refinementt::set_assumptions(const bvt &_assumptions) { parent_assumptions=_assumptions; diff --git a/src/solvers/refinement/refine_arithmetic.cpp b/src/solvers/refinement/refine_arithmetic.cpp index 3c59537900b..f0be4a531bf 100644 --- a/src/solvers/refinement/refine_arithmetic.cpp +++ b/src/solvers/refinement/refine_arithmetic.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "bv_refinement.h" + #include #include #include @@ -15,24 +17,10 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "bv_refinement.h" - // Parameters #define MAX_INTEGER_UNDERAPPROX 3 #define MAX_FLOAT_UNDERAPPROX 10 -/*******************************************************************\ - -Function: bv_refinementt::approximationt::add_over_assumption - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bv_refinementt::approximationt::add_over_assumption(literalt l) { // if it's a constant already, give up @@ -40,18 +28,6 @@ void bv_refinementt::approximationt::add_over_assumption(literalt l) over_assumptions.push_back(l); } -/*******************************************************************\ - -Function: bv_refinementt::approximationt::add_under_assumption - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bv_refinementt::approximationt::add_under_assumption(literalt l) { // if it's a constant already, give up @@ -59,18 +35,6 @@ void bv_refinementt::approximationt::add_under_assumption(literalt l) under_assumptions.push_back(l); } -/*******************************************************************\ - -Function: bv_refinementt::convert_floatbv_op - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt bv_refinementt::convert_floatbv_op(const exprt &expr) { if(!do_arithmetic_refinement) @@ -85,18 +49,6 @@ bvt bv_refinementt::convert_floatbv_op(const exprt &expr) return bv; } -/*******************************************************************\ - -Function: bv_refinementt::convert_mult - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt bv_refinementt::convert_mult(const exprt &expr) { if(!do_arithmetic_refinement || expr.type().id()==ID_fixedbv) @@ -145,18 +97,6 @@ bvt bv_refinementt::convert_mult(const exprt &expr) return bv; } -/*******************************************************************\ - -Function: bv_refinementt::convert_div - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt bv_refinementt::convert_div(const div_exprt &expr) { if(!do_arithmetic_refinement || expr.type().id()==ID_fixedbv) @@ -175,18 +115,6 @@ bvt bv_refinementt::convert_div(const div_exprt &expr) return bv; } -/*******************************************************************\ - -Function: bv_refinementt::convert_mod - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bvt bv_refinementt::convert_mod(const mod_exprt &expr) { if(!do_arithmetic_refinement || expr.type().id()==ID_fixedbv) @@ -205,18 +133,6 @@ bvt bv_refinementt::convert_mod(const mod_exprt &expr) return bv; } -/*******************************************************************\ - -Function: bv_refinementt::get_values - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bv_refinementt::get_values(approximationt &a) { std::size_t o=a.expr.operands().size(); @@ -240,19 +156,8 @@ void bv_refinementt::get_values(approximationt &a) a.result_value=get_value(a.result_bv); } -/*******************************************************************\ - -Function: bv_refinementt::check_SAT - - Inputs: - - Outputs: - - Purpose: inspect if satisfying assignment extends to original - formula, otherwise refine overapproximation - -\*******************************************************************/ - +/// inspect if satisfying assignment extends to original formula, otherwise +/// refine overapproximation void bv_refinementt::check_SAT(approximationt &a) { // get values @@ -413,21 +318,24 @@ void bv_refinementt::check_SAT(approximationt &a) r=bv_utils.multiplier( a.op0_bv, a.op1_bv, a.expr.type().id()==ID_signedbv? - bv_utilst::SIGNED:bv_utilst::UNSIGNED); + bv_utilst::representationt::SIGNED: + bv_utilst::representationt::UNSIGNED); } else if(a.expr.id()==ID_div) { r=bv_utils.divider( a.op0_bv, a.op1_bv, a.expr.type().id()==ID_signedbv? - bv_utilst::SIGNED:bv_utilst::UNSIGNED); + bv_utilst::representationt::SIGNED: + bv_utilst::representationt::UNSIGNED); } else if(a.expr.id()==ID_mod) { r=bv_utils.remainder( a.op0_bv, a.op1_bv, a.expr.type().id()==ID_signedbv? - bv_utilst::SIGNED:bv_utilst::UNSIGNED); + bv_utilst::representationt::SIGNED: + bv_utilst::representationt::UNSIGNED); } else assert(0); @@ -455,19 +363,8 @@ void bv_refinementt::check_SAT(approximationt &a) a.over_state++; } -/*******************************************************************\ - -Function: bv_refinementt::check_UNSAT - - Inputs: - - Outputs: - - Purpose: inspect if proof holds on original formula, - otherwise refine underapproximation - -\*******************************************************************/ - +/// inspect if proof holds on original formula, otherwise refine +/// underapproximation void bv_refinementt::check_UNSAT(approximationt &a) { // part of the conflict? @@ -555,18 +452,7 @@ void bv_refinementt::check_UNSAT(approximationt &a) progress=true; } -/*******************************************************************\ - -Function: bv_refinementt::is_in_conflict - - Inputs: - - Outputs: - - Purpose: check if an under-approximation is part of the conflict - -\*******************************************************************/ - +/// check if an under-approximation is part of the conflict bool bv_refinementt::is_in_conflict(approximationt &a) { for(std::size_t i=0; i #include @@ -14,21 +16,9 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "bv_refinement.h" #include -/*******************************************************************\ - -Function: bv_refinementt::post_process_arrays - - Inputs: - - Outputs: - - Purpose: generate array constraints - -\*******************************************************************/ - +/// generate array constraints void bv_refinementt::post_process_arrays() { collect_indices(); @@ -43,18 +33,7 @@ void bv_refinementt::post_process_arrays() freeze_lazy_constraints(); } -/*******************************************************************\ - -Function: bv_refinementt::arrays_overapproximated - - Inputs: - - Outputs: - - Purpose: check whether counterexample is spurious - -\*******************************************************************/ - +/// check whether counterexample is spurious void bv_refinementt::arrays_overapproximated() { if(!do_array_refinement) @@ -67,7 +46,7 @@ void bv_refinementt::arrays_overapproximated() { satcheck_no_simplifiert sat_check; bv_pointerst solver(ns, sat_check); - solver.unbounded_array=bv_pointerst::U_ALL; + solver.unbounded_array=bv_pointerst::unbounded_arrayt::U_ALL; exprt current=(*it).lazy; @@ -101,12 +80,12 @@ void bv_refinementt::arrays_overapproximated() exprt simplified=get(current); solver << simplified; - switch(sat_check.prop_solve()) + switch(static_cast(sat_check.prop_solve())) { - case decision_proceduret::D_SATISFIABLE: + case decision_proceduret::resultt::D_SATISFIABLE: ++it; break; - case decision_proceduret::D_UNSATISFIABLE: + case decision_proceduret::resultt::D_UNSATISFIABLE: prop.l_set_to_true(convert(current)); nb_active++; lazy_array_constraints.erase(it++); @@ -125,18 +104,7 @@ void bv_refinementt::arrays_overapproximated() } -/*******************************************************************\ - -Function: bv_refinementt::freeze_lazy_constraints - - Inputs: - - Outputs: - - Purpose: freeze symbols for incremental solving - -\*******************************************************************/ - +/// freeze symbols for incremental solving void bv_refinementt::freeze_lazy_constraints() { if(!lazy_arrays) diff --git a/src/solvers/refinement/refined_string_type.cpp b/src/solvers/refinement/refined_string_type.cpp index 012d30eb8de..edd1c43e49a 100644 --- a/src/solvers/refinement/refined_string_type.cpp +++ b/src/solvers/refinement/refined_string_type.cpp @@ -10,17 +10,15 @@ Author: Romain Brenguier, romain.brenguier@diffblue.com \*******************************************************************/ -#include +/// \file +/// Type for string expressions used by the string solver. These string +/// expressions contain a field `length`, of type `index_type`, a field +/// `content` of type `content_type`. This module also defines functions to +/// recognise the C and java string types. #include "refined_string_type.h" -/*******************************************************************\ - -Constructor: refined_string_typet::refined_string_typet - - Inputs: type of characters - -\*******************************************************************/ +#include refined_string_typet::refined_string_typet( const typet &index_type, const typet &char_type) @@ -31,16 +29,8 @@ refined_string_typet::refined_string_typet( components().emplace_back("content", char_array); } -/*******************************************************************\ - -Function: refined_string_typet::is_c_string_type - - Inputs: a type - - Outputs: Boolean telling whether the type is that of C strings - -\*******************************************************************/ - +/// \par parameters: a type +/// \return Boolean telling whether the type is that of C strings bool refined_string_typet::is_c_string_type(const typet &type) { return @@ -48,16 +38,8 @@ bool refined_string_typet::is_c_string_type(const typet &type) to_struct_type(type).get_tag()==CPROVER_PREFIX"string"; } -/*******************************************************************\ - -Function: refined_string_typet::is_java_string_pointer_type - - Inputs: a type - - Outputs: Boolean telling whether the type is that of java string pointers - -\*******************************************************************/ - +/// \par parameters: a type +/// \return Boolean telling whether the type is that of java string pointers bool refined_string_typet::is_java_string_pointer_type(const typet &type) { if(type.id()==ID_pointer) @@ -69,16 +51,8 @@ bool refined_string_typet::is_java_string_pointer_type(const typet &type) return false; } -/*******************************************************************\ - -Function: refined_string_typet::is_java_string_type - - Inputs: a type - - Outputs: Boolean telling whether the type is that of java string - -\*******************************************************************/ - +/// \par parameters: a type +/// \return Boolean telling whether the type is that of java string bool refined_string_typet::is_java_string_type(const typet &type) { if(type.id()==ID_symbol) @@ -94,16 +68,8 @@ bool refined_string_typet::is_java_string_type(const typet &type) return false; } -/*******************************************************************\ - -Function: refined_string_typet::is_java_string_builder_type - - Inputs: a type - - Outputs: Boolean telling whether the type is that of java string builder - -\*******************************************************************/ - +/// \par parameters: a type +/// \return Boolean telling whether the type is that of java string builder bool refined_string_typet::is_java_string_builder_type(const typet &type) { if(type.id()==ID_pointer) @@ -119,16 +85,8 @@ bool refined_string_typet::is_java_string_builder_type(const typet &type) return false; } -/*******************************************************************\ - -Function: refined_string_typet::is_java_char_sequence_type - - Inputs: a type - - Outputs: Boolean telling whether the type is that of java char sequence - -\*******************************************************************/ - +/// \par parameters: a type +/// \return Boolean telling whether the type is that of java char sequence bool refined_string_typet::is_java_char_sequence_type(const typet &type) { if(type.id()==ID_pointer) diff --git a/src/solvers/refinement/refined_string_type.h b/src/solvers/refinement/refined_string_type.h index 3ecc0ac3a9f..4d5e11afa84 100644 --- a/src/solvers/refinement/refined_string_type.h +++ b/src/solvers/refinement/refined_string_type.h @@ -10,6 +10,12 @@ Author: Romain Brenguier, romain.brenguier@diffblue.com \*******************************************************************/ +/// \file +/// Type for string expressions used by the string solver. These string +/// expressions contain a field `length`, of type `index_type`, a field +/// `content` of type `content_type`. This module also defines functions to +/// recognise the C and java string types. + #ifndef CPROVER_SOLVERS_REFINEMENT_REFINED_STRING_TYPE_H #define CPROVER_SOLVERS_REFINEMENT_REFINED_STRING_TYPE_H diff --git a/src/solvers/refinement/string_constraint.h b/src/solvers/refinement/string_constraint.h index 61a6f3ebdd6..27a6a87a5a8 100644 --- a/src/solvers/refinement/string_constraint.h +++ b/src/solvers/refinement/string_constraint.h @@ -10,6 +10,13 @@ Author: Romain Brenguier, romain.brenguier@diffblue.com \*******************************************************************/ +/// \file +/// Defines string constraints. These are formulas talking about strings. We +/// implemented two forms of constraints: `string_constraintt` are formulas +/// of the form $\forall univ_var \in [lb,ub[. prem => body$, and +/// not_contains_constraintt of the form: $\forall x in [lb,ub[. p(x) => +/// \exists y in [lb,ub[. s1[x+y] != s2[y]$. + #ifndef CPROVER_SOLVERS_REFINEMENT_STRING_CONSTRAINT_H #define CPROVER_SOLVERS_REFINEMENT_STRING_CONSTRAINT_H diff --git a/src/solvers/refinement/string_constraint_generator.h b/src/solvers/refinement/string_constraint_generator.h index 2a56f09fddd..84732931d70 100644 --- a/src/solvers/refinement/string_constraint_generator.h +++ b/src/solvers/refinement/string_constraint_generator.h @@ -10,6 +10,13 @@ Author: Romain Brenguier, romain.brenguier@diffblue.com \*******************************************************************/ +/// \file +/// Generates string constraints to link results from string functions with +/// their arguments. This is inspired by the PASS paper at HVC'13: "PASS: +/// String Solving with Parameterized Array and Interval Automaton" by Guodong +/// Li and Indradeep Ghosh, which gives examples of constraints for several +/// functions. + #ifndef CPROVER_SOLVERS_REFINEMENT_STRING_CONSTRAINT_GENERATOR_H #define CPROVER_SOLVERS_REFINEMENT_STRING_CONSTRAINT_GENERATOR_H diff --git a/src/solvers/refinement/string_constraint_generator_code_points.cpp b/src/solvers/refinement/string_constraint_generator_code_points.cpp index 7c035a0d3e4..6bf8e035ad5 100644 --- a/src/solvers/refinement/string_constraint_generator_code_points.cpp +++ b/src/solvers/refinement/string_constraint_generator_code_points.cpp @@ -7,6 +7,9 @@ Author: Romain Brenguier, romain.brenguier@diffblue.com \*******************************************************************/ +/// \file +/// Generates string constraints for Java functions dealing with code points + #include /******************************************************************* \ @@ -70,21 +73,12 @@ string_exprt string_constraint_generatort::add_axioms_for_code_point( return res; } -/*******************************************************************\ - -Function: string_constraint_generatort::is_high_surrogate - - Inputs: a character expression - - Outputs: a Boolean expression - - Purpose: the output is true when the character is a high surrogate for - UTF-16 encoding, see https://en.wikipedia.org/wiki/UTF-16 for - more explenation about the encoding; - this is true when the character is in the range 0xD800..0xDBFF - -\*******************************************************************/ - +/// the output is true when the character is a high surrogate for UTF-16 +/// encoding, see https://en.wikipedia.org/wiki/UTF-16 for more explenation +/// about the encoding; this is true when the character is in the range +/// 0xD800..0xDBFF +/// \par parameters: a character expression +/// \return a Boolean expression exprt string_constraint_generatort::is_high_surrogate(const exprt &chr) const { return and_exprt( @@ -92,21 +86,12 @@ exprt string_constraint_generatort::is_high_surrogate(const exprt &chr) const binary_relation_exprt(chr, ID_le, constant_char(0xDBFF, chr.type()))); } -/*******************************************************************\ - -Function: string_constraint_generatort::is_low_surrogate - - Inputs: a character expression - - Outputs: a Boolean expression - - Purpose: the output is true when the character is a low surrogate for - UTF-16 encoding, see https://en.wikipedia.org/wiki/UTF-16 for - more explenation about the encoding; - this is true when the character is in the range 0xDC00..0xDFFF - -\*******************************************************************/ - +/// the output is true when the character is a low surrogate for UTF-16 +/// encoding, see https://en.wikipedia.org/wiki/UTF-16 for more explenation +/// about the encoding; this is true when the character is in the range +/// 0xDC00..0xDFFF +/// \par parameters: a character expression +/// \return a Boolean expression exprt string_constraint_generatort::is_low_surrogate(const exprt &chr) const { return and_exprt( @@ -114,24 +99,14 @@ exprt string_constraint_generatort::is_low_surrogate(const exprt &chr) const binary_relation_exprt(chr, ID_le, constant_char(0xDFFF, chr.type()))); } -/*******************************************************************\ - -Function: string_constraint_generatort::pair_value - - Inputs: two character expressions and a return type - char1 and char2 should be of type return_type - - Outputs: an integer expression of type return_type - - Purpose: the output corresponds to the unicode character given by the - pair of characters of inputs assuming it has been encoded in - UTF-16, see https://en.wikipedia.org/wiki/UTF-16 for - more explenation about the encoding; - the operation we perform is: - pair_value=0x10000+(((char1%0x0800)*0x0400)+char2%0x0400) - -\*******************************************************************/ - +/// the output corresponds to the unicode character given by the pair of +/// characters of inputs assuming it has been encoded in UTF-16, see +/// https://en.wikipedia.org/wiki/UTF-16 for more explenation about the +/// encoding; the operation we perform is: +/// pair_value=0x10000+(((char1%0x0800)*0x0400)+char2%0x0400) +/// \par parameters: two character expressions and a return type +/// char1 and char2 should be of type return_type +/// \return an integer expression of type return_type exprt pair_value(exprt char1, exprt char2, typet return_type) { exprt hex010000=from_integer(0x010000, return_type); @@ -143,18 +118,10 @@ exprt pair_value(exprt char1, exprt char2, typet return_type) return pair_value; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_code_point_at - - Inputs: function application with two arguments: a string and an index - - Outputs: a integer expression corresponding to a code point - - Purpose: add axioms corresponding to the String.codePointAt java function - -\*******************************************************************/ - +/// add axioms corresponding to the String.codePointAt java function +/// \par parameters: function application with two arguments: a string and an +/// index +/// \return a integer expression corresponding to a code point exprt string_constraint_generatort::add_axioms_for_code_point_at( const function_application_exprt &f) { @@ -179,18 +146,10 @@ exprt string_constraint_generatort::add_axioms_for_code_point_at( return result; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_code_point_before - - Inputs: function application with two arguments: a string and an index - - Outputs: a integer expression corresponding to a code point - - Purpose: add axioms corresponding to the String.codePointBefore java function - -\*******************************************************************/ - +/// add axioms corresponding to the String.codePointBefore java function +/// \par parameters: function application with two arguments: a string and an +/// index +/// \return a integer expression corresponding to a code point exprt string_constraint_generatort::add_axioms_for_code_point_before( const function_application_exprt &f) { @@ -218,19 +177,11 @@ exprt string_constraint_generatort::add_axioms_for_code_point_before( return result; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_code_point_count - - Inputs: function application with three arguments: a string and two indexes - - Outputs: an integer expression - - Purpose: add axioms giving approximate bounds on the result of the - String.codePointCount java function - -\*******************************************************************/ - +/// add axioms giving approximate bounds on the result of the +/// String.codePointCount java function +/// \par parameters: function application with three arguments: a string and two +/// indexes +/// \return an integer expression exprt string_constraint_generatort::add_axioms_for_code_point_count( const function_application_exprt &f) { @@ -247,21 +198,12 @@ exprt string_constraint_generatort::add_axioms_for_code_point_count( return result; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_offset_by_code_point - - Inputs: function application with three arguments: a string and two indexes - - Outputs: a new string expression - - Purpose: add axioms giving approximate bounds on the result of the - String.offsetByCodePointCount java function. - We approximate the result by saying the result is - between index + offset and index + 2 * offset - -\*******************************************************************/ - +/// add axioms giving approximate bounds on the result of the +/// String.offsetByCodePointCount java function. We approximate the result by +/// saying the result is between index + offset and index + 2 * offset +/// \par parameters: function application with three arguments: a string and two +/// indexes +/// \return a new string expression exprt string_constraint_generatort::add_axioms_for_offset_by_code_point( const function_application_exprt &f) { diff --git a/src/solvers/refinement/string_constraint_generator_comparison.cpp b/src/solvers/refinement/string_constraint_generator_comparison.cpp index 321282ee9c1..fbb64c55d68 100644 --- a/src/solvers/refinement/string_constraint_generator_comparison.cpp +++ b/src/solvers/refinement/string_constraint_generator_comparison.cpp @@ -7,21 +7,16 @@ Author: Romain Brenguier, romain.brenguier@diffblue.com \*******************************************************************/ -#include - -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_equals - - Inputs: function application with two string arguments - - Outputs: a expression of Boolean type - - Purpose: add axioms stating that the result is true exactly when the strings - represented by the arguments are equal +/// \file +/// Generates string constraints for function comparing strings, such as: +/// equals, equalsIgnoreCase, compareTo, hashCode, intern -\*******************************************************************/ +#include +/// add axioms stating that the result is true exactly when the strings +/// represented by the arguments are equal +/// \par parameters: function application with two string arguments +/// \return a expression of Boolean type exprt string_constraint_generatort::add_axioms_for_equals( const function_application_exprt &f) { @@ -62,20 +57,12 @@ exprt string_constraint_generatort::add_axioms_for_equals( return tc_eq; } -/*******************************************************************\ - -Function: string_constraint_generatort::character_equals_ignore_case - - Inputs: two character expressions and constant character expressions - representing 'a', 'A' and 'Z' - - Outputs: a expression of Boolean type - - Purpose: returns an expression which is true when the two given - characters are equal when ignoring case for ASCII - -\*******************************************************************/ - +/// returns an expression which is true when the two given characters are equal +/// when ignoring case for ASCII +/// \par parameters: two character expressions and constant character +/// expressions +/// representing 'a', 'A' and 'Z' +/// \return a expression of Boolean type exprt string_constraint_generatort::character_equals_ignore_case( exprt char1, exprt char2, exprt char_a, exprt char_A, exprt char_Z) { @@ -97,18 +84,9 @@ exprt string_constraint_generatort::character_equals_ignore_case( return or_exprt(or_exprt(p1, p2), p3); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_equals_ignore_case - - Inputs: function application with two string arguments - - Outputs: a Boolean expression - - Purpose: add axioms corresponding to the String.equalsIgnoreCase java function - -\*******************************************************************/ - +/// add axioms corresponding to the String.equalsIgnoreCase java function +/// \par parameters: function application with two string arguments +/// \return a Boolean expression exprt string_constraint_generatort::add_axioms_for_equals_ignore_case( const function_application_exprt &f) { @@ -158,19 +136,10 @@ exprt string_constraint_generatort::add_axioms_for_equals_ignore_case( return tc_eq; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_hash_code - - Inputs: function application with a string argument - - Outputs: a integer expression corresponding to the hash code of the string - - Purpose: add axioms stating that if two strings are equal then their hash - codes are equals - -\*******************************************************************/ - +/// add axioms stating that if two strings are equal then their hash codes are +/// equals +/// \par parameters: function application with a string argument +/// \return a integer expression corresponding to the hash code of the string exprt string_constraint_generatort::add_axioms_for_hash_code( const function_application_exprt &f) { @@ -207,18 +176,9 @@ exprt string_constraint_generatort::add_axioms_for_hash_code( return hash[str]; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_compare_to - - Inputs: function application with two string arguments - - Outputs: a integer expression - - Purpose: add axioms corresponding to the String.compareTo java function - -\*******************************************************************/ - +/// add axioms corresponding to the String.compareTo java function +/// \par parameters: function application with two string arguments +/// \return a integer expression exprt string_constraint_generatort::add_axioms_for_compare_to( const function_application_exprt &f) { @@ -288,19 +248,10 @@ exprt string_constraint_generatort::add_axioms_for_compare_to( return res; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_intern - - Inputs: function application with one string argument - - Outputs: a string expression - - Purpose: add axioms stating that the return value for two equal string - should be the same - -\*******************************************************************/ - +/// add axioms stating that the return value for two equal string should be the +/// same +/// \par parameters: function application with one string argument +/// \return a string expression symbol_exprt string_constraint_generatort::add_axioms_for_intern( const function_application_exprt &f) { diff --git a/src/solvers/refinement/string_constraint_generator_concat.cpp b/src/solvers/refinement/string_constraint_generator_concat.cpp index a7d9c4921c4..4d0a5b47151 100644 --- a/src/solvers/refinement/string_constraint_generator_concat.cpp +++ b/src/solvers/refinement/string_constraint_generator_concat.cpp @@ -7,21 +7,16 @@ Author: Romain Brenguier, romain.brenguier@diffblue.com \*******************************************************************/ -#include - -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_concat - - Inputs: two string expressions +/// \file +/// Generates string constraints for functions adding content add the end of +/// strings - Outputs: a new string expression - - Purpose: add axioms to say that the returned string expression is equal to - the concatenation of the two string expressions given as input - -\*******************************************************************/ +#include +/// add axioms to say that the returned string expression is equal to the +/// concatenation of the two string expressions given as input +/// \par parameters: two string expressions +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_concat( const string_exprt &s1, const string_exprt &s2) { @@ -53,20 +48,10 @@ string_exprt string_constraint_generatort::add_axioms_for_concat( return res; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_concat - - Inputs: function application with two arguments which are strings - - Outputs: a new string expression - - Purpose: add axioms to say that the returned string expression is equal to - the concatenation of the two string arguments of - the function application - -\*******************************************************************/ - +/// add axioms to say that the returned string expression is equal to the +/// concatenation of the two string arguments of the function application +/// \par parameters: function application with two arguments which are strings +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_concat( const function_application_exprt &f) { @@ -79,18 +64,10 @@ string_exprt string_constraint_generatort::add_axioms_for_concat( return add_axioms_for_concat(s1, s2); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_concat_int - - Inputs: function application with two arguments: a string and an integer - - Outputs: a new string expression - - Purpose: add axioms corresponding to the StringBuilder.append(I) java function - -\*******************************************************************/ - +/// add axioms corresponding to the StringBuilder.append(I) java function +/// \par parameters: function application with two arguments: a string and an +/// integer +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_concat_int( const function_application_exprt &f) { @@ -101,19 +78,10 @@ string_exprt string_constraint_generatort::add_axioms_for_concat_int( return add_axioms_for_concat(s1, s2); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_long - - Inputs: function application with two arguments: a string and a - integer of type long - - Outputs: a new string expression - - Purpose: Add axioms corresponding to the StringBuilder.append(J) java function - -\*******************************************************************/ - +/// Add axioms corresponding to the StringBuilder.append(J) java function +/// \par parameters: function application with two arguments: a string and a +/// integer of type long +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_concat_long( const function_application_exprt &f) { @@ -123,18 +91,9 @@ string_exprt string_constraint_generatort::add_axioms_for_concat_long( return add_axioms_for_concat(s1, s2); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_concat_bool - - Inputs: function application two arguments: a string and a bool - - Outputs: a new string expression - - Purpose: add axioms corresponding to the StringBuilder.append(Z) java function - -\*******************************************************************/ - +/// add axioms corresponding to the StringBuilder.append(Z) java function +/// \par parameters: function application two arguments: a string and a bool +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_concat_bool( const function_application_exprt &f) { @@ -144,18 +103,10 @@ string_exprt string_constraint_generatort::add_axioms_for_concat_bool( return add_axioms_for_concat(s1, s2); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_concat_char - - Inputs: function application with two arguments: a string and a char - - Outputs: a new string expression - - Purpose: add axioms corresponding to the StringBuilder.append(C) java function - -\*******************************************************************/ - +/// add axioms corresponding to the StringBuilder.append(C) java function +/// \par parameters: function application with two arguments: a string and a +/// char +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_concat_char( const function_application_exprt &f) { @@ -165,18 +116,10 @@ string_exprt string_constraint_generatort::add_axioms_for_concat_char( return add_axioms_for_concat(s1, s2); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_concat_double - - Inputs: function application with two arguments: a string and a double - - Outputs: a new string expression - - Purpose: add axioms corresponding to the StringBuilder.append(D) java function - -\*******************************************************************/ - +/// add axioms corresponding to the StringBuilder.append(D) java function +/// \par parameters: function application with two arguments: a string and a +/// double +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_concat_double( const function_application_exprt &f) { @@ -186,18 +129,10 @@ string_exprt string_constraint_generatort::add_axioms_for_concat_double( return add_axioms_for_concat(s1, s2); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_concat_float - - Inputs: function application with two arguments: a string and a float - - Outputs: a new string expression - - Purpose: add axioms corresponding to the StringBuilder.append(F) java function - -\*******************************************************************/ - +/// add axioms corresponding to the StringBuilder.append(F) java function +/// \par parameters: function application with two arguments: a string and a +/// float +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_concat_float( const function_application_exprt &f) { @@ -206,19 +141,10 @@ string_exprt string_constraint_generatort::add_axioms_for_concat_float( return add_axioms_for_concat(s1, s2); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_concat_code_point - - Inputs: function application with two arguments: a string and a code point - - Outputs: a new string expression - - Purpose: Add axioms corresponding to the StringBuilder.appendCodePoint(I) - function - -\*******************************************************************/ - +/// Add axioms corresponding to the StringBuilder.appendCodePoint(I) function +/// \par parameters: function application with two arguments: a string and a +/// code point +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_concat_code_point( const function_application_exprt &f) { diff --git a/src/solvers/refinement/string_constraint_generator_constants.cpp b/src/solvers/refinement/string_constraint_generator_constants.cpp index 90769747949..fe85c70dc46 100644 --- a/src/solvers/refinement/string_constraint_generator_constants.cpp +++ b/src/solvers/refinement/string_constraint_generator_constants.cpp @@ -6,24 +6,19 @@ Author: Romain Brenguier, romain.brenguier@diffblue.com \*******************************************************************/ -#include +/// \file +/// Generates string constraints for constant strings + #include + +#include #include #include -/*******************************************************************\ - -Function: string_constraint_generatort::extract_java_string - - Inputs: a symbol expression representing a java literal - - Outputs: a string constant - - Purpose: extract java string from symbol expression when they are encoded - inside the symbol name - -\*******************************************************************/ - +/// extract java string from symbol expression when they are encoded inside the +/// symbol name +/// \par parameters: a symbol expression representing a java literal +/// \return a string constant irep_idt string_constraint_generatort::extract_java_string( const symbol_exprt &s) { @@ -34,19 +29,10 @@ irep_idt string_constraint_generatort::extract_java_string( return irep_idt(value); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_constant - - Inputs: a string constant - - Outputs: a string expression - - Purpose: add axioms saying the returned string expression should be equal - to the string constant - -\*******************************************************************/ - +/// add axioms saying the returned string expression should be equal to the +/// string constant +/// \par parameters: a string constant +/// \return a string expression string_exprt string_constraint_generatort::add_axioms_for_constant( irep_idt sval, const refined_string_typet &ref_type) { @@ -77,18 +63,9 @@ string_exprt string_constraint_generatort::add_axioms_for_constant( return res; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_empty_string - - Inputs: function application without argument - - Outputs: string expression - - Purpose: add axioms to say that the returned string expression is empty - -\*******************************************************************/ - +/// add axioms to say that the returned string expression is empty +/// \par parameters: function application without argument +/// \return string expression string_exprt string_constraint_generatort::add_axioms_for_empty_string( const function_application_exprt &f) { @@ -99,19 +76,11 @@ string_exprt string_constraint_generatort::add_axioms_for_empty_string( return res; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_from_literal - - Inputs: function application with an argument which is a string literal - - Outputs: string expression - - Purpose: add axioms to say that the returned string expression is equal to - the string literal - -\*******************************************************************/ - +/// add axioms to say that the returned string expression is equal to the string +/// literal +/// \par parameters: function application with an argument which is a string +/// literal +/// \return string expression string_exprt string_constraint_generatort::add_axioms_from_literal( const function_application_exprt &f) { diff --git a/src/solvers/refinement/string_constraint_generator_indexof.cpp b/src/solvers/refinement/string_constraint_generator_indexof.cpp index 93db048458b..d32be2e3570 100644 --- a/src/solvers/refinement/string_constraint_generator_indexof.cpp +++ b/src/solvers/refinement/string_constraint_generator_indexof.cpp @@ -7,21 +7,17 @@ Author: Romain Brenguier, romain.brenguier@diffblue.com \*******************************************************************/ -#include - -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_index_of - - Inputs: a string expression, a character expression and an integer expression +/// \file +/// Generates string constraints for the family of indexOf and lastIndexOf java +/// functions - Outputs: a integer expression - - Purpose: add axioms that the returned value is either -1 or greater than - from_index and the character at that position equals to c - -\*******************************************************************/ +#include +/// add axioms that the returned value is either -1 or greater than from_index +/// and the character at that position equals to c +/// \par parameters: a string expression, a character expression and an integer +/// expression +/// \return a integer expression exprt string_constraint_generatort::add_axioms_for_index_of( const string_exprt &str, const exprt &c, const exprt &from_index) { @@ -69,19 +65,10 @@ exprt string_constraint_generatort::add_axioms_for_index_of( return index; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_index_of_string - - Inputs: two string expressions and an integer expression - - Outputs: a integer expression - - Purpose: add axioms stating that the returned value is either -1 or greater - than from_index and the string beggining there has prefix substring - -\*******************************************************************/ - +/// add axioms stating that the returned value is either -1 or greater than +/// from_index and the string beggining there has prefix substring +/// \par parameters: two string expressions and an integer expression +/// \return a integer expression exprt string_constraint_generatort::add_axioms_for_index_of_string( const string_exprt &str, const string_exprt &substring, @@ -155,20 +142,10 @@ exprt string_constraint_generatort::add_axioms_for_last_index_of_string( return offset; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_index_of - - Inputs: function application with 2 or 3 arguments - - Outputs: a integer expression - - Purpose: add axioms corresponding to the String.indexOf:(C), - String.indexOf:(CI), String.indexOf:(String), and - String.indexOf:(String,I) java functions - -\*******************************************************************/ - +/// add axioms corresponding to the String.indexOf:(C), String.indexOf:(CI), +/// String.indexOf:(String), and String.indexOf:(String,I) java functions +/// \par parameters: function application with 2 or 3 arguments +/// \return a integer expression exprt string_constraint_generatort::add_axioms_for_index_of( const function_application_exprt &f) { @@ -249,20 +226,11 @@ exprt string_constraint_generatort::add_axioms_for_last_index_of( return index; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_last_index_of - - Inputs: function application with 2 or 3 arguments - - Outputs: a integer expression - - Purpose: add axioms corresponding to the String.lastIndexOf:(C), - String.lastIndexOf:(CI), String.lastIndexOf:(String), and - String.lastIndexOf:(String,I) java functions - -\*******************************************************************/ - +/// add axioms corresponding to the String.lastIndexOf:(C), +/// String.lastIndexOf:(CI), String.lastIndexOf:(String), and +/// String.lastIndexOf:(String,I) java functions +/// \par parameters: function application with 2 or 3 arguments +/// \return a integer expression exprt string_constraint_generatort::add_axioms_for_last_index_of( const function_application_exprt &f) { diff --git a/src/solvers/refinement/string_constraint_generator_insert.cpp b/src/solvers/refinement/string_constraint_generator_insert.cpp index 6a080a5dc6c..f757317121e 100644 --- a/src/solvers/refinement/string_constraint_generator_insert.cpp +++ b/src/solvers/refinement/string_constraint_generator_insert.cpp @@ -6,21 +6,15 @@ Author: Romain Brenguier, romain.brenguier@diffblue.com \*******************************************************************/ -#include - -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_insert - - Inputs: two string expression and an integer offset +/// \file +/// Generates string constraints for the family of insert Java functions - Outputs: a new string expression - - Purpose: add axioms stating that the result correspond to the first string - where we inserted the second one at possition offset - -\*******************************************************************/ +#include +/// add axioms stating that the result correspond to the first string where we +/// inserted the second one at possition offset +/// \par parameters: two string expression and an integer offset +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_insert( const string_exprt &s1, const string_exprt &s2, const exprt &offset) { @@ -32,19 +26,10 @@ string_exprt string_constraint_generatort::add_axioms_for_insert( return add_axioms_for_concat(concat1, suf); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_insert - - Inputs: function application with three arguments: two strings and an index - - Outputs: a new string expression - - Purpose: add axioms corresponding to the StringBuilder.insert(String) java - function - -\*******************************************************************/ - +/// add axioms corresponding to the StringBuilder.insert(String) java function +/// \par parameters: function application with three arguments: two strings and +/// an index +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_insert( const function_application_exprt &f) { @@ -53,19 +38,11 @@ string_exprt string_constraint_generatort::add_axioms_for_insert( return add_axioms_for_insert(s1, s2, args(f, 3)[1]); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_insert_int - - Inputs: function application with three arguments: a string, an integer - offset, and an integer - - Outputs: a new string expression - - Purpose: add axioms corresponding to the StringBuilder.insert(I) java function - -\*******************************************************************/ - +/// add axioms corresponding to the StringBuilder.insert(I) java function +/// \par parameters: function application with three arguments: a string, an +/// integer +/// offset, and an integer +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_insert_int( const function_application_exprt &f) { @@ -76,19 +53,11 @@ string_exprt string_constraint_generatort::add_axioms_for_insert_int( return add_axioms_for_insert(s1, s2, args(f, 3)[1]); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_insert_long - - Inputs: function application with three arguments: a string, an integer - offset and a long - - Outputs: a new string expression - - Purpose: add axioms corresponding to the StringBuilder.insert(J) java function - -\*******************************************************************/ - +/// add axioms corresponding to the StringBuilder.insert(J) java function +/// \par parameters: function application with three arguments: a string, an +/// integer +/// offset and a long +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_insert_long( const function_application_exprt &f) { @@ -98,19 +67,11 @@ string_exprt string_constraint_generatort::add_axioms_for_insert_long( return add_axioms_for_insert(s1, s2, args(f, 3)[1]); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_insert_bool - - Inputs: function application with three arguments: a string, an integer - offset, and a Boolean - - Outputs: a new string expression - - Purpose: add axioms corresponding to the StringBuilder.insert(Z) java function - -\*******************************************************************/ - +/// add axioms corresponding to the StringBuilder.insert(Z) java function +/// \par parameters: function application with three arguments: a string, an +/// integer +/// offset, and a Boolean +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_insert_bool( const function_application_exprt &f) { @@ -120,19 +81,11 @@ string_exprt string_constraint_generatort::add_axioms_for_insert_bool( return add_axioms_for_insert(s1, s2, args(f, 3)[1]); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_insert_char - - Inputs: function application with three arguments: a string, an integer - offset, and a character - - Outputs: a new string expression - - Purpose: add axioms corresponding to the StringBuilder.insert(C) java function - -\*******************************************************************/ - +/// add axioms corresponding to the StringBuilder.insert(C) java function +/// \par parameters: function application with three arguments: a string, an +/// integer +/// offset, and a character +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_insert_char( const function_application_exprt &f) { @@ -142,19 +95,11 @@ string_exprt string_constraint_generatort::add_axioms_for_insert_char( return add_axioms_for_insert(s1, s2, args(f, 3)[1]); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_insert_double - - Inputs: function application with three arguments: a string, an integer - offset, and a double - - Outputs: a new string expression - - Purpose: add axioms corresponding to the StringBuilder.insert(D) java function - -\*******************************************************************/ - +/// add axioms corresponding to the StringBuilder.insert(D) java function +/// \par parameters: function application with three arguments: a string, an +/// integer +/// offset, and a double +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_insert_double( const function_application_exprt &f) { @@ -163,19 +108,11 @@ string_exprt string_constraint_generatort::add_axioms_for_insert_double( return add_axioms_for_insert(s1, s2, args(f, 3)[1]); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_insert_float - - Inputs: function application with three arguments: a string, an integer - offset, and a float - - Outputs: a new string expression - - Purpose: add axioms corresponding to the StringBuilder.insert(F) java function - -\*******************************************************************/ - +/// add axioms corresponding to the StringBuilder.insert(F) java function +/// \par parameters: function application with three arguments: a string, an +/// integer +/// offset, and a float +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_insert_float( const function_application_exprt &f) { @@ -184,21 +121,13 @@ string_exprt string_constraint_generatort::add_axioms_for_insert_float( return add_axioms_for_insert(s1, s2, args(f, 3)[1]); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_insert_char_array - - Inputs: function application with 4 arguments plus two optional arguments: - a string, an offset index, a length, data array, an offset and a - count - - Outputs: a new string expression - - Purpose: add axioms corresponding to the StringBuilder.insert:(I[CII) - and StringBuilder.insert:(I[C) java functions - -\*******************************************************************/ - +/// add axioms corresponding to the StringBuilder.insert:(I[CII) and +/// StringBuilder.insert:(I[C) java functions +/// \par parameters: function application with 4 arguments plus two optional +/// arguments: +/// a string, an offset index, a length, data array, an offset and a +/// count +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_insert_char_array( const function_application_exprt &f) { diff --git a/src/solvers/refinement/string_constraint_generator_main.cpp b/src/solvers/refinement/string_constraint_generator_main.cpp index 5a269e5ad3b..308846338ef 100644 --- a/src/solvers/refinement/string_constraint_generator_main.cpp +++ b/src/solvers/refinement/string_constraint_generator_main.cpp @@ -10,48 +10,39 @@ Author: Romain Brenguier, romain.brenguier@diffblue.com \*******************************************************************/ +/// \file +/// Generates string constraints to link results from string functions with +/// their arguments. This is inspired by the PASS paper at HVC'13: "PASS: +/// String Solving with Parameterized Array and Interval Automaton" by Guodong +/// Li and Indradeep Ghosh, which gives examples of constraints for several +/// functions. + +#include + #include #include -#include #include #include #include unsigned string_constraint_generatort::next_symbol_id=1; -/*******************************************************************\ - -Function: string_constraint_generatort::constant_char - - Inputs: integer representing a character, and a type for characters; - we do not use char type here because in some languages - (for instance java) characters use more than 8 bits. - - Outputs: constant expression corresponding to the character. - - Purpose: generate constant character expression with character type. - -\*******************************************************************/ - +/// generate constant character expression with character type. +/// \par parameters: integer representing a character, and a type for +/// characters; +/// we do not use char type here because in some languages +/// (for instance java) characters use more than 8 bits. +/// \return constant expression corresponding to the character. constant_exprt string_constraint_generatort::constant_char( int i, const typet &char_type) { return from_integer(i, char_type); } -/*******************************************************************\ - -Function: string_constraint_generator::fresh_symbol - - Inputs: a prefix and a type - - Outputs: a symbol of type tp whose name starts with - "string_refinement#" followed by prefix - - Purpose: generate a new symbol expression of the given type with some prefix - -\*******************************************************************/ - +/// generate a new symbol expression of the given type with some prefix +/// \par parameters: a prefix and a type +/// \return a symbol of type tp whose name starts with "string_refinement#" +/// followed by prefix symbol_exprt string_constraint_generatort::fresh_symbol( const irep_idt &prefix, const typet &type) { @@ -61,37 +52,18 @@ symbol_exprt string_constraint_generatort::fresh_symbol( return symbol_exprt(name, type); } -/*******************************************************************\ - -Function: string_constraint_generatort::fresh_univ_index - - Inputs: a prefix - - Outputs: a symbol of index type whose name starts with the prefix - - Purpose: generate an index symbol to be used as an universaly quantified - variable - -\*******************************************************************/ - +/// generate an index symbol to be used as an universaly quantified variable +/// \par parameters: a prefix +/// \return a symbol of index type whose name starts with the prefix symbol_exprt string_constraint_generatort::fresh_univ_index( const irep_idt &prefix, const typet &type) { return fresh_symbol(prefix, type); } -/*******************************************************************\ - -Function: string_constraint_generatort::fresh_exist_index - - Inputs: a prefix - - Outputs: a symbol of index type whose name starts with the prefix - - Purpose: generate an index symbol which is existentially quantified - -\*******************************************************************/ - +/// generate an index symbol which is existentially quantified +/// \par parameters: a prefix +/// \return a symbol of index type whose name starts with the prefix symbol_exprt string_constraint_generatort::fresh_exist_index( const irep_idt &prefix, const typet &type) { @@ -100,18 +72,9 @@ symbol_exprt string_constraint_generatort::fresh_exist_index( return s; } -/*******************************************************************\ - -Function: string_constraint_generatort::fresh_boolean - - Inputs: a prefix - - Outputs: a symbol of index type whose name starts with the prefix - - Purpose: generate a Boolean symbol which is existentially quantified - -\*******************************************************************/ - +/// generate a Boolean symbol which is existentially quantified +/// \par parameters: a prefix +/// \return a symbol of index type whose name starts with the prefix symbol_exprt string_constraint_generatort::fresh_boolean( const irep_idt &prefix) { @@ -120,19 +83,9 @@ symbol_exprt string_constraint_generatort::fresh_boolean( return b; } -/*******************************************************************\ - -Function: string_constraint_generatort::fresh_string - - Inputs: a type for string - - Outputs: a string expression - - Purpose: construct a string expression whose length and content are new - variables - -\*******************************************************************/ - +/// construct a string expression whose length and content are new variables +/// \par parameters: a type for string +/// \return a string expression string_exprt string_constraint_generatort::fresh_string( const refined_string_typet &type) { @@ -142,20 +95,11 @@ string_exprt string_constraint_generatort::fresh_string( return string_exprt(length, content, type); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_string_expr - - Inputs: an expression of type string - - Outputs: a string expression that is linked to the argument through - axioms that are added to the list - - Purpose: obtain a refined string expression corresponding to string - variable of string function call - -\*******************************************************************/ - +/// obtain a refined string expression corresponding to string variable of +/// string function call +/// \par parameters: an expression of type string +/// \return a string expression that is linked to the argument through axioms +/// that are added to the list string_exprt string_constraint_generatort::add_axioms_for_string_expr( const exprt &unrefined_string) { @@ -199,18 +143,9 @@ string_exprt string_constraint_generatort::add_axioms_for_string_expr( return s; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_if - - Inputs: an if expression - - Outputs: a string expression - - Purpose: add axioms for an if expression which should return a string - -\*******************************************************************/ - +/// add axioms for an if expression which should return a string +/// \par parameters: an if expression +/// \return a string expression string_exprt string_constraint_generatort::add_axioms_for_if( const if_exprt &expr) { @@ -238,21 +173,12 @@ string_exprt string_constraint_generatort::add_axioms_for_if( return res; } -/*******************************************************************\ - -Function: string_constraint_generatort::find_or_add_string_of_symbol - - Inputs: a symbol expression - - Outputs: a string expression - - Purpose: if a symbol represent a string is present in the symbol_to_string - table, returns the corresponding string, if the symbol is not yet - present, creates a new string with the correct type depending on - whether the mode is java or c, adds it to the table and returns it. - -\*******************************************************************/ - +/// if a symbol represent a string is present in the symbol_to_string table, +/// returns the corresponding string, if the symbol is not yet present, creates +/// a new string with the correct type depending on whether the mode is java or +/// c, adds it to the table and returns it. +/// \par parameters: a symbol expression +/// \return a string expression string_exprt string_constraint_generatort::find_or_add_string_of_symbol( const symbol_exprt &sym) { @@ -263,20 +189,11 @@ string_exprt string_constraint_generatort::find_or_add_string_of_symbol( return entry.first->second; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_function_application - - Inputs: an expression containing a function application - - Outputs: expression corresponding to the result of the function application - - Purpose: strings contained in this call are converted to objects of type - `string_exprt`, through adding axioms. Axioms are then added to - enforce that the result corresponds to the function application. - -\*******************************************************************/ - +/// strings contained in this call are converted to objects of type +/// `string_exprt`, through adding axioms. Axioms are then added to enforce that +/// the result corresponds to the function application. +/// \par parameters: an expression containing a function application +/// \return expression corresponding to the result of the function application exprt string_constraint_generatort::add_axioms_for_function_application( const function_application_exprt &expr) { @@ -414,19 +331,10 @@ exprt string_constraint_generatort::add_axioms_for_function_application( } } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_copy - - Inputs: function application with one argument, which is a string - - Outputs: a new string expression - - Purpose: add axioms to say that the returned string expression is equal to - the argument of the function application - -\*******************************************************************/ - +/// add axioms to say that the returned string expression is equal to the +/// argument of the function application +/// \par parameters: function application with one argument, which is a string +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_copy( const function_application_exprt &f) { @@ -446,18 +354,10 @@ string_exprt string_constraint_generatort::add_axioms_for_copy( return res; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_java_char_array - - Inputs: an expression corresponding to a java object of type char array - - Outputs: a new string expression - - Purpose: add axioms corresponding to the String.valueOf([C) java function - -\*******************************************************************/ - +/// add axioms corresponding to the String.valueOf([C) java function +/// \par parameters: an expression corresponding to a java object of type char +/// array +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_java_char_array( const exprt &char_array) { @@ -471,18 +371,9 @@ string_exprt string_constraint_generatort::add_axioms_for_java_char_array( return res; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_length - - Inputs: function application with one string argument - - Outputs: a string expression of index type - - Purpose: add axioms corresponding to the String.length java function - -\*******************************************************************/ - +/// add axioms corresponding to the String.length java function +/// \par parameters: function application with one string argument +/// \return a string expression of index type exprt string_constraint_generatort::add_axioms_for_length( const function_application_exprt &f) { @@ -490,21 +381,13 @@ exprt string_constraint_generatort::add_axioms_for_length( return str.length(); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_from_char_array - - Inputs: a length expression, an array expression, a offset index, and a - count index - - Outputs: a new string expression - - Purpose: add axioms stating that the content of the returned string - equals to the content of the array argument, starting at offset and - with `count` characters - -\*******************************************************************/ - +/// add axioms stating that the content of the returned string equals to the +/// content of the array argument, starting at offset and with `count` +/// characters +/// \par parameters: a length expression, an array expression, a offset index, +/// and a +/// count index +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_from_char_array( const exprt &length, const exprt &data, @@ -532,20 +415,11 @@ string_exprt string_constraint_generatort::add_axioms_from_char_array( return str; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_from_char_array - - Inputs: function application with 2 arguments and 2 additional optional - arguments: length, char array, offset and count - - Outputs: a new string expression - - Purpose: add axioms corresponding to the String.:(I[CII) - and String.:(I[C) java functions - -\*******************************************************************/ - +/// add axioms corresponding to the String.:(I[CII) and +/// String.:(I[C) java functions +/// function application with 2 arguments and 2 additional optional +/// \param arguments: length, char array, offset and count +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_from_char_array( const function_application_exprt &f) { @@ -567,36 +441,18 @@ string_exprt string_constraint_generatort::add_axioms_from_char_array( return add_axioms_from_char_array(tab_length, data, offset, count); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_is_positive_index - - Inputs: an index expression - - Outputs: a Boolean expression - - Purpose: expression true exactly when the index is positive - -\*******************************************************************/ - +/// expression true exactly when the index is positive +/// \par parameters: an index expression +/// \return a Boolean expression exprt string_constraint_generatort::axiom_for_is_positive_index(const exprt &x) { return binary_relation_exprt( x, ID_ge, from_integer(0, x.type())); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_char_literal - - Inputs: function application with one character argument - - Outputs: a new character expression - - Purpose: add axioms stating that the returned value is equal to the argument - -\*******************************************************************/ - +/// add axioms stating that the returned value is equal to the argument +/// \par parameters: function application with one character argument +/// \return a new character expression exprt string_constraint_generatort::add_axioms_for_char_literal( const function_application_exprt &f) { @@ -622,19 +478,11 @@ exprt string_constraint_generatort::add_axioms_for_char_literal( } } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_char_at - - Inputs: function application with two arguments: a string and an integer - - Outputs: a character expression - - Purpose: add axioms stating that the character of the string at the given - position is equal to the returned value - -\*******************************************************************/ - +/// add axioms stating that the character of the string at the given position is +/// equal to the returned value +/// \par parameters: function application with two arguments: a string and an +/// integer +/// \return a character expression exprt string_constraint_generatort::add_axioms_for_char_at( const function_application_exprt &f) { @@ -645,18 +493,9 @@ exprt string_constraint_generatort::add_axioms_for_char_at( return char_sym; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_to_char_array - - Inputs: function application with one string argument - - Outputs: a char array expression - - Purpose: add axioms corresponding to the String.toCharArray java function - -\*******************************************************************/ - +/// add axioms corresponding to the String.toCharArray java function +/// \par parameters: function application with one string argument +/// \return a char array expression exprt string_constraint_generatort::add_axioms_for_to_char_array( const function_application_exprt &f) { @@ -664,17 +503,9 @@ exprt string_constraint_generatort::add_axioms_for_to_char_array( return str.content(); } -/*******************************************************************\ - -Function: string_constraint_generatort::set_string_symbol_equal_to_expr - - Inputs: a symbol and a string - - Purpose: add a correspondence to make sure the symbol points to the - same string as the second argument - -\*******************************************************************/ - +/// add a correspondence to make sure the symbol points to the same string as +/// the second argument +/// \par parameters: a symbol and a string void string_constraint_generatort::set_string_symbol_equal_to_expr( const symbol_exprt &sym, const exprt &str) { diff --git a/src/solvers/refinement/string_constraint_generator_testing.cpp b/src/solvers/refinement/string_constraint_generator_testing.cpp index 8b1c7bca9d4..dc28a5198e9 100644 --- a/src/solvers/refinement/string_constraint_generator_testing.cpp +++ b/src/solvers/refinement/string_constraint_generator_testing.cpp @@ -7,22 +7,15 @@ Author: Romain Brenguier, romain.brenguier@diffblue.com \*******************************************************************/ -#include - -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_is_prefix - - Inputs: a prefix string, a string and an integer offset - - Outputs: a Boolean expression +/// \file +/// Generates string constraints for string functions that return Boolean values - Purpose: add axioms stating that the returned expression is true exactly - when the first string is a prefix of the second one, starting at - position offset - -\*******************************************************************/ +#include +/// add axioms stating that the returned expression is true exactly when the +/// first string is a prefix of the second one, starting at position offset +/// \par parameters: a prefix string, a string and an integer offset +/// \return a Boolean expression exprt string_constraint_generatort::add_axioms_for_is_prefix( const string_exprt &prefix, const string_exprt &str, const exprt &offset) { @@ -69,20 +62,12 @@ exprt string_constraint_generatort::add_axioms_for_is_prefix( return isprefix; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_is_prefix - - Inputs: a function application with 2 or 3 arguments and a Boolean telling - whether the prefix is the second argument (when swap_arguments is - true) or the first argument - - Outputs: a Boolean expression - - Purpose: add axioms corresponding to the String.isPrefix java function - -\*******************************************************************/ - +/// add axioms corresponding to the String.isPrefix java function +/// \par parameters: a function application with 2 or 3 arguments and a Boolean +/// telling +/// whether the prefix is the second argument (when swap_arguments is +/// true) or the first argument +/// \return a Boolean expression exprt string_constraint_generatort::add_axioms_for_is_prefix( const function_application_exprt &f, bool swap_arguments) { @@ -98,19 +83,10 @@ exprt string_constraint_generatort::add_axioms_for_is_prefix( return typecast_exprt(add_axioms_for_is_prefix(s0, s1, offset), f.type()); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_is_empty - - Inputs: function application with a string argument - - Outputs: a Boolean expression - - Purpose: add axioms stating that the returned value is true exactly when - the argument string is empty - -\*******************************************************************/ - +/// add axioms stating that the returned value is true exactly when the argument +/// string is empty +/// \par parameters: function application with a string argument +/// \return a Boolean expression exprt string_constraint_generatort::add_axioms_for_is_empty( const function_application_exprt &f) { @@ -127,20 +103,12 @@ exprt string_constraint_generatort::add_axioms_for_is_empty( return typecast_exprt(is_empty, f.type()); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_is_suffix - - Inputs: a function application with 2 or 3 arguments and a Boolean telling - whether the suffix is the second argument (when swap_arguments is - true) or the first argument - - Outputs: a Boolean expression - - Purpose: add axioms corresponding to the String.isSuffix java function - -\*******************************************************************/ - +/// add axioms corresponding to the String.isSuffix java function +/// \par parameters: a function application with 2 or 3 arguments and a Boolean +/// telling +/// whether the suffix is the second argument (when swap_arguments is +/// true) or the first argument +/// \return a Boolean expression exprt string_constraint_generatort::add_axioms_for_is_suffix( const function_application_exprt &f, bool swap_arguments) { @@ -189,18 +157,9 @@ exprt string_constraint_generatort::add_axioms_for_is_suffix( return tc_issuffix; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_contains - - Inputs: function application with two string arguments - - Outputs: a Boolean expression - - Purpose: add axioms corresponding to the String.contains java function - -\*******************************************************************/ - +/// add axioms corresponding to the String.contains java function +/// \par parameters: function application with two string arguments +/// \return a Boolean expression exprt string_constraint_generatort::add_axioms_for_contains( const function_application_exprt &f) { diff --git a/src/solvers/refinement/string_constraint_generator_transformation.cpp b/src/solvers/refinement/string_constraint_generator_transformation.cpp index 83735e0d5b5..01395b25cc1 100644 --- a/src/solvers/refinement/string_constraint_generator_transformation.cpp +++ b/src/solvers/refinement/string_constraint_generator_transformation.cpp @@ -7,25 +7,20 @@ Author: Romain Brenguier, romain.brenguier@diffblue.com \*******************************************************************/ -#include - -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_set_length - - Inputs: function application with two arguments, the first of which is - a string and the second an integer which should have same type has - return by get_index_type() - - Outputs: a new string expression +/// \file +/// Generates string constraints for string transformations, that is, functions +/// taking one string and returning another - Purpose: add axioms to say that the returned string expression has length - given by the second argument and whose characters are equal to - those of the first argument for the positions which are defined in - both strings - -\*******************************************************************/ +#include +/// add axioms to say that the returned string expression has length given by +/// the second argument and whose characters are equal to those of the first +/// argument for the positions which are defined in both strings +/// \par parameters: function application with two arguments, the first of which +/// is +/// a string and the second an integer which should have same type has +/// return by get_index_type() +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_set_length( const function_application_exprt &f) { @@ -56,21 +51,13 @@ string_exprt string_constraint_generatort::add_axioms_for_set_length( } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_substring - - Inputs: function application with one string argument, one start index - argument and an optional end index argument - - Outputs: a new string expression - - Purpose: add axioms corresponding to the String.substring java function - Warning: the specification may not be correct for the case where the - string is shorter than the end index - -\*******************************************************************/ - +/// add axioms corresponding to the String.substring java function Warning: the +/// specification may not be correct for the case where the string is shorter +/// than the end index +/// \par parameters: function application with one string argument, one start +/// index +/// argument and an optional end index argument +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_substring( const function_application_exprt &f) { @@ -91,20 +78,12 @@ string_exprt string_constraint_generatort::add_axioms_for_substring( return add_axioms_for_substring(str, i, j); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_substring - - Inputs: a string expression, an expression for the start index, and an - expression for the end index - - Outputs: a new string expression - - Purpose: add axioms stating that the returned string expression is equal - to the input one starting at `start` and ending before `end` - -\*******************************************************************/ - +/// add axioms stating that the returned string expression is equal to the input +/// one starting at `start` and ending before `end` +/// \par parameters: a string expression, an expression for the start index, and +/// an +/// expression for the end index +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_substring( const string_exprt &str, const exprt &start, const exprt &end) { @@ -139,18 +118,9 @@ string_exprt string_constraint_generatort::add_axioms_for_substring( return res; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_trim - - Inputs: function application with one string argument - - Outputs: a new string expression - - Purpose: add axioms corresponding to the String.trim java function - -\*******************************************************************/ - +/// add axioms corresponding to the String.trim java function +/// \par parameters: function application with one string argument +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_trim( const function_application_exprt &expr) { @@ -221,18 +191,9 @@ string_exprt string_constraint_generatort::add_axioms_for_trim( return res; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_to_lower_case - - Inputs: function application with one string argument - - Outputs: a new string expression - - Purpose: add axioms corresponding to the String.toLowerCase java function - -\*******************************************************************/ - +/// add axioms corresponding to the String.toLowerCase java function +/// \par parameters: function application with one string argument +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_to_lower_case( const function_application_exprt &expr) { @@ -274,18 +235,9 @@ string_exprt string_constraint_generatort::add_axioms_for_to_lower_case( return res; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_to_upper_case - - Inputs: function application with one string argument - - Outputs: a new string expression - - Purpose: add axioms corresponding to the String.toUpperCase java function - -\*******************************************************************/ - +/// add axioms corresponding to the String.toUpperCase java function +/// \par parameters: function application with one string argument +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_to_upper_case( const function_application_exprt &expr) { @@ -326,22 +278,13 @@ string_exprt string_constraint_generatort::add_axioms_for_to_upper_case( } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_char_set - - Inputs: function application with three arguments, the first is a string - the second an index and the third a character - - Outputs: a new string expression - - Purpose: add axioms corresponding stating that the result is similar to - that of the StringBuilder.setCharAt java function - Warning: this may be underspecified in the case wher the index exceed - the length of the string - -\*******************************************************************/ - +/// add axioms corresponding stating that the result is similar to that of the +/// StringBuilder.setCharAt java function Warning: this may be underspecified in +/// the case wher the index exceed the length of the string +/// \par parameters: function application with three arguments, the first is a +/// string +/// the second an index and the third a character +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_char_set( const function_application_exprt &f) { @@ -362,19 +305,11 @@ string_exprt string_constraint_generatort::add_axioms_for_char_set( return res; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_replace - - Inputs: function application with three arguments, the first is a string, - the second and the third are characters - - Outputs: a new string expression - - Purpose: add axioms corresponding to the String.replace java function - -\*******************************************************************/ - +/// add axioms corresponding to the String.replace java function +/// \par parameters: function application with three arguments, the first is a +/// string, +/// the second and the third are characters +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_replace( const function_application_exprt &f) { @@ -404,20 +339,11 @@ string_exprt string_constraint_generatort::add_axioms_for_replace( return res; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_delete_char_at - - Inputs: function application with two arguments, the first is a string - and the second is an index - - Outputs: a new string expression - - Purpose: add axioms corresponding to the StringBuilder.deleteCharAt java - function - -\*******************************************************************/ - +/// add axioms corresponding to the StringBuilder.deleteCharAt java function +/// \par parameters: function application with two arguments, the first is a +/// string +/// and the second is an index +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_delete_char_at( const function_application_exprt &f) { @@ -427,20 +353,11 @@ string_exprt string_constraint_generatort::add_axioms_for_delete_char_at( str, args(f, 2)[1], plus_exprt(args(f, 2)[1], index_one)); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_delete - - Inputs: a string expression, a start index and an end index - - Outputs: a new string expression - - Purpose: add axioms stating that the returned string corresponds to the input - one where we removed characters between the positions - start (included) and end (not included) - -\*******************************************************************/ - +/// add axioms stating that the returned string corresponds to the input one +/// where we removed characters between the positions start (included) and end +/// (not included) +/// \par parameters: a string expression, a start index and an end index +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_delete( const string_exprt &str, const exprt &start, const exprt &end) { @@ -452,19 +369,10 @@ string_exprt string_constraint_generatort::add_axioms_for_delete( return add_axioms_for_concat(str1, str2); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_delete - - Inputs: function application with three arguments: a string - expression, a start index and an end index - - Outputs: a new string expression - - Purpose: add axioms corresponding to the StringBuilder.delete java function - -\*******************************************************************/ - +/// add axioms corresponding to the StringBuilder.delete java function +/// \par parameters: function application with three arguments: a string +/// expression, a start index and an end index +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_delete( const function_application_exprt &f) { diff --git a/src/solvers/refinement/string_constraint_generator_valueof.cpp b/src/solvers/refinement/string_constraint_generator_valueof.cpp index d1030e5e085..66364bcdc2f 100644 --- a/src/solvers/refinement/string_constraint_generator_valueof.cpp +++ b/src/solvers/refinement/string_constraint_generator_valueof.cpp @@ -7,21 +7,17 @@ Author: Romain Brenguier, romain.brenguier@diffblue.com \*******************************************************************/ -#include -#include - -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_from_int +/// \file +/// Generates string constraints for functions generating strings from other +/// types, in particular int, long, float, double, char, bool - Inputs: function application with one integer argument - - Outputs: a new string expression - - Purpose: add axioms corresponding to the String.valueOf(I) java function +#include -\*******************************************************************/ +#include +/// add axioms corresponding to the String.valueOf(I) java function +/// \par parameters: function application with one integer argument +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_from_int( const function_application_exprt &expr) { @@ -29,18 +25,9 @@ string_exprt string_constraint_generatort::add_axioms_from_int( return add_axioms_from_int(args(expr, 1)[0], MAX_INTEGER_LENGTH, ref_type); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_from_long - - Inputs: function application with one long argument - - Outputs: a new string expression - - Purpose: add axioms corresponding to the String.valueOf(J) java function - -\*******************************************************************/ - +/// add axioms corresponding to the String.valueOf(J) java function +/// \par parameters: function application with one long argument +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_from_long( const function_application_exprt &expr) { @@ -48,56 +35,30 @@ string_exprt string_constraint_generatort::add_axioms_from_long( return add_axioms_from_int(args(expr, 1)[0], MAX_LONG_LENGTH, ref_type); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_from_float - - Inputs: function application with one float argument - - Outputs: a new string expression - - Purpose: add axioms corresponding to the String.valueOf(F) java function - -\*******************************************************************/ - +/// add axioms corresponding to the String.valueOf(F) java function +/// \par parameters: function application with one float argument +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_from_float( const function_application_exprt &f) { return add_axioms_from_float(args(f, 1)[0], false); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_from_double - - Inputs: function application with one double argument - - Outputs: a new string expression - - Purpose: add axioms corresponding to the String.valueOf(D) java function - -\*******************************************************************/ - +/// add axioms corresponding to the String.valueOf(D) java function +/// \par parameters: function application with one double argument +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_from_double( const function_application_exprt &f) { return add_axioms_from_float(args(f, 1)[0], true); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_from_float - - Inputs: float expression and Boolean signaling that the argument has - double precision - - Outputs: a new string expression - - Purpose: add axioms corresponding to the String.valueOf(F) java function - Warning: we currently only have partial specification - -\*******************************************************************/ - +/// add axioms corresponding to the String.valueOf(F) java function Warning: we +/// currently only have partial specification +/// \par parameters: float expression and Boolean signaling that the argument +/// has +/// double precision +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_from_float( const exprt &f, bool double_precision) { @@ -190,18 +151,9 @@ string_exprt string_constraint_generatort::add_axioms_from_float( } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_from_bool - - Inputs: function application with on Boolean argument - - Outputs: a new string expression - - Purpose: add axioms corresponding to the String.valueOf(Z) java function - -\*******************************************************************/ - +/// add axioms corresponding to the String.valueOf(Z) java function +/// \par parameters: function application with on Boolean argument +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_from_bool( const function_application_exprt &f) { @@ -210,19 +162,10 @@ string_exprt string_constraint_generatort::add_axioms_from_bool( } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_from_bool - - Inputs: Boolean expression - - Outputs: a new string expression - - Purpose: add axioms stating that the returned string equals "true" when - the Boolean expression is true and "false" when it is false - -\*******************************************************************/ - +/// add axioms stating that the returned string equals "true" when the Boolean +/// expression is true and "false" when it is false +/// \par parameters: Boolean expression +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_from_bool( const exprt &b, const refined_string_typet &ref_type) { @@ -267,38 +210,20 @@ string_exprt string_constraint_generatort::add_axioms_from_bool( return res; } -/*******************************************************************\ - -Function: smallest_by_digit - - Inputs: number of digit - - Outputs: an integer with the right number of digit - - Purpose: gives the smallest integer with the specified number of digits - -\*******************************************************************/ - +/// gives the smallest integer with the specified number of digits +/// \par parameters: number of digit +/// \return an integer with the right number of digit static mp_integer smallest_by_digit(int nb) { return power(10, nb-1); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_from_int - - Inputs: a signed integer expression, and a maximal size for the string - representation - - Outputs: a string expression - - Purpose: add axioms to say the string corresponds to the result of - String.valueOf(I) or String.valueOf(J) java functions applied on the - integer expression - -\*******************************************************************/ - +/// add axioms to say the string corresponds to the result of String.valueOf(I) +/// or String.valueOf(J) java functions applied on the integer expression +/// \par parameters: a signed integer expression, and a maximal size for the +/// string +/// representation +/// \return a string expression string_exprt string_constraint_generatort::add_axioms_from_int( const exprt &i, size_t max_size, const refined_string_typet &ref_type) { @@ -400,18 +325,10 @@ string_exprt string_constraint_generatort::add_axioms_from_int( return res; } -/*******************************************************************\ - -Function: string_constraint_generatort::int_of_hex_char - - Inputs: a character expression in the following set: 0123456789abcdef - - Outputs: an integer expression - - Purpose: returns the value represented by the character - -\*******************************************************************/ - +/// returns the value represented by the character +/// \par parameters: a character expression in the following set: +/// 0123456789abcdef +/// \return an integer expression exprt string_constraint_generatort::int_of_hex_char(const exprt &chr) const { exprt zero_char=constant_char('0', chr.type()); @@ -423,19 +340,10 @@ exprt string_constraint_generatort::int_of_hex_char(const exprt &chr) const minus_exprt(chr, zero_char)); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_from_int_hex - - Inputs: one integer argument - - Outputs: a new string expression - - Purpose: add axioms stating that the returned string corresponds to the - integer argument written in hexadecimal - -\*******************************************************************/ - +/// add axioms stating that the returned string corresponds to the integer +/// argument written in hexadecimal +/// \par parameters: one integer argument +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_from_int_hex( const exprt &i, const refined_string_typet &ref_type) { @@ -489,18 +397,9 @@ string_exprt string_constraint_generatort::add_axioms_from_int_hex( return res; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_int_hex - - Inputs: function application with integer argument - - Outputs: a new string expression - - Purpose: add axioms corresponding to the Integer.toHexString(I) java function - -\*******************************************************************/ - +/// add axioms corresponding to the Integer.toHexString(I) java function +/// \par parameters: function application with integer argument +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_from_int_hex( const function_application_exprt &f) { @@ -508,18 +407,9 @@ string_exprt string_constraint_generatort::add_axioms_from_int_hex( return add_axioms_from_int_hex(args(f, 1)[0], ref_type); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_from_char - - Inputs: function application one char argument - - Outputs: a new string expression - - Purpose: add axioms corresponding to the String.valueOf(C) java function - -\*******************************************************************/ - +/// add axioms corresponding to the String.valueOf(C) java function +/// \par parameters: function application one char argument +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_from_char( const function_application_exprt &f) { @@ -527,19 +417,10 @@ string_exprt string_constraint_generatort::add_axioms_from_char( return add_axioms_from_char(args(f, 1)[0], ref_type); } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_from_char - - Inputs: one expression of type char - - Outputs: a new string expression - - Purpose: add axioms stating that the returned string has length 1 and - the character it contains correspond to the input expression - -\*******************************************************************/ - +/// add axioms stating that the returned string has length 1 and the character +/// it contains correspond to the input expression +/// \par parameters: one expression of type char +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_from_char( const exprt &c, const refined_string_typet &ref_type) { @@ -549,19 +430,10 @@ string_exprt string_constraint_generatort::add_axioms_from_char( return res; } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_value_of - - Inputs: function application with one or three arguments - - Outputs: a new string expression - - Purpose: add axioms corresponding to the String.valueOf([C) and - String.valueOf([CII) functions - -\*******************************************************************/ - +/// add axioms corresponding to the String.valueOf([C) and String.valueOf([CII) +/// functions +/// \par parameters: function application with one or three arguments +/// \return a new string expression string_exprt string_constraint_generatort::add_axioms_for_value_of( const function_application_exprt &f) { @@ -595,18 +467,9 @@ string_exprt string_constraint_generatort::add_axioms_for_value_of( } } -/*******************************************************************\ - -Function: string_constraint_generatort::add_axioms_for_parse_int - - Inputs: function application with one string expression - - Outputs: an integer expression - - Purpose: add axioms corresponding to the Integer.parseInt java function - -\*******************************************************************/ - +/// add axioms corresponding to the Integer.parseInt java function +/// \par parameters: function application with one string expression +/// \return an integer expression exprt string_constraint_generatort::add_axioms_for_parse_int( const function_application_exprt &f) { diff --git a/src/solvers/refinement/string_refinement.cpp b/src/solvers/refinement/string_refinement.cpp index 16b89bc43c8..34e3217e27a 100644 --- a/src/solvers/refinement/string_refinement.cpp +++ b/src/solvers/refinement/string_refinement.cpp @@ -10,12 +10,20 @@ Author: Alberto Griggio, alberto.griggio@gmail.com \*******************************************************************/ +/// \file +/// String support via creating string constraints and progressively +/// instantiating the universal constraints as needed. The procedure is +/// described in the PASS paper at HVC'13: "PASS: String Solving with +/// Parameterized Array and Interval Automaton" by Guodong Li and Indradeep +/// Ghosh. + +#include + #include #include #include #include #include -#include #include string_refinementt::string_refinementt( @@ -25,14 +33,7 @@ string_refinementt::string_refinementt( initial_loop_bound(refinement_bound) { } -/*******************************************************************\ - -Function: string_refinementt::set_mode - - Purpose: determine which language should be used - -\*******************************************************************/ - +/// determine which language should be used void string_refinementt::set_mode() { debug() << "initializing mode" << eom; @@ -42,14 +43,7 @@ void string_refinementt::set_mode() generator.set_mode(mode); } -/*******************************************************************\ - -Function: string_refinementt::display_index_set - - Purpose: display the current index set, for debugging - -\*******************************************************************/ - +/// display the current index set, for debugging void string_refinementt::display_index_set() { for(const auto &i : index_set) @@ -63,15 +57,8 @@ void string_refinementt::display_index_set() } } -/*******************************************************************\ - -Function: string_refinementt::add_instantiations - - Purpose: compute the index set for all formulas, instantiate the formulas - with the found indexes, and add them as lemmas. - -\*******************************************************************/ - +/// compute the index set for all formulas, instantiate the formulas with the +/// found indexes, and add them as lemmas. void string_refinementt::add_instantiations() { debug() << "string_constraint_generatort::add_instantiations: " @@ -98,19 +85,10 @@ void string_refinementt::add_instantiations() } } -/*******************************************************************\ - -Function: string_refinementt::convert_rest - - Inputs: an expression - - Outputs: a literal - - Purpose: if the expression is a function application, we convert it - using our own convert_function_application method - -\*******************************************************************/ - +/// if the expression is a function application, we convert it using our own +/// convert_function_application method +/// \par parameters: an expression +/// \return a literal literalt string_refinementt::convert_rest(const exprt &expr) { if(expr.id()==ID_function_application) @@ -126,20 +104,11 @@ literalt string_refinementt::convert_rest(const exprt &expr) } } -/*******************************************************************\ - -Function: string_refinementt::convert_symbol - - Inputs: an expression - - Outputs: a bitvector - - Purpose: if the expression as string type, look up for the string in the - list of string symbols that we maintain, and convert it; - otherwise use the method of the parent class - -\*******************************************************************/ - +/// if the expression as string type, look up for the string in the list of +/// string symbols that we maintain, and convert it; otherwise use the method of +/// the parent class +/// \par parameters: an expression +/// \return a bitvector bvt string_refinementt::convert_symbol(const exprt &expr) { const typet &type=expr.type(); @@ -157,20 +126,10 @@ bvt string_refinementt::convert_symbol(const exprt &expr) return supert::convert_symbol(expr); } -/*******************************************************************\ - -Function: string_refinementt::convert_function_application - - Inputs: a function_application - - Outputs: a bitvector - - Purpose: generate an expression, add lemmas stating that this expression - corresponds to the result of the given function call, and convert - this expression - -\*******************************************************************/ - +/// generate an expression, add lemmas stating that this expression corresponds +/// to the result of the given function call, and convert this expression +/// \par parameters: a function_application +/// \return a bitvector bvt string_refinementt::convert_function_application (const function_application_exprt &expr) { @@ -180,18 +139,9 @@ bvt string_refinementt::convert_function_application return convert_bv(f); } -/*******************************************************************\ - -Function: string_refinementt::boolbv_set_equality_to_true - - Inputs: an equality expression - - Outputs: a Boolean flag to signal a proble - - Purpose: add lemmas to the solver corresponding to the given equation - -\*******************************************************************/ - +/// add lemmas to the solver corresponding to the given equation +/// \par parameters: an equality expression +/// \return a Boolean flag to signal a proble bool string_refinementt::boolbv_set_equality_to_true(const equal_exprt &expr) { if(!equality_propagation) @@ -248,17 +198,9 @@ bool string_refinementt::boolbv_set_equality_to_true(const equal_exprt &expr) return true; } -/*******************************************************************\ - -Function: string_refinementt::dec_solve - - Outputs: result of the decision procedure - - Purpose: use a refinement loop to instantiate universal axioms, - call the sat solver, and instantiate more indexes if needed. - -\*******************************************************************/ - +/// use a refinement loop to instantiate universal axioms, call the sat solver, +/// and instantiate more indexes if needed. +/// \return result of the decision procedure decision_proceduret::resultt string_refinementt::dec_solve() { for(const exprt &axiom : generator.axioms) @@ -341,19 +283,9 @@ decision_proceduret::resultt string_refinementt::dec_solve() return D_ERROR; } -/*******************************************************************\ - -Function: string_refinementt::convert_bool_bv - - Inputs: a Boolean and a expression with the desired type - - Outputs: a bit vector - - Purpose: fills as many 0 as necessary in the bit vectors to have the - right width - -\*******************************************************************/ - +/// fills as many 0 as necessary in the bit vectors to have the right width +/// \par parameters: a Boolean and a expression with the desired type +/// \return a bit vector bvt string_refinementt::convert_bool_bv(const exprt &boole, const exprt &orig) { bvt ret; @@ -363,16 +295,8 @@ bvt string_refinementt::convert_bool_bv(const exprt &boole, const exprt &orig) return ret; } -/*******************************************************************\ - -Function: string_refinementt::add_lemma - - Inputs: a lemma - - Purpose: add the given lemma to the solver - -\*******************************************************************/ - +/// add the given lemma to the solver +/// \par parameters: a lemma void string_refinementt::add_lemma(const exprt &lemma, bool add_to_index_set) { if(!seen_instances.insert(lemma).second) @@ -391,19 +315,10 @@ void string_refinementt::add_lemma(const exprt &lemma, bool add_to_index_set) cur.push_back(lemma); } -/*******************************************************************\ - -Function: string_refinementt::string_of_array - - Inputs: a constant array expression and a integer expression - - Outputs: a string - - Purpose: convert the content of a string to a more readable representation. - This should only be used for debbuging. - -\*******************************************************************/ - +/// convert the content of a string to a more readable representation. This +/// should only be used for debbuging. +/// \par parameters: a constant array expression and a integer expression +/// \return a string std::string string_refinementt::string_of_array( const exprt &arr, const exprt &size) const { @@ -449,18 +364,9 @@ std::string string_refinementt::string_of_array( return buf.str(); } -/*******************************************************************\ - -Function: string_refinementt::get_array - - Inputs: an array expression and a integer expression - - Outputs: a string expression - - Purpose: gets a model of an array and put it in a certain form - -\*******************************************************************/ - +/// gets a model of an array and put it in a certain form +/// \par parameters: an array expression and a integer expression +/// \return a string expression exprt string_refinementt::get_array(const exprt &arr, const exprt &size) { exprt val=get(arr); @@ -490,16 +396,8 @@ exprt string_refinementt::get_array(const exprt &arr, const exprt &size) } } -/*******************************************************************\ - -Function: string_refinementt::check_axioms - - Outputs: a Boolean - - Purpose: return true if the current model satisfies all the axioms - -\*******************************************************************/ - +/// return true if the current model satisfies all the axioms +/// \return a Boolean bool string_refinementt::check_axioms() { debug() << "string_refinementt::check_axioms: ===============" @@ -618,18 +516,10 @@ bool string_refinementt::check_axioms() } } -/*******************************************************************\ - -Function: string_refinementt::map_representation_of_sum - - Inputs: an expression with only addition and substraction - - Outputs: a map where each leaf of the input is mapped to the number of times - it is added. For instance, expression $x + x - y$ would give the map - x -> 2, y -> -1. - -\*******************************************************************/ - +/// \par parameters: an expression with only addition and substraction +/// \return a map where each leaf of the input is mapped to the number of times +/// it is added. For instance, expression $x + x - y$ would give the map x -> +/// 2, y -> -1. std::map string_refinementt::map_representation_of_sum( const exprt &f) const { @@ -669,18 +559,10 @@ std::map string_refinementt::map_representation_of_sum( return elems; } -/*******************************************************************\ - -Function: string_refinementt::sum_over_map - - Inputs: a map from expressions to integers - - Outputs: a expression for the sum of each element in the map a number of - times given by the corresponding integer in the map. - For a map x -> 2, y -> -1 would give an expression $x + x - y$. - -\*******************************************************************/ - +/// \par parameters: a map from expressions to integers +/// \return a expression for the sum of each element in the map a number of +/// times given by the corresponding integer in the map. For a map x -> 2, y +/// -> -1 would give an expression $x + x - y$. exprt string_refinementt::sum_over_map( std::map &m, bool negated) const { @@ -742,37 +624,21 @@ exprt string_refinementt::sum_over_map( return index_const; } -/*******************************************************************\ - -Function: string_refinementt::simplify_sum - - Inputs: an expression with only plus and minus expr - - Outputs: an equivalent expression in a cannonical form - -\*******************************************************************/ - +/// \par parameters: an expression with only plus and minus expr +/// \return an equivalent expression in a cannonical form exprt string_refinementt::simplify_sum(const exprt &f) const { std::map map=map_representation_of_sum(f); return sum_over_map(map); } -/*******************************************************************\ - -Function: string_refinementt::compute_inverse_function - - Inputs: a symbol qvar, an expression val, an expression f containing + and − - operations in which qvar should appear exactly once. - - Outputs: an expression corresponding of $f^{−1}(val)$ where $f$ is seen as a - function of $qvar$, i.e. the value that is necessary for qvar for f - to be equal to val. For instance, if `f` corresponds to the expression - $q + x$, `compute_inverse_function(q,v,f)` returns an expression for - $v - x$. - -\*******************************************************************/ - +/// \par parameters: a symbol qvar, an expression val, an expression f +/// containing + and − +/// operations in which qvar should appear exactly once. +/// \return an expression corresponding of $f^{−1}(val)$ where $f$ is seen as +/// a function of $qvar$, i.e. the value that is necessary for qvar for f to +/// be equal to val. For instance, if `f` corresponds to the expression $q + +/// x$, `compute_inverse_function(q,v,f)` returns an expression for $v - x$. exprt string_refinementt::compute_inverse_function( const exprt &qvar, const exprt &val, const exprt &f) { @@ -822,18 +688,9 @@ class find_qvar_visitort: public const_expr_visitort } }; -/*******************************************************************\ - -Function: find_qvar - - Inputs: an index expression and a symbol qvar - - Outputs: a Boolean - - Purpose: looks for the symbol and return true if it is found - -\*******************************************************************/ - +/// looks for the symbol and return true if it is found +/// \par parameters: an index expression and a symbol qvar +/// \return a Boolean static bool find_qvar(const exprt index, const symbol_exprt &qvar) { find_qvar_visitort v2(qvar); @@ -841,17 +698,9 @@ static bool find_qvar(const exprt index, const symbol_exprt &qvar) return v2.found; } -/*******************************************************************\ - -Function: string_refinementt::initial_index_set - - Inputs: a list of string constraints - - Purpose: add to the index set all the indices that appear in the formulas - and the upper bound minus one - -\*******************************************************************/ - +/// add to the index set all the indices that appear in the formulas and the +/// upper bound minus one +/// \par parameters: a list of string constraints void string_refinementt::initial_index_set( const std::vector &string_axioms) { @@ -859,33 +708,17 @@ void string_refinementt::initial_index_set( initial_index_set(axiom); } -/*******************************************************************\ - -Function: string_refinementt::update_index_set - - Inputs: a list of string constraints - - Purpose: add to the index set all the indices that appear in the formulas - -\*******************************************************************/ - +/// add to the index set all the indices that appear in the formulas +/// \par parameters: a list of string constraints void string_refinementt::update_index_set(const std::vector &cur) { for(const auto &axiom : cur) update_index_set(axiom); } -/*******************************************************************\ - -Function: string_refinementt::initial_index_set - - Inputs: a string constraint - - Purpose: add to the index set all the indices that appear in the formula - and the upper bound minus one - -\*******************************************************************/ - +/// add to the index set all the indices that appear in the formula and the +/// upper bound minus one +/// \par parameters: a string constraint void string_refinementt::initial_index_set(const string_constraintt &axiom) { symbol_exprt qvar=axiom.univ_var(); @@ -927,16 +760,8 @@ void string_refinementt::initial_index_set(const string_constraintt &axiom) } } -/*******************************************************************\ - -Function: string_refinementt::update_index_set - - Inputs: a string constraint - - Purpose: add to the index set all the indices that appear in the formula - -\*******************************************************************/ - +/// add to the index set all the indices that appear in the formula +/// \par parameters: a string constraint void string_refinementt::update_index_set(const exprt &formula) { std::list to_process; @@ -989,20 +814,10 @@ class find_index_visitort: public const_expr_visitort } }; -/*******************************************************************\ - -Function: string_refinementt::update_index_set - - Inputs: a formula expr and a char array str - - Outputs: an index expression - - Purpose: find an index used in the expression for str, for instance - with arguments (str[k] == 'a') and str, the function should - return k - -\*******************************************************************/ - +/// find an index used in the expression for str, for instance with arguments +/// (str[k] == 'a') and str, the function should return k +/// \par parameters: a formula expr and a char array str +/// \return an index expression exprt find_index(const exprt &expr, const exprt &str) { find_index_visitort v1(str); @@ -1015,21 +830,13 @@ exprt find_index(const exprt &expr, const exprt &str) } -/*******************************************************************\ - -Function: string_refinementt::instantiate - - Inputs: an universaly quantified formula `axiom`, an array of char - variable `str`, and an index expression `val`. - - Outputs: substitute `qvar` the universaly quantified variable of `axiom`, by - an index `val`, in `axiom`, so that the index used for `str` equals - `val`. For instance, if `axiom` corresponds to - $\forall q. s[q+x]='a' && t[q]='b'$, `instantiate(axom,s,v)` would return - an expression for $s[v]='a' && t[v-x]='b'$. - -\*******************************************************************/ - +/// \par parameters: an universaly quantified formula `axiom`, an array of char +/// variable `str`, and an index expression `val`. +/// \return substitute `qvar` the universaly quantified variable of `axiom`, by +/// an index `val`, in `axiom`, so that the index used for `str` equals `val`. +/// For instance, if `axiom` corresponds to $\forall q. s[q+x]='a' && +/// t[q]='b'$, `instantiate(axom,s,v)` would return an expression for +/// $s[v]='a' && t[v-x]='b'$. exprt string_refinementt::instantiate( const string_constraintt &axiom, const exprt &str, const exprt &val) { diff --git a/src/solvers/refinement/string_refinement.h b/src/solvers/refinement/string_refinement.h index be0cd332bc3..aa28f8a0c96 100644 --- a/src/solvers/refinement/string_refinement.h +++ b/src/solvers/refinement/string_refinement.h @@ -10,6 +10,13 @@ Author: Alberto Griggio, alberto.griggio@gmail.com \*******************************************************************/ +/// \file +/// String support via creating string constraints and progressively +/// instantiating the universal constraints as needed. The procedure is +/// described in the PASS paper at HVC'13: "PASS: String Solving with +/// Parameterized Array and Interval Automaton" by Guodong Li and Indradeep +/// Ghosh + #ifndef CPROVER_SOLVERS_REFINEMENT_STRING_REFINEMENT_H #define CPROVER_SOLVERS_REFINEMENT_STRING_REFINEMENT_H diff --git a/src/solvers/sat/cnf.cpp b/src/solvers/sat/cnf.cpp index a69947df8f4..bed97954bac 100644 --- a/src/solvers/sat/cnf.cpp +++ b/src/solvers/sat/cnf.cpp @@ -6,27 +6,22 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// CNF Generation, via Tseitin + +#include "cnf.h" + #include #include #include #include -#include "cnf.h" // #define VERBOSE -/*******************************************************************\ - -Function: cnft::gate_and - - Inputs: Two input signals to the AND gate, one output - - Outputs: Side effect: add clauses that encodes relation between - inputs/output via lcnf - - Purpose: Tseitin encoding of conjunction of two literals - -\*******************************************************************/ - +/// Tseitin encoding of conjunction of two literals +/// \par parameters: Two input signals to the AND gate, one output +/// \return Side effect: add clauses that encodes relation between inputs/output +/// via lcnf void cnft::gate_and(literalt a, literalt b, literalt o) { // a*b=c <==> (a + o')( b + o')(a'+b'+o) @@ -48,18 +43,8 @@ void cnft::gate_and(literalt a, literalt b, literalt o) lcnf(lits); } -/*******************************************************************\ - -Function: cnft::gate_or - - Inputs: Two input signals to the OR gate, one output - - Outputs: - - Purpose: Tseitin encoding of disjunction of two literals - -\*******************************************************************/ - +/// Tseitin encoding of disjunction of two literals +/// \par parameters: Two input signals to the OR gate, one output void cnft::gate_or(literalt a, literalt b, literalt o) { // a+b=c <==> (a' + c)( b' + c)(a + b + c') @@ -80,18 +65,8 @@ void cnft::gate_or(literalt a, literalt b, literalt o) lcnf(lits); } -/*******************************************************************\ - -Function: cnft::gate_xor - - Inputs: Two input signals to the XOR gate, one output - - Outputs: - - Purpose: Tseitin encoding of XOR of two literals - -\*******************************************************************/ - +/// Tseitin encoding of XOR of two literals +/// \par parameters: Two input signals to the XOR gate, one output void cnft::gate_xor(literalt a, literalt b, literalt o) { // a xor b = o <==> (a' + b' + o') @@ -121,18 +96,8 @@ void cnft::gate_xor(literalt a, literalt b, literalt o) lcnf(lits); } -/*******************************************************************\ - -Function: cnft::gate_nand - - Inputs: Two input signals to the NAND gate, one output - - Outputs: - - Purpose: Tseitin encoding of NAND of two literals - -\*******************************************************************/ - +/// Tseitin encoding of NAND of two literals +/// \par parameters: Two input signals to the NAND gate, one output void cnft::gate_nand(literalt a, literalt b, literalt o) { // a Nand b = o <==> (a + o)( b + o)(a' + b' + o') @@ -153,18 +118,8 @@ void cnft::gate_nand(literalt a, literalt b, literalt o) lcnf(lits); } -/*******************************************************************\ - -Function: cnft::gate_nor - - Inputs: Two input signals to the NOR gate, one output - - Outputs: - - Purpose: Tseitin encoding of NOR of two literals - -\*******************************************************************/ - +/// Tseitin encoding of NOR of two literals +/// \par parameters: Two input signals to the NOR gate, one output void cnft::gate_nor(literalt a, literalt b, literalt o) { // a Nor b = o <==> (a' + o')( b' + o')(a + b + o) @@ -185,52 +140,23 @@ void cnft::gate_nor(literalt a, literalt b, literalt o) lcnf(lits); } -/*******************************************************************\ - -Function: cnft::gate_equal - - Inputs: Two input signals to the EQUAL gate, one output - - Outputs: - - Purpose: Tseitin encoding of equality between two literals - -\*******************************************************************/ - +/// Tseitin encoding of equality between two literals +/// \par parameters: Two input signals to the EQUAL gate, one output void cnft::gate_equal(literalt a, literalt b, literalt o) { gate_xor(a, b, !o); } -/*******************************************************************\ - -Function: cnft::gate_implies - - Inputs: Two input signals to the IMPLIES gate, one output - - Outputs: - - Purpose: Tseitin encoding of implication between two literals - -\*******************************************************************/ - +/// Tseitin encoding of implication between two literals +/// \par parameters: Two input signals to the IMPLIES gate, one output void cnft::gate_implies(literalt a, literalt b, literalt o) { gate_or(!a, b, o); } -/*******************************************************************\ - -Function: cnft::land - - Inputs: Any number of inputs to the AND gate - - Outputs: Output signal of the AND gate as literal - - Purpose: Tseitin encoding of conjunction between multiple literals - -\*******************************************************************/ - +/// Tseitin encoding of conjunction between multiple literals +/// \par parameters: Any number of inputs to the AND gate +/// \return Output signal of the AND gate as literal literalt cnft::land(const bvt &bv) { if(bv.empty()) @@ -271,18 +197,9 @@ literalt cnft::land(const bvt &bv) return literal; } -/*******************************************************************\ - -Function: cnft::lor - - Inputs: Any number of inputs to the OR gate - - Outputs: Output signal of the OR gate as literal - - Purpose: Tseitin encoding of disjunction between multiple literals - -\*******************************************************************/ - +/// Tseitin encoding of disjunction between multiple literals +/// \par parameters: Any number of inputs to the OR gate +/// \return Output signal of the OR gate as literal literalt cnft::lor(const bvt &bv) { if(bv.empty()) @@ -323,18 +240,9 @@ literalt cnft::lor(const bvt &bv) return literal; } -/*******************************************************************\ - -Function: cnft::lxor - - Inputs: Any number of inputs to the XOR gate - - Outputs: Output signal of the XOR gate as literal - - Purpose: Tseitin encoding of XOR between multiple literals - -\*******************************************************************/ - +/// Tseitin encoding of XOR between multiple literals +/// \par parameters: Any number of inputs to the XOR gate +/// \return Output signal of the XOR gate as literal literalt cnft::lxor(const bvt &bv) { if(bv.empty()) @@ -352,18 +260,8 @@ literalt cnft::lxor(const bvt &bv) return literal; } -/*******************************************************************\ - -Function: cnft::land - - Inputs: Two inputs to the AND gate - - Outputs: Output signal of the AND gate as literal - - Purpose: - -\*******************************************************************/ - +/// \par parameters: Two inputs to the AND gate +/// \return Output signal of the AND gate as literal literalt cnft::land(literalt a, literalt b) { if(a.is_true() || b.is_false()) @@ -378,18 +276,8 @@ literalt cnft::land(literalt a, literalt b) return o; } -/*******************************************************************\ - -Function: cnft::lor - - Inputs: Two inputs to the OR gate - - Outputs: Output signal of the OR gate as literal - - Purpose: - -\*******************************************************************/ - +/// \par parameters: Two inputs to the OR gate +/// \return Output signal of the OR gate as literal literalt cnft::lor(literalt a, literalt b) { if(a.is_false() || b.is_true()) @@ -404,18 +292,8 @@ literalt cnft::lor(literalt a, literalt b) return o; } -/*******************************************************************\ - -Function: cnft::lxor - - Inputs: Two inputs to the XOR gate - - Outputs: Output signal of the XOR gate as literal - - Purpose: - -\*******************************************************************/ - +/// \par parameters: Two inputs to the XOR gate +/// \return Output signal of the XOR gate as literal literalt cnft::lxor(literalt a, literalt b) { if(a.is_false()) @@ -436,86 +314,30 @@ literalt cnft::lxor(literalt a, literalt b) return o; } -/*******************************************************************\ - -Function: cnft::lnand - - Inputs: Two inputs to the NAND gate - - Outputs: Output signal of the NAND gate as literal - - Purpose: - -\*******************************************************************/ - +/// \par parameters: Two inputs to the NAND gate +/// \return Output signal of the NAND gate as literal literalt cnft::lnand(literalt a, literalt b) { return !land(a, b); } -/*******************************************************************\ - -Function: cnft::lnor - - Inputs: Two inputs to the NOR gate - - Outputs: Output signal of the NOR gate as literal - - Purpose: - -\*******************************************************************/ - +/// \par parameters: Two inputs to the NOR gate +/// \return Output signal of the NOR gate as literal literalt cnft::lnor(literalt a, literalt b) { return !lor(a, b); } -/*******************************************************************\ - -Function: cnft::lequal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt cnft::lequal(literalt a, literalt b) { return !lxor(a, b); } -/*******************************************************************\ - -Function: cnft::limplies - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt cnft::limplies(literalt a, literalt b) { return lor(!a, b); } -/*******************************************************************\ - -Function: cnft::lselect - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - // Tino observed slow-downs up to 50% with OPTIMAL_COMPACT_ITE. #define COMPACT_ITE @@ -560,18 +382,8 @@ literalt cnft::lselect(literalt a, literalt b, literalt c) #endif } -/*******************************************************************\ - -Function: cnft::new_variable - - Inputs: - - Outputs: New variable as literal - - Purpose: Generate a new variable and return it as a literal - -\*******************************************************************/ - +/// Generate a new variable and return it as a literal +/// \return New variable as literal literalt cnft::new_variable() { literalt l; @@ -582,18 +394,9 @@ literalt cnft::new_variable() return l; } -/*******************************************************************\ - -Function: cnft::eliminate_duplicates - - Inputs: set of literals given as vector - - Outputs: set of literals, duplicates removed - - Purpose: eliminate duplicates from given vector of literals - -\*******************************************************************/ - +/// eliminate duplicates from given vector of literals +/// \par parameters: set of literals given as vector +/// \return set of literals, duplicates removed bvt cnft::eliminate_duplicates(const bvt &bv) { std::set s; @@ -608,19 +411,8 @@ bvt cnft::eliminate_duplicates(const bvt &bv) return dest; } -/*******************************************************************\ - -Function: cnft::process_clause - - Inputs: - - Outputs: - - Purpose: filter 'true' from clause, eliminate duplicates, - recognise trivially satisfied clauses - -\*******************************************************************/ - +/// filter 'true' from clause, eliminate duplicates, recognise trivially +/// satisfied clauses bool cnft::process_clause(const bvt &bv, bvt &dest) { dest.clear(); @@ -647,7 +439,7 @@ bool cnft::process_clause(const bvt &bv, bvt &dest) if(l.var_no()>=_no_variables) std::cout << "l.var_no()=" << l.var_no() - << " _no_variables=" << _no_variables << std::endl; + << " _no_variables=" << _no_variables << '\n'; assert(l.var_no()<_no_variables); } diff --git a/src/solvers/sat/cnf.h b/src/solvers/sat/cnf.h index 49af573bda8..236de673374 100644 --- a/src/solvers/sat/cnf.h +++ b/src/solvers/sat/cnf.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// CNF Generation, via Tseitin + #ifndef CPROVER_SOLVERS_SAT_CNF_H #define CPROVER_SOLVERS_SAT_CNF_H @@ -63,7 +66,7 @@ class cnft:public propt class cnf_solvert:public cnft { public: - cnf_solvert():status(INIT), clause_counter(0) + cnf_solvert():status(statust::INIT), clause_counter(0) { } @@ -73,7 +76,7 @@ class cnf_solvert:public cnft } protected: - typedef enum { INIT, SAT, UNSAT, ERROR } statust; + enum class statust { INIT, SAT, UNSAT, ERROR }; statust status; size_t clause_counter; }; diff --git a/src/solvers/sat/cnf_clause_list.cpp b/src/solvers/sat/cnf_clause_list.cpp index 629a7363795..20c0e5168c1 100644 --- a/src/solvers/sat/cnf_clause_list.cpp +++ b/src/solvers/sat/cnf_clause_list.cpp @@ -6,22 +6,13 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include -#include +/// \file +/// CNF Generation #include "cnf_clause_list.h" -/*******************************************************************\ - -Function: cnf_clause_listt::lcnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include void cnf_clause_listt::lcnf(const bvt &bv) { @@ -33,36 +24,12 @@ void cnf_clause_listt::lcnf(const bvt &bv) clauses.push_back(new_bv); } -/*******************************************************************\ - -Function: cnf_clause_list_assignmentt::print_assignment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cnf_clause_list_assignmentt::print_assignment(std::ostream &out) const { for(unsigned v=1; v -/*******************************************************************\ - -Function: dimacs_cnft::dimacs_cnft - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - dimacs_cnft::dimacs_cnft():break_lines(false) { } -/*******************************************************************\ - -Function: dimacs_cnf_dumpt::dimacs_cnf_dumpt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - dimacs_cnf_dumpt::dimacs_cnf_dumpt(std::ostream &_out):out(_out) { } -/*******************************************************************\ - -Function: dimacs_cnft::write_dimacs_cnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dimacs_cnft::write_dimacs_cnf(std::ostream &out) { write_problem_line(out); write_clauses(out); } -/*******************************************************************\ - -Function: dimacs_cnft::write_problem_line - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dimacs_cnft::write_problem_line(std::ostream &out) { // We start counting at 1, thus there is one variable fewer. @@ -79,18 +32,6 @@ void dimacs_cnft::write_problem_line(std::ostream &out) << clauses.size() << "\n"; } -/*******************************************************************\ - -Function: write_dimacs_clause - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static void write_dimacs_clause( const bvt &clause, std::ostream &out, @@ -117,18 +58,6 @@ static void write_dimacs_clause( out << "0" << "\n"; } -/*******************************************************************\ - -Function: dimacs_cnft::write_clauses - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dimacs_cnft::write_clauses(std::ostream &out) { for(clausest::const_iterator it=clauses.begin(); @@ -136,18 +65,6 @@ void dimacs_cnft::write_clauses(std::ostream &out) write_dimacs_clause(*it, out, break_lines); } -/*******************************************************************\ - -Function: dimacs_cnf_dumpt::lcnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void dimacs_cnf_dumpt::lcnf(const bvt &bv) { write_dimacs_clause(bv, out, true); diff --git a/src/solvers/sat/dimacs_cnf.h b/src/solvers/sat/dimacs_cnf.h index 1dac83b4a89..302fee4e36b 100644 --- a/src/solvers/sat/dimacs_cnf.h +++ b/src/solvers/sat/dimacs_cnf.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_SAT_DIMACS_CNF_H #define CPROVER_SOLVERS_SAT_DIMACS_CNF_H @@ -50,7 +51,7 @@ class dimacs_cnf_dumpt:public cnft virtual resultt prop_solve() { - return P_ERROR; + return resultt::P_ERROR; } virtual tvt l_get(literalt) const diff --git a/src/solvers/sat/pbs_dimacs_cnf.cpp b/src/solvers/sat/pbs_dimacs_cnf.cpp index 073c16ad89b..c5cd3991c53 100644 --- a/src/solvers/sat/pbs_dimacs_cnf.cpp +++ b/src/solvers/sat/pbs_dimacs_cnf.cpp @@ -6,25 +6,13 @@ Author: Alex Groce \*******************************************************************/ +#include "pbs_dimacs_cnf.h" + #include #include #include #include -#include "pbs_dimacs_cnf.h" - -/*******************************************************************\ - -Function: pbs_dimacs_cnft::write_dimacs_cnf_pb - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void pbs_dimacs_cnft::write_dimacs_pb(std::ostream &out) { double d_sum=0; @@ -64,18 +52,6 @@ void pbs_dimacs_cnft::write_dimacs_pb(std::ostream &out) // std::cout << "exit: No Lit.=" << no_variables () << "\n"; } -/*******************************************************************\ - -Function: pbs_dimacs_cnft::pbs_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool pbs_dimacs_cnft::pbs_solve() { // std::cout << "solve: No Lit.=" << no_variables () << "\n"; @@ -149,7 +125,7 @@ bool pbs_dimacs_cnft::pbs_solve() { std::getline(file, line); if(strstr(line.c_str(), - "Variable Assignments Satisfying CNF Formula:")!=NULL) + "Variable Assignments Satisfying CNF Formula:")!=nullptr) { // print ("Reading assignments...\n"); // std::cout << "No literals: " << no_variables() << "\n"; @@ -167,12 +143,12 @@ bool pbs_dimacs_cnft::pbs_solve() // std::cout << "\n"; // print ("Finished reading assignments.\n"); } - else if(strstr(line.c_str(), "SAT... SUM")!=NULL) + else if(strstr(line.c_str(), "SAT... SUM")!=nullptr) { // print (line); sscanf(line.c_str(), "%*s %*s %*s %d", &opt_sum); } - else if(strstr(line.c_str(), "SAT - All implied")!=NULL) + else if(strstr(line.c_str(), "SAT - All implied")!=nullptr) { // print (line); sscanf( @@ -180,17 +156,18 @@ bool pbs_dimacs_cnft::pbs_solve() "%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %d", &opt_sum); } - else if(strstr(line.c_str(), "SAT... Solution")!=NULL) + else if(strstr(line.c_str(), "SAT... Solution")!=nullptr) { // print(line); sscanf(line.c_str(), "%*s %*s %*s %d", &opt_sum); } - else if(strstr(line.c_str(), "Optimal Soln")!=NULL) + else if(strstr(line.c_str(), "Optimal Soln")!=nullptr) { // print(line); - if(strstr(line.c_str(), "time out")!=NULL) + if(strstr(line.c_str(), "time out")!=nullptr) { - print(6, "WARNING: TIMED OUT. SOLUTION MAY BE INCORRECT.\n"); + status() << "WARNING: TIMED OUT. SOLUTION MAY BE INCORRECT." + << eom; return satisfied; } sscanf(line.c_str(), "%*s %*s %*s %d", &opt_sum); @@ -200,18 +177,6 @@ bool pbs_dimacs_cnft::pbs_solve() return satisfied; } -/*******************************************************************\ - -Function: pbs_dimacs_cnft::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - propt::resultt pbs_dimacs_cnft::prop_solve() { std::ofstream file("temp.cnf"); @@ -247,23 +212,11 @@ propt::resultt pbs_dimacs_cnft::prop_solve() } if(result) - return P_SATISFIABLE; + return resultt::P_SATISFIABLE; else - return P_UNSATISFIABLE; + return resultt::P_UNSATISFIABLE; } -/*******************************************************************\ - -Function: pbs_dimacs_cnft::l_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt pbs_dimacs_cnft::l_get(literalt a) const { int dimacs_lit=a.dimacs(); @@ -302,7 +255,4 @@ tvt pbs_dimacs_cnft::l_get(literalt a) const return tvt(true); } } - - // std::cout << "ERROR" << "\n"; - return tvt::unknown(); } diff --git a/src/solvers/sat/pbs_dimacs_cnf.h b/src/solvers/sat/pbs_dimacs_cnf.h index 8d2b04bae24..f257746b8c4 100644 --- a/src/solvers/sat/pbs_dimacs_cnf.h +++ b/src/solvers/sat/pbs_dimacs_cnf.h @@ -6,6 +6,7 @@ Author: Alex Groce \*******************************************************************/ + #ifndef CPROVER_SOLVERS_SAT_PBS_DIMACS_CNF_H #define CPROVER_SOLVERS_SAT_PBS_DIMACS_CNF_H diff --git a/src/solvers/sat/read_dimacs_cnf.cpp b/src/solvers/sat/read_dimacs_cnf.cpp index 42e63a5e9e2..4228851fcdf 100644 --- a/src/solvers/sat/read_dimacs_cnf.cpp +++ b/src/solvers/sat/read_dimacs_cnf.cpp @@ -6,27 +6,18 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Reading DIMACS CNF + +#include "read_dimacs_cnf.h" + #include #include // for abs() #include -#include "read_dimacs_cnf.h" - // #define VERBOSE -/*******************************************************************\ - -Function: cnft::read_dimacs_cnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void read_dimacs_cnf(std::istream &in, cnft &dest) { #define DELIMITERS "\t\n\v\f\r " @@ -45,11 +36,11 @@ void read_dimacs_cnf(std::istream &in, cnft &dest) break; #ifdef VERBOSE - std::cout << "begin line " << line << std::endl; + std::cout << "begin line " << line << '\n'; #endif size_t pos = line.find_first_of(DELIMITERS, 0); #ifdef VERBOSE - std::cout << "pos " << pos << std::endl; + std::cout << "pos " << pos << '\n'; #endif size_t pos_char = line.find_first_of(CHAR_DELIMITERS, 0); @@ -59,13 +50,13 @@ void read_dimacs_cnf(std::istream &in, cnft &dest) line.erase(0, pos+1); #ifdef VERBOSE std::cout << "i am here\n"; - std::cout << decision << std::endl; - std::cout << "line" << line << std::endl; + std::cout << decision << '\n'; + std::cout << "line" << line << '\n'; #endif if(!decision.compare(std::string("c"))) { #ifdef VERBOSE - std::cout << "c " << std::endl; + std::cout << "c \n"; #endif break; } @@ -73,7 +64,7 @@ void read_dimacs_cnf(std::istream &in, cnft &dest) if(!decision.compare(std::string("p"))) { #ifdef VERBOSE - std::cout << "p " << std::endl; + std::cout << "p \n"; #endif break; } @@ -82,13 +73,13 @@ void read_dimacs_cnf(std::istream &in, cnft &dest) { int parsed_lit = unsafe_string2int(decision); #ifdef VERBOSE - std::cout << "parsed_lit " << parsed_lit << " " << std::endl; + std::cout << "parsed_lit " << parsed_lit << " \n"; #endif if(parsed_lit == 0) { bvt no_dup=cnft::eliminate_duplicates(new_bv); #ifdef VERBOSE - std::cout << "calling lcnf " << new_bv.size() << std::endl; + std::cout << "calling lcnf " << new_bv.size() << '\n'; #endif dest.lcnf(no_dup); new_bv.clear(); @@ -101,7 +92,7 @@ void read_dimacs_cnf(std::istream &in, cnft &dest) bool sign = (parsed_lit > 0) ? false : true; l.set(var, sign); #ifdef VERBOSE - std::cout << "setting l to " << l.get() << std::endl; + std::cout << "setting l to " << l.get() << '\n'; #endif new_bv.push_back(l); if(dest.no_variables() <= var) diff --git a/src/solvers/sat/read_dimacs_cnf.h b/src/solvers/sat/read_dimacs_cnf.h index 2a0c0cb3950..96bb752867a 100644 --- a/src/solvers/sat/read_dimacs_cnf.h +++ b/src/solvers/sat/read_dimacs_cnf.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Reading DIMACS CNF + #ifndef CPROVER_SOLVERS_SAT_READ_DIMACS_CNF_H #define CPROVER_SOLVERS_SAT_READ_DIMACS_CNF_H diff --git a/src/solvers/sat/resolution_proof.cpp b/src/solvers/sat/resolution_proof.cpp index 20c10498a96..c0102da2ae1 100644 --- a/src/solvers/sat/resolution_proof.cpp +++ b/src/solvers/sat/resolution_proof.cpp @@ -6,22 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include -#include - #include "resolution_proof.h" -/*******************************************************************\ - -Function: resolution_prooft::build_core - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include template void resolution_prooft::build_core(std::vector &in_core) diff --git a/src/solvers/sat/resolution_proof.h b/src/solvers/sat/resolution_proof.h index dc810620aaf..04ceb489a12 100644 --- a/src/solvers/sat/resolution_proof.h +++ b/src/solvers/sat/resolution_proof.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_SAT_RESOLUTION_PROOF_H #define CPROVER_SOLVERS_SAT_RESOLUTION_PROOF_H diff --git a/src/solvers/sat/satcheck.cpp b/src/solvers/sat/satcheck.cpp index 48daf8f6399..27cdb5d79a6 100644 --- a/src/solvers/sat/satcheck.cpp +++ b/src/solvers/sat/satcheck.cpp @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #include "satcheck.h" // Sanity check diff --git a/src/solvers/sat/satcheck.h b/src/solvers/sat/satcheck.h index 19fc7759f69..ada65d253e8 100644 --- a/src/solvers/sat/satcheck.h +++ b/src/solvers/sat/satcheck.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_SAT_SATCHECK_H #define CPROVER_SOLVERS_SAT_SATCHECK_H diff --git a/src/solvers/sat/satcheck_booleforce.cpp b/src/solvers/sat/satcheck_booleforce.cpp index 16a23f152f9..c6374c7012f 100644 --- a/src/solvers/sat/satcheck_booleforce.cpp +++ b/src/solvers/sat/satcheck_booleforce.cpp @@ -6,79 +6,30 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - - #include "satcheck_booleforce.h" +#include + extern "C" { #include "booleforce.h" } -/*******************************************************************\ - -Function: satcheck_booleforcet::satcheck_booleforcet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_booleforcet::satcheck_booleforcet() { booleforce_set_trace(false); } -/*******************************************************************\ - -Function: satcheck_booleforce_coret::satcheck_booleforce_coret - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_booleforce_coret::satcheck_booleforce_coret() { booleforce_set_trace(true); } -/*******************************************************************\ - -Function: satcheck_booleforce_baset::~satcheck_booleforce_baset - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_booleforce_baset::~satcheck_booleforce_baset() { booleforce_reset(); } -/*******************************************************************\ - -Function: satcheck_booleforce_baset::l_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt satcheck_booleforce_baset::l_get(literalt a) const { assert(status==SAT); @@ -108,35 +59,11 @@ tvt satcheck_booleforce_baset::l_get(literalt a) const return result; } -/*******************************************************************\ - -Function: satcheck_booleforce_Baset::solver_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::string satcheck_booleforce_baset::solver_text() { return std::string("Booleforce version ")+booleforce_version(); } -/*******************************************************************\ - -Function: satcheck_booleforce_baset::lcnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void satcheck_booleforce_baset::lcnf(const bvt &bv) { bvt tmp; @@ -153,18 +80,6 @@ void satcheck_booleforce_baset::lcnf(const bvt &bv) clause_counter++; } -/*******************************************************************\ - -Function: satcheck_booleforce_baset::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - propt::resultt satcheck_booleforce_baset::prop_solve() { assert(status==SAT || status==INIT); @@ -209,18 +124,6 @@ propt::resultt satcheck_booleforce_baset::prop_solve() return P_ERROR; } -/*******************************************************************\ - -Function: satcheck_booleforce_coret::in_core - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool satcheck_booleforce_coret::is_in_core(literalt l) const { return booleforce_var_in_core(l.var_no()); diff --git a/src/solvers/sat/satcheck_booleforce.h b/src/solvers/sat/satcheck_booleforce.h index 6dd3ac69ffd..e52dc1b0883 100644 --- a/src/solvers/sat/satcheck_booleforce.h +++ b/src/solvers/sat/satcheck_booleforce.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_SAT_SATCHECK_BOOLEFORCE_H #define CPROVER_SOLVERS_SAT_SATCHECK_BOOLEFORCE_H diff --git a/src/solvers/sat/satcheck_core.h b/src/solvers/sat/satcheck_core.h index 65ad61bab83..17b44c79402 100644 --- a/src/solvers/sat/satcheck_core.h +++ b/src/solvers/sat/satcheck_core.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_SAT_SATCHECK_CORE_H #define CPROVER_SOLVERS_SAT_SATCHECK_CORE_H diff --git a/src/solvers/sat/satcheck_glucose.cpp b/src/solvers/sat/satcheck_glucose.cpp index 152716d8157..3d6e2ae3934 100644 --- a/src/solvers/sat/satcheck_glucose.cpp +++ b/src/solvers/sat/satcheck_glucose.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "satcheck_glucose.h" + #ifndef _MSC_VER #include #endif @@ -15,8 +17,6 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "satcheck_glucose.h" - #include #include @@ -24,18 +24,6 @@ Author: Daniel Kroening, kroening@kroening.com #error "Expected HAVE_GLUCOSE" #endif -/*******************************************************************\ - -Function: convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void convert(const bvt &bv, Glucose::vec &dest) { dest.capacity(bv.size()); @@ -45,18 +33,6 @@ void convert(const bvt &bv, Glucose::vec &dest) dest.push(Glucose::mkLit(it->var_no(), it->sign())); } -/*******************************************************************\ - -Function: satcheck_glucose_baset::l_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template tvt satcheck_glucose_baset::l_get(literalt a) const { @@ -85,18 +61,6 @@ tvt satcheck_glucose_baset::l_get(literalt a) const return result; } -/*******************************************************************\ - -Function: satcheck_glucose_baset::set_polarity - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void satcheck_glucose_baset::set_polarity(literalt a, bool value) { @@ -105,52 +69,16 @@ void satcheck_glucose_baset::set_polarity(literalt a, bool value) solver->setPolarity(a.var_no(), value); } -/*******************************************************************\ - -Function: satcheck_glucose_no_simplifiert::solver_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::string satcheck_glucose_no_simplifiert::solver_text() { return "Glucose Syrup without simplifier"; } -/*******************************************************************\ - -Function: satcheck_glucose_simplifiert::solver_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::string satcheck_glucose_simplifiert::solver_text() { return "Glucose Syrup with simplifier"; } -/*******************************************************************\ - -Function: satcheck_glucose_baset::add_variables - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void satcheck_glucose_baset::add_variables() { @@ -158,18 +86,6 @@ void satcheck_glucose_baset::add_variables() solver->newVar(); } -/*******************************************************************\ - -Function: satcheck_glucose_baset::lcnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void satcheck_glucose_baset::lcnf(const bvt &bv) { @@ -195,18 +111,6 @@ void satcheck_glucose_baset::lcnf(const bvt &bv) clause_counter++; } -/*******************************************************************\ - -Function: satcheck_glucose_baset::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template propt::resultt satcheck_glucose_baset::prop_solve() { @@ -249,7 +153,7 @@ propt::resultt satcheck_glucose_baset::prop_solve() { messaget::status() << "SAT checker: instance is SATISFIABLE" << eom; - assert(solver->model.size()!=0); + assert(!solver->model.empty()); status=SAT; return P_SATISFIABLE; } @@ -265,18 +169,6 @@ propt::resultt satcheck_glucose_baset::prop_solve() return P_UNSATISFIABLE; } -/*******************************************************************\ - -Function: satcheck_glucose_baset::set_assignment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void satcheck_glucose_baset::set_assignment(literalt a, bool value) { @@ -291,36 +183,12 @@ void satcheck_glucose_baset::set_assignment(literalt a, bool value) solver->model[v]=Glucose::lbool(value); } -/*******************************************************************\ - -Function: satcheck_glucose_baset::satcheck_glucose_baset - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template satcheck_glucose_baset::satcheck_glucose_baset(T *_solver): solver(_solver) { } -/*******************************************************************\ - -Function: satcheck_glucose_baset::~satcheck_glucose_baset - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template<> satcheck_glucose_baset::~satcheck_glucose_baset() { @@ -333,18 +201,6 @@ satcheck_glucose_baset::~satcheck_glucose_baset() delete solver; } -/*******************************************************************\ - -Function: satcheck_glucose_baset::is_in_conflict - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template bool satcheck_glucose_baset::is_in_conflict(literalt a) const { @@ -357,18 +213,6 @@ bool satcheck_glucose_baset::is_in_conflict(literalt a) const return false; } -/*******************************************************************\ - -Function: satcheck_glucose_baset::set_assumptions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void satcheck_glucose_baset::set_assumptions(const bvt &bv) { @@ -378,52 +222,16 @@ void satcheck_glucose_baset::set_assumptions(const bvt &bv) assert(!it->is_constant()); } -/*******************************************************************\ - -Function: satcheck_glucose_no_simplifiert::satcheck_glucose_no_simplifiert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_glucose_no_simplifiert::satcheck_glucose_no_simplifiert(): satcheck_glucose_baset(new Glucose::Solver) { } -/*******************************************************************\ - -Function: satcheck_glucose_simplifiert::satcheck_glucose_simplifiert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_glucose_simplifiert::satcheck_glucose_simplifiert(): satcheck_glucose_baset(new Glucose::SimpSolver) { } -/*******************************************************************\ - -Function: satcheck_glucose_simplifiert::set_frozen - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void satcheck_glucose_simplifiert::set_frozen(literalt a) { if(!a.is_constant()) @@ -433,18 +241,6 @@ void satcheck_glucose_simplifiert::set_frozen(literalt a) } } -/*******************************************************************\ - -Function: satcheck_glucose_simplifiert::is_eliminated - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool satcheck_glucose_simplifiert::is_eliminated(literalt a) const { assert(!a.is_constant()); diff --git a/src/solvers/sat/satcheck_glucose.h b/src/solvers/sat/satcheck_glucose.h index 100a514e601..8f849630db5 100644 --- a/src/solvers/sat/satcheck_glucose.h +++ b/src/solvers/sat/satcheck_glucose.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_SAT_SATCHECK_GLUCOSE_H #define CPROVER_SOLVERS_SAT_SATCHECK_GLUCOSE_H diff --git a/src/solvers/sat/satcheck_limmat.cpp b/src/solvers/sat/satcheck_limmat.cpp index a8393cf30e8..10fd310ff35 100644 --- a/src/solvers/sat/satcheck_limmat.cpp +++ b/src/solvers/sat/satcheck_limmat.cpp @@ -6,63 +6,26 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - - #include "satcheck_limmat.h" +#include + extern "C" { #include "limmat.h" } -/*******************************************************************\ - -Function: satcheck_limmatt::satcheck_limmatt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_limmatt::satcheck_limmatt() { solver=new_Limmat(NULL); } -/*******************************************************************\ - -Function: satcheck_limmatt::~satcheck_limmatt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_limmatt::~satcheck_limmatt() { if(solver!=NULL) delete_Limmat(solver); } -/*******************************************************************\ - -Function: satcheck_limmatt::l_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt satcheck_limmatt::l_get(literalt a) const { if(a.is_true()) @@ -88,35 +51,11 @@ tvt satcheck_limmatt::l_get(literalt a) const return result; } -/*******************************************************************\ - -Function: satcheck_limmatt::solver_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::string satcheck_limmatt::solver_text() { return std::string("Limmat version ")+version_Limmat(); } -/*******************************************************************\ - -Function: satcheck_limmatt::copy_cnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void satcheck_limmatt::copy_cnf() { for(clausest::iterator it=clauses.begin(); @@ -138,18 +77,6 @@ void satcheck_limmatt::copy_cnf() } } -/*******************************************************************\ - -Function: satcheck_limmatt::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - propt::resultt satcheck_limmatt::prop_solve() { copy_cnf(); diff --git a/src/solvers/sat/satcheck_limmat.h b/src/solvers/sat/satcheck_limmat.h index 1ef88177176..91e8e3d9df8 100644 --- a/src/solvers/sat/satcheck_limmat.h +++ b/src/solvers/sat/satcheck_limmat.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_SAT_SATCHECK_LIMMAT_H #define CPROVER_SOLVERS_SAT_SATCHECK_LIMMAT_H diff --git a/src/solvers/sat/satcheck_lingeling.cpp b/src/solvers/sat/satcheck_lingeling.cpp index 18237a903ab..ad0a504d412 100644 --- a/src/solvers/sat/satcheck_lingeling.cpp +++ b/src/solvers/sat/satcheck_lingeling.cpp @@ -6,12 +6,12 @@ Author: Michael Tautschnig, michael.tautschnig@cs.ox.ac.uk \*******************************************************************/ +#include "satcheck_lingeling.h" + #include #include -#include "satcheck_lingeling.h" - extern "C" { #include @@ -21,18 +21,6 @@ extern "C" #error "Expected HAVE_LINGELING" #endif -/*******************************************************************\ - -Function: satcheck_lingelingt::l_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt satcheck_lingelingt::l_get(literalt a) const { if(a.is_constant()) @@ -54,35 +42,11 @@ tvt satcheck_lingelingt::l_get(literalt a) const return result; } -/*******************************************************************\ - -Function: satcheck_lingelingt::solver_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::string satcheck_lingelingt::solver_text() { return "Lingeling"; } -/*******************************************************************\ - -Function: satcheck_lingelingt::lcnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void satcheck_lingelingt::lcnf(const bvt &bv) { bvt new_bv; @@ -98,18 +62,6 @@ void satcheck_lingelingt::lcnf(const bvt &bv) clause_counter++; } -/*******************************************************************\ - -Function: satcheck_lingelingt::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - propt::resultt satcheck_lingelingt::prop_solve() { assert(status!=ERROR); @@ -146,70 +98,22 @@ propt::resultt satcheck_lingelingt::prop_solve() return P_UNSATISFIABLE; } -/*******************************************************************\ - -Function: satcheck_lingelingt::set_assignment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void satcheck_lingelingt::set_assignment(literalt a, bool value) { assert(false); } -/*******************************************************************\ - -Function: satcheck_lingelingt::satcheck_lingelingt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_lingelingt::satcheck_lingelingt() : solver(lglinit()) { } -/*******************************************************************\ - -Function: satcheck_lingelingt::satcheck_lingelingt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_lingelingt::~satcheck_lingelingt() { lglrelease(solver); solver=0; } -/*******************************************************************\ - -Function: satcheck_lingelingt::set_assumptions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void satcheck_lingelingt::set_assumptions(const bvt &bv) { assumptions=bv; @@ -218,40 +122,16 @@ void satcheck_lingelingt::set_assumptions(const bvt &bv) assert(!it->is_constant()); } -/*******************************************************************\ - -Function: satcheck_lingelingt::set_frozen - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void satcheck_lingelingt::set_frozen(literalt a) { if(!a.is_constant()) lglfreeze(solver, a.dimacs()); } -/*******************************************************************\ - -Function: satcheck_lingelingt::is_in_conflict - - Inputs: - - Outputs: - - Purpose: Returns true if an assumed literal is in conflict if the - formula is UNSAT. - - NOTE: if the literal is not in the assumption it causes an - assertion failure in lingeling. - -\*******************************************************************/ - +/// Returns true if an assumed literal is in conflict if the formula is UNSAT. +/// +/// NOTE: if the literal is not in the assumption it causes an +/// assertion failure in lingeling. bool satcheck_lingelingt::is_in_conflict(literalt a) const { assert(!a.is_constant()); diff --git a/src/solvers/sat/satcheck_lingeling.h b/src/solvers/sat/satcheck_lingeling.h index bc9a9198f77..ddc9388407c 100644 --- a/src/solvers/sat/satcheck_lingeling.h +++ b/src/solvers/sat/satcheck_lingeling.h @@ -6,6 +6,7 @@ Author: Michael Tautschnig, michael.tautschnig@cs.ox.ac.uk \*******************************************************************/ + #ifndef CPROVER_SOLVERS_SAT_SATCHECK_LINGELING_H #define CPROVER_SOLVERS_SAT_SATCHECK_LINGELING_H diff --git a/src/solvers/sat/satcheck_minisat.cpp b/src/solvers/sat/satcheck_minisat.cpp index b615d04e112..fb892707b83 100644 --- a/src/solvers/sat/satcheck_minisat.cpp +++ b/src/solvers/sat/satcheck_minisat.cpp @@ -6,13 +6,13 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "satcheck_minisat.h" + #include #include #include -#include "satcheck_minisat.h" - #include #include @@ -20,18 +20,6 @@ Author: Daniel Kroening, kroening@kroening.com #error "Expected HAVE_MINISAT" #endif -/*******************************************************************\ - -Function: convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void convert(const bvt &bv, vec &dest) { dest.growTo(bv.size()); @@ -40,14 +28,6 @@ void convert(const bvt &bv, vec &dest) dest[i]=Lit(bv[i].var_no(), bv[i].sign()); } -/*******************************************************************\ - - Class: minisat_prooft - - Purpose: - -\*******************************************************************/ - class minisat_prooft:public ProofTraverser { public: @@ -76,18 +56,6 @@ class minisat_prooft:public ProofTraverser simple_prooft resolution_proof; }; -/*******************************************************************\ - -Function: minisat_prooft::chain - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void minisat_prooft::chain(const vec &cs, const vec &xs) { assert(cs.size()==xs.size()+1); @@ -112,18 +80,6 @@ void minisat_prooft::chain(const vec &cs, const vec &xs) } } -/*******************************************************************\ - -Function: satcheck_minisat1_baset::l_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt satcheck_minisat1_baset::l_get(literalt a) const { if(a.is_true()) @@ -149,53 +105,17 @@ tvt satcheck_minisat1_baset::l_get(literalt a) const return result; } -/*******************************************************************\ - -Function: satcheck_minisat1_baset::solver_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::string satcheck_minisat1_baset::solver_text() { return "MiniSAT 1.14p"; } -/*******************************************************************\ - -Function: satcheck_minisat1_baset::add_variables - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void satcheck_minisat1_baset::add_variables() { while((unsigned)solver->nVars()newVar(); } -/*******************************************************************\ - -Function: satcheck_minisat1_baset::lcnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void satcheck_minisat1_baset::lcnf(const bvt &bv) { bvt new_bv; @@ -223,18 +143,6 @@ void satcheck_minisat1_baset::lcnf(const bvt &bv) clause_counter++; } -/*******************************************************************\ - -Function: satcheck_minisat1_baset::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - propt::resultt satcheck_minisat1_baset::prop_solve() { assert(status!=ERROR); @@ -280,18 +188,6 @@ propt::resultt satcheck_minisat1_baset::prop_solve() return P_UNSATISFIABLE; } -/*******************************************************************\ - -Function: satcheck_minisat1_baset::set_assignment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void satcheck_minisat1_baset::set_assignment(literalt a, bool value) { unsigned v=a.var_no(); @@ -301,18 +197,6 @@ void satcheck_minisat1_baset::set_assignment(literalt a, bool value) solver->model[v]=lbool(value); } -/*******************************************************************\ - -Function: satcheck_minisat1_baset::is_in_conflict - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool satcheck_minisat1_baset::is_in_conflict(literalt a) const { int v=a.var_no(); @@ -326,18 +210,6 @@ bool satcheck_minisat1_baset::is_in_conflict(literalt a) const return false; } -/*******************************************************************\ - -Function: satcheck_minisat1_baset::set_assumptions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void satcheck_minisat1_baset::set_assumptions(const bvt &bv) { assumptions=bv; @@ -348,36 +220,12 @@ void satcheck_minisat1_baset::set_assumptions(const bvt &bv) assert(!it->is_constant()); } -/*******************************************************************\ - -Function: satcheck_minisat1t::satcheck_minisat1t - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_minisat1t::satcheck_minisat1t() { empty_clause_added=false; solver=new Solver; } -/*******************************************************************\ - -Function: satcheck_minisat1_prooft::satcheck_minisat1_prooft - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_minisat1_prooft::satcheck_minisat1_prooft():satcheck_minisat1t() { minisat_proof=new minisat_prooft; @@ -386,102 +234,30 @@ satcheck_minisat1_prooft::satcheck_minisat1_prooft():satcheck_minisat1t() solver->proof=proof; } -/*******************************************************************\ - -Function: satcheck_minisat1_prooft::~satcheck_minisat1_prooft - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_minisat1_prooft::~satcheck_minisat1_prooft() { delete proof; delete minisat_proof; } -/*******************************************************************\ - -Function: satcheck_minisat1_coret::satcheck_minisat1_coret - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_minisat1_coret::satcheck_minisat1_coret() { } -/*******************************************************************\ - -Function: satcheck_minisat1_coret::~satcheck_minisat1_coret - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_minisat1_coret::~satcheck_minisat1_coret() { } -/*******************************************************************\ - -Function: satcheck_minisat1_baset::~satcheck_minisat1_baset - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_minisat1_baset::~satcheck_minisat1_baset() { delete solver; } -/*******************************************************************\ - -Function: satcheck_minisat1_prooft::solver_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::string satcheck_minisat1_prooft::solver_text() { return "MiniSAT + Proof"; } -/*******************************************************************\ - -Function: satcheck_minisat1_coret::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - propt::resultt satcheck_minisat1_coret::prop_solve() { propt::resultt r; @@ -497,35 +273,11 @@ propt::resultt satcheck_minisat1_coret::prop_solve() return r; } -/*******************************************************************\ - -Function: satcheck_minisat1_coret::solver_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::string satcheck_minisat1_coret::solver_text() { return "MiniSAT + Core"; } -/*******************************************************************\ - -Function: satcheck_minisat1_prooft::get_resolution_proof - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - simple_prooft &satcheck_minisat1_prooft::get_resolution_proof() { return minisat_proof->resolution_proof; diff --git a/src/solvers/sat/satcheck_minisat.h b/src/solvers/sat/satcheck_minisat.h index 3924d26b816..88dbe864a4e 100644 --- a/src/solvers/sat/satcheck_minisat.h +++ b/src/solvers/sat/satcheck_minisat.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_SAT_SATCHECK_MINISAT_H #define CPROVER_SOLVERS_SAT_SATCHECK_MINISAT_H diff --git a/src/solvers/sat/satcheck_minisat2.cpp b/src/solvers/sat/satcheck_minisat2.cpp index c17f7f553f8..ef6605532c1 100644 --- a/src/solvers/sat/satcheck_minisat2.cpp +++ b/src/solvers/sat/satcheck_minisat2.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "satcheck_minisat2.h" + #ifndef _MSC_VER #include #endif @@ -13,9 +15,9 @@ Author: Daniel Kroening, kroening@kroening.com #include #include +#include #include - -#include "satcheck_minisat2.h" +#include #include #include @@ -24,18 +26,6 @@ Author: Daniel Kroening, kroening@kroening.com #error "Expected HAVE_MINISAT2" #endif -/*******************************************************************\ - -Function: convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void convert(const bvt &bv, Minisat::vec &dest) { dest.capacity(bv.size()); @@ -45,18 +35,6 @@ void convert(const bvt &bv, Minisat::vec &dest) dest.push(Minisat::mkLit(it->var_no(), it->sign())); } -/*******************************************************************\ - -Function: satcheck_minisat2_baset::l_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template tvt satcheck_minisat2_baset::l_get(literalt a) const { @@ -85,18 +63,6 @@ tvt satcheck_minisat2_baset::l_get(literalt a) const return result; } -/*******************************************************************\ - -Function: satcheck_minisat2_baset::set_polarity - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void satcheck_minisat2_baset::set_polarity(literalt a, bool value) { @@ -105,52 +71,16 @@ void satcheck_minisat2_baset::set_polarity(literalt a, bool value) solver->setPolarity(a.var_no(), value); } -/*******************************************************************\ - -Function: satcheck_minisat_no_simplifiert::solver_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::string satcheck_minisat_no_simplifiert::solver_text() { return "MiniSAT 2.2.1 without simplifier"; } -/*******************************************************************\ - -Function: satcheck_minisat_simplifiert::solver_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::string satcheck_minisat_simplifiert::solver_text() { return "MiniSAT 2.2.1 with simplifier"; } -/*******************************************************************\ - -Function: satcheck_minisat2_baset::add_variables - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void satcheck_minisat2_baset::add_variables() { @@ -158,18 +88,6 @@ void satcheck_minisat2_baset::add_variables() solver->newVar(); } -/*******************************************************************\ - -Function: satcheck_minisat2_baset::lcnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void satcheck_minisat2_baset::lcnf(const bvt &bv) { @@ -195,22 +113,10 @@ void satcheck_minisat2_baset::lcnf(const bvt &bv) clause_counter++; } -/*******************************************************************\ - -Function: satcheck_minisat2_baset::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template propt::resultt satcheck_minisat2_baset::prop_solve() { - assert(status!=ERROR); + assert(status!=statust::ERROR); { messaget::status() << @@ -250,9 +156,9 @@ propt::resultt satcheck_minisat2_baset::prop_solve() { messaget::status() << "SAT checker: instance is SATISFIABLE" << eom; - assert(solver->model.size()!=0); - status=SAT; - return P_SATISFIABLE; + CHECK_RETURN(solver->model.size()>0); + status=statust::SAT; + return resultt::P_SATISFIABLE; } else { @@ -262,30 +168,18 @@ propt::resultt satcheck_minisat2_baset::prop_solve() } } - status=UNSAT; - return P_UNSATISFIABLE; + status=statust::UNSAT; + return resultt::P_UNSATISFIABLE; } catch(Minisat::OutOfMemoryException) { messaget::error() << "SAT checker ran out of memory" << eom; - status=ERROR; - return P_ERROR; + status=statust::ERROR; + return resultt::P_ERROR; } } -/*******************************************************************\ - -Function: satcheck_minisat2_baset::set_assignment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void satcheck_minisat2_baset::set_assignment(literalt a, bool value) { @@ -300,36 +194,12 @@ void satcheck_minisat2_baset::set_assignment(literalt a, bool value) solver->model[v]=Minisat::lbool(value); } -/*******************************************************************\ - -Function: satcheck_minisat2_baset::satcheck_minisat2_baset - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template satcheck_minisat2_baset::satcheck_minisat2_baset(T *_solver): solver(_solver) { } -/*******************************************************************\ - -Function: satcheck_minisat2_baset::~satcheck_minisat2_baset - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template<> satcheck_minisat2_baset::~satcheck_minisat2_baset() { @@ -342,18 +212,6 @@ satcheck_minisat2_baset::~satcheck_minisat2_baset() delete solver; } -/*******************************************************************\ - -Function: satcheck_minisat2_baset::is_in_conflict - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template bool satcheck_minisat2_baset::is_in_conflict(literalt a) const { @@ -366,18 +224,6 @@ bool satcheck_minisat2_baset::is_in_conflict(literalt a) const return false; } -/*******************************************************************\ - -Function: satcheck_minisat2_baset::set_assumptions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void satcheck_minisat2_baset::set_assumptions(const bvt &bv) { @@ -391,52 +237,16 @@ void satcheck_minisat2_baset::set_assumptions(const bvt &bv) } } -/*******************************************************************\ - -Function: satcheck_minisat_no_simplifiert::satcheck_minisat_no_simplifiert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_minisat_no_simplifiert::satcheck_minisat_no_simplifiert(): satcheck_minisat2_baset(new Minisat::Solver) { } -/*******************************************************************\ - -Function: satcheck_minisat_simplifiert::satcheck_minisat_simplifiert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_minisat_simplifiert::satcheck_minisat_simplifiert(): satcheck_minisat2_baset(new Minisat::SimpSolver) { } -/*******************************************************************\ - -Function: satcheck_minisat_simplifiert::set_frozen - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void satcheck_minisat_simplifiert::set_frozen(literalt a) { if(!a.is_constant()) @@ -446,18 +256,6 @@ void satcheck_minisat_simplifiert::set_frozen(literalt a) } } -/*******************************************************************\ - -Function: satcheck_minisat_simplifiert::is_eliminated - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool satcheck_minisat_simplifiert::is_eliminated(literalt a) const { assert(!a.is_constant()); diff --git a/src/solvers/sat/satcheck_minisat2.h b/src/solvers/sat/satcheck_minisat2.h index f31018d7125..22026e27d85 100644 --- a/src/solvers/sat/satcheck_minisat2.h +++ b/src/solvers/sat/satcheck_minisat2.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_SAT_SATCHECK_MINISAT2_H #define CPROVER_SOLVERS_SAT_SATCHECK_MINISAT2_H diff --git a/src/solvers/sat/satcheck_picosat.cpp b/src/solvers/sat/satcheck_picosat.cpp index 7c3417592a3..de54f70f9c0 100644 --- a/src/solvers/sat/satcheck_picosat.cpp +++ b/src/solvers/sat/satcheck_picosat.cpp @@ -6,12 +6,12 @@ Author: Michael Tautschnig, michael.tautschnig@cs.ox.ac.uk \*******************************************************************/ +#include "satcheck_picosat.h" + #include #include -#include "satcheck_picosat.h" - extern "C" { #include @@ -21,18 +21,6 @@ extern "C" #error "Expected HAVE_PICOSAT" #endif -/*******************************************************************\ - -Function: satcheck_picosatt::l_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt satcheck_picosatt::l_get(literalt a) const { if(a.is_constant()) @@ -54,35 +42,11 @@ tvt satcheck_picosatt::l_get(literalt a) const return result; } -/*******************************************************************\ - -Function: satcheck_picosatt::solver_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::string satcheck_picosatt::solver_text() { return "PicoSAT"; } -/*******************************************************************\ - -Function: satcheck_picosatt::lcnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void satcheck_picosatt::lcnf(const bvt &bv) { bvt new_bv; @@ -100,18 +64,6 @@ void satcheck_picosatt::lcnf(const bvt &bv) clause_counter++; } -/*******************************************************************\ - -Function: satcheck_picosatt::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - propt::resultt satcheck_picosatt::prop_solve() { assert(status!=ERROR); @@ -147,69 +99,21 @@ propt::resultt satcheck_picosatt::prop_solve() return P_UNSATISFIABLE; } -/*******************************************************************\ - -Function: satcheck_picosatt::set_assignment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void satcheck_picosatt::set_assignment(literalt a, bool value) { assert(false); } -/*******************************************************************\ - -Function: satcheck_picosatt::satcheck_picosatt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_picosatt::satcheck_picosatt() { picosat = picosat_init(); } -/*******************************************************************\ - -Function: satcheck_picosatt::~satcheck_picosatt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_picosatt::~satcheck_picosatt() { picosat_reset(picosat); } -/*******************************************************************\ - -Function: satcheck_picosatt::is_in_conflict - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool satcheck_picosatt::is_in_conflict(literalt a) const { assert(!a.is_constant()); @@ -217,18 +121,6 @@ bool satcheck_picosatt::is_in_conflict(literalt a) const return picosat_failed_assumption(picosat, a.dimacs())!=0; } -/*******************************************************************\ - -Function: satcheck_picosatt::set_assumptions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void satcheck_picosatt::set_assumptions(const bvt &bv) { assumptions=bv; diff --git a/src/solvers/sat/satcheck_picosat.h b/src/solvers/sat/satcheck_picosat.h index 43e4b7f356d..5380c186ee9 100644 --- a/src/solvers/sat/satcheck_picosat.h +++ b/src/solvers/sat/satcheck_picosat.h @@ -6,6 +6,7 @@ Author: Michael Tautschnig, michael.tautschnig@cs.ox.ac.uk \*******************************************************************/ + #ifndef CPROVER_SOLVERS_SAT_SATCHECK_PICOSAT_H #define CPROVER_SOLVERS_SAT_SATCHECK_PICOSAT_H diff --git a/src/solvers/sat/satcheck_precosat.cpp b/src/solvers/sat/satcheck_precosat.cpp index 7589d085678..6e9a2248c94 100644 --- a/src/solvers/sat/satcheck_precosat.cpp +++ b/src/solvers/sat/satcheck_precosat.cpp @@ -6,12 +6,12 @@ Author: Michael Tautschnig, michael.tautschnig@cs.ox.ac.uk \*******************************************************************/ +#include "satcheck_precosat.h" + #include #include -#include "satcheck_precosat.h" - #include #ifndef HAVE_PRECOSAT @@ -20,18 +20,6 @@ Author: Michael Tautschnig, michael.tautschnig@cs.ox.ac.uk #define precosat_lit(a) ((a).var_no()*2 + !(a).sign()) -/*******************************************************************\ - -Function: satcheck_precosatt::l_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt satcheck_precosatt::l_get(literalt a) const { if(a.is_constant()) @@ -53,35 +41,11 @@ tvt satcheck_precosatt::l_get(literalt a) const return result; } -/*******************************************************************\ - -Function: satcheck_precosatt::solver_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::string satcheck_precosatt::solver_text() { return "PrecoSAT"; } -/*******************************************************************\ - -Function: satcheck_precosatt::lcnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void satcheck_precosatt::lcnf(const bvt &bv) { bvt new_bv; @@ -97,18 +61,6 @@ void satcheck_precosatt::lcnf(const bvt &bv) clause_counter++; } -/*******************************************************************\ - -Function: satcheck_precosatt::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - propt::resultt satcheck_precosatt::prop_solve() { assert(status!=ERROR); @@ -142,70 +94,22 @@ propt::resultt satcheck_precosatt::prop_solve() return P_UNSATISFIABLE; } -/*******************************************************************\ - -Function: satcheck_precosatt::set_assignment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void satcheck_precosatt::set_assignment(literalt a, bool value) { assert(false); } -/*******************************************************************\ - -Function: satcheck_precosatt::satcheck_precosatt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_precosatt::satcheck_precosatt() : solver(new PrecoSat::Solver()) { solver->init(); } -/*******************************************************************\ - -Function: satcheck_precosatt::~satcheck_precosatt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_precosatt::~satcheck_precosatt() { delete solver; } -/*******************************************************************\ - -Function: satcheck_precosatt::set_assumptions - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - /* void satcheck_precosatt::set_assumptions(const bvt &bv) { diff --git a/src/solvers/sat/satcheck_precosat.h b/src/solvers/sat/satcheck_precosat.h index c2cf053ac49..78caad55d7d 100644 --- a/src/solvers/sat/satcheck_precosat.h +++ b/src/solvers/sat/satcheck_precosat.h @@ -6,6 +6,7 @@ Author: Michael Tautschnig, michael.tautschnig@cs.ox.ac.uk \*******************************************************************/ + #ifndef CPROVER_SOLVERS_SAT_SATCHECK_PRECOSAT_H #define CPROVER_SOLVERS_SAT_SATCHECK_PRECOSAT_H diff --git a/src/solvers/sat/satcheck_smvsat.cpp b/src/solvers/sat/satcheck_smvsat.cpp index 8064900735d..1018a4d96b1 100644 --- a/src/solvers/sat/satcheck_smvsat.cpp +++ b/src/solvers/sat/satcheck_smvsat.cpp @@ -6,27 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "satcheck_smvsat.h" + #include #include - -#include "satcheck_smvsat.h" - #include #include -/*******************************************************************\ - -Function: satcheck_smvsatt::satcheck_smvsatt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_smvsatt::satcheck_smvsatt() { satsolver= @@ -36,50 +23,14 @@ satcheck_smvsatt::satcheck_smvsatt() init_const(); } -/*******************************************************************\ - -Function: satcheck_smvsat_coret::satcheck_smvsat_coret - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_smvsat_coret::satcheck_smvsat_coret() { } -/*******************************************************************\ - -Function: satcheck_smvsatt::~satcheck_smvsatt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_smvsatt::~satcheck_smvsatt() { } -/*******************************************************************\ - -Function: satcheck_smvsatt::l_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt satcheck_smvsatt::l_get(literalt a) const { assert(status==SAT); @@ -105,35 +56,11 @@ tvt satcheck_smvsatt::l_get(literalt a) const return result; } -/*******************************************************************\ - -Function: satcheck_smvsatt::solver_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::string satcheck_smvsatt::solver_text() { return std::string("SMVSAT"); } -/*******************************************************************\ - -Function: satcheck_smvsatt::lcnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void satcheck_smvsatt::lcnf(const bvt &bv) { bvt tmp; @@ -156,18 +83,6 @@ void satcheck_smvsatt::lcnf(const bvt &bv) delete[] lits; } -/*******************************************************************\ - -Function: satcheck_smvsatt::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - propt::resultt satcheck_smvsatt::prop_solve() { int result=sat_instance_solve(satsolver); @@ -210,18 +125,6 @@ propt::resultt satcheck_smvsatt::prop_solve() return P_ERROR; } -/*******************************************************************\ - -Function: satcheck_smvsat_coret::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - propt::resultt satcheck_smvsat_coret::prop_solve() { propt::resultt result=satcheck_smvsatt::prop_solve(); @@ -234,18 +137,6 @@ propt::resultt satcheck_smvsat_coret::prop_solve() return result; } -/*******************************************************************\ - -Function: satcheck_smvsat_interpolatort::lcnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void satcheck_smvsat_interpolatort::lcnf(const bvt &bv) { bvt tmp; @@ -271,18 +162,6 @@ void satcheck_smvsat_interpolatort::lcnf(const bvt &bv) delete[] lits; } -/*******************************************************************\ - -Function: satcheck_smvsat_interpolatort::interpolate - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void satcheck_smvsat_interpolatort::interpolate(exprt &dest) { // crate instance @@ -307,18 +186,6 @@ void satcheck_smvsat_interpolatort::interpolate(exprt &dest) delete interpolator_satsolver; } -/*******************************************************************\ - -Function: satcheck_smvsat_interpolatort::build_aig - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void satcheck_smvsat_interpolatort::build_aig( // NOLINTNEXTLINE(readability/identifiers) struct interpolator &interpolator_satsolver, diff --git a/src/solvers/sat/satcheck_smvsat.h b/src/solvers/sat/satcheck_smvsat.h index fa347ca2fad..c9d13c1d000 100644 --- a/src/solvers/sat/satcheck_smvsat.h +++ b/src/solvers/sat/satcheck_smvsat.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_SAT_SATCHECK_SMVSAT_H #define CPROVER_SOLVERS_SAT_SATCHECK_SMVSAT_H diff --git a/src/solvers/sat/satcheck_zchaff.cpp b/src/solvers/sat/satcheck_zchaff.cpp index 6697d6b3c6c..9a854286a6e 100644 --- a/src/solvers/sat/satcheck_zchaff.cpp +++ b/src/solvers/sat/satcheck_zchaff.cpp @@ -6,24 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - - #include "satcheck_zchaff.h" -#include - -/*******************************************************************\ - -Function: satcheck_zchaff_baset::satcheck_zchaff_baset - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include satcheck_zchaff_baset::satcheck_zchaff_baset(CSolver *_solver):solver(_solver) { @@ -32,34 +19,10 @@ satcheck_zchaff_baset::satcheck_zchaff_baset(CSolver *_solver):solver(_solver) solver->set_variable_number(0); } -/*******************************************************************\ - -Function: satcheck_zchaff_baset::~satcheck_zchaff_baset - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_zchaff_baset::~satcheck_zchaff_baset() { } -/*******************************************************************\ - -Function: satcheck_zchaff_baset::l_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt satcheck_zchaff_baset::l_get(literalt a) const { assert(status==SAT); @@ -86,35 +49,11 @@ tvt satcheck_zchaff_baset::l_get(literalt a) const return result; } -/*******************************************************************\ - -Function: satcheck_zchaff_baset::solver_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::string satcheck_zchaff_baset::solver_text() { return solver->version(); } -/*******************************************************************\ - -Function: satcheck_zchaff_baset::copy_cnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void satcheck_zchaff_baset::copy_cnf() { assert(status==INIT); @@ -129,18 +68,6 @@ void satcheck_zchaff_baset::copy_cnf() reinterpret_cast(&((*it)[0])), it->size()); } -/*******************************************************************\ - -Function: satcheck_zchaff_baset::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - propt::resultt satcheck_zchaff_baset::prop_solve() { // this is *not* incremental @@ -206,7 +133,7 @@ propt::resultt satcheck_zchaff_baset::prop_solve() if(result==SATISFIABLE) { for(unsigned i=2; i<(_no_variables*2); i+=2) - cout << "DEBUG L" << i << ":" << get(i) << endl; + cout << "DEBUG L" << i << ":" << get(i) << '\n'; } #endif @@ -227,18 +154,6 @@ propt::resultt satcheck_zchaff_baset::prop_solve() return P_ERROR; } -/*******************************************************************\ - -Function: satcheck_zchaff_baset::set_assignment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void satcheck_zchaff_baset::set_assignment(literalt a, bool value) { unsigned v=a.var_no(); @@ -247,35 +162,11 @@ void satcheck_zchaff_baset::set_assignment(literalt a, bool value) solver->variables()[v].set_value(value); } -/*******************************************************************\ - -Function: satcheck_zchafft::satcheck_zchafft - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_zchafft::satcheck_zchafft(): satcheck_zchaff_baset(new CSolver) { } -/*******************************************************************\ - -Function: satcheck_zchafft::~satcheck_zchafft - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_zchafft::~satcheck_zchafft() { delete solver; diff --git a/src/solvers/sat/satcheck_zchaff.h b/src/solvers/sat/satcheck_zchaff.h index 218c3d3c1c1..a25846fecff 100644 --- a/src/solvers/sat/satcheck_zchaff.h +++ b/src/solvers/sat/satcheck_zchaff.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_SAT_SATCHECK_ZCHAFF_H #define CPROVER_SOLVERS_SAT_SATCHECK_ZCHAFF_H @@ -37,7 +38,7 @@ class satcheck_zchaff_baset:public cnf_clause_listt protected: CSolver *solver; - typedef enum { INIT, SAT, UNSAT, ERROR } statust; + enum statust { INIT, SAT, UNSAT, ERROR }; statust status; }; diff --git a/src/solvers/sat/satcheck_zcore.cpp b/src/solvers/sat/satcheck_zcore.cpp index 5079259d6cf..ac0d60977f0 100644 --- a/src/solvers/sat/satcheck_zcore.cpp +++ b/src/solvers/sat/satcheck_zcore.cpp @@ -6,94 +6,34 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "satcheck_zcore.h" + #include #include #include -#include "satcheck_zcore.h" - #include -/*******************************************************************\ - -Function: satcheck_zcoret::satcheck_zcoret - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_zcoret::satcheck_zcoret() { } -/*******************************************************************\ - -Function: satcheck_zcoret::~satcheck_zcoret - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - satcheck_zcoret::~satcheck_zcoret() { } -/*******************************************************************\ - -Function: satcheck_zcoret::l_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt satcheck_zcoret::l_get(literalt a) const { assert(false); return tvt(tvt::tv_enumt::TV_UNKNOWN); } -/*******************************************************************\ - -Function: satcheck_zcoret::solver_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::string satcheck_zcoret::solver_text() { return "ZCore"; } -/*******************************************************************\ - -Function: satcheck_zcoret::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - propt::resultt satcheck_zcoret::prop_solve() { // We start counting at 1, thus there is one variable fewer. diff --git a/src/solvers/sat/satcheck_zcore.h b/src/solvers/sat/satcheck_zcore.h index fdd152bfdc9..e643f86e67f 100644 --- a/src/solvers/sat/satcheck_zcore.h +++ b/src/solvers/sat/satcheck_zcore.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_SAT_SATCHECK_ZCORE_H #define CPROVER_SOLVERS_SAT_SATCHECK_ZCORE_H diff --git a/src/solvers/smt1/smt1_conv.cpp b/src/solvers/smt1/smt1_conv.cpp index d7c89ed8921..ee85dfc63a0 100644 --- a/src/solvers/smt1/smt1_conv.cpp +++ b/src/solvers/smt1/smt1_conv.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// SMT Version 1 Backend + +#include "smt1_conv.h" + #include #include @@ -16,6 +21,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include +#include #include @@ -26,20 +32,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "smt1_conv.h" - -/*******************************************************************\ - -Function: smt1_convt::print_assignment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::print_assignment(std::ostream &out) const { // Boolean stuff @@ -50,18 +42,6 @@ void smt1_convt::print_assignment(std::ostream &out) const // others } -/*******************************************************************\ - -Function: smt1_convt::l_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt smt1_convt::l_get(literalt l) const { if(l.is_true()) @@ -72,37 +52,13 @@ tvt smt1_convt::l_get(literalt l) const return tvt(boolean_assignment[l.var_no()]^l.sign()); } -/*******************************************************************\ - -Function: smt1_convt::dec_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - decision_proceduret::resultt smt1_convt::dec_solve() { write_footer(); out.flush(); - return decision_proceduret::D_ERROR; + return decision_proceduret::resultt::D_ERROR; } -/*******************************************************************\ - -Function: smt1_convt::write_header - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::write_header() { out << "(benchmark " << benchmark << "\n"; @@ -111,18 +67,6 @@ void smt1_convt::write_header() out << ":logic " << logic << " ; SMT1" << "\n"; } -/*******************************************************************\ - -Function: smt1_convt::write_footer() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::write_footer() { out << "\n"; @@ -130,18 +74,6 @@ void smt1_convt::write_footer() out << ") ; benchmark" << "\n"; } -/*******************************************************************\ - -Function: smt1_convt::get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt smt1_convt::get(const exprt &expr) const { if(expr.id()==ID_symbol) @@ -183,18 +115,6 @@ exprt smt1_convt::get(const exprt &expr) const return nil_exprt(); } -/*******************************************************************\ - -Function: smt1_convt::ce_value - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt smt1_convt::ce_value( const typet &type, const std::string &index, @@ -309,18 +229,6 @@ exprt smt1_convt::ce_value( return nil_exprt(); } -/*******************************************************************\ - -Function: smt1_convt::array_index_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet smt1_convt::array_index_type() const { signedbv_typet t; @@ -328,18 +236,6 @@ typet smt1_convt::array_index_type() const return t; } -/*******************************************************************\ - -Function: smt1_convt::array_index - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::array_index(const exprt &expr) { if(expr.type().id()==ID_integer) @@ -353,18 +249,6 @@ void smt1_convt::array_index(const exprt &expr) convert_expr(tmp, true); } -/*******************************************************************\ - -Function: smt1_convt::convert_address_of_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_address_of_rec( const exprt &expr, const pointer_typet &result_type) @@ -403,12 +287,14 @@ void smt1_convt::convert_address_of_rec( exprt new_index_expr=expr; new_index_expr.op1()=from_integer(0, index.type()); - exprt address_of_expr(ID_address_of, pointer_typet()); - address_of_expr.type().subtype()=array.type().subtype(); - address_of_expr.copy_to_operands(new_index_expr); + address_of_exprt address_of_expr( + new_index_expr, + pointer_type(array.type().subtype())); - exprt plus_expr(ID_plus, address_of_expr.type()); - plus_expr.copy_to_operands(address_of_expr, index); + plus_exprt plus_expr( + address_of_expr, + index, + address_of_expr.type()); convert_expr(plus_expr, true); } @@ -432,6 +318,7 @@ void smt1_convt::convert_address_of_rec( member_expr.get_component_name(); mp_integer offset=member_offset(struct_type, component_name, ns); + assert(offset>=0); typet index_type(ID_unsignedbv); index_type.set(ID_width, boolbv_width(result_type)); @@ -466,18 +353,6 @@ void smt1_convt::convert_address_of_rec( throw "don't know how to take address of: "+expr.id_string(); } -/*******************************************************************\ - -Function: smt1_convt::convert_byte_extract - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_byte_extract( const byte_extract_exprt &expr, bool bool_as_bv) @@ -487,18 +362,6 @@ void smt1_convt::convert_byte_extract( convert_expr(flattened_expr, bool_as_bv); } -/*******************************************************************\ - -Function: smt1_convt::convert_byte_update - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_byte_update( const exprt &expr, bool bool_as_bv) @@ -576,18 +439,6 @@ void smt1_convt::convert_byte_update( } } -/*******************************************************************\ - -Function: smt1_convt::convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt1_convt::convert(const exprt &expr) { assert(expr.type().id()==ID_bool); @@ -624,18 +475,6 @@ literalt smt1_convt::convert(const exprt &expr) return l; } -/*******************************************************************\ - -Function: smt1_convt::convert_identifier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string smt1_convt::convert_identifier(const irep_idt &identifier) { std::string s=id2string(identifier), dest; @@ -689,18 +528,6 @@ std::string smt1_convt::convert_identifier(const irep_idt &identifier) return dest; } -/*******************************************************************\ - -Function: smt1_convt::convert_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_expr(const exprt &expr, bool bool_as_bv) { if(expr.id()==ID_symbol) @@ -1510,18 +1337,6 @@ void smt1_convt::convert_expr(const exprt &expr, bool bool_as_bv) expr.id_string()+"' is unsupported"; } -/*******************************************************************\ - -Function: smt1_convt::convert_typecast - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_typecast( const typecast_exprt &expr, bool bool_as_bv) @@ -1903,18 +1718,6 @@ void smt1_convt::convert_typecast( throw "TODO typecast4 ? -> "+dest_type.id_string(); } -/*******************************************************************\ - -Function: smt1_convt::convert_struct - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_struct(const exprt &expr) { const struct_typet &struct_type=to_struct_type(expr.type()); @@ -1969,18 +1772,6 @@ void smt1_convt::convert_struct(const exprt &expr) } } -/*******************************************************************\ - -Function: smt1_convt::convert_union - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_union(const exprt &expr) { const union_typet &union_type=to_union_type(expr.type()); @@ -2010,18 +1801,6 @@ void smt1_convt::convert_union(const exprt &expr) } } -/*******************************************************************\ - -Function: smt1_convt::convert_constant - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_constant( const constant_exprt &expr, bool bool_as_bv) @@ -2123,18 +1902,6 @@ void smt1_convt::convert_constant( throw "unknown constant: "+expr.type().id_string(); } -/*******************************************************************\ - -Function: smt1_convt::convert_mod - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_mod(const mod_exprt &expr) { assert(expr.operands().size()==2); @@ -2156,18 +1923,6 @@ void smt1_convt::convert_mod(const mod_exprt &expr) throw "unsupported type for mod: "+expr.type().id_string(); } -/*******************************************************************\ - -Function: smt1_convt::convert_is_dynamic_object - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_is_dynamic_object( const exprt &expr, bool bool_as_bv) @@ -2217,18 +1972,6 @@ void smt1_convt::convert_is_dynamic_object( from_bool_end(expr.type(), bool_as_bv); } -/*******************************************************************\ - -Function: smt1_convt::convert_relation - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_relation(const exprt &expr, bool bool_as_bv) { assert(expr.operands().size()==2); @@ -2294,18 +2037,6 @@ void smt1_convt::convert_relation(const exprt &expr, bool bool_as_bv) from_bool_end(expr.type(), bool_as_bv); } -/*******************************************************************\ - -Function: smt1_convt::convert_plus - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_plus(const plus_exprt &expr) { assert(expr.operands().size()>=2); @@ -2333,6 +2064,7 @@ void smt1_convt::convert_plus(const plus_exprt &expr) mp_integer element_size= pointer_offset_size(expr.type().subtype(), ns); + assert(element_size>0); // adjust width if needed if(boolbv_width(i.type())!=boolbv_width(expr.type())) @@ -2386,18 +2118,6 @@ void smt1_convt::convert_plus(const plus_exprt &expr) throw "unsupported type for +: "+expr.type().id_string(); } -/*******************************************************************\ - -Function: smt1_convt::convert_floatbv_plus - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_floatbv_plus(const exprt &expr) { assert(expr.operands().size()==3); @@ -2406,18 +2126,6 @@ void smt1_convt::convert_floatbv_plus(const exprt &expr) throw "todo: floatbv_plus"; } -/*******************************************************************\ - -Function: smt1_convt::convert_minus - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_minus(const minus_exprt &expr) { assert(expr.operands().size()==2); @@ -2457,18 +2165,6 @@ void smt1_convt::convert_minus(const minus_exprt &expr) throw "unsupported type for -: "+expr.type().id_string(); } -/*******************************************************************\ - -Function: smt1_convt::convert_floatbv_minus - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_floatbv_minus(const exprt &expr) { assert(expr.operands().size()==3); @@ -2477,18 +2173,6 @@ void smt1_convt::convert_floatbv_minus(const exprt &expr) throw "todo: floatbv_minus"; } -/*******************************************************************\ - -Function: smt1_convt::convert_div - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_div(const div_exprt &expr) { assert(expr.operands().size()==2); @@ -2528,18 +2212,6 @@ void smt1_convt::convert_div(const div_exprt &expr) throw "unsupported type for /: "+expr.type().id_string(); } -/*******************************************************************\ - -Function: smt1_convt::convert_floatbv_div - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_floatbv_div(const exprt &expr) { assert(expr.operands().size()==3); @@ -2548,18 +2220,6 @@ void smt1_convt::convert_floatbv_div(const exprt &expr) throw "todo: floatbv_div"; } -/*******************************************************************\ - -Function: smt1_convt::convert_mult - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_mult(const mult_exprt &expr) { assert(expr.operands().size()>=2); @@ -2623,18 +2283,6 @@ void smt1_convt::convert_mult(const mult_exprt &expr) throw "unsupported type for *: "+expr.type().id_string(); } -/*******************************************************************\ - -Function: smt1_convt::convert_floatbv_mult - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_floatbv_mult(const exprt &expr) { assert(expr.operands().size()==3); @@ -2643,18 +2291,6 @@ void smt1_convt::convert_floatbv_mult(const exprt &expr) throw "todo: floatbv_mult"; } -/*******************************************************************\ - -Function: smt1_convt::convert_with - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_with(const exprt &expr) { // get rid of "with" that has more than three operands @@ -2995,18 +2631,6 @@ void smt1_convt::convert_with(const exprt &expr) } } -/*******************************************************************\ - -Function: smt1_convt::convert_update - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_update(const exprt &expr) { assert(expr.operands().size()==3); @@ -3015,18 +2639,6 @@ void smt1_convt::convert_update(const exprt &expr) throw "smt1_convt::convert_update to be implemented"; } -/*******************************************************************\ - -Function: smt1_convt::convert_index - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_index(const index_exprt &expr, bool bool_as_bv) { assert(expr.operands().size()==2); @@ -3078,18 +2690,6 @@ void smt1_convt::convert_index(const index_exprt &expr, bool bool_as_bv) } } -/*******************************************************************\ - -Function: smt1_convt::convert_member - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_member(const member_exprt &expr, bool bool_as_bv) { assert(expr.operands().size()==1); @@ -3140,34 +2740,10 @@ void smt1_convt::convert_member(const member_exprt &expr, bool bool_as_bv) from_bv_end(expr.type(), bool_as_bv); } -/*******************************************************************\ - -Function: smt1_convt::convert_overflow - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_overflow(const exprt &expr) { } -/*******************************************************************\ - -Function: smt1_convt::set_to - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::set_to(const exprt &expr, bool value) { if(expr.id()==ID_and && value) @@ -3210,18 +2786,6 @@ void smt1_convt::set_to(const exprt &expr, bool value) out << "\n"; } -/*******************************************************************\ - -Function: smt1_convt::find_symbols - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::find_symbols(const exprt &expr) { const typet &type=expr.type(); @@ -3349,18 +2913,6 @@ void smt1_convt::find_symbols(const exprt &expr) } } -/*******************************************************************\ - -Function: smt1_convt::convert_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_type(const typet &type) { if(type.id()==ID_array) @@ -3423,18 +2975,6 @@ void smt1_convt::convert_type(const typet &type) throw "unsupported type: "+type.id_string(); } -/*******************************************************************\ - -Function: smt1_convt::convert_literal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_literal(const literalt l) { if(l==const_literal(false)) @@ -3453,18 +2993,6 @@ void smt1_convt::convert_literal(const literalt l) } } -/*******************************************************************\ - -Function: smt1_convt::from_bv_begin - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::from_bv_begin(const typet &type, bool bool_as_bv) { // this turns bv[1] into a predicate if needed @@ -3472,18 +3000,6 @@ void smt1_convt::from_bv_begin(const typet &type, bool bool_as_bv) out << "(= "; } -/*******************************************************************\ - -Function: smt1_convt::from_bv_end - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::from_bv_end(const typet &type, bool bool_as_bv) { // this turns bv[1] into a predicate if needed @@ -3491,18 +3007,6 @@ void smt1_convt::from_bv_end(const typet &type, bool bool_as_bv) out << " bv1[1])"; } -/*******************************************************************\ - -Function: smt1_convt::from_bool_begin - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::from_bool_begin(const typet &type, bool bool_as_bv) { // this turns a predicate into bv[1] if needed @@ -3510,18 +3014,6 @@ void smt1_convt::from_bool_begin(const typet &type, bool bool_as_bv) out << "(ite "; } -/*******************************************************************\ - -Function: smt1_convt::from_bool_end - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::from_bool_end(const typet &type, bool bool_as_bv) { // this turns a predicate into bv[1] if needed @@ -3529,36 +3021,12 @@ void smt1_convt::from_bool_end(const typet &type, bool bool_as_bv) out << " bv1[1] bv0[1])"; } -/*******************************************************************\ - -Function: smt1_convt::find_symbols - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::find_symbols(const typet &type) { std::set rec_stack; find_symbols_rec(type, rec_stack); } -/*******************************************************************\ - -Function: smt1_convt::find_symbols_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::find_symbols_rec( const typet &type, std::set &recstack) @@ -3609,18 +3077,6 @@ void smt1_convt::find_symbols_rec( } } -/*******************************************************************\ - -Function: smt1_convt::binary2struct - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt smt1_convt::binary2struct( const struct_typet &type, const std::string &binary) const @@ -3655,18 +3111,6 @@ exprt smt1_convt::binary2struct( return e; } -/*******************************************************************\ - -Function: smt1_convt::binary2union - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt smt1_convt::binary2union( const union_typet &type, const std::string &binary) const @@ -3697,18 +3141,6 @@ exprt smt1_convt::binary2union( return e; } -/*******************************************************************\ - -Function: smt1_convt::flatten_array - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::flatten_array(const exprt &op) { const array_typet array_type=to_array_type(op.type()); @@ -3756,18 +3188,6 @@ void smt1_convt::flatten_array(const exprt &op) #endif } -/*******************************************************************\ - -Function: smt1_convt::convert_nary - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_convt::convert_nary( const exprt &expr, const irep_idt op_string, diff --git a/src/solvers/smt1/smt1_conv.h b/src/solvers/smt1/smt1_conv.h index 5cdf736bda6..f152423df1c 100644 --- a/src/solvers/smt1/smt1_conv.h +++ b/src/solvers/smt1/smt1_conv.h @@ -7,6 +7,9 @@ Revision: Roberto Bruttomesso, roberto.bruttomesso@unisi.ch \*******************************************************************/ +/// \file +/// SMT Version 1 Backend + #ifndef CPROVER_SOLVERS_SMT1_SMT1_CONV_H #define CPROVER_SOLVERS_SMT1_SMT1_CONV_H @@ -28,8 +31,17 @@ class member_exprt; class smt1_convt:public prop_convt { public: - typedef enum - { GENERIC, BOOLECTOR, CVC3, CVC4, MATHSAT, OPENSMT, YICES, Z3 } solvert; + enum class solvert + { + GENERIC, + BOOLECTOR, + CVC3, + CVC4, + MATHSAT, + OPENSMT, + YICES, + Z3 + }; smt1_convt( const namespacet &_ns, diff --git a/src/solvers/smt1/smt1_dec.cpp b/src/solvers/smt1/smt1_dec.cpp index e994ba109d2..807fa527339 100644 --- a/src/solvers/smt1/smt1_dec.cpp +++ b/src/solvers/smt1/smt1_dec.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "smt1_dec.h" + #include #if defined(__linux__) || \ @@ -24,46 +26,20 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "smt1_dec.h" - -/*******************************************************************\ - -Function: smt1_dect::decision_procedure_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string smt1_dect::decision_procedure_text() const { return "SMT1 "+logic+" using "+ - (solver==GENERIC?"Generic": - solver==BOOLECTOR?"Boolector": - solver==CVC3?"CVC3": - solver==CVC4?"CVC3": - solver==MATHSAT?"MathSAT": - solver==OPENSMT?"OpenSMT": - solver==YICES?"Yices": - solver==Z3?"Z3": + (solver==solvert::GENERIC?"Generic": + solver==solvert::BOOLECTOR?"Boolector": + solver==solvert::CVC3?"CVC3": + solver==solvert::CVC4?"CVC3": + solver==solvert::MATHSAT?"MathSAT": + solver==solvert::OPENSMT?"OpenSMT": + solver==solvert::YICES?"Yices": + solver==solvert::Z3?"Z3": "(unknown)"); } -/*******************************************************************\ - -Function: smt1_temp_filet::smt1_temp_filet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - smt1_temp_filet::smt1_temp_filet() { temp_out_filename=get_temporary_file("smt1_dec_out_", ""); @@ -73,18 +49,6 @@ smt1_temp_filet::smt1_temp_filet() std::ios_base::out | std::ios_base::trunc); } -/*******************************************************************\ - -Function: smt1_temp_filet::~smt1_temp_filet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - smt1_temp_filet::~smt1_temp_filet() { temp_out.close(); @@ -96,18 +60,6 @@ smt1_temp_filet::~smt1_temp_filet() unlink(temp_result_filename.c_str()); } -/*******************************************************************\ - -Function: smt1_dect::dec_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - decision_proceduret::resultt smt1_dect::dec_solve() { // SMT1 is really not incremental @@ -125,7 +77,7 @@ decision_proceduret::resultt smt1_dect::dec_solve() switch(solver) { - case BOOLECTOR: + case solvert::BOOLECTOR: // -rwl0 disables rewriting, which makes things slower, // but in return values for arrays appear // command = "boolector -rwl0 --smt " @@ -136,34 +88,34 @@ decision_proceduret::resultt smt1_dect::dec_solve() + temp_result_filename; break; - case CVC3: + case solvert::CVC3: command = "cvc3 +model -lang smtlib -output-lang smtlib " + temp_out_filename + " > " + temp_result_filename; break; - case CVC4: + case solvert::CVC4: command = "cvc4 -L smt1 " + temp_out_filename + " > " + temp_result_filename; break; - case MATHSAT: + case solvert::MATHSAT: command = "mathsat -model -input=smt" " < "+temp_out_filename + " > "+temp_result_filename; break; - case OPENSMT: + case solvert::OPENSMT: command = "opensmt " + temp_out_filename + " > " + temp_result_filename; break; - case YICES: + case solvert::YICES: // command = "yices -smt -e " // Calling convention for older versions command = "yices-smt --full-model " // Calling for 2.2.1 + temp_out_filename @@ -171,7 +123,7 @@ decision_proceduret::resultt smt1_dect::dec_solve() + temp_result_filename; break; - case Z3: + case solvert::Z3: command = "z3 -smt " + temp_out_filename + " > " @@ -190,54 +142,43 @@ decision_proceduret::resultt smt1_dect::dec_solve() if(res<0) { error() << "error running SMT1 solver" << eom; - return decision_proceduret::D_ERROR; + return decision_proceduret::resultt::D_ERROR; } std::ifstream in(temp_result_filename.c_str()); switch(solver) { - case BOOLECTOR: + case solvert::BOOLECTOR: return read_result_boolector(in); - case CVC3: + case solvert::CVC3: return read_result_cvc3(in); - case CVC4: + case solvert::CVC4: error() << "no support for CVC4 with SMT1, use SMT2 instead" << eom; - return decision_proceduret::D_ERROR; + return decision_proceduret::resultt::D_ERROR; - case MATHSAT: + case solvert::MATHSAT: return read_result_mathsat(in); - case OPENSMT: + case solvert::OPENSMT: return read_result_opensmt(in); - case YICES: + case solvert::YICES: return read_result_yices(in); - case Z3: + case solvert::Z3: return read_result_z3(in); - case GENERIC: + case solvert::GENERIC: default: error() << "Generic solver can't solve" << eom; - return decision_proceduret::D_ERROR; + return decision_proceduret::resultt::D_ERROR; } } -/*******************************************************************\ - -Function: smt1_dect::read_result_boolector - - Inputs: - - Outputs: - - Purpose: read model produced by Boolector - -\*******************************************************************/ - +/// read model produced by Boolector decision_proceduret::resultt smt1_dect::read_result_boolector(std::istream &in) { std::string line; @@ -311,45 +252,21 @@ decision_proceduret::resultt smt1_dect::read_result_boolector(std::istream &in) boolean_assignment[v]=(value=="1"); } - return D_SATISFIABLE; + return resultt::D_SATISFIABLE; } else if(line=="unsat") - return D_UNSATISFIABLE; + return resultt::D_UNSATISFIABLE; else error() << "Unexpected result from SMT-Solver: " << line << eom; - return D_ERROR; + return resultt::D_ERROR; } -/*******************************************************************\ - -Function: smt1_dect::read_result_opensmt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - decision_proceduret::resultt smt1_dect::read_result_opensmt(std::istream &in) { - return D_ERROR; + return resultt::D_ERROR; } -/*******************************************************************\ - -Function: smt1_dect::read_result_yices - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - decision_proceduret::resultt smt1_dect::read_result_yices(std::istream &in) { std::string line; @@ -359,29 +276,17 @@ decision_proceduret::resultt smt1_dect::read_result_yices(std::istream &in) if(line=="sat") { // fixme: read values - return D_SATISFIABLE; + return resultt::D_SATISFIABLE; } else if(line=="unsat") - return D_UNSATISFIABLE; + return resultt::D_UNSATISFIABLE; } error() << "Unexpected result from SMT-Solver" << eom; - return D_ERROR; + return resultt::D_ERROR; } -/*******************************************************************\ - -Function: smt1_dect::mathsat_value - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string smt1_dect::mathsat_value(const std::string &src) { std::size_t pos=src.find('['); @@ -399,22 +304,10 @@ std::string smt1_dect::mathsat_value(const std::string &src) return ""; } -/*******************************************************************\ - -Function: smt1_dect::read_result_mathsat - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - decision_proceduret::resultt smt1_dect::read_result_mathsat(std::istream &in) { std::string line; - decision_proceduret::resultt res = D_ERROR; + decision_proceduret::resultt res = resultt::D_ERROR; boolean_assignment.clear(); boolean_assignment.resize(no_boolean_variables, false); @@ -425,9 +318,9 @@ decision_proceduret::resultt smt1_dect::read_result_mathsat(std::istream &in) while(std::getline(in, line)) { if(line=="sat") - res=D_SATISFIABLE; + res=resultt::D_SATISFIABLE; else if(line=="unsat") - res=D_UNSATISFIABLE; + res=resultt::D_UNSATISFIABLE; else if(line.size()>=1 && line[0]=='(') { // (iff B0 true) @@ -481,22 +374,10 @@ decision_proceduret::resultt smt1_dect::read_result_mathsat(std::istream &in) return res; } -/*******************************************************************\ - -Function: smt1_dect::read_result_z3 - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - decision_proceduret::resultt smt1_dect::read_result_z3(std::istream &in) { std::string line; - decision_proceduret::resultt res = D_ERROR; + decision_proceduret::resultt res = resultt::D_ERROR; boolean_assignment.clear(); boolean_assignment.resize(no_boolean_variables, false); @@ -507,9 +388,9 @@ decision_proceduret::resultt smt1_dect::read_result_z3(std::istream &in) while(std::getline(in, line)) { if(line=="sat") - res = D_SATISFIABLE; + res = resultt::D_SATISFIABLE; else if(line=="unsat") - res = D_UNSATISFIABLE; + res = resultt::D_UNSATISFIABLE; else { std::size_t pos=line.find(" -> "); @@ -549,18 +430,6 @@ decision_proceduret::resultt smt1_dect::read_result_z3(std::istream &in) return res; } -/*******************************************************************\ - -Function: smt1_dect::string_to_expr_z3 - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool smt1_dect::string_to_expr_z3( const typet &type, const std::string &value, @@ -677,22 +546,10 @@ bool smt1_dect::string_to_expr_z3( return false; } -/*******************************************************************\ - -Function: smt1_dect::read_result_cvc3 - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - decision_proceduret::resultt smt1_dect::read_result_cvc3(std::istream &in) { std::string line; - decision_proceduret::resultt res = D_ERROR; + decision_proceduret::resultt res = resultt::D_ERROR; boolean_assignment.clear(); boolean_assignment.resize(no_boolean_variables, false); @@ -703,9 +560,9 @@ decision_proceduret::resultt smt1_dect::read_result_cvc3(std::istream &in) while(std::getline(in, line)) { if(line=="sat") - res = D_SATISFIABLE; + res = resultt::D_SATISFIABLE; else if(line=="unsat") - res = D_UNSATISFIABLE; + res = resultt::D_UNSATISFIABLE; else if(line.find("Current scope level")!=std::string::npos || line.find("Variable Assignment")!=std::string::npos) { diff --git a/src/solvers/smt1/smt1_dec.h b/src/solvers/smt1/smt1_dec.h index 3cc6de03d46..7d1c8e49e9e 100644 --- a/src/solvers/smt1/smt1_dec.h +++ b/src/solvers/smt1/smt1_dec.h @@ -6,11 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_SMT1_SMT1_DEC_H #define CPROVER_SOLVERS_SMT1_SMT1_DEC_H -/*! \defgroup gr_smt1 SMT-LIB 1.x Interface */ - #include #include "smt1_conv.h" @@ -27,7 +26,6 @@ class smt1_temp_filet }; /*! \brief Decision procedure interface for various SMT 1.x solvers - \ingroup gr_smt1 */ class smt1_dect:protected smt1_temp_filet, public smt1_convt { diff --git a/src/solvers/smt1/smt1_prop.cpp b/src/solvers/smt1/smt1_prop.cpp index e39dfedde80..481d0d289c5 100644 --- a/src/solvers/smt1/smt1_prop.cpp +++ b/src/solvers/smt1/smt1_prop.cpp @@ -8,22 +8,9 @@ Revisions: Roberto Bruttomesso, roberto.bruttomesso@unisi.ch \*******************************************************************/ -#include - - #include "smt1_prop.h" -/*******************************************************************\ - -Function: smt1_propt::smt1_propt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include smt1_propt::smt1_propt( const std::string &benchmark, @@ -38,34 +25,10 @@ smt1_propt::smt1_propt( _no_variables=0; } -/*******************************************************************\ - -Function: smt1_propt::~smt1_propt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - smt1_propt::~smt1_propt() { } -/*******************************************************************\ - -Function: smt1_propt::finalize - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_propt::finalize() { out << "\n"; @@ -73,18 +36,6 @@ void smt1_propt::finalize() out << ") ; benchmark" << "\n"; } -/*******************************************************************\ - -Function: smt1_propt::land - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt1_propt::land(const bvt &bv) { out << "\n"; @@ -102,18 +53,6 @@ literalt smt1_propt::land(const bvt &bv) return l; } -/*******************************************************************\ - -Function: smt1_propt::lor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt1_propt::lor(const bvt &bv) { out << "\n"; @@ -131,18 +70,6 @@ literalt smt1_propt::lor(const bvt &bv) return l; } -/*******************************************************************\ - -Function: smt1_propt::lxor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt1_propt::lxor(const bvt &bv) { if(bv.empty()) @@ -165,18 +92,6 @@ literalt smt1_propt::lxor(const bvt &bv) return l; } -/*******************************************************************\ - -Function: smt1_propt::land - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt1_propt::land(literalt a, literalt b) { if(a==const_literal(true)) @@ -203,18 +118,6 @@ literalt smt1_propt::land(literalt a, literalt b) return l; } -/*******************************************************************\ - -Function: smt1_propt::lor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt1_propt::lor(literalt a, literalt b) { if(a==const_literal(false)) @@ -241,18 +144,6 @@ literalt smt1_propt::lor(literalt a, literalt b) return l; } -/*******************************************************************\ - -Function: smt1_propt::lxor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt1_propt::lxor(literalt a, literalt b) { if(a==const_literal(false)) @@ -277,86 +168,26 @@ literalt smt1_propt::lxor(literalt a, literalt b) return l; } -/*******************************************************************\ - -Function: smt1_propt::lnand - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt1_propt::lnand(literalt a, literalt b) { return !land(a, b); } -/*******************************************************************\ - -Function: smt1_propt::lnor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt1_propt::lnor(literalt a, literalt b) { return !lor(a, b); } -/*******************************************************************\ - -Function: smt1_propt::lequal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt1_propt::lequal(literalt a, literalt b) { return !lxor(a, b); } -/*******************************************************************\ - -Function: smt1_propt::limplies - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt1_propt::limplies(literalt a, literalt b) { return lor(!a, b); } -/*******************************************************************\ - -Function: smt1_propt::lselect - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt1_propt::lselect(literalt a, literalt b, literalt c) { if(a==const_literal(true)) @@ -387,18 +218,6 @@ literalt smt1_propt::lselect(literalt a, literalt b, literalt c) return l; } -/*******************************************************************\ - -Function: smt1_propt::new_variable - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt1_propt::new_variable() { literalt l; @@ -410,18 +229,6 @@ literalt smt1_propt::new_variable() return l; } -/*******************************************************************\ - -Function: smt1_propt::lcnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_propt::lcnf(const bvt &bv) { out << "\n"; @@ -445,18 +252,6 @@ void smt1_propt::lcnf(const bvt &bv) out << "\n"; } -/*******************************************************************\ - -Function: smt1_propt::smt1_literal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string smt1_propt::smt1_literal(literalt l) { if(l==const_literal(false)) @@ -472,18 +267,6 @@ std::string smt1_propt::smt1_literal(literalt l) return v; } -/*******************************************************************\ - -Function: smt1_propt::l_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt smt1_propt::l_get(literalt literal) const { if(literal.is_true()) @@ -498,18 +281,6 @@ tvt smt1_propt::l_get(literalt literal) const return literal.sign()?!r:r; } -/*******************************************************************\ - -Function: smt1_propt::set_assignment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt1_propt::set_assignment(literalt literal, bool value) { if(literal.is_true() || literal.is_false()) @@ -520,18 +291,6 @@ void smt1_propt::set_assignment(literalt literal, bool value) assignment[v]=tvt(value); } -/*******************************************************************\ - -Function: smt1_propt::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - propt::resultt smt1_propt::prop_solve() { return P_ERROR; diff --git a/src/solvers/smt1/smt1_prop.h b/src/solvers/smt1/smt1_prop.h index 1a7a5b86ddf..18fd9da1099 100644 --- a/src/solvers/smt1/smt1_prop.h +++ b/src/solvers/smt1/smt1_prop.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_SMT1_SMT1_PROP_H #define CPROVER_SOLVERS_SMT1_SMT1_PROP_H diff --git a/src/solvers/smt2/smt2_conv.cpp b/src/solvers/smt2/smt2_conv.cpp index badc8646993..50aff65da36 100644 --- a/src/solvers/smt2/smt2_conv.cpp +++ b/src/solvers/smt2/smt2_conv.cpp @@ -6,16 +6,23 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// SMT Backend + +#include "smt2_conv.h" + #include #include +#include +#include #include -#include -#include #include -#include #include -#include +#include +#include +#include +#include #include #include @@ -27,11 +34,8 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "smt2_conv.h" - // Mark different kinds of error condition // General -#define UNREACHABLE throw "Supposidly unreachable location reached" #define PARSERERROR(S) throw S // Error checking the expression type @@ -42,19 +46,7 @@ Author: Daniel Kroening, kroening@kroening.com #define UNEXPECTEDCASE(S) throw "Unexpected case: " S // General todos -#define TODO(S) throw "TODO: " S - -/*******************************************************************\ - -Function: smt2_convt::print_assignment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#define SMT2_TODO(S) throw "TODO: " S void smt2_convt::print_assignment(std::ostream &out) const { @@ -66,18 +58,6 @@ void smt2_convt::print_assignment(std::ostream &out) const // others } -/*******************************************************************\ - -Function: smt2_convt::l_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt smt2_convt::l_get(literalt l) const { if(l.is_true()) @@ -88,32 +68,20 @@ tvt smt2_convt::l_get(literalt l) const return tvt(boolean_assignment[l.var_no()]^l.sign()); } -/*******************************************************************\ - -Function: smt2_convt::write_header - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::write_header() { out << "; SMT 2" << "\n"; switch(solver) { - case GENERIC: break; - case BOOLECTOR: out << "; Generated for Boolector\n"; break; - case CVC3: out << "; Generated for CVC 3\n"; break; - case CVC4: out << "; Generated for CVC 4\n"; break; - case MATHSAT: out << "; Generated for MathSAT\n"; break; - case OPENSMT: out << "; Generated for OPENSMT\n"; break; - case YICES: out << "; Generated for Yices\n"; break; - case Z3: out << "; Generated for Z3\n"; break; + case solvert::GENERIC: break; + case solvert::BOOLECTOR: out << "; Generated for Boolector\n"; break; + case solvert::CVC3: out << "; Generated for CVC 3\n"; break; + case solvert::CVC4: out << "; Generated for CVC 4\n"; break; + case solvert::MATHSAT: out << "; Generated for MathSAT\n"; break; + case solvert::OPENSMT: out << "; Generated for OPENSMT\n"; break; + case solvert::YICES: out << "; Generated for Yices\n"; break; + case solvert::Z3: out << "; Generated for Z3\n"; break; } out << "(set-info :source \"" << notes << "\")" << "\n"; @@ -127,18 +95,6 @@ void smt2_convt::write_header() out << "(set-logic " << logic << ")" << "\n"; } -/*******************************************************************\ - -Function: smt2_convt::write_footer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::write_footer(std::ostream &out) { out << "\n"; @@ -163,7 +119,7 @@ void smt2_convt::write_footer(std::ostream &out) out << "(check-sat)" << "\n"; out << "\n"; - if(solver!=BOOLECTOR) + if(solver!=solvert::BOOLECTOR) { for(const auto &id : smt2_identifiers) out << "(get-value (|" << id << "|))" << "\n"; @@ -176,18 +132,6 @@ void smt2_convt::write_footer(std::ostream &out) out << "; end of SMT2 file" << "\n"; } -/*******************************************************************\ - -Function: smt2_convt::define_object_size - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::define_object_size( const irep_idt &id, const exprt &expr) @@ -225,37 +169,13 @@ void smt2_convt::define_object_size( } } -/*******************************************************************\ - -Function: smt2_convt::dec_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - decision_proceduret::resultt smt2_convt::dec_solve() { write_footer(out); out.flush(); - return decision_proceduret::D_ERROR; + return decision_proceduret::resultt::D_ERROR; } -/*******************************************************************\ - -Function: smt2_convt::get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt smt2_convt::get(const exprt &expr) const { if(expr.id()==ID_symbol) @@ -279,18 +199,6 @@ exprt smt2_convt::get(const exprt &expr) const return nil_exprt(); } -/*******************************************************************\ - -Function: smt2_convt::parse_literal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - constant_exprt smt2_convt::parse_literal( const irept &src, const typet &type) @@ -411,18 +319,6 @@ constant_exprt smt2_convt::parse_literal( UNEXPECTEDCASE("smt2_convt::parse_literal can't do type "+type.id_string()); } -/*******************************************************************\ - -Function: smt2_convt::parse_array - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt smt2_convt::parse_array( const irept &src, const array_typet &type) @@ -453,18 +349,6 @@ exprt smt2_convt::parse_array( return nil_exprt(); } -/*******************************************************************\ - -Function: smt2_convt::parse_union - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt smt2_convt::parse_union( const irept &src, const union_typet &type) @@ -480,18 +364,6 @@ exprt smt2_convt::parse_union( return union_exprt(first.get_name(), converted, type); } -/*******************************************************************\ - -Function: smt2_convt::parse_struct - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt smt2_convt::parse_struct( const irept &src, const struct_typet &type) @@ -553,18 +425,6 @@ exprt smt2_convt::parse_struct( return result; } -/*******************************************************************\ - -Function: smt2_convt::parse_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt smt2_convt::parse_rec(const irept &src, const typet &_type) { const typet &type=ns.follow(_type); @@ -616,18 +476,6 @@ exprt smt2_convt::parse_rec(const irept &src, const typet &_type) return nil_exprt(); } -/*******************************************************************\ - -Function: smt2_convt::convert_address_of_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_address_of_rec( const exprt &expr, const pointer_typet &result_type) @@ -665,12 +513,14 @@ void smt2_convt::convert_address_of_rec( exprt new_index_expr=expr; new_index_expr.op1()=from_integer(0, index.type()); - exprt address_of_expr(ID_address_of, pointer_typet()); - address_of_expr.type().subtype()=array.type().subtype(); - address_of_expr.copy_to_operands(new_index_expr); + address_of_exprt address_of_expr( + new_index_expr, + pointer_type(array.type().subtype())); - exprt plus_expr(ID_plus, address_of_expr.type()); - plus_expr.copy_to_operands(address_of_expr, index); + plus_exprt plus_expr( + address_of_expr, + index, + address_of_expr.type()); convert_expr(plus_expr); } @@ -694,6 +544,7 @@ void smt2_convt::convert_address_of_rec( member_expr.get_component_name(); mp_integer offset=member_offset(struct_type, component_name, ns); + assert(offset>=0); unsignedbv_typet index_type; index_type.set_width(boolbv_width(result_type)); @@ -723,39 +574,15 @@ void smt2_convt::convert_address_of_rec( UNEXPECTEDCASE("don't know how to take address of: "+expr.id_string()); } -/*******************************************************************\ - -Function: smt2_convt::convert_byte_extract - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_byte_extract(const byte_extract_exprt &expr) { // we just run the flattener exprt flattened_expr=flatten_byte_extract(expr, ns); - unflatten(BEGIN, expr.type()); + unflatten(wheret::BEGIN, expr.type()); convert_expr(flattened_expr); - unflatten(END, expr.type()); + unflatten(wheret::END, expr.type()); } -/*******************************************************************\ - -Function: smt2_convt::convert_byte_update - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_byte_update(const byte_update_exprt &expr) { assert(expr.operands().size()==3); @@ -854,24 +681,12 @@ void smt2_convt::convert_byte_update(const byte_update_exprt &expr) exprt ext_value=typecast_exprt(expr.value(), one_mask.type()); exprt or_expr=bitor_exprt(and_expr, shl_exprt(ext_value, distance)); - unflatten(BEGIN, expr.type()); + unflatten(wheret::BEGIN, expr.type()); flatten2bv(or_expr); - unflatten(END, expr.type()); + unflatten(wheret::END, expr.type()); #endif } -/*******************************************************************\ - -Function: smt2_convt::convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt2_convt::convert(const exprt &expr) { assert(expr.type().id()==ID_bool); @@ -904,18 +719,6 @@ literalt smt2_convt::convert(const exprt &expr) return l; } -/*******************************************************************\ - -Function: smt2_convt::convert_literal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_literal(const literalt l) { if(l==const_literal(false)) @@ -936,18 +739,6 @@ void smt2_convt::convert_literal(const literalt l) } } -/*******************************************************************\ - -Function: smt2_convt::convert_identifier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string smt2_convt::convert_identifier(const irep_idt &identifier) { // Backslashes are disallowed in quoted symbols just for simplicity. @@ -979,18 +770,6 @@ std::string smt2_convt::convert_identifier(const irep_idt &identifier) return result; } -/*******************************************************************\ - -Function: smt2_convt::type2id - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string smt2_convt::type2id(const typet &type) const { if(type.id()==ID_floatbv) @@ -1025,36 +804,12 @@ std::string smt2_convt::type2id(const typet &type) const } } -/*******************************************************************\ - -Function: smt2_convt::floatbv_suffix - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string smt2_convt::floatbv_suffix(const exprt &expr) const { assert(!expr.operands().empty()); return "_"+type2id(expr.op0().type())+"->"+type2id(expr.type()); } -/*******************************************************************\ - -Function: smt2_convt::convert_floatbv - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_floatbv(const exprt &expr) { assert(!use_FPA_theory); @@ -1088,18 +843,6 @@ void smt2_convt::convert_floatbv(const exprt &expr) out << ')'; } -/*******************************************************************\ - -Function: smt2_convt::convert_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_expr(const exprt &expr) { // huge monster case split over expression id @@ -1212,7 +955,7 @@ void smt2_convt::convert_expr(const exprt &expr) out << "))"; // mk-, let } else - TODO("bitnot for vectors"); + SMT2_TODO("bitnot for vectors"); } else { @@ -1277,7 +1020,7 @@ void smt2_convt::convert_expr(const exprt &expr) out << "))"; // mk-, let } else - TODO("unary minus for vector"); + SMT2_TODO("unary minus for vector"); } else { @@ -1623,7 +1366,7 @@ void smt2_convt::convert_expr(const exprt &expr) assert(expr.operands().size()==1); out << "false"; // TODO - TODO("pointer_object_has_type not implemented"); + SMT2_TODO("pointer_object_has_type not implemented"); } else if(expr.id()==ID_string_constant) { @@ -1692,7 +1435,7 @@ void smt2_convt::convert_expr(const exprt &expr) convert_expr(tmp); out << ")) bin1)"; // bvlshr, extract, = #endif - TODO("smt2: extractbits with non-constant index"); + SMT2_TODO("smt2: extractbits with non-constant index"); } } else if(expr.id()==ID_replication) @@ -1972,7 +1715,7 @@ void smt2_convt::convert_expr(const exprt &expr) else if(expr.id()==ID_forall || expr.id()==ID_exists) { - if(solver==MATHSAT) + if(solver==solvert::MATHSAT) // NOLINTNEXTLINE(readability/throw) throw "MathSAT does not support quantifiers"; @@ -2050,18 +1793,6 @@ void smt2_convt::convert_expr(const exprt &expr) "smt2_convt::convert_expr: `"+expr.id_string()+"' is unsupported"); } -/*******************************************************************\ - -Function: smt2_convt::convert_typecast - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_typecast(const typecast_exprt &expr) { assert(expr.operands().size()==1); @@ -2216,7 +1947,7 @@ void smt2_convt::convert_typecast(const typecast_exprt &expr) // This conversion is non-trivial as it requires creating a // new bit-vector variable and then asserting that it converts // to the required floating-point number. - TODO("bit-wise floatbv to bv"); + SMT2_TODO("bit-wise floatbv to bv"); } else { @@ -2289,7 +2020,7 @@ void smt2_convt::convert_typecast(const typecast_exprt &expr) out << "(_ bv" << i << " " << to_width << ")"; } else - TODO("can't convert non-constant integer to bitvector"); + SMT2_TODO("can't convert non-constant integer to bitvector"); } else if(src_type.id()==ID_struct) // flatten a struct to a bit-vector { @@ -2479,7 +2210,7 @@ void smt2_convt::convert_typecast(const typecast_exprt &expr) } else if(dest_type.id()==ID_range) { - TODO("range typecast"); + SMT2_TODO("range typecast"); } else if(dest_type.id()==ID_floatbv) { @@ -2546,18 +2277,6 @@ void smt2_convt::convert_typecast(const typecast_exprt &expr) "TODO typecast8 "+src_type.id_string()+" -> "+dest_type.id_string()); } -/*******************************************************************\ - -Function: smt2_convt::convert_floatbv_typecast - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_floatbv_typecast(const floatbv_typecast_exprt &expr) { const exprt &src=expr.op(); @@ -2704,18 +2423,6 @@ void smt2_convt::convert_floatbv_typecast(const floatbv_typecast_exprt &expr) } } -/*******************************************************************\ - -Function: smt2_convt::convert_struct - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_struct(const struct_exprt &expr) { const struct_typet &struct_type=to_struct_type(expr.type()); @@ -2778,18 +2485,7 @@ void smt2_convt::convert_struct(const struct_exprt &expr) } } -/*******************************************************************\ - -Function: smt2_convt::flatten_array - - Inputs: - - Outputs: - - Purpose: produce a flat bit-vector for a given array of fixed size - -\*******************************************************************/ - +/// produce a flat bit-vector for a given array of fixed size void smt2_convt::flatten_array(const exprt &expr) { const array_typet &array_type= @@ -2824,18 +2520,6 @@ void smt2_convt::flatten_array(const exprt &expr) out << ")"; // let } -/*******************************************************************\ - -Function: smt2_convt::convert_union - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_union(const union_exprt &expr) { const union_typet &union_type=to_union_type(expr.type()); @@ -2869,18 +2553,6 @@ void smt2_convt::convert_union(const union_exprt &expr) } } -/*******************************************************************\ - -Function: smt2_convt::convert_constant - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_constant(const constant_exprt &expr) { const typet &expr_type=expr.type(); @@ -3017,18 +2689,6 @@ void smt2_convt::convert_constant(const constant_exprt &expr) UNEXPECTEDCASE("unknown constant: "+expr_type.id_string()); } -/*******************************************************************\ - -Function: smt2_convt::convert_mod - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_mod(const mod_exprt &expr) { assert(expr.operands().size()==2); @@ -3050,18 +2710,6 @@ void smt2_convt::convert_mod(const mod_exprt &expr) UNEXPECTEDCASE("unsupported type for mod: "+expr.type().id_string()); } -/*******************************************************************\ - -Function: smt2_convt::convert_is_dynamic_object - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_is_dynamic_object(const exprt &expr) { std::vector dynamic_objects; @@ -3101,18 +2749,6 @@ void smt2_convt::convert_is_dynamic_object(const exprt &expr) } } -/*******************************************************************\ - -Function: smt2_convt::convert_relation - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_relation(const exprt &expr) { assert(expr.operands().size()==2); @@ -3198,21 +2834,9 @@ void smt2_convt::convert_relation(const exprt &expr) "unsupported type for "+expr.id_string()+": "+op_type.id_string()); } -/*******************************************************************\ - -Function: smt2_convt::convert_plus - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_plus(const plus_exprt &expr) { - if(expr.operands().size()==0) + if(expr.operands().empty()) { INVALIDEXPR("No operands to plus"); } @@ -3253,6 +2877,7 @@ void smt2_convt::convert_plus(const plus_exprt &expr) mp_integer element_size= pointer_offset_size(expr.type().subtype(), ns); + assert(element_size>0); out << "(bvadd "; convert_expr(p); @@ -3326,19 +2951,10 @@ void smt2_convt::convert_plus(const plus_exprt &expr) } } -/*******************************************************************\ - -Function: smt2_convt::convert_rounding_mode_FPA - - Inputs: The expression representing the rounding mode. - - Outputs: SMT-LIB output to out. - - Purpose: Converting a constant or symbolic rounding mode to SMT-LIB. - Only called when use_FPA_theory is enabled - -\*******************************************************************/ - +/// Converting a constant or symbolic rounding mode to SMT-LIB. Only called when +/// use_FPA_theory is enabled +/// \par parameters: The expression representing the rounding mode. +/// \return SMT-LIB output to out. void smt2_convt::convert_rounding_mode_FPA(const exprt &expr) { assert(use_FPA_theory); @@ -3395,18 +3011,6 @@ void smt2_convt::convert_rounding_mode_FPA(const exprt &expr) } } -/*******************************************************************\ - -Function: smt2_convt::convert_floatbv_plus - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_floatbv_plus(const ieee_float_op_exprt &expr) { const typet &type=expr.type(); @@ -3430,11 +3034,11 @@ void smt2_convt::convert_floatbv_plus(const ieee_float_op_exprt &expr) } else if(type.id()==ID_complex) { - TODO("+ for floatbv complex"); + SMT2_TODO("+ for floatbv complex"); } else if(type.id()==ID_vector) { - TODO("+ for floatbv vector"); + SMT2_TODO("+ for floatbv vector"); } else UNEXPECTEDCASE("unsupported type for +: "+type.id_string()); @@ -3443,18 +3047,6 @@ void smt2_convt::convert_floatbv_plus(const ieee_float_op_exprt &expr) convert_floatbv(expr); } -/*******************************************************************\ - -Function: smt2_convt::convert_minus - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_minus(const minus_exprt &expr) { assert(expr.operands().size()==2); @@ -3469,6 +3061,7 @@ void smt2_convt::convert_minus(const minus_exprt &expr) // Pointer difference. mp_integer element_size= pointer_offset_size(expr.op0().type().subtype(), ns); + assert(element_size>0); if(element_size>=2) out << "(bvsdiv "; @@ -3503,7 +3096,7 @@ void smt2_convt::convert_minus(const minus_exprt &expr) } else if(expr.type().id()==ID_pointer) { - TODO("pointer subtraction"); + SMT2_TODO("pointer subtraction"); } else if(expr.type().id()==ID_vector) { @@ -3548,18 +3141,6 @@ void smt2_convt::convert_minus(const minus_exprt &expr) UNEXPECTEDCASE("unsupported type for -: "+expr.type().id_string()); } -/*******************************************************************\ - -Function: smt2_convt::convert_floatbv_minus - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_floatbv_minus(const ieee_float_op_exprt &expr) { assert(expr.operands().size()==3); @@ -3579,18 +3160,6 @@ void smt2_convt::convert_floatbv_minus(const ieee_float_op_exprt &expr) convert_floatbv(expr); } -/*******************************************************************\ - -Function: smt2_convt::convert_div - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_div(const div_exprt &expr) { assert(expr.operands().size()==2); @@ -3637,18 +3206,6 @@ void smt2_convt::convert_div(const div_exprt &expr) UNEXPECTEDCASE("unsupported type for /: "+expr.type().id_string()); } -/*******************************************************************\ - -Function: smt2_convt::convert_floatbv_div - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_floatbv_div(const ieee_float_op_exprt &expr) { assert(expr.operands().size()==3); @@ -3668,18 +3225,6 @@ void smt2_convt::convert_floatbv_div(const ieee_float_op_exprt &expr) convert_floatbv(expr); } -/*******************************************************************\ - -Function: smt2_convt::convert_mult - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_mult(const mult_exprt &expr) { assert(expr.operands().size()>=2); @@ -3753,18 +3298,6 @@ void smt2_convt::convert_mult(const mult_exprt &expr) UNEXPECTEDCASE("unsupported type for *: "+expr.type().id_string()); } -/*******************************************************************\ - -Function: smt2_convt::convert_floatbv_mult - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_floatbv_mult(const ieee_float_op_exprt &expr) { assert(expr.operands().size()==3); @@ -3784,18 +3317,6 @@ void smt2_convt::convert_floatbv_mult(const ieee_float_op_exprt &expr) convert_floatbv(expr); } -/*******************************************************************\ - -Function: smt2_convt::convert_with - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_with(const with_exprt &expr) { // get rid of "with" that has more than three operands @@ -4009,7 +3530,9 @@ void smt2_convt::convert_with(const with_exprt &expr) typecast_exprt index_tc(index, expr_type); // TODO: SMT2-ify - TODO("SMT2-ify"); + SMT2_TODO("SMT2-ify"); + +#if 0 out << "(bvor "; out << "(band "; @@ -4036,6 +3559,7 @@ void smt2_convt::convert_with(const with_exprt &expr) out << ")"; // bvshl out << ")"; // bvor +#endif } else UNEXPECTEDCASE( @@ -4043,37 +3567,13 @@ void smt2_convt::convert_with(const with_exprt &expr) expr.type().id_string()); } -/*******************************************************************\ - -Function: smt2_convt::convert_update - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_update(const exprt &expr) { assert(expr.operands().size()==3); - TODO("smt2_convt::convert_update to be implemented"); + SMT2_TODO("smt2_convt::convert_update to be implemented"); } -/*******************************************************************\ - -Function: smt2_convt::convert_index - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_index(const index_exprt &expr) { assert(expr.operands().size()==2); @@ -4111,7 +3611,7 @@ void smt2_convt::convert_index(const index_exprt &expr) std::size_t array_width=boolbv_width(array_type); assert(array_width!=0); - unflatten(BEGIN, array_type.subtype()); + unflatten(wheret::BEGIN, array_type.subtype()); std::size_t sub_width=boolbv_width(array_type.subtype()); std::size_t index_width=boolbv_width(expr.index().type()); @@ -4139,7 +3639,7 @@ void smt2_convt::convert_index(const index_exprt &expr) out << ")))"; // mult, bvlshr, extract - unflatten(END, array_type.subtype()); + unflatten(wheret::END, array_type.subtype()); } } else if(array_op_type.id()==ID_vector) @@ -4157,7 +3657,7 @@ void smt2_convt::convert_index(const index_exprt &expr) mp_integer index_int; if(to_integer(expr.index(), index_int)) { - TODO("non-constant index on vectors"); + SMT2_TODO("non-constant index on vectors"); } else { @@ -4168,7 +3668,7 @@ void smt2_convt::convert_index(const index_exprt &expr) } else { - TODO("index on vectors"); + SMT2_TODO("index on vectors"); } } else @@ -4176,18 +3676,6 @@ void smt2_convt::convert_index(const index_exprt &expr) "index with unsupported array type: "+array_op_type.id_string()); } -/*******************************************************************\ - -Function: smt2_convt::convert_member - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_member(const member_exprt &expr) { assert(expr.operands().size()==1); @@ -4238,7 +3726,7 @@ void smt2_convt::convert_member(const member_exprt &expr) if(width==0) INVALIDEXPR("failed to get union member width"); - unflatten(BEGIN, expr.type()); + unflatten(wheret::BEGIN, expr.type()); out << "((_ extract " << (width-1) @@ -4246,25 +3734,13 @@ void smt2_convt::convert_member(const member_exprt &expr) convert_expr(struct_op); out << ")"; - unflatten(END, expr.type()); + unflatten(wheret::END, expr.type()); } else UNEXPECTEDCASE( "convert_member on an unexpected type "+struct_op_type.id_string()); } -/*******************************************************************\ - -Function: smt2_convt::flatten2bv - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::flatten2bv(const exprt &expr) { const typet &type=ns.follow(expr.type()); @@ -4361,18 +3837,6 @@ void smt2_convt::flatten2bv(const exprt &expr) convert_expr(expr); } -/*******************************************************************\ - -Function: smt2_convt::unflatten - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::unflatten( wheret where, const typet &type, @@ -4383,7 +3847,7 @@ void smt2_convt::unflatten( if(type.id()==ID_bool) { - if(where==BEGIN) + if(where==wheret::BEGIN) out << "(= "; // produces a bool else out << " #b1)"; @@ -4406,7 +3870,7 @@ void smt2_convt::unflatten( if(to_integer(vector_type.size(), size)) INVALIDEXPR("failed to convert vector size to constant"); - if(where==BEGIN) + if(where==wheret::BEGIN) out << "(let ((?ufop" << nesting << " "; else { @@ -4419,10 +3883,10 @@ void smt2_convt::unflatten( for(mp_integer i=0; i!=size; ++i, offset+=subtype_width) { out << " "; - unflatten(BEGIN, vector_type.subtype(), nesting+1); + unflatten(wheret::BEGIN, vector_type.subtype(), nesting+1); out << "((_ extract " << offset+subtype_width-1 << " " << offset << ") ?ufop" << nesting << ")"; - unflatten(END, vector_type.subtype(), nesting+1); + unflatten(wheret::END, vector_type.subtype(), nesting+1); } out << "))"; // mk-, let @@ -4438,7 +3902,7 @@ void smt2_convt::unflatten( if(use_datatypes) { // extract members - if(where==BEGIN) + if(where==wheret::BEGIN) out << "(let ((?ufop" << nesting << " "; else { @@ -4467,10 +3931,10 @@ void smt2_convt::unflatten( std::size_t member_width=boolbv_width(it->type()); out << " "; - unflatten(BEGIN, it->type(), nesting+1); + unflatten(wheret::BEGIN, it->type(), nesting+1); out << "((_ extract " << offset+member_width-1 << " " << offset << ") ?ufop" << nesting << ")"; - unflatten(END, it->type(), nesting+1); + unflatten(wheret::END, it->type(), nesting+1); offset+=member_width; } @@ -4488,35 +3952,11 @@ void smt2_convt::unflatten( } } -/*******************************************************************\ - -Function: smt2_convt::convert_overflow - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_overflow(const exprt &expr) { UNREACHABLE; } -/*******************************************************************\ - -Function: smt2_convt::set_to - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::set_to(const exprt &expr, bool value) { if(expr.id()==ID_and && value) @@ -4605,18 +4045,6 @@ void smt2_convt::set_to(const exprt &expr, bool value) return; } -/*******************************************************************\ - -Function: smt2_convt::find_symbols - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::find_symbols(const exprt &expr) { // recursive call on type @@ -4810,18 +4238,6 @@ void smt2_convt::find_symbols(const exprt &expr) } } -/*******************************************************************\ - -Function: smt2_convt::use_array_theory - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool smt2_convt::use_array_theory(const exprt &expr) { const typet &type=ns.follow(expr.type()); @@ -4844,18 +4260,6 @@ bool smt2_convt::use_array_theory(const exprt &expr) } } -/*******************************************************************\ - -Function: smt2_convt::convert_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::convert_type(const typet &type) { if(type.id()==ID_array) @@ -5007,36 +4411,12 @@ void smt2_convt::convert_type(const typet &type) } } -/*******************************************************************\ - -Function: smt2_convt::find_symbols - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::find_symbols(const typet &type) { std::set recstack; find_symbols_rec(type, recstack); } -/*******************************************************************\ - -Function: smt2_convt::find_symbols_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::find_symbols_rec( const typet &type, std::set &recstack) @@ -5233,18 +4613,6 @@ void smt2_convt::find_symbols_rec( } } -/*******************************************************************\ - -Function: smt2_convt::letify - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt smt2_convt::letify(exprt &expr) { seen_expressionst map; @@ -5255,18 +4623,6 @@ exprt smt2_convt::letify(exprt &expr) return letify_rec(expr, let_order, map, 0); } -/*******************************************************************\ - -Function: smt2_convt::letify_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt smt2_convt::letify_rec( exprt &expr, std::vector &let_order, @@ -5291,18 +4647,6 @@ exprt smt2_convt::letify_rec( return let; } -/*******************************************************************\ - -Function: smt2_convt::collect_bindings - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_convt::collect_bindings( exprt &expr, seen_expressionst &map, @@ -5334,18 +4678,6 @@ void smt2_convt::collect_bindings( let_order.push_back(expr); } -/*******************************************************************\ - -Function: smt2_convt::substitute_let - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt smt2_convt::substitute_let( exprt &expr, const seen_expressionst &map) diff --git a/src/solvers/smt2/smt2_conv.h b/src/solvers/smt2/smt2_conv.h index c5127db59f0..c857cd8efaf 100644 --- a/src/solvers/smt2/smt2_conv.h +++ b/src/solvers/smt2/smt2_conv.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_SMT2_SMT2_CONV_H #define CPROVER_SOLVERS_SMT2_SMT2_CONV_H @@ -27,7 +28,7 @@ class member_exprt; class smt2_convt:public prop_convt { public: - typedef enum + enum class solvert { GENERIC, BOOLECTOR, @@ -37,7 +38,7 @@ class smt2_convt:public prop_convt OPENSMT, YICES, Z3 - } solvert; + }; smt2_convt( const namespacet &_ns, @@ -66,28 +67,28 @@ class smt2_convt:public prop_convt switch(solver) { - case GENERIC: + case solvert::GENERIC: break; - case BOOLECTOR: + case solvert::BOOLECTOR: break; - case CVC3: + case solvert::CVC3: break; - case CVC4: + case solvert::CVC4: break; - case MATHSAT: + case solvert::MATHSAT: break; - case OPENSMT: + case solvert::OPENSMT: break; - case YICES: + case solvert::YICES: break; - case Z3: + case solvert::Z3: use_array_of_bool=true; emit_set_logic=false; use_datatypes=true; @@ -249,7 +250,7 @@ class smt2_convt:public prop_convt // e.g., booleans, vectors, structs, arrays but also // floats when using the FPA theory. // unflatten() does the opposite. - typedef enum { BEGIN, END } wheret; + enum class wheret { BEGIN, END }; void flatten2bv(const exprt &); void unflatten(wheret, const typet &, unsigned nesting=0); diff --git a/src/solvers/smt2/smt2_dec.cpp b/src/solvers/smt2/smt2_dec.cpp index 451f9da0d0a..41f17d66fc3 100644 --- a/src/solvers/smt2/smt2_dec.cpp +++ b/src/solvers/smt2/smt2_dec.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "smt2_dec.h" + #include #if defined(__linux__) || \ @@ -23,49 +25,24 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "smt2_dec.h" #include "smt2irep.h" -/*******************************************************************\ - -Function: smt2_dect::decision_procedure_text - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string smt2_dect::decision_procedure_text() const { return "SMT2 "+logic+ (use_FPA_theory?" (with FPA)":"")+ " using "+ - (solver==GENERIC?"Generic": - solver==BOOLECTOR?"Boolector": - solver==CVC3?"CVC3": - solver==CVC4?"CVC4": - solver==MATHSAT?"MathSAT": - solver==OPENSMT?"OpenSMT": - solver==YICES?"Yices": - solver==Z3?"Z3": + (solver==solvert::GENERIC?"Generic": + solver==solvert::BOOLECTOR?"Boolector": + solver==solvert::CVC3?"CVC3": + solver==solvert::CVC4?"CVC4": + solver==solvert::MATHSAT?"MathSAT": + solver==solvert::OPENSMT?"OpenSMT": + solver==solvert::YICES?"Yices": + solver==solvert::Z3?"Z3": "(unknown)"); } -/*******************************************************************\ - -Function: smt2_temp_filet::smt2_temp_filet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - smt2_temp_filet::smt2_temp_filet() { temp_out_filename=get_temporary_file("smt2_dec_out_", ""); @@ -75,18 +52,6 @@ smt2_temp_filet::smt2_temp_filet() std::ios_base::out | std::ios_base::trunc); } -/*******************************************************************\ - -Function: smt2_temp_filet::~smt2_temp_filet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - smt2_temp_filet::~smt2_temp_filet() { temp_out.close(); @@ -98,18 +63,6 @@ smt2_temp_filet::~smt2_temp_filet() unlink(temp_result_filename.c_str()); } -/*******************************************************************\ - -Function: smt2_dect::dec_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - decision_proceduret::resultt smt2_dect::dec_solve() { // we write the problem into a file @@ -129,21 +82,21 @@ decision_proceduret::resultt smt2_dect::dec_solve() switch(solver) { - case BOOLECTOR: + case solvert::BOOLECTOR: command = "boolector --smt2 " + smt2_temp_file.temp_out_filename + " -m > " + smt2_temp_file.temp_result_filename; break; - case CVC3: + case solvert::CVC3: command = "cvc3 +model -lang smtlib -output-lang smtlib " + smt2_temp_file.temp_out_filename + " > " + smt2_temp_file.temp_result_filename; break; - case CVC4: + case solvert::CVC4: // The flags --bitblast=eager --bv-div-zero-const help but only // work for pure bit-vector formulas. command = "cvc4 -L smt2 " @@ -152,7 +105,7 @@ decision_proceduret::resultt smt2_dect::dec_solve() + smt2_temp_file.temp_result_filename; break; - case MATHSAT: + case solvert::MATHSAT: // The options below were recommended by Alberto Griggio // on 10 July 2013 command = "mathsat -input=smt2" @@ -173,7 +126,7 @@ decision_proceduret::resultt smt2_dect::dec_solve() + " > "+smt2_temp_file.temp_result_filename; break; - case OPENSMT: + case solvert::OPENSMT: command = "opensmt " + smt2_temp_file.temp_out_filename + " > " @@ -181,7 +134,7 @@ decision_proceduret::resultt smt2_dect::dec_solve() break; - case YICES: + case solvert::YICES: // command = "yices -smt -e " // Calling convention for older versions command = "yices-smt2 " // Calling for 2.2.1 + smt2_temp_file.temp_out_filename @@ -189,7 +142,7 @@ decision_proceduret::resultt smt2_dect::dec_solve() + smt2_temp_file.temp_result_filename; break; - case Z3: + case solvert::Z3: command = "z3 -smt2 " + smt2_temp_file.temp_out_filename + " > " @@ -208,7 +161,7 @@ decision_proceduret::resultt smt2_dect::dec_solve() if(res<0) { error() << "error running SMT2 solver" << eom; - return decision_proceduret::D_ERROR; + return decision_proceduret::resultt::D_ERROR; } std::ifstream in(smt2_temp_file.temp_result_filename.c_str()); @@ -216,22 +169,10 @@ decision_proceduret::resultt smt2_dect::dec_solve() return read_result(in); } -/*******************************************************************\ - -Function: smt2_dect::read_result - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - decision_proceduret::resultt smt2_dect::read_result(std::istream &in) { std::string line; - decision_proceduret::resultt res=D_ERROR; + decision_proceduret::resultt res=resultt::D_ERROR; boolean_assignment.clear(); boolean_assignment.resize(no_boolean_variables, false); @@ -244,9 +185,9 @@ decision_proceduret::resultt smt2_dect::read_result(std::istream &in) irept parsed=smt2irep(in); if(parsed.id()=="sat") - res=D_SATISFIABLE; + res=resultt::D_SATISFIABLE; else if(parsed.id()=="unsat") - res=D_UNSATISFIABLE; + res=resultt::D_UNSATISFIABLE; else if(parsed.id()=="" && parsed.get_sub().size()==1 && parsed.get_sub().front().get_sub().size()==2) @@ -266,11 +207,11 @@ decision_proceduret::resultt smt2_dect::read_result(std::istream &in) { // We ignore errors after UNSAT because get-value after check-sat // returns unsat will give an error. - if(res!=D_UNSATISFIABLE) + if(res!=resultt::D_UNSATISFIABLE) { error() << "SMT2 solver returned error message:\n" << "\t\"" << parsed.get_sub()[1].id() <<"\"" << eom; - return decision_proceduret::D_ERROR; + return decision_proceduret::resultt::D_ERROR; } } } diff --git a/src/solvers/smt2/smt2_dec.h b/src/solvers/smt2/smt2_dec.h index 30bf18f8796..8770485e189 100644 --- a/src/solvers/smt2/smt2_dec.h +++ b/src/solvers/smt2/smt2_dec.h @@ -6,11 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_SMT2_SMT2_DEC_H #define CPROVER_SOLVERS_SMT2_SMT2_DEC_H -/*! \defgroup gr_smt2 SMT-LIB 2.x Interface */ - #include #include "smt2_conv.h" @@ -32,7 +31,6 @@ class smt2_stringstreamt }; /*! \brief Decision procedure interface for various SMT 2.x solvers - \ingroup gr_smt2 */ class smt2_dect:protected smt2_stringstreamt, public smt2_convt { diff --git a/src/solvers/smt2/smt2_parser.cpp b/src/solvers/smt2/smt2_parser.cpp index 96439833c11..c29d54dda2e 100644 --- a/src/solvers/smt2/smt2_parser.cpp +++ b/src/solvers/smt2/smt2_parser.cpp @@ -6,22 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include -#include - #include "smt2_parser.h" -/*******************************************************************\ - -Function: smt2_parsert::is_simple_symbol_character - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include bool smt2_parsert::is_simple_symbol_character(char ch) { @@ -36,18 +24,6 @@ bool smt2_parsert::is_simple_symbol_character(char ch) ch=='?' || ch=='/'; } -/*******************************************************************\ - -Function: smt2_parsert::get_simple_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_parsert::get_simple_symbol() { // any non-empty sequence of letters, digits and the characters @@ -73,18 +49,6 @@ void smt2_parsert::get_simple_symbol() // eof -- this is ok here } -/*******************************************************************\ - -Function: smt2_parsert::get_decimal_numeral - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_parsert::get_decimal_numeral() { // we accept any sequence of digits and dots @@ -108,18 +72,6 @@ void smt2_parsert::get_decimal_numeral() // eof -- this is ok here } -/*******************************************************************\ - -Function: smt2_parsert::get_bin_numeral - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_parsert::get_bin_numeral() { // we accept any sequence of '0' or '1' @@ -145,18 +97,6 @@ void smt2_parsert::get_bin_numeral() // eof -- this is ok here } -/*******************************************************************\ - -Function: smt2_parsert::get_hex_numeral - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_parsert::get_hex_numeral() { // we accept any sequence of '0'-'9', 'a'-'f', 'A'-'F' @@ -182,18 +122,6 @@ void smt2_parsert::get_hex_numeral() // eof -- this is ok here } -/*******************************************************************\ - -Function: smt2_parsert::get_quoted_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_parsert::get_quoted_symbol() { // any sequence of printable ASCII characters (including space, @@ -214,18 +142,6 @@ void smt2_parsert::get_quoted_symbol() // Hmpf. Eof before end of quoted string. This is an error. } -/*******************************************************************\ - -Function: smt2_parsert::get_string_literal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_parsert::get_string_literal() { buffer.clear(); @@ -257,18 +173,6 @@ void smt2_parsert::get_string_literal() error("EOF within string literal"); } -/*******************************************************************\ - -Function: smt2_parsert::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_parsert::operator()() { char ch; diff --git a/src/solvers/smt2/smt2_parser.h b/src/solvers/smt2/smt2_parser.h index c01069b3cfd..46633eaa174 100644 --- a/src/solvers/smt2/smt2_parser.h +++ b/src/solvers/smt2/smt2_parser.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_SMT2_SMT2_PARSER_H #define CPROVER_SOLVERS_SMT2_SMT2_PARSER_H diff --git a/src/solvers/smt2/smt2_prop.cpp b/src/solvers/smt2/smt2_prop.cpp index d1f7f8bd21f..d6810e5d0c0 100644 --- a/src/solvers/smt2/smt2_prop.cpp +++ b/src/solvers/smt2/smt2_prop.cpp @@ -6,22 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - - #include "smt2_prop.h" -/*******************************************************************\ - -Function: smt2_propt::smt2_propt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include smt2_propt::smt2_propt( const std::string &benchmark, @@ -47,34 +34,10 @@ smt2_propt::smt2_propt( _no_variables=0; } -/*******************************************************************\ - -Function: smt2_propt::~smt2_propt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - smt2_propt::~smt2_propt() { } -/*******************************************************************\ - -Function: smt2_propt::finalize - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_propt::finalize() { out << "\n"; @@ -95,18 +58,6 @@ void smt2_propt::finalize() out << "; end of SMT2 file" << "\n"; } -/*******************************************************************\ - -Function: smt2_propt::land - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt2_propt::land(const bvt &bv) { out << "\n"; @@ -124,18 +75,6 @@ literalt smt2_propt::land(const bvt &bv) return l; } -/*******************************************************************\ - -Function: smt2_propt::lor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt2_propt::lor(const bvt &bv) { out << "\n"; @@ -153,18 +92,6 @@ literalt smt2_propt::lor(const bvt &bv) return l; } -/*******************************************************************\ - -Function: smt2_propt::lxor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt2_propt::lxor(const bvt &bv) { if(bv.empty()) @@ -187,18 +114,6 @@ literalt smt2_propt::lxor(const bvt &bv) return l; } -/*******************************************************************\ - -Function: smt2_propt::land - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt2_propt::land(literalt a, literalt b) { if(a==const_literal(true)) @@ -225,18 +140,6 @@ literalt smt2_propt::land(literalt a, literalt b) return l; } -/*******************************************************************\ - -Function: smt2_propt::lor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt2_propt::lor(literalt a, literalt b) { if(a==const_literal(false)) @@ -263,18 +166,6 @@ literalt smt2_propt::lor(literalt a, literalt b) return l; } -/*******************************************************************\ - -Function: smt2_propt::lxor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt2_propt::lxor(literalt a, literalt b) { if(a==const_literal(false)) @@ -299,86 +190,26 @@ literalt smt2_propt::lxor(literalt a, literalt b) return l; } -/*******************************************************************\ - -Function: smt2_propt::lnand - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt2_propt::lnand(literalt a, literalt b) { return !land(a, b); } -/*******************************************************************\ - -Function: smt2_propt::lnor - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt2_propt::lnor(literalt a, literalt b) { return !lor(a, b); } -/*******************************************************************\ - -Function: smt2_propt::lequal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt2_propt::lequal(literalt a, literalt b) { return !lxor(a, b); } -/*******************************************************************\ - -Function: smt2_propt::limplies - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt2_propt::limplies(literalt a, literalt b) { return lor(!a, b); } -/*******************************************************************\ - -Function: smt2_propt::lselect - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt2_propt::lselect(literalt a, literalt b, literalt c) { if(a==const_literal(true)) @@ -409,18 +240,6 @@ literalt smt2_propt::lselect(literalt a, literalt b, literalt c) return l; } -/*******************************************************************\ - -Function: smt2_propt::new_variable - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt2_propt::new_variable() { literalt l; @@ -432,18 +251,6 @@ literalt smt2_propt::new_variable() return l; } -/*******************************************************************\ - -Function: smt2_propt::define_new_variable - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - literalt smt2_propt::define_new_variable() { literalt l; @@ -457,18 +264,6 @@ literalt smt2_propt::define_new_variable() return l; } -/*******************************************************************\ - -Function: smt2_propt::lcnf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_propt::lcnf(const bvt &bv) { out << "\n"; @@ -492,18 +287,6 @@ void smt2_propt::lcnf(const bvt &bv) out << ")" << "\n"; } -/*******************************************************************\ - -Function: smt2_propt::smt2_literal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string smt2_propt::smt2_literal(literalt l) { if(l==const_literal(false)) @@ -521,18 +304,6 @@ std::string smt2_propt::smt2_literal(literalt l) return v; } -/*******************************************************************\ - -Function: smt2_propt::l_get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt smt2_propt::l_get(literalt literal) const { if(literal.is_true()) @@ -547,18 +318,6 @@ tvt smt2_propt::l_get(literalt literal) const return literal.sign()?!r:r; } -/*******************************************************************\ - -Function: smt2_propt::set_assignment - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void smt2_propt::set_assignment(literalt literal, bool value) { if(literal.is_true() || literal.is_false()) @@ -569,18 +328,6 @@ void smt2_propt::set_assignment(literalt literal, bool value) assignment[v]=tvt(value); } -/*******************************************************************\ - -Function: smt2_propt::prop_solve - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - propt::resultt smt2_propt::prop_solve() { return P_ERROR; diff --git a/src/solvers/smt2/smt2_prop.h b/src/solvers/smt2/smt2_prop.h index e417adbafbe..e2d1074f1a7 100644 --- a/src/solvers/smt2/smt2_prop.h +++ b/src/solvers/smt2/smt2_prop.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_SMT2_SMT2_PROP_H #define CPROVER_SOLVERS_SMT2_SMT2_PROP_H diff --git a/src/solvers/smt2/smt2irep.cpp b/src/solvers/smt2/smt2irep.cpp index 97029db66c4..a549d558670 100644 --- a/src/solvers/smt2/smt2irep.cpp +++ b/src/solvers/smt2/smt2irep.cpp @@ -6,10 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "smt2irep.h" + #include #include -#include "smt2irep.h" #include "smt2_parser.h" class smt2irept:public smt2_parsert diff --git a/src/solvers/smt2/smt2irep.h b/src/solvers/smt2/smt2irep.h index 52791c69783..94d1ecb6b94 100644 --- a/src/solvers/smt2/smt2irep.h +++ b/src/solvers/smt2/smt2irep.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_SOLVERS_SMT2_SMT2IREP_H #define CPROVER_SOLVERS_SMT2_SMT2IREP_H diff --git a/src/symex/path_search.cpp b/src/symex/path_search.cpp index fcbaebbc39a..54f15543430 100644 --- a/src/symex/path_search.cpp +++ b/src/symex/path_search.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Path-based Symbolic Execution + +#include "path_search.h" + #include #include @@ -15,20 +20,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "path_search.h" - -/*******************************************************************\ - -Function: path_searcht::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - path_searcht::resultt path_searcht::operator()( const goto_functionst &goto_functions) { @@ -77,9 +68,9 @@ path_searcht::resultt path_searcht::operator()( statet &state=tmp_queue.front(); // record we have seen it - loc_data[state.get_pc().loc_number].visited=true; + loc_data[state.pc().loc_number].visited=true; - debug() << "Loc: #" << state.get_pc().loc_number + debug() << "Loc: #" << state.pc().loc_number << ", queue: " << queue.size() << ", depth: " << state.get_depth(); for(const auto &s : queue) @@ -111,10 +102,13 @@ path_searcht::resultt path_searcht::operator()( if(number_of_steps%1000==0) { + time_periodt running_time=current_time()-start_time; status() << "Queue " << queue.size() - << " thread " << state.get_current_thread() + << " thread " << state.get_current_thread()+1 << '/' << state.threads.size() - << " PC " << state.pc() << messaget::eom; + << " PC " << state.pc() + << " [" << number_of_steps << " steps, " + << running_time << "s]" << messaget::eom; } // an error, possibly? @@ -156,21 +150,9 @@ path_searcht::resultt path_searcht::operator()( report_statistics(); - return number_of_failed_properties==0?SAFE:UNSAFE; + return number_of_failed_properties==0?resultt::SAFE:resultt::UNSAFE; } -/*******************************************************************\ - -Function: path_searcht::report_statistics - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void path_searcht::report_statistics() { std::size_t number_of_visited_locations=0; @@ -208,18 +190,6 @@ void path_searcht::report_statistics() << sat_time << "s SAT" << messaget::eom; } -/*******************************************************************\ - -Function: path_searcht::pick_state - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void path_searcht::pick_state() { switch(search_heuristic) @@ -240,18 +210,6 @@ void path_searcht::pick_state() } } -/*******************************************************************\ - -Function: path_searcht::do_show_vcc - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void path_searcht::do_show_vcc(statet &state) { // keep statistics @@ -304,50 +262,97 @@ void path_searcht::do_show_vcc(statet &state) out << eom; } -/*******************************************************************\ - -Function: path_searcht::drop_state - - Inputs: - - Outputs: - - Purpose: decide whether to drop a state - -\*******************************************************************/ - +/// decide whether to drop a state bool path_searcht::drop_state(const statet &state) { goto_programt::const_targett pc=state.get_instruction(); + const source_locationt &source_location=pc->source_location; + + if(!source_location.is_nil() && + last_source_location!=source_location) + { + debug() << "SYMEX at file " << source_location.get_file() + << " line " << source_location.get_line() + << " function " << source_location.get_function() + << eom; + + last_source_location=source_location; + } + // depth limit - if(depth_limit_set && state.get_depth()>depth_limit) + if(state.get_depth()>=depth_limit) return true; // context bound - if(context_bound_set && state.get_no_thread_interleavings()>context_bound) + if(state.get_no_thread_interleavings()>=context_bound) return true; // branch bound - if(branch_bound_set && state.get_no_branches()>branch_bound) + if(state.get_no_branches()>=branch_bound) return true; // unwinding limit -- loops - if(unwind_limit_set && state.get_instruction()->is_backwards_goto()) + if(unwind_limit!=std::numeric_limits::max() && + pc->is_backwards_goto()) { + bool stop=false; + for(const auto &loop_info : state.unwinding_map) - if(loop_info.second>unwind_limit) - return true; + if(loop_info.second>=unwind_limit) + { + stop=true; + break; + } + + const irep_idt id=goto_programt::loop_id(pc); + path_symex_statet::unwinding_mapt::const_iterator entry= + state.unwinding_map.find(state.pc()); + debug() << (stop?"Not unwinding":"Unwinding") + << " loop " << id << " iteration " + << (entry==state.unwinding_map.end()?-1:entry->second) + << " (" << unwind_limit << " max)" + << " " << source_location + << " thread " << state.get_current_thread() << eom; + + if(stop) + return true; } // unwinding limit -- recursion - if(unwind_limit_set && state.get_instruction()->is_function_call()) + if(unwind_limit!=std::numeric_limits::max() && + pc->is_function_call()) { + bool stop=false; + for(const auto &rec_info : state.recursion_map) - if(rec_info.second>unwind_limit) - return true; + if(rec_info.second>=unwind_limit) + { + stop=true; + break; + } + + exprt function=to_code_function_call(pc->code).function(); + const irep_idt id=function.get(ID_identifier); // could be nil + path_symex_statet::recursion_mapt::const_iterator entry= + state.recursion_map.find(id); + if(entry!=state.recursion_map.end()) + debug() << (stop?"Not unwinding":"Unwinding") + << " recursion " << id << " iteration " + << entry->second + << " (" << unwind_limit << " max)" + << " " << source_location + << " thread " << state.get_current_thread() << eom; + + if(stop) + return true; } + // search time limit (--max-search-time) + if(time_limit!=std::numeric_limits::max() && + current_time().get_t()>start_time.get_t()+time_limit*1000) + return true; + if(pc->is_assume() && simplify_expr(pc->guard, ns).is_false()) { @@ -367,18 +372,6 @@ bool path_searcht::drop_state(const statet &state) return false; } -/*******************************************************************\ - -Function: path_searcht::check_assertion - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void path_searcht::check_assertion(statet &state) { // keep statistics @@ -426,18 +419,6 @@ void path_searcht::check_assertion(statet &state) sat_time+=current_time()-sat_start_time; } -/*******************************************************************\ - -Function: path_searcht::is_feasible - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool path_searcht::is_feasible(statet &state) { status() << "Feasibility check" << eom; @@ -458,18 +439,6 @@ bool path_searcht::is_feasible(statet &state) return result; } -/*******************************************************************\ - -Function: path_searcht::initialize_property_map - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void path_searcht::initialize_property_map( const goto_functionst &goto_functions) { diff --git a/src/symex/path_search.h b/src/symex/path_search.h index 49fc621b84e..0959002d163 100644 --- a/src/symex/path_search.h +++ b/src/symex/path_search.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Path-based Symbolic Execution + #ifndef CPROVER_SYMEX_PATH_SEARCH_H #define CPROVER_SYMEX_PATH_SEARCH_H @@ -16,6 +19,8 @@ Author: Daniel Kroening, kroening@kroening.com #include +#include + class path_searcht:public safety_checkert { public: @@ -23,10 +28,20 @@ class path_searcht:public safety_checkert safety_checkert(_ns), show_vcc(false), eager_infeasibility(false), - depth_limit_set(false), // no limit - context_bound_set(false), - unwind_limit_set(false), - branch_bound_set(false), + number_of_dropped_states(0), + number_of_paths(0), + number_of_steps(0), + number_of_feasible_paths(0), + number_of_infeasible_paths(0), + number_of_VCCs(0), + number_of_VCCs_after_simplification(0), + number_of_failed_properties(0), + number_of_locs(0), + depth_limit(std::numeric_limits::max()), + context_bound(std::numeric_limits::max()), + branch_bound(std::numeric_limits::max()), + unwind_limit(std::numeric_limits::max()), + time_limit(std::numeric_limits::max()), search_heuristic(search_heuristict::DFS) { } @@ -34,42 +49,43 @@ class path_searcht:public safety_checkert virtual resultt operator()( const goto_functionst &goto_functions); - void set_depth_limit(unsigned limit) + void set_depth_limit(int limit) { - depth_limit_set=true; depth_limit=limit; } - void set_context_bound(unsigned limit) + void set_context_bound(int limit) { - context_bound_set=true; context_bound=limit; } - void set_branch_bound(unsigned limit) + void set_branch_bound(int limit) { - branch_bound_set=true; branch_bound=limit; } - void set_unwind_limit(unsigned limit) + void set_unwind_limit(int limit) { - unwind_limit_set=true; unwind_limit=limit; } + void set_time_limit(int limit) + { + time_limit=limit; + } + bool show_vcc; bool eager_infeasibility; // statistics - unsigned number_of_dropped_states; - unsigned number_of_paths; - unsigned number_of_steps; - unsigned number_of_feasible_paths; - unsigned number_of_infeasible_paths; - unsigned number_of_VCCs; - unsigned number_of_VCCs_after_simplification; - unsigned number_of_failed_properties; + std::size_t number_of_dropped_states; + std::size_t number_of_paths; + std::size_t number_of_steps; + std::size_t number_of_feasible_paths; + std::size_t number_of_infeasible_paths; + std::size_t number_of_VCCs; + std::size_t number_of_VCCs_after_simplification; + std::size_t number_of_failed_properties; std::size_t number_of_locs; absolute_timet start_time; time_periodt sat_time; @@ -131,9 +147,11 @@ class path_searcht:public safety_checkert unsigned context_bound; unsigned branch_bound; unsigned unwind_limit; - bool depth_limit_set, context_bound_set, unwind_limit_set, branch_bound_set; + unsigned time_limit; enum class search_heuristict { DFS, BFS, LOCS } search_heuristic; + + source_locationt last_source_location; }; #endif // CPROVER_SYMEX_PATH_SEARCH_H diff --git a/src/symex/symex_cover.cpp b/src/symex/symex_cover.cpp index e5a7195d924..e7f101c0870 100644 --- a/src/symex/symex_cover.cpp +++ b/src/symex/symex_cover.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symex Test Suite Generation + +#include "symex_parse_options.h" + #include #include @@ -14,20 +19,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "symex_parse_options.h" - -/*******************************************************************\ - -Function: symex_parse_optionst::get_test - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string symex_parse_optionst::get_test(const goto_tracet &goto_trace) { bool first=true; @@ -52,18 +43,6 @@ std::string symex_parse_optionst::get_test(const goto_tracet &goto_trace) return test; } -/*******************************************************************\ - -Function: symex_parse_optionst::report_cover - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_parse_optionst::report_cover( const path_searcht::property_mapt &property_map) { @@ -76,7 +55,7 @@ void symex_parse_optionst::report_cover( switch(get_ui()) { - case ui_message_handlert::PLAIN: + case ui_message_handlert::uit::PLAIN: { status() << "\n** coverage results:" << eom; @@ -101,7 +80,7 @@ void symex_parse_optionst::report_cover( break; } - case ui_message_handlert::XML_UI: + case ui_message_handlert::uit::XML_UI: { for(const auto &prop_pair : property_map) { @@ -148,7 +127,7 @@ void symex_parse_optionst::report_cover( break; } - case ui_message_handlert::JSON_UI: + case ui_message_handlert::uit::JSON_UI: { json_objectt json_result; json_arrayt &result_array=json_result["results"].make_array(); @@ -208,7 +187,7 @@ void symex_parse_optionst::report_cover( << "%)" << eom; - if(get_ui()==ui_message_handlert::PLAIN) + if(get_ui()==ui_message_handlert::uit::PLAIN) { std::set tests; diff --git a/src/symex/symex_main.cpp b/src/symex/symex_main.cpp index 9407efd6c28..36080f4a69a 100644 --- a/src/symex/symex_main.cpp +++ b/src/symex/symex_main.cpp @@ -6,21 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Symex Main Module #include "symex_parse_options.h" -/*******************************************************************\ - -Function: main - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include #ifdef _MSC_VER int wmain(int argc, const wchar_t **argv_wide) diff --git a/src/symex/symex_parse_options.cpp b/src/symex/symex_parse_options.cpp index 3b1b7f873a4..c2e567cc643 100644 --- a/src/symex/symex_parse_options.cpp +++ b/src/symex/symex_parse_options.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Symex Command Line Options Processing + +#include "symex_parse_options.h" + #include #include #include @@ -31,6 +36,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include +#include #include #include #include @@ -49,19 +55,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include "path_search.h" -#include "symex_parse_options.h" - -/*******************************************************************\ - -Function: symex_parse_optionst::symex_parse_optionst - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ symex_parse_optionst::symex_parse_optionst(int argc, const char **argv): parse_options_baset(SYMEX_OPTIONS, argc, argv), @@ -70,18 +63,6 @@ symex_parse_optionst::symex_parse_optionst(int argc, const char **argv): { } -/*******************************************************************\ - -Function: symex_parse_optionst::eval_verbosity - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_parse_optionst::eval_verbosity() { // this is our default verbosity @@ -99,18 +80,6 @@ void symex_parse_optionst::eval_verbosity() ui_message_handler.set_verbosity(v); } -/*******************************************************************\ - -Function: symex_parse_optionst::get_command_line_options - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_parse_optionst::get_command_line_options(optionst &options) { if(config.set(cmdline)) @@ -145,23 +114,12 @@ void symex_parse_optionst::get_command_line_options(optionst &options) options.set_option("error-label", cmdline.get_values("error-label")); } -/*******************************************************************\ - -Function: symex_parse_optionst::doit - - Inputs: - - Outputs: - - Purpose: invoke main modules - -\*******************************************************************/ - +/// invoke main modules int symex_parse_optionst::doit() { if(cmdline.isset("version")) { - std::cout << CBMC_VERSION << std::endl; + std::cout << CBMC_VERSION << '\n'; return 0; } @@ -229,6 +187,10 @@ int symex_parse_optionst::doit() path_search.set_unwind_limit( unsafe_string2unsigned(cmdline.get_value("unwind"))); + if(cmdline.isset("max-search-time")) + path_search.set_time_limit( + safe_string2unsigned(cmdline.get_value("max-search-time"))); + if(cmdline.isset("dfs")) path_search.set_dfs(); @@ -260,12 +222,12 @@ int symex_parse_optionst::doit() // do actual symex, for assertion checking switch(path_search(goto_model.goto_functions)) { - case safety_checkert::SAFE: + case safety_checkert::resultt::SAFE: report_properties(path_search.property_map); report_success(); return 0; - case safety_checkert::UNSAFE: + case safety_checkert::resultt::UNSAFE: report_properties(path_search.property_map); report_failure(); return 10; @@ -296,18 +258,6 @@ int symex_parse_optionst::doit() #endif } -/*******************************************************************\ - -Function: symex_parse_optionst::set_properties - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool symex_parse_optionst::set_properties() { try @@ -337,18 +287,6 @@ bool symex_parse_optionst::set_properties() return false; } -/*******************************************************************\ - -Function: symex_parse_optionst::process_goto_program - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool symex_parse_optionst::process_goto_program(const optionst &options) { try @@ -367,6 +305,12 @@ bool symex_parse_optionst::process_goto_program(const optionst &options) // remove stuff remove_complex(goto_model); remove_vector(goto_model); + // remove function pointers + status() << "Removal of function pointers and virtual functions" << eom; + remove_function_pointers( + get_message_handler(), + goto_model, + cmdline.isset("pointer-check")); // Java virtual functions -> explicit dispatch tables: remove_virtual_functions(goto_model); // Java throw and catch -> explicit exceptional return variables: @@ -417,7 +361,7 @@ bool symex_parse_optionst::process_goto_program(const optionst &options) return true; } - status() << "Instrumenting coverge goals" << eom; + status() << "Instrumenting coverage goals" << eom; instrument_cover_goals(symbol_table, goto_model.goto_functions, c); goto_model.goto_functions.update(); } @@ -463,22 +407,10 @@ bool symex_parse_optionst::process_goto_program(const optionst &options) return false; } -/*******************************************************************\ - -Function: symex_parse_optionst::report_properties - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_parse_optionst::report_properties( const path_searcht::property_mapt &property_map) { - if(get_ui()==ui_message_handlert::PLAIN) + if(get_ui()==ui_message_handlert::uit::PLAIN) status() << "\n** Results:" << eom; for(path_searcht::property_mapt::const_iterator @@ -486,7 +418,7 @@ void symex_parse_optionst::report_properties( it!=property_map.end(); it++) { - if(get_ui()==ui_message_handlert::XML_UI) + if(get_ui()==ui_message_handlert::uit::XML_UI) { xmlt xml_result("result"); xml_result.set_attribute("claim", id2string(it->first)); @@ -542,33 +474,21 @@ void symex_parse_optionst::report_properties( } } -/*******************************************************************\ - -Function: symex_parse_optionst::report_success - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_parse_optionst::report_success() { result() << "VERIFICATION SUCCESSFUL" << eom; switch(get_ui()) { - case ui_message_handlert::PLAIN: + case ui_message_handlert::uit::PLAIN: break; - case ui_message_handlert::XML_UI: + case ui_message_handlert::uit::XML_UI: { xmlt xml("cprover-status"); xml.data="SUCCESS"; std::cout << xml; - std::cout << std::endl; + std::cout << '\n'; } break; @@ -577,18 +497,6 @@ void symex_parse_optionst::report_success() } } -/*******************************************************************\ - -Function: symex_parse_optionst::show_counterexample - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_parse_optionst::show_counterexample( const goto_tracet &error_trace) { @@ -596,12 +504,12 @@ void symex_parse_optionst::show_counterexample( switch(get_ui()) { - case ui_message_handlert::PLAIN: + case ui_message_handlert::uit::PLAIN: std::cout << '\n' << "Counterexample:" << '\n'; show_goto_trace(std::cout, ns, error_trace); break; - case ui_message_handlert::XML_UI: + case ui_message_handlert::uit::XML_UI: { xmlt xml; convert(ns, error_trace, xml); @@ -614,33 +522,21 @@ void symex_parse_optionst::show_counterexample( } } -/*******************************************************************\ - -Function: symex_parse_optionst::report_failure - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symex_parse_optionst::report_failure() { result() << "VERIFICATION FAILED" << eom; switch(get_ui()) { - case ui_message_handlert::PLAIN: + case ui_message_handlert::uit::PLAIN: break; - case ui_message_handlert::XML_UI: + case ui_message_handlert::uit::XML_UI: { xmlt xml("cprover-status"); xml.data="FAILURE"; std::cout << xml; - std::cout << std::endl; + std::cout << '\n'; } break; @@ -649,18 +545,7 @@ void symex_parse_optionst::report_failure() } } -/*******************************************************************\ - -Function: symex_parse_optionst::help - - Inputs: - - Outputs: - - Purpose: display command line help - -\*******************************************************************/ - +/// display command line help void symex_parse_optionst::help() { std::cout << @@ -733,6 +618,7 @@ void symex_parse_optionst::help() " --depth nr limit search depth\n" " --context-bound nr limit number of context switches\n" " --branch-bound nr limit number of branches taken\n" + " --max-search-time s limit search to approximately s seconds\n" "\n" "Other options:\n" " --version show version and exit\n" diff --git a/src/symex/symex_parse_options.h b/src/symex/symex_parse_options.h index 4a149e2147f..a9f3d9e3e83 100644 --- a/src/symex/symex_parse_options.h +++ b/src/symex/symex_parse_options.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Command Line Parsing + #ifndef CPROVER_SYMEX_SYMEX_PARSE_OPTIONS_H #define CPROVER_SYMEX_SYMEX_PARSE_OPTIONS_H @@ -27,7 +30,7 @@ class optionst; #define SYMEX_OPTIONS \ "(function):" \ "D:I:" \ - "(depth):(context-bound):(branch-bound):(unwind):" \ + "(depth):(context-bound):(branch-bound):(unwind):(max-search-time):" \ OPT_GOTO_CHECK \ "(no-assertions)(no-assumptions)" \ "(16)(32)(64)(LP64)(ILP64)(LLP64)(ILP32)(LP32)" \ diff --git a/src/util/Makefile b/src/util/Makefile index f0d8826a0b1..63be2f999b0 100644 --- a/src/util/Makefile +++ b/src/util/Makefile @@ -3,6 +3,7 @@ SRC = arith_tools.cpp \ base_type.cpp \ bv_arithmetic.cpp \ byte_operators.cpp \ + c_types.cpp \ cmdline.cpp \ config.cpp \ cout_message.cpp \ @@ -23,6 +24,7 @@ SRC = arith_tools.cpp \ guard.cpp \ identifier.cpp \ ieee_float.cpp \ + invariant.cpp \ irep.cpp \ irep_hash.cpp \ irep_hash_container.cpp \ diff --git a/src/util/arith_tools.cpp b/src/util/arith_tools.cpp index 37e96ec8ef8..5b94a141dfa 100644 --- a/src/util/arith_tools.cpp +++ b/src/util/arith_tools.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "arith_tools.h" + #include #include "fixedbv.h" @@ -13,20 +15,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "std_types.h" #include "std_expr.h" -#include "arith_tools.h" - -/*******************************************************************\ - -Function: to_integer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool to_integer(const exprt &expr, mp_integer &int_value) { if(!expr.is_constant()) @@ -34,18 +22,6 @@ bool to_integer(const exprt &expr, mp_integer &int_value) return to_integer(to_constant_expr(expr), int_value); } -/*******************************************************************\ - -Function: to_integer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool to_integer(const constant_exprt &expr, mp_integer &int_value) { const irep_idt &value=expr.get_value(); @@ -113,18 +89,9 @@ bool to_integer(const constant_exprt &expr, mp_integer &int_value) return true; } -/*******************************************************************\ - -Function: to_unsigned_integer - - Inputs: a constant expression and a reference to an unsigned int - - Outputs: an error flag - - Purpose: convert a positive integer expression to an unsigned int - -\*******************************************************************/ - +/// convert a positive integer expression to an unsigned int +/// \par parameters: a constant expression and a reference to an unsigned int +/// \return an error flag bool to_unsigned_integer(const constant_exprt &expr, unsigned &uint_value) { mp_integer i; @@ -139,18 +106,6 @@ bool to_unsigned_integer(const constant_exprt &expr, unsigned &uint_value) } } -/*******************************************************************\ - -Function: from_integer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - constant_exprt from_integer( const mp_integer &int_value, const typet &type) @@ -251,18 +206,7 @@ constant_exprt from_integer( } } -/*******************************************************************\ - -Function: address_bits - - Inputs: - - Outputs: - - Purpose: ceil(log2(size)) - -\*******************************************************************/ - +/// ceil(log2(size)) mp_integer address_bits(const mp_integer &size) { mp_integer result, x=2; @@ -272,18 +216,9 @@ mp_integer address_bits(const mp_integer &size) return result; } -/*******************************************************************\ - -Function: power - - Inputs: Two mp_integers, base and exponent - - Outputs: One mp_integer with the value base^{exponent} - - Purpose: A multi-precision implementation of the power operator. - -\*******************************************************************/ - +/// A multi-precision implementation of the power operator. +/// \par parameters: Two mp_integers, base and exponent +/// \return One mp_integer with the value base^{exponent} mp_integer power(const mp_integer &base, const mp_integer &exponent) { @@ -335,36 +270,12 @@ mp_integer power(const mp_integer &base, return result; } -/*******************************************************************\ - -Function: mp_min - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void mp_min(mp_integer &a, const mp_integer &b) { if(ba) diff --git a/src/util/arith_tools.h b/src/util/arith_tools.h index 54f83a2d923..e9691db7322 100644 --- a/src/util/arith_tools.h +++ b/src/util/arith_tools.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_ARITH_TOOLS_H #define CPROVER_UTIL_ARITH_TOOLS_H diff --git a/src/util/array_name.cpp b/src/util/array_name.cpp index d29d60f77fc..a4bfa42c8df 100644 --- a/src/util/array_name.cpp +++ b/src/util/array_name.cpp @@ -6,24 +6,16 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Misc Utilities + #include "array_name.h" + #include "expr.h" #include "namespace.h" #include "symbol.h" #include "ssa_expr.h" -/*******************************************************************\ - -Function: goto_checkt::array_name - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string array_name( const namespacet &ns, const exprt &expr) diff --git a/src/util/array_name.h b/src/util/array_name.h index 8c797668a65..e3aee4e57a3 100644 --- a/src/util/array_name.h +++ b/src/util/array_name.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Misc Utilities + #ifndef CPROVER_UTIL_ARRAY_NAME_H #define CPROVER_UTIL_ARRAY_NAME_H diff --git a/src/util/base_exceptions.h b/src/util/base_exceptions.h new file mode 100644 index 00000000000..6d1218a9e7c --- /dev/null +++ b/src/util/base_exceptions.h @@ -0,0 +1,37 @@ +/*******************************************************************\ + +Module: Util base exceptions + +Author: Diffblue Ltd. + +\*******************************************************************/ + +/// \file +/// Generic exception types primarily designed for use with invariants. + +#ifndef CPROVER_UTIL_BASE_EXCEPTIONS_H +#define CPROVER_UTIL_BASE_EXCEPTIONS_H + +#include "util/invariant.h" + +class bad_cast_exceptiont:public invariant_failedt +{ +public: + // Normally we'd prefer + // using invariant_failedt::invariant_failedt; + // However, this isn't supported on VS2013. + + template + explicit bad_cast_exceptiont(Ts &&...ts): + invariant_failedt(std::forward(ts)...) {} +}; + +class nullptr_exceptiont:public invariant_failedt +{ +public: + template + explicit nullptr_exceptiont(Ts &&...ts): + invariant_failedt(std::forward(ts)...) {} +}; + +#endif diff --git a/src/util/base_type.cpp b/src/util/base_type.cpp index 340d13116a0..f8c29a95e0e 100644 --- a/src/util/base_type.cpp +++ b/src/util/base_type.cpp @@ -6,26 +6,18 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Base Type Computation + +#include "base_type.h" + #include #include #include "std_types.h" -#include "base_type.h" #include "namespace.h" #include "symbol.h" -/*******************************************************************\ - -Function: base_type_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void base_type_rec( typet &type, const namespacet &ns, std::set &symb) { @@ -84,36 +76,12 @@ void base_type_rec( } } -/*******************************************************************\ - -Function: base_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void base_type(typet &type, const namespacet &ns) { std::set symb; base_type_rec(type, ns, symb); } -/*******************************************************************\ - -Function: base_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void base_type(exprt &expr, const namespacet &ns) { base_type(expr.type(), ns); @@ -122,18 +90,6 @@ void base_type(exprt &expr, const namespacet &ns) base_type(*it, ns); } -/*******************************************************************\ - -Function: base_type_eqt::base_type_eq_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool base_type_eqt::base_type_eq_rec( const typet &type1, const typet &type2) @@ -142,8 +98,8 @@ bool base_type_eqt::base_type_eq_rec( return true; #if 0 - std::cout << "T1: " << type1.pretty() << std::endl; - std::cout << "T2: " << type2.pretty() << std::endl; + std::cout << "T1: " << type1.pretty() << '\n'; + std::cout << "T2: " << type2.pretty() << '\n'; #endif // loop avoidance @@ -282,18 +238,6 @@ bool base_type_eqt::base_type_eq_rec( return tmp1==tmp2; } -/*******************************************************************\ - -Function: base_type_eqt::base_type_eq_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool base_type_eqt::base_type_eq_rec( const exprt &expr1, const exprt &expr2) @@ -323,18 +267,6 @@ bool base_type_eqt::base_type_eq_rec( return true; } -/*******************************************************************\ - -Function: base_type_eq - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool base_type_eq( const typet &type1, const typet &type2, @@ -344,18 +276,6 @@ bool base_type_eq( return base_type_eq.base_type_eq(type1, type2); } -/*******************************************************************\ - -Function: base_type_eq - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool base_type_eq( const exprt &expr1, const exprt &expr2, diff --git a/src/util/base_type.h b/src/util/base_type.h index 41e2fe6df4f..833fd855cca 100644 --- a/src/util/base_type.h +++ b/src/util/base_type.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Base Type Computation + #ifndef CPROVER_UTIL_BASE_TYPE_H #define CPROVER_UTIL_BASE_TYPE_H @@ -26,14 +29,6 @@ bool base_type_eq( const exprt &expr2, const namespacet &ns); -/*******************************************************************\ - - Class: base_type_eqt - - Purpose: - -\*******************************************************************/ - class base_type_eqt { public: diff --git a/src/util/bv_arithmetic.cpp b/src/util/bv_arithmetic.cpp index 4e077ad0a1e..4287e04adf1 100644 --- a/src/util/bv_arithmetic.cpp +++ b/src/util/bv_arithmetic.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "bv_arithmetic.h" + #include #include @@ -13,19 +15,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "arith_tools.h" #include "std_types.h" #include "std_expr.h" -#include "bv_arithmetic.h" - -/*******************************************************************\ - -Function: bv_spect::to_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ typet bv_spect::to_type() const { @@ -34,54 +23,18 @@ typet bv_spect::to_type() const return unsignedbv_typet(width); } -/*******************************************************************\ - -Function: bv_spect::max_value - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - mp_integer bv_spect::max_value() const { return is_signed?power(2, width-1)-1: power(2, width)-1; } -/*******************************************************************\ - -Function: bv_spect::min_value - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - mp_integer bv_spect::min_value() const { return is_signed?-power(2, width-1): 0; } -/*******************************************************************\ - -Function: bv_spect::from_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bv_spect::from_type(const typet &type) { if(type.id()==ID_unsignedbv) @@ -94,35 +47,11 @@ void bv_spect::from_type(const typet &type) width=unsafe_string2unsigned(type.get_string(ID_width)); } -/*******************************************************************\ - -Function: bv_arithmetict::print - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bv_arithmetict::print(std::ostream &out) const { out << to_ansi_c_string(); } -/*******************************************************************\ - -Function: bv_arithmetict::format - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string bv_arithmetict::format(const format_spect &format_spec) const { std::string result; @@ -132,36 +61,12 @@ std::string bv_arithmetict::format(const format_spect &format_spec) const return result; } -/*******************************************************************\ - -Function: bv_arithmetict::from_integer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bv_arithmetict::from_integer(const mp_integer &i) { value=i; adjust(); } -/*******************************************************************\ - -Function: bv_arithmetict::adjust - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bv_arithmetict::adjust() { mp_integer p=power(2, spec.width); @@ -171,18 +76,6 @@ void bv_arithmetict::adjust() value-=p; } -/*******************************************************************\ - -Function: bv_arithmetict::pack - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - mp_integer bv_arithmetict::pack() const { if(value>=0) @@ -190,18 +83,6 @@ mp_integer bv_arithmetict::pack() const return value+power(2, spec.width); } -/*******************************************************************\ - -Function: bv_arithmetict::to_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt bv_arithmetict::to_expr() const { constant_exprt result(spec.to_type()); @@ -209,18 +90,6 @@ exprt bv_arithmetict::to_expr() const return result; } -/*******************************************************************\ - -Function: operator /= - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bv_arithmetict &bv_arithmetict::operator/=(const bv_arithmetict &other) { assert(other.spec==spec); @@ -233,18 +102,6 @@ bv_arithmetict &bv_arithmetict::operator/=(const bv_arithmetict &other) return *this; } -/*******************************************************************\ - -Function: operator *= - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bv_arithmetict &bv_arithmetict::operator*=(const bv_arithmetict &other) { assert(other.spec==spec); @@ -255,18 +112,6 @@ bv_arithmetict &bv_arithmetict::operator*=(const bv_arithmetict &other) return *this; } -/*******************************************************************\ - -Function: operator += - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bv_arithmetict &bv_arithmetict::operator+=(const bv_arithmetict &other) { assert(other.spec==spec); @@ -277,18 +122,6 @@ bv_arithmetict &bv_arithmetict::operator+=(const bv_arithmetict &other) return *this; } -/*******************************************************************\ - -Function: operator -= - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bv_arithmetict &bv_arithmetict::operator -= (const bv_arithmetict &other) { assert(other.spec==spec); @@ -299,18 +132,6 @@ bv_arithmetict &bv_arithmetict::operator -= (const bv_arithmetict &other) return *this; } -/*******************************************************************\ - -Function: operator %= - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bv_arithmetict &bv_arithmetict::operator%=(const bv_arithmetict &other) { assert(other.spec==spec); @@ -321,155 +142,47 @@ bv_arithmetict &bv_arithmetict::operator%=(const bv_arithmetict &other) return *this; } -/*******************************************************************\ - -Function: operator < - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool bv_arithmetict::operator<(const bv_arithmetict &other) { return value - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool bv_arithmetict::operator>(const bv_arithmetict &other) { return value>other.value; } -/*******************************************************************\ - -Function: bv_arithmetict::operator>= - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool bv_arithmetict::operator>=(const bv_arithmetict &other) { return value>=other.value; } -/*******************************************************************\ - -Function: bv_arithmetict::operator== - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool bv_arithmetict::operator==(const bv_arithmetict &other) { return value==other.value; } -/*******************************************************************\ - -Function: bv_arithmetict::operator== - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool bv_arithmetict::operator==(int i) { return value==i; } -/*******************************************************************\ - -Function: bv_arithmetict::operator!= - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool bv_arithmetict::operator!=(const bv_arithmetict &other) { return value!=other.value; } -/*******************************************************************\ - -Function: bv_arithmetict::change_spec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bv_arithmetict::change_spec(const bv_spect &dest_spec) { spec=dest_spec; adjust(); } -/*******************************************************************\ - -Function: bv_arithmetict::from_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void bv_arithmetict::from_expr(const exprt &expr) { assert(expr.is_constant()); diff --git a/src/util/bv_arithmetic.h b/src/util/bv_arithmetic.h index a5d91485490..3774344d18f 100644 --- a/src/util/bv_arithmetic.h +++ b/src/util/bv_arithmetic.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_BV_ARITHMETIC_H #define CPROVER_UTIL_BV_ARITHMETIC_H diff --git a/src/util/byte_operators.cpp b/src/util/byte_operators.cpp index 46e7d3f218e..9ebc340d9cb 100644 --- a/src/util/byte_operators.cpp +++ b/src/util/byte_operators.cpp @@ -6,22 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "byte_operators.h" -#include "config.h" - -/*******************************************************************\ -Function: byte_extract_id - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include "config.h" irep_idt byte_extract_id() { @@ -38,18 +27,6 @@ irep_idt byte_extract_id() } } -/*******************************************************************\ - -Function: byte_update_id - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - irep_idt byte_update_id() { switch(config.ansi_c.endianness) diff --git a/src/util/byte_operators.h b/src/util/byte_operators.h index 9b0745833cc..6833a509346 100644 --- a/src/util/byte_operators.h +++ b/src/util/byte_operators.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_BYTE_OPERATORS_H #define CPROVER_UTIL_BYTE_OPERATORS_H diff --git a/src/util/c_types.cpp b/src/util/c_types.cpp new file mode 100644 index 00000000000..cc2880cb577 --- /dev/null +++ b/src/util/c_types.cpp @@ -0,0 +1,371 @@ +/*******************************************************************\ + +Module: + +Author: Daniel Kroening, kroening@kroening.com + +\*******************************************************************/ + + +#include "std_types.h" +#include "config.h" + +#include "c_types.h" + +bitvector_typet index_type() +{ + // same as signed size type + return signed_size_type(); +} + +/// return type of enum constants +bitvector_typet enum_constant_type() +{ + // usually same as 'int', + // but might be unsigned, or shorter than 'int' + return signed_int_type(); +} + +signedbv_typet signed_int_type() +{ + signedbv_typet result(config.ansi_c.int_width); + result.set(ID_C_c_type, ID_signed_int); + return result; +} + +signedbv_typet signed_short_int_type() +{ + signedbv_typet result(config.ansi_c.short_int_width); + result.set(ID_C_c_type, ID_signed_short_int); + return result; +} + +unsignedbv_typet unsigned_int_type() +{ + unsignedbv_typet result(config.ansi_c.int_width); + result.set(ID_C_c_type, ID_unsigned_int); + return result; +} + +unsignedbv_typet unsigned_short_int_type() +{ + unsignedbv_typet result(config.ansi_c.short_int_width); + result.set(ID_C_c_type, ID_unsigned_short_int); + return result; +} + +unsignedbv_typet size_type() +{ + // The size type varies. This is unsigned int on some systems, + // and unsigned long int on others, + // and unsigned long long on say Windows 64. + + if(config.ansi_c.pointer_width==config.ansi_c.int_width) + return unsigned_int_type(); + else if(config.ansi_c.pointer_width==config.ansi_c.long_int_width) + return unsigned_long_int_type(); + else if(config.ansi_c.pointer_width==config.ansi_c.long_long_int_width) + return unsigned_long_long_int_type(); + else + assert(false); // aaah! +} + +signedbv_typet signed_size_type() +{ + // we presume this is the same as pointer difference + return pointer_diff_type(); +} + +signedbv_typet signed_long_int_type() +{ + signedbv_typet result(config.ansi_c.long_int_width); + result.set(ID_C_c_type, ID_signed_long_int); + return result; +} + +signedbv_typet signed_long_long_int_type() +{ + signedbv_typet result(config.ansi_c.long_long_int_width); + result.set(ID_C_c_type, ID_signed_long_long_int); + return result; +} + +unsignedbv_typet unsigned_long_int_type() +{ + unsignedbv_typet result(config.ansi_c.long_int_width); + result.set(ID_C_c_type, ID_unsigned_long_int); + return result; +} + +unsignedbv_typet unsigned_long_long_int_type() +{ + unsignedbv_typet result(config.ansi_c.long_long_int_width); + result.set(ID_C_c_type, ID_unsigned_long_long_int); + return result; +} + +typet c_bool_type() +{ + typet result=c_bool_typet(config.ansi_c.bool_width); + return result; +} + +bitvector_typet char_type() +{ + // this can be signed or unsigned, depending on the architecture + + // There are 3 char types, i.e., this one is + // different from either signed char or unsigned char! + + if(config.ansi_c.char_is_unsigned) + { + unsignedbv_typet result(config.ansi_c.char_width); + result.set(ID_C_c_type, ID_char); + return result; + } + else + { + signedbv_typet result(config.ansi_c.char_width); + result.set(ID_C_c_type, ID_char); + return result; + } +} + +unsignedbv_typet unsigned_char_type() +{ + unsignedbv_typet result(config.ansi_c.char_width); + result.set(ID_C_c_type, ID_unsigned_char); + return result; +} + +signedbv_typet signed_char_type() +{ + signedbv_typet result(config.ansi_c.char_width); + result.set(ID_C_c_type, ID_signed_char); + return result; +} + +bitvector_typet wchar_t_type() +{ + if(config.ansi_c.wchar_t_is_unsigned) + { + unsignedbv_typet result(config.ansi_c.wchar_t_width); + result.set(ID_C_c_type, ID_wchar_t); + return result; + } + else + { + signedbv_typet result(config.ansi_c.wchar_t_width); + result.set(ID_C_c_type, ID_wchar_t); + return result; + } +} + +unsignedbv_typet char16_t_type() +{ + // Types char16_t and char32_t denote distinct types with the same size, + // signedness, and alignment as uint_least16_t and uint_least32_t, + // respectively, in , called the underlying types. + unsignedbv_typet result(16); + result.set(ID_C_c_type, ID_char16_t); + return result; +} + +unsignedbv_typet char32_t_type() +{ + // Types char16_t and char32_t denote distinct types with the same size, + // signedness, and alignment as uint_least16_t and uint_least32_t, + // respectively, in , called the underlying types. + unsignedbv_typet result(32); + result.set(ID_C_c_type, ID_char32_t); + return result; +} + +bitvector_typet float_type() +{ + if(config.ansi_c.use_fixed_for_float) + { + fixedbv_typet result; + result.set_width(config.ansi_c.single_width); + result.set_integer_bits(config.ansi_c.single_width/2); + result.set(ID_C_c_type, ID_float); + return result; + } + else + { + floatbv_typet result= + ieee_float_spect::single_precision().to_type(); + result.set(ID_C_c_type, ID_float); + return result; + } +} + +bitvector_typet double_type() +{ + if(config.ansi_c.use_fixed_for_float) + { + fixedbv_typet result; + result.set_width(config.ansi_c.double_width); + result.set_integer_bits(config.ansi_c.double_width/2); + result.set(ID_C_c_type, ID_double); + return result; + } + else + { + floatbv_typet result= + ieee_float_spect::double_precision().to_type(); + result.set(ID_C_c_type, ID_double); + return result; + } +} + +bitvector_typet long_double_type() +{ + if(config.ansi_c.use_fixed_for_float) + { + fixedbv_typet result; + result.set_width(config.ansi_c.long_double_width); + result.set_integer_bits(config.ansi_c.long_double_width/2); + result.set(ID_C_c_type, ID_long_double); + return result; + } + else + { + floatbv_typet result; + if(config.ansi_c.long_double_width==128) + result=ieee_float_spect::quadruple_precision().to_type(); + else if(config.ansi_c.long_double_width==64) + result=ieee_float_spect::double_precision().to_type(); + else if(config.ansi_c.long_double_width==80) + { + // x86 extended precision has 80 bits in total, and + // deviating from IEEE, does not use a hidden bit. + // We use the closest we have got, but the below isn't accurate. + result=ieee_float_spect(63, 15).to_type(); + } + else if(config.ansi_c.long_double_width==96) + { + result=ieee_float_spect(80, 15).to_type(); + // not quite right. The extra bits beyond 80 are usually padded. + } + else + assert(false); + + result.set(ID_C_c_type, ID_long_double); + + return result; + } +} + +bitvector_typet gcc_float128_type() +{ + // not same as long double! + + if(config.ansi_c.use_fixed_for_float) + { + fixedbv_typet result; + result.set_width(128); + result.set_integer_bits(128/2); + result.set(ID_C_c_type, ID_gcc_float128); + return result; + } + else + { + floatbv_typet result= + ieee_float_spect::quadruple_precision().to_type(); + result.set(ID_C_c_type, ID_gcc_float128); + return result; + } +} + +signedbv_typet pointer_diff_type() +{ + // The pointer-diff type varies. This is signed int on some systems, + // and signed long int on others, and signed long long on say Windows. + + if(config.ansi_c.pointer_width==config.ansi_c.int_width) + return signed_int_type(); + else if(config.ansi_c.pointer_width==config.ansi_c.long_int_width) + return signed_long_int_type(); + else if(config.ansi_c.pointer_width==config.ansi_c.long_long_int_width) + return signed_long_long_int_type(); + else + assert(false); // aaah! +} + +pointer_typet pointer_type(const typet &subtype) +{ + return pointer_typet(subtype); +} + +reference_typet reference_type(const typet &subtype) +{ + return reference_typet(subtype); +} + +typet void_type() +{ + return empty_typet(); +} + +unsignedbv_typet gcc_unsigned_int128_type() +{ + unsignedbv_typet result(128); + result.set(ID_C_c_type, ID_unsigned_int128); + return result; +} + +signedbv_typet gcc_signed_int128_type() +{ + signedbv_typet result(128); + result.set(ID_C_c_type, ID_signed_int128); + return result; +} + +std::string c_type_as_string(const irep_idt &c_type) +{ + if(c_type==ID_signed_int) + return "signed int"; + else if(c_type==ID_signed_short_int) + return "signed short int"; + else if(c_type==ID_unsigned_int) + return "unsigned int"; + else if(c_type==ID_unsigned_short_int) + return "unsigned short int"; + else if(c_type==ID_signed_long_int) + return "signed long int"; + else if(c_type==ID_signed_long_long_int) + return "signed long long int"; + else if(c_type==ID_unsigned_long_int) + return "unsigned long int"; + else if(c_type==ID_unsigned_long_long_int) + return "unsigned long long int"; + else if(c_type==ID_bool) + return "_Bool"; + else if(c_type==ID_char) + return "char"; + else if(c_type==ID_unsigned_char) + return "unsigned char"; + else if(c_type==ID_signed_char) + return "signed char"; + else if(c_type==ID_wchar_t) + return "wchar_t"; + else if(c_type==ID_char16_t) + return "char16_t"; + else if(c_type==ID_char32_t) + return "char32_t"; + else if(c_type==ID_float) + return "float"; + else if(c_type==ID_double) + return "double"; + else if(c_type==ID_long_double) + return "long double"; + else if(c_type==ID_gcc_float128) + return "__float128"; + else if(c_type==ID_unsigned_int128) + return "unsigned __int128"; + else if(c_type==ID_signed_int128) + return "signed __int128"; + else + return ""; +} diff --git a/src/util/c_types.h b/src/util/c_types.h new file mode 100644 index 00000000000..39e76a6c7b3 --- /dev/null +++ b/src/util/c_types.h @@ -0,0 +1,51 @@ +/*******************************************************************\ + +Module: + +Author: Daniel Kroening, kroening@kroening.com + +\*******************************************************************/ + + +#ifndef CPROVER_UTIL_C_TYPES_H +#define CPROVER_UTIL_C_TYPES_H + +#include "std_types.h" + +bitvector_typet index_type(); +bitvector_typet enum_constant_type(); +signedbv_typet signed_int_type(); +unsignedbv_typet unsigned_int_type(); +signedbv_typet signed_long_int_type(); +signedbv_typet signed_short_int_type(); +unsignedbv_typet unsigned_short_int_type(); +signedbv_typet signed_long_long_int_type(); +unsignedbv_typet unsigned_long_int_type(); +unsignedbv_typet unsigned_long_long_int_type(); +typet c_bool_type(); +bitvector_typet char_type(); +unsignedbv_typet unsigned_char_type(); +signedbv_typet signed_char_type(); +bitvector_typet wchar_t_type(); +unsignedbv_typet char16_t_type(); +unsignedbv_typet char32_t_type(); +bitvector_typet float_type(); +bitvector_typet double_type(); +bitvector_typet long_double_type(); +bitvector_typet gcc_float128_type(); +unsignedbv_typet gcc_unsigned_int128_type(); +signedbv_typet gcc_signed_int128_type(); +unsignedbv_typet size_type(); +signedbv_typet signed_size_type(); +signedbv_typet pointer_diff_type(); +pointer_typet pointer_type(const typet &); +typet void_type(); + +// This is for Java and C++ +reference_typet reference_type(const typet &); + +// Turns an ID_C_c_type into a string, e.g., +// ID_signed_int gets "signed int". +std::string c_type_as_string(const irep_idt &); + +#endif // CPROVER_UTIL_C_TYPES_H diff --git a/src/util/cmdline.cpp b/src/util/cmdline.cpp index 56d6a7a1a6c..5010a48e8d3 100644 --- a/src/util/cmdline.cpp +++ b/src/util/cmdline.cpp @@ -6,75 +6,27 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "cmdline.h" + #include #include #include -#include "cmdline.h" - -/*******************************************************************\ - -Function: cmdlinet::cmdlinet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - cmdlinet::cmdlinet() { } -/*******************************************************************\ - -Function: cmdlinet::~cmdlinet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - cmdlinet::~cmdlinet() { clear(); } -/*******************************************************************\ - -Function: cmdlinet::clear - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cmdlinet::clear() { options.clear(); args.clear(); } -/*******************************************************************\ - -Function: cmdlinet::isset - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool cmdlinet::isset(char option) const { int i=getoptnr(option); @@ -83,18 +35,6 @@ bool cmdlinet::isset(char option) const return options[i].isset; } -/*******************************************************************\ - -Function: cmdlinet::isset - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool cmdlinet::isset(const char *option) const { int i=getoptnr(option); @@ -103,18 +43,6 @@ bool cmdlinet::isset(const char *option) const return options[i].isset; } -/*******************************************************************\ - -Function: cmdlinet::get_value - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string cmdlinet::get_value(char option) const { int i=getoptnr(option); @@ -125,18 +53,6 @@ std::string cmdlinet::get_value(char option) const return options[i].values.front(); } -/*******************************************************************\ - -Function: cmdlinet::set - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cmdlinet::set(const std::string &option) { int i=getoptnr(option); @@ -145,18 +61,6 @@ void cmdlinet::set(const std::string &option) options[i].isset=true; } -/*******************************************************************\ - -Function: cmdlinet::set - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void cmdlinet::set(const std::string &option, const std::string &value) { int i=getoptnr(option); @@ -166,18 +70,6 @@ void cmdlinet::set(const std::string &option, const std::string &value) options[i].values.push_back(value); } -/*******************************************************************\ - -Function: cmdlinet::get_values - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::list &cmdlinet::get_values(char option) const { int i=getoptnr(option); @@ -185,18 +77,6 @@ const std::list &cmdlinet::get_values(char option) const return options[i].values; } -/*******************************************************************\ - -Function: cmdlinet::get_value - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string cmdlinet::get_value(const char *option) const { int i=getoptnr(option); @@ -207,18 +87,6 @@ std::string cmdlinet::get_value(const char *option) const return options[i].values.front(); } -/*******************************************************************\ - -Function: cmdlinet::get_values - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::list &cmdlinet::get_values( const std::string &option) const { @@ -227,18 +95,6 @@ const std::list &cmdlinet::get_values( return options[i].values; } -/*******************************************************************\ - -Function: cmdlinet::getoptnr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - int cmdlinet::getoptnr(char option) const { for(unsigned i=0; i 2 [label="C files or goto-binaries"]; + 2 -> 3 [label="Command line options, file names"]; +} +\enddot diff --git a/src/util/config.cpp b/src/util/config.cpp index 8751a35b711..a256ff6b17e 100644 --- a/src/util/config.cpp +++ b/src/util/config.cpp @@ -6,10 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "config.h" + #include #include "namespace.h" -#include "config.h" #include "symbol_table.h" #include "arith_tools.h" #include "cmdline.h" @@ -19,52 +20,16 @@ Author: Daniel Kroening, kroening@kroening.com configt config; -/*******************************************************************\ - -Function: configt::ansi_ct::set_16 - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void configt::ansi_ct::set_16() { set_LP32(); } -/*******************************************************************\ - -Function: configt::ansi_ct::set_32 - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void configt::ansi_ct::set_32() { set_ILP32(); } -/*******************************************************************\ - -Function: configt::ansi_ct::set_64 - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void configt::ansi_ct::set_64() { #ifdef _WIN32 @@ -74,18 +39,7 @@ void configt::ansi_ct::set_64() #endif } -/*******************************************************************\ - -Function: configt::ansi_ct::set_LP64 - - Inputs: - - Outputs: - - Purpose: int=32, long=64, pointer=64 - -\*******************************************************************/ - +/// int=32, long=64, pointer=64 void configt::ansi_ct::set_LP64() { bool_width=1*8; @@ -105,18 +59,7 @@ void configt::ansi_ct::set_LP64() memory_operand_size=int_width/8; } -/*******************************************************************\ - -Function: configt::ansi_ct::set_ILP64 - - Inputs: - - Outputs: - - Purpose: int=64, long=64, pointer=64 - -\*******************************************************************/ - +/// int=64, long=64, pointer=64 // TODO: find the alignment restrictions (per type) of the different // architectures (currently: sizeof=alignedof) // TODO: implement the __attribute__((__aligned__(val))) @@ -140,18 +83,7 @@ void configt::ansi_ct::set_ILP64() memory_operand_size=int_width/8; } -/*******************************************************************\ - -Function: configt::ansi_ct::set_LLP64 - - Inputs: - - Outputs: - - Purpose: int=32, long=32, pointer=64 - -\*******************************************************************/ - +/// int=32, long=32, pointer=64 void configt::ansi_ct::set_LLP64() { bool_width=1*8; @@ -171,18 +103,7 @@ void configt::ansi_ct::set_LLP64() memory_operand_size=int_width/8; } -/*******************************************************************\ - -Function: configt::ansi_ct::set_ILP32 - - Inputs: - - Outputs: - - Purpose: int=32, long=32, pointer=32 - -\*******************************************************************/ - +/// int=32, long=32, pointer=32 void configt::ansi_ct::set_ILP32() { bool_width=1*8; @@ -202,18 +123,7 @@ void configt::ansi_ct::set_ILP32() memory_operand_size=int_width/8; } -/*******************************************************************\ - -Function: configt::ansi_ct::set_LP32 - - Inputs: - - Outputs: - - Purpose: int=16, long=32, pointer=32 - -\*******************************************************************/ - +/// int=16, long=32, pointer=32 void configt::ansi_ct::set_LP32() { bool_width=1*8; @@ -233,18 +143,6 @@ void configt::ansi_ct::set_LP32() memory_operand_size=int_width/8; } -/*******************************************************************\ - -Function: configt::ansi_ct::set_arch_spec_i386 - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void configt::ansi_ct::set_arch_spec_i386() { set_ILP32(); @@ -277,18 +175,6 @@ void configt::ansi_ct::set_arch_spec_i386() } } -/*******************************************************************\ - -Function: configt::ansi_ct::set_arch_spec_x86_64 - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void configt::ansi_ct::set_arch_spec_x86_64() { set_LP64(); @@ -326,18 +212,6 @@ void configt::ansi_ct::set_arch_spec_x86_64() } } -/*******************************************************************\ - -Function: configt::ansi_ct::set_arch_spec_power - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void configt::ansi_ct::set_arch_spec_power(const irep_idt &subarch) { if(subarch=="powerpc") @@ -399,18 +273,6 @@ void configt::ansi_ct::set_arch_spec_power(const irep_idt &subarch) } } -/*******************************************************************\ - -Function: configt::ansi_ct::set_arch_spec_arm - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void configt::ansi_ct::set_arch_spec_arm(const irep_idt &subarch) { if(subarch=="arm64") @@ -454,18 +316,6 @@ void configt::ansi_ct::set_arch_spec_arm(const irep_idt &subarch) } } -/*******************************************************************\ - -Function: configt::ansi_ct::set_arch_spec_alpha - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void configt::ansi_ct::set_arch_spec_alpha() { set_LP64(); @@ -495,18 +345,6 @@ void configt::ansi_ct::set_arch_spec_alpha() } } -/*******************************************************************\ - -Function: configt::ansi_ct::set_arch_spec_mips - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void configt::ansi_ct::set_arch_spec_mips(const irep_idt &subarch) { if(subarch=="mipsel" || @@ -557,18 +395,6 @@ void configt::ansi_ct::set_arch_spec_mips(const irep_idt &subarch) } } -/*******************************************************************\ - -Function: configt::ansi_ct::set_arch_spec_s390 - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void configt::ansi_ct::set_arch_spec_s390() { set_ILP32(); @@ -598,18 +424,6 @@ void configt::ansi_ct::set_arch_spec_s390() } } -/*******************************************************************\ - -Function: configt::ansi_ct::set_arch_spec_s390x - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void configt::ansi_ct::set_arch_spec_s390x() { set_LP64(); @@ -638,18 +452,6 @@ void configt::ansi_ct::set_arch_spec_s390x() } } -/*******************************************************************\ - -Function: configt::ansi_ct::set_arch_spec_sparc - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void configt::ansi_ct::set_arch_spec_sparc(const irep_idt &subarch) { if(subarch=="sparc64") @@ -690,18 +492,6 @@ void configt::ansi_ct::set_arch_spec_sparc(const irep_idt &subarch) } } -/*******************************************************************\ - -Function: configt::ansi_ct::set_arch_spec_ia64 - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void configt::ansi_ct::set_arch_spec_ia64() { set_LP64(); @@ -733,18 +523,6 @@ void configt::ansi_ct::set_arch_spec_ia64() } } -/*******************************************************************\ - -Function: configt::ansi_ct::set_arch_spec_x32 - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void configt::ansi_ct::set_arch_spec_x32() { // This is a variant of x86_64 that has @@ -780,18 +558,8 @@ void configt::ansi_ct::set_arch_spec_x32() } } -/*******************************************************************\ - -Function: configt::ansi_ct::set_arch_spec_v850 - - Inputs: None - - Outputs: None - - Purpose: Sets up the widths of variables for the Renesas V850 - -\*******************************************************************/ - +/// Sets up the widths of variables for the Renesas V850 +/// \return None void configt::ansi_ct::set_arch_spec_v850() { // The Renesas V850 is a 32-bit microprocessor used in @@ -815,18 +583,6 @@ void configt::ansi_ct::set_arch_spec_v850() // No preprocessor definitions due to lack of information } -/*******************************************************************\ - -Function: configt::ansi_ct::set_arch_spec_hppa - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void configt::ansi_ct::set_arch_spec_hppa() { set_ILP32(); @@ -856,18 +612,6 @@ void configt::ansi_ct::set_arch_spec_hppa() } } -/*******************************************************************\ - -Function: configt::ansi_ct::set_arch_spec_sh4 - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void configt::ansi_ct::set_arch_spec_sh4() { set_ILP32(); @@ -898,18 +642,6 @@ void configt::ansi_ct::set_arch_spec_sh4() } } -/*******************************************************************\ - -Function: configt::ansi_ct::default_c_standard - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - configt::ansi_ct::c_standardt configt::ansi_ct::default_c_standard() { #if defined(__APPLE__) @@ -923,35 +655,11 @@ configt::ansi_ct::c_standardt configt::ansi_ct::default_c_standard() #endif } -/*******************************************************************\ - -Function: configt::ansi_ct::default_cpp_standard - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - configt::cppt::cpp_standardt configt::cppt::default_cpp_standard() { return cpp_standardt::CPP98; } -/*******************************************************************\ - -Function: configt::set_arch - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void configt::set_arch(const irep_idt &arch) { ansi_c.arch=arch; @@ -1016,18 +724,6 @@ void configt::set_arch(const irep_idt &arch) } } -/*******************************************************************\ - -Function: configt::set - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool configt::set(const cmdlinet &cmdline) { // defaults -- we match the architecture we have ourselves @@ -1043,7 +739,7 @@ bool configt::set(const cmdlinet &cmdline) ansi_c.arch="none"; ansi_c.lib=configt::ansi_ct::libt::LIB_NONE; // NOLINTNEXTLINE(readability/casting) - ansi_c.NULL_is_zero=reinterpret_cast((void*)0)==0; + ansi_c.NULL_is_zero=reinterpret_cast(nullptr)==0; // Default is ROUND_TO_EVEN, justified by C99: // 1 At program startup the floating-point environment is initialized as @@ -1077,7 +773,7 @@ bool configt::set(const cmdlinet &cmdline) { // environment variable set? const char *CLASSPATH=getenv("CLASSPATH"); - if(CLASSPATH!=NULL) + if(CLASSPATH!=nullptr) set_classpath(CLASSPATH); else set_classpath("."); // default @@ -1159,6 +855,9 @@ bool configt::set(const cmdlinet &cmdline) #ifdef _WIN32 ansi_c.defines.push_back("__CYGWIN__"); #endif + + // MinGW has extra defines + ansi_c.defines.push_back("__int64=\"long long\""); } else { @@ -1314,18 +1013,6 @@ bool configt::set(const cmdlinet &cmdline) return false; } -/*******************************************************************\ - -Function: configt::ansi_ct::os_to_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string configt::ansi_ct::os_to_string(ost os) { switch(os) @@ -1337,18 +1024,6 @@ std::string configt::ansi_ct::os_to_string(ost os) } } -/*******************************************************************\ - -Function: configt::ansi_ct::string_to_os - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - configt::ansi_ct::ost configt::ansi_ct::string_to_os(const std::string &os) { if(os=="linux") @@ -1361,18 +1036,6 @@ configt::ansi_ct::ost configt::ansi_ct::string_to_os(const std::string &os) return ost::NO_OS; } -/*******************************************************************\ - -Function: string_from_ns - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static irep_idt string_from_ns( const namespacet &ns, const std::string &what) @@ -1399,18 +1062,6 @@ static irep_idt string_from_ns( return tmp.op0().op0().get(ID_value); } -/*******************************************************************\ - -Function: unsigned_from_ns - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static unsigned unsigned_from_ns( const namespacet &ns, const std::string &what) @@ -1437,18 +1088,6 @@ static unsigned unsigned_from_ns( return integer2unsigned(int_value); } -/*******************************************************************\ - -Function: configt::set_from_symbol_table - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void configt::set_from_symbol_table( const symbol_tablet &symbol_table) { @@ -1506,18 +1145,6 @@ void configt::set_from_symbol_table( // lib, string_abstraction not stored in namespace } -/*******************************************************************\ - -Function: configt::ansi_ct::this_architecture - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - irep_idt configt::this_architecture() { irep_idt this_arch; @@ -1599,18 +1226,6 @@ irep_idt configt::this_architecture() return this_arch; } -/*******************************************************************\ - -Function: configt::set_classpath - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void configt::set_classpath(const std::string &cp) { std::string current; @@ -1640,18 +1255,6 @@ void configt::set_classpath(const std::string &cp) java.classpath.push_back(current); } -/*******************************************************************\ - -Function: configt::ansi_ct::this_operating_system - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - irep_idt configt::this_operating_system() { irep_idt this_os; diff --git a/src/util/config.h b/src/util/config.h index f8c2f1f96dd..6fb4a5a2376 100644 --- a/src/util/config.h +++ b/src/util/config.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_CONFIG_H #define CPROVER_UTIL_CONFIG_H diff --git a/src/util/cout_message.cpp b/src/util/cout_message.cpp index 393ec62432f..5221fda0f21 100644 --- a/src/util/cout_message.cpp +++ b/src/util/cout_message.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "cout_message.h" + #include #ifdef _WIN32 @@ -16,70 +18,23 @@ Author: Daniel Kroening, kroening@kroening.com #endif #include "unicode.h" -#include "cout_message.h" - -/*******************************************************************\ -Function: cout_message_handlert::print - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void cout_message_handlert::print( - unsigned level, - const std::string &message) +cout_message_handlert::cout_message_handlert(): + stream_message_handlert(std::cout) { - if(verbosity>=level) - { - std::cout << message << '\n'; - - // We flush for level 6 or below. - if(level<=6) - std::cout << std::flush; - } } -/*******************************************************************\ - -Function: cerr_message_handlert::print - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void cerr_message_handlert::print( - unsigned level, - const std::string &message) +cerr_message_handlert::cerr_message_handlert(): + stream_message_handlert(std::cerr) { - if(verbosity>=level) - std::cerr << message << '\n' << std::flush; } -/*******************************************************************\ - -Function: consolte_message_handlert::print - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void console_message_handlert::print( unsigned level, const std::string &message) { + message_handlert::print(level, message); + if(verbosity=4) { std::cout << message << '\n'; - - if(level<=6) - std::cout << std::flush; } else - std::cerr << message << '\n' << std::flush; + std::cerr << message << '\n'; } #else - // We flush after messages of level 6 or lower. - // We don't for messages of level 7 or higher to improve performance, - // in particular when writing to NFS. // Messages level 3 or lower go to cerr, messages level 4 or // above go to cout. if(level>=4) { std::cout << message << '\n'; + } + else + std::cerr << message << '\n'; + #endif +} +void console_message_handlert::flush(unsigned level) +{ + // We flush after messages of level 6 or lower. + // We don't for messages of level 7 or higher to improve performance, + // in particular when writing to NFS. + if(level>=4) + { if(level<=6) std::cout << std::flush; } else - std::cerr << message << '\n' << std::flush; - #endif + std::cerr << std::flush; } -/*******************************************************************\ - -Function: gcc_message_handlert::print - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void gcc_message_handlert::print( unsigned level, const std::string &message, @@ -183,9 +131,9 @@ void gcc_message_handlert::print( else dest+=id2string(column)+": "; - if(level==message_clientt::M_ERROR) + if(level==messaget::M_ERROR) dest+="error: "; - else if(level==message_clientt::M_WARNING) + else if(level==messaget::M_WARNING) dest+="warning: "; } @@ -194,22 +142,12 @@ void gcc_message_handlert::print( print(level, dest); } -/*******************************************************************\ - -Function: gcc_message_handlert::print - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void gcc_message_handlert::print( unsigned level, const std::string &message) { + message_handlert::print(level, message); + // gcc appears to send everything to cerr if(verbosity>=level) std::cerr << message << '\n' << std::flush; diff --git a/src/util/cout_message.h b/src/util/cout_message.h index ab78148c6d6..39d4bddd349 100644 --- a/src/util/cout_message.h +++ b/src/util/cout_message.h @@ -6,39 +6,38 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_COUT_MESSAGE_H #define CPROVER_UTIL_COUT_MESSAGE_H -#include "message.h" +#include "ui_message.h" -class cout_message_handlert:public message_handlert +class cout_message_handlert:public stream_message_handlert { public: - // all messages go to cout - virtual void print( - unsigned level, - const std::string &message) override; + // all messages go to stdout + cout_message_handlert(); }; -class cerr_message_handlert:public message_handlert +class cerr_message_handlert:public stream_message_handlert { public: - // all messages go to cerr - virtual void print( - unsigned level, - const std::string &message) override; + // all messages go to stderr + cerr_message_handlert(); }; -class console_message_handlert:public message_handlert +class console_message_handlert:public ui_message_handlert { public: // level 4 and upwards go to cout, level 1-3 to cerr virtual void print( unsigned level, const std::string &message) override; + + virtual void flush(unsigned level) override; }; -class gcc_message_handlert:public message_handlert +class gcc_message_handlert:public ui_message_handlert { public: // aims to imitate the messages gcc prints diff --git a/src/util/cprover_prefix.h b/src/util/cprover_prefix.h index 01fc391bf02..5d6fe6b84e0 100644 --- a/src/util/cprover_prefix.h +++ b/src/util/cprover_prefix.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_CPROVER_PREFIX_H #define CPROVER_UTIL_CPROVER_PREFIX_H diff --git a/src/util/decision_procedure.cpp b/src/util/decision_procedure.cpp index 6800b0148d6..85f52acdba2 100644 --- a/src/util/decision_procedure.cpp +++ b/src/util/decision_procedure.cpp @@ -6,21 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Decision Procedure Interface #include "decision_procedure.h" -/*******************************************************************\ - -Function: decision_proceduret::in_core - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include bool decision_proceduret::in_core(const exprt &expr) { diff --git a/src/util/decision_procedure.h b/src/util/decision_procedure.h index db609b1137e..65caffab17e 100644 --- a/src/util/decision_procedure.h +++ b/src/util/decision_procedure.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Decision Procedure Interface + #ifndef CPROVER_UTIL_DECISION_PROCEDURE_H #define CPROVER_UTIL_DECISION_PROCEDURE_H @@ -39,7 +42,7 @@ class decision_proceduret:public messaget { set_to(expr, false); } // solve the problem - typedef enum { D_SATISFIABLE, D_UNSATISFIABLE, D_ERROR } resultt; + enum class resultt { D_SATISFIABLE, D_UNSATISFIABLE, D_ERROR }; // will eventually be protected, use below call operator virtual resultt dec_solve()=0; diff --git a/src/util/dstring.cpp b/src/util/dstring.cpp index 08f798b5b89..43181cb61b1 100644 --- a/src/util/dstring.cpp +++ b/src/util/dstring.cpp @@ -6,23 +6,15 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Container for C-Strings + #include "dstring.h" #include "serializer.h" -/*******************************************************************\ - - Function: dstring::serialize - - Inputs: - serializer: The serializer to read from/write to - - Outputs: - - Purpose: - Serializes this instance to/from the given serializer. - -\*******************************************************************/ +/// Serializes this instance to/from the given serializer. +/// \param serializer: The serializer to read from/write to void dstringt::serialize(serializert &serializer) { if(serializer.is_for_reading()) diff --git a/src/util/dstring.h b/src/util/dstring.h index ae219a01bb0..27f3b1bec0f 100644 --- a/src/util/dstring.h +++ b/src/util/dstring.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Container for C-Strings + #ifndef CPROVER_UTIL_DSTRING_H #define CPROVER_UTIL_DSTRING_H diff --git a/src/util/endianness_map.cpp b/src/util/endianness_map.cpp index d030df0c75e..913bc8ad5df 100644 --- a/src/util/endianness_map.cpp +++ b/src/util/endianness_map.cpp @@ -6,27 +6,16 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "endianness_map.h" + #include #include #include "std_types.h" #include "pointer_offset_size.h" #include "arith_tools.h" -#include "endianness_map.h" #include "namespace.h" -/*******************************************************************\ - -Function: endianness_mapt::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void endianness_mapt::output(std::ostream &out) const { for(std::vector::const_iterator it=map.begin(); @@ -39,18 +28,6 @@ void endianness_mapt::output(std::ostream &out) const } } -/*******************************************************************\ - -Function: endianness_mapt::build - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void endianness_mapt::build(const typet &src, bool little_endian) { if(little_endian) @@ -59,18 +36,6 @@ void endianness_mapt::build(const typet &src, bool little_endian) build_big_endian(src); } -/*******************************************************************\ - -Function: endianness_mapt::build_little_endian - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void endianness_mapt::build_little_endian(const typet &src) { mp_integer s=pointer_offset_bits(src, ns); // error is -1 @@ -84,18 +49,6 @@ void endianness_mapt::build_little_endian(const typet &src) map.push_back(i); } -/*******************************************************************\ - -Function: endianness_mapt::build_big_endian - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void endianness_mapt::build_big_endian(const typet &src) { if(src.id()==ID_symbol) diff --git a/src/util/endianness_map.h b/src/util/endianness_map.h index 03fb0a9e6b1..835f7e52938 100644 --- a/src/util/endianness_map.h +++ b/src/util/endianness_map.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_ENDIANNESS_MAP_H #define CPROVER_UTIL_ENDIANNESS_MAP_H diff --git a/src/util/error.h b/src/util/error.h index 8025dd10e7d..183ebec0872 100644 --- a/src/util/error.h +++ b/src/util/error.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_ERROR_H #define CPROVER_UTIL_ERROR_H diff --git a/src/util/expanding_vector.h b/src/util/expanding_vector.h index bb67ba73441..f8b0421db72 100644 --- a/src/util/expanding_vector.h +++ b/src/util/expanding_vector.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_EXPANDING_VECTOR_H #define CPROVER_UTIL_EXPANDING_VECTOR_H diff --git a/src/util/expr.cpp b/src/util/expr.cpp index 3b480e4bfe2..ee7f310d471 100644 --- a/src/util/expr.cpp +++ b/src/util/expr.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Expression Representation + +#include "expr.h" + #include #include @@ -14,24 +19,12 @@ Author: Daniel Kroening, kroening@kroening.com #include "mp_arith.h" #include "fixedbv.h" #include "ieee_float.h" -#include "expr.h" +#include "invariant.h" #include "rational.h" #include "rational_tools.h" #include "arith_tools.h" #include "std_expr.h" -/*******************************************************************\ - -Function: exprt::move_to_operands - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void exprt::move_to_operands(exprt &expr) { operandst &op=operands(); @@ -39,18 +32,6 @@ void exprt::move_to_operands(exprt &expr) op.back().swap(expr); } -/*******************************************************************\ - -Function: exprt::move_to_operands - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void exprt::move_to_operands(exprt &e1, exprt &e2) { operandst &op=operands(); @@ -63,18 +44,6 @@ void exprt::move_to_operands(exprt &e1, exprt &e2) op.back().swap(e2); } -/*******************************************************************\ - -Function: exprt::move_to_operands - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void exprt::move_to_operands(exprt &e1, exprt &e2, exprt &e3) { operandst &op=operands(); @@ -89,35 +58,11 @@ void exprt::move_to_operands(exprt &e1, exprt &e2, exprt &e3) op.back().swap(e3); } -/*******************************************************************\ - -Function: exprt::copy_to_operands - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void exprt::copy_to_operands(const exprt &expr) { operands().push_back(expr); } -/*******************************************************************\ - -Function: exprt::copy_to_operands - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void exprt::copy_to_operands(const exprt &e1, const exprt &e2) { operandst &op=operands(); @@ -128,18 +73,6 @@ void exprt::copy_to_operands(const exprt &e1, const exprt &e2) op.push_back(e2); } -/*******************************************************************\ - -Function: exprt::copy_to_operands - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void exprt::copy_to_operands( const exprt &e1, const exprt &e2, @@ -154,18 +87,6 @@ void exprt::copy_to_operands( op.push_back(e3); } -/*******************************************************************\ - -Function: exprt::make_typecast - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void exprt::make_typecast(const typet &_type) { exprt new_expr(ID_typecast); @@ -176,18 +97,6 @@ void exprt::make_typecast(const typet &_type) swap(new_expr); } -/*******************************************************************\ - -Function: exprt::make_not - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void exprt::make_not() { if(is_true()) @@ -216,35 +125,11 @@ void exprt::make_not() swap(new_expr); } -/*******************************************************************\ - -Function: exprt::is_constant - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool exprt::is_constant() const { return id()==ID_constant; } -/*******************************************************************\ - -Function: exprt::is_true - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool exprt::is_true() const { return is_constant() && @@ -252,18 +137,6 @@ bool exprt::is_true() const get(ID_value)!=ID_false; } -/*******************************************************************\ - -Function: exprt::is_false - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool exprt::is_false() const { return is_constant() && @@ -271,72 +144,24 @@ bool exprt::is_false() const get(ID_value)==ID_false; } -/*******************************************************************\ - -Function: exprt::make_bool - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void exprt::make_bool(bool value) { *this=exprt(ID_constant, typet(ID_bool)); set(ID_value, value?ID_true:ID_false); } -/*******************************************************************\ - -Function: exprt::make_true - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void exprt::make_true() { *this=exprt(ID_constant, typet(ID_bool)); set(ID_value, ID_true); } -/*******************************************************************\ - -Function: exprt::make_false - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void exprt::make_false() { *this=exprt(ID_constant, typet(ID_bool)); set(ID_value, ID_false); } -/*******************************************************************\ - -Function: exprt::negate - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void exprt::negate() { const irep_idt &type_id=type().id(); @@ -380,7 +205,7 @@ void exprt::negate() else { make_nil(); - assert(false); + UNREACHABLE; } } else @@ -388,7 +213,8 @@ void exprt::negate() if(id()==ID_unary_minus) { exprt tmp; - assert(operands().size()==1); + DATA_INVARIANT(operands().size()==1, + "Unary minus must have one operand"); tmp.swap(op0()); swap(tmp); } @@ -402,35 +228,11 @@ void exprt::negate() } } -/*******************************************************************\ - -Function: exprt::is_boolean - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool exprt::is_boolean() const { return type().id()==ID_bool; } -/*******************************************************************\ - -Function: exprt::is_zero - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool exprt::is_zero() const { if(is_constant()) @@ -446,7 +248,7 @@ bool exprt::is_zero() const { rationalt rat_value; if(to_rational(*this, rat_value)) - assert(false); + CHECK_RETURN(false); return rat_value.is_zero(); } else if(type_id==ID_unsignedbv || @@ -475,18 +277,6 @@ bool exprt::is_zero() const return false; } -/*******************************************************************\ - -Function: exprt::is_one - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool exprt::is_one() const { if(is_constant()) @@ -504,7 +294,7 @@ bool exprt::is_one() const { rationalt rat_value; if(to_rational(*this, rat_value)) - assert(false); + CHECK_RETURN(false); return rat_value.is_one(); } else if(type_id==ID_unsignedbv || type_id==ID_signedbv) @@ -528,18 +318,6 @@ bool exprt::is_one() const return false; } -/*******************************************************************\ - -Function: exprt::sum - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool exprt::sum(const exprt &expr) { if(!is_constant() || !expr.is_constant()) @@ -593,18 +371,6 @@ bool exprt::sum(const exprt &expr) return true; } -/*******************************************************************\ - -Function: exprt::mul - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool exprt::mul(const exprt &expr) { if(!is_constant() || !expr.is_constant()) @@ -658,18 +424,6 @@ bool exprt::mul(const exprt &expr) return true; } -/*******************************************************************\ - -Function: exprt::subtract - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool exprt::subtract(const exprt &expr) { if(!is_constant() || !expr.is_constant()) @@ -709,18 +463,6 @@ bool exprt::subtract(const exprt &expr) return true; } -/*******************************************************************\ - -Function: exprt::find_source_location - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const source_locationt &exprt::find_source_location() const { const source_locationt &l=source_location(); @@ -738,18 +480,6 @@ const source_locationt &exprt::find_source_location() const return static_cast(get_nil_irep()); } -/*******************************************************************\ - -Function: exprt::visit - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void exprt::visit(expr_visitort &visitor) { std::stack stack; @@ -768,18 +498,6 @@ void exprt::visit(expr_visitort &visitor) } } -/*******************************************************************\ - -Function: exprt::visit - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void exprt::visit(const_expr_visitort &visitor) const { std::stack stack; diff --git a/src/util/expr.h b/src/util/expr.h index 47a85b50f1c..2d58dca1cf2 100644 --- a/src/util/expr.h +++ b/src/util/expr.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_EXPR_H #define CPROVER_UTIL_EXPR_H diff --git a/src/util/expr_util.cpp b/src/util/expr_util.cpp index 38252a3683f..25b741a9a63 100644 --- a/src/util/expr_util.cpp +++ b/src/util/expr_util.cpp @@ -6,7 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #include "expr_util.h" + #include "expr.h" #include "fixedbv.h" #include "ieee_float.h" @@ -15,18 +17,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "namespace.h" #include "arith_tools.h" -/*******************************************************************\ - -Function: make_next_state - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void make_next_state(exprt &expr) { Forall_operands(it, expr) @@ -36,18 +26,6 @@ void make_next_state(exprt &expr) expr.id(ID_next_symbol); } -/*******************************************************************\ - -Function: make_binary - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt make_binary(const exprt &expr) { const exprt::operandst &operands=expr.operands(); @@ -59,14 +37,14 @@ exprt make_binary(const exprt &expr) const typet &type=expr.type(); exprt previous=operands.front(); - assert(previous.type()==type); + PRECONDITION(previous.type()==type); for(exprt::operandst::const_iterator it=++operands.begin(); it!=operands.end(); ++it) { - assert(it->type()==type); + PRECONDITION(it->type()==type); exprt tmp=expr; tmp.operands().clear(); @@ -79,22 +57,10 @@ exprt make_binary(const exprt &expr) return previous; } -/*******************************************************************\ - -Function: make_with_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - with_exprt make_with_expr(const update_exprt &src) { const exprt::operandst &designator=src.designator(); - assert(!designator.empty()); + PRECONDITION(!designator.empty()); with_exprt result; exprt *dest=&result; @@ -113,7 +79,7 @@ with_exprt make_with_expr(const update_exprt &src) // to_member_designator(*it).get_component_name(); } else - assert(false); + UNREACHABLE; *dest=tmp; dest=&to_with_expr(*dest).new_value(); @@ -122,18 +88,6 @@ with_exprt make_with_expr(const update_exprt &src) return result; } -/*******************************************************************\ - -Function: is_not_zero - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt is_not_zero( const exprt &src, const namespacet &ns) @@ -155,7 +109,7 @@ exprt is_not_zero( src_type.id()==ID_floatbv?ID_ieee_float_notequal:ID_notequal; exprt zero=from_integer(0, src_type); - assert(zero.is_not_nil()); + CHECK_RETURN(zero.is_not_nil()); binary_exprt comparison(src, id, zero, bool_typet()); comparison.add_source_location()=src.source_location(); @@ -163,18 +117,6 @@ exprt is_not_zero( return comparison; } -/*******************************************************************\ - -Function: boolean_negate - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt boolean_negate(const exprt &src) { if(src.id()==ID_not && src.operands().size()==1) @@ -187,18 +129,6 @@ exprt boolean_negate(const exprt &src) return not_exprt(src); } -/*******************************************************************\ - -Function: has_subexpr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool has_subexpr(const exprt &src, const irep_idt &id) { if(src.id()==id) @@ -211,22 +141,10 @@ bool has_subexpr(const exprt &src, const irep_idt &id) return false; } -/*******************************************************************\ - -Function: lift_if - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - if_exprt lift_if(const exprt &src, std::size_t operand_number) { - assert(operand_number=3 operands into nested binary expressions */ +/// splits an expression with >=3 operands into nested binary expressions exprt make_binary(const exprt &); -/*! converts an udpate expr into a (possibly nested) with expression */ +/// converts an update expr into a (possibly nested) with expression with_exprt make_with_expr(const update_exprt &); -/*! converts a scalar/float expression to C/C++ Booleans */ +/// converts a scalar/float expression to C/C++ Booleans exprt is_not_zero(const exprt &, const namespacet &ns); -/*! negate a Boolean expression, possibly removing a not_exprt, - and swapping false and true */ +/// negate a Boolean expression, possibly removing a not_exprt, +/// and swapping false and true exprt boolean_negate(const exprt &); -/*! returns true if the expression has a subexpresion with given ID */ +/// returns true if the expression has a subexpression with given ID bool has_subexpr(const exprt &, const irep_idt &); -/*! lift up an if_exprt one level */ +/// lift up an if_exprt one level if_exprt lift_if(const exprt &, std::size_t operand_number); const exprt &get_underlying_object(const exprt &possible_member); diff --git a/src/util/file_util.cpp b/src/util/file_util.cpp index 180967b3338..dea8955fb11 100644 --- a/src/util/file_util.cpp +++ b/src/util/file_util.cpp @@ -8,6 +8,11 @@ Date: January 2012 \*******************************************************************/ +/// \file +/// File Utilities + +#include "file_util.h" + #include #include @@ -45,21 +50,7 @@ Date: January 2012 #include #endif -#include "file_util.h" - - -/*******************************************************************\ - -Function: get_current_working_directory - - Inputs: none - - Outputs: current working directory - - Purpose: - -\*******************************************************************/ - +/// \return current working directory std::string get_current_working_directory() { unsigned bsize=50; @@ -70,7 +61,7 @@ std::string get_current_working_directory() errno=0; - while(buf && getcwd(buf, bsize-1)==NULL && errno==ERANGE) + while(buf && getcwd(buf, bsize-1)==nullptr && errno==ERANGE) { bsize*=2; buf=reinterpret_cast(realloc(buf, sizeof(char)*bsize)); @@ -82,18 +73,7 @@ std::string get_current_working_directory() return working_directory; } -/*******************************************************************\ - -Function: delete_directory - - Inputs: path - - Outputs: - - Purpose: deletes all files in 'path' and then the directory itself - -\*******************************************************************/ - +/// deletes all files in 'path' and then the directory itself #ifdef _WIN32 void delete_directory_utf16(const std::wstring &path) @@ -128,10 +108,10 @@ void delete_directory(const std::string &path) delete_directory_utf16(utf8_to_utf16_little_endian(path)); #else DIR *dir=opendir(path.c_str()); - if(dir!=NULL) + if(dir!=nullptr) { struct dirent *ent; - while((ent=readdir(dir))!=NULL) + while((ent=readdir(dir))!=nullptr) { // Needed for Alpine Linux if(strcmp(ent->d_name, ".")==0 || strcmp(ent->d_name, "..")==0) @@ -140,12 +120,18 @@ void delete_directory(const std::string &path) std::string sub_path=path+"/"+ent->d_name; struct stat stbuf; - stat(sub_path.c_str(), &stbuf); + int result=stat(sub_path.c_str(), &stbuf); + if(result!=0) + throw std::string("Stat failed: ")+std::strerror(errno); if(S_ISDIR(stbuf.st_mode)) delete_directory(sub_path); else - remove(sub_path.c_str()); + { + result=remove(sub_path.c_str()); + if(result!=0) + throw std::string("Remove failed: ")+std::strerror(errno); + } } closedir(dir); } @@ -153,19 +139,8 @@ void delete_directory(const std::string &path) #endif } -/*******************************************************************\ - -Function: concat_dir_file - - Inputs: directory name and file name - - Outputs: concatenation of directory and file, if the file path is - relative - - Purpose: - -\*******************************************************************/ - +/// \par parameters: directory name and file name +/// \return concatenation of directory and file, if the file path is relative std::string concat_dir_file( const std::string &directory, const std::string &file_name) @@ -381,22 +356,11 @@ std::string fileutl_get_relative_path( return result; } -/*******************************************************************\ - - Function: make_valid_filename - - Inputs: - file_name: The file name to sanitize. - - Outputs: - - Purpose: - Replaces invalid characters in a file name using a hard-coded list of - replacements. - This is not designed to operate on path names and will replace folder - seperator characters. - -\*******************************************************************/ +/// Replaces invalid characters in a file name using a hard-coded list of +/// replacements. +/// This is not designed to operate on path names and will replace folder +/// seperator characters. +/// \param file_name: The file name to sanitize. std::string make_valid_filename(std::string file_name) { std::replace(file_name.begin(), file_name.end(), '#', '_'); diff --git a/src/util/file_util.h b/src/util/file_util.h index 9c01c15f951..c7e947ec3e4 100644 --- a/src/util/file_util.h +++ b/src/util/file_util.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_FILE_UTIL_H #define CPROVER_UTIL_FILE_UTIL_H diff --git a/src/util/find_macros.cpp b/src/util/find_macros.cpp index 8e2e249ada6..10adacba6c9 100644 --- a/src/util/find_macros.cpp +++ b/src/util/find_macros.cpp @@ -6,25 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "find_macros.h" + #include -#include "find_macros.h" #include "expr.h" #include "namespace.h" #include "symbol.h" -/*******************************************************************\ - -Function: find_macros - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void find_macros( const exprt &src, const namespacet &ns, diff --git a/src/util/find_macros.h b/src/util/find_macros.h index 17b8282502c..23142dd478d 100644 --- a/src/util/find_macros.h +++ b/src/util/find_macros.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_FIND_MACROS_H #define CPROVER_UTIL_FIND_MACROS_H diff --git a/src/util/find_symbols.cpp b/src/util/find_symbols.cpp index 03cd78f4347..9984ae584c2 100644 --- a/src/util/find_symbols.cpp +++ b/src/util/find_symbols.cpp @@ -6,24 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "std_types.h" -#include "std_expr.h" - #include "find_symbols.h" -typedef enum { F_TYPE, F_TYPE_NON_PTR, F_EXPR, F_BOTH } kindt; - -/*******************************************************************\ - -Function: find_symbols - - Inputs: - - Outputs: - - Purpose: +#include "std_types.h" +#include "std_expr.h" -\*******************************************************************/ +enum class kindt { F_TYPE, F_TYPE_NON_PTR, F_EXPR, F_BOTH }; void find_symbols( const exprt &src, @@ -32,18 +20,6 @@ void find_symbols( find_symbols(src, dest, true, true); } -/*******************************************************************\ - -Function: find_symbols - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void find_symbols( const exprt &src, find_symbols_sett &dest, @@ -60,18 +36,6 @@ void find_symbols( } } -/*******************************************************************\ - -Function: has_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool has_symbol( const exprt &src, const find_symbols_sett &symbols, @@ -91,18 +55,6 @@ bool has_symbol( return false; } -/*******************************************************************\ - -Function: has_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool has_symbol( const exprt &src, const find_symbols_sett &symbols) @@ -110,18 +62,6 @@ bool has_symbol( return has_symbol(src, symbols, true, true); } -/*******************************************************************\ - -Function: find_symbols - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void find_symbols( const exprt &src, std::set &dest) @@ -135,18 +75,6 @@ void find_symbols( } } -/*******************************************************************\ - -Function: find_symbols - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void find_symbols( const exprt &src, std::set &dest) @@ -160,18 +88,6 @@ void find_symbols( } } -/*******************************************************************\ - -Function: find_symbols - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void find_symbols(kindt kind, const typet &src, find_symbols_sett &dest); void find_symbols(kindt kind, const exprt &src, find_symbols_sett &dest) @@ -181,7 +97,7 @@ void find_symbols(kindt kind, const exprt &src, find_symbols_sett &dest) find_symbols(kind, src.type(), dest); - if(kind==F_BOTH || kind==F_EXPR) + if(kind==kindt::F_BOTH || kind==kindt::F_EXPR) if(src.id()==ID_symbol || src.id()==ID_next_symbol) dest.insert(src.get(ID_identifier)); @@ -197,21 +113,9 @@ void find_symbols(kindt kind, const exprt &src, find_symbols_sett &dest) find_symbols(kind, static_cast(va_arg_type), dest); } -/*******************************************************************\ - -Function: find_symbols - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void find_symbols(kindt kind, const typet &src, find_symbols_sett &dest) { - if(kind!=F_TYPE_NON_PTR || + if(kind!=kindt::F_TYPE_NON_PTR || src.id()!=ID_pointer) { if(src.has_subtype()) @@ -219,6 +123,10 @@ void find_symbols(kindt kind, const typet &src, find_symbols_sett &dest) forall_subtypes(it, src) find_symbols(kind, *it, dest); + + const irep_idt &typedef_name=src.get(ID_C_typedef); + if(!typedef_name.empty()) + dest.insert(typedef_name); } if(src.id()==ID_struct || @@ -248,7 +156,7 @@ void find_symbols(kindt kind, const typet &src, find_symbols_sett &dest) find_symbols(kind, *it, dest); // irep_idt identifier=it->get_identifier(); - // if(identifier!=irep_idt() && (kind==F_TYPE || kind==F_BOTH)) + // if(!identifier.empty() && (kind==F_TYPE || kind==F_BOTH)) // dest.insert(identifier); } } @@ -273,108 +181,36 @@ void find_symbols(kindt kind, const typet &src, find_symbols_sett &dest) } } -/*******************************************************************\ - -Function: find_type_symbols - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void find_type_symbols(const exprt &src, find_symbols_sett &dest) { - find_symbols(F_TYPE, src, dest); + find_symbols(kindt::F_TYPE, src, dest); } -/*******************************************************************\ - -Function: find_type_symbols - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void find_type_symbols(const typet &src, find_symbols_sett &dest) { - find_symbols(F_TYPE, src, dest); + find_symbols(kindt::F_TYPE, src, dest); } -/*******************************************************************\ - -Function: find_non_pointer_type_symbols - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void find_non_pointer_type_symbols( const exprt &src, find_symbols_sett &dest) { - find_symbols(F_TYPE_NON_PTR, src, dest); + find_symbols(kindt::F_TYPE_NON_PTR, src, dest); } -/*******************************************************************\ - -Function: find_non_pointer_type_symbols - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void find_non_pointer_type_symbols( const typet &src, find_symbols_sett &dest) { - find_symbols(F_TYPE_NON_PTR, src, dest); + find_symbols(kindt::F_TYPE_NON_PTR, src, dest); } -/*******************************************************************\ - -Function: find_type_and_expr_symbols - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void find_type_and_expr_symbols(const exprt &src, find_symbols_sett &dest) { - find_symbols(F_BOTH, src, dest); + find_symbols(kindt::F_BOTH, src, dest); } -/*******************************************************************\ - -Function: find_type_and_expr_symbols - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void find_type_and_expr_symbols(const typet &src, find_symbols_sett &dest) { - find_symbols(F_BOTH, src, dest); + find_symbols(kindt::F_BOTH, src, dest); } diff --git a/src/util/find_symbols.h b/src/util/find_symbols.h index 4ca899e4b40..e86957b7093 100644 --- a/src/util/find_symbols.h +++ b/src/util/find_symbols.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_FIND_SYMBOLS_H #define CPROVER_UTIL_FIND_SYMBOLS_H diff --git a/src/util/fixedbv.cpp b/src/util/fixedbv.cpp index d1703d85ca9..4ea2a166129 100644 --- a/src/util/fixedbv.cpp +++ b/src/util/fixedbv.cpp @@ -6,111 +6,40 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "fixedbv.h" + #include "std_types.h" #include "std_expr.h" -#include "fixedbv.h" #include "arith_tools.h" -/*******************************************************************\ - -Function: fixedbv_spect::fixedbv_spect - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - fixedbv_spect::fixedbv_spect(const fixedbv_typet &type) { integer_bits=type.get_integer_bits(); width=type.get_width(); } -/*******************************************************************\ - -Function: fixedbvt::fixedbvt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - fixedbvt::fixedbvt(const constant_exprt &expr) { from_expr(expr); } -/*******************************************************************\ - -Function: fixedbvt::from_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void fixedbvt::from_expr(const constant_exprt &expr) { spec=fixedbv_spect(to_fixedbv_type(expr.type())); v=binary2integer(id2string(expr.get_value()), true); } -/*******************************************************************\ - -Function: fixedbvt::from_integer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void fixedbvt::from_integer(const mp_integer &i) { v=i*power(2, spec.get_fraction_bits()); } -/*******************************************************************\ - -Function: fixedbvt::to_integer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - mp_integer fixedbvt::to_integer() const { // this rounds to zero, i.e., we just divide return v/power(2, spec.get_fraction_bits()); } -/*******************************************************************\ - -Function: fixedbvt::to_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - constant_exprt fixedbvt::to_expr() const { fixedbv_typet type; @@ -122,18 +51,6 @@ constant_exprt fixedbvt::to_expr() const return expr; } -/*******************************************************************\ - -Function: fixedbvt::round - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void fixedbvt::round(const fixedbv_spect &dest_spec) { std::size_t old_fraction_bits=spec.width-spec.integer_bits; @@ -167,35 +84,11 @@ void fixedbvt::round(const fixedbv_spect &dest_spec) spec=dest_spec; } -/*******************************************************************\ - -Function: fixedbvt::negate - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void fixedbvt::negate() { v=-v; } -/*******************************************************************\ - -Function: fixedbvt::operator* - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - fixedbvt &fixedbvt::operator*=(const fixedbvt &o) { v*=o.v; @@ -210,18 +103,6 @@ fixedbvt &fixedbvt::operator*=(const fixedbvt &o) return *this; } -/*******************************************************************\ - -Function: fixedbvt::operator/= - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - fixedbvt &fixedbvt::operator/=(const fixedbvt &o) { v*=power(2, o.spec.get_fraction_bits()); @@ -230,35 +111,11 @@ fixedbvt &fixedbvt::operator/=(const fixedbvt &o) return *this; } -/*******************************************************************\ - -Function: fixedbvt::operator== - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool fixedbvt::operator==(int i) const { return v==power(2, spec.get_fraction_bits())*i; } -/*******************************************************************\ - -Function: fixedbvt::format - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string fixedbvt::format( const format_spect &format_spec) const { diff --git a/src/util/fixedbv.h b/src/util/fixedbv.h index 8354e0bef7c..bf37be62b7f 100644 --- a/src/util/fixedbv.h +++ b/src/util/fixedbv.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_FIXEDBV_H #define CPROVER_UTIL_FIXEDBV_H diff --git a/src/util/format_constant.cpp b/src/util/format_constant.cpp index a63b1d01555..85778504e47 100644 --- a/src/util/format_constant.cpp +++ b/src/util/format_constant.cpp @@ -6,25 +6,15 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #include "format_constant.h" + #include "arith_tools.h" #include "fixedbv.h" #include "ieee_float.h" #include "expr.h" #include "std_expr.h" -/*******************************************************************\ - -Function: format_constantt::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string format_constantt::operator()(const exprt &expr) { if(expr.is_constant()) diff --git a/src/util/format_constant.h b/src/util/format_constant.h index 08702096596..a17765b1a44 100644 --- a/src/util/format_constant.h +++ b/src/util/format_constant.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_FORMAT_CONSTANT_H #define CPROVER_UTIL_FORMAT_CONSTANT_H diff --git a/src/util/format_spec.h b/src/util/format_spec.h index 495d364d5cf..828ccdcb0ce 100644 --- a/src/util/format_spec.h +++ b/src/util/format_spec.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_FORMAT_SPEC_H #define CPROVER_UTIL_FORMAT_SPEC_H @@ -23,14 +24,14 @@ class format_spect // eE: SCIENTIFIC // gG: AUTOMATIC - typedef enum { DECIMAL, SCIENTIFIC, AUTOMATIC } stylet; + enum class stylet { DECIMAL, SCIENTIFIC, AUTOMATIC }; stylet style; format_spect(): min_width(0), precision(6), zero_padding(false), - style(AUTOMATIC) + style(stylet::AUTOMATIC) { } @@ -44,12 +45,12 @@ class format_spect static format_spect scientific() { - return format_spect(SCIENTIFIC); + return format_spect(stylet::SCIENTIFIC); } static format_spect automatic() { - return format_spect(AUTOMATIC); + return format_spect(stylet::AUTOMATIC); } }; diff --git a/src/util/fresh_symbol.cpp b/src/util/fresh_symbol.cpp index fbe6f09b871..a259a4ec15e 100644 --- a/src/util/fresh_symbol.cpp +++ b/src/util/fresh_symbol.cpp @@ -6,27 +6,19 @@ Author: Chris Smowton, chris.smowton@diffblue.com \*******************************************************************/ -#include "fresh_symbol.h" - -/*******************************************************************\ - -Function: get_fresh_aux_symbol - - Inputs: `type`: type of new symbol - `name_prefix`, `basename_prefix`: - new symbol will be named name_prefix::basename_prefix$num - unless name_prefix is empty, in which case the :: prefix - is omitted. - `source_location`: new symbol source loc - `symbol_mode`: new symbol mode - `symbol_table`: table to add the new symbol to +/// \file +/// Fresh auxiliary symbol creation - Outputs: - - Purpose: Installs a fresh-named symbol with the requested name pattern - -\*******************************************************************/ +#include "fresh_symbol.h" +/// Installs a fresh-named symbol with the requested name pattern +/// \par parameters: `type`: type of new symbol +/// `name_prefix`, `basename_prefix`: new symbol will be named +/// name_prefix::basename_prefix$num unless name_prefix is empty, in which +/// case the :: prefix is omitted. +/// `source_location`: new symbol source loc +/// `symbol_mode`: new symbol mode +/// `symbol_table`: table to add the new symbol to symbolt &get_fresh_aux_symbol( const typet &type, const std::string &name_prefix, @@ -41,6 +33,7 @@ symbolt &get_fresh_aux_symbol( do { + // Distinguish local variables with the same name new_symbol.base_name= basename_prefix+ "$"+ diff --git a/src/util/fresh_symbol.h b/src/util/fresh_symbol.h index c3b2749cbe3..a176a16a551 100644 --- a/src/util/fresh_symbol.h +++ b/src/util/fresh_symbol.h @@ -6,6 +6,9 @@ Author: Chris Smowton, chris.smowton@diffblue.com \*******************************************************************/ +/// \file +/// Fresh auxiliary symbol creation + #ifndef CPROVER_UTIL_FRESH_SYMBOL_H #define CPROVER_UTIL_FRESH_SYMBOL_H diff --git a/src/util/get_base_name.cpp b/src/util/get_base_name.cpp index 3f7bb186937..79d72618a61 100644 --- a/src/util/get_base_name.cpp +++ b/src/util/get_base_name.cpp @@ -8,20 +8,12 @@ Author: CM Wintersteiger \*******************************************************************/ -#include "get_base_name.h" - -/*******************************************************************\ - -Function: get_base_name - - Inputs: a string - Outputs: a new string - - Purpose: cleans a filename from path and extension - -\*******************************************************************/ +#include "get_base_name.h" +/// cleans a filename from path and extension +/// \par parameters: a string +/// \return a new string std::string get_base_name(const std::string &in, bool strip_suffix) { size_t r=std::string::npos; diff --git a/src/util/get_base_name.h b/src/util/get_base_name.h index 648b4689dc8..d1edfc09765 100644 --- a/src/util/get_base_name.h +++ b/src/util/get_base_name.h @@ -8,6 +8,7 @@ Author: CM Wintersteiger \*******************************************************************/ + #ifndef CPROVER_UTIL_GET_BASE_NAME_H #define CPROVER_UTIL_GET_BASE_NAME_H diff --git a/src/util/get_module.cpp b/src/util/get_module.cpp index e4afd21400f..3af2c46b49c 100644 --- a/src/util/get_module.cpp +++ b/src/util/get_module.cpp @@ -6,10 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Find module symbol using name + +#include "get_module.h" + #include #include -#include "get_module.h" #include "message.h" #include "symbol_table.h" @@ -23,18 +27,6 @@ typedef std::list symbolptr_listt; for(symbolptr_listt::iterator it=(list).begin(); \ it!=(list).end(); ++it) -/*******************************************************************\ - -Function: get_module_by_name - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const symbolt &get_module_by_name( const symbol_tablet &symbol_table, const std::string &module, @@ -80,18 +72,6 @@ const symbolt &get_module_by_name( return *symbolptr_list.front(); } -/*******************************************************************\ - -Function: get_module - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const symbolt &get_module( const symbol_tablet &symbol_table, const std::string &module, diff --git a/src/util/get_module.h b/src/util/get_module.h index 1f1063c073c..73eda37dfbb 100644 --- a/src/util/get_module.h +++ b/src/util/get_module.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Find module symbol using name + #ifndef CPROVER_UTIL_GET_MODULE_H #define CPROVER_UTIL_GET_MODULE_H diff --git a/src/util/graph.cpp b/src/util/graph.cpp index 07fabf150da..2d80781f41a 100644 --- a/src/util/graph.cpp +++ b/src/util/graph.cpp @@ -6,4 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// A Template Class for Graphs + #include "graph.h" diff --git a/src/util/graph.h b/src/util/graph.h index 42988914362..3673b4544c0 100644 --- a/src/util/graph.h +++ b/src/util/graph.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// A Template Class for Graphs + #ifndef CPROVER_UTIL_GRAPH_H #define CPROVER_UTIL_GRAPH_H @@ -16,11 +19,16 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include +#include + +#include "invariant.h" class empty_edget { }; +/// This class represents a node in a directed graph. +/// See \ref grapht for more information. template class graph_nodet { @@ -53,7 +61,7 @@ class graph_nodet } }; -// a node type with an exta bit +/// A node type with an extra bit template class visited_nodet:public graph_nodet { @@ -68,8 +76,7 @@ class visited_nodet:public graph_nodet } }; -// compute intersection of two edge sets, -// in linear time +/// Compute intersection of two edge sets, in linear time template void intersection( const typename graph_nodet::edgest &a, @@ -95,7 +102,32 @@ void intersection( } } -// a generic graph class with a parametric node type +/// A generic directed graph with a parametric node type. +/// +/// The nodes of the graph are stored in the only field of the class, a +/// std::vector named `nodes`. Nodes are instances of class graph_nodet or a +/// subclass of it. Graph edges contain a payload object of parametric type E +/// (which has to be default-constructible). By default E is instantiated with +/// an empty class (empty_edget). +/// +/// Each node is identified by its offset inside the `nodes` vector. The +/// incoming and outgoing edges of a node are stored as std::maps in the fields +/// `in` and `out` of the graph_nodet. These maps associate a node identifier +/// (the offset) to the edge payload (of type E). +/// +/// In fact, observe that two instances of E are stored per edge of the graph. +/// For instance, assume that we want to create a graph with two nodes, A and B, +/// and one edge from A to B, labelled by object e. We achieve this by inserting +/// the pair (offsetof(B),e) in the map `A.out` and the pair (offsetof(A),e) in +/// the map `B.in`. +/// +/// Nodes are inserted in the graph using grapht::add_node(), which returns the +/// identifier (offset) of the inserted node. Edges between nodes are created +/// by grapht::add_edge(a,b), where `a` and `b` are the identifiers of nodes. +/// Method `add_edges` adds a default-constructed payload object of type E. +/// Adding a payload objet `e` to an edge seems to be only possibly by manually +/// inserting `e` in the std::maps `in` and `out` of the two nodes associated to +/// the edge. template > class grapht { @@ -147,6 +179,11 @@ class grapht return nodes.size(); } + bool empty() const + { + return nodes.empty(); + } + const edgest &in(node_indext n) const { return nodes[n].in; @@ -218,6 +255,13 @@ class grapht // return value: number of SCCs std::size_t SCCs(std::vector &subgraph_nr); + bool is_dag() const + { + return empty() || !topsort().empty(); + } + + std::list topsort() const; + void output_dot(std::ostream &out) const; void output_dot_node(std::ostream &out, node_indext n) const; @@ -255,18 +299,6 @@ class grapht bool non_trivial) const; }; -/*******************************************************************\ - -Function: grapht::add_undirected_edge - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void grapht::add_undirected_edge(node_indext a, node_indext b) { @@ -280,18 +312,6 @@ void grapht::add_undirected_edge(node_indext a, node_indext b) nb.add_in(a); } -/*******************************************************************\ - -Function: grapht::remove_undirected_edge - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void grapht::remove_undirected_edge(node_indext a, node_indext b) { @@ -303,18 +323,6 @@ void grapht::remove_undirected_edge(node_indext a, node_indext b) nb.in.erase(a); } -/*******************************************************************\ - -Function: grapht::remove_in_edges - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void grapht::remove_in_edges(node_indext n) { @@ -330,18 +338,6 @@ void grapht::remove_in_edges(node_indext n) node.in.clear(); } -/*******************************************************************\ - -Function: grapht::remove_out_edges - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void grapht::remove_out_edges(node_indext n) { @@ -357,18 +353,6 @@ void grapht::remove_out_edges(node_indext n) node.out.clear(); } -/*******************************************************************\ - -Function: grapht::shortest_path - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void grapht::shortest_path( node_indext src, @@ -460,18 +444,6 @@ void grapht::shortest_path( } } -/*******************************************************************\ - -Function: grapht::visit_reachable - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void grapht::visit_reachable(node_indext src) { @@ -497,18 +469,6 @@ void grapht::visit_reachable(node_indext src) } } -/*******************************************************************\ - -Function: grapht::connected_subgraphs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template std::size_t grapht::connected_subgraphs( std::vector &subgraph_nr) @@ -554,18 +514,6 @@ std::size_t grapht::connected_subgraphs( return nr; } -/*******************************************************************\ - -Function: grapht::tarjan - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void grapht::tarjan(tarjant &t, node_indext v) { @@ -610,18 +558,6 @@ void grapht::tarjan(tarjant &t, node_indext v) } } -/*******************************************************************\ - -Function: grapht::SCCs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template std::size_t grapht::SCCs(std::vector &subgraph_nr) { @@ -634,18 +570,6 @@ std::size_t grapht::SCCs(std::vector &subgraph_nr) return t.scc_count; } -/*******************************************************************\ - -Function: grapht::make_chordal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void grapht::make_chordal() { @@ -682,17 +606,51 @@ void grapht::make_chordal() } } -/*******************************************************************\ - -Function: grapht::output_dot - - Inputs: +/// Find a topological order of the nodes if graph is DAG, return empty list for +/// non-DAG or empty graph. Uses Kahn's algorithm running in O(#edges+#nodes). +template +std::list::node_indext> grapht::topsort() const +{ + // list of topologically sorted nodes + std::list nodelist; + // queue of working set nodes with in-degree zero + std::queue indeg0_nodes; + // in-degree for each node + std::vector in_deg(nodes.size(), 0); + + // abstract graph as in-degree of each node + for(node_indext idx=0; idx void grapht::output_dot(std::ostream &out) const @@ -701,18 +659,6 @@ void grapht::output_dot(std::ostream &out) const output_dot_node(out, n); } -/*******************************************************************\ - -Function: grapht::output_dot_node - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template void grapht::output_dot_node(std::ostream &out, node_indext n) const { diff --git a/src/util/guard.cpp b/src/util/guard.cpp index da9cc130723..693b48602c9 100644 --- a/src/util/guard.cpp +++ b/src/util/guard.cpp @@ -6,23 +6,15 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Symbolic Execution -#include "std_expr.h" -#include "simplify_utils.h" #include "guard.h" -/*******************************************************************\ - -Function: guardt::as_expr - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include "std_expr.h" +#include "simplify_utils.h" void guardt::guard_expr(exprt &dest) const { @@ -48,18 +40,6 @@ void guardt::guard_expr(exprt &dest) const } #if 0 -/*******************************************************************\ - -Function: guardt::as_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt guardt::as_expr(guard_listt::const_iterator it) const { if(it==guard_list.end()) @@ -81,18 +61,6 @@ exprt guardt::as_expr(guard_listt::const_iterator it) const } #endif -/*******************************************************************\ - -Function: guardt::add - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void guardt::add(const exprt &expr) { assert(expr.type().id()==ID_bool); @@ -122,18 +90,6 @@ void guardt::add(const exprt &expr) op.push_back(expr); } -/*******************************************************************\ - -Function: operator -= - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - guardt &operator -= (guardt &g1, const guardt &g2) { if(g1.id()!=ID_and || g2.id()!=ID_and) @@ -163,18 +119,6 @@ guardt &operator -= (guardt &g1, const guardt &g2) return g1; } -/*******************************************************************\ - -Function: operator |= - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - guardt &operator |= (guardt &g1, const guardt &g2) { if(g2.is_false() || g1.is_true()) @@ -260,37 +204,13 @@ guardt &operator |= (guardt &g1, const guardt &g2) } #if 0 -/*******************************************************************\ - -Function: operator << - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::ostream &operator << (std::ostream &out, const guardt &g) { forall_expr_list(it, g.guard_list) - out << "*** " << it->pretty() << std::endl; + out << "*** " << it->pretty() << '\n'; return out; } -/*******************************************************************\ - -Function: guardt::is_false - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - #define forall_guard(it, guard_list) \ for(guardt::guard_listt::const_iterator it=(guard_list).begin(); \ it!=(guard_list).end(); ++it) @@ -304,18 +224,6 @@ bool guardt::is_false() const return false; } -/*******************************************************************\ - -Function: guardt::make_false - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void guardt::make_false() { guard_list.clear(); diff --git a/src/util/guard.h b/src/util/guard.h index 215ac58ba02..a923680e2ad 100644 --- a/src/util/guard.h +++ b/src/util/guard.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Guard Data Structure + #ifndef CPROVER_UTIL_GUARD_H #define CPROVER_UTIL_GUARD_H diff --git a/src/util/identifier.cpp b/src/util/identifier.cpp index 96074d9c43e..daa41cad07d 100644 --- a/src/util/identifier.cpp +++ b/src/util/identifier.cpp @@ -6,21 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "identifier.h" -/*******************************************************************\ - -Function: identifiert::as_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include std::string identifiert::as_string() const { @@ -37,18 +25,6 @@ std::string identifiert::as_string() const return result; } -/*******************************************************************\ - -Function: identifiert::parse - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void identifiert::parse(const std::string &s) { std::string component; diff --git a/src/util/identifier.h b/src/util/identifier.h index 5bcd8e9b6eb..c9148eb5c10 100644 --- a/src/util/identifier.h +++ b/src/util/identifier.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_IDENTIFIER_H #define CPROVER_UTIL_IDENTIFIER_H diff --git a/src/util/ieee_float.cpp b/src/util/ieee_float.cpp index 5220b05885c..ba9fb9ac857 100644 --- a/src/util/ieee_float.cpp +++ b/src/util/ieee_float.cpp @@ -6,9 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -// is yet to come -#include +#include "ieee_float.h" +#include #include #include #include @@ -17,37 +17,12 @@ Author: Daniel Kroening, kroening@kroening.com #include "arith_tools.h" #include "std_types.h" #include "std_expr.h" -#include "ieee_float.h" - -/*******************************************************************\ - -Function: ieee_float_spect::bias - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ mp_integer ieee_float_spect::bias() const { return power(2, e-1)-1; } -/*******************************************************************\ - -Function: ieee_float_spect::to_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - floatbv_typet ieee_float_spect::to_type() const { floatbv_typet result; @@ -58,52 +33,16 @@ floatbv_typet ieee_float_spect::to_type() const return result; } -/*******************************************************************\ - -Function: ieee_float_spect::max_exponent - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - mp_integer ieee_float_spect::max_exponent() const { return power(2, e)-1; } -/*******************************************************************\ - -Function: ieee_float_spect::max_fraction - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - mp_integer ieee_float_spect::max_fraction() const { return power(2, f)-1; } -/*******************************************************************\ - -Function: ieee_float_spect::from_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ieee_float_spect::from_type(const floatbv_typet &type) { std::size_t width=type.get_width(); @@ -116,70 +55,60 @@ void ieee_float_spect::from_type(const floatbv_typet &type) e=e-1; // no hidden bit } -/*******************************************************************\ - -Function: ieee_floatt::print - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ieee_floatt::print(std::ostream &out) const { out << to_ansi_c_string(); } -/*******************************************************************\ - -Function: ieee_floatt::format - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string ieee_floatt::format(const format_spect &format_spec) const { std::string result; switch(format_spec.style) { - case format_spect::DECIMAL: + case format_spect::stylet::DECIMAL: result+=to_string_decimal(format_spec.precision); break; - case format_spect::SCIENTIFIC: + case format_spect::stylet::SCIENTIFIC: result+=to_string_scientific(format_spec.precision); break; - case format_spect::AUTOMATIC: + case format_spect::stylet::AUTOMATIC: { + // On Linux, the man page says: // "Style e is used if the exponent from its conversion // is less than -4 or greater than or equal to the precision." + // + // On BSD, it's + // "The argument is printed in style f (F) or in style e (E) + // whichever gives full precision in minimum space." mp_integer _exponent, _fraction; extract_base10(_fraction, _exponent); - if(_exponent>=0) + mp_integer adjusted_exponent=base10_digits(_fraction)+_exponent; + + if(adjusted_exponent>=format_spec.precision || + adjusted_exponent<-4) { - if(base10_digits(_fraction)+_exponent>=format_spec.precision) - result+=to_string_scientific(format_spec.precision); - else - result+=to_string_decimal(format_spec.precision); + result+=to_string_scientific(format_spec.precision); } - else // _exponent<0 + else { - if(true) // base10_digits(fraction)+_exponent<-4) - result+=to_string_scientific(format_spec.precision); - else - result+=to_string_decimal(format_spec.precision); + result+=to_string_decimal(format_spec.precision); + + // Implementations tested also appear to suppress trailing zeros + // and trailing dots. + + { + std::size_t trunc_pos=result.find_last_not_of('0'); + if(trunc_pos!=std::string::npos) + result.resize(trunc_pos+1); + } + + if(!result.empty() && result.back()=='.') + result.resize(result.size()-1); } } break; @@ -191,18 +120,6 @@ std::string ieee_floatt::format(const format_spect &format_spec) const return result; } -/*******************************************************************\ - -Function: ieee_floatt::base10_digits - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - mp_integer ieee_floatt::base10_digits(const mp_integer &src) { mp_integer tmp=src; @@ -212,18 +129,6 @@ mp_integer ieee_floatt::base10_digits(const mp_integer &src) return result; } -/*******************************************************************\ - -Function: ieee_floatt::to_string_decimal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string ieee_floatt::to_string_decimal(std::size_t precision) const { std::string result; @@ -315,20 +220,8 @@ std::string ieee_floatt::to_string_decimal(std::size_t precision) const return result; } -/*******************************************************************\ - -Function: ieee_floatt::to_string_scientific - - Inputs: - - Outputs: - - Purpose: format as [-]d.ddde+-d - Note that printf always produces at least two digits - for the exponent. - -\*******************************************************************/ - +/// format as [-]d.ddde+-d Note that printf always produces at least two digits +/// for the exponent. std::string ieee_floatt::to_string_scientific(std::size_t precision) const { std::string result; @@ -407,7 +300,7 @@ std::string ieee_floatt::to_string_scientific(std::size_t precision) const std::string exponent_str= integer2string(base10_digits(_fraction)+_exponent-1); - if(exponent_str.size()>0 && exponent_str[0]!='-') + if(!exponent_str.empty() && exponent_str[0]!='-') result+='+'; result+=exponent_str; @@ -416,18 +309,6 @@ std::string ieee_floatt::to_string_scientific(std::size_t precision) const return result; } -/*******************************************************************\ - -Function: ieee_floatt::unpack - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ieee_floatt::unpack(const mp_integer &i) { assert(spec.f!=0); @@ -478,35 +359,11 @@ void ieee_floatt::unpack(const mp_integer &i) } } -/*******************************************************************\ - -Function: ieee_floatt::is_normal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool ieee_floatt::is_normal() const { return fraction>=power(2, spec.f); } -/*******************************************************************\ - -Function: ieee_floatt::pack - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - mp_integer ieee_floatt::pack() const { mp_integer result=0; @@ -545,18 +402,6 @@ mp_integer ieee_floatt::pack() const return result; } -/*******************************************************************\ - -Function: ieee_floatt::extract_base2 - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ieee_floatt::extract_base2( mp_integer &_fraction, mp_integer &_exponent) const @@ -581,18 +426,6 @@ void ieee_floatt::extract_base2( } } -/*******************************************************************\ - -Function: ieee_floatt::extract_base10 - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ieee_floatt::extract_base10( mp_integer &_fraction, mp_integer &_exponent) const @@ -629,18 +462,6 @@ void ieee_floatt::extract_base10( } } -/*******************************************************************\ - -Function: ieee_floatt::build - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ieee_floatt::build( const mp_integer &_fraction, const mp_integer &_exponent) @@ -654,18 +475,7 @@ void ieee_floatt::build( align(); } -/*******************************************************************\ - -Function: ieee_floatt::from_base10 - - Inputs: - - Outputs: - - Purpose: compute f * (10^e) - -\*******************************************************************/ - +/// compute f * (10^e) void ieee_floatt::from_base10( const mp_integer &_fraction, const mp_integer &_exponent) @@ -695,18 +505,6 @@ void ieee_floatt::from_base10( align(); } -/*******************************************************************\ - -Function: ieee_floatt::from_integer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ieee_floatt::from_integer(const mp_integer &i) { NaN_flag=infinity_flag=sign_flag=false; @@ -715,18 +513,6 @@ void ieee_floatt::from_integer(const mp_integer &i) align(); } -/*******************************************************************\ - -Function: ieee_floatt::align - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ieee_floatt::align() { // NaN? @@ -847,18 +633,6 @@ void ieee_floatt::align() exponent=0; } -/*******************************************************************\ - -Function: ieee_floatt::divide_and_round - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ieee_floatt::divide_and_round( mp_integer &fraction, const mp_integer &factor) @@ -909,18 +683,6 @@ void ieee_floatt::divide_and_round( } } -/*******************************************************************\ - -Function: ieee_floatt::to_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - constant_exprt ieee_floatt::to_expr() const { constant_exprt result(spec.to_type()); @@ -928,18 +690,6 @@ constant_exprt ieee_floatt::to_expr() const return result; } -/*******************************************************************\ - -Function: operator /= - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - ieee_floatt &ieee_floatt::operator/=(const ieee_floatt &other) { assert(other.spec.f==spec.f); @@ -1014,18 +764,6 @@ ieee_floatt &ieee_floatt::operator/=(const ieee_floatt &other) return *this; } -/*******************************************************************\ - -Function: operator *= - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - ieee_floatt &ieee_floatt::operator*=(const ieee_floatt &other) { assert(other.spec.f==spec.f); @@ -1062,18 +800,6 @@ ieee_floatt &ieee_floatt::operator*=(const ieee_floatt &other) return *this; } -/*******************************************************************\ - -Function: operator += - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - ieee_floatt &ieee_floatt::operator+=(const ieee_floatt &other) { ieee_floatt _other=other; @@ -1163,18 +889,6 @@ ieee_floatt &ieee_floatt::operator+=(const ieee_floatt &other) return *this; } -/*******************************************************************\ - -Function: operator -= - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - ieee_floatt &ieee_floatt::operator-=(const ieee_floatt &other) { ieee_floatt _other=other; @@ -1182,18 +896,6 @@ ieee_floatt &ieee_floatt::operator-=(const ieee_floatt &other) return (*this)+=_other; } -/*******************************************************************\ - -Function: ieee_floatt::operator< - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool ieee_floatt::operator<(const ieee_floatt &other) const { if(NaN_flag || other.NaN_flag) @@ -1240,18 +942,6 @@ bool ieee_floatt::operator<(const ieee_floatt &other) const return fraction - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool ieee_floatt::operator>(const ieee_floatt &other) const { return other<*this; } -/*******************************************************************\ - -Function: ieee_floatt::operator>= - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool ieee_floatt::operator>=(const ieee_floatt &other) const { return other<=*this; } -/*******************************************************************\ - -Function: ieee_floatt::operator== - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool ieee_floatt::operator==(const ieee_floatt &other) const { // packed equality! @@ -1343,18 +997,6 @@ bool ieee_floatt::operator==(const ieee_floatt &other) const sign_flag==other.sign_flag; } -/*******************************************************************\ - -Function: ieee_floatt::ieee_equal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool ieee_floatt::ieee_equal(const ieee_floatt &other) const { if(NaN_flag || other.NaN_flag) @@ -1365,18 +1007,6 @@ bool ieee_floatt::ieee_equal(const ieee_floatt &other) const return *this==other; } -/*******************************************************************\ - -Function: ieee_floatt::operator== - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool ieee_floatt::operator==(int i) const { ieee_floatt other(spec); @@ -1384,35 +1014,11 @@ bool ieee_floatt::operator==(int i) const return *this==other; } -/*******************************************************************\ - -Function: ieee_floatt::operator!= - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool ieee_floatt::operator!=(const ieee_floatt &other) const { return !(*this==other); } -/*******************************************************************\ - -Function: ieee_floatt::ieee_not_equal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool ieee_floatt::ieee_not_equal(const ieee_floatt &other) const { if(NaN_flag || other.NaN_flag) @@ -1423,18 +1029,6 @@ bool ieee_floatt::ieee_not_equal(const ieee_floatt &other) const return *this!=other; } -/*******************************************************************\ - -Function: ieee_floatt::change_spec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ieee_floatt::change_spec(const ieee_float_spect &dest_spec) { mp_integer _exponent=exponent-spec.f; @@ -1454,36 +1048,12 @@ void ieee_floatt::change_spec(const ieee_float_spect &dest_spec) build(_fraction, _exponent); } -/*******************************************************************\ - -Function: ieee_floatt::from_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ieee_floatt::from_expr(const constant_exprt &expr) { spec=ieee_float_spect(to_floatbv_type(expr.type())); unpack(binary2integer(id2string(expr.get_value()), false)); } -/*******************************************************************\ - -Function: ieee_floatt::to_integer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - mp_integer ieee_floatt::to_integer() const { if(NaN_flag || infinity_flag || is_zero()) @@ -1505,18 +1075,6 @@ mp_integer ieee_floatt::to_integer() const return result; } -/*******************************************************************\ - -Function: ieee_floatt::from_double - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ieee_floatt::from_double(const double d) { spec.f=52; @@ -1537,18 +1095,6 @@ void ieee_floatt::from_double(const double d) unpack(u.i); } -/*******************************************************************\ - -Function: ieee_floatt::from_float - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ieee_floatt::from_float(const float f) { spec.f=23; @@ -1568,18 +1114,6 @@ void ieee_floatt::from_float(const float f) unpack(u.i); } -/*******************************************************************\ - -Function: ieee_floatt::make_NaN - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ieee_floatt::make_NaN() { NaN_flag=true; @@ -1589,18 +1123,6 @@ void ieee_floatt::make_NaN() infinity_flag=false; } -/*******************************************************************\ - -Function: ieee_floatt::make_fltmax - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ieee_floatt::make_fltmax() { mp_integer bit_pattern= @@ -1608,35 +1130,11 @@ void ieee_floatt::make_fltmax() unpack(bit_pattern); } -/*******************************************************************\ - -Function: ieee_floatt::make_fltmin - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ieee_floatt::make_fltmin() { unpack(power(2, spec.f)); } -/*******************************************************************\ - -Function: ieee_floatt::make_plus_infinity - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ieee_floatt::make_plus_infinity() { NaN_flag=false; @@ -1646,71 +1144,24 @@ void ieee_floatt::make_plus_infinity() infinity_flag=true; } -/*******************************************************************\ - -Function: ieee_floatt::make_minus_infinity - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ieee_floatt::make_minus_infinity() { make_plus_infinity(); sign_flag=true; } -/*******************************************************************\ - -Function: ieee_floatt::is_double - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool ieee_floatt::is_double() const { return spec.f==52 && spec.e==11; } -/*******************************************************************\ - -Function: ieee_floatt::is_float - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool ieee_floatt::is_float() const { return spec.f==23 && spec.e==8; } -/*******************************************************************\ - -Function: ieee_floatt::to_double - - Inputs: - - Outputs: - - Purpose: Note that calling from_double -> to_double can return different bit - patterns for NaN. - -\*******************************************************************/ - +/// Note that calling from_double -> to_double can return different bit patterns +/// for NaN. double ieee_floatt::to_double() const { union { double f; uint64_t i; } a; @@ -1738,19 +1189,8 @@ double ieee_floatt::to_double() const return a.f; } -/*******************************************************************\ - -Function: ieee_floatt::to_float - - Inputs: - - Outputs: - - Purpose: Note that calling from_float -> to_float can return different bit - patterns for NaN. - -\*******************************************************************/ - +/// Note that calling from_float -> to_float can return different bit patterns +/// for NaN. float ieee_floatt::to_float() const { if(sizeof(unsigned)!=sizeof(float)) @@ -1783,20 +1223,8 @@ float ieee_floatt::to_float() const return a.f; } -/*******************************************************************\ - -Function: ieee_floatt::next_representable - - Inputs: - - Outputs: - - Purpose: Sets *this to the next representable number closer to - plus infinity (greater = true) or minus infinity - (greater = false). - -\*******************************************************************/ - +/// Sets *this to the next representable number closer to plus infinity (greater +/// = true) or minus infinity (greater = false). void ieee_floatt::next_representable(bool greater) { if(is_NaN()) @@ -1838,6 +1266,6 @@ void ieee_floatt::next_representable(bool greater) unpack(old); - // sign change impossible (zero case caught earler) + // sign change impossible (zero case caught earlier) set_sign(old_sign); } diff --git a/src/util/ieee_float.h b/src/util/ieee_float.h index 20239cd92aa..5c975f3782e 100644 --- a/src/util/ieee_float.h +++ b/src/util/ieee_float.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_IEEE_FLOAT_H #define CPROVER_UTIL_IEEE_FLOAT_H @@ -110,12 +111,12 @@ class ieee_floatt // ROUND_TO_EVEN is also known as "round to nearest, ties to even", and // is the IEEE default. // The numbering below is what x86 uses in the control word. - typedef enum + enum rounding_modet { ROUND_TO_EVEN=0, ROUND_TO_MINUS_INF=1, ROUND_TO_PLUS_INF=2, ROUND_TO_ZERO=3, UNKNOWN, NONDETERMINISTIC - } rounding_modet; + }; rounding_modet rounding_mode; @@ -237,7 +238,7 @@ class ieee_floatt void from_double(const double d); void from_float(const float f); - // perfroms conversions from IEEE float-point format + // performs conversions from IEEE float-point format // to something else double to_double() const; float to_float() const; @@ -267,7 +268,7 @@ class ieee_floatt constant_exprt to_expr() const; void from_expr(const constant_exprt &expr); - // the usual opertors + // the usual operators ieee_floatt &operator/=(const ieee_floatt &other); ieee_floatt &operator*=(const ieee_floatt &other); ieee_floatt &operator+=(const ieee_floatt &other); diff --git a/src/util/infix.h b/src/util/infix.h index 2fcc1338d5d..0ff47c646c1 100644 --- a/src/util/infix.h +++ b/src/util/infix.h @@ -6,6 +6,9 @@ Author: Chris Smowton, chris.smowton@diffblue.com \*******************************************************************/ +/// \file +/// String infix shorthand + #ifndef CPROVER_UTIL_INFIX_H #define CPROVER_UTIL_INFIX_H diff --git a/src/util/invariant.cpp b/src/util/invariant.cpp new file mode 100644 index 00000000000..d3f750041a3 --- /dev/null +++ b/src/util/invariant.cpp @@ -0,0 +1,135 @@ +/*******************************************************************\ + +Module: + +Author: Martin Brain, martin.brain@diffblue.com + +\*******************************************************************/ + + +#include "invariant.h" + +#include +#include + +#include + +// Backtraces compiler and C library specific +// So we should include something explicitly from the C library +// to check if the C library is glibc. +#include +#ifdef __GLIBC__ + +// GCC needs LINKFLAGS="-rdynamic" to give function names in the backtrace +#include +#include + + +/// Attempts to demangle the function name assuming the glibc +/// format of stack entry: +/// +/// path '(' mangled_name '+' offset ') [' address ']\0' +/// +/// \param out: The output stream +/// \param stack_entry: Description of the stack_entry +/// +/// \return True <=> the entry has been successfully demangled and printed. +static bool output_demangled_name( + std::ostream &out, + const std::string &stack_entry) +{ + bool return_value=false; + + std::string working(stack_entry); + + std::string::size_type start=working.rfind('('); // Path may contain '(' ! + std::string::size_type end=working.find('+', start); + + if(start!=std::string::npos && + end!=std::string::npos && + start+1<=end-1) + { + std::string::size_type length=end-(start+1); + std::string mangled(working.substr(start+1, length)); + + int demangle_success=1; + char *demangled= + abi::__cxa_demangle(mangled.c_str(), nullptr, nullptr, &demangle_success); + + if(demangle_success==0) + { + out << working.substr(0, start+1) + << demangled + << working.substr(end); + return_value=true; + } + + free(demangled); + } + + return return_value; +} +#endif + + +/// Prints a back trace to 'out' +/// \param out: Stream to print backtrace +void print_backtrace( + std::ostream &out) +{ +#ifdef __GLIBC__ + out << "Backtrace\n" << std::flush; + + void * stack[50] = {}; + + std::size_t entries=backtrace(stack, sizeof(stack) / sizeof(void *)); + char **description=backtrace_symbols(stack, entries); + + for(std::size_t i=0; i +#include +#include +#include + +/* +** Invariants document conditions that the programmer believes to +** be always true as a consequence of the system architecture and / or +** preceeding code. In principle it should be possible to (machine +** checked) verify them. The condition should be side-effect free and +** evaluate to a boolean. +** +** As well as the condition they have a text argument that should be +** used to say why they are true. The reason should be a string literals. +** Longer diagnostics should be output to error(). For example: +** +** INVARIANT(x > 0, "x negative and zero case handled by other branches"); +** +** To help classify different kinds of invariants, various short-hand +** macros are provided. +** +** Invariants are used to document and check design / implementation +** knowledge. They should *not* be used: +** - to validate user input or options +** (throw an exception or handle more gracefully) +** - to log information (use debug(), progress(), etc.) +** - as TODO notes (acceptable in private repositories but fix before PR) +** - to handle cases that are unlikely, tedious or expensive (ditto) +** - to modify the state of the system (i.e. no side effects) +** +** Invariants provide the following guarantee: +** IF the condition is false +** THEN an invariant_failed exception will be thrown +** OR there will be undefined behaviour +** +** Consequentally, programmers may assume that the condition of an +** invariant is true after it has been executed. Applications are +** encouraged to (at least) catch exceptions at the top level and +** output them. +** +** Various different approaches to checking (or not) the invariants +** and handling their failure are supported and can be configured with +** CPROVER_INVARIANT_* macros. +*/ + +/// A logic error, augmented with a distinguished field to hold a backtrace. +/// Classes that extend this one should share the same initial constructor +/// parameters: their constructor signature should be of the form: +/// my_invariantt::my_invariantt( +/// const std::string &file, +/// const std::string &function, +/// int line, +/// const std::string &backtrace, +/// T1 arg1, +/// T2 arg2 ... +/// Tn argn) +/// It should pretty-print the T1 ... Tn arguments and pass it as `reason` to +/// invariant_failedt's constructor, or else simply pass a reason string +/// through. +/// Conforming to this pattern allows the class to be used with the INVARIANT +/// family of macros, allowing constructs like +/// `INVARIANT(x==y, my_invariantt, (T1)actual1, (T2)actual2, ...)` +/// +class invariant_failedt: public std::logic_error +{ + private: + std::string get_invariant_failed_message( + const std::string &file, + const std::string &function, + int line, + const std::string &backtrace, + const std::string &reason); + + public: + + const std::string file; + const std::string function; + const int line; + const std::string backtrace; + const std::string reason; + + invariant_failedt( + const std::string &_file, + const std::string &_function, + int _line, + const std::string &_backtrace, + const std::string &_reason): + logic_error( + get_invariant_failed_message( + _file, + _function, + _line, + _backtrace, + _reason)), + file(_file), + function(_function), + line(_line), + backtrace(_backtrace), + reason(_reason) + { + } +}; + +#if defined(CPROVER_INVARIANT_CPROVER_ASSERT) +// Used to allow CPROVER to check itself +#define INVARIANT(CONDITION, REASON) \ + __CPROVER_assert((CONDITION), "Invariant : " REASON) + + +#elif defined(CPROVER_INVARIANT_DO_NOT_CHECK) +// For performance builds, invariants can be ignored +// This is *not* recommended as it can result in unpredictable behaviour +// including silently reporting incorrect results. +// This is also useful for checking side-effect freedom. +#define INVARIANT(CONDITION, REASON, ...) do {} while(0) + +#elif defined(CPROVER_INVARIANT_ASSERT) +// Not recommended but provided for backwards compatability +#include +// NOLINTNEXTLINE(*) +#define INVARIANT(CONDITION, REASON, ...) assert((CONDITION) && ((REASON), true)) + +#else + +void print_backtrace(std::ostream &out); + +std::string get_backtrace(); + +void report_exception_to_stderr(const invariant_failedt &); + +/// Takes a backtrace, gives it to the reason structure, then aborts, printing +/// reason.what() (which therefore includes the backtrace). +/// In future this may throw `reason` instead of aborting. +/// \param ET : (template type parameter), type of exception to construct +/// \param file : C string giving the name of the file. +/// \param function : C string giving the name of the function. +/// \param line : The line number of the invariant +/// \param params : (variadic) parameters to forward to ET's constructor +/// its backtrace member will be set before it is used. +template +#ifdef __GNUC__ +__attribute__((noreturn)) +#endif +typename std::enable_if::value>::type +invariant_violated_structured( + const std::string &file, + const std::string &function, + const int line, + Params &&... params) +{ + std::string backtrace=get_backtrace(); + ET to_throw(file, function, line, backtrace, std::forward(params)...); + // We now have a structured exception ready to use; + // in future this is the place to put a 'throw'. + report_exception_to_stderr(to_throw); + abort(); +} + +/// Takes a backtrace, constructs an invariant_violatedt from reason and the +/// backtrace, aborts printing the invariant's description. +/// In future this may throw rather than aborting. +/// \param file : C string giving the name of the file. +/// \param function : C string giving the name of the function. +/// \param line : The line number of the invariant +/// \param reason : brief description of the invariant violation. +#ifdef __GNUC__ +__attribute__((noreturn)) +#endif +inline void invariant_violated_string( + const std::string &file, + const std::string &function, + const int line, + const std::string &reason) +{ + invariant_violated_structured( + file, + function, + line, + reason); +} + +// These require a trailing semicolon by the user, such that INVARIANT +// behaves syntactically like a function call. +// NOLINT as macro definitions confuse the linter it seems. +#ifdef _MSC_VER +#define __this_function__ __FUNCTION__ +#else +#define __this_function__ __func__ +#endif + +#define INVARIANT(CONDITION, REASON) \ + do /* NOLINT */ \ + { \ + if(!(CONDITION)) \ + invariant_violated_string(__FILE__, __this_function__, __LINE__, (REASON)); /* NOLINT */ \ + } while(0) + +#define INVARIANT_STRUCTURED(CONDITION, TYPENAME, ...) \ + do /* NOLINT */ \ + { \ + if(!(CONDITION)) \ + invariant_violated_structured(__FILE__, __this_function__, __LINE__, __VA_ARGS__); /* NOLINT */ \ + } while(0) + +#endif // End CPROVER_DO_NOT_CHECK / CPROVER_ASSERT / ... if block + +// Short hand macros. The second variant of each one permits including an +// explanation or structured exception, in which case they are synonyms +// for INVARIANT. + +// The condition should only contain (unmodified) arguments to the method. +// "The design of the system means that the arguments to this method +// will always meet this condition". +#define PRECONDITION(CONDITION) INVARIANT(CONDITION, "Precondition") +#define PRECONDITION_STRUCTURED(CONDITION, TYPENAME, ...) \ + INVARIANT_STRUCTURED(CONDITION, TYPENAME, __VA_ARGS__) + +// The condition should only contain variables that will be returned / +// output without further modification. +// "The implementation of this method means that the condition will hold". +#define POSTCONDITION(CONDITION) INVARIANT(CONDITION, "Postcondition") +#define POSTCONDITION_STRUCTURED(CONDITION, TYPENAME, ...) \ + INVARIANT_STRUCTURED(CONDITION, TYPENAME, __VA_ARGS__) + +// The condition should only contain (unmodified) values that were +// changed by a previous method call. +// "The contract of the previous method call means the following +// condition holds". +#define CHECK_RETURN(CONDITION) INVARIANT(CONDITION, "Check return value") +#define CHECK_RETURN_STRUCTURED(CONDITION, TYPENAME, ...) \ + INVARIANT_STRUCTURED(CONDITION, TYPENAME, __VA_ARGS__) + +// This should be used to mark dead code +#define UNREACHABLE INVARIANT(false, "Unreachable") +#define UNREACHABLE_STRUCTURED(TYPENAME, ...) \ + INVARIANT_STRUCTURED(false, TYPENAME, __VA_ARGS__) + +// This condition should be used to document that assumptions that are +// made on goto_functions, goto_programs, exprts, etc. being well formed. +// "The data structure is corrupt or malformed" +#define DATA_INVARIANT(CONDITION, REASON) INVARIANT(CONDITION, REASON) +#define DATA_INVARIANT_STRUCTURED(CONDITION, TYPENAME, ...) \ + INVARIANT_STRUCTURED(CONDITION, TYPENAME, __VA_ARGS__) + +// Legacy annotations + +// The following should not be used in new code and are only intended +// to migrate documentation and "error handling" in older code +#define TODO INVARIANT(0, "Todo") +#define UNIMPLEMENTED INVARIANT(0, "Unimplemented") +#define UNHANDLED_CASE INVARIANT(0, "Unhandled case") + +#endif // CPROVER_UTIL_INVARIANT_H diff --git a/src/util/irep.cpp b/src/util/irep.cpp index 21480aadd8a..5a762cfdfc9 100644 --- a/src/util/irep.cpp +++ b/src/util/irep.cpp @@ -6,11 +6,15 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Internal Representation + +#include "irep.h" + #include +#include "invariant.h" #include "string2int.h" -#include "irep.h" #include "string_hash.h" #include "serializer.h" #include "irep_hash.h" @@ -29,18 +33,6 @@ irept nil_rep_storage; irept::dt irept::empty_d; #endif -/*******************************************************************\ - -Function: named_subt_lower_bound - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - #ifdef SUB_IS_LIST static inline bool named_subt_order( const std::pair &a, @@ -62,18 +54,6 @@ static inline irept::named_subt::iterator named_subt_lower_bound( } #endif -/*******************************************************************\ - -Function: get_nil_irep - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const irept &get_nil_irep() { if(nil_rep_storage.id().empty()) // initialized? @@ -81,23 +61,11 @@ const irept &get_nil_irep() return nil_rep_storage; } -/*******************************************************************\ - -Function: irept::detach - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - #ifdef SHARING void irept::detach() { #ifdef IREP_DEBUG - std::cout << "DETACH1: " << data << std::endl; + std::cout << "DETACH1: " << data << '\n'; #endif if(data==&empty_d) @@ -105,7 +73,7 @@ void irept::detach() data=new dt; #ifdef IREP_DEBUG - std::cout << "ALLOCATED " << data << std::endl; + std::cout << "ALLOCATED " << data << '\n'; #endif } else if(data->ref_count>1) @@ -114,33 +82,21 @@ void irept::detach() data=new dt(*old_data); #ifdef IREP_DEBUG - std::cout << "ALLOCATED " << data << std::endl; + std::cout << "ALLOCATED " << data << '\n'; #endif data->ref_count=1; remove_ref(old_data); } - assert(data->ref_count==1); + POSTCONDITION(data->ref_count==1); #ifdef IREP_DEBUG - std::cout << "DETACH2: " << data << std::endl; + std::cout << "DETACH2: " << data << '\n'; #endif } #endif -/*******************************************************************\ - -Function: irept::remove_ref - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - #ifdef SHARING void irept::remove_ref(dt *old_data) { @@ -151,19 +107,19 @@ void irept::remove_ref(dt *old_data) nonrecursive_destructor(old_data); #else - assert(old_data->ref_count!=0); + PRECONDITION(old_data->ref_count!=0); #ifdef IREP_DEBUG - std::cout << "R: " << old_data << " " << old_data->ref_count << std::endl; + std::cout << "R: " << old_data << " " << old_data->ref_count << '\n'; #endif old_data->ref_count--; if(old_data->ref_count==0) { #ifdef IREP_DEBUG - std::cout << "D: " << pretty() << std::endl; + std::cout << "D: " << pretty() << '\n'; std::cout << "DELETING " << old_data->data - << " " << old_data << std::endl; + << " " << old_data << '\n'; old_data->clear(); std::cout << "DEALLOCATING " << old_data << "\n"; #endif @@ -179,19 +135,8 @@ void irept::remove_ref(dt *old_data) } #endif -/*******************************************************************\ - -Function: irept::nonrecursive_destructor - - Inputs: - - Outputs: - - Purpose: Does the same as remove_ref, but - using an explicit stack instead of recursion. - -\*******************************************************************/ - +/// Does the same as remove_ref, but using an explicit stack instead of +/// recursion. #ifdef SHARING void irept::nonrecursive_destructor(dt *old_data) { @@ -204,7 +149,7 @@ void irept::nonrecursive_destructor(dt *old_data) if(d==&empty_d) continue; - assert(d->ref_count!=0); + INVARIANT(d->ref_count!=0, "All contents of the stack must be in use"); d->ref_count--; if(d->ref_count==0) @@ -248,18 +193,6 @@ void irept::nonrecursive_destructor(dt *old_data) } #endif -/*******************************************************************\ - -Function: irept::move_to_named_sub - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void irept::move_to_named_sub(const irep_namet &name, irept &irep) { #ifdef SHARING @@ -269,18 +202,6 @@ void irept::move_to_named_sub(const irep_namet &name, irept &irep) irep.clear(); } -/*******************************************************************\ - -Function: irept::move_to_sub - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void irept::move_to_sub(irept &irep) { #ifdef SHARING @@ -290,18 +211,6 @@ void irept::move_to_sub(irept &irep) get_sub().back().swap(irep); } -/*******************************************************************\ - -Function: irept::get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const irep_idt &irept::get(const irep_namet &name) const { const named_subt &s= @@ -329,120 +238,36 @@ const irep_idt &irept::get(const irep_namet &name) const return it->second.id(); } -/*******************************************************************\ - -Function: irept::get_bool - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool irept::get_bool(const irep_namet &name) const { return get(name)==ID_1; } -/*******************************************************************\ - -Function: irept::get_int - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - int irept::get_int(const irep_namet &name) const { return unsafe_string2int(get_string(name)); } -/*******************************************************************\ - -Function: irept::get_unsigned_int - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - unsigned int irept::get_unsigned_int(const irep_namet &name) const { return unsafe_string2unsigned(get_string(name)); } -/*******************************************************************\ - -Function: irept::get_size_t - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::size_t irept::get_size_t(const irep_namet &name) const { return unsafe_string2size_t(get_string(name)); } -/*******************************************************************\ - -Function: irept::get_long_long - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - long long irept::get_long_long(const irep_namet &name) const { return unsafe_string2signedlonglong(get_string(name)); } -/*******************************************************************\ - -Function: irept::set - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void irept::set(const irep_namet &name, const long long value) { add(name).id(std::to_string(value)); } -/*******************************************************************\ - -Function: irept::remove - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void irept::remove(const irep_namet &name) { named_subt &s= @@ -458,18 +283,6 @@ void irept::remove(const irep_namet &name) #endif } -/*******************************************************************\ - -Function: irept::find - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const irept &irept::find(const irep_namet &name) const { const named_subt &s= @@ -491,18 +304,6 @@ const irept &irept::find(const irep_namet &name) const return it->second; } -/*******************************************************************\ - -Function: irept::add - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - irept &irept::add(const irep_namet &name) { named_subt &s= @@ -521,18 +322,6 @@ irept &irept::add(const irep_namet &name) #endif } -/*******************************************************************\ - -Function: irept::add - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - irept &irept::add(const irep_namet &name, const irept &irep) { named_subt &s= @@ -559,18 +348,6 @@ irept &irept::add(const irep_namet &name, const irept &irep) #endif } -/*******************************************************************\ - -Function: irept::operator== - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - #ifdef IREP_HASH_STATS unsigned long long irep_cmp_cnt=0; unsigned long long irep_cmp_ne_cnt=0; @@ -601,18 +378,6 @@ bool irept::operator==(const irept &other) const return true; } -/*******************************************************************\ - -Function: irept::full_eq - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool irept::full_eq(const irept &other) const { #ifdef SHARING @@ -662,18 +427,7 @@ bool irept::full_eq(const irept &other) const return true; } -/*******************************************************************\ - -Function: irept::ordering - - Inputs: - - Outputs: - - Purpose: defines ordering on the internal represenation - -\*******************************************************************/ - +/// defines ordering on the internal representation bool irept::ordering(const irept &other) const { return compare(other)<0; @@ -704,7 +458,8 @@ bool irept::ordering(const irept &other) const return false; } - assert(it1==X.sub.end() && it2==Y.sub.end()); + INVARIANT(it1==X.sub.end() && it2==Y.sub.end(), + "Unequal lengths will return before this"); } if(X.named_sub.size()0 && indent>max_indent) @@ -1005,19 +692,8 @@ std::string irept::pretty(unsigned indent, unsigned max_indent) const return result; } -/*******************************************************************\ - - Function: irept::serialize - - Inputs: - serializer: The serializer to read from/write to - - Outputs: - - Purpose: - Serializes this instance to/from the given serializer. - -\*******************************************************************/ +/// Serializes this instance to/from the given serializer. +/// \param serializer: The serializer to read from/write to void irept::serialize(serializert &serializer) { serializer.serialize("id", write().data); diff --git a/src/util/irep.h b/src/util/irep.h index 49ed9fb3070..c18b7121822 100644 --- a/src/util/irep.h +++ b/src/util/irep.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_IREP_H #define CPROVER_UTIL_IREP_H @@ -105,7 +106,10 @@ class irept bool is_nil() const { return id()==ID_nil; } bool is_not_nil() const { return id()!=ID_nil; } - explicit irept(const irep_idt &_id):data(&empty_d) + explicit irept(const irep_idt &_id) +#ifdef SHARING + :data(&empty_d) +#endif { id(_id); } @@ -124,7 +128,7 @@ class irept assert(data->ref_count!=0); data->ref_count++; #ifdef IREP_DEBUG - std::cout << "COPY " << data << " " << data->ref_count << std::endl; + std::cout << "COPY " << data << " " << data->ref_count << '\n'; #endif } } diff --git a/src/util/irep_hash.cpp b/src/util/irep_hash.cpp index 96a00a27595..a68776d00cd 100644 --- a/src/util/irep_hash.cpp +++ b/src/util/irep_hash.cpp @@ -6,4 +6,7 @@ Author: Michael Tautschnig, mt@eecs.qmul.ac.uk \*******************************************************************/ +/// \file +/// irep hash functions + #include "irep_hash.h" diff --git a/src/util/irep_hash.h b/src/util/irep_hash.h index b0d24221ff3..ce4ef52da76 100644 --- a/src/util/irep_hash.h +++ b/src/util/irep_hash.h @@ -6,6 +6,9 @@ Author: Michael Tautschnig, mt@eecs.qmul.ac.uk \*******************************************************************/ +/// \file +/// irep hash functions + #ifndef CPROVER_UTIL_IREP_HASH_H #define CPROVER_UTIL_IREP_HASH_H @@ -74,18 +77,6 @@ std::size_t basic_hash_combine( std::size_t h1, std::size_t h2); -/*******************************************************************\ - -Function: basic_hash_combine - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template<> inline std::size_t basic_hash_combine<32>( std::size_t h1, @@ -94,18 +85,6 @@ inline std::size_t basic_hash_combine<32>( return ROTL32(h1, 7)^h2; } -/*******************************************************************\ - -Function: basic_hash_combine - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template<> inline std::size_t basic_hash_combine<64>( std::size_t h1, @@ -127,18 +106,6 @@ inline std::size_t basic_hash_combine<64>( #endif } -/*******************************************************************\ - -Function: basic_hash_finalize - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - inline std::size_t basic_hash_finalize( std::size_t h1, std::size_t len) @@ -175,18 +142,6 @@ std::size_t murmurhash2a_hash_finalize( std::size_t h1, std::size_t len); -/*******************************************************************\ - -Function: murmurhash2a_hash_combine - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static FORCE_INLINE uint32_t mmix32(uint32_t h1, uint32_t h2) { const int r=24; @@ -209,18 +164,7 @@ inline std::size_t murmurhash2a_hash_combine<32>( return mmix32(h1, h2); } -/*******************************************************************\ - -Function: murmurhash2a_hash_finalize - - Inputs: - - Outputs: - - Purpose: force all bits of a hash block to avalanche - -\*******************************************************************/ - +/// force all bits of a hash block to avalanche template<> inline std::size_t murmurhash2a_hash_finalize<32>( std::size_t h1, @@ -237,18 +181,6 @@ inline std::size_t murmurhash2a_hash_finalize<32>( return h1; } -/*******************************************************************\ - -Function: murmurhash2a_hash_combine - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static FORCE_INLINE uint64_t mmix64(uint64_t h1, uint64_t h2) { const int r=47; @@ -273,18 +205,7 @@ inline std::size_t murmurhash2a_hash_combine<64>( return mmix64(h1, h2); } -/*******************************************************************\ - -Function: murmurhash2a_hash_finalize - - Inputs: - - Outputs: - - Purpose: force all bits of a hash block to avalanche - -\*******************************************************************/ - +/// force all bits of a hash block to avalanche template<> inline std::size_t murmurhash2a_hash_finalize<64>( std::size_t h1, @@ -328,18 +249,6 @@ std::size_t murmurhash3_hash_finalize( std::size_t h1, std::size_t len); -/*******************************************************************\ - -Function: murmurhash3_hash_combine - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template<> inline std::size_t murmurhash3_hash_combine<32>( std::size_t h1, @@ -359,18 +268,7 @@ inline std::size_t murmurhash3_hash_combine<32>( return h1; } -/*******************************************************************\ - -Function: murmurhash3_hash_finalize - - Inputs: - - Outputs: - - Purpose: force all bits of a hash block to avalanche - -\*******************************************************************/ - +/// force all bits of a hash block to avalanche static FORCE_INLINE uint32_t fmix32(uint32_t h) { h^=h>>16; @@ -392,18 +290,6 @@ inline std::size_t murmurhash3_hash_finalize<32>( return fmix32(h1); } -/*******************************************************************\ - -Function: murmurhash3_hash_combine - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - template<> inline std::size_t murmurhash3_hash_combine<64>( std::size_t h1, @@ -429,18 +315,7 @@ inline std::size_t murmurhash3_hash_combine<64>( return h1; } -/*******************************************************************\ - -Function: murmurhash3_hash_finalize - - Inputs: - - Outputs: - - Purpose: force all bits of a hash block to avalanche - -\*******************************************************************/ - +/// force all bits of a hash block to avalanche static FORCE_INLINE uint64_t fmix64(uint64_t h) { // a brief experiment with supposedly better constants from diff --git a/src/util/irep_hash_container.cpp b/src/util/irep_hash_container.cpp index 5d17b3d3f9f..c72d2315928 100644 --- a/src/util/irep_hash_container.cpp +++ b/src/util/irep_hash_container.cpp @@ -6,22 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Hashing IREPs + #include "irep_hash_container.h" + #include "irep.h" #include "irep_hash.h" -/*******************************************************************\ - -Function: irep_hash_container_baset::number - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - size_t irep_hash_container_baset::number(const irept &irep) { // the ptr-hash provides a speedup of up to 3x @@ -40,18 +32,6 @@ size_t irep_hash_container_baset::number(const irept &irep) return id; } -/*******************************************************************\ - -Function: irep_hash_container_baset::vector_hasht::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - size_t irep_hash_container_baset::vector_hasht::operator()( const packedt &p) const { @@ -61,18 +41,6 @@ size_t irep_hash_container_baset::vector_hasht::operator()( return result; } -/*******************************************************************\ - -Function: irep_hash_container_baset::pack - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void irep_hash_container_baset::pack( const irept &irep, packedt &packed) diff --git a/src/util/irep_hash_container.h b/src/util/irep_hash_container.h index 6edaaf0c21c..382130659e0 100644 --- a/src/util/irep_hash_container.h +++ b/src/util/irep_hash_container.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// IREP Hash Container + #ifndef CPROVER_UTIL_IREP_HASH_CONTAINER_H #define CPROVER_UTIL_IREP_HASH_CONTAINER_H diff --git a/src/util/irep_ids.cpp b/src/util/irep_ids.cpp index bb67b275f0a..50e0f537fa5 100644 --- a/src/util/irep_ids.cpp +++ b/src/util/irep_ids.cpp @@ -6,9 +6,13 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Internal Representation #include "irep_ids.h" + +#include + #include "string_container.h" const char *irep_ids_table[]= @@ -18,7 +22,7 @@ const char *irep_ids_table[]= #include "irep_ids.def" - NULL, + nullptr, }; #ifdef USE_DSTRING @@ -39,23 +43,11 @@ const char *irep_ids_table[]= #include "irep_ids.def" // NOLINT(build/include) -/*******************************************************************\ - -Function: initialize_string_container - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void initialize_string_container() { // this is called by the constructor of string_containert - for(unsigned i=0; irep_ids_table[i]!=NULL; i++) + for(unsigned i=0; irep_ids_table[i]!=nullptr; i++) { unsigned x; x=string_container[irep_ids_table[i]]; diff --git a/src/util/irep_ids.def b/src/util/irep_ids.def index 5410619deb3..90b7b46b7bf 100644 --- a/src/util/irep_ids.def +++ b/src/util/irep_ids.def @@ -748,6 +748,7 @@ IREP_ID_ONE(java_instanceof) IREP_ID_ONE(java_super_method_call) IREP_ID_ONE(java_enum_static_unwind) IREP_ID_ONE(push_catch) +IREP_ID_ONE(length_upper_bound) IREP_ID_ONE(string_constraint) IREP_ID_ONE(string_not_contains_constraint) IREP_ID_ONE(cprover_char_literal_func) @@ -811,6 +812,7 @@ IREP_ID_ONE(cprover_string_to_lower_case_func) IREP_ID_ONE(cprover_string_to_upper_case_func) IREP_ID_ONE(cprover_string_trim_func) IREP_ID_ONE(cprover_string_value_of_func) +IREP_ID_ONE(array_replace) IREP_ID_ONE(external_value_set) IREP_ID_ONE(access_path_entry) IREP_ID_ONE(access_path_label) diff --git a/src/util/irep_ids.h b/src/util/irep_ids.h index c456840ef5f..2202c95c62b 100644 --- a/src/util/irep_ids.h +++ b/src/util/irep_ids.h @@ -6,6 +6,9 @@ Author: Reuben Thomas, reuben.thomas@me.com \*******************************************************************/ +/// \file +/// util + #ifndef CPROVER_UTIL_IREP_IDS_H #define CPROVER_UTIL_IREP_IDS_H diff --git a/src/util/irep_serialization.cpp b/src/util/irep_serialization.cpp index 3d5734bbb43..92f975ef949 100644 --- a/src/util/irep_serialization.cpp +++ b/src/util/irep_serialization.cpp @@ -8,23 +8,15 @@ Date: May 2007 \*******************************************************************/ -#include -#include +/// \file +/// binary irep conversions with hashing #include "irep_serialization.h" -#include "string_hash.h" - -/*******************************************************************\ - -Function: irep_serializationt::write_irep - - Inputs: - Outputs: - - Purpose: +#include +#include -\*******************************************************************/ +#include "string_hash.h" void irep_serializationt::write_irep( std::ostream &out, @@ -55,28 +47,16 @@ void irep_serializationt::write_irep( out.put(0); // terminator } -/*******************************************************************\ - -Function: irep_serializationt::reference_convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void irep_serializationt::reference_convert( std::istream &in, irept &irep) { - std::size_t id = read_gb_word(in); + std::size_t id=read_gb_word(in); - if(id < ireps_container.ireps_on_read.size() && + if(id res= @@ -190,19 +137,10 @@ std::size_t irep_serializationt::insert_on_write(std::size_t h) return res.first->second; } -/*******************************************************************\ - -Function: irep_serializationt::insert_on_read - - Inputs: a size_t and an irep - - Outputs: true on success, false otherwise - - Purpose: inserts an irep into the hashtable, but only the id-hashtable - (only to be used upon reading ireps from a file) - -\*******************************************************************/ - +/// inserts an irep into the hashtable, but only the id-hashtable (only to be +/// used upon reading ireps from a file) +/// \par parameters: a size_t and an irep +/// \return true on success, false otherwise std::size_t irep_serializationt::insert_on_read( std::size_t id, const irept &i) @@ -222,19 +160,9 @@ std::size_t irep_serializationt::insert_on_read( return id; } -/*******************************************************************\ - -Function: write_gb_word - - Inputs: an output stream and a number - - Outputs: nothing - - Purpose: outputs 4 characters for a long, - most-significand byte first - -\*******************************************************************/ - +/// outputs 4 characters for a long, most-significant byte first +/// \par parameters: an output stream and a number +/// \return nothing void write_gb_word(std::ostream &out, std::size_t u) { // we write 7 bits each time, until we have zero @@ -254,18 +182,9 @@ void write_gb_word(std::ostream &out, std::size_t u) } } -/*******************************************************************\ - -Function: irep_serializationt::read_gb_word - - Inputs: a stream - - Outputs: a long - - Purpose: reads 4 characters and builds a long int from them - -\*******************************************************************/ - +/// reads 4 characters and builds a long int from them +/// \par parameters: a stream +/// \return a long std::size_t irep_serializationt::read_gb_word(std::istream &in) { std::size_t res=0; @@ -274,7 +193,7 @@ std::size_t irep_serializationt::read_gb_word(std::istream &in) while(in.good()) { - unsigned char ch=in.get(); + unsigned char ch=static_cast(in.get()); res|=(size_t(ch&0x7f))<(in.get()))!=0) { if(length>=read_buffer.size()) read_buffer.resize(read_buffer.size()*2, 0); if(c=='\\') // escaped chars - read_buffer[length] = in.get(); + read_buffer[length]=static_cast(in.get()); else - read_buffer[length] = c; + read_buffer[length]=c; length++; } @@ -343,18 +244,9 @@ irep_idt irep_serializationt::read_gb_string(std::istream &in) return irep_idt(std::string(read_buffer.data(), length)); } -/*******************************************************************\ - -Function: irep_serializationt::write_string_ref - - Inputs: an output stream and a string - - Outputs: nothing - - Purpose: outputs the string reference - -\*******************************************************************/ - +/// outputs the string reference +/// \par parameters: an output stream and a string +/// \return nothing void irep_serializationt::write_string_ref( std::ostream &out, const irep_idt &s) @@ -373,21 +265,12 @@ void irep_serializationt::write_string_ref( } } -/*******************************************************************\ - -Function: irep_serializationt::read_string_ref - - Inputs: a stream - - Outputs: a string - - Purpose: reads a string reference from the stream - -\*******************************************************************/ - +/// reads a string reference from the stream +/// \par parameters: a stream +/// \return a string irep_idt irep_serializationt::read_string_ref(std::istream &in) { - std::size_t id = read_gb_word(in); + std::size_t id=read_gb_word(in); if(id>=ireps_container.string_rev_map.size()) ireps_container.string_rev_map.resize(1+id*2, @@ -400,7 +283,7 @@ irep_idt irep_serializationt::read_string_ref(std::istream &in) else { irep_idt s=read_gb_string(in); - ireps_container.string_rev_map[id] = + ireps_container.string_rev_map[id]= std::pair(true, s); return ireps_container.string_rev_map[id].second; } diff --git a/src/util/irep_serialization.h b/src/util/irep_serialization.h index 715e042300d..6162826475a 100644 --- a/src/util/irep_serialization.h +++ b/src/util/irep_serialization.h @@ -8,6 +8,9 @@ Date: May 2007 \*******************************************************************/ +/// \file +/// binary irep conversions with hashing + #ifndef CPROVER_UTIL_IREP_SERIALIZATION_H #define CPROVER_UTIL_IREP_SERIALIZATION_H diff --git a/src/util/json.cpp b/src/util/json.cpp index 75a9b5d3f42..79352da4f7e 100644 --- a/src/util/json.cpp +++ b/src/util/json.cpp @@ -6,23 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "json.h" -const jsont jsont::null_json_object(jsont::J_NULL); - -/*******************************************************************\ - -Function: jsont::escape_string - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +const jsont jsont::null_json_object(jsont::kindt::J_NULL); void jsont::escape_string(const std::string &src, std::ostream &out) { @@ -62,33 +50,21 @@ void jsont::escape_string(const std::string &src, std::ostream &out) } } -/*******************************************************************\ - -Function: jsont::output_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsont::output_rec(std::ostream &out, unsigned indent) const { switch(kind) { - case J_STRING: + case kindt::J_STRING: out << '"'; escape_string(value, out); out << '"'; break; - case J_NUMBER: + case kindt::J_NUMBER: out << value; break; - case J_OBJECT: + case kindt::J_OBJECT: out << '{'; for(objectt::const_iterator o_it=object.begin(); o_it!=object.end(); @@ -115,7 +91,7 @@ void jsont::output_rec(std::ostream &out, unsigned indent) const out << '}'; break; - case J_ARRAY: + case kindt::J_ARRAY: out << '['; if(array.empty()) @@ -149,26 +125,14 @@ void jsont::output_rec(std::ostream &out, unsigned indent) const out << ']'; break; - case J_TRUE: out << "true"; break; + case kindt::J_TRUE: out << "true"; break; - case J_FALSE: out << "false"; break; + case kindt::J_FALSE: out << "false"; break; - case J_NULL: out << "null"; break; + case kindt::J_NULL: out << "null"; break; } } -/*******************************************************************\ - -Function: jsont::swap - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void jsont::swap(jsont &other) { std::swap(other.kind, kind); diff --git a/src/util/json.h b/src/util/json.h index c6ddd1b1d19..5095a3044df 100644 --- a/src/util/json.h +++ b/src/util/json.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_JSON_H #define CPROVER_UTIL_JSON_H @@ -20,46 +21,55 @@ class json_arrayt; class jsont { public: - typedef enum { J_STRING, J_NUMBER, J_OBJECT, J_ARRAY, - J_TRUE, J_FALSE, J_NULL } kindt; + enum class kindt + { + J_STRING, + J_NUMBER, + J_OBJECT, + J_ARRAY, + J_TRUE, + J_FALSE, + J_NULL + }; + kindt kind; bool is_string() const { - return kind==J_STRING; + return kind==kindt::J_STRING; } bool is_number() const { - return kind==J_NUMBER; + return kind==kindt::J_NUMBER; } bool is_object() const { - return kind==J_OBJECT; + return kind==kindt::J_OBJECT; } bool is_array() const { - return kind==J_ARRAY; + return kind==kindt::J_ARRAY; } bool is_true() const { - return kind==J_TRUE; + return kind==kindt::J_TRUE; } bool is_false() const { - return kind==J_FALSE; + return kind==kindt::J_FALSE; } bool is_null() const { - return kind==J_NULL; + return kind==kindt::J_NULL; } - jsont():kind(J_NULL) + jsont():kind(kindt::J_NULL) { } @@ -72,13 +82,13 @@ class jsont static jsont json_boolean(bool value) { - return jsont(value?J_TRUE:J_FALSE); + return jsont(value?kindt::J_TRUE:kindt::J_FALSE); } void clear() { value.clear(); - kind=J_NULL; + kind=kindt::J_NULL; object.clear(); array.clear(); } @@ -130,7 +140,7 @@ inline std::ostream &operator<<(std::ostream &out, const jsont &src) class json_arrayt:public jsont { public: - json_arrayt():jsont(J_ARRAY) + json_arrayt():jsont(kindt::J_ARRAY) { } @@ -161,7 +171,7 @@ class json_stringt:public jsont { public: explicit json_stringt(const std::string &_value): - jsont(J_STRING, _value) + jsont(kindt::J_STRING, _value) { } }; @@ -170,7 +180,7 @@ class json_numbert:public jsont { public: explicit json_numbert(const std::string &_value): - jsont(J_NUMBER, _value) + jsont(kindt::J_NUMBER, _value) { } }; @@ -178,7 +188,7 @@ class json_numbert:public jsont class json_objectt:public jsont { public: - json_objectt():jsont(J_OBJECT) + json_objectt():jsont(kindt::J_OBJECT) { } @@ -200,30 +210,30 @@ class json_objectt:public jsont class json_truet:public jsont { public: - json_truet():jsont(J_TRUE) { } + json_truet():jsont(kindt::J_TRUE) { } }; class json_falset:public jsont { public: - json_falset():jsont(J_FALSE) { } + json_falset():jsont(kindt::J_FALSE) { } }; class json_nullt:public jsont { public: - json_nullt():jsont(J_NULL) { } + json_nullt():jsont(kindt::J_NULL) { } }; inline json_arrayt &jsont::make_array() { - kind=J_ARRAY; + kind=kindt::J_ARRAY; return static_cast(*this); } inline json_objectt &jsont::make_object() { - kind=J_OBJECT; + kind=kindt::J_OBJECT; return static_cast(*this); } diff --git a/src/util/json_expr.cpp b/src/util/json_expr.cpp index 77f58eb0e18..43f12ee82b9 100644 --- a/src/util/json_expr.cpp +++ b/src/util/json_expr.cpp @@ -6,6 +6,11 @@ Author: Peter Schrammel \*******************************************************************/ +/// \file +/// Expressions in JSON + +#include "json_expr.h" + #include "namespace.h" #include "expr.h" #include "json.h" @@ -15,20 +20,6 @@ Author: Peter Schrammel #include "std_expr.h" #include "config.h" -#include "json_expr.h" - -/*******************************************************************\ - -Function: json - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - json_objectt json(const source_locationt &location) { json_objectt result; @@ -52,18 +43,6 @@ json_objectt json(const source_locationt &location) return result; } -/*******************************************************************\ - -Function: json - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - json_objectt json( const typet &type, const namespacet &ns) @@ -165,18 +144,6 @@ json_objectt json( return result; } -/*******************************************************************\ - -Function: json - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - json_objectt json( const exprt &expr, const namespacet &ns) diff --git a/src/util/json_expr.h b/src/util/json_expr.h index 702ad74ac59..28a6f3de102 100644 --- a/src/util/json_expr.h +++ b/src/util/json_expr.h @@ -6,6 +6,9 @@ Author: Peter Schrammel \*******************************************************************/ +/// \file +/// Expressions in JSON + #ifndef CPROVER_UTIL_JSON_EXPR_H #define CPROVER_UTIL_JSON_EXPR_H diff --git a/src/util/json_irep.cpp b/src/util/json_irep.cpp index 2740228d1db..c091b227335 100644 --- a/src/util/json_irep.cpp +++ b/src/util/json_irep.cpp @@ -6,46 +6,28 @@ Author: Thomas Kiley, thomas.kiley@diffblue.com \*******************************************************************/ +/// \file +/// Util + +#include "json_irep.h" + #include "irep.h" #include "json.h" -#include "json_irep.h" #include -/*******************************************************************\ - -Function: json_irept::json_irept - - Inputs: - include_comments - when writing JSON, should the comments - sub tree be included. - - Outputs: - - Purpose: To convert to JSON from an irep structure by recurssively - generating JSON for the different sub trees. - -\*******************************************************************/ - +/// To convert to JSON from an irep structure by recursively generating JSON +/// for the different sub trees. +/// \param include_comments: when writing JSON, should the comments +/// sub tree be included. json_irept::json_irept(bool include_comments): include_comments(include_comments) {} -/*******************************************************************\ - -Function: json_irept::convert_from_irep - - Inputs: - irep - The irep structure to turn into json - json - The json object to be filled up. - - Outputs: - - Purpose: To convert to JSON from an irep structure by recurssively - generating JSON for the different sub trees. - -\*******************************************************************/ - +/// To convert to JSON from an irep structure by recursively generating JSON +/// for the different sub trees. +/// \param irep: The irep structure to turn into json +/// \param json: The json object to be filled up. void json_irept::convert_from_irep(const irept &irep, jsont &json) const { json_objectt &irep_object=json.make_object(); @@ -60,30 +42,18 @@ void json_irept::convert_from_irep(const irept &irep, jsont &json) const } } -/*******************************************************************\ - -Function: json_irept::convert_sub_tree - - Inputs: - sub_tree_id - the name to give the subtree in the parent object - sub_trees - the list of subtrees to parse - parent - the parent JSON object who should be added to - - Outputs: - - Purpose: To convert to JSON from a list of ireps that are in an - unlabelled subtree. The parent JSON object will get a key - called sub_tree_id and the value shall be an array of JSON - objects generated from each of the sub trees - -\*******************************************************************/ - +/// To convert to JSON from a list of ireps that are in an unlabelled subtree. +/// The parent JSON object will get a key called sub_tree_id and the value shall +/// be an array of JSON objects generated from each of the sub trees +/// \param sub_tree_id: the name to give the subtree in the parent object +/// \param sub_trees: the list of subtrees to parse +/// \param parent: the parent JSON object who should be added to void json_irept::convert_sub_tree( const std::string &sub_tree_id, const irept::subt &sub_trees, json_objectt &parent) const { - if(sub_trees.size()>0) + if(!sub_trees.empty()) { json_arrayt sub_objects; for(const irept &sub_tree : sub_trees) @@ -96,31 +66,19 @@ void json_irept::convert_sub_tree( } } -/*******************************************************************\ - -Function: json_irept::convert_named_sub_tree - - Inputs: - sub_tree_id - the name to give the subtree in the parent object - sub_trees - the map of subtrees to parse - parent - the parent JSON object who should be added to - - Outputs: - - Purpose: To convert to JSON from a map of ireps that are in a - named subtree. The parent JSON object will get a key - called sub_tree_id and the value shall be a JSON object - whose keys shall be the name of the sub tree and the value - will be the object generated from the sub tree. - -\*******************************************************************/ - +/// To convert to JSON from a map of ireps that are in a named subtree. The +/// parent JSON object will get a key called sub_tree_id and the value shall be +/// a JSON object whose keys shall be the name of the sub tree and the value +/// will be the object generated from the sub tree. +/// \param sub_tree_id: the name to give the subtree in the parent object +/// \param sub_trees: the map of subtrees to parse +/// \param parent: the parent JSON object who should be added to void json_irept::convert_named_sub_tree( const std::string &sub_tree_id, const irept::named_subt &sub_trees, json_objectt &parent) const { - if(sub_trees.size()>0) + if(!sub_trees.empty()) { json_objectt sub_objects; for(const auto &sub_tree : sub_trees) @@ -133,18 +91,9 @@ void json_irept::convert_named_sub_tree( } } -/*******************************************************************\ - -Function: json_irept::convert_from_json - - Inputs: input - json object to convert - - Outputs: result - irep equivalent of input - - Purpose: Deserialize a JSON irep representation. - -\*******************************************************************/ - +/// Deserialize a JSON irep representation. +/// \param input: json object to convert +/// \return result - irep equivalent of input void json_irept::convert_from_json(const jsont &in, irept &out) const { std::vector have_keys; diff --git a/src/util/json_irep.h b/src/util/json_irep.h index 20a364d31e9..83c8a6902d8 100644 --- a/src/util/json_irep.h +++ b/src/util/json_irep.h @@ -6,6 +6,9 @@ Author: Thomas Kiley, thomas.kiley@diffblue.com \*******************************************************************/ +/// \file +/// Util + #ifndef CPROVER_UTIL_JSON_IREP_H #define CPROVER_UTIL_JSON_IREP_H diff --git a/src/util/language.cpp b/src/util/language.cpp index 937df8b8a92..fec2ba03d1d 100644 --- a/src/util/language.cpp +++ b/src/util/language.cpp @@ -6,73 +6,29 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "language.h" -#include "expr.h" - -/*******************************************************************\ - -Function: languaget::final - - Inputs: - - Outputs: +/// \file +/// Abstract interface to support a programming language - Purpose: +#include "language.h" -\*******************************************************************/ +#include "expr.h" bool languaget::final(symbol_tablet &symbol_table, bool generate_start_function) { return false; } -/*******************************************************************\ - -Function: languaget::interfaces - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool languaget::interfaces(symbol_tablet &symbol_table) { return false; } -/*******************************************************************\ - -Function: languaget::dependencies - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void languaget::dependencies( const std::string &module, std::set &modules) { } -/*******************************************************************\ - -Function: languaget::from_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool languaget::from_expr( const exprt &expr, std::string &code, @@ -82,18 +38,6 @@ bool languaget::from_expr( return false; } -/*******************************************************************\ - -Function: languaget::from_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool languaget::from_type( const typet &type, std::string &code, @@ -103,18 +47,6 @@ bool languaget::from_type( return false; } -/*******************************************************************\ - -Function: languaget::type_to_name - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool languaget::type_to_name( const typet &type, std::string &name, diff --git a/src/util/language.h b/src/util/language.h index cc5929d6e21..c8c7756a126 100644 --- a/src/util/language.h +++ b/src/util/language.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Abstract interface to support a programming language + #ifndef CPROVER_UTIL_LANGUAGE_H #define CPROVER_UTIL_LANGUAGE_H diff --git a/src/util/language_file.cpp b/src/util/language_file.cpp index b8f0b779502..856435107df 100644 --- a/src/util/language_file.cpp +++ b/src/util/language_file.cpp @@ -6,60 +6,25 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - -#include "language.h" #include "language_file.h" -/*******************************************************************\ - -Function: language_filet::language_filet - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include "language.h" language_filet::language_filet(const language_filet &rhs): modules(rhs.modules), - language(rhs.language==NULL?NULL:rhs.language->new_language()), + language(rhs.language==nullptr?nullptr:rhs.language->new_language()), filename(rhs.filename) { } -/*******************************************************************\ - -Function: language_filet::~language_filet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - language_filet::~language_filet() { - if(language!=NULL) + if(language!=nullptr) delete language; } -/*******************************************************************\ - -Function: language_filet::get_modules - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void language_filet::get_modules() { language->modules_provided(modules); @@ -72,18 +37,6 @@ void language_filet::convert_lazy_method( language->convert_lazy_method(id, symbol_table); } -/*******************************************************************\ - -Function: language_filest::show_parse - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void language_filest::show_parse(std::ostream &out) { for(file_mapt::iterator it=file_map.begin(); @@ -91,18 +44,6 @@ void language_filest::show_parse(std::ostream &out) it->second.language->show_parse(out); } -/*******************************************************************\ - -Function: language_filest::parse - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool language_filest::parse() { for(file_mapt::iterator it=file_map.begin(); @@ -136,18 +77,6 @@ bool language_filest::parse() return false; } -/*******************************************************************\ - -Function: language_filest::typecheck - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool language_filest::typecheck(symbol_tablet &symbol_table) { // typecheck interfaces @@ -222,18 +151,6 @@ bool language_filest::typecheck(symbol_tablet &symbol_table) return false; } -/*******************************************************************\ - -Function: language_filest::final - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool language_filest::final( symbol_tablet &symbol_table, bool generate_start_function) @@ -251,18 +168,6 @@ bool language_filest::final( return false; } -/*******************************************************************\ - -Function: language_filest::interfaces - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool language_filest::interfaces( symbol_tablet &symbol_table) { @@ -276,18 +181,6 @@ bool language_filest::interfaces( return false; } -/*******************************************************************\ - -Function: language_filest::typecheck_module - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool language_filest::typecheck_module( symbol_tablet &symbol_table, const std::string &module) @@ -305,18 +198,6 @@ bool language_filest::typecheck_module( return typecheck_module(symbol_table, it->second); } -/*******************************************************************\ - -Function: language_filest::typecheck_module - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool language_filest::typecheck_module( symbol_tablet &symbol_table, language_modulet &module) diff --git a/src/util/language_file.h b/src/util/language_file.h index 1f1fc176487..2049e609e8d 100644 --- a/src/util/language_file.h +++ b/src/util/language_file.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_LANGUAGE_FILE_H #define CPROVER_UTIL_LANGUAGE_FILE_H @@ -27,8 +28,11 @@ class language_modulet bool type_checked, in_progress; language_filet *file; - language_modulet() - { type_checked=in_progress=false; } + language_modulet(): + type_checked(false), + in_progress(false), + file(nullptr) + {} }; class language_filet @@ -48,7 +52,7 @@ class language_filet language_filet(const language_filet &rhs); - language_filet():language(NULL) + language_filet():language(nullptr) { } diff --git a/src/util/lispexpr.cpp b/src/util/lispexpr.cpp index 7b19fe5db37..80f62d15c3f 100644 --- a/src/util/lispexpr.cpp +++ b/src/util/lispexpr.cpp @@ -6,21 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "lispexpr.h" -/*******************************************************************\ - -Function: lispexprt::expr2string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include std::string lispexprt::expr2string() const { @@ -61,36 +49,12 @@ std::string lispexprt::expr2string() const return result; } -/*******************************************************************\ - -Function: lispexprt::parse - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool lispexprt::parse(const std::string &s) { std::string::size_type ptr=0; return parse(s, ptr); } -/*******************************************************************\ - -Function: lispexprt::parse - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool lispexprt::parse( const std::string &s, std::string::size_type &ptr) @@ -183,18 +147,6 @@ bool lispexprt::parse( return false; } -/*******************************************************************\ - -Function: escape - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string escape(const std::string &s) { std::string result; @@ -210,18 +162,6 @@ std::string escape(const std::string &s) return result; } -/*******************************************************************\ - -Function: test_lispexpr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - int test_lispexpr() { std::string line; diff --git a/src/util/lispexpr.h b/src/util/lispexpr.h index 0eae32ef779..09c1ff50f42 100644 --- a/src/util/lispexpr.h +++ b/src/util/lispexpr.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + // THIS HEADER IS DEPRECATED AND WILL GO AWAY #ifndef CPROVER_UTIL_LISPEXPR_H diff --git a/src/util/lispirep.cpp b/src/util/lispirep.cpp index 75e926e8107..22e3e0b99a9 100644 --- a/src/util/lispirep.cpp +++ b/src/util/lispirep.cpp @@ -6,27 +6,17 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #include "lispirep.h" + #include "irep.h" #include "lispexpr.h" -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void lisp2irep(const lispexprt &src, irept &dest) { dest.make_nil(); - if(src.type!=lispexprt::List || src.size()<1) + if(src.type!=lispexprt::List || src.empty()) return; dest.id(src[0].value); @@ -65,7 +55,7 @@ void irep2lisp(const irept &src, lispexprt &dest) id.value=src.id_string(); dest.push_back(id); - // reserve objects for extra performace + // reserve objects for extra performance forall_irep(it, src.get_sub()) { diff --git a/src/util/lispirep.h b/src/util/lispirep.h index 8faba937e49..914ba099ad2 100644 --- a/src/util/lispirep.h +++ b/src/util/lispirep.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_LISPIREP_H #define CPROVER_UTIL_LISPIREP_H diff --git a/src/util/memory_info.cpp b/src/util/memory_info.cpp index af4f2ef1d52..3840ba4fc5b 100644 --- a/src/util/memory_info.cpp +++ b/src/util/memory_info.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "memory_info.h" + #ifdef __APPLE__ #include #include @@ -23,20 +25,6 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "memory_info.h" - -/*******************************************************************\ - -Function: memory_info - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void memory_info(std::ostream &out) { #if defined(__linux__) && defined(__GLIBC__) diff --git a/src/util/memory_info.h b/src/util/memory_info.h index 7c35825742a..7364e0e2bd6 100644 --- a/src/util/memory_info.h +++ b/src/util/memory_info.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_MEMORY_INFO_H #define CPROVER_UTIL_MEMORY_INFO_H diff --git a/src/util/merge_irep.cpp b/src/util/merge_irep.cpp index 6b8d4a6924a..02e04b461e5 100644 --- a/src/util/merge_irep.cpp +++ b/src/util/merge_irep.cpp @@ -6,20 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "irep_hash.h" #include "merge_irep.h" -/*******************************************************************\ - -Function: to_be_merged_irept::hash - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include "irep_hash.h" std::size_t to_be_merged_irept::hash() const { @@ -44,18 +33,6 @@ std::size_t to_be_merged_irept::hash() const return result; } -/*******************************************************************\ - -Function: to_be_merged_irept::operator== - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool to_be_merged_irept::operator == (const to_be_merged_irept &other) const { if(id()!=other.id()) @@ -95,18 +72,6 @@ bool to_be_merged_irept::operator == (const to_be_merged_irept &other) const return true; } -/*******************************************************************\ - -Function: merged_irepst::merged - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const merged_irept &merged_irepst::merged(const irept &irep) { // first see if it's already a merged_irep @@ -149,18 +114,6 @@ const merged_irept &merged_irepst::merged(const irept &irep) static_cast(*result.first)); } -/*******************************************************************\ - -Function: merge_irept::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void merge_irept::operator()(irept &irep) { // only useful if there is sharing @@ -169,18 +122,6 @@ void merge_irept::operator()(irept &irep) #endif } -/*******************************************************************\ - -Function: merge_irept::merged - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const irept &merge_irept::merged(const irept &irep) { irep_storet::const_iterator entry=irep_store.find(irep); @@ -221,18 +162,6 @@ const irept &merge_irept::merged(const irept &irep) return *irep_store.insert(new_irep).first; } -/*******************************************************************\ - -Function: merge_full_irept::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void merge_full_irept::operator()(irept &irep) { // only useful if there is sharing @@ -241,18 +170,6 @@ void merge_full_irept::operator()(irept &irep) #endif } -/*******************************************************************\ - -Function: merge_full_irept::merged - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const irept &merge_full_irept::merged(const irept &irep) { irep_storet::const_iterator entry=irep_store.find(irep); diff --git a/src/util/merge_irep.h b/src/util/merge_irep.h index c656cfccca0..9b7d34b580d 100644 --- a/src/util/merge_irep.h +++ b/src/util/merge_irep.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_MERGE_IREP_H #define CPROVER_UTIL_MERGE_IREP_H @@ -20,16 +21,19 @@ class merged_irept:public irept { // We assume that both are in the same container, // which isn't checked. - return data==other.data; + return &read()==&other.read(); } bool operator<(const merged_irept &other) const { // again, assumes that both are in the same container - return ((std::size_t)data)<((std::size_t)other.data); + return &read()<&other.read(); } - std::size_t hash() const { return (std::size_t)data; } + std::size_t hash() const + { + return reinterpret_cast(&read()); + } // copy constructor: will only copy from other merged_irepts merged_irept(const merged_irept &_src):irept(_src) diff --git a/src/util/message.cpp b/src/util/message.cpp index 21a67433609..ad0448adf28 100644 --- a/src/util/message.cpp +++ b/src/util/message.cpp @@ -6,19 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "message.h" - -/*******************************************************************\ - -Function: message_handlert::print - - Inputs: - - Outputs: - - Purpose: -\*******************************************************************/ +#include "message.h" void message_handlert::print( unsigned level, @@ -65,77 +54,15 @@ void message_handlert::print( print(level, dest); } -/*******************************************************************\ - -Function: messaget::print - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void messaget::print(unsigned level, const std::string &message) -{ - if(message_handler!=NULL) - message_handler->print(level, message); -} - -/*******************************************************************\ - -Function: messaget::print - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void messaget::print( +void message_handlert::print( unsigned level, - const std::string &message, - int sequence_number, - const source_locationt &location) + const std::string &message) { - if(message_handler!=NULL) - message_handler->print(level, message, sequence_number, - location); + if(level>=message_count.size()) + message_count.resize(level+1, 0); + ++message_count[level]; } -/*******************************************************************\ - -Function: message_clientt::~message_clientt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -message_clientt::~message_clientt() -{ -} - -/*******************************************************************\ - -Function: message_clientt::set_message_handler - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void message_clientt::set_message_handler( - message_handlert &_message_handler) +messaget::~messaget() { - message_handler=&_message_handler; } diff --git a/src/util/message.h b/src/util/message.h index b92fb8f3dfd..c3d73d5f4d2 100644 --- a/src/util/message.h +++ b/src/util/message.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_MESSAGE_H #define CPROVER_UTIL_MESSAGE_H @@ -13,12 +14,13 @@ Author: Daniel Kroening, kroening@kroening.com #include #include +#include "invariant.h" #include "source_location.h" class message_handlert { public: - message_handlert():verbosity(10) + message_handlert():verbosity(10), message_count(10, 0) { } @@ -30,6 +32,11 @@ class message_handlert int sequence_number, const source_locationt &location); + virtual void flush(unsigned level) + { + // no-op by default + } + virtual ~message_handlert() { } @@ -37,8 +44,17 @@ class message_handlert void set_verbosity(unsigned _verbosity) { verbosity=_verbosity; } unsigned get_verbosity() const { return verbosity; } + unsigned get_message_count(unsigned level) const + { + if(level>=message_count.size()) + return 0; + + return message_count[level]; + } + protected: unsigned verbosity; + std::vector message_count; }; class null_message_handlert:public message_handlert @@ -46,6 +62,7 @@ class null_message_handlert:public message_handlert public: virtual void print(unsigned level, const std::string &message) { + message_handlert::print(level, message); } virtual void print( @@ -54,6 +71,7 @@ class null_message_handlert:public message_handlert int sequence_number, const source_locationt &location) { + print(level, message); } }; @@ -65,13 +83,23 @@ class stream_message_handlert:public message_handlert } virtual void print(unsigned level, const std::string &message) - { out << message << '\n'; } + { + message_handlert::print(level, message); + + if(verbosity>=level) + out << message << '\n'; + } + + virtual void flush(unsigned level) + { + out << std::flush; + } protected: std::ostream &out; }; -class message_clientt +class messaget { public: // Standard message levels: @@ -91,80 +119,38 @@ class message_clientt M_STATISTICS=8, M_PROGRESS=9, M_DEBUG=10 }; - virtual ~message_clientt(); - - virtual void set_message_handler(message_handlert &_message_handler); - - message_clientt():message_handler(NULL) - { - } - - explicit message_clientt(message_handlert &_message_handler): - message_handler(&_message_handler) + virtual void set_message_handler(message_handlert &_message_handler) { + message_handler=&_message_handler; } message_handlert &get_message_handler() { + INVARIANT(message_handler!=nullptr, "message handler is set"); return *message_handler; } -protected: - message_handlert *message_handler; -}; - -class messaget:public message_clientt -{ -public: // constructors, destructor messaget(): + message_handler(nullptr), mstream(M_DEBUG, *this) { } messaget(const messaget &other): - message_clientt(other), - mstream(M_DEBUG, *this) + message_handler(other.message_handler), + mstream(other.mstream) { } explicit messaget(message_handlert &_message_handler): - message_clientt(_message_handler), + message_handler(&_message_handler), mstream(M_DEBUG, *this) { } - virtual ~messaget() { } - - // old interface, will go away - void status( - const std::string &message, - const std::string &file) - { - source_locationt location; - location.set_file(file); - print(6, message, -1, location); - } - - void error( - const std::string &message, - const std::string &file) - { - source_locationt location; - location.set_file(file); - print(1, message, -1, location); - } - - virtual void print(unsigned level, const std::string &message); - - virtual void print( - unsigned level, - const std::string &message, - int sequence_number, // -1: no sequence information - const source_locationt &location); - - // New interface + virtual ~messaget(); class mstreamt:public std::ostringstream { @@ -177,6 +163,13 @@ class messaget:public message_clientt { } + mstreamt(const mstreamt &other): + message_level(other.message_level), + message(other.message), + source_location(other.source_location) + { + } + unsigned message_level; messaget &message; source_locationt source_location; @@ -197,9 +190,17 @@ class messaget:public message_clientt // Feeding 'eom' into the stream triggers // the printing of the message - static inline mstreamt &eom(mstreamt &m) + static mstreamt &eom(mstreamt &m) { - m.message.print(m.message_level, m.str(), -1, m.source_location); + if(m.message.message_handler) + { + m.message.message_handler->print( + m.message_level, + m.str(), + -1, + m.source_location); + m.message.message_handler->flush(m.message_level); + } m.clear(); // clears error bits m.str(std::string()); // clears the string m.source_location.clear(); @@ -207,61 +208,55 @@ class messaget:public message_clientt } // in lieu of std::endl - static inline mstreamt &endl(mstreamt &m) + static mstreamt &endl(mstreamt &m) { static_cast(m) << std::endl; return m; } - mstreamt &error() + mstreamt &get_mstream(unsigned message_level) { - mstream.message_level=M_ERROR; + mstream.message_level=message_level; return mstream; } + mstreamt &error() + { + return get_mstream(M_ERROR); + } + mstreamt &warning() { - mstream.message_level=M_WARNING; - return mstream; + return get_mstream(M_WARNING); } mstreamt &result() { - mstream.message_level=M_RESULT; - return mstream; + return get_mstream(M_RESULT); } mstreamt &status() { - mstream.message_level=M_STATUS; - return mstream; + return get_mstream(M_STATUS); } mstreamt &statistics() { - mstream.message_level=M_STATISTICS; - return mstream; + return get_mstream(M_STATISTICS); } mstreamt &progress() { - mstream.message_level=M_PROGRESS; - return mstream; + return get_mstream(M_PROGRESS); } mstreamt &debug() { - mstream.message_level=M_DEBUG; - return mstream; - } - - mstreamt &get_mstream(unsigned message_level) - { - mstream.message_level=message_level; - return mstream; + return get_mstream(M_DEBUG); } protected: + message_handlert *message_handler; mstreamt mstream; }; diff --git a/src/util/mp_arith.cpp b/src/util/mp_arith.cpp index 338a6103e40..035541749e1 100644 --- a/src/util/mp_arith.cpp +++ b/src/util/mp_arith.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "mp_arith.h" + #include #include #include @@ -14,21 +16,8 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include "mp_arith.h" #include "arith_tools.h" -/*******************************************************************\ - -Function: >> - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - mp_integer operator>>(const mp_integer &a, const mp_integer &b) { mp_integer power=::power(2, b); @@ -47,54 +36,20 @@ mp_integer operator>>(const mp_integer &a, const mp_integer &b) } } -/*******************************************************************\ - -Function: << - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - mp_integer operator<<(const mp_integer &a, const mp_integer &b) { return a*power(2, b); } -/*******************************************************************\ - -Function: << - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::ostream &operator<<(std::ostream &out, const mp_integer &n) { out << integer2string(n); return out; } -/*******************************************************************\ - -Function: string2integer - - Inputs: string of '0'-'9' etc. most significant digit first - base of number representation - - Outputs: mp_integer - - Purpose: - -\*******************************************************************/ - +/// \par parameters: string of '0'-'9' etc. most significant digit first +/// base of number representation +/// \return mp_integer const mp_integer string2integer(const std::string &n, unsigned base) { for(unsigned i=0; i=0); @@ -301,18 +200,6 @@ std::size_t integer2size_t(const mp_integer &n) return (std::size_t)ull; } -/*******************************************************************\ - -Function: integer2unsigned - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - unsigned integer2unsigned(const mp_integer &n) { assert(n>=0); diff --git a/src/util/mp_arith.h b/src/util/mp_arith.h index 030a292bb74..eede5855b75 100644 --- a/src/util/mp_arith.h +++ b/src/util/mp_arith.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_MP_ARITH_H #define CPROVER_UTIL_MP_ARITH_H diff --git a/src/util/namespace.cpp b/src/util/namespace.cpp index 1abf0fb1c59..218e73d2850 100644 --- a/src/util/namespace.cpp +++ b/src/util/namespace.cpp @@ -6,6 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Namespace + +#include "namespace.h" + #include #include @@ -14,19 +19,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "symbol_table.h" #include "prefix.h" #include "std_types.h" -#include "namespace.h" - -/*******************************************************************\ - -Function: get_max - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ unsigned get_max( const std::string &prefix, @@ -44,34 +36,10 @@ unsigned get_max( return max_nr; } -/*******************************************************************\ - -Function: namespace_baset::~namespace_baset - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - namespace_baset::~namespace_baset() { } -/*******************************************************************\ - -Function: namespace_baset::follow_symbol - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void namespace_baset::follow_symbol(irept &irep) const { while(irep.id()==ID_symbol) @@ -95,18 +63,6 @@ void namespace_baset::follow_symbol(irept &irep) const } } -/*******************************************************************\ - -Function: namespace_baset::follow - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const typet &namespace_baset::follow(const typet &src) const { if(src.id()!=ID_symbol) @@ -124,18 +80,6 @@ const typet &namespace_baset::follow(const typet &src) const } } -/*******************************************************************\ - -Function: namespace_baset::follow_tag - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const typet &namespace_baset::follow_tag(const union_tag_typet &src) const { const symbolt &symbol=lookup(src.get_identifier()); @@ -144,18 +88,6 @@ const typet &namespace_baset::follow_tag(const union_tag_typet &src) const return symbol.type; } -/*******************************************************************\ - -Function: namespace_baset::follow_tag - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const typet &namespace_baset::follow_tag(const struct_tag_typet &src) const { const symbolt &symbol=lookup(src.get_identifier()); @@ -164,18 +96,6 @@ const typet &namespace_baset::follow_tag(const struct_tag_typet &src) const return symbol.type; } -/*******************************************************************\ - -Function: namespace_baset::follow_tag - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const typet &namespace_baset::follow_tag(const c_enum_tag_typet &src) const { const symbolt &symbol=lookup(src.get_identifier()); @@ -184,18 +104,6 @@ const typet &namespace_baset::follow_tag(const c_enum_tag_typet &src) const return symbol.type; } -/*******************************************************************\ - -Function: namespace_baset::follow_macros - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void namespace_baset::follow_macros(exprt &expr) const { if(expr.id()==ID_symbol) @@ -215,50 +123,26 @@ void namespace_baset::follow_macros(exprt &expr) const follow_macros(*it); } -/*******************************************************************\ - -Function: namespace_baset::get_max - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - unsigned namespacet::get_max(const std::string &prefix) const { unsigned m=0; - if(symbol_table1!=NULL) + if(symbol_table1!=nullptr) m=std::max(m, ::get_max(prefix, symbol_table1->symbols)); - if(symbol_table2!=NULL) + if(symbol_table2!=nullptr) m=std::max(m, ::get_max(prefix, symbol_table2->symbols)); return m; } -/*******************************************************************\ - -Function: namespacet::lookup - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool namespacet::lookup( const irep_idt &name, const symbolt *&symbol) const { symbol_tablet::symbolst::const_iterator it; - if(symbol_table1!=NULL) + if(symbol_table1!=nullptr) { it=symbol_table1->symbols.find(name); @@ -269,7 +153,7 @@ bool namespacet::lookup( } } - if(symbol_table2!=NULL) + if(symbol_table2!=nullptr) { it=symbol_table2->symbols.find(name); @@ -283,18 +167,6 @@ bool namespacet::lookup( return true; } -/*******************************************************************\ - -Function: multi_namespacet::get_max - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - unsigned multi_namespacet::get_max(const std::string &prefix) const { unsigned m=0; @@ -308,18 +180,6 @@ unsigned multi_namespacet::get_max(const std::string &prefix) const return m; } -/*******************************************************************\ - -Function: multi_namespacet::lookup - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool multi_namespacet::lookup( const irep_idt &name, const symbolt *&symbol) const diff --git a/src/util/namespace.h b/src/util/namespace.h index 6f81ed8a55d..a3b9f3827c6 100644 --- a/src/util/namespace.h +++ b/src/util/namespace.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_NAMESPACE_H #define CPROVER_UTIL_NAMESPACE_H @@ -63,7 +64,7 @@ class namespacet:public namespace_baset public: // constructors explicit namespacet(const symbol_tablet &_symbol_table) - { symbol_table1=&_symbol_table; symbol_table2=NULL; } + { symbol_table1=&_symbol_table; symbol_table2=nullptr; } namespacet( const symbol_tablet &_symbol_table1, @@ -100,12 +101,12 @@ class multi_namespacet:public namespacet { public: // constructors - multi_namespacet():namespacet(NULL, NULL) + multi_namespacet():namespacet(nullptr, nullptr) { } explicit multi_namespacet( - const symbol_tablet &symbol_table):namespacet(NULL, NULL) + const symbol_tablet &symbol_table):namespacet(nullptr, nullptr) { add(symbol_table); } diff --git a/src/util/numbering.h b/src/util/numbering.h index aab703b9121..359f3c48ed2 100644 --- a/src/util/numbering.h +++ b/src/util/numbering.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_NUMBERING_H #define CPROVER_UTIL_NUMBERING_H diff --git a/src/util/options.cpp b/src/util/options.cpp index e1cb8a369db..bd952760a4c 100644 --- a/src/util/options.cpp +++ b/src/util/options.cpp @@ -6,20 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "string2int.h" -#include "options.h" - -/*******************************************************************\ - -Function: optionst::set_option +/// \file +/// Options - Inputs: - - Outputs: - - Purpose: +#include "options.h" -\*******************************************************************/ +#include "string2int.h" void optionst::set_option(const std::string &option, const std::string &value) @@ -29,126 +21,42 @@ void optionst::set_option(const std::string &option, value_list.push_back(value); } -/*******************************************************************\ - -Function: optionst::set_option - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void optionst::set_option(const std::string &option, const bool value) { set_option(option, std::string(value?"1":"0")); } -/*******************************************************************\ - -Function: optionst::set_option - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void optionst::set_option(const std::string &option, const signed int value) { set_option(option, std::to_string(value)); } -/*******************************************************************\ - -Function: optionst::set_option - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void optionst::set_option(const std::string &option, const unsigned int value) { set_option(option, std::to_string(value)); } -/*******************************************************************\ - -Function: optionst::get_bool_option - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool optionst::get_bool_option(const std::string &option) const { const std::string value=get_option(option); return value.empty()?false:(std::stoi(value)!=0); } -/*******************************************************************\ - -Function: optionst::get_signed_int_option - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - signed int optionst::get_signed_int_option(const std::string &option) const { const std::string value=get_option(option); return value.empty()?0:std::stoi(value); } -/*******************************************************************\ - -Function: optionst::get_unsigned_int_option - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - unsigned int optionst::get_unsigned_int_option(const std::string &option) const { const std::string value=get_option(option); return value.empty()?0:safe_string2unsigned(value); } -/*******************************************************************\ - -Function: optionst::get_option - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const std::string optionst::get_option(const std::string &option) const { option_mapt::const_iterator it= @@ -162,18 +70,6 @@ const std::string optionst::get_option(const std::string &option) const return it->second.front(); } -/*******************************************************************\ - -Function: optionst::get_list_option - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const optionst::value_listt &optionst::get_list_option( const std::string &option) const { diff --git a/src/util/options.h b/src/util/options.h index 118c365c992..1a558a37331 100644 --- a/src/util/options.h +++ b/src/util/options.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Options + #ifndef CPROVER_UTIL_OPTIONS_H #define CPROVER_UTIL_OPTIONS_H diff --git a/src/util/overlay_map.h b/src/util/overlay_map.h index bfcbef75d1d..a63ae03dc6e 100644 --- a/src/util/overlay_map.h +++ b/src/util/overlay_map.h @@ -6,6 +6,9 @@ Author: Chris Smowton, chris.smowton@diffblue.com \*******************************************************************/ +/// \file +/// Overlay-map + #ifndef CPROVER_UTIL_OVERLAY_MAP_H #define CPROVER_UTIL_OVERLAY_MAP_H diff --git a/src/util/parameter_indices.cpp b/src/util/parameter_indices.cpp index bba825090f8..ad0eae20d9b 100644 --- a/src/util/parameter_indices.cpp +++ b/src/util/parameter_indices.cpp @@ -6,21 +6,15 @@ Author: Chris Smowton, chris.smowton@diffblue.com \*******************************************************************/ -#include "parameter_indices.h" - -/*******************************************************************\ - -Function: get_parameter_indices - - Inputs: Code type +/// \file +/// Parameter indexing - Outputs: Map from parameter name to position - - Purpose: Make a map useful for mapping from symbol expressions to - actual or formal parameter indices. - -\*******************************************************************/ +#include "parameter_indices.h" +/// Make a map useful for mapping from symbol expressions to actual or formal +/// parameter indices. +/// \par parameters: Code type +/// \return Map from parameter name to position std::map get_parameter_indices(const code_typet &fn_type) { std::map parameter_indices; diff --git a/src/util/parameter_indices.h b/src/util/parameter_indices.h index a421638d870..621da803d31 100644 --- a/src/util/parameter_indices.h +++ b/src/util/parameter_indices.h @@ -6,6 +6,9 @@ Author: Chris Smowton, chris.smowton@diffblue.com \*******************************************************************/ +/// \file +/// Parameter indexing + #ifndef CPROVER_UTIL_PARAMETER_INDICES_H #define CPROVER_UTIL_PARAMETER_INDICES_H diff --git a/src/util/parse_options.cpp b/src/util/parse_options.cpp index f674d9717e6..db809a387a3 100644 --- a/src/util/parse_options.cpp +++ b/src/util/parse_options.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "parse_options.h" + #include #if defined (_WIN32) @@ -16,21 +18,8 @@ Author: Daniel Kroening, kroening@kroening.com #endif #include "cmdline.h" -#include "parse_options.h" #include "signal_catcher.h" -/*******************************************************************\ - -Function: parse_options_baset::parse_options_baset - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - parse_options_baset::parse_options_baset( const std::string &_optstring, int argc, const char **argv) { @@ -38,52 +27,16 @@ parse_options_baset::parse_options_baset( parse_result=cmdline.parse(argc, argv, optstring.c_str()); } -/*******************************************************************\ - -Function: parse_options_baset::help - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void parse_options_baset::help() { } -/*******************************************************************\ - -Function: parse_options_baset::usage_error - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void parse_options_baset::usage_error() { std::cerr << "Usage error!\n\n"; help(); } -/*******************************************************************\ - -Function: parse_options_baset::main - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - int parse_options_baset::main() { if(parse_result) diff --git a/src/util/parse_options.h b/src/util/parse_options.h index 52a201158a1..73f436cf331 100644 --- a/src/util/parse_options.h +++ b/src/util/parse_options.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_PARSE_OPTIONS_H #define CPROVER_UTIL_PARSE_OPTIONS_H diff --git a/src/util/parser.cpp b/src/util/parser.cpp index 539ed1f0e63..98f1508e07e 100644 --- a/src/util/parser.cpp +++ b/src/util/parser.cpp @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #include "parser.h" #ifdef _WIN32 @@ -15,18 +16,6 @@ int isatty(int f) } #endif -/*******************************************************************\ - -Function: _newstack - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt &_newstack(parsert &parser, unsigned &x) { x=(unsigned)parser.stack.size(); @@ -38,18 +27,6 @@ exprt &_newstack(parsert &parser, unsigned &x) return parser.stack.back(); } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void parsert::parse_error( const std::string &message, const std::string &before) @@ -63,6 +40,7 @@ void parsert::parse_error( tmp_source_location.set_column(column-before.size()); print(1, tmp, -1, tmp_source_location); #else - print(1, tmp, -1, source_location); + error().source_location=source_location; + error() << tmp << eom; #endif } diff --git a/src/util/parser.h b/src/util/parser.h index f8792a75c66..bf572e6004d 100644 --- a/src/util/parser.h +++ b/src/util/parser.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Parser utilities + #ifndef CPROVER_UTIL_PARSER_H #define CPROVER_UTIL_PARSER_H @@ -36,7 +39,7 @@ class parsert:public messaget last_line.clear(); } - parsert():in(NULL) { clear(); } + parsert():in(nullptr) { clear(); } virtual ~parsert() { } // The following are for the benefit of the scanner diff --git a/src/util/pipe_stream.cpp b/src/util/pipe_stream.cpp index 104dd3a2075..e9fc1887fb5 100644 --- a/src/util/pipe_stream.cpp +++ b/src/util/pipe_stream.cpp @@ -6,12 +6,16 @@ Module: A stdin/stdout pipe as STL stream \*******************************************************************/ +/// \file +/// A stdin/stdout pipe as STL stream + +#include "pipe_stream.h" + #include #include #include #include "unicode.h" -#include "pipe_stream.h" #ifdef _WIN32 #include @@ -19,25 +23,14 @@ Module: A stdin/stdout pipe as STL stream #else #include #include -#include #include #include +#include #endif #define READ_BUFFER_SIZE 1024 -/*******************************************************************\ - -Function: pipe_streamt::pipe_streamt - - Inputs: - - Outputs: - - Purpose: Constructor for external process - -\*******************************************************************/ - +/// Constructor for external process pipe_streamt::pipe_streamt( const std::string &_executable, const std::list &_args): @@ -50,19 +43,9 @@ pipe_streamt::pipe_streamt( #endif } -/*******************************************************************\ - -Function: pipe_streamt::run - - Inputs: - - Outputs: Returns -1 if an error occurs. - - Purpose: Starts an external process. A new process is forked and - run returns immediately. - -\*******************************************************************/ - +/// Starts an external process. A new process is forked and run returns +/// immediately. +/// \return Returns -1 if an error occurs. #ifdef _WIN32 int pipe_streamt::run() @@ -176,12 +159,12 @@ int pipe_streamt::run() a_it++, i++) _argv[i]=strdup(a_it->c_str()); - _argv[args.size()+1]=NULL; + _argv[args.size()+1]=nullptr; int result=execvp(executable.c_str(), _argv); if(result==-1) - perror(0); + perror(nullptr); return result; } @@ -204,18 +187,7 @@ int pipe_streamt::run() #endif -/*******************************************************************\ - -Function: pipe_streamt::wait - - Inputs: - - Outputs: - - Purpose: Wait for the process to terminate - -\*******************************************************************/ - +/// Wait for the process to terminate int pipe_streamt::wait() { #ifdef _WIN32 @@ -242,18 +214,7 @@ int pipe_streamt::wait() #endif } -/*******************************************************************\ - -Function: filedescriptor_streambuft::filedescriptor_streambuft - - Inputs: - - Outputs: - - Purpose: Constructor - -\*******************************************************************/ - +/// Constructor filedescriptor_streambuft::filedescriptor_streambuft(): #ifdef _WIN32 proc_in(INVALID_HANDLE_VALUE), @@ -267,18 +228,7 @@ filedescriptor_streambuft::filedescriptor_streambuft(): setg(in_buffer, in_buffer, in_buffer); } -/*******************************************************************\ - -Function: filedescriptor_streambuft::~filedescriptor_streambuft - - Inputs: - - Outputs: - - Purpose: Destructor - -\*******************************************************************/ - +/// Destructor filedescriptor_streambuft::~filedescriptor_streambuft() { #ifdef _WIN32 @@ -302,18 +252,7 @@ filedescriptor_streambuft::~filedescriptor_streambuft() delete in_buffer; } -/*******************************************************************\ - -Function: filedescriptor_streambuft::overflow - - Inputs: - - Outputs: - - Purpose: write one character to the piped process - -\*******************************************************************/ - +/// write one character to the piped process std::streambuf::int_type filedescriptor_streambuft::overflow( std::streambuf::int_type character) { @@ -334,18 +273,7 @@ std::streambuf::int_type filedescriptor_streambuft::overflow( return character; } -/*******************************************************************\ - -Function: filedescriptor_streambuft::xsputn - - Inputs: - - Outputs: - - Purpose: write a number of character to the piped process - -\*******************************************************************/ - +/// write a number of character to the piped process std::streamsize filedescriptor_streambuft::xsputn( const char* str, std::streamsize count) { @@ -358,21 +286,10 @@ std::streamsize filedescriptor_streambuft::xsputn( #endif } -/*******************************************************************\ - -Function: filedescriptor_streambuft::underflow - - Inputs: - - Outputs: - - Purpose: read a character from the piped process - -\*******************************************************************/ - +/// read a character from the piped process std::streambuf::int_type filedescriptor_streambuft::underflow() { - if(gptr()==0) + if(gptr()==nullptr) return traits_type::eof(); if(gptr() @@ -472,13 +361,13 @@ int main(int argc, char** argv) if(process.run() < 0) return -1; - process << "xxx\n" << std::endl; + process << "xxx\n\n"; char token; for(int i=0; i<3; ++i) { process >> token; - std::cout << "Answer: " << token << std::endl; + std::cout << "Answer: " << token << '\n'; } return process.wait(); diff --git a/src/util/pipe_stream.h b/src/util/pipe_stream.h index b2b5bcea533..385cb65f790 100644 --- a/src/util/pipe_stream.h +++ b/src/util/pipe_stream.h @@ -6,10 +6,13 @@ Module: A stdin/stdout pipe as STL stream \*******************************************************************/ +/// \file +/// A stdin/stdout pipe as STL stream + #ifndef CPROVER_UTIL_PIPE_STREAM_H #define CPROVER_UTIL_PIPE_STREAM_H -#include +#include #include #include diff --git a/src/util/pointer_offset_size.cpp b/src/util/pointer_offset_size.cpp index 43e7dd0d5a9..dee9aeff82d 100644 --- a/src/util/pointer_offset_size.cpp +++ b/src/util/pointer_offset_size.cpp @@ -6,8 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Pointer Logic + +#include "pointer_offset_size.h" + #include +#include "c_types.h" #include "expr.h" #include "arith_tools.h" #include "std_types.h" @@ -19,8 +25,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "symbol.h" #include "ssa_expr.h" -#include "pointer_offset_size.h" - member_offset_iterator::member_offset_iterator( const struct_typet &_type, const namespacet &_ns): @@ -56,18 +60,6 @@ member_offset_iterator &member_offset_iterator::operator++() return *this; } -/*******************************************************************\ - -Function: member_offset - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - mp_integer member_offset( const struct_typet &type, const irep_idt &member, @@ -88,18 +80,6 @@ mp_integer member_offset( return offsets->second; } -/*******************************************************************\ - -Function: pointer_offset_size - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - mp_integer pointer_offset_size( const typet &type, const namespacet &ns) @@ -110,18 +90,6 @@ mp_integer pointer_offset_size( return bits/8+(((bits%8)==0)?0:1); } -/*******************************************************************\ - -Function: pointer_offset_bits - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - mp_integer pointer_offset_bits( const typet &type, const namespacet &ns) @@ -129,6 +97,8 @@ mp_integer pointer_offset_bits( if(type.id()==ID_array) { mp_integer sub=pointer_offset_bits(type.subtype(), ns); + if(sub<0) + return -1; // get size const exprt &size=to_array_type(type).size(); @@ -144,6 +114,8 @@ mp_integer pointer_offset_bits( else if(type.id()==ID_vector) { mp_integer sub=pointer_offset_bits(type.subtype(), ns); + if(sub<0) + return -1; // get size const exprt &size=to_vector_type(type).size(); @@ -159,6 +131,9 @@ mp_integer pointer_offset_bits( else if(type.id()==ID_complex) { mp_integer sub=pointer_offset_bits(type.subtype(), ns); + if(sub<0) + return -1; + return sub*2; } else if(type.id()==ID_struct) @@ -200,6 +175,8 @@ mp_integer pointer_offset_bits( { const typet &subtype=it->type(); mp_integer sub_size=pointer_offset_bits(subtype, ns); + if(sub_size==-1) + return -1; if(sub_size>result) result=sub_size; } @@ -251,18 +228,6 @@ mp_integer pointer_offset_bits( return mp_integer(-1); } -/*******************************************************************\ - -Function: member_offset_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt member_offset_expr( const member_exprt &member_expr, const namespacet &ns) @@ -273,23 +238,11 @@ exprt member_offset_expr( return member_offset_expr( to_struct_type(type), member_expr.get_component_name(), ns); else if(type.id()==ID_union) - return from_integer(0, signedbv_typet(config.ansi_c.pointer_width)); + return from_integer(0, size_type()); else return nil_exprt(); } -/*******************************************************************\ - -Function: member_offset_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt member_offset_expr( const struct_typet &type, const irep_idt &member, @@ -297,7 +250,7 @@ exprt member_offset_expr( { const struct_typet::componentst &components=type.components(); - exprt result=from_integer(0, signedbv_typet(config.ansi_c.pointer_width)); + exprt result=from_integer(0, size_type()); std::size_t bit_field_bits=0; for(struct_typet::componentst::const_iterator @@ -331,18 +284,6 @@ exprt member_offset_expr( return result; } -/*******************************************************************\ - -Function: size_of_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt size_of_expr( const typet &type, const namespacet &ns) @@ -407,7 +348,7 @@ exprt size_of_expr( const struct_typet::componentst &components= struct_type.components(); - exprt result=from_integer(0, signedbv_typet(config.ansi_c.pointer_width)); + exprt result=from_integer(0, size_type()); std::size_t bit_field_bits=0; for(struct_typet::componentst::const_iterator @@ -466,11 +407,16 @@ exprt size_of_expr( else sub_size=pointer_offset_size(subtype, ns); + if(sub_size==-1) + { + result=-1; + break; + } if(sub_size>result) result=sub_size; } - return from_integer(result, signedbv_typet(config.ansi_c.pointer_width)); + return from_integer(result, size_type()); } else if(type.id()==ID_signedbv || type.id()==ID_unsignedbv || @@ -483,7 +429,7 @@ exprt size_of_expr( std::size_t bytes=width/8; if(bytes*8!=width) bytes++; - return from_integer(bytes, signedbv_typet(config.ansi_c.pointer_width)); + return from_integer(bytes, size_type()); } else if(type.id()==ID_c_enum) { @@ -491,7 +437,7 @@ exprt size_of_expr( std::size_t bytes=width/8; if(bytes*8!=width) bytes++; - return from_integer(bytes, signedbv_typet(config.ansi_c.pointer_width)); + return from_integer(bytes, size_type()); } else if(type.id()==ID_c_enum_tag) { @@ -499,7 +445,7 @@ exprt size_of_expr( } else if(type.id()==ID_bool) { - return from_integer(1, signedbv_typet(config.ansi_c.pointer_width)); + return from_integer(1, size_type()); } else if(type.id()==ID_pointer) { @@ -507,7 +453,7 @@ exprt size_of_expr( std::size_t bytes=width/8; if(bytes*8!=width) bytes++; - return from_integer(bytes, signedbv_typet(config.ansi_c.pointer_width)); + return from_integer(bytes, size_type()); } else if(type.id()==ID_symbol) { @@ -515,29 +461,16 @@ exprt size_of_expr( } else if(type.id()==ID_code) { - return from_integer(0, signedbv_typet(config.ansi_c.pointer_width)); + return from_integer(0, size_type()); } else if(type.id()==ID_string) { - return from_integer( - 32/8, signedbv_typet(config.ansi_c.pointer_width)); + return from_integer(32/8, size_type()); } else return nil_exprt(); } -/*******************************************************************\ - -Function: compute_pointer_offset - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - mp_integer compute_pointer_offset( const exprt &expr, const namespacet &ns) @@ -566,7 +499,7 @@ mp_integer compute_pointer_offset( mp_integer i; - if(sub_size!=0 && !to_integer(expr.op1(), i)) + if(sub_size>0 && !to_integer(expr.op1(), i)) return o+i*sub_size; } @@ -597,18 +530,6 @@ mp_integer compute_pointer_offset( return -1; // don't know } -/*******************************************************************\ - -Function: build_sizeof_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt build_sizeof_expr( const constant_exprt &expr, const namespacet &ns) @@ -628,7 +549,7 @@ exprt build_sizeof_expr( return nil_exprt(); assert(address_bits(val+1)<=config.ansi_c.pointer_width); - const unsignedbv_typet t(config.ansi_c.pointer_width); + const typet t(size_type()); mp_integer remainder=0; if(type_size!=0) diff --git a/src/util/pointer_offset_size.h b/src/util/pointer_offset_size.h index e6f7ae15314..aeb62e03d74 100644 --- a/src/util/pointer_offset_size.h +++ b/src/util/pointer_offset_size.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Pointer Logic + #ifndef CPROVER_UTIL_POINTER_OFFSET_SIZE_H #define CPROVER_UTIL_POINTER_OFFSET_SIZE_H diff --git a/src/util/pointer_predicates.cpp b/src/util/pointer_predicates.cpp index 53427d056e2..e0ef139be4a 100644 --- a/src/util/pointer_predicates.cpp +++ b/src/util/pointer_predicates.cpp @@ -6,6 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Various predicates over pointers in programs + +#include "pointer_predicates.h" + +#include "c_types.h" #include "cprover_prefix.h" #include "namespace.h" #include "std_expr.h" @@ -15,92 +21,26 @@ Author: Daniel Kroening, kroening@kroening.com #include "config.h" #include "symbol.h" -#include "pointer_predicates.h" - -/*******************************************************************\ - -Function: pointer_object - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt pointer_object(const exprt &p) { - return unary_exprt( - ID_pointer_object, p, - unsignedbv_typet(config.ansi_c.pointer_width)); + return unary_exprt(ID_pointer_object, p, size_type()); } -/*******************************************************************\ - -Function: same_object - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt same_object(const exprt &p1, const exprt &p2) { return equal_exprt(pointer_object(p1), pointer_object(p2)); } -/*******************************************************************\ - -Function: object_size - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt object_size(const exprt &pointer) { - typet type=signedbv_typet(config.ansi_c.pointer_width); - return unary_exprt(ID_object_size, pointer, type); + return unary_exprt(ID_object_size, pointer, size_type()); } -/*******************************************************************\ - -Function: pointer_offset - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt pointer_offset(const exprt &pointer) { - typet type=signedbv_typet(config.ansi_c.pointer_width); - return unary_exprt(ID_pointer_offset, pointer, type); + return unary_exprt(ID_pointer_offset, pointer, signed_size_type()); } -/*******************************************************************\ - -Function: malloc_object - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt malloc_object(const exprt &pointer, const namespacet &ns) { // we check __CPROVER_malloc_object! @@ -109,18 +49,6 @@ exprt malloc_object(const exprt &pointer, const namespacet &ns) return same_object(pointer, malloc_object_symbol.symbol_expr()); } -/*******************************************************************\ - -Function: deallocated - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt deallocated(const exprt &pointer, const namespacet &ns) { // we check __CPROVER_deallocated! @@ -129,18 +57,6 @@ exprt deallocated(const exprt &pointer, const namespacet &ns) return same_object(pointer, deallocated_symbol.symbol_expr()); } -/*******************************************************************\ - -Function: dead_object - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt dead_object(const exprt &pointer, const namespacet &ns) { // we check __CPROVER_dead_object! @@ -149,52 +65,16 @@ exprt dead_object(const exprt &pointer, const namespacet &ns) return same_object(pointer, deallocated_symbol.symbol_expr()); } -/*******************************************************************\ - -Function: dynamic_size - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt dynamic_size(const namespacet &ns) { return ns.lookup(CPROVER_PREFIX "malloc_size").symbol_expr(); } -/*******************************************************************\ - -Function: pointer_object_has_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt pointer_object_has_type(const exprt &pointer, const typet &type) { return false_exprt(); } -/*******************************************************************\ - -Function: dynamic_object - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt dynamic_object(const exprt &pointer) { exprt dynamic_expr(ID_dynamic_object, bool_typet()); @@ -202,35 +82,11 @@ exprt dynamic_object(const exprt &pointer) return dynamic_expr; } -/*******************************************************************\ - -Function: good_pointer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt good_pointer(const exprt &pointer) { return unary_exprt(ID_good_pointer, pointer, bool_typet()); } -/*******************************************************************\ - -Function: good_pointer_def - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt good_pointer_def( const exprt &pointer, const namespacet &ns) @@ -287,36 +143,12 @@ exprt good_pointer_def( good_other); } -/*******************************************************************\ - -Function: null_object - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt null_object(const exprt &pointer) { null_pointer_exprt null_pointer(to_pointer_type(pointer.type())); return same_object(null_pointer, pointer); } -/*******************************************************************\ - -Function: integer_address - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt integer_address(const exprt &pointer) { null_pointer_exprt null_pointer(to_pointer_type(pointer.type())); @@ -324,53 +156,17 @@ exprt integer_address(const exprt &pointer) notequal_exprt(null_pointer, pointer)); } -/*******************************************************************\ - -Function: null_pointer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt null_pointer(const exprt &pointer) { null_pointer_exprt null_pointer(to_pointer_type(pointer.type())); return same_object(pointer, null_pointer); } -/*******************************************************************\ - -Function: invalid_pointer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt invalid_pointer(const exprt &pointer) { return unary_exprt(ID_invalid_pointer, pointer, bool_typet()); } -/*******************************************************************\ - -Function: dynamic_object_lower_bound - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt dynamic_object_lower_bound( const exprt &pointer, const namespacet &ns, @@ -379,18 +175,6 @@ exprt dynamic_object_lower_bound( return object_lower_bound(pointer, ns, offset); } -/*******************************************************************\ - -Function: dynamic_object_upper_bound - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt dynamic_object_upper_bound( const exprt &pointer, const typet &dereference_type, @@ -411,6 +195,10 @@ exprt dynamic_object_upper_bound( if(access_size.is_not_nil()) { op=ID_gt; + + if(ns.follow(object_offset.type())!= + ns.follow(access_size.type())) + object_offset.make_typecast(access_size.type()); sum=plus_exprt(object_offset, access_size); } @@ -421,18 +209,6 @@ exprt dynamic_object_upper_bound( return binary_relation_exprt(sum, op, malloc_size); } -/*******************************************************************\ - -Function: object_upper_bound - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt object_upper_bound( const exprt &pointer, const typet &dereference_type, @@ -453,6 +229,10 @@ exprt object_upper_bound( if(access_size.is_not_nil()) { op=ID_gt; + + if(ns.follow(object_offset.type())!= + ns.follow(access_size.type())) + object_offset.make_typecast(access_size.type()); sum=plus_exprt(object_offset, access_size); } @@ -464,18 +244,6 @@ exprt object_upper_bound( return binary_relation_exprt(sum, op, object_size_expr); } -/*******************************************************************\ - -Function: object_lower_bound - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt object_lower_bound( const exprt &pointer, const namespacet &ns, diff --git a/src/util/pointer_predicates.h b/src/util/pointer_predicates.h index 9f3ee3980fd..201d094f50a 100644 --- a/src/util/pointer_predicates.h +++ b/src/util/pointer_predicates.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Various predicates over pointers in programs + #ifndef CPROVER_UTIL_POINTER_PREDICATES_H #define CPROVER_UTIL_POINTER_PREDICATES_H diff --git a/src/util/prefix.h b/src/util/prefix.h index 1efd86bae7a..7edb43a80a0 100644 --- a/src/util/prefix.h +++ b/src/util/prefix.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_PREFIX_H #define CPROVER_UTIL_PREFIX_H diff --git a/src/util/preprocessor.h b/src/util/preprocessor.h index 248a85d0402..64919612319 100644 --- a/src/util/preprocessor.h +++ b/src/util/preprocessor.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Preprocessing Base Class + #ifndef CPROVER_UTIL_PREPROCESSOR_H #define CPROVER_UTIL_PREPROCESSOR_H diff --git a/src/util/rational.cpp b/src/util/rational.cpp index 45dfdec86db..521e7683c1e 100644 --- a/src/util/rational.cpp +++ b/src/util/rational.cpp @@ -6,22 +6,13 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include -#include +/// \file +/// Rational Numbers #include "rational.h" -/*******************************************************************\ - -Function: rationalt::operator+= - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include rationalt &rationalt::operator+=(const rationalt &n) { @@ -32,18 +23,6 @@ rationalt &rationalt::operator+=(const rationalt &n) return *this; } -/*******************************************************************\ - -Function: rationalt::operator-= - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - rationalt &rationalt::operator-=(const rationalt &n) { rationalt tmp(n); @@ -53,36 +32,12 @@ rationalt &rationalt::operator-=(const rationalt &n) return *this; } -/*******************************************************************\ - -Function: rationalt::operator-= - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - rationalt &rationalt::operator-() { numerator.negate(); return *this; } -/*******************************************************************\ - -Function: rationalt::operator*= - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - rationalt &rationalt::operator*=(const rationalt &n) { numerator*=n.numerator; @@ -91,18 +46,6 @@ rationalt &rationalt::operator*=(const rationalt &n) return *this; } -/*******************************************************************\ - -Function: rationalt::operator/= - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - rationalt &rationalt::operator/=(const rationalt &n) { assert(!n.numerator.is_zero()); @@ -112,18 +55,6 @@ rationalt &rationalt::operator/=(const rationalt &n) return *this; } -/*******************************************************************\ - -Function: rationalt::normalize - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rationalt::normalize() { // first do sign @@ -144,18 +75,6 @@ void rationalt::normalize() } } -/*******************************************************************\ - -Function: rationalt::same_denominator - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rationalt::same_denominator(rationalt &n) { if(denominator==n.denominator) @@ -169,36 +88,12 @@ void rationalt::same_denominator(rationalt &n) n.denominator=t; } -/*******************************************************************\ - -Function: rationalt::invert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rationalt::invert() { assert(numerator!=0); std::swap(numerator, denominator); } -/*******************************************************************\ - -Function: inverse - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - rationalt inverse(const rationalt &n) { rationalt tmp(n); @@ -206,18 +101,6 @@ rationalt inverse(const rationalt &n) return tmp; } -/*******************************************************************\ - -Function: operator<< - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::ostream &operator<<(std::ostream &out, const rationalt &a) { std::string d=integer2string(a.get_numerator()); diff --git a/src/util/rational.h b/src/util/rational.h index 6551b35a033..809f237c95a 100644 --- a/src/util/rational.h +++ b/src/util/rational.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_RATIONAL_H #define CPROVER_UTIL_RATIONAL_H diff --git a/src/util/rational_tools.cpp b/src/util/rational_tools.cpp index 3e57beefc91..cd03b1bd9c3 100644 --- a/src/util/rational_tools.cpp +++ b/src/util/rational_tools.cpp @@ -6,22 +6,13 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "rational.h" -#include "std_types.h" +/// \file +/// Rational Numbers #include "rational_tools.h" -/*******************************************************************\ - -Function: power10 - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include "rational.h" +#include "std_types.h" static mp_integer power10(size_t i) { @@ -33,18 +24,6 @@ static mp_integer power10(size_t i) return result; } -/*******************************************************************\ - -Function: to_rational - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool to_rational(const exprt &expr, rationalt &rational_value) { if(expr.id()!=ID_constant) @@ -99,18 +78,6 @@ bool to_rational(const exprt &expr, rationalt &rational_value) return false; } -/*******************************************************************\ - -Function: from_rational - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - constant_exprt from_rational(const rationalt &a) { std::string d=integer2string(a.get_numerator()); diff --git a/src/util/rational_tools.h b/src/util/rational_tools.h index 34dcf8d4932..fe4ed4d4321 100644 --- a/src/util/rational_tools.h +++ b/src/util/rational_tools.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_RATIONAL_TOOLS_H #define CPROVER_UTIL_RATIONAL_TOOLS_H diff --git a/src/util/ref_expr_set.cpp b/src/util/ref_expr_set.cpp index 7e54107fd52..2b9fc3b213d 100644 --- a/src/util/ref_expr_set.cpp +++ b/src/util/ref_expr_set.cpp @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Value Set + #include "ref_expr_set.h" const ref_expr_set_dt ref_expr_set_dt::blank; diff --git a/src/util/ref_expr_set.h b/src/util/ref_expr_set.h index d7846d092d1..1ab8ae328a3 100644 --- a/src/util/ref_expr_set.h +++ b/src/util/ref_expr_set.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Value Set + #ifndef CPROVER_UTIL_REF_EXPR_SET_H #define CPROVER_UTIL_REF_EXPR_SET_H @@ -32,7 +35,7 @@ class ref_expr_sett:public reference_counting bool empty() const { - if(d==NULL) + if(d==nullptr) return true; return d->expr_set.empty(); } @@ -49,13 +52,13 @@ class ref_expr_sett:public reference_counting bool make_union(const ref_expr_sett &s2) { - if(s2.d==NULL) + if(s2.d==nullptr) return false; if(s2.d==d) return false; - if(d==NULL) + if(d==nullptr) { copy_from(s2); return true; diff --git a/src/util/reference_counting.h b/src/util/reference_counting.h index e6746f3c3a6..4d5accb5ece 100644 --- a/src/util/reference_counting.h +++ b/src/util/reference_counting.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Reference Counting + #ifndef CPROVER_UTIL_REFERENCE_COUNTING_H #define CPROVER_UTIL_REFERENCE_COUNTING_H @@ -16,7 +19,7 @@ template class reference_counting { public: - reference_counting():d(NULL) + reference_counting():d(nullptr) { } @@ -28,12 +31,12 @@ class reference_counting // copy constructor reference_counting(const reference_counting &other):d(other.d) { - if(d!=NULL) + if(d!=nullptr) { assert(d->ref_count!=0); d->ref_count++; #ifdef REFERENCE_COUNTING_DEBUG - std::cout << "COPY " << d << " " << d->ref_count << std::endl; + std::cout << "COPY " << d << " " << d->ref_count << '\n'; #endif } } @@ -47,7 +50,7 @@ class reference_counting ~reference_counting() { remove_ref(d); - d=NULL; + d=nullptr; } void swap(reference_counting &other) @@ -58,12 +61,12 @@ class reference_counting void clear() { remove_ref(d); - d=NULL; + d=nullptr; } const T &read() const { - if(d==NULL) + if(d==nullptr) return T::blank; return *d; } @@ -101,7 +104,7 @@ class reference_counting remove_ref(d); d=other.d; - if(d!=NULL) + if(d!=nullptr) d->ref_count++; } @@ -115,20 +118,20 @@ class reference_counting template void reference_counting::remove_ref(dt *old_d) { - if(old_d==NULL) + if(old_d==nullptr) return; assert(old_d->ref_count!=0); #ifdef REFERENCE_COUNTING_DEBUG - std::cout << "R: " << old_d << " " << old_d->ref_count << std::endl; + std::cout << "R: " << old_d << " " << old_d->ref_count << '\n'; #endif old_d->ref_count--; if(old_d->ref_count==0) { #ifdef REFERENCE_COUNTING_DEBUG - std::cout << "DELETING " << old_d << std::endl; + std::cout << "DELETING " << old_d << '\n'; old_d->clear(); std::cout << "DEALLOCATING " << old_d << "\n"; #endif @@ -145,15 +148,15 @@ template void reference_counting::detatch() { #ifdef REFERENCE_COUNTING_DEBUG - std::cout << "DETATCH1: " << d << std::endl; + std::cout << "DETATCH1: " << d << '\n'; #endif - if(d==NULL) + if(d==nullptr) { d=new dt; #ifdef REFERENCE_COUNTING_DEBUG - std::cout << "ALLOCATED " << d << std::endl; + std::cout << "ALLOCATED " << d << '\n'; #endif } else if(d->ref_count>1) @@ -162,7 +165,7 @@ void reference_counting::detatch() d=new dt(*old_d); #ifdef REFERENCE_COUNTING_DEBUG - std::cout << "ALLOCATED " << d << std::endl; + std::cout << "ALLOCATED " << d << '\n'; #endif d->ref_count=1; @@ -172,7 +175,7 @@ void reference_counting::detatch() assert(d->ref_count==1); #ifdef REFERENCE_COUNTING_DEBUG - std::cout << "DETATCH2: " << d << std::endl; + std::cout << "DETATCH2: " << d << '\n' #endif } diff --git a/src/util/rename.cpp b/src/util/rename.cpp index b121edb6acb..52977ab8c6a 100644 --- a/src/util/rename.cpp +++ b/src/util/rename.cpp @@ -6,42 +6,25 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "rename.h" + #include -#include "rename.h" #include "symbol.h" #include "expr.h" #include "namespace.h" -/*******************************************************************\ - -Function: get_new_name - - Inputs: symbol to be renamed, namespace - - Outputs: new symbol - - Purpose: automated variable renaming - -\*******************************************************************/ - +/// automated variable renaming +/// \par parameters: symbol to be renamed, namespace +/// \return new symbol void get_new_name(symbolt &symbol, const namespacet &ns) { get_new_name(symbol.name, ns); } -/*******************************************************************\ - -Function: get_new_name - - Inputs: symbol to be renamed, namespace - - Outputs: new symbol - - Purpose: automated variable renaming - -\*******************************************************************/ - +/// automated variable renaming +/// \par parameters: symbol to be renamed, namespace +/// \return new symbol void get_new_name(irep_idt &new_name, const namespacet &ns) { const symbolt *symbol; @@ -53,19 +36,9 @@ void get_new_name(irep_idt &new_name, const namespacet &ns) new_name=prefix+std::to_string(ns.get_max(prefix)+1); } -/*******************************************************************\ - -Function: rename - - Inputs: expression, old name, new name - - Outputs: modifies the expression - returns false iff something was renamed - - Purpose: automated variable renaming - -\*******************************************************************/ - +/// automated variable renaming +/// \par parameters: expression, old name, new name +/// \return modifies the expression returns false iff something was renamed bool rename(exprt &expr, const irep_idt &old_name, const irep_idt &new_name) { diff --git a/src/util/rename.h b/src/util/rename.h index 16be66f9599..691f877d3a1 100644 --- a/src/util/rename.h +++ b/src/util/rename.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_RENAME_H #define CPROVER_UTIL_RENAME_H diff --git a/src/util/rename_symbol.cpp b/src/util/rename_symbol.cpp index c6930a01d87..59b257b09a0 100644 --- a/src/util/rename_symbol.cpp +++ b/src/util/rename_symbol.cpp @@ -6,54 +6,19 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "std_types.h" -#include "std_expr.h" #include "rename_symbol.h" -/*******************************************************************\ - -Function: rename_symbolt::rename_symbolt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include "std_types.h" +#include "std_expr.h" rename_symbolt::rename_symbolt() { } -/*******************************************************************\ - -Function: rename_symbolt::~rename_symbolt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - rename_symbolt::~rename_symbolt() { } -/*******************************************************************\ - -Function: rename_symbolt::insert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void rename_symbolt::insert( const symbol_exprt &old_expr, const symbol_exprt &new_expr) @@ -61,18 +26,6 @@ void rename_symbolt::insert( insert_expr(old_expr.get_identifier(), new_expr.get_identifier()); } -/*******************************************************************\ - -Function: rename_symbolt::rename - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool rename_symbolt::rename(exprt &dest) const { bool result=true; @@ -119,18 +72,6 @@ bool rename_symbolt::rename(exprt &dest) const return result; } -/*******************************************************************\ - -Function: rename_symbolt::have_to_rename - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool rename_symbolt::have_to_rename(const exprt &dest) const { if(expr_map.empty() && type_map.empty()) @@ -165,18 +106,6 @@ bool rename_symbolt::have_to_rename(const exprt &dest) const return false; } -/*******************************************************************\ - -Function: rename_symbolt::rename - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool rename_symbolt::rename(typet &dest) const { if(!have_to_rename(dest)) @@ -263,18 +192,6 @@ bool rename_symbolt::rename(typet &dest) const return result; } -/*******************************************************************\ - -Function: rename_symbolt::have_to_rename - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool rename_symbolt::have_to_rename(const typet &dest) const { if(expr_map.empty() && type_map.empty()) diff --git a/src/util/rename_symbol.h b/src/util/rename_symbol.h index e103ff37ecd..88e08991b6d 100644 --- a/src/util/rename_symbol.h +++ b/src/util/rename_symbol.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_RENAME_SYMBOL_H #define CPROVER_UTIL_RENAME_SYMBOL_H diff --git a/src/util/replace_expr.cpp b/src/util/replace_expr.cpp index fc419aa59fa..9655359796a 100644 --- a/src/util/replace_expr.cpp +++ b/src/util/replace_expr.cpp @@ -6,19 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "replace_expr.h" - -/*******************************************************************\ - -Function: replace_expr - - Inputs: - Outputs: - - Purpose: - -\*******************************************************************/ +#include "replace_expr.h" bool replace_expr(const exprt &what, const exprt &by, exprt &dest) { @@ -36,18 +25,6 @@ bool replace_expr(const exprt &what, const exprt &by, exprt &dest) return result; } -/*******************************************************************\ - -Function: replace_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool replace_expr(const replace_mapt &what, exprt &dest) { { diff --git a/src/util/replace_expr.h b/src/util/replace_expr.h index 74b2a64374c..058909076dc 100644 --- a/src/util/replace_expr.h +++ b/src/util/replace_expr.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_REPLACE_EXPR_H #define CPROVER_UTIL_REPLACE_EXPR_H diff --git a/src/util/replace_symbol.cpp b/src/util/replace_symbol.cpp index 4dce48d8b93..2585a69e61d 100644 --- a/src/util/replace_symbol.cpp +++ b/src/util/replace_symbol.cpp @@ -6,54 +6,19 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "std_types.h" -#include "std_expr.h" #include "replace_symbol.h" -/*******************************************************************\ - -Function: replace_symbolt::replace_symbolt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include "std_types.h" +#include "std_expr.h" replace_symbolt::replace_symbolt() { } -/*******************************************************************\ - -Function: replace_symbolt::~replace_symbolt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - replace_symbolt::~replace_symbolt() { } -/*******************************************************************\ - -Function: replace_symbolt::insert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void replace_symbolt::insert( const symbol_exprt &old_expr, const exprt &new_expr) @@ -62,18 +27,6 @@ void replace_symbolt::insert( old_expr.get_identifier(), new_expr)); } -/*******************************************************************\ - -Function: replace_symbolt::replace - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool replace_symbolt::replace(exprt &dest) const { bool result=true; @@ -120,18 +73,6 @@ bool replace_symbolt::replace(exprt &dest) const return result; } -/*******************************************************************\ - -Function: replace_symbolt::have_to_replace - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool replace_symbolt::have_to_replace(const exprt &dest) const { // first look at type @@ -163,18 +104,6 @@ bool replace_symbolt::have_to_replace(const exprt &dest) const return false; } -/*******************************************************************\ - -Function: replace_symbolt::replace - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool replace_symbolt::replace(typet &dest) const { if(!have_to_replace(dest)) @@ -207,7 +136,7 @@ bool replace_symbolt::replace(typet &dest) const else if(dest.id()==ID_code) { code_typet &code_type=to_code_type(dest); - replace(code_type.return_type()); + (void)replace(code_type.return_type()); code_typet::parameterst ¶meters=code_type.parameters(); for(code_typet::parameterst::iterator it = parameters.begin(); it!=parameters.end(); @@ -236,18 +165,6 @@ bool replace_symbolt::replace(typet &dest) const return result; } -/*******************************************************************\ - -Function: replace_symbolt::have_to_replace - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool replace_symbolt::have_to_replace(const typet &dest) const { if(dest.has_subtype()) diff --git a/src/util/replace_symbol.h b/src/util/replace_symbol.h index f26c8eb067a..ebc1102e921 100644 --- a/src/util/replace_symbol.h +++ b/src/util/replace_symbol.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_REPLACE_SYMBOL_H #define CPROVER_UTIL_REPLACE_SYMBOL_H @@ -56,6 +57,11 @@ class replace_symbolt type_map.clear(); } + bool empty() const + { + return expr_map.empty() && type_map.empty(); + } + replace_symbolt(); virtual ~replace_symbolt(); diff --git a/src/util/run.cpp b/src/util/run.cpp index 8a8a1c68659..c01aff35bd6 100644 --- a/src/util/run.cpp +++ b/src/util/run.cpp @@ -8,6 +8,8 @@ Date: August 2012 \*******************************************************************/ +#include "run.h" + #include #ifdef _WIN32 @@ -31,20 +33,6 @@ Date: August 2012 #include #include -#include "run.h" - -/*******************************************************************\ - -Function: run_shell - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - int run_shell(const std::string &command) { std::string shell="/bin/sh"; @@ -54,18 +42,6 @@ int run_shell(const std::string &command) return run(shell, argv, "", ""); } -/*******************************************************************\ - -Function: run - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - int run( const std::string &what, const std::vector &argv, @@ -141,13 +117,13 @@ int run( { // resume signals remove_signal_catcher(); - sigprocmask(SIG_SETMASK, &old_mask, NULL); + sigprocmask(SIG_SETMASK, &old_mask, nullptr); char **_argv=new char * [argv.size()+1]; for(std::size_t i=0; iget_value(), true); } -/*******************************************************************\ - -Function: insert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - SHARING_MAPT2(, const_find_type)::insert( const value_type &p, const tvt &key_exists) @@ -652,18 +535,6 @@ SHARING_MAPT2(, const_find_type)::insert( return insert(p.first, p.second, key_exists); } -/*******************************************************************\ - -Function: place - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - SHARING_MAPT2(, find_type)::place( const key_type &k, const mapped_type &m) @@ -682,36 +553,12 @@ SHARING_MAPT2(, find_type)::place( return find_type(p->get_value(), true); } -/*******************************************************************\ - -Function: place - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - SHARING_MAPT2(, find_type)::place( const value_type &p) { return place(p.first, p.second); } -/*******************************************************************\ - -Function: find - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - SHARING_MAPT2(, find_type)::find( const key_type &k, const tvt &key_exists) @@ -731,18 +578,6 @@ SHARING_MAPT2(, find_type)::find( } -/*******************************************************************\ - -Function: find - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - SHARING_MAPT2(, const_find_type)::find(const key_type &k) const { const node_type *p=get_leaf_node(k); @@ -753,18 +588,6 @@ SHARING_MAPT2(, const_find_type)::find(const key_type &k) const return const_find_type(p->get_value(), true); } -/*******************************************************************\ - -Function: at - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - SHARING_MAPT2(, mapped_type &)::at( const key_type &k, const tvt &key_exists) @@ -777,18 +600,6 @@ SHARING_MAPT2(, mapped_type &)::at( return r.first; } -/*******************************************************************\ - -Function: at - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - SHARING_MAPT2(const, mapped_type &)::at(const key_type &k) const { const_find_type r=find(k); @@ -798,18 +609,6 @@ SHARING_MAPT2(const, mapped_type &)::at(const key_type &k) const return r.first; } -/*******************************************************************\ - -Function: operator[] - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - SHARING_MAPT2(, mapped_type &)::operator[](const key_type &k) { return place(k, mapped_type()).first; diff --git a/src/util/sharing_node.h b/src/util/sharing_node.h index 1e3d29a413e..9f8cc0a4416 100644 --- a/src/util/sharing_node.h +++ b/src/util/sharing_node.h @@ -6,6 +6,9 @@ Author: Daniel Poetzl \*******************************************************************/ +/// \file +/// Sharing node + #ifndef CPROVER_UTIL_SHARING_NODE_H #define CPROVER_UTIL_SHARING_NODE_H diff --git a/src/util/signal_catcher.cpp b/src/util/signal_catcher.cpp index b0178340543..8d25e275e77 100644 --- a/src/util/signal_catcher.cpp +++ b/src/util/signal_catcher.cpp @@ -8,6 +8,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "signal_catcher.h" + #if defined(_WIN32) #include #else @@ -17,8 +19,6 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "signal_catcher.h" - // Here we have an instance of an ugly global object. // It keeps track of any child processes that we'll kill // when we are told to terminate. @@ -28,18 +28,6 @@ Author: Daniel Kroening, kroening@kroening.com std::vector pids_of_children; #endif -/*******************************************************************\ - -Function: install_signal_catcher - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void install_signal_catcher() { #if defined(_WIN32) @@ -53,22 +41,10 @@ void install_signal_catcher() sigfillset(&(act.sa_mask)); // install signal handler - sigaction(SIGTERM, &act, NULL); + sigaction(SIGTERM, &act, nullptr); #endif } -/*******************************************************************\ - -Function: remove_signal_catcher - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void remove_signal_catcher() { #if defined(_WIN32) @@ -81,22 +57,10 @@ void remove_signal_catcher() act.sa_flags=0; sigfillset(&(act.sa_mask)); - sigaction(SIGTERM, &act, NULL); + sigaction(SIGTERM, &act, nullptr); #endif } -/*******************************************************************\ - -Function: signal_catcher - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void signal_catcher(int sig) { #if defined(_WIN32) diff --git a/src/util/signal_catcher.h b/src/util/signal_catcher.h index 3896252ad20..399e6bb960e 100644 --- a/src/util/signal_catcher.h +++ b/src/util/signal_catcher.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_SIGNAL_CATCHER_H #define CPROVER_UTIL_SIGNAL_CATCHER_H diff --git a/src/util/simplify_expr.cpp b/src/util/simplify_expr.cpp index 6f7dcf64f4a..ee6492c8124 100644 --- a/src/util/simplify_expr.cpp +++ b/src/util/simplify_expr.cpp @@ -6,12 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "simplify_expr.h" + #include #include +#include "c_types.h" #include "rational.h" #include "simplify_expr_class.h" -#include "simplify_expr.h" #include "mp_arith.h" #include "arith_tools.h" #include "replace_expr.h" @@ -63,18 +65,6 @@ struct simplify_expr_cachet simplify_expr_cachet simplify_expr_cache; #endif -/*******************************************************************\ - -Function: simplify_exprt::simplify_abs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_abs(exprt &expr) { if(expr.operands().size()!=1) @@ -115,18 +105,6 @@ bool simplify_exprt::simplify_abs(exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_sign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_sign(exprt &expr) { if(expr.operands().size()!=1) @@ -157,18 +135,6 @@ bool simplify_exprt::simplify_sign(exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_popcount - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_popcount(exprt &expr) { if(expr.operands().size()!=1) @@ -200,18 +166,6 @@ bool simplify_exprt::simplify_popcount(exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_typecast - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_typecast(exprt &expr) { if(expr.operands().size()!=1) @@ -268,7 +222,7 @@ bool simplify_exprt::simplify_typecast(exprt &expr) return false; } - // elminiate casts to proper bool + // eliminate casts to proper bool if(expr_type.id()==ID_bool) { // rewrite (bool)x to x!=0 @@ -283,7 +237,7 @@ bool simplify_exprt::simplify_typecast(exprt &expr) return false; } - // elminiate casts to _Bool + // eliminate casts to _Bool if(expr_type.id()==ID_c_bool && op_type.id()!=ID_bool) { @@ -335,7 +289,7 @@ bool simplify_exprt::simplify_typecast(exprt &expr) expr.op0().operands().size()==1 && op_type.id()==ID_pointer) { - expr.op0().type()=unsignedbv_typet(config.ansi_c.pointer_width); + expr.op0().type()=size_type(); simplify_typecast(expr.op0()); // rec. call simplify_typecast(expr); // rec. call return false; @@ -352,17 +306,15 @@ bool simplify_exprt::simplify_typecast(exprt &expr) expr.op0().op0().op0().is_zero() && op_type.id()==ID_pointer) { - unsignedbv_typet size_type(config.ansi_c.pointer_width); - mp_integer sub_size=pointer_offset_size(op_type.subtype(), ns); if(sub_size!=-1) { // void* if(sub_size==0 || sub_size==1) - expr.op0()=typecast_exprt(expr.op0().op1(), size_type); + expr.op0()=typecast_exprt(expr.op0().op1(), size_type()); else - expr.op0()=mult_exprt(from_integer(sub_size, size_type), - typecast_exprt(expr.op0().op1(), size_type)); + expr.op0()=mult_exprt(from_integer(sub_size, size_type()), + typecast_exprt(expr.op0().op1(), size_type())); simplify_rec(expr.op0()); simplify_typecast(expr); // rec. call @@ -429,7 +381,7 @@ bool simplify_exprt::simplify_typecast(exprt &expr) if(step>0) { - const unsignedbv_typet size_t_type(config.ansi_c.pointer_width); + const typet size_t_type(size_type()); expr.op0().type()=size_t_type; for(auto &op : expr.op0().operands()) @@ -760,18 +712,6 @@ bool simplify_exprt::simplify_typecast(exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_dereference - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_dereference(exprt &expr) { const exprt &pointer=to_dereference_expr(expr).pointer(); @@ -830,18 +770,6 @@ bool simplify_exprt::simplify_dereference(exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_if_implies - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_if_implies( exprt &expr, const exprt &cond, @@ -933,18 +861,6 @@ bool simplify_exprt::simplify_if_implies( return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_if_recursive - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_if_recursive( exprt &expr, const exprt &cond, @@ -977,18 +893,6 @@ bool simplify_exprt::simplify_if_recursive( return result; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_if_conj - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_if_conj( exprt &expr, const exprt &cond) @@ -1010,18 +914,6 @@ bool simplify_exprt::simplify_if_conj( return result; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_if_disj - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_if_disj( exprt &expr, const exprt &cond) @@ -1043,18 +935,6 @@ bool simplify_exprt::simplify_if_disj( return result; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_if_branch - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_if_branch( exprt &trueexpr, exprt &falseexpr, @@ -1087,18 +967,6 @@ bool simplify_exprt::simplify_if_branch( return tresult && fresult; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_if_cond - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_if_cond(exprt &expr) { bool result=true; @@ -1135,18 +1003,6 @@ bool simplify_exprt::simplify_if_cond(exprt &expr) return result; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_if_preorder - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_if_preorder(if_exprt &expr) { exprt &cond=expr.cond(); @@ -1232,18 +1088,6 @@ bool simplify_exprt::simplify_if_preorder(if_exprt &expr) return result; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_if - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_if(if_exprt &expr) { exprt &cond=expr.cond(); @@ -1352,18 +1196,6 @@ bool simplify_exprt::simplify_if(if_exprt &expr) return result; } -/*******************************************************************\ - -Function: simplify_exprt::get_values - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::get_values( const exprt &expr, value_listt &value_list) @@ -1390,18 +1222,6 @@ bool simplify_exprt::get_values( return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_lambda - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_lambda(exprt &expr) { bool result=true; @@ -1409,18 +1229,6 @@ bool simplify_exprt::simplify_lambda(exprt &expr) return result; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_with - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_with(exprt &expr) { bool result=true; @@ -1494,18 +1302,6 @@ bool simplify_exprt::simplify_with(exprt &expr) return result; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_update - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_update(exprt &expr) { if(expr.operands().size()!=3) @@ -1553,7 +1349,7 @@ bool simplify_exprt::simplify_update(exprt &expr) value_ptr=&value_ptr->operands()[number]; } else - return true; // give up, unkown designator + return true; // give up, unknown designator } // found, done @@ -1563,18 +1359,6 @@ bool simplify_exprt::simplify_update(exprt &expr) return false; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_object - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_object(exprt &expr) { if(expr.id()==ID_plus) @@ -1666,18 +1450,6 @@ bool simplify_exprt::simplify_object(exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::bits2expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt simplify_exprt::bits2expr( const std::string &bits, const typet &_type, @@ -1792,18 +1564,6 @@ exprt simplify_exprt::bits2expr( return nil_exprt(); } -/*******************************************************************\ - -Function: simplify_exprt::expr2bits - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string simplify_exprt::expr2bits( const exprt &expr, bool little_endian) @@ -1864,18 +1624,6 @@ std::string simplify_exprt::expr2bits( return ""; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_byte_extract - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_byte_extract(byte_extract_exprt &expr) { // lift up any ID_if on the object @@ -2047,7 +1795,9 @@ bool simplify_exprt::simplify_byte_extract(byte_extract_exprt &expr) assert(el_size%8==0); mp_integer el_bytes=el_size/8; - if(base_type_eq(expr.type(), op_type_ptr->subtype(), ns)) + if(base_type_eq(expr.type(), op_type_ptr->subtype(), ns) || + (expr.type().id()==ID_pointer && + op_type_ptr->subtype().id()==ID_pointer)) { if(offset%el_bytes==0) { @@ -2058,6 +1808,9 @@ bool simplify_exprt::simplify_byte_extract(byte_extract_exprt &expr) result, from_integer(offset, expr.offset().type())); + if(!base_type_eq(expr.type(), op_type_ptr->subtype(), ns)) + result.make_typecast(expr.type()); + expr.swap(result); simplify_rec(expr); return false; @@ -2126,18 +1879,6 @@ bool simplify_exprt::simplify_byte_extract(byte_extract_exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_byte_update - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_byte_update(byte_update_exprt &expr) { // byte_update(byte_update(root, offset, value), offset, value2) => @@ -2410,18 +2151,6 @@ bool simplify_exprt::simplify_byte_update(byte_update_exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_node_preorder - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_node_preorder(exprt &expr) { bool result=true; @@ -2447,18 +2176,6 @@ bool simplify_exprt::simplify_node_preorder(exprt &expr) return result; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_node - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_node(exprt &expr) { if(!expr.has_operands()) @@ -2514,8 +2231,7 @@ bool simplify_exprt::simplify_node(exprt &expr) result=simplify_mod(expr) && result; else if(expr.id()==ID_bitnot) result=simplify_bitnot(expr) && result; - else if(expr.id()==ID_bitnot || - expr.id()==ID_bitand || + else if(expr.id()==ID_bitand || expr.id()==ID_bitor || expr.id()==ID_bitxor) result=simplify_bitwise(expr) && result; @@ -2592,19 +2308,7 @@ bool simplify_exprt::simplify_node(exprt &expr) return result; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_rec - - Inputs: - - Outputs: returns true if expression unchanged; - returns false if changed - - Purpose: - -\*******************************************************************/ - +/// \return returns true if expression unchanged; returns false if changed bool simplify_exprt::simplify_rec(exprt &expr) { // look up in cache @@ -2618,7 +2322,7 @@ bool simplify_exprt::simplify_rec(exprt &expr) { const exprt &new_expr=cache_result.first->second; - if(new_expr.id()==irep_idt()) + if(new_expr.id().empty()) return true; // no change expr=new_expr; @@ -2664,18 +2368,6 @@ bool simplify_exprt::simplify_rec(exprt &expr) return result; } -/*******************************************************************\ - -Function: simplify_exprt::simplify - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify(exprt &expr) { #ifdef DEBUG_ON_DEMAND @@ -2690,35 +2382,11 @@ bool simplify_exprt::simplify(exprt &expr) return res; } -/*******************************************************************\ - -Function: simplify - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify(exprt &expr, const namespacet &ns) { return simplify_exprt(ns).simplify(expr); } -/*******************************************************************\ - -Function: simplify_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt simplify_expr(const exprt &src, const namespacet &ns) { exprt tmp=src; diff --git a/src/util/simplify_expr.h b/src/util/simplify_expr.h index f327f26ca52..1ef1533eb30 100644 --- a/src/util/simplify_expr.h +++ b/src/util/simplify_expr.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_SIMPLIFY_EXPR_H #define CPROVER_UTIL_SIMPLIFY_EXPR_H diff --git a/src/util/simplify_expr_array.cpp b/src/util/simplify_expr_array.cpp index f00c039a6ef..26a61f65be8 100644 --- a/src/util/simplify_expr_array.cpp +++ b/src/util/simplify_expr_array.cpp @@ -6,9 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "simplify_expr_class.h" + #include -#include "simplify_expr_class.h" #include "expr.h" #include "namespace.h" #include "std_expr.h" @@ -16,18 +17,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "arith_tools.h" #include "pointer_offset_size.h" -/*******************************************************************\ - -Function: simplify_exprt::simplify_index - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_index(exprt &expr) { bool result=true; diff --git a/src/util/simplify_expr_boolean.cpp b/src/util/simplify_expr_boolean.cpp index b747047cf98..238dfd384c9 100644 --- a/src/util/simplify_expr_boolean.cpp +++ b/src/util/simplify_expr_boolean.cpp @@ -6,26 +6,15 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "simplify_expr_class.h" + #include #include -#include "simplify_expr_class.h" #include "expr.h" #include "namespace.h" #include "std_expr.h" -/*******************************************************************\ - -Function: simplify_exprt::simplify_boolean - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_boolean(exprt &expr) { if(!expr.has_operands()) @@ -199,18 +188,6 @@ bool simplify_exprt::simplify_boolean(exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_not - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_not(exprt &expr) { if(expr.operands().size()!=1) diff --git a/src/util/simplify_expr_class.h b/src/util/simplify_expr_class.h index bb0c5eed419..f5fa55eb324 100644 --- a/src/util/simplify_expr_class.h +++ b/src/util/simplify_expr_class.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_SIMPLIFY_EXPR_CLASS_H #define CPROVER_UTIL_SIMPLIFY_EXPR_CLASS_H diff --git a/src/util/simplify_expr_floatbv.cpp b/src/util/simplify_expr_floatbv.cpp index 7115e23024a..cff452cfcbd 100644 --- a/src/util/simplify_expr_floatbv.cpp +++ b/src/util/simplify_expr_floatbv.cpp @@ -6,27 +6,16 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "simplify_expr_class.h" + #include -#include "simplify_expr_class.h" #include "expr.h" #include "namespace.h" #include "ieee_float.h" #include "std_expr.h" #include "arith_tools.h" -/*******************************************************************\ - -Function: simplify_exprt::simplify_isinf - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_isinf(exprt &expr) { if(expr.operands().size()!=1) @@ -45,18 +34,6 @@ bool simplify_exprt::simplify_isinf(exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_isnan - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_isnan(exprt &expr) { if(expr.operands().size()!=1) @@ -72,18 +49,6 @@ bool simplify_exprt::simplify_isnan(exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_isnormal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_isnormal(exprt &expr) { if(expr.operands().size()!=1) @@ -99,18 +64,6 @@ bool simplify_exprt::simplify_isnormal(exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_abs - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - #if 0 bool simplify_exprt::simplify_abs(exprt &expr) { @@ -153,18 +106,6 @@ bool simplify_exprt::simplify_abs(exprt &expr) } #endif -/*******************************************************************\ - -Function: simplify_exprt::simplify_sign - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - #if 0 bool simplify_exprt::simplify_sign(exprt &expr) { @@ -197,18 +138,6 @@ bool simplify_exprt::simplify_sign(exprt &expr) } #endif -/*******************************************************************\ - -Function: simplify_exprt::simplify_floatbv_typecast - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_floatbv_typecast(exprt &expr) { // These casts usually reduce precision, and thus, usually round. @@ -338,18 +267,6 @@ bool simplify_exprt::simplify_floatbv_typecast(exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_floatbv_op - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_floatbv_op(exprt &expr) { const typet &type=ns.follow(expr.type()); @@ -413,18 +330,6 @@ bool simplify_exprt::simplify_floatbv_op(exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_ieee_float_relation - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_ieee_float_relation(exprt &expr) { assert(expr.id()==ID_ieee_float_equal || diff --git a/src/util/simplify_expr_int.cpp b/src/util/simplify_expr_int.cpp index c9c8a7f12a0..a94674c3fd9 100644 --- a/src/util/simplify_expr_int.cpp +++ b/src/util/simplify_expr_int.cpp @@ -6,11 +6,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "simplify_expr_class.h" + #include #include "base_type.h" #include "rational.h" -#include "simplify_expr_class.h" #include "expr.h" #include "namespace.h" #include "config.h" @@ -22,18 +23,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "rational_tools.h" #include "ieee_float.h" -/*******************************************************************\ - -Function: simplify_exprt::simplify_bswap - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_bswap(exprt &expr) { if(expr.type().id()==ID_unsignedbv && @@ -66,18 +55,6 @@ bool simplify_exprt::simplify_bswap(exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_mult - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_mult(exprt &expr) { // check to see if it is a number type @@ -183,18 +160,6 @@ bool simplify_exprt::simplify_mult(exprt &expr) return result; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_div - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_div(exprt &expr) { if(!is_number(expr.type())) @@ -315,18 +280,6 @@ bool simplify_exprt::simplify_div(exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_mod - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_mod(exprt &expr) { if(!is_number(expr.type())) @@ -376,18 +329,6 @@ bool simplify_exprt::simplify_mod(exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_plus - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_plus(exprt &expr) { if(!is_number(expr.type()) && @@ -545,18 +486,6 @@ bool simplify_exprt::simplify_plus(exprt &expr) return result; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_minus - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_minus(exprt &expr) { if(!is_number(expr.type()) && @@ -616,18 +545,6 @@ bool simplify_exprt::simplify_minus(exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_bitwise - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_bitwise(exprt &expr) { if(!is_bitvector_type(expr.type())) @@ -747,7 +664,7 @@ bool simplify_exprt::simplify_bitwise(exprt &expr) result=false; } - // now erase zeros out of bitor, bitxor + // now erase 'all zeros' out of bitor, bitxor if(expr.id()==ID_bitor || expr.id()==ID_bitxor) { @@ -766,6 +683,28 @@ bool simplify_exprt::simplify_bitwise(exprt &expr) } } + // now erase 'all ones' out of bitand + + if(expr.id()==ID_bitand) + { + for(exprt::operandst::iterator + it=expr.operands().begin(); + it!=expr.operands().end(); + ) // no it++ + { + if(it->is_constant() && + id2string(to_constant_expr(*it).get_value()).find('0')== + std::string::npos && + expr.operands().size()>1) + { + it=expr.operands().erase(it); + result=false; + } + else + it++; + } + } + // two operands that are syntactically the same if(expr.operands().size()==2 && @@ -798,18 +737,6 @@ bool simplify_exprt::simplify_bitwise(exprt &expr) return result; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_extractbit - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_extractbit(exprt &expr) { const typet &op0_type=expr.op0().type(); @@ -844,18 +771,6 @@ bool simplify_exprt::simplify_extractbit(exprt &expr) return false; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_concatenation - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_concatenation(exprt &expr) { bool result=true; @@ -943,18 +858,6 @@ bool simplify_exprt::simplify_concatenation(exprt &expr) return result; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_shifts - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_shifts(exprt &expr) { if(!is_number(expr.type())) @@ -1067,18 +970,6 @@ bool simplify_exprt::simplify_shifts(exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_power - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_power(exprt &expr) { if(!is_number(expr.type())) @@ -1101,18 +992,7 @@ bool simplify_exprt::simplify_power(exprt &expr) return false; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_extractbits - - Inputs: - - Outputs: - - Purpose: Simplifies extracting of bits from a constant. - -\*******************************************************************/ - +/// Simplifies extracting of bits from a constant. bool simplify_exprt::simplify_extractbits(exprt &expr) { assert(expr.operands().size()==3); @@ -1161,18 +1041,6 @@ bool simplify_exprt::simplify_extractbits(exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_unary_plus - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_unary_plus(exprt &expr) { if(expr.operands().size()!=1) @@ -1183,18 +1051,6 @@ bool simplify_exprt::simplify_unary_plus(exprt &expr) return false; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_unary_minus - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_unary_minus(exprt &expr) { if(expr.operands().size()!=1) @@ -1272,18 +1128,6 @@ bool simplify_exprt::simplify_unary_minus(exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_bitnot - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_bitnot(exprt &expr) { if(!expr.has_operands()) @@ -1320,18 +1164,7 @@ bool simplify_exprt::simplify_bitnot(exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_inequality - - Inputs: - - Outputs: - - Purpose: simplifies inequalities !=, <=, <, >=, >, and also == - -\*******************************************************************/ - +/// simplifies inequalities !=, <=, <, >=, >, and also == bool simplify_exprt::simplify_inequality(exprt &expr) { exprt::operandst &operands=expr.operands(); @@ -1548,18 +1381,6 @@ bool simplify_exprt::simplify_inequality(exprt &expr) return false; } -/*******************************************************************\ - -Function: simplify_exprt::eliminate_common_addends - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::eliminate_common_addends( exprt &op0, exprt &op1) @@ -1608,18 +1429,6 @@ bool simplify_exprt::eliminate_common_addends( return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_inequality_not_constant - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_inequality_not_constant(exprt &expr) { exprt::operandst &operands=expr.operands(); @@ -1746,18 +1555,7 @@ bool simplify_exprt::simplify_inequality_not_constant(exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_inequality_constant - - Inputs: an inequality with a constant on the RHS - - Outputs: - - Purpose: - -\*******************************************************************/ - +/// \par parameters: an inequality with a constant on the RHS bool simplify_exprt::simplify_inequality_constant(exprt &expr) { // the constant is always on the RHS diff --git a/src/util/simplify_expr_pointer.cpp b/src/util/simplify_expr_pointer.cpp index 9bc2496f5ff..1044d43dac4 100644 --- a/src/util/simplify_expr_pointer.cpp +++ b/src/util/simplify_expr_pointer.cpp @@ -6,9 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "simplify_expr_class.h" + #include -#include "simplify_expr_class.h" +#include "c_types.h" #include "expr.h" #include "namespace.h" #include "std_expr.h" @@ -20,18 +22,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "prefix.h" #include "pointer_predicates.h" -/*******************************************************************\ - -Function: is_dereference_integer_object - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static bool is_dereference_integer_object( const exprt &expr, mp_integer &address) @@ -61,18 +51,6 @@ static bool is_dereference_integer_object( return false; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_address_of_arg - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_address_of_arg(exprt &expr) { if(expr.id()==ID_index) @@ -100,11 +78,10 @@ bool simplify_exprt::simplify_address_of_arg(exprt &expr) if(!to_integer(expr.op1(), index) && step_size!=-1) { - unsignedbv_typet int_type(config.ansi_c.pointer_width); pointer_typet pointer_type; pointer_type.subtype()=expr.type(); typecast_exprt typecast_expr( - from_integer(step_size*index+address, int_type), pointer_type); + from_integer(step_size*index+address, index_type()), pointer_type); exprt new_expr=dereference_exprt(typecast_expr, expr.type()); expr=new_expr; result=true; @@ -137,11 +114,10 @@ bool simplify_exprt::simplify_address_of_arg(exprt &expr) mp_integer offset=member_offset(struct_type, member, ns); if(offset!=-1) { - unsignedbv_typet int_type(config.ansi_c.pointer_width); pointer_typet pointer_type; pointer_type.subtype()=expr.type(); typecast_exprt typecast_expr( - from_integer(address+offset, int_type), pointer_type); + from_integer(address+offset, index_type()), pointer_type); exprt new_expr=dereference_exprt(typecast_expr, expr.type()); expr=new_expr; result=true; @@ -192,18 +168,6 @@ bool simplify_exprt::simplify_address_of_arg(exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_address_of - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_address_of(exprt &expr) { if(expr.operands().size()!=1) @@ -246,18 +210,6 @@ bool simplify_exprt::simplify_address_of(exprt &expr) return result; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_pointer_offset - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_pointer_offset(exprt &expr) { if(expr.operands().size()!=1) @@ -384,18 +336,19 @@ bool simplify_exprt::simplify_pointer_offset(exprt &expr) if(ptr_expr.size()!=1 || int_expr.empty()) return true; - typet pointer_type=ptr_expr.front().type(); + typet pointer_sub_type=ptr_expr.front().type().subtype(); + if(pointer_sub_type.id()==ID_empty) + pointer_sub_type=char_type(); mp_integer element_size= - pointer_offset_size(pointer_type.subtype(), ns); + pointer_offset_size(pointer_sub_type, ns); - if(element_size==0) + if(element_size<0) return true; // this might change the type of the pointer! - exprt pointer_offset(ID_pointer_offset, expr.type()); - pointer_offset.copy_to_operands(ptr_expr.front()); - simplify_node(pointer_offset); + exprt pointer_offset_expr=pointer_offset(ptr_expr.front()); + simplify_node(pointer_offset_expr); exprt sum; @@ -416,7 +369,7 @@ bool simplify_exprt::simplify_pointer_offset(exprt &expr) simplify_node(product); - expr=binary_exprt(pointer_offset, ID_plus, product, expr.type()); + expr=binary_exprt(pointer_offset_expr, ID_plus, product, expr.type()); simplify_node(expr); @@ -435,18 +388,6 @@ bool simplify_exprt::simplify_pointer_offset(exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_inequality_address_of - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_inequality_address_of(exprt &expr) { assert(expr.type().id()==ID_bool); @@ -488,18 +429,6 @@ bool simplify_exprt::simplify_inequality_address_of(exprt &expr) return true; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_inequality_pointer_object - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_inequality_pointer_object(exprt &expr) { assert(expr.type().id()==ID_bool); @@ -532,18 +461,6 @@ bool simplify_exprt::simplify_inequality_pointer_object(exprt &expr) return false; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_pointer_object - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_pointer_object(exprt &expr) { if(expr.operands().size()!=1) @@ -572,18 +489,6 @@ bool simplify_exprt::simplify_pointer_object(exprt &expr) return result; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_dynamic_object - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_dynamic_object(exprt &expr) { if(expr.operands().size()!=1) @@ -640,18 +545,6 @@ bool simplify_exprt::simplify_dynamic_object(exprt &expr) return result; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_invalid_pointer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_invalid_pointer(exprt &expr) { if(expr.operands().size()!=1) @@ -681,18 +574,6 @@ bool simplify_exprt::simplify_invalid_pointer(exprt &expr) return result; } -/*******************************************************************\ - -Function: simplify_exprt::objects_equal - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt simplify_exprt::objects_equal(const exprt &a, const exprt &b) { if(a==b) @@ -717,18 +598,6 @@ tvt simplify_exprt::objects_equal(const exprt &a, const exprt &b) return tvt::unknown(); } -/*******************************************************************\ - -Function: simplify_exprt::objects_equal_address_of - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - tvt simplify_exprt::objects_equal_address_of(const exprt &a, const exprt &b) { if(a==b) @@ -753,18 +622,6 @@ tvt simplify_exprt::objects_equal_address_of(const exprt &a, const exprt &b) return tvt::unknown(); } -/*******************************************************************\ - -Function: simplify_exprt::simplify_object_size - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_object_size(exprt &expr) { if(expr.operands().size()!=1) @@ -811,18 +668,6 @@ bool simplify_exprt::simplify_object_size(exprt &expr) return result; } -/*******************************************************************\ - -Function: simplify_exprt::simplify_good_pointer - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_good_pointer(exprt &expr) { if(expr.operands().size()!=1) diff --git a/src/util/simplify_expr_struct.cpp b/src/util/simplify_expr_struct.cpp index a59c355e72c..a6ac35ca008 100644 --- a/src/util/simplify_expr_struct.cpp +++ b/src/util/simplify_expr_struct.cpp @@ -6,27 +6,16 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "simplify_expr_class.h" + #include -#include "simplify_expr_class.h" #include "expr.h" #include "namespace.h" #include "std_expr.h" #include "pointer_offset_size.h" #include "arith_tools.h" -/*******************************************************************\ - -Function: simplify_exprt::simplify_member - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool simplify_exprt::simplify_member(exprt &expr) { if(expr.operands().size()!=1) diff --git a/src/util/simplify_utils.cpp b/src/util/simplify_utils.cpp index ff5abf78930..53b2f38f7e1 100644 --- a/src/util/simplify_utils.cpp +++ b/src/util/simplify_utils.cpp @@ -6,24 +6,13 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "simplify_utils.h" -/*******************************************************************\ - -Function: simplify_exprt::sort_operands - - Inputs: operand list - - Outputs: modifies operand list - returns true iff nothing was changed - - Purpose: sort operands of an expression according to ordering - defined by operator< - -\*******************************************************************/ +#include +/// sort operands of an expression according to ordering defined by operator< +/// \par parameters: operand list +/// \return modifies operand list returns true iff nothing was changed bool sort_operands(exprt::operandst &operands) { bool do_sort=false; @@ -48,19 +37,7 @@ bool sort_operands(exprt::operandst &operands) return false; } -/*******************************************************************\ - -Function: sort_and_join - - Inputs: - - Outputs: - - Purpose: produce canonical ordering for associative and commutative - binary operators - -\*******************************************************************/ - +/// produce canonical ordering for associative and commutative binary operators // The entries // { ID_plus, ID_floatbv }, // { ID_mult, ID_floatbv }, @@ -121,7 +98,7 @@ static bool sort_and_join( const struct saj_tablet &saj_entry, const irep_idt &type_id) { - for(unsigned i=0; saj_entry.type_ids[i]!=irep_idt(); i++) + for(unsigned i=0; !saj_entry.type_ids[i].empty(); i++) if(type_id==saj_entry.type_ids[i]) return true; @@ -134,7 +111,7 @@ static const struct saj_tablet &sort_and_join( { unsigned i=0; - for( ; saj_table[i].id!=irep_idt(); i++) + for( ; !saj_table[i].id.empty(); i++) if(id==saj_table[i].id && sort_and_join(saj_table[i], type_id)) return saj_table[i]; @@ -142,18 +119,6 @@ static const struct saj_tablet &sort_and_join( return saj_table[i]; } -/*******************************************************************\ - -Function: sort_and_join - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool sort_and_join(exprt &expr) { bool result=true; @@ -163,7 +128,7 @@ bool sort_and_join(exprt &expr) const struct saj_tablet &saj_entry= sort_and_join(expr.id(), expr.type().id()); - if(saj_entry.id==irep_idt()) + if(saj_entry.id.empty()) return true; // check operand types diff --git a/src/util/simplify_utils.h b/src/util/simplify_utils.h index 7860912a58f..33e294f4e96 100644 --- a/src/util/simplify_utils.h +++ b/src/util/simplify_utils.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_SIMPLIFY_UTILS_H #define CPROVER_UTIL_SIMPLIFY_UTILS_H diff --git a/src/util/source_location.cpp b/src/util/source_location.cpp index 7583b40b496..7fc392620b7 100644 --- a/src/util/source_location.cpp +++ b/src/util/source_location.cpp @@ -6,23 +6,13 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "source_location.h" -#include "file_util.h" - -/*******************************************************************\ -Function: source_locationt::as_string - - Inputs: print_cwd, print the absolute path to the file - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include "file_util.h" +/// \par parameters: print_cwd, print the absolute path to the file std::string source_locationt::as_string(bool print_cwd) const { std::string dest; @@ -72,18 +62,6 @@ std::string source_locationt::as_string(bool print_cwd) const return dest; } -/*******************************************************************\ - -Function: operator<< - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::ostream &operator << ( std::ostream &out, const source_locationt &source_location) diff --git a/src/util/source_location.h b/src/util/source_location.h index b9cf434f3b0..4186f3e35e2 100644 --- a/src/util/source_location.h +++ b/src/util/source_location.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_SOURCE_LOCATION_H #define CPROVER_UTIL_SOURCE_LOCATION_H diff --git a/src/util/ssa_expr.cpp b/src/util/ssa_expr.cpp index c75d7d2ed92..1285a8b260d 100644 --- a/src/util/ssa_expr.cpp +++ b/src/util/ssa_expr.cpp @@ -6,25 +6,13 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "ssa_expr.h" + #include #include #include -#include "ssa_expr.h" - -/*******************************************************************\ - -Function: build_identifier_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static void build_ssa_identifier_rec( const exprt &expr, const irep_idt &l0, @@ -61,35 +49,28 @@ static void build_ssa_identifier_rec( if(!l0.empty()) { + // Distinguish different threads of execution os << '!' << l0; l1_object_os << '!' << l0; } if(!l1.empty()) { + // Distinguish different calls to the same function (~stack frame) os << '@' << l1; l1_object_os << '@' << l1; } if(!l2.empty()) + { + // Distinguish SSA steps for the same variable os << '#' << l2; + } } else assert(false); } -/*******************************************************************\ - -Function: ssa_exprt::build_identifier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::pair ssa_exprt::build_identifier( const exprt &expr, const irep_idt &l0, diff --git a/src/util/ssa_expr.h b/src/util/ssa_expr.h index 36e5a946ea7..61cbc566ef1 100644 --- a/src/util/ssa_expr.h +++ b/src/util/ssa_expr.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_SSA_EXPR_H #define CPROVER_UTIL_SSA_EXPR_H diff --git a/src/util/std_code.cpp b/src/util/std_code.cpp index d7a4f2aa0fd..b57f1d1b44d 100644 --- a/src/util/std_code.cpp +++ b/src/util/std_code.cpp @@ -6,55 +6,21 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "std_code.h" -#include "std_expr.h" - -/*******************************************************************\ - -Function: code_declt::get_identifier - Inputs: - - Outputs: - - Purpose: +#include "std_code.h" -\*******************************************************************/ +#include "std_expr.h" const irep_idt &code_declt::get_identifier() const { return to_symbol_expr(symbol()).get_identifier(); } -/*******************************************************************\ - -Function: code_deadt::get_identifier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const irep_idt &code_deadt::get_identifier() const { return to_symbol_expr(symbol()).get_identifier(); } -/*******************************************************************\ - -Function: codet::make_block - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - code_blockt &codet::make_block() { if(get_statement()==ID_block) @@ -70,18 +36,6 @@ code_blockt &codet::make_block() return static_cast(*this); } -/*******************************************************************\ - -Function: codet::first_statement - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - codet &codet::first_statement() { const irep_idt &statement=get_statement(); @@ -97,18 +51,6 @@ codet &codet::first_statement() return *this; } -/*******************************************************************\ - -Function: first_statement - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const codet &codet::first_statement() const { const irep_idt &statement=get_statement(); @@ -124,18 +66,6 @@ const codet &codet::first_statement() const return *this; } -/*******************************************************************\ - -Function: codet::last_statement - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - codet &codet::last_statement() { const irep_idt &statement=get_statement(); @@ -151,18 +81,6 @@ codet &codet::last_statement() return *this; } -/*******************************************************************\ - -Function: codet::last_statement - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const codet &codet::last_statement() const { const irep_idt &statement=get_statement(); @@ -178,20 +96,8 @@ const codet &codet::last_statement() const return *this; } -/*******************************************************************\ - -Function: code_blockt::append - - Inputs: - extra_block - The input code_blockt - - Outputs: - - Purpose: Add all the codets from extra_block to the current - code_blockt - -\*******************************************************************/ - +/// Add all the codets from extra_block to the current code_blockt +/// \param extra_block: The input code_blockt void code_blockt::append(const code_blockt &extra_block) { operands().reserve(operands().size()+extra_block.operands().size()); diff --git a/src/util/std_code.h b/src/util/std_code.h index 9768098b1b7..cd017a658ba 100644 --- a/src/util/std_code.h +++ b/src/util/std_code.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_STD_CODE_H #define CPROVER_UTIL_STD_CODE_H diff --git a/src/util/std_expr.cpp b/src/util/std_expr.cpp index 4cb9eeff9cc..71d8b0e42d3 100644 --- a/src/util/std_expr.cpp +++ b/src/util/std_expr.cpp @@ -6,28 +6,16 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "std_expr.h" + #include #include "arith_tools.h" #include "byte_operators.h" -#include "config.h" +#include "c_types.h" #include "namespace.h" #include "pointer_offset_size.h" - #include "std_types.h" -#include "std_expr.h" - -/*******************************************************************\ - -Function: constant_exprt::value_is_zero_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ bool constant_exprt::value_is_zero_string() const { @@ -35,18 +23,6 @@ bool constant_exprt::value_is_zero_string() const return val.find_first_not_of('0')==std::string::npos; } -/*******************************************************************\ - -Function: disjunction - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt disjunction(const exprt::operandst &op) { if(op.empty()) @@ -71,18 +47,6 @@ unsigned int dynamic_object_exprt::get_instance() const return std::stoul(id2string(to_constant_expr(op0()).get_value())); } -/*******************************************************************\ - -Function: conjunction - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - exprt conjunction(const exprt::operandst &op) { if(op.empty()) @@ -97,25 +61,12 @@ exprt conjunction(const exprt::operandst &op) } } -/*******************************************************************\ - -Function: build_object_descriptor_rec - - Inputs: - - Outputs: - - Purpose: Build an object_descriptor_exprt from a given expr - -\*******************************************************************/ - +/// Build an object_descriptor_exprt from a given expr static void build_object_descriptor_rec( const namespacet &ns, const exprt &expr, object_descriptor_exprt &dest) { - const signedbv_typet index_type(config.ansi_c.pointer_width); - if(expr.id()==ID_index) { const index_exprt &index=to_index_expr(expr); @@ -127,8 +78,8 @@ static void build_object_descriptor_rec( dest.offset()= plus_exprt(dest.offset(), - mult_exprt(typecast_exprt(index.index(), index_type), - typecast_exprt(sub_size, index_type))); + mult_exprt(typecast_exprt(index.index(), index_type()), + typecast_exprt(sub_size, index_type()))); } else if(expr.id()==ID_member) { @@ -142,7 +93,7 @@ static void build_object_descriptor_rec( dest.offset()= plus_exprt(dest.offset(), - typecast_exprt(offset, index_type)); + typecast_exprt(offset, index_type())); } else if(expr.id()==ID_byte_extract_little_endian || expr.id()==ID_byte_extract_big_endian) @@ -156,7 +107,7 @@ static void build_object_descriptor_rec( dest.offset()= plus_exprt(dest.offset(), typecast_exprt(to_byte_extract_expr(expr).offset(), - index_type)); + index_type())); } else if(expr.id()==ID_typecast) { @@ -168,18 +119,7 @@ static void build_object_descriptor_rec( } } -/*******************************************************************\ - -Function: object_descriptor_exprt::build - - Inputs: - - Outputs: - - Purpose: Build an object_descriptor_exprt from a given expr - -\*******************************************************************/ - +/// Build an object_descriptor_exprt from a given expr void object_descriptor_exprt::build( const exprt &expr, const namespacet &ns) @@ -188,82 +128,34 @@ void object_descriptor_exprt::build( object()=expr; if(offset().id()==ID_unknown) - offset()=from_integer(0, signedbv_typet(config.ansi_c.pointer_width)); + offset()=from_integer(0, index_type()); build_object_descriptor_rec(ns, expr, *this); assert(root_object().type().id()!=ID_empty); } -/*******************************************************************\ - -Function: constant_exprt::integer_constant - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -constant_exprt constant_exprt::integer_constant(unsigned v) +static constant_exprt integer_constant(unsigned v) { return constant_exprt(std::to_string(v), integer_typet()); } -/*******************************************************************\ - -Function: shift_exprt::shift_exprt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - shift_exprt::shift_exprt( const exprt &_src, const irep_idt &_id, const std::size_t _distance): - binary_exprt(_src, _id, constant_exprt::integer_constant(_distance)) + binary_exprt(_src, _id, integer_constant(_distance)) { } -/*******************************************************************\ - -Function: extractbit_exprt::extractbit_exprt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - extractbit_exprt::extractbit_exprt( const exprt &_src, const std::size_t _index): binary_predicate_exprt( - _src, ID_extractbit, constant_exprt::integer_constant(_index)) + _src, ID_extractbit, integer_constant(_index)) { } -/*******************************************************************\ - -Function: extractbit_exprt::extractbits_exprt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - extractbits_exprt::extractbits_exprt( const exprt &_src, const std::size_t _upper, @@ -274,6 +166,11 @@ extractbits_exprt::extractbits_exprt( assert(_upper>=_lower); operands().resize(3); src()=_src; - upper()=constant_exprt::integer_constant(_upper); - lower()=constant_exprt::integer_constant(_lower); + upper()=integer_constant(_upper); + lower()=integer_constant(_lower); +} + +address_of_exprt::address_of_exprt(const exprt &_op): + unary_exprt(ID_address_of, _op, pointer_type(_op.type())) +{ } diff --git a/src/util/std_expr.h b/src/util/std_expr.h index 1a9ff7b412d..8323333d203 100644 --- a/src/util/std_expr.h +++ b/src/util/std_expr.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_STD_EXPR_H #define CPROVER_UTIL_STD_EXPR_H @@ -16,8 +17,7 @@ Author: Daniel Kroening, kroening@kroening.com * \date Sun Jul 31 21:54:44 BST 2011 */ -#include - +#include "invariant.h" #include "std_types.h" /*! \defgroup gr_std_expr Conversion to specific expressions @@ -58,7 +58,10 @@ class transt:public exprt */ inline const transt &to_trans_expr(const exprt &expr) { - assert(expr.id()==ID_trans && expr.operands().size()==3); + PRECONDITION(expr.id()==ID_trans); + DATA_INVARIANT( + expr.operands().size()==3, + "Transition systems must have three operands"); return static_cast(expr); } @@ -67,7 +70,10 @@ inline const transt &to_trans_expr(const exprt &expr) */ inline transt &to_trans_expr(exprt &expr) { - assert(expr.id()==ID_trans && expr.operands().size()==3); + PRECONDITION(expr.id()==ID_trans); + DATA_INVARIANT( + expr.operands().size()==3, + "Transition systems must have three operands"); return static_cast(expr); } @@ -195,7 +201,8 @@ class decorated_symbol_exprt:public symbol_exprt */ inline const symbol_exprt &to_symbol_expr(const exprt &expr) { - assert(expr.id()==ID_symbol && !expr.has_operands()); + PRECONDITION(expr.id()==ID_symbol); + DATA_INVARIANT(!expr.has_operands(), "Symbols must not have operands"); return static_cast(expr); } @@ -204,7 +211,8 @@ inline const symbol_exprt &to_symbol_expr(const exprt &expr) */ inline symbol_exprt &to_symbol_expr(exprt &expr) { - assert(expr.id()==ID_symbol && !expr.has_operands()); + PRECONDITION(expr.id()==ID_symbol); + DATA_INVARIANT(!expr.has_operands(), "Symbols must not have operands"); return static_cast(expr); } @@ -270,7 +278,9 @@ class unary_exprt:public exprt */ inline const unary_exprt &to_unary_expr(const exprt &expr) { - assert(expr.operands().size()==1); + DATA_INVARIANT( + expr.operands().size()==1, + "Unary expressions must have one operand"); return static_cast(expr); } @@ -279,7 +289,9 @@ inline const unary_exprt &to_unary_expr(const exprt &expr) */ inline unary_exprt &to_unary_expr(exprt &expr) { - assert(expr.operands().size()==1); + DATA_INVARIANT( + expr.operands().size()==1, + "Unary expressions must have one operand"); return static_cast(expr); } @@ -310,7 +322,10 @@ class abs_exprt:public unary_exprt */ inline const abs_exprt &to_abs_expr(const exprt &expr) { - assert(expr.id()==ID_abs && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_abs); + DATA_INVARIANT( + expr.operands().size()==1, + "Absolute value must have one operand"); return static_cast(expr); } @@ -319,7 +334,10 @@ inline const abs_exprt &to_abs_expr(const exprt &expr) */ inline abs_exprt &to_abs_expr(exprt &expr) { - assert(expr.id()==ID_abs && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_abs); + DATA_INVARIANT( + expr.operands().size()==1, + "Absolute value must have one operand"); return static_cast(expr); } @@ -357,7 +375,10 @@ class unary_minus_exprt:public unary_exprt */ inline const unary_minus_exprt &to_unary_minus_expr(const exprt &expr) { - assert(expr.id()==ID_unary_minus && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_unary_minus); + DATA_INVARIANT( + expr.operands().size()==1, + "Unary minus must have one operand"); return static_cast(expr); } @@ -366,7 +387,10 @@ inline const unary_minus_exprt &to_unary_minus_expr(const exprt &expr) */ inline unary_minus_exprt &to_unary_minus_expr(exprt &expr) { - assert(expr.id()==ID_unary_minus && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_unary_minus); + DATA_INVARIANT( + expr.operands().size()==1, + "Unary minus must have one operand"); return static_cast(expr); } @@ -499,7 +523,9 @@ class binary_exprt:public exprt */ inline const binary_exprt &to_binary_expr(const exprt &expr) { - assert(expr.operands().size()==2); + DATA_INVARIANT( + expr.operands().size()==2, + "Binary expressions must have two operands"); return static_cast(expr); } @@ -508,7 +534,9 @@ inline const binary_exprt &to_binary_expr(const exprt &expr) */ inline binary_exprt &to_binary_expr(exprt &expr) { - assert(expr.operands().size()==2); + DATA_INVARIANT( + expr.operands().size()==2, + "Binary expressions must have two operands"); return static_cast(expr); } @@ -590,7 +618,9 @@ class binary_relation_exprt:public binary_predicate_exprt */ inline const binary_relation_exprt &to_binary_relation_expr(const exprt &expr) { - assert(expr.operands().size()==2); + DATA_INVARIANT( + expr.operands().size()==2, + "Binary relations must have two operands"); return static_cast(expr); } @@ -599,7 +629,9 @@ inline const binary_relation_exprt &to_binary_relation_expr(const exprt &expr) */ inline binary_relation_exprt &to_binary_relation_expr(exprt &expr) { - assert(expr.operands().size()==2); + DATA_INVARIANT( + expr.operands().size()==2, + "Binary relations must have two operands"); return static_cast(expr); } @@ -702,7 +734,10 @@ class plus_exprt:public multi_ary_exprt */ inline const plus_exprt &to_plus_expr(const exprt &expr) { - assert(expr.id()==ID_plus && expr.operands().size()>=2); + PRECONDITION(expr.id()==ID_plus); + DATA_INVARIANT( + expr.operands().size()>=2, + "Plus must have two or more operands"); return static_cast(expr); } @@ -711,7 +746,10 @@ inline const plus_exprt &to_plus_expr(const exprt &expr) */ inline plus_exprt &to_plus_expr(exprt &expr) { - assert(expr.id()==ID_plus && expr.operands().size()>=2); + PRECONDITION(expr.id()==ID_plus); + DATA_INVARIANT( + expr.operands().size()>=2, + "Plus must have two or more operands"); return static_cast(expr); } @@ -744,7 +782,10 @@ class minus_exprt:public binary_exprt */ inline const minus_exprt &to_minus_expr(const exprt &expr) { - assert(expr.id()==ID_minus && expr.operands().size()>=2); + PRECONDITION(expr.id()==ID_minus); + DATA_INVARIANT( + expr.operands().size()>=2, + "Minus must have two or more operands"); return static_cast(expr); } @@ -753,7 +794,10 @@ inline const minus_exprt &to_minus_expr(const exprt &expr) */ inline minus_exprt &to_minus_expr(exprt &expr) { - assert(expr.id()==ID_minus && expr.operands().size()>=2); + PRECONDITION(expr.id()==ID_minus); + DATA_INVARIANT( + expr.operands().size()>=2, + "Minus must have two or more operands"); return static_cast(expr); } @@ -786,7 +830,10 @@ class mult_exprt:public multi_ary_exprt */ inline const mult_exprt &to_mult_expr(const exprt &expr) { - assert(expr.id()==ID_mult && expr.operands().size()>=2); + PRECONDITION(expr.id()==ID_mult); + DATA_INVARIANT( + expr.operands().size()>=2, + "Multiply must have two or more operands"); return static_cast(expr); } @@ -795,7 +842,10 @@ inline const mult_exprt &to_mult_expr(const exprt &expr) */ inline mult_exprt &to_mult_expr(exprt &expr) { - assert(expr.id()==ID_mult && expr.operands().size()>=2); + PRECONDITION(expr.id()==ID_mult); + DATA_INVARIANT( + expr.operands().size()>=2, + "Multiply must have two or more operands"); return static_cast(expr); } @@ -828,7 +878,10 @@ class div_exprt:public binary_exprt */ inline const div_exprt &to_div_expr(const exprt &expr) { - assert(expr.id()==ID_div && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_div); + DATA_INVARIANT( + expr.operands().size()==2, + "Divide must have two operands"); return static_cast(expr); } @@ -837,7 +890,10 @@ inline const div_exprt &to_div_expr(const exprt &expr) */ inline div_exprt &to_div_expr(exprt &expr) { - assert(expr.id()==ID_div && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_div); + DATA_INVARIANT( + expr.operands().size()==2, + "Divide must have two operands"); return static_cast(expr); } @@ -870,7 +926,8 @@ class mod_exprt:public binary_exprt */ inline const mod_exprt &to_mod_expr(const exprt &expr) { - assert(expr.id()==ID_mod && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_mod); + DATA_INVARIANT(expr.operands().size()==2, "Modulo must have two operands"); return static_cast(expr); } @@ -879,7 +936,8 @@ inline const mod_exprt &to_mod_expr(const exprt &expr) */ inline mod_exprt &to_mod_expr(exprt &expr) { - assert(expr.id()==ID_mod && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_mod); + DATA_INVARIANT(expr.operands().size()==2, "Modulo must have two operands"); return static_cast(expr); } @@ -912,7 +970,8 @@ class rem_exprt:public binary_exprt */ inline const rem_exprt &to_rem_expr(const exprt &expr) { - assert(expr.id()==ID_rem && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_rem); + DATA_INVARIANT(expr.operands().size()==2, "Remainder must have two operands"); return static_cast(expr); } @@ -921,7 +980,8 @@ inline const rem_exprt &to_rem_expr(const exprt &expr) */ inline rem_exprt &to_rem_expr(exprt &expr) { - assert(expr.id()==ID_rem && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_rem); + DATA_INVARIANT(expr.operands().size()==2, "Remainder must have two operands"); return static_cast(expr); } @@ -954,7 +1014,8 @@ class power_exprt:public binary_exprt */ inline const power_exprt &to_power_expr(const exprt &expr) { - assert(expr.id()==ID_power && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_power); + DATA_INVARIANT(expr.operands().size()==2, "Power must have two operands"); return static_cast(expr); } @@ -963,7 +1024,8 @@ inline const power_exprt &to_power_expr(const exprt &expr) */ inline power_exprt &to_power_expr(exprt &expr) { - assert(expr.id()==ID_power && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_power); + DATA_INVARIANT(expr.operands().size()==2, "Power must have two operands"); return static_cast(expr); } @@ -996,7 +1058,10 @@ class factorial_power_exprt:public binary_exprt */ inline const factorial_power_exprt &to_factorial_power_expr(const exprt &expr) { - assert(expr.id()==ID_factorial_power && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_factorial_power); + DATA_INVARIANT( + expr.operands().size()==2, + "Factorial power must have two operands"); return static_cast(expr); } @@ -1005,7 +1070,10 @@ inline const factorial_power_exprt &to_factorial_power_expr(const exprt &expr) */ inline factorial_power_exprt &to_factorial_expr(exprt &expr) { - assert(expr.id()==ID_factorial_power && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_factorial_power); + DATA_INVARIANT( + expr.operands().size()==2, + "Factorial power must have two operands"); return static_cast(expr); } @@ -1036,7 +1104,8 @@ class equal_exprt:public binary_relation_exprt */ inline const equal_exprt &to_equal_expr(const exprt &expr) { - assert(expr.id()==ID_equal && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_equal); + DATA_INVARIANT(expr.operands().size()==2, "Equality must have two operands"); return static_cast(expr); } @@ -1045,7 +1114,8 @@ inline const equal_exprt &to_equal_expr(const exprt &expr) */ inline equal_exprt &to_equal_expr(exprt &expr) { - assert(expr.id()==ID_equal && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_equal); + DATA_INVARIANT(expr.operands().size()==2, "Equality must have two operands"); return static_cast(expr); } @@ -1076,7 +1146,10 @@ class notequal_exprt:public binary_relation_exprt */ inline const notequal_exprt &to_notequal_expr(const exprt &expr) { - assert(expr.id()==ID_notequal && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_notequal); + DATA_INVARIANT( + expr.operands().size()==2, + "Inequality must have two operands"); return static_cast(expr); } @@ -1085,7 +1158,10 @@ inline const notequal_exprt &to_notequal_expr(const exprt &expr) */ inline notequal_exprt &to_notequal_expr(exprt &expr) { - assert(expr.id()==ID_notequal && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_notequal); + DATA_INVARIANT( + expr.operands().size()==2, + "Inequality must have two operands"); return static_cast(expr); } @@ -1152,7 +1228,10 @@ class index_exprt:public exprt */ inline const index_exprt &to_index_expr(const exprt &expr) { - assert(expr.id()==ID_index && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_index); + DATA_INVARIANT( + expr.operands().size()==2, + "Array index must have two operands"); return static_cast(expr); } @@ -1161,7 +1240,10 @@ inline const index_exprt &to_index_expr(const exprt &expr) */ inline index_exprt &to_index_expr(exprt &expr) { - assert(expr.id()==ID_index && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_index); + DATA_INVARIANT( + expr.operands().size()==2, + "Array index must have two operands"); return static_cast(expr); } @@ -1203,7 +1285,10 @@ class array_of_exprt:public unary_exprt */ inline const array_of_exprt &to_array_of_expr(const exprt &expr) { - assert(expr.id()==ID_array_of && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_array_of); + DATA_INVARIANT( + expr.operands().size()==1, + "'Array of' must have one operand"); return static_cast(expr); } @@ -1212,7 +1297,10 @@ inline const array_of_exprt &to_array_of_expr(const exprt &expr) */ inline array_of_exprt &to_array_of_expr(exprt &expr) { - assert(expr.id()==ID_array_of && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_array_of); + DATA_INVARIANT( + expr.operands().size()==1, + "'Array of' must have one operand"); return static_cast(expr); } @@ -1243,7 +1331,7 @@ class array_exprt:public exprt */ inline const array_exprt &to_array_expr(const exprt &expr) { - assert(expr.id()==ID_array); + PRECONDITION(expr.id()==ID_array); return static_cast(expr); } @@ -1252,11 +1340,11 @@ inline const array_exprt &to_array_expr(const exprt &expr) */ inline array_exprt &to_array_expr(exprt &expr) { - assert(expr.id()==ID_array); + PRECONDITION(expr.id()==ID_array); return static_cast(expr); } -/*! \brief array constructor from list of elements +/*! \brief vector constructor from list of elements */ class vector_exprt:public exprt { @@ -1283,7 +1371,7 @@ class vector_exprt:public exprt */ inline const vector_exprt &to_vector_expr(const exprt &expr) { - assert(expr.id()==ID_vector); + PRECONDITION(expr.id()==ID_vector); return static_cast(expr); } @@ -1292,7 +1380,7 @@ inline const vector_exprt &to_vector_expr(const exprt &expr) */ inline vector_exprt &to_vector_expr(exprt &expr) { - assert(expr.id()==ID_vector); + PRECONDITION(expr.id()==ID_vector); return static_cast(expr); } @@ -1352,7 +1440,10 @@ class union_exprt:public unary_exprt */ inline const union_exprt &to_union_expr(const exprt &expr) { - assert(expr.id()==ID_union && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_union); + DATA_INVARIANT( + expr.operands().size()==1, + "Union constructor must have one operand"); return static_cast(expr); } @@ -1361,7 +1452,10 @@ inline const union_exprt &to_union_expr(const exprt &expr) */ inline union_exprt &to_union_expr(exprt &expr) { - assert(expr.id()==ID_union && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_union); + DATA_INVARIANT( + expr.operands().size()==1, + "Union constructor must have one operand"); return static_cast(expr); } @@ -1392,7 +1486,7 @@ class struct_exprt:public exprt */ inline const struct_exprt &to_struct_expr(const exprt &expr) { - assert(expr.id()==ID_struct); + PRECONDITION(expr.id()==ID_struct); return static_cast(expr); } @@ -1401,7 +1495,7 @@ inline const struct_exprt &to_struct_expr(const exprt &expr) */ inline struct_exprt &to_struct_expr(exprt &expr) { - assert(expr.id()==ID_struct); + PRECONDITION(expr.id()==ID_struct); return static_cast(expr); } @@ -1458,7 +1552,10 @@ class complex_exprt:public binary_exprt */ inline const complex_exprt &to_complex_expr(const exprt &expr) { - assert(expr.id()==ID_complex && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_complex); + DATA_INVARIANT( + expr.operands().size()==2, + "Complex constructor must have two operands"); return static_cast(expr); } @@ -1467,7 +1564,10 @@ inline const complex_exprt &to_complex_expr(const exprt &expr) */ inline complex_exprt &to_complex_expr(exprt &expr) { - assert(expr.id()==ID_complex && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_complex); + DATA_INVARIANT( + expr.operands().size()==2, + "Complex constructor must have two operands"); return static_cast(expr); } @@ -1534,7 +1634,10 @@ class object_descriptor_exprt:public exprt inline const object_descriptor_exprt &to_object_descriptor_expr( const exprt &expr) { - assert(expr.id()==ID_object_descriptor && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_object_descriptor); + DATA_INVARIANT( + expr.operands().size()==2, + "Object descriptor must have two operands"); return static_cast(expr); } @@ -1543,7 +1646,10 @@ inline const object_descriptor_exprt &to_object_descriptor_expr( */ inline object_descriptor_exprt &to_object_descriptor_expr(exprt &expr) { - assert(expr.id()==ID_object_descriptor && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_object_descriptor); + DATA_INVARIANT( + expr.operands().size()==2, + "Object descriptor must have two operands"); return static_cast(expr); } @@ -1631,7 +1737,10 @@ class dynamic_object_exprt:public exprt inline const dynamic_object_exprt &to_dynamic_object_expr( const exprt &expr) { - assert(expr.id()==ID_dynamic_object && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_dynamic_object); + DATA_INVARIANT( + expr.operands().size()==2, + "Dynamic object must have two operands"); return static_cast(expr); } @@ -1640,7 +1749,10 @@ inline const dynamic_object_exprt &to_dynamic_object_expr( */ inline dynamic_object_exprt &to_dynamic_object_expr(exprt &expr) { - assert(expr.id()==ID_dynamic_object && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_dynamic_object); + DATA_INVARIANT( + expr.operands().size()==2, + "Dynamic object must have two operands"); return static_cast(expr); } @@ -1683,7 +1795,10 @@ class typecast_exprt:public exprt */ inline const typecast_exprt &to_typecast_expr(const exprt &expr) { - assert(expr.id()==ID_typecast && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_typecast); + DATA_INVARIANT( + expr.operands().size()==1, + "Typecast must have one operand"); return static_cast(expr); } @@ -1692,7 +1807,10 @@ inline const typecast_exprt &to_typecast_expr(const exprt &expr) */ inline typecast_exprt &to_typecast_expr(exprt &expr) { - assert(expr.id()==ID_typecast && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_typecast); + DATA_INVARIANT( + expr.operands().size()==1, + "Typecast must have one operand"); return static_cast(expr); } @@ -1746,7 +1864,10 @@ class floatbv_typecast_exprt:public binary_exprt */ inline const floatbv_typecast_exprt &to_floatbv_typecast_expr(const exprt &expr) { - assert(expr.id()==ID_floatbv_typecast && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_floatbv_typecast); + DATA_INVARIANT( + expr.operands().size()==2, + "Float typecast must have two operands"); return static_cast(expr); } @@ -1755,7 +1876,10 @@ inline const floatbv_typecast_exprt &to_floatbv_typecast_expr(const exprt &expr) */ inline floatbv_typecast_exprt &to_floatbv_typecast_expr(exprt &expr) { - assert(expr.id()==ID_floatbv_typecast && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_floatbv_typecast); + DATA_INVARIANT( + expr.operands().size()==2, + "Float typecast must have two operands"); return static_cast(expr); } @@ -1814,7 +1938,10 @@ exprt conjunction(const exprt::operandst &); */ inline const and_exprt &to_and_expr(const exprt &expr) { - assert(expr.id()==ID_and); + PRECONDITION(expr.id()==ID_and); + // DATA_INVARIANT( + // expr.operands().size()>=2, + // "And must have two or more operands"); return static_cast(expr); } @@ -1823,7 +1950,10 @@ inline const and_exprt &to_and_expr(const exprt &expr) */ inline and_exprt &to_and_expr(exprt &expr) { - assert(expr.id()==ID_and); + PRECONDITION(expr.id()==ID_and); + // DATA_INVARIANT( + // expr.operands().size()>=2, + // "And must have two or more operands"); return static_cast(expr); } @@ -1854,7 +1984,8 @@ class implies_exprt:public binary_exprt */ inline const implies_exprt &to_implies_expr(const exprt &expr) { - assert(expr.id()==ID_implies && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_implies); + DATA_INVARIANT(expr.operands().size()==2, "Implies must have two operands"); return static_cast(expr); } @@ -1863,7 +1994,8 @@ inline const implies_exprt &to_implies_expr(const exprt &expr) */ inline implies_exprt &to_implies_expr(exprt &expr) { - assert(expr.id()==ID_implies && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_implies); + DATA_INVARIANT(expr.operands().size()==2, "Implies must have two operands"); return static_cast(expr); } @@ -1922,7 +2054,10 @@ exprt disjunction(const exprt::operandst &); */ inline const or_exprt &to_or_expr(const exprt &expr) { - assert(expr.id()==ID_or); + PRECONDITION(expr.id()==ID_or); + // DATA_INVARIANT( + // expr.operands().size()>=2, + // "Or must have two or more operands"); return static_cast(expr); } @@ -1931,7 +2066,10 @@ inline const or_exprt &to_or_expr(const exprt &expr) */ inline or_exprt &to_or_expr(exprt &expr) { - assert(expr.id()==ID_or); + PRECONDITION(expr.id()==ID_or); + // DATA_INVARIANT( + // expr.operands().size()>=2, + // "Or must have two or more operands"); return static_cast(expr); } @@ -1950,6 +2088,36 @@ class bitnot_exprt:public unary_exprt } }; +/*! \brief Cast a generic exprt to a \ref bitnot_exprt + * + * This is an unchecked conversion. \a expr must be known to be \ref + * bitnot_exprt. + * + * \param expr Source expression + * \return Object of type \ref bitnot_exprt + * + * \ingroup gr_std_expr +*/ +inline const bitnot_exprt &to_bitnot_expr(const exprt &expr) +{ + PRECONDITION(expr.id()==ID_bitnot); + // DATA_INVARIANT(expr.operands().size()==1, + // "Bit-wise not must have one operand"); + return static_cast(expr); +} + +/*! \copydoc to_bitnot_expr(const exprt &) + * \ingroup gr_std_expr +*/ +inline bitnot_exprt &to_bitnot_expr(exprt &expr) +{ + PRECONDITION(expr.id()==ID_bitnot); + // DATA_INVARIANT(expr.operands().size()==1, + // "Bit-wise not must have one operand"); + return static_cast(expr); +} + + /*! \brief Bit-wise OR */ class bitor_exprt:public multi_ary_exprt @@ -1978,7 +2146,10 @@ class bitor_exprt:public multi_ary_exprt */ inline const bitor_exprt &to_bitor_expr(const exprt &expr) { - assert(expr.id()==ID_bitor); + PRECONDITION(expr.id()==ID_bitor); + // DATA_INVARIANT( + // expr.operands().size()>=2, + // "Bit-wise or must have two or more operands"); return static_cast(expr); } @@ -1987,7 +2158,10 @@ inline const bitor_exprt &to_bitor_expr(const exprt &expr) */ inline bitor_exprt &to_bitor_expr(exprt &expr) { - assert(expr.id()==ID_bitor); + PRECONDITION(expr.id()==ID_bitor); + // DATA_INVARIANT( + // expr.operands().size()>=2, + // "Bit-wise or must have two or more operands"); return static_cast(expr); } @@ -2018,7 +2192,10 @@ class bitxor_exprt:public multi_ary_exprt */ inline const bitxor_exprt &to_bitxor_expr(const exprt &expr) { - assert(expr.id()==ID_bitxor); + PRECONDITION(expr.id()==ID_bitxor); + // DATA_INVARIANT( + // expr.operands().size()>=2, + // "Bit-wise xor must have two or more operands"); return static_cast(expr); } @@ -2027,7 +2204,10 @@ inline const bitxor_exprt &to_bitxor_expr(const exprt &expr) */ inline bitxor_exprt &to_bitxor_expr(exprt &expr) { - assert(expr.id()==ID_bitxor); + PRECONDITION(expr.id()==ID_bitxor); + // DATA_INVARIANT( + // expr.operands().size()>=2, + // "Bit-wise xor must have two or more operands"); return static_cast(expr); } @@ -2059,7 +2239,10 @@ class bitand_exprt:public multi_ary_exprt */ inline const bitand_exprt &to_bitand_expr(const exprt &expr) { - assert(expr.id()==ID_bitand); + PRECONDITION(expr.id()==ID_bitand); + // DATA_INVARIANT( + // expr.operands().size()>=2, + // "Bit-wise and must have two or more operands"); return static_cast(expr); } @@ -2068,7 +2251,10 @@ inline const bitand_exprt &to_bitand_expr(const exprt &expr) */ inline bitand_exprt &to_bitand_expr(exprt &expr) { - assert(expr.id()==ID_bitand); + PRECONDITION(expr.id()==ID_bitand); + // DATA_INVARIANT( + // expr.operands().size()>=2, + // "Bit-wise and must have two or more operands"); return static_cast(expr); } @@ -2129,7 +2315,9 @@ class shift_exprt:public binary_exprt */ inline const shift_exprt &to_shift_expr(const exprt &expr) { - assert(expr.operands().size()==2); + DATA_INVARIANT( + expr.operands().size()==2, + "Shifts must have two operands"); return static_cast(expr); } @@ -2138,7 +2326,9 @@ inline const shift_exprt &to_shift_expr(const exprt &expr) */ inline shift_exprt &to_shift_expr(exprt &expr) { - assert(expr.operands().size()==2); + DATA_INVARIANT( + expr.operands().size()==2, + "Shifts must have two operands"); return static_cast(expr); } @@ -2256,7 +2446,10 @@ class replication_exprt:public binary_exprt */ inline const replication_exprt &to_replication_expr(const exprt &expr) { - assert(expr.id()==ID_replication && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_replication); + DATA_INVARIANT( + expr.operands().size()==2, + "Bit-wise replication must have two operands"); return static_cast(expr); } @@ -2265,7 +2458,10 @@ inline const replication_exprt &to_replication_expr(const exprt &expr) */ inline replication_exprt &to_replication_expr(exprt &expr) { - assert(expr.id()==ID_replication && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_replication); + DATA_INVARIANT( + expr.operands().size()==2, + "Bit-wise replication must have two operands"); return static_cast(expr); } @@ -2321,7 +2517,10 @@ class extractbit_exprt:public binary_predicate_exprt */ inline const extractbit_exprt &to_extractbit_expr(const exprt &expr) { - assert(expr.id()==ID_extractbit && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_extractbit); + DATA_INVARIANT( + expr.operands().size()==2, + "Extract bit must have two operands"); return static_cast(expr); } @@ -2330,7 +2529,10 @@ inline const extractbit_exprt &to_extractbit_expr(const exprt &expr) */ inline extractbit_exprt &to_extractbit_expr(exprt &expr) { - assert(expr.id()==ID_extractbit && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_extractbit); + DATA_INVARIANT( + expr.operands().size()==2, + "Extract bit must have two operands"); return static_cast(expr); } @@ -2351,7 +2553,7 @@ class extractbits_exprt:public exprt const exprt &_lower, const typet &_type):exprt(ID_extractbits, _type) { - copy_to_operands(_src, _lower, _upper); + copy_to_operands(_src, _upper, _lower); } extractbits_exprt( @@ -2403,7 +2605,10 @@ class extractbits_exprt:public exprt */ inline const extractbits_exprt &to_extractbits_expr(const exprt &expr) { - assert(expr.id()==ID_extractbits && expr.operands().size()==3); + PRECONDITION(expr.id()==ID_extractbits); + DATA_INVARIANT( + expr.operands().size()==3, + "Extract bits must have three operands"); return static_cast(expr); } @@ -2412,25 +2617,28 @@ inline const extractbits_exprt &to_extractbits_expr(const exprt &expr) */ inline extractbits_exprt &to_extractbits_expr(exprt &expr) { - assert(expr.id()==ID_extractbits && expr.operands().size()==3); + PRECONDITION(expr.id()==ID_extractbits); + DATA_INVARIANT( + expr.operands().size()==3, + "Extract bits must have three operands"); return static_cast(expr); } /*! \brief Operator to return the address of an object */ -class address_of_exprt:public exprt +class address_of_exprt:public unary_exprt { public: - explicit address_of_exprt(const exprt &op): - exprt(ID_address_of, pointer_typet(op.type())) + explicit address_of_exprt(const exprt &op); + + address_of_exprt(const exprt &op, const pointer_typet &_type): + unary_exprt(ID_address_of, op, _type) { - copy_to_operands(op); } address_of_exprt(): - exprt(ID_address_of, pointer_typet()) + unary_exprt(ID_address_of, pointer_typet()) { - operands().resize(1); } exprt &object() @@ -2456,7 +2664,8 @@ class address_of_exprt:public exprt */ inline const address_of_exprt &to_address_of_expr(const exprt &expr) { - assert(expr.id()==ID_address_of && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_address_of); + DATA_INVARIANT(expr.operands().size()==1, "Address of must have one operand"); return static_cast(expr); } @@ -2465,7 +2674,8 @@ inline const address_of_exprt &to_address_of_expr(const exprt &expr) */ inline address_of_exprt &to_address_of_expr(exprt &expr) { - assert(expr.id()==ID_address_of && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_address_of); + DATA_INVARIANT(expr.operands().size()==1, "Address of must have one operand"); return static_cast(expr); } @@ -2507,7 +2717,8 @@ class not_exprt:public exprt */ inline const not_exprt &to_not_expr(const exprt &expr) { - assert(expr.id()==ID_not && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_not); + DATA_INVARIANT(expr.operands().size()==1, "Not must have one operand"); return static_cast(expr); } @@ -2516,7 +2727,8 @@ inline const not_exprt &to_not_expr(const exprt &expr) */ inline not_exprt &to_not_expr(exprt &expr) { - assert(expr.id()==ID_not && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_not); + DATA_INVARIANT(expr.operands().size()==1, "Not must have one operand"); return static_cast(expr); } @@ -2571,7 +2783,10 @@ class dereference_exprt:public exprt */ inline const dereference_exprt &to_dereference_expr(const exprt &expr) { - assert(expr.id()==ID_dereference && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_dereference); + DATA_INVARIANT( + expr.operands().size()==1, + "Dereference must have one operand"); return static_cast(expr); } @@ -2580,7 +2795,10 @@ inline const dereference_exprt &to_dereference_expr(const exprt &expr) */ inline dereference_exprt &to_dereference_expr(exprt &expr) { - assert(expr.id()==ID_dereference && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_dereference); + DATA_INVARIANT( + expr.operands().size()==1, + "Dereference must have one operand"); return static_cast(expr); } @@ -2653,7 +2871,10 @@ class if_exprt:public exprt */ inline const if_exprt &to_if_expr(const exprt &expr) { - assert(expr.id()==ID_if && expr.operands().size()==3); + PRECONDITION(expr.id()==ID_if); + DATA_INVARIANT( + expr.operands().size()==3, + "If-then-else must have three operands"); return static_cast(expr); } @@ -2662,7 +2883,10 @@ inline const if_exprt &to_if_expr(const exprt &expr) */ inline if_exprt &to_if_expr(exprt &expr) { - assert(expr.id()==ID_if && expr.operands().size()==3); + PRECONDITION(expr.id()==ID_if); + DATA_INVARIANT( + expr.operands().size()==3, + "If-then-else must have three operands"); return static_cast(expr); } @@ -2730,7 +2954,10 @@ class with_exprt:public exprt */ inline const with_exprt &to_with_expr(const exprt &expr) { - assert(expr.id()==ID_with && expr.operands().size()==3); + PRECONDITION(expr.id()==ID_with); + DATA_INVARIANT( + expr.operands().size()==3, + "Array/structure update must have three operands"); return static_cast(expr); } @@ -2739,7 +2966,10 @@ inline const with_exprt &to_with_expr(const exprt &expr) */ inline with_exprt &to_with_expr(exprt &expr) { - assert(expr.id()==ID_with && expr.operands().size()==3); + PRECONDITION(expr.id()==ID_with); + DATA_INVARIANT( + expr.operands().size()==3, + "Array/structure update must have three operands"); return static_cast(expr); } @@ -2775,7 +3005,10 @@ class index_designatort:public exprt */ inline const index_designatort &to_index_designator(const exprt &expr) { - assert(expr.id()==ID_index_designator && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_index_designator); + DATA_INVARIANT( + expr.operands().size()==1, + "Index designator must have one operand"); return static_cast(expr); } @@ -2784,7 +3017,10 @@ inline const index_designatort &to_index_designator(const exprt &expr) */ inline index_designatort &to_index_designator(exprt &expr) { - assert(expr.id()==ID_index_designator && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_index_designator); + DATA_INVARIANT( + expr.operands().size()==1, + "Index designator must have one operand"); return static_cast(expr); } @@ -2815,7 +3051,10 @@ class member_designatort:public exprt */ inline const member_designatort &to_member_designator(const exprt &expr) { - assert(expr.id()==ID_member_designator && expr.operands().size()==0); + PRECONDITION(expr.id()==ID_member_designator); + DATA_INVARIANT( + !expr.has_operands(), + "Member designator must not have operands"); return static_cast(expr); } @@ -2824,7 +3063,10 @@ inline const member_designatort &to_member_designator(const exprt &expr) */ inline member_designatort &to_member_designator(exprt &expr) { - assert(expr.id()==ID_member_designator && expr.operands().size()==0); + PRECONDITION(expr.id()==ID_member_designator); + DATA_INVARIANT( + !expr.has_operands(), + "Member designator must not have operands"); return static_cast(expr); } @@ -2901,7 +3143,10 @@ class update_exprt:public exprt */ inline const update_exprt &to_update_expr(const exprt &expr) { - assert(expr.id()==ID_update && expr.operands().size()==3); + PRECONDITION(expr.id()==ID_update); + DATA_INVARIANT( + expr.operands().size()==3, + "Array/structure update must have three operands"); return static_cast(expr); } @@ -2910,7 +3155,10 @@ inline const update_exprt &to_update_expr(const exprt &expr) */ inline update_exprt &to_update_expr(exprt &expr) { - assert(expr.id()==ID_update && expr.operands().size()==3); + PRECONDITION(expr.id()==ID_update); + DATA_INVARIANT( + expr.operands().size()==3, + "Array/structure update must have three operands"); return static_cast(expr); } @@ -2977,7 +3225,10 @@ class array_update_exprt:public exprt */ inline const array_update_exprt &to_array_update_expr(const exprt &expr) { - assert(expr.id()==ID_array_update && expr.operands().size()==3); + PRECONDITION(expr.id()==ID_array_update); + DATA_INVARIANT( + expr.operands().size()==3, + "Array update must have three operands"); return static_cast(expr); } @@ -2986,7 +3237,10 @@ inline const array_update_exprt &to_array_update_expr(const exprt &expr) */ inline array_update_exprt &to_array_update_expr(exprt &expr) { - assert(expr.id()==ID_array_update && expr.operands().size()==3); + PRECONDITION(expr.id()==ID_array_update); + DATA_INVARIANT( + expr.operands().size()==3, + "Array update must have three operands"); return static_cast(expr); } #endif @@ -3083,7 +3337,10 @@ class member_exprt:public exprt */ inline const member_exprt &to_member_expr(const exprt &expr) { - assert(expr.id()==ID_member && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_member); + DATA_INVARIANT( + expr.operands().size()==1, + "Extract member must have one operand"); return static_cast(expr); } @@ -3092,7 +3349,10 @@ inline const member_exprt &to_member_expr(const exprt &expr) */ inline member_exprt &to_member_expr(exprt &expr) { - assert(expr.id()==ID_member && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_member); + DATA_INVARIANT( + expr.operands().size()==1, + "Extract member must have one operand"); return static_cast(expr); } @@ -3123,7 +3383,8 @@ class isnan_exprt:public unary_predicate_exprt */ inline const isnan_exprt &to_isnan_expr(const exprt &expr) { - assert(expr.id()==ID_isnan && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_isnan); + DATA_INVARIANT(expr.operands().size()==1, "Is NaN must have one operand"); return static_cast(expr); } @@ -3132,7 +3393,8 @@ inline const isnan_exprt &to_isnan_expr(const exprt &expr) */ inline isnan_exprt &to_isnan_expr(exprt &expr) { - assert(expr.id()==ID_isnan && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_isnan); + DATA_INVARIANT(expr.operands().size()==1, "Is NaN must have one operand"); return static_cast(expr); } @@ -3163,7 +3425,10 @@ class isinf_exprt:public unary_predicate_exprt */ inline const isinf_exprt &to_isinf_expr(const exprt &expr) { - assert(expr.id()==ID_isinf && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_isinf); + DATA_INVARIANT( + expr.operands().size()==1, + "Is infinite must have one operand"); return static_cast(expr); } @@ -3172,7 +3437,10 @@ inline const isinf_exprt &to_isinf_expr(const exprt &expr) */ inline isinf_exprt &to_isinf_expr(exprt &expr) { - assert(expr.id()==ID_isinf && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_isinf); + DATA_INVARIANT( + expr.operands().size()==1, + "Is infinite must have one operand"); return static_cast(expr); } @@ -3203,7 +3471,8 @@ class isfinite_exprt:public unary_predicate_exprt */ inline const isfinite_exprt &to_isfinite_expr(const exprt &expr) { - assert(expr.id()==ID_isfinite && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_isfinite); + DATA_INVARIANT(expr.operands().size()==1, "Is finite must have one operand"); return static_cast(expr); } @@ -3212,7 +3481,8 @@ inline const isfinite_exprt &to_isfinite_expr(const exprt &expr) */ inline isfinite_exprt &to_isfinite_expr(exprt &expr) { - assert(expr.id()==ID_isfinite && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_isfinite); + DATA_INVARIANT(expr.operands().size()==1, "Is finite must have one operand"); return static_cast(expr); } @@ -3243,7 +3513,8 @@ class isnormal_exprt:public unary_predicate_exprt */ inline const isnormal_exprt &to_isnormal_expr(const exprt &expr) { - assert(expr.id()==ID_isnormal && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_isnormal); + DATA_INVARIANT(expr.operands().size()==1, "Is normal must have one operand"); return static_cast(expr); } @@ -3252,7 +3523,8 @@ inline const isnormal_exprt &to_isnormal_expr(const exprt &expr) */ inline isnormal_exprt &to_isnormal_expr(exprt &expr) { - assert(expr.id()==ID_isnormal && expr.operands().size()==1); + PRECONDITION(expr.id()==ID_isnormal); + DATA_INVARIANT(expr.operands().size()==1, "Is normal must have one operand"); return static_cast(expr); } @@ -3283,7 +3555,10 @@ class ieee_float_equal_exprt:public binary_relation_exprt */ inline const ieee_float_equal_exprt &to_ieee_float_equal_expr(const exprt &expr) { - assert(expr.id()==ID_ieee_float_equal && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_ieee_float_equal); + DATA_INVARIANT( + expr.operands().size()==2, + "IEEE equality must have two operands"); return static_cast(expr); } @@ -3292,11 +3567,14 @@ inline const ieee_float_equal_exprt &to_ieee_float_equal_expr(const exprt &expr) */ inline ieee_float_equal_exprt &to_ieee_float_equal_expr(exprt &expr) { - assert(expr.id()==ID_ieee_float_equal && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_ieee_float_equal); + DATA_INVARIANT( + expr.operands().size()==2, + "IEEE equality must have two operands"); return static_cast(expr); } -/*! \brief IEEE-floating-point disequality +/*! \brief IEEE floating-point disequality */ class ieee_float_notequal_exprt:public binary_relation_exprt { @@ -3325,7 +3603,10 @@ class ieee_float_notequal_exprt:public binary_relation_exprt inline const ieee_float_notequal_exprt &to_ieee_float_notequal_expr( const exprt &expr) { - assert(expr.id()==ID_ieee_float_notequal && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_ieee_float_notequal); + DATA_INVARIANT( + expr.operands().size()==2, + "IEEE inequality must have two operands"); return static_cast(expr); } @@ -3334,11 +3615,14 @@ inline const ieee_float_notequal_exprt &to_ieee_float_notequal_expr( */ inline ieee_float_notequal_exprt &to_ieee_float_notequal_expr(exprt &expr) { - assert(expr.id()==ID_ieee_float_notequal && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_ieee_float_notequal); + DATA_INVARIANT( + expr.operands().size()==2, + "IEEE inequality must have two operands"); return static_cast(expr); } -/*! \brief IEEE-floating-point disequality +/*! \brief IEEE floating-point operations */ class ieee_float_op_exprt:public exprt { @@ -3401,7 +3685,9 @@ class ieee_float_op_exprt:public exprt */ inline const ieee_float_op_exprt &to_ieee_float_op_expr(const exprt &expr) { - assert(expr.operands().size()==3); + DATA_INVARIANT( + expr.operands().size()==3, + "IEEE float operations must have three arguments"); return static_cast(expr); } @@ -3410,7 +3696,9 @@ inline const ieee_float_op_exprt &to_ieee_float_op_expr(const exprt &expr) */ inline ieee_float_op_exprt &to_ieee_float_op_expr(exprt &expr) { - assert(expr.operands().size()==3); + DATA_INVARIANT( + expr.operands().size()==3, + "IEEE float operations must have three arguments"); return static_cast(expr); } @@ -3458,8 +3746,6 @@ class constant_exprt:public exprt } bool value_is_zero_string() const; - - static constant_exprt integer_constant(unsigned); }; /*! \brief Cast a generic exprt to a \ref constant_exprt @@ -3474,7 +3760,7 @@ class constant_exprt:public exprt */ inline const constant_exprt &to_constant_expr(const exprt &expr) { - assert(expr.id()==ID_constant); + PRECONDITION(expr.id()==ID_constant); return static_cast(expr); } @@ -3483,7 +3769,7 @@ inline const constant_exprt &to_constant_expr(const exprt &expr) */ inline constant_exprt &to_constant_expr(exprt &expr) { - assert(expr.id()==ID_constant); + PRECONDITION(expr.id()==ID_constant); return static_cast(expr); } @@ -3576,7 +3862,10 @@ class function_application_exprt:public exprt inline const function_application_exprt &to_function_application_expr( const exprt &expr) { - assert(expr.id()==ID_function_application && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_function_application); + DATA_INVARIANT( + expr.operands().size()==2, + "Function application must have two operands"); return static_cast(expr); } @@ -3585,7 +3874,10 @@ inline const function_application_exprt &to_function_application_expr( */ inline function_application_exprt &to_function_application_expr(exprt &expr) { - assert(expr.id()==ID_function_application && expr.operands().size()==2); + PRECONDITION(expr.id()==ID_function_application); + DATA_INVARIANT( + expr.operands().size()==2, + "Function application must have two operands"); return static_cast(expr); } @@ -3628,7 +3920,10 @@ class concatenation_exprt:public exprt */ inline const concatenation_exprt &to_concatenation_expr(const exprt &expr) { - assert(expr.id()==ID_concatenation); + PRECONDITION(expr.id()==ID_concatenation); + // DATA_INVARIANT( + // expr.operands().size()>=2, + // "Concatenation must have two or more operands"); return static_cast(expr); } @@ -3637,7 +3932,10 @@ inline const concatenation_exprt &to_concatenation_expr(const exprt &expr) */ inline concatenation_exprt &to_concatenation_expr(exprt &expr) { - assert(expr.id()==ID_concatenation); + PRECONDITION(expr.id()==ID_concatenation); + // DATA_INVARIANT( + // expr.operands().size()>=2, + // "Concatenation must have two or more operands"); return static_cast(expr); } @@ -3706,7 +4004,8 @@ class let_exprt:public exprt */ inline const let_exprt &to_let_expr(const exprt &expr) { - assert(expr.id()==ID_let && expr.operands().size()==3); + PRECONDITION(expr.id()==ID_let); + DATA_INVARIANT(expr.operands().size()==3, "Let must have three operands"); return static_cast(expr); } @@ -3715,7 +4014,8 @@ inline const let_exprt &to_let_expr(const exprt &expr) */ inline let_exprt &to_let_expr(exprt &expr) { - assert(expr.id()==ID_let && expr.operands().size()==3); + PRECONDITION(expr.id()==ID_let); + DATA_INVARIANT(expr.operands().size()==3, "Let must have three operands"); return static_cast(expr); } diff --git a/src/util/std_types.cpp b/src/util/std_types.cpp index e6244ab5c9b..b2d0c4f36d5 100644 --- a/src/util/std_types.cpp +++ b/src/util/std_types.cpp @@ -6,61 +6,26 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "std_types.h" + #include "string2int.h" #include "arith_tools.h" -#include "std_types.h" #include "std_expr.h" -/*******************************************************************\ - -Function: fixedbv_typet::get_integer_bits - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::size_t fixedbv_typet::get_integer_bits() const { const irep_idt integer_bits=get(ID_integer_bits); - assert(integer_bits!=irep_idt()); + assert(!integer_bits.empty()); return unsafe_string2unsigned(id2string(integer_bits)); } -/*******************************************************************\ - -Function: floatbv_typet::get_f - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::size_t floatbv_typet::get_f() const { const irep_idt &f=get(ID_f); - assert(f!=irep_idt()); + assert(!f.empty()); return unsafe_string2unsigned(id2string(f)); } -/*******************************************************************\ - -Function: struct_union_typet::component_number - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::size_t struct_union_typet::component_number( const irep_idt &component_name) const { @@ -83,18 +48,6 @@ std::size_t struct_union_typet::component_number( return 0; } -/*******************************************************************\ - -Function: struct_union_typet::get_component - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const struct_union_typet::componentt &struct_union_typet::get_component( const irep_idt &component_name) const { @@ -112,18 +65,6 @@ const struct_union_typet::componentt &struct_union_typet::get_component( return static_cast(get_nil_irep()); } -/*******************************************************************\ - -Function: struct_union_typet::component_type - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - typet struct_union_typet::component_type( const irep_idt &component_name) const { @@ -132,18 +73,6 @@ typet struct_union_typet::component_type( return c.type(); } -/*******************************************************************\ - -Function: struct_typet::is_prefix_of - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool struct_typet::is_prefix_of(const struct_typet &other) const { const componentst &ot_components=other.components(); @@ -173,275 +102,83 @@ bool struct_typet::is_prefix_of(const struct_typet &other) const return true; // ok, *this is a prefix of ot } -/*******************************************************************\ - -Function: is_reference - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool is_reference(const typet &type) { return type.id()==ID_pointer && type.get_bool(ID_C_reference); } -/*******************************************************************\ - -Function: is_rvalue_reference - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool is_rvalue_reference(const typet &type) { return type.id()==ID_pointer && type.get_bool(ID_C_rvalue_reference); } -/*******************************************************************\ - -Function: range_typet::set_from - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void range_typet::set_from(const mp_integer &from) { set(ID_from, integer2string(from)); } -/*******************************************************************\ - -Function: range_typet::set_to - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void range_typet::set_to(const mp_integer &to) { set(ID_to, integer2string(to)); } -/*******************************************************************\ - -Function: range_typet::get_from - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - mp_integer range_typet::get_from() const { return string2integer(get_string(ID_from)); } -/*******************************************************************\ - -Function: range_typet::get_to - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - mp_integer range_typet::get_to() const { return string2integer(get_string(ID_to)); } -/*******************************************************************\ - -Function: signedbv_typet::smallest - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - mp_integer signedbv_typet::smallest() const { return -power(2, get_width()-1); } -/*******************************************************************\ - -Function: signedbv_typet::largest - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - mp_integer signedbv_typet::largest() const { return power(2, get_width()-1)-1; } -/*******************************************************************\ - -Function: signedbv_typet::zero_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - constant_exprt signedbv_typet::zero_expr() const { return to_constant_expr(from_integer(0, *this)); } -/*******************************************************************\ - -Function: signedbv_typet::smallest_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - constant_exprt signedbv_typet::smallest_expr() const { return to_constant_expr(from_integer(smallest(), *this)); } -/*******************************************************************\ - -Function: signedbv_typet::largest_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - constant_exprt signedbv_typet::largest_expr() const { return to_constant_expr(from_integer(largest(), *this)); } -/*******************************************************************\ - -Function: unsignedbv_typet::smallest - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - mp_integer unsignedbv_typet::smallest() const { return 0; } -/*******************************************************************\ - -Function: unsignedbv_typet::largest - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - mp_integer unsignedbv_typet::largest() const { return power(2, get_width())-1; } -/*******************************************************************\ - -Function: unsignedbv_typet::zero_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - constant_exprt unsignedbv_typet::zero_expr() const { return to_constant_expr(from_integer(0, *this)); } -/*******************************************************************\ - -Function: unsignedbv_typet::smallest_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - constant_exprt unsignedbv_typet::smallest_expr() const { return to_constant_expr(from_integer(smallest(), *this)); } -/*******************************************************************\ - -Function: unsignedbv_typet::largest_expr - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - constant_exprt unsignedbv_typet::largest_expr() const { return to_constant_expr(from_integer(largest(), *this)); diff --git a/src/util/std_types.h b/src/util/std_types.h index d6b1d899a08..ef6bc05a43b 100644 --- a/src/util/std_types.h +++ b/src/util/std_types.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_STD_TYPES_H #define CPROVER_UTIL_STD_TYPES_H @@ -1438,6 +1439,31 @@ class reference_typet:public pointer_typet } }; +/*! \brief Cast a generic typet to a \ref reference_typet + * + * This is an unchecked conversion. \a type must be known to be \ref + * reference_typet. + * + * \param type Source type + * \return Object of type \ref reference_typet + * + * \ingroup gr_std_types +*/ +inline const reference_typet &to_reference_type(const typet &type) +{ + assert(type.id()==ID_pointer && type.get_bool(ID_C_reference)); + return static_cast(type); +} + +/*! \copydoc to_reference_type(const typet &) + * \ingroup gr_std_types +*/ +inline reference_typet &to_reference_type(typet &type) +{ + assert(type.id()==ID_pointer && type.get_bool(ID_C_reference)); + return static_cast(type); +} + /*! \brief TO_BE_DOCUMENTED */ bool is_reference(const typet &type); diff --git a/src/util/string2int.cpp b/src/util/string2int.cpp index 224e5779858..2285c3e0691 100644 --- a/src/util/string2int.cpp +++ b/src/util/string2int.cpp @@ -6,31 +6,20 @@ Author: Michael Tautschnig, michael.tautschnig@cs.ox.ac.uk \*******************************************************************/ +#include "string2int.h" + #include #include #include -#include - -#include "string2int.h" - -/*******************************************************************\ - -Function: str2number - - Inputs: - - Outputs: - Purpose: - -\*******************************************************************/ +#include "invariant.h" template inline T str2number(const char *str, int base, bool safe) { int errno_bak=errno; errno=0; - char * endptr; + char *endptr; // _strtoi64 is available in Visual Studio, but not yet in MINGW #ifdef _MSC_VER const __int64 val=_strtoi64(str, &endptr, base); @@ -40,123 +29,53 @@ inline T str2number(const char *str, int base, bool safe) if(safe) { - assert(0 == errno); + CHECK_RETURN(0==errno); errno=errno_bak; - assert(endptr!=str); + CHECK_RETURN(endptr!=str); if(std::numeric_limits::min()==0) { // unsigned - assert(val >= 0); - assert((T)val <= std::numeric_limits::max()); + CHECK_RETURN(val>=0); + CHECK_RETURN( + (unsigned long long)(T)val<= + (unsigned long long)std::numeric_limits::max()); } else { // signed - assert(val <= (long long)std::numeric_limits::max()); - assert(val >= (long long)std::numeric_limits::min()); + CHECK_RETURN(val<=(long long)std::numeric_limits::max()); + CHECK_RETURN(val>=(long long)std::numeric_limits::min()); } } return (T)val; } -/*******************************************************************\ - -Function: safe_string2unsigned - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - unsigned safe_string2unsigned(const std::string &str, int base) { return str2number(str.c_str(), base, true); } -/*******************************************************************\ - -Function: safe_string2size_t - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::size_t safe_string2size_t(const std::string &str, int base) { return str2number(str.c_str(), base, true); } -/*******************************************************************\ - -Function: unsafe_string2int - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - int unsafe_string2int(const std::string &str, int base) { return str2number(str.c_str(), base, false); } -/*******************************************************************\ - -Function: unsafe_string2unsigned - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - unsigned unsafe_string2unsigned(const std::string &str, int base) { return str2number(str.c_str(), base, false); } -/*******************************************************************\ - -Function: unsafe_string2size_t - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::size_t unsafe_string2size_t(const std::string &str, int base) { return str2number(str.c_str(), base, false); } -/*******************************************************************\ - -Function: unsafe_string2signedlonglong - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - signed long long int unsafe_string2signedlonglong( const std::string &str, int base) @@ -164,18 +83,6 @@ signed long long int unsafe_string2signedlonglong( return str2number(str.c_str(), base, false); } -/*******************************************************************\ - -Function: unsafe_string2unsignedlonglong - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - unsigned long long int unsafe_string2unsignedlonglong( const std::string &str, int base) diff --git a/src/util/string2int.h b/src/util/string2int.h index 9b39c0ed829..12c0260aaac 100644 --- a/src/util/string2int.h +++ b/src/util/string2int.h @@ -6,6 +6,7 @@ Author: Michael Tautschnig, michael.tautschnig@cs.ox.ac.uk \*******************************************************************/ + #ifndef CPROVER_UTIL_STRING2INT_H #define CPROVER_UTIL_STRING2INT_H @@ -18,7 +19,7 @@ Author: Michael Tautschnig, michael.tautschnig@cs.ox.ac.uk unsigned safe_string2unsigned(const std::string &str, int base=10); std::size_t safe_string2size_t(const std::string &str, int base=10); -// The below mimick C's atoi/atol: any errors are silently ignored. +// The below mimic C's atoi/atol: any errors are silently ignored. // They are meant to replace atoi/atol. int unsafe_string2int(const std::string &str, int base=10); unsigned unsafe_string2unsigned(const std::string &str, int base=10); diff --git a/src/util/string_container.cpp b/src/util/string_container.cpp index 1b1603631d0..8793666506a 100644 --- a/src/util/string_container.cpp +++ b/src/util/string_container.cpp @@ -6,40 +6,19 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Container for C-Strings #include "string_container.h" -string_containert string_container; - -/*******************************************************************\ - -Function: string_ptrt::string_ptrt - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +string_containert string_container; string_ptrt::string_ptrt(const char *_s):s(_s), len(strlen(_s)) { } -/*******************************************************************\ - -Function: string_ptrt::operator== - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool string_ptrt::operator==(const string_ptrt &other) const { if(len!=other.len) @@ -48,18 +27,6 @@ bool string_ptrt::operator==(const string_ptrt &other) const return len==0 || memcmp(s, other.s, len)==0; } -/*******************************************************************\ - -Function: string_containert::string_containert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void initialize_string_container(); string_containert::string_containert() @@ -71,34 +38,10 @@ string_containert::string_containert() initialize_string_container(); } -/*******************************************************************\ - -Function: string_containert::~string_containert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - string_containert::~string_containert() { } -/*******************************************************************\ - -Function: string_containert::get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - unsigned string_containert::get(const char *s) { string_ptrt string_ptr(s); @@ -122,18 +65,6 @@ unsigned string_containert::get(const char *s) return r; } -/*******************************************************************\ - -Function: string_containert::get - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - unsigned string_containert::get(const std::string &s) { string_ptrt string_ptr(s); diff --git a/src/util/string_container.h b/src/util/string_container.h index cbd8d0d320b..59a5daff0b8 100644 --- a/src/util/string_container.h +++ b/src/util/string_container.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Container for C-Strings + #ifndef CPROVER_UTIL_STRING_CONTAINER_H #define CPROVER_UTIL_STRING_CONTAINER_H diff --git a/src/util/string_expr.h b/src/util/string_expr.h index 317e3c1ee6e..e141f2a1598 100644 --- a/src/util/string_expr.h +++ b/src/util/string_expr.h @@ -6,6 +6,9 @@ Author: Romain Brenguier, romain.brenguier@diffblue.com \*******************************************************************/ +/// \file +/// String expressions for the string solver + #ifndef CPROVER_UTIL_STRING_EXPR_H #define CPROVER_UTIL_STRING_EXPR_H diff --git a/src/util/string_hash.cpp b/src/util/string_hash.cpp index c59a0a61280..c283155caee 100644 --- a/src/util/string_hash.cpp +++ b/src/util/string_hash.cpp @@ -1,24 +1,15 @@ /*******************************************************************\ -Module: string hasing +Module: string hashing Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "string_hash.h" - -/*******************************************************************\ - -Function: hash_string - - Inputs: +/// \file +/// string hashing - Outputs: - - Purpose: - -\*******************************************************************/ +#include "string_hash.h" size_t hash_string(const std::string &s) { @@ -31,18 +22,6 @@ size_t hash_string(const std::string &s) return h; } -/*******************************************************************\ - -Function: hash_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - size_t hash_string(const char *s) { size_t h=0; diff --git a/src/util/string_hash.h b/src/util/string_hash.h index 41f45adeda0..021cb95b341 100644 --- a/src/util/string_hash.h +++ b/src/util/string_hash.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// string hashing + #ifndef CPROVER_UTIL_STRING_HASH_H #define CPROVER_UTIL_STRING_HASH_H diff --git a/src/util/string_utils.cpp b/src/util/string_utils.cpp index 9fb81dfa08c..101b6cd520c 100644 --- a/src/util/string_utils.cpp +++ b/src/util/string_utils.cpp @@ -6,24 +6,12 @@ Author: Daniel Poetzl \*******************************************************************/ +#include "string_utils.h" + #include #include #include -#include "string_utils.h" - -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string strip_string(const std::string &s) { auto pred=[](char c){ return std::isspace(c); }; @@ -42,18 +30,6 @@ std::string strip_string(const std::string &s) return s.substr(i, (j-i+1)); } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void split_string( const std::string &s, char delim, @@ -104,18 +80,6 @@ void split_string( result.push_back(""); } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void split_string( const std::string &s, char delim, diff --git a/src/util/string_utils.h b/src/util/string_utils.h index 703fc359e82..5e4ef23a63a 100644 --- a/src/util/string_utils.h +++ b/src/util/string_utils.h @@ -6,6 +6,7 @@ Author: Daniel Poetzl \*******************************************************************/ + #ifndef CPROVER_UTIL_STRING_UTILS_H #define CPROVER_UTIL_STRING_UTILS_H diff --git a/src/util/substitute.cpp b/src/util/substitute.cpp index d83ad9361fe..39010d79676 100644 --- a/src/util/substitute.cpp +++ b/src/util/substitute.cpp @@ -6,21 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "substitute.h" -/*******************************************************************\ - -Function: substitute - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void substitute( std::string &dest, diff --git a/src/util/substitute.h b/src/util/substitute.h index c39774fa615..ed3ea5293a0 100644 --- a/src/util/substitute.h +++ b/src/util/substitute.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_SUBSTITUTE_H #define CPROVER_UTIL_SUBSTITUTE_H diff --git a/src/util/suffix.h b/src/util/suffix.h index 7ddc08fe5cf..1c2568e239b 100644 --- a/src/util/suffix.h +++ b/src/util/suffix.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_SUFFIX_H #define CPROVER_UTIL_SUFFIX_H diff --git a/src/util/symbol.cpp b/src/util/symbol.cpp index d2883832faf..652fe422c56 100644 --- a/src/util/symbol.cpp +++ b/src/util/symbol.cpp @@ -6,24 +6,13 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "symbol.h" + #include -#include "symbol.h" #include "source_location.h" #include "std_expr.h" -/*******************************************************************\ - -Function: symbolt::show - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symbolt::show(std::ostream &out) const { out << " " << name << '\n'; @@ -77,18 +66,6 @@ void symbolt::show(std::ostream &out) const out << '\n'; } -/*******************************************************************\ - -Function: operator<< - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::ostream &operator<<(std::ostream &out, const symbolt &symbol) { @@ -96,18 +73,6 @@ std::ostream &operator<<(std::ostream &out, return out; } -/*******************************************************************\ - -Function: symbolt::to_irep - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - irept symbolt::to_irep() const { irept dest; @@ -158,18 +123,6 @@ irept symbolt::to_irep() const return dest; } -/*******************************************************************\ - -Function: symbolt::from_irep - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symbolt::from_irep(const irept &src) { type=static_cast(src.find(ID_type)); @@ -200,18 +153,6 @@ void symbolt::from_irep(const irept &src) is_volatile=src.get_bool("is_volatile"); } -/*******************************************************************\ - -Function: symbolt::swap - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void symbolt::swap(symbolt &b) { #define SYM_SWAP1(x) x.swap(b.x) @@ -245,18 +186,8 @@ void symbolt::swap(symbolt &b) SYM_SWAP2(is_volatile); } -/*******************************************************************\ - -Function: symbolt::symbol_expr - - Inputs: symbol - - Outputs: symbol_exprt - - Purpose: produces a symbol_exprt for a symbol - -\*******************************************************************/ - +/// produces a symbol_exprt for a symbol +/// \return symbol_exprt symbol_exprt symbolt::symbol_expr() const { return symbol_exprt(name, type); diff --git a/src/util/symbol.h b/src/util/symbol.h index b8f52fc7099..7edae3146c0 100644 --- a/src/util/symbol.h +++ b/src/util/symbol.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_SYMBOL_H #define CPROVER_UTIL_SYMBOL_H @@ -144,6 +145,14 @@ class auxiliary_symbolt:public symbolt is_file_local=true; is_auxiliary=true; } + + auxiliary_symbolt(const irep_idt &name, const typet &type): + auxiliary_symbolt() + { + this->name=name; + this->base_name=name; + this->type=type; + } }; /*! \brief Symbol table entry of function parameter diff --git a/src/util/symbol_table.cpp b/src/util/symbol_table.cpp index 37053b7737b..3ee5211e99b 100644 --- a/src/util/symbol_table.cpp +++ b/src/util/symbol_table.cpp @@ -6,25 +6,15 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "symbol_table.h" -/*******************************************************************\ - -Function: symbol_tablet::add - - Inputs: - symbol - The symbol to be added to the symbol table - - Outputs: Returns a boolean indicating whether the process failed, - which should only happen if there is a symbol with the same - name already in the symbol table - - Purpose: Add a new symbol to the symbol table - -\*******************************************************************/ +#include +/// Add a new symbol to the symbol table +/// \param symbol: The symbol to be added to the symbol table +/// \return Returns a boolean indicating whether the process failed, which +/// should only happen if there is a symbol with the same name already in the +/// symbol table bool symbol_tablet::add(const symbolt &symbol) { if(!symbols.insert(std::pair(symbol.name, symbol)).second) @@ -38,35 +28,21 @@ bool symbol_tablet::add(const symbolt &symbol) return false; } -/*******************************************************************\ - -Function: symbol_tablet::move - - Inputs: - symbol - The symbol to be added to the symbol table - new_symbol - Pointer which the function will set to either point - to the symbol in the symbol table with the same name - or to the symbol that has been successfully moved - into the symbol table - - Outputs: Returns a boolean indicating whether the process failed, - which should only happen if there is a symbol with the - same name already in the symbol table. If the process - failed then symbol is unchanged and new_symbol points to - the symbol with the same name. If the process succeeded - symbol is set to be empty and new_symbol points to its new - location in the symbol table - - Purpose: Move a symbol into the symbol table. If there is already - a symbol with the same name then symbol is unchanged, - new_symbol points to the symbol with the same name and - true is returned. Otherwise, the symbol is moved into the - symbol table, symbol is set to be empty, new_symbol points - to its new location in the symbol table and false is - returned - -\*******************************************************************/ - +/// Move a symbol into the symbol table. If there is already a symbol with the +/// same name then symbol is unchanged, new_symbol points to the symbol with the +/// same name and true is returned. Otherwise, the symbol is moved into the +/// symbol table, symbol is set to be empty, new_symbol points to its new +/// location in the symbol table and false is returned +/// \param symbol: The symbol to be added to the symbol table +/// \param new_symbol: Pointer which the function will set to either point to +/// the symbol in the symbol table with the same name or to the symbol that +/// has been successfully moved into the symbol table +/// \return Returns a boolean indicating whether the process failed, which +/// should only happen if there is a symbol with the same name already in the +/// symbol table. If the process failed then symbol is unchanged and +/// new_symbol points to the symbol with the same name. If the process +/// succeeded symbol is set to be empty and new_symbol points to its new +/// location in the symbol table bool symbol_tablet::move(symbolt &symbol, symbolt *&new_symbol) { symbolt tmp; @@ -91,19 +67,9 @@ bool symbol_tablet::move(symbolt &symbol, symbolt *&new_symbol) return false; } -/*******************************************************************\ - -Function: symbol_tablet::remove - - Inputs: - name - The name of the symbol to remove - - Outputs: Returns a boolean indicating whether the process failed - - Purpose: Remove a symbol from the symbol table - -\*******************************************************************/ - +/// Remove a symbol from the symbol table +/// \param name: The name of the symbol to remove +/// \return Returns a boolean indicating whether the process failed bool symbol_tablet::remove(const irep_idt &name) { symbolst::iterator entry=symbols.find(name); @@ -138,19 +104,8 @@ bool symbol_tablet::remove(const irep_idt &name) return false; } -/*******************************************************************\ - -Function: symbol_tablet::show - - Inputs: - out - The ostream to direct output to - - Outputs: - - Purpose: Print the contents of the symbol table - -\*******************************************************************/ - +/// Print the contents of the symbol table +/// \param out: The ostream to direct output to void symbol_tablet::show(std::ostream &out) const { out << "\n" << "Symbols:" << "\n"; @@ -159,20 +114,10 @@ void symbol_tablet::show(std::ostream &out) const out << it->second; } -/*******************************************************************\ - -Function: symbol_tablet::lookup - - Inputs: - identifier - The name of the symbol to look for - - Outputs: The symbol in the symbol table with the correct name - - Purpose: Find a symbol in the symbol table. Throws a string if no - such symbol is found. - -\*******************************************************************/ - +/// Find a symbol in the symbol table. Throws a string if no such symbol is +/// found. +/// \param identifier: The name of the symbol to look for +/// \return The symbol in the symbol table with the correct name const symbolt &symbol_tablet::lookup(const irep_idt &identifier) const { symbolst::const_iterator it=symbols.find(identifier); @@ -183,20 +128,10 @@ const symbolt &symbol_tablet::lookup(const irep_idt &identifier) const return it->second; } -/*******************************************************************\ - -Function: symbol_tablet::lookup - - Inputs: - identifier - The name of the symbol to look for - - Outputs: The symbol in the symbol table with the correct name - - Purpose: Find a symbol in the symbol table. Throws a string if no - such symbol is found. - -\*******************************************************************/ - +/// Find a symbol in the symbol table. Throws a string if no such symbol is +/// found. +/// \param identifier: The name of the symbol to look for +/// \return The symbol in the symbol table with the correct name symbolt &symbol_tablet::lookup(const irep_idt &identifier) { symbolst::iterator it=symbols.find(identifier); @@ -207,20 +142,9 @@ symbolt &symbol_tablet::lookup(const irep_idt &identifier) return it->second; } -/*******************************************************************\ - -Function: operator << - - Inputs: - out - The ostream to direct output to - symbol_table - The symbol table to print out - - Outputs: - - Purpose: Print the contents of the symbol table - -\*******************************************************************/ - +/// Print the contents of the symbol table +/// \param out: The ostream to direct output to +/// \param symbol_table: The symbol table to print out std::ostream &operator << (std::ostream &out, const symbol_tablet &symbol_table) { symbol_table.show(out); diff --git a/src/util/symbol_table.h b/src/util/symbol_table.h index 08eb616c852..9a1b0b7f95c 100644 --- a/src/util/symbol_table.h +++ b/src/util/symbol_table.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_SYMBOL_TABLE_H #define CPROVER_UTIL_SYMBOL_TABLE_H diff --git a/src/util/symbol_utils.cpp b/src/util/symbol_utils.cpp index a74352b3ada..438e7521e47 100644 --- a/src/util/symbol_utils.cpp +++ b/src/util/symbol_utils.cpp @@ -6,28 +6,23 @@ Author: Nathan Phillips, nathan.phillips@diffblue.com \*******************************************************************/ +/// \file +/// Symbol utilities + #include "symbol_utils.h" #include "symbol.h" #include -/*******************************************************************\ - - Function: symbol_utilst::does_symbol_match - - Purpose: - Checks whether an exprt is actually a symbolt matching a predicate - - Inputs: - lvalue: - An exprt to be tested - predicate: - The predicate to test for - - Outputs: - Whether the exprt was actually a symbolt matching a predicate - -\*******************************************************************/ - +/// Checks whether an exprt is actually a symbolt matching a predicate +/// +/// Inputs: +/// lvalue: +/// An exprt to be tested +/// predicate: +/// The predicate to test for +/// +/// Outputs: +/// Whether the exprt was actually a symbolt matching a predicate bool symbol_utilst::does_symbol_match( const exprt &lvalue, std::function predicate) const @@ -40,22 +35,14 @@ bool symbol_utilst::does_symbol_match( return predicate(*symbol); } -/*******************************************************************\ - - Function: symbol_utilst::is_parameter - - Purpose: - Checks whether an exprt is actually a parameter symbol - - Inputs: - lvalue: - An exprt to be tested - - Outputs: - Whether the exprt was actually a parameter symbol - -\*******************************************************************/ - +/// Checks whether an exprt is actually a parameter symbol +/// +/// Inputs: +/// lvalue: +/// An exprt to be tested +/// +/// Outputs: +/// Whether the exprt was actually a parameter symbol bool symbol_utilst::is_parameter(const exprt &lvalue) const { return does_symbol_match( @@ -63,22 +50,14 @@ bool symbol_utilst::is_parameter(const exprt &lvalue) const [] (symbolt symbol) { return symbol.is_parameter; }); } -/*******************************************************************\ - - Function: symbol_utilst::is_static - - Purpose: - Checks whether an exprt is actually a static symbol - - Inputs: - lvalue: - An exprt to be tested - - Outputs: - Whether the exprt was actually a static symbol - -\*******************************************************************/ - +/// Checks whether an exprt is actually a static symbol +/// +/// Inputs: +/// lvalue: +/// An exprt to be tested +/// +/// Outputs: +/// Whether the exprt was actually a static symbol bool symbol_utilst::is_static(const exprt &lvalue) const { // TODO: Also check for static member accesses @@ -87,22 +66,14 @@ bool symbol_utilst::is_static(const exprt &lvalue) const [] (symbolt symbol) { return symbol.is_static_lifetime; }); } -/*******************************************************************\ - - Function: symbol_utilst::is_auxiliary_variable - - Purpose: - Checks whether an exprt is actually an auxiliary variable symbol - - Inputs: - lvalue: - An exprt to be tested - - Outputs: - Whether the exprt was actually an auxiliary variable symbol - -\*******************************************************************/ - +/// Checks whether an exprt is actually an auxiliary variable symbol +/// +/// Inputs: +/// lvalue: +/// An exprt to be tested +/// +/// Outputs: +/// Whether the exprt was actually an auxiliary variable symbol bool symbol_utilst::is_auxiliary_variable(const exprt &lvalue) const { return does_symbol_match( @@ -110,22 +81,14 @@ bool symbol_utilst::is_auxiliary_variable(const exprt &lvalue) const [] (symbolt symbol) { return symbol.is_auxiliary; }); } -/*******************************************************************\ - - Function: symbol_utilst::is_return_value_auxiliary - - Purpose: - Checks whether an exprt is actually an auxiliary return value symbol - - Inputs: - lvalue: - An exprt to be tested - - Outputs: - Whether the exprt was actually an auxiliary return value symbol - -\*******************************************************************/ - +/// Checks whether an exprt is actually an auxiliary return value symbol +/// +/// Inputs: +/// lvalue: +/// An exprt to be tested +/// +/// Outputs: +/// Whether the exprt was actually an auxiliary return value symbol bool symbol_utilst::is_return_value_auxiliary(const exprt &lvalue) const { return diff --git a/src/util/symbol_utils.h b/src/util/symbol_utils.h index 7c0887c4050..76e7e1307bb 100644 --- a/src/util/symbol_utils.h +++ b/src/util/symbol_utils.h @@ -6,6 +6,9 @@ Author: Nathan Phillips, nathan.phillips@diffblue.com \*******************************************************************/ +/// \file +/// Symbol utilities + #ifndef CPROVER_UTIL_SYMBOL_UTILS_H #define CPROVER_UTIL_SYMBOL_UTILS_H diff --git a/src/util/tempdir.cpp b/src/util/tempdir.cpp index e160c664558..b796befa707 100644 --- a/src/util/tempdir.cpp +++ b/src/util/tempdir.cpp @@ -6,6 +6,8 @@ Author: CM Wintersteiger \*******************************************************************/ +#include "tempdir.h" + #ifdef _WIN32 #include #include @@ -25,21 +27,8 @@ Author: CM Wintersteiger #include #endif -#include "tempdir.h" #include "file_util.h" -/*******************************************************************\ - -Function: get_temporary_directory - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string get_temporary_directory(const std::string &name_template) { std::string result; @@ -69,7 +58,7 @@ std::string get_temporary_directory(const std::string &name_template) #else std::string prefixed_name_template="/tmp/"; const char *TMPDIR_env=getenv("TMPDIR"); - if(TMPDIR_env!=0) + if(TMPDIR_env!=nullptr) prefixed_name_template=TMPDIR_env; if(*prefixed_name_template.rbegin()!='/') prefixed_name_template+='/'; @@ -86,86 +75,26 @@ std::string get_temporary_directory(const std::string &name_template) return result; } -/*******************************************************************\ - -Function: temp_dirt::temp_dirt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - temp_dirt::temp_dirt(const std::string &name_template) { path=get_temporary_directory(name_template); } -/*******************************************************************\ - -Function: temp_dirt::operator() - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string temp_dirt::operator()(const std::string &file) { return concat_dir_file(path, file); } -/*******************************************************************\ - -Function: temp_dirt::~temp_dirt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void temp_dirt::clear() { delete_directory(path); } -/*******************************************************************\ - -Function: temp_dirt::~temp_dirt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - temp_dirt::~temp_dirt() { clear(); } -/*******************************************************************\ - -Function: temp_working_dirt::temp_working_dirt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - temp_working_dirt::temp_working_dirt(const std::string &name_template): temp_dirt(name_template) { @@ -174,18 +103,6 @@ temp_working_dirt::temp_working_dirt(const std::string &name_template): assert(false); } -/*******************************************************************\ - -Function: temp_working_dirt::~temp_working_dirt - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - temp_working_dirt::~temp_working_dirt() { if(chdir(old_working_directory.c_str())!=0) diff --git a/src/util/tempdir.h b/src/util/tempdir.h index b8c467e7a76..a01e6352562 100644 --- a/src/util/tempdir.h +++ b/src/util/tempdir.h @@ -6,6 +6,7 @@ Author: CM Wintersteiger \*******************************************************************/ + #ifndef CPROVER_UTIL_TEMPDIR_H #define CPROVER_UTIL_TEMPDIR_H diff --git a/src/util/tempfile.cpp b/src/util/tempfile.cpp index 9db2a68c370..a9f761fb882 100644 --- a/src/util/tempfile.cpp +++ b/src/util/tempfile.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening \*******************************************************************/ +#include "tempfile.h" + #ifdef _WIN32 #include #include @@ -32,21 +34,8 @@ Author: Daniel Kroening #include #endif -#include "tempfile.h" - -/*******************************************************************\ - -Function: my_mkstemps - - Inputs: - - Outputs: - - Purpose: Substitute for mkstemps (OpenBSD standard) for Windows, - where it is unavailable. - -\*******************************************************************/ - +/// Substitute for mkstemps (OpenBSD standard) for Windows, where it is +/// unavailable. #ifdef _WIN32 #define mkstemps my_mkstemps int my_mkstemps(char *template_str, int suffix_len) @@ -55,7 +44,10 @@ int my_mkstemps(char *template_str, int suffix_len) std::size_t template_length=strlen(template_str); - if(suffix_len+6>template_length) + if(suffix_len<0) + return -1; + + if(static_cast(suffix_len+6)>template_length) return -1; // suffix too long char *XXXXXX_pos= @@ -92,18 +84,6 @@ int my_mkstemps(char *template_str, int suffix_len) } #endif -/*******************************************************************\ - -Function: get_temporary_file - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string get_temporary_file( const std::string &prefix, const std::string &suffix) @@ -127,7 +107,7 @@ std::string get_temporary_file( #else std::string dir="/tmp/"; const char *TMPDIR_env=getenv("TMPDIR"); - if(TMPDIR_env!=0) + if(TMPDIR_env!=nullptr) dir=TMPDIR_env; if(*dir.rbegin()!='/') dir+='/'; @@ -150,19 +130,8 @@ std::string get_temporary_file( return result; } -/*******************************************************************\ - -Function: temporary_filet::~temporary_filet - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - temporary_filet::~temporary_filet() { - unlink(name.c_str()); + if(!name.empty()) + unlink(name.c_str()); } diff --git a/src/util/tempfile.h b/src/util/tempfile.h index 06bd216ec48..6445086c26e 100644 --- a/src/util/tempfile.h +++ b/src/util/tempfile.h @@ -6,6 +6,7 @@ Author: Daniel Kroening \*******************************************************************/ + #ifndef CPROVER_UTIL_TEMPFILE_H #define CPROVER_UTIL_TEMPFILE_H @@ -32,9 +33,9 @@ class temporary_filet // Using the copy constructor would delete the file twice. temporary_filet(const temporary_filet &)=delete; - temporary_filet(temporary_filet &&other) : - name(std::move(other.name)) + temporary_filet(temporary_filet &&other) { + name.swap(other.name); } // get the name diff --git a/src/util/threeval.cpp b/src/util/threeval.cpp index ea073177df2..04311325043 100644 --- a/src/util/threeval.cpp +++ b/src/util/threeval.cpp @@ -6,10 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include "threeval.h" +#include + const char *tvt::to_string() const { switch(value) diff --git a/src/util/threeval.h b/src/util/threeval.h index 59c0400f7da..e1f92ceae48 100644 --- a/src/util/threeval.h +++ b/src/util/threeval.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_THREEVAL_H #define CPROVER_UTIL_THREEVAL_H @@ -41,7 +42,7 @@ class tvt return value; } - tvt() + tvt():value(tv_enumt::TV_UNKNOWN) { } @@ -73,7 +74,7 @@ class tvt return unknown(); } - tvt operator||(const tvt other) + tvt operator||(const tvt other) const { if(is_true() || other.is_true()) return tvt(true); diff --git a/src/util/time_stopping.cpp b/src/util/time_stopping.cpp index 3dda40c9ee5..b81848c323d 100644 --- a/src/util/time_stopping.cpp +++ b/src/util/time_stopping.cpp @@ -8,6 +8,11 @@ Date: February 2004 \*******************************************************************/ +/// \file +/// Time Stopping + +#include "time_stopping.h" + #include #if defined(_WIN32) && !defined(__MINGW32__) @@ -17,8 +22,6 @@ Date: February 2004 #include #endif -#include "time_stopping.h" - #if defined(_WIN32) && !defined(__MINGW32__) // NOLINTNEXTLINE(readability/identifiers) struct timezone @@ -41,18 +44,6 @@ void gettimeofday(struct timeval* p, struct timezone *tz) } #endif -/*******************************************************************\ - -Function: current_time - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - absolute_timet current_time() { // NOLINTNEXTLINE(readability/identifiers) @@ -65,35 +56,11 @@ absolute_timet current_time() return absolute_timet(tv.tv_usec/1000+(unsigned long long)tv.tv_sec*1000); } -/*******************************************************************\ - -Function: operator << - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::ostream &operator << (std::ostream &out, const time_periodt &period) { return out << static_cast(period.get_t())/1000; } -/*******************************************************************\ - -Function: time_periodt::as_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string time_periodt::as_string() const { std::ostringstream out; diff --git a/src/util/time_stopping.h b/src/util/time_stopping.h index 9187ce2529c..d09a4a91077 100644 --- a/src/util/time_stopping.h +++ b/src/util/time_stopping.h @@ -8,6 +8,9 @@ Date: February 2004 \*******************************************************************/ +/// \file +/// Time Stopping + #ifndef CPROVER_UTIL_TIME_STOPPING_H #define CPROVER_UTIL_TIME_STOPPING_H diff --git a/src/util/timer.cpp b/src/util/timer.cpp index 655dcb21ffb..095947a65d3 100644 --- a/src/util/timer.cpp +++ b/src/util/timer.cpp @@ -8,39 +8,18 @@ Module: Time Stopping \*******************************************************************/ -#include -#include +/// \file +/// Time Stopping #include "timer.h" -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include +#include timert::~timert() { } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void timert::start() { assert(!started); @@ -50,18 +29,6 @@ void timert::start() nr_starts++; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void timert::stop() { assert(started); @@ -71,18 +38,6 @@ void timert::stop() _total_time += _latest_time; } -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void timert::clear() { _total_time.clear(); diff --git a/src/util/timer.h b/src/util/timer.h index dcdba700542..79d60082f65 100644 --- a/src/util/timer.h +++ b/src/util/timer.h @@ -6,6 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +/// \file +/// Time Stopping + #ifndef CPROVER_UTIL_TIMER_H #define CPROVER_UTIL_TIMER_H diff --git a/src/util/type.cpp b/src/util/type.cpp index fa33c7ea58b..288666ac443 100644 --- a/src/util/type.cpp +++ b/src/util/type.cpp @@ -6,37 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "type.h" - -/*******************************************************************\ - -Function: typet::copy_to_subtypes - - Inputs: - - Outputs: - - Purpose: -\*******************************************************************/ +#include "type.h" void typet::copy_to_subtypes(const typet &type) { subtypes().push_back(type); } -/*******************************************************************\ - -Function: typet::move_to_subtypes - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void typet::move_to_subtypes(typet &type) { subtypest &sub=subtypes(); @@ -44,18 +21,6 @@ void typet::move_to_subtypes(typet &type) sub.back().swap(type); } -/*******************************************************************\ - -Function: is_number - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool is_number(const typet &type) { const irep_idt &id=type.id(); diff --git a/src/util/type.h b/src/util/type.h index c9640959a2f..7e9b3a47e87 100644 --- a/src/util/type.h +++ b/src/util/type.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_TYPE_H #define CPROVER_UTIL_TYPE_H diff --git a/src/util/type_eq.cpp b/src/util/type_eq.cpp index 0a63181b04f..0f78c20880f 100644 --- a/src/util/type_eq.cpp +++ b/src/util/type_eq.cpp @@ -6,25 +6,17 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +/// \file +/// Type Checking #include "type_eq.h" + +#include + #include "type.h" #include "symbol.h" #include "namespace.h" -/*******************************************************************\ - -Function: type_eq - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool type_eq(const typet &type1, const typet &type2, const namespacet &ns) { if(type1==type2) diff --git a/src/util/type_eq.h b/src/util/type_eq.h index f81cb9b19b4..d871536eca8 100644 --- a/src/util/type_eq.h +++ b/src/util/type_eq.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_TYPE_EQ_H #define CPROVER_UTIL_TYPE_EQ_H diff --git a/src/util/typecheck.cpp b/src/util/typecheck.cpp index 67b695e53fa..a09f54d8ff0 100644 --- a/src/util/typecheck.cpp +++ b/src/util/typecheck.cpp @@ -6,22 +6,16 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "typecheck.h" - -/*******************************************************************\ - -Function: - - Inputs: - - Outputs: - Purpose: - -\*******************************************************************/ +#include "typecheck.h" bool typecheckt::typecheck_main() { + assert(message_handler); + + const unsigned errors_before= + message_handler->get_message_count(messaget::M_ERROR); + try { typecheck(); @@ -29,7 +23,7 @@ bool typecheckt::typecheck_main() catch(int) { - error_found=true; + error(); } catch(const char *e) @@ -42,5 +36,5 @@ bool typecheckt::typecheck_main() error() << e << eom; } - return error_found; + return message_handler->get_message_count(messaget::M_ERROR)!=errors_before; } diff --git a/src/util/typecheck.h b/src/util/typecheck.h index ee80f6e42f0..a11b2738fb8 100644 --- a/src/util/typecheck.h +++ b/src/util/typecheck.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_TYPECHECK_H #define CPROVER_UTIL_TYPECHECK_H @@ -16,30 +17,27 @@ class typecheckt:public messaget { public: explicit typecheckt(message_handlert &_message_handler): - messaget(_message_handler), - error_found(false) + messaget(_message_handler) { } virtual ~typecheckt() { } - mstreamt &error() + // not pretty, but makes transition easier + void err_location(const source_locationt &loc) { - error_found=true; - return messaget::error(); + messaget::error().source_location=loc; } // not pretty, but makes transition easier void err_location(const exprt &src) { - error().source_location=src.find_source_location(); + err_location(src.find_source_location()); } - bool error_found; - - bool get_error_found() const + void err_location(const typet &src) { - return error_found; + err_location(src.source_location()); } protected: diff --git a/src/util/ui_message.cpp b/src/util/ui_message.cpp index c8d908c20d7..b680184e5ac 100644 --- a/src/util/ui_message.cpp +++ b/src/util/ui_message.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "ui_message.h" + #include #include @@ -13,30 +15,17 @@ Author: Daniel Kroening, kroening@kroening.com #include "json.h" #include "xml_expr.h" #include "cout_message.h" -#include "ui_message.h" #include "cmdline.h" -/*******************************************************************\ - -Function: ui_message_handlert::ui_message_handlert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - ui_message_handlert::ui_message_handlert( uit __ui, const std::string &program):_ui(__ui) { switch(__ui) { - case PLAIN: + case uit::PLAIN: break; - case XML_UI: + case uit::XML_UI: std::cout << "" << "\n"; std::cout << "" << "\n"; @@ -49,7 +38,7 @@ ui_message_handlert::ui_message_handlert( } break; - case JSON_UI: + case uit::JSON_UI: { std::cout << "[\n"; json_objectt json_program; @@ -60,70 +49,34 @@ ui_message_handlert::ui_message_handlert( } } -/*******************************************************************\ - -Function: ui_message_handlert::ui_message_handlert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - ui_message_handlert::ui_message_handlert( const class cmdlinet &cmdline, const std::string &program): ui_message_handlert( - cmdline.isset("xml-ui")?XML_UI: - cmdline.isset("json-ui")?JSON_UI: - PLAIN, + cmdline.isset("xml-ui")?uit::XML_UI: + cmdline.isset("json-ui")?uit::JSON_UI: + uit::PLAIN, program) { } -/*******************************************************************\ - -Function: ui_message_handlert::~ui_message_handlert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - ui_message_handlert::~ui_message_handlert() { switch(get_ui()) { - case XML_UI: + case uit::XML_UI: std::cout << "" << "\n"; break; - case JSON_UI: + case uit::JSON_UI: std::cout << "\n]\n"; break; - case PLAIN: + case uit::PLAIN: break; } } -/*******************************************************************\ - -Function: ui_message_handlert::level_string - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const char *ui_message_handlert::level_string(unsigned level) { if(level==1) @@ -134,18 +87,6 @@ const char *ui_message_handlert::level_string(unsigned level) return "STATUS-MESSAGE"; } -/*******************************************************************\ - -Function: ui_message_handlert::print - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ui_message_handlert::print( unsigned level, const std::string &message) @@ -154,15 +95,15 @@ void ui_message_handlert::print( { switch(get_ui()) { - case PLAIN: + case uit::PLAIN: { console_message_handlert console_message_handler; console_message_handler.print(level, message); } break; - case XML_UI: - case JSON_UI: + case uit::XML_UI: + case uit::JSON_UI: { source_locationt location; location.make_nil(); @@ -173,35 +114,25 @@ void ui_message_handlert::print( } } -/*******************************************************************\ - -Function: ui_message_handlert::print - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ui_message_handlert::print( unsigned level, const std::string &message, int sequence_number, const source_locationt &location) { + message_handlert::print(level, message); + if(verbosity>=level) { switch(get_ui()) { - case PLAIN: + case uit::PLAIN: message_handlert::print( level, message, sequence_number, location); break; - case XML_UI: - case JSON_UI: + case uit::XML_UI: + case uit::JSON_UI: { std::string tmp_message(message); @@ -220,18 +151,6 @@ void ui_message_handlert::print( } } -/*******************************************************************\ - -Function: ui_message_handlert::ui_msg - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ui_message_handlert::ui_msg( const std::string &type, const std::string &msg1, @@ -240,31 +159,19 @@ void ui_message_handlert::ui_msg( { switch(get_ui()) { - case PLAIN: + case uit::PLAIN: break; - case XML_UI: + case uit::XML_UI: xml_ui_msg(type, msg1, msg2, location); break; - case JSON_UI: + case uit::JSON_UI: json_ui_msg(type, msg1, msg2, location); break; } } -/*******************************************************************\ - -Function: ui_message_handlert::xml_ui_msg - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ui_message_handlert::xml_ui_msg( const std::string &type, const std::string &msg1, @@ -282,21 +189,9 @@ void ui_message_handlert::xml_ui_msg( result.set_attribute("type", type); std::cout << result; - std::cout << std::endl; + std::cout << '\n'; } -/*******************************************************************\ - -Function: ui_message_handlert::json_ui_msg - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void ui_message_handlert::json_ui_msg( const std::string &type, const std::string &msg1, @@ -319,3 +214,23 @@ void ui_message_handlert::json_ui_msg( // a trailing comma. std::cout << ",\n" << result; } + +void ui_message_handlert::flush(unsigned level) +{ + switch(get_ui()) + { + case uit::PLAIN: + { + console_message_handlert console_message_handler; + console_message_handler.flush(level); + } + break; + + case uit::XML_UI: + case uit::JSON_UI: + { + std::cout << std::flush; + } + break; + } +} diff --git a/src/util/ui_message.h b/src/util/ui_message.h index 80ee5c28ba9..757108483f1 100644 --- a/src/util/ui_message.h +++ b/src/util/ui_message.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_UI_MESSAGE_H #define CPROVER_UTIL_UI_MESSAGE_H @@ -14,10 +15,14 @@ Author: Daniel Kroening, kroening@kroening.com class ui_message_handlert:public message_handlert { public: - typedef enum { PLAIN, XML_UI, JSON_UI } uit; + enum class uit { PLAIN, XML_UI, JSON_UI }; ui_message_handlert(uit, const std::string &program); ui_message_handlert(const class cmdlinet &, const std::string &program); + ui_message_handlert(): + _ui(uit::PLAIN) + { + } virtual ~ui_message_handlert(); @@ -31,6 +36,8 @@ class ui_message_handlert:public message_handlert _ui=__ui; } + virtual void flush(unsigned level); + protected: uit _ui; diff --git a/src/util/unicode.cpp b/src/util/unicode.cpp index 4c997f1a6c3..df38d52f8e7 100644 --- a/src/util/unicode.cpp +++ b/src/util/unicode.cpp @@ -6,48 +6,26 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "unicode.h" + #include #include #include #include #include -#include "unicode.h" - #ifdef _WIN32 #include #endif -/*******************************************************************\ - -Function: is_little_endian_arch - - Inputs: - - Outputs: True if the architecture is little_endian - - Purpose: Determine endianness of the architecture - -\*******************************************************************/ - +/// Determine endianness of the architecture +/// \return True if the architecture is little_endian bool is_little_endian_arch() { uint32_t i=1; return reinterpret_cast(i); } -/*******************************************************************\ - -Function: narrow - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - #define BUFSIZE 100 std::string narrow(const wchar_t *s) @@ -75,18 +53,6 @@ std::string narrow(const wchar_t *s) #endif } -/*******************************************************************\ - -Function: widen - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::wstring widen(const char *s) { #ifdef _WIN32 @@ -112,18 +78,6 @@ std::wstring widen(const char *s) #endif } -/*******************************************************************\ - -Function: narrow - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::string narrow(const std::wstring &s) { #ifdef _WIN32 @@ -141,18 +95,6 @@ std::string narrow(const std::wstring &s) #endif } -/*******************************************************************\ - -Function: widen - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - std::wstring widen(const std::string &s) { #ifdef _WIN32 @@ -170,18 +112,8 @@ std::wstring widen(const std::string &s) #endif } -/*******************************************************************\ - -Function: utf8_append_code - - Inputs: character to append, string to append to - - Outputs: - - Purpose: Appends a unicode character to a utf8-encoded string - -\*******************************************************************/ - +/// Appends a unicode character to a utf8-encoded string +/// \par parameters: character to append, string to append to static void utf8_append_code(unsigned int c, std::string &result) { if(c<=0x7f) @@ -206,19 +138,8 @@ static void utf8_append_code(unsigned int c, std::string &result) } } -/*******************************************************************\ - -Function: utf32_to_utf8 - - Inputs: utf32-encoded wide string - - Outputs: utf8-encoded string with the same unicode characters - as the input. - - Purpose: - -\*******************************************************************/ - +/// \param utf32:encoded wide string +/// \return utf8-encoded string with the same unicode characters as the input. std::string utf32_to_utf8(const std::basic_string &s) { std::string result; @@ -231,26 +152,14 @@ std::string utf32_to_utf8(const std::basic_string &s) return result; } -/*******************************************************************\ - -Function: narrow_argv - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - const char **narrow_argv(int argc, const wchar_t **argv_wide) { - if(argv_wide==NULL) - return NULL; + if(argv_wide==nullptr) + return nullptr; // the following never gets deleted const char **argv_narrow=new const char *[argc+1]; - argv_narrow[argc]=0; + argv_narrow[argc]=nullptr; for(int i=0; i - #include "union_find.h" -/*******************************************************************\ - -Function: unsigned_union_find::make_union - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ +#include void unsigned_union_find::make_union(size_type j, size_type k) { @@ -50,18 +38,6 @@ void unsigned_union_find::make_union(size_type j, size_type k) } } -/*******************************************************************\ - -Function: unsigned_union_find::isolate - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void unsigned_union_find::isolate(size_type a) { check_index(a); @@ -95,18 +71,6 @@ void unsigned_union_find::isolate(size_type a) nodes[a].count=1; } -/*******************************************************************\ - -Function: unsigned_union_find::re_root - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void unsigned_union_find::re_root(size_type old_root, size_type new_root) { check_index(old_root); @@ -120,7 +84,7 @@ void unsigned_union_find::re_root(size_type old_root, size_type new_root) if(find(new_root)!=old_root) return; - // make sure we actually do s.th. + // make sure we actually do something assert(new_root!=old_root); assert(nodes[old_root].count>=2); @@ -141,18 +105,6 @@ void unsigned_union_find::re_root(size_type old_root, size_type new_root) } } -/*******************************************************************\ - -Function: unsigned_union_find::get_other - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - unsigned_union_find::size_type unsigned_union_find::get_other(size_type a) { check_index(a); @@ -169,18 +121,6 @@ unsigned_union_find::size_type unsigned_union_find::get_other(size_type a) return 0; } -/*******************************************************************\ - -Function: unsigned_union_find::intersection - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void unsigned_union_find::intersection( const unsigned_union_find &other) { @@ -202,18 +142,6 @@ void unsigned_union_find::intersection( swap(new_sets); } -/*******************************************************************\ - -Function: unsigned_union_find::find - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - unsigned_union_find::size_type unsigned_union_find::find(size_type a) const { if(a>=size()) diff --git a/src/util/union_find.h b/src/util/union_find.h index 2fee15e495b..4908bf65a49 100644 --- a/src/util/union_find.h +++ b/src/util/union_find.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_UNION_FIND_H #define CPROVER_UTIL_UNION_FIND_H diff --git a/src/util/xml.cpp b/src/util/xml.cpp index aa784c96604..991617cca73 100644 --- a/src/util/xml.cpp +++ b/src/util/xml.cpp @@ -6,22 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - -#include "string2int.h" #include "xml.h" -/*******************************************************************\ - -Function: xmlt::clear - - Inputs: - - Outputs: - - Purpose: +#include -\*******************************************************************/ +#include "string2int.h" void xmlt::clear() { @@ -31,18 +20,6 @@ void xmlt::clear() elements.clear(); } -/*******************************************************************\ - -Function: xmlt::swap - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void xmlt::swap(xmlt &xml) { xml.data.swap(data); @@ -51,18 +28,6 @@ void xmlt::swap(xmlt &xml) xml.name.swap(name); } -/*******************************************************************\ - -Function: xmlt::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void xmlt::output(std::ostream &out, unsigned indent) const { // 'name' needs to be set, or we produce mal-formed @@ -109,18 +74,7 @@ void xmlt::output(std::ostream &out, unsigned indent) const out << '<' << '/' << name << '>' << "\n"; } -/*******************************************************************\ - -Function: xmlt::escape - - Inputs: - - Outputs: - - Purpose: escaping for XML elements - -\*******************************************************************/ - +/// escaping for XML elements void xmlt::escape(const std::string &s, std::ostream &out) { for(const auto ch : s) @@ -156,20 +110,8 @@ void xmlt::escape(const std::string &s, std::ostream &out) } } -/*******************************************************************\ - -Function: xmlt::escape_attribute - - Inputs: - - Outputs: - - Purpose: escaping for XML attributes, assuming that - double quotes " are used consistently, - not single quotes - -\*******************************************************************/ - +/// escaping for XML attributes, assuming that double quotes " are used +/// consistently, not single quotes void xmlt::escape_attribute(const std::string &s, std::ostream &out) { for(const auto ch : s) @@ -202,35 +144,11 @@ void xmlt::escape_attribute(const std::string &s, std::ostream &out) } } -/*******************************************************************\ - -Function: xmlt::do_indent - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void xmlt::do_indent(std::ostream &out, unsigned indent) { out << std::string(indent, ' '); } -/*******************************************************************\ - -Function: xmlt::find - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - xmlt::elementst::const_iterator xmlt::find(const std::string &name) const { for(elementst::const_iterator it=elements.begin(); @@ -242,18 +160,6 @@ xmlt::elementst::const_iterator xmlt::find(const std::string &name) const return elements.end(); } -/*******************************************************************\ - -Function: xmlt::find - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - xmlt::elementst::iterator xmlt::find(const std::string &name) { for(elementst::iterator it=elements.begin(); @@ -265,18 +171,6 @@ xmlt::elementst::iterator xmlt::find(const std::string &name) return elements.end(); } -/*******************************************************************\ - -Function: xmlt::set_attribute - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void xmlt::set_attribute( const std::string &attribute, unsigned value) @@ -284,18 +178,6 @@ void xmlt::set_attribute( set_attribute(attribute, std::to_string(value)); } -/*******************************************************************\ - -Function: xmlt::set_attribute - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void xmlt::set_attribute( const std::string &attribute, unsigned long value) @@ -303,18 +185,6 @@ void xmlt::set_attribute( set_attribute(attribute, std::to_string(value)); } -/*******************************************************************\ - -Function: xmlt::set_attribute - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void xmlt::set_attribute( const std::string &attribute, unsigned long long value) @@ -322,18 +192,6 @@ void xmlt::set_attribute( set_attribute(attribute, std::to_string(value)); } -/*******************************************************************\ - -Function: xmlt::set_attribute - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void xmlt::set_attribute( const std::string &attribute, const std::string &value) @@ -349,18 +207,9 @@ void xmlt::set_attribute( } } -/*******************************************************************\ - -Function: xmlt::unescape - - Inputs: a string - - Outputs: the unescaped string - - Purpose: takes a string and unescapes any xml style escaped symbols - -\*******************************************************************/ - +/// takes a string and unescapes any xml style escaped symbols +/// \par parameters: a string +/// \return the unescaped string std::string xmlt::unescape(const std::string &str) { std::string result(""); diff --git a/src/util/xml.h b/src/util/xml.h index 8ca5726df96..28a52f59c30 100644 --- a/src/util/xml.h +++ b/src/util/xml.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_XML_H #define CPROVER_UTIL_XML_H @@ -14,11 +15,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -/*! \defgroup gr_xml XML file processing */ - -/*! \brief TO_BE_DOCUMENTED - \ingroup xml -*/ class xmlt { public: diff --git a/src/util/xml_expr.cpp b/src/util/xml_expr.cpp index 236c844f6e5..c3551617b68 100644 --- a/src/util/xml_expr.cpp +++ b/src/util/xml_expr.cpp @@ -8,6 +8,11 @@ Author: Daniel Kroening \*******************************************************************/ +/// \file +/// Expressions in XML + +#include "xml_expr.h" + #include "namespace.h" #include "expr.h" #include "xml.h" @@ -17,20 +22,6 @@ Author: Daniel Kroening #include "std_expr.h" #include "config.h" -#include "xml_expr.h" - -/*******************************************************************\ - -Function: xml - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - xmlt xml(const source_locationt &location) { xmlt result; @@ -52,18 +43,6 @@ xmlt xml(const source_locationt &location) return result; } -/*******************************************************************\ - -Function: xml - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - xmlt xml( const typet &type, const namespacet &ns) @@ -159,18 +138,6 @@ xmlt xml( return result; } -/*******************************************************************\ - -Function: xml - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - xmlt xml( const exprt &expr, const namespacet &ns) diff --git a/src/util/xml_expr.h b/src/util/xml_expr.h index 145c09310be..bc5ccf857d9 100644 --- a/src/util/xml_expr.h +++ b/src/util/xml_expr.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_XML_EXPR_H #define CPROVER_UTIL_XML_EXPR_H diff --git a/src/util/xml_irep.cpp b/src/util/xml_irep.cpp index 92bad4df40c..33d09f42c94 100644 --- a/src/util/xml_irep.cpp +++ b/src/util/xml_irep.cpp @@ -8,25 +8,14 @@ Author: Daniel Kroening \*******************************************************************/ +#include "xml_irep.h" + #include #include -#include "xml_irep.h" #include "irep.h" #include "xml.h" -/*******************************************************************\ - -Function: convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void convert( const irept &irep, xmlt &xml) @@ -55,18 +44,6 @@ void convert( } } -/*******************************************************************\ - -Function: convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void convert( const xmlt &xml, irept &irep) diff --git a/src/util/xml_irep.h b/src/util/xml_irep.h index 2537649356a..3c931cbf5f5 100644 --- a/src/util/xml_irep.h +++ b/src/util/xml_irep.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_UTIL_XML_IREP_H #define CPROVER_UTIL_XML_IREP_H diff --git a/src/xmllang/graphml.cpp b/src/xmllang/graphml.cpp index e96abaa74ee..d76f5b1f956 100644 --- a/src/xmllang/graphml.cpp +++ b/src/xmllang/graphml.cpp @@ -6,32 +6,23 @@ Author: Michael Tautschnig, mt@eecs.qmul.ac.uk \*******************************************************************/ +/// \file +/// Read/write graphs as GraphML + +#include "graphml.h" + #include #include #include #include -#include "graphml.h" - // include last to make sure #define stack(x) of parser.h does not // collide with std::stack included by graph.h #include "xml_parser.h" typedef std::map name_mapt; -/*******************************************************************\ - -Function: add_node - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static graphmlt::node_indext add_node( const std::string &name, name_mapt &name_to_node, @@ -45,18 +36,6 @@ static graphmlt::node_indext add_node( return entry.first->second; } -/*******************************************************************\ - -Function: build_graph_rec - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static bool build_graph_rec( const xmlt &xml, name_mapt &name_to_node, @@ -168,24 +147,12 @@ static bool build_graph_rec( return false; } -/*******************************************************************\ - -Function: build_graph - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static bool build_graph( const xmlt &xml, graphmlt &dest, graphmlt::node_indext &entry) { - assert(dest.size()==0); + assert(dest.empty()); name_mapt name_to_node; std::map > defaults; @@ -214,18 +181,6 @@ static bool build_graph( return err; } -/*******************************************************************\ - -Function: read_graphml - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool read_graphml( std::istream &is, graphmlt &dest, @@ -240,18 +195,6 @@ bool read_graphml( return build_graph(xml, dest, entry); } -/*******************************************************************\ - -Function: read_graphml - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool read_graphml( const std::string &filename, graphmlt &dest, @@ -266,18 +209,6 @@ bool read_graphml( return build_graph(xml, dest, entry); } -/*******************************************************************\ - -Function: write_graphml - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - bool write_graphml(const graphmlt &src, std::ostream &os) { xmlt graphml("graphml"); diff --git a/src/xmllang/graphml.h b/src/xmllang/graphml.h index 1ef5aaedae1..3b399d48c3b 100644 --- a/src/xmllang/graphml.h +++ b/src/xmllang/graphml.h @@ -6,6 +6,9 @@ Author: Michael Tautschnig, mt@eecs.qmul.ac.uk \*******************************************************************/ +/// \file +/// Read/write graphs as GraphML + #ifndef CPROVER_XMLLANG_GRAPHML_H #define CPROVER_XMLLANG_GRAPHML_H diff --git a/src/xmllang/xml_parse_tree.cpp b/src/xmllang/xml_parse_tree.cpp index b18bda862a5..c673f87f034 100644 --- a/src/xmllang/xml_parse_tree.cpp +++ b/src/xmllang/xml_parse_tree.cpp @@ -6,37 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include "xml_parse_tree.h" - -/*******************************************************************\ - -Function: xml_parse_treet::swap - - Inputs: - Outputs: - - Purpose: - -\*******************************************************************/ +#include "xml_parse_tree.h" void xml_parse_treet::swap(xml_parse_treet &xml_parse_tree) { xml_parse_tree.element.swap(element); } -/*******************************************************************\ - -Function: xml_parse_treet::clear - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - void xml_parse_treet::clear() { xml.clear(); diff --git a/src/xmllang/xml_parse_tree.h b/src/xmllang/xml_parse_tree.h index 4d0ab02b8b7..5aa2f4f6080 100644 --- a/src/xmllang/xml_parse_tree.h +++ b/src/xmllang/xml_parse_tree.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_XMLLANG_XML_PARSE_TREE_H #define CPROVER_XMLLANG_XML_PARSE_TREE_H diff --git a/src/xmllang/xml_parser.cpp b/src/xmllang/xml_parser.cpp index f56ee14e202..f03d4d87b24 100644 --- a/src/xmllang/xml_parser.cpp +++ b/src/xmllang/xml_parser.cpp @@ -6,26 +6,14 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include "xml_parser.h" + #include #include #include -#include "xml_parser.h" - xml_parsert xml_parser; -/*******************************************************************\ - -Function: parse_xml - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - // 'do it all' function bool parse_xml( std::istream &in, @@ -49,18 +37,6 @@ bool parse_xml( return result; } -/*******************************************************************\ - -Function: parse_xml - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - // 'do it all' function bool parse_xml( const std::string &filename, diff --git a/src/xmllang/xml_parser.h b/src/xmllang/xml_parser.h index b4ebd33c3e6..f4659160653 100644 --- a/src/xmllang/xml_parser.h +++ b/src/xmllang/xml_parser.h @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ + #ifndef CPROVER_XMLLANG_XML_PARSER_H #define CPROVER_XMLLANG_XML_PARSER_H diff --git a/unit/Makefile b/unit/Makefile index a1de1539ee7..409402af1f1 100644 --- a/unit/Makefile +++ b/unit/Makefile @@ -1,9 +1,20 @@ .PHONY: all cprover.dir test -SRC = unit_tests.cpp \ - catch_example.cpp \ +# Source files for test utilities +SRC = src/expr/require_expr.cpp \ + src/ansi-c/c_to_expr.cpp \ # Empty last line +# Test source files +SRC += unit_tests.cpp \ + analyses/ai/ai_simplify_lhs.cpp \ + analyses/does_remove_const/does_expr_lose_const.cpp \ + analyses/does_remove_const/does_type_preserve_const_correctness.cpp \ + analyses/does_remove_const/is_type_at_least_as_const_as.cpp \ + miniBDD_new.cpp \ + catch_example.cpp \ + # Empty last line + INCLUDES= -I ../src/ -I. include ../src/config.inc @@ -12,19 +23,21 @@ include ../src/common cprover.dir: $(MAKE) $(MAKEARGS) -C ../src -LIBS += ../src/ansi-c/ansi-c$(LIBEXT) \ - ../src/cpp/cpp$(LIBEXT) \ - ../src/json/json$(LIBEXT) \ - ../src/linking/linking$(LIBEXT) \ - ../src/util/util$(LIBEXT) \ - ../src/big-int/big-int$(LIBEXT) \ - ../src/goto-programs/goto-programs$(LIBEXT) \ - ../src/pointer-analysis/pointer-analysis$(LIBEXT) \ - ../src/langapi/langapi$(LIBEXT) \ - ../src/assembler/assembler$(LIBEXT) \ - ../src/analyses/analyses$(LIBEXT) \ - ../src/solvers/solvers$(LIBEXT) \ - # Empty last line +CPROVER_LIBS =../src/ansi-c/ansi-c$(LIBEXT) \ + ../src/cpp/cpp$(LIBEXT) \ + ../src/json/json$(LIBEXT) \ + ../src/linking/linking$(LIBEXT) \ + ../src/util/util$(LIBEXT) \ + ../src/big-int/big-int$(LIBEXT) \ + ../src/goto-programs/goto-programs$(LIBEXT) \ + ../src/pointer-analysis/pointer-analysis$(LIBEXT) \ + ../src/langapi/langapi$(LIBEXT) \ + ../src/assembler/assembler$(LIBEXT) \ + ../src/analyses/analyses$(LIBEXT) \ + ../src/solvers/solvers$(LIBEXT) \ + # Empty last line + +OBJ += $(CPROVER_LIBS) TESTS = unit_tests$(EXEEXT) \ miniBDD$(EXEEXT) \ @@ -46,11 +59,11 @@ test: all unit_tests$(EXEEXT): $(OBJ) $(LINKBIN) -miniBDD$(EXEEXT): miniBDD$(OBJEXT) +miniBDD$(EXEEXT): miniBDD$(OBJEXT) $(CPROVER_LIBS) $(LINKBIN) -string_utils$(EXEEXT): string_utils$(OBJEXT) +string_utils$(EXEEXT): string_utils$(OBJEXT) $(CPROVER_LIBS) $(LINKBIN) -sharing_node$(EXEEXT): sharing_node$(OBJEXT) +sharing_node$(EXEEXT): sharing_node$(OBJEXT) $(CPROVER_LIBS) $(LINKBIN) diff --git a/unit/analyses/ai/ai_simplify_lhs.cpp b/unit/analyses/ai/ai_simplify_lhs.cpp new file mode 100644 index 00000000000..d161df0bffb --- /dev/null +++ b/unit/analyses/ai/ai_simplify_lhs.cpp @@ -0,0 +1,169 @@ +/*******************************************************************\ + + Module: Unit tests for ai_domain_baset::ai_simplify_lhs + + Author: DiffBlue Limited. All rights reserved. + +\*******************************************************************/ + +/// \file +/// Unit tests for ai_domain_baset::ai_simplify_lhs + +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include + +class constant_simplification_mockt:public ai_domain_baset +{ +public: + void transform(locationt, locationt, ai_baset &, const namespacet &) override + {} + void make_bottom() override + {} + void make_top() override + {} + void make_entry() override + {} + + bool ai_simplify(exprt &condition, const namespacet &ns) const override; +}; + +bool constant_simplification_mockt::ai_simplify( + exprt &condition, const namespacet &ns) const +{ + exprt simplified_expr=simplify_expr(condition, ns); + // no simplification + if(simplified_expr==condition) + { + return true; + } + // a simplification has occurred + condition=simplified_expr; + return false; +} + +SCENARIO("ai_domain_baset::ai_simplify_lhs", + "[core][analyses][ai][ai_simplify_lhs]") +{ + ui_message_handlert message_handler; + ansi_c_languaget language; + language.set_message_handler(message_handler); + + symbol_tablet symbol_table; + namespacet ns(symbol_table); + + constant_simplification_mockt mock_ai_domain; + + config.set_arch("none"); + + GIVEN("A index_exprt") + { + // Construct an expression that the simplify_expr can simplify + exprt simplifiable_expression; + bool compile_failed= + language.to_expr("1 + 1", "", simplifiable_expression, ns); + + const unsigned int array_size=5; + array_typet array_type( + signedbv_typet(32), from_integer(array_size, size_type())); + + // Verify the results of the setup + REQUIRE_FALSE(compile_failed);\ + REQUIRE(simplifiable_expression.id()==ID_plus); + exprt simplified_version=simplify_expr(simplifiable_expression, ns); + REQUIRE(simplified_version.id()==ID_constant); + + WHEN( + "Simplifying an index expression with constant index but variable array") + { + const index_exprt &index_expr= + index_exprt(symbol_exprt("a", array_type), simplifiable_expression); + + THEN("Then only the index of the part of the expression should be " + "simplified") + { + exprt out_expr=index_expr; + bool no_simplification=mock_ai_domain.ai_simplify_lhs(out_expr, ns); + REQUIRE_FALSE(no_simplification); + REQUIRE(index_expr.id()==ID_index); + + index_exprt simplified_index_expr=to_index_expr(out_expr); + REQUIRE(simplified_index_expr.index().id()==ID_constant); + + constant_exprt constant_index= + to_constant_expr(simplified_index_expr.index()); + + mp_integer out_index; + bool failed_to_integer=to_integer(constant_index, out_index); + REQUIRE_FALSE(failed_to_integer); + REQUIRE(out_index==2); + } + } + WHEN("Simplifying an index expression with variable index and array") + { + // a[i] + const index_exprt &index_expr= + index_exprt( + symbol_exprt("a", array_type), symbol_exprt("i", signedbv_typet(32))); + + THEN("Then no simplification should occur") + { + exprt out_expr=index_expr; + bool no_simplification=mock_ai_domain.ai_simplify_lhs(out_expr, ns); + REQUIRE(no_simplification); + REQUIRE(index_expr.id()==ID_index); + + index_exprt simplified_index_expr=to_index_expr(out_expr); + REQUIRE(simplified_index_expr.index().id()==ID_symbol); + } + } + + // This fails since the implementation does do a constant simplification + // on the array part. It isn't clear to me if this is correct +#if 0 + WHEN( + "Simplifying an index expression with constant index in a constant array") + { + array_exprt constant_array=array_exprt(array_type); + for(unsigned int i=0; i +#include +#include +#include +#include +#include +#include +#include + + +SCENARIO("does_expr_lose_const", + "[core][analyses][does_remove_const][does_expr_remove_const]") +{ + symbol_tablet symbol_table; + namespacet ns(symbol_table); + goto_programt program; + does_remove_constt does_remove_const(program, ns); + does_remove_const_testt does_remove_const_test(does_remove_const); + + GIVEN("Const and non-const primitive and pointers to primitives") + { + c_qualifierst const_qualifier; + const_qualifier.is_constant=true; + + // const int + typet const_primitive_type=integer_typet(); + const_qualifier.write(const_primitive_type); + + // int + typet non_const_primitive_type=integer_typet(); + + // pointer (can be reassigned) + // to int (value can be changed) + // int * + typet pointer_to_int_type=pointer_typet(non_const_primitive_type); + + // const pointer (can't be reassigned) + // to int (value can be changed) + // int * const + typet const_pointer_to_int_type=pointer_typet(non_const_primitive_type); + const_qualifier.write(const_pointer_to_int_type); + + // pointer (can be reassigned) + // to const int (value can't be changed) + // const int * + typet pointer_to_const_int_type=pointer_typet(const_primitive_type); + + // constant pointer (can't be reassigned) + // to const int (value can't be changed) + // const int * const + typet const_pointer_to_const_int_type=pointer_typet(const_primitive_type); + const_qualifier.write(const_pointer_to_const_int_type); + + symbol_exprt const_primitive_symbol( + "const_primitive", const_primitive_type); + symbol_exprt non_const_primitive_symbol( + "non_const_primitive", non_const_primitive_type); + symbol_exprt pointer_to_int_symbol( + "pointer_to_int", pointer_to_int_type); + symbol_exprt const_pointer_to_int_symbol( + "const_pointer_to_int", const_pointer_to_int_type); + symbol_exprt pointer_to_const_int_symbol( + "pointer_to_const_int", pointer_to_const_int_type); + symbol_exprt const_pointer_to_const_int_symbol( + "const_pointer_to_const_int", const_pointer_to_const_int_type); + + WHEN("Casting from int to int") + { + typecast_exprt cast_expr( + non_const_primitive_symbol, non_const_primitive_type); + + THEN("The cast_expr does not lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE_FALSE(result); + } + } + WHEN("Casting from const int to int") + { + typecast_exprt cast_expr( + non_const_primitive_symbol, const_primitive_type); + + THEN("The cast_expr does not lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE_FALSE(result); + } + } + WHEN("Casting from int to const int") + { + typecast_exprt cast_expr( + non_const_primitive_symbol, const_primitive_type); + + THEN("The cast_expr does not lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE_FALSE(result); + } + } + WHEN("Casting from const int to const int") + { + typecast_exprt cast_expr( + const_primitive_symbol, const_primitive_type); + + THEN("The cast_expr does not lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE_FALSE(result); + } + } + WHEN("Casting from int * to int *") + { + typecast_exprt cast_expr( + pointer_to_int_symbol, pointer_to_int_type); + THEN("The cast_expr does not lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE_FALSE(result); + } + } + WHEN("Casting from const int * to int *") + { + typecast_exprt cast_expr( + pointer_to_const_int_symbol, pointer_to_int_type); + THEN("The cast_expr does lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE(result); + } + } + WHEN("Casting from int * b const to int *") + { + typecast_exprt cast_expr( + const_pointer_to_int_symbol, pointer_to_int_type); + THEN("The cast_expr does not lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE_FALSE(result); + } + } + WHEN("Casting from const int * b const to int *") + { + typecast_exprt cast_expr( + const_pointer_to_const_int_symbol, pointer_to_int_type); + THEN("The cast_expr does lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE(result); + } + } + WHEN("Casting from int * to const int *") + { + typecast_exprt cast_expr( + pointer_to_int_symbol, pointer_to_const_int_type); + THEN("The cast_expr does not lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE_FALSE(result); + } + } + WHEN("Casting from const int * to const int *") + { + typecast_exprt cast_expr( + pointer_to_const_int_symbol, pointer_to_const_int_type); + THEN("The cast_expr does not lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE_FALSE(result); + } + } + WHEN("Casting from int * b const to const int *") + { + typecast_exprt cast_expr( + const_pointer_to_int_symbol, pointer_to_const_int_type); + THEN("The cast_expr does not lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE_FALSE(result); + } + } + WHEN("Casting from const int * b const to const int *") + { + typecast_exprt cast_expr( + const_pointer_to_const_int_symbol, pointer_to_const_int_type); + THEN("The cast_expr does not lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE_FALSE(result); + } + } + WHEN("Casting from int * to int * const") + { + typecast_exprt cast_expr( + pointer_to_int_symbol, const_pointer_to_int_type); + THEN("The cast_expr does not lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE_FALSE(result); + } + } + WHEN("Casting from const int * to int * const") + { + typecast_exprt cast_expr( + pointer_to_const_int_symbol, const_pointer_to_int_type); + THEN("The cast_expr does lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE(result); + } + } + WHEN("Casting from int * b const to int * const") + { + typecast_exprt cast_expr( + const_pointer_to_int_symbol, const_pointer_to_int_type); + THEN("The cast_expr does not lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE_FALSE(result); + } + } + WHEN("Casting from const int * b const to int * const") + { + typecast_exprt cast_expr( + const_pointer_to_const_int_symbol, const_pointer_to_int_type); + THEN("The cast_expr does not lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE(result); + } + } + WHEN("Casting from int * to const int * const") + { + typecast_exprt cast_expr( + pointer_to_int_symbol, const_pointer_to_const_int_type); + THEN("The cast_expr does not lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE_FALSE(result); + } + } + WHEN("Casting from const int * to const int * const") + { + typecast_exprt cast_expr( + pointer_to_const_int_symbol, const_pointer_to_const_int_type); + THEN("The cast_expr does not lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE_FALSE(result); + } + } + WHEN("Casting from int * b const to const int * const") + { + typecast_exprt cast_expr( + const_pointer_to_int_symbol, const_pointer_to_const_int_type); + THEN("The cast_expr does not lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE_FALSE(result); + } + } + WHEN("Casting from const int * b const to const int * const") + { + typecast_exprt cast_expr( + const_pointer_to_const_int_symbol, const_pointer_to_const_int_type); + THEN("The cast_expr does not lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE_FALSE(result); + } + } + + WHEN("Casting from &(int) to int *") + { + typecast_exprt cast_expr( + address_of_exprt(non_const_primitive_symbol), pointer_to_int_type); + + THEN("The typecast_expr does not lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE_FALSE(result); + } + } + WHEN("Casting from &(const int) to int *") + { + typecast_exprt cast_expr( + address_of_exprt(const_primitive_symbol), pointer_to_int_type); + + THEN("The cast_expr does lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE(result); + } + } + WHEN("Casting from &(int) to const int *") + { + typecast_exprt cast_expr( + address_of_exprt(non_const_primitive_symbol), + pointer_to_const_int_type); + + THEN("The cast_expr does not lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE_FALSE(result); + } + } + WHEN("Casting from &(const int) to const int *") + { + typecast_exprt cast_expr( + address_of_exprt(const_primitive_symbol), pointer_to_const_int_type); + + THEN("The cast_expr does not lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE_FALSE(result); + } + } + WHEN("Casting from &(int) to int * const") + { + typecast_exprt cast_expr( + address_of_exprt(non_const_primitive_symbol), + const_pointer_to_int_type); + + THEN("The cast_expr does not lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE_FALSE(result); + } + } + WHEN("Casting from &(const int) to int * const") + { + typecast_exprt cast_expr( + address_of_exprt(const_primitive_symbol), const_pointer_to_int_type); + + THEN("The cast_expr does lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE(result); + } + } + WHEN("Casting from &(int) to const int * const") + { + typecast_exprt cast_expr( + address_of_exprt(non_const_primitive_symbol), + const_pointer_to_const_int_type); + + THEN("The cast_expr does not lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE_FALSE(result); + } + } + WHEN("Casting from &(const int) to const int * const") + { + typecast_exprt cast_expr( + address_of_exprt(const_primitive_symbol), + const_pointer_to_const_int_type); + + THEN("The cast_expr does not lose const-correctness") + { + bool result=does_remove_const_test.does_expr_lose_const(cast_expr); + REQUIRE_FALSE(result); + } + } + } +} diff --git a/unit/analyses/does_remove_const/does_remove_const_util.h b/unit/analyses/does_remove_const/does_remove_const_util.h new file mode 100644 index 00000000000..e1a459b6c1b --- /dev/null +++ b/unit/analyses/does_remove_const/does_remove_const_util.h @@ -0,0 +1,49 @@ +/*******************************************************************\ + + Module: Does Remove Const Unit Tests + + Author: DiffBlue Limited. All rights reserved. + +\*******************************************************************/ + +/// \file +/// Does Remove Const Unit Tests + +#ifndef CPROVER__ANALYSES_DOES_REMOVE_CONST_DOES_REMOVE_CONST_UTIL_H +#define CPROVER__ANALYSES_DOES_REMOVE_CONST_DOES_REMOVE_CONST_UTIL_H + +#include + +// This class provides access to private members and functions of +// does_remove_const +class does_remove_const_testt +{ +public: + explicit does_remove_const_testt(does_remove_constt does_remove_const): + does_remove_const(does_remove_const) + {} + + bool does_expr_lose_const(const exprt &expr) const + { + return does_remove_const.does_expr_lose_const(expr); + } + + bool is_type_at_least_as_const_as( + const typet &type_more_const, const typet &type_compare) const + { + return does_remove_const.is_type_at_least_as_const_as( + type_more_const, type_compare); + } + + bool does_type_preserve_const_correctness( + const typet *target_type, const typet *source_type) const + { + return does_remove_const.does_type_preserve_const_correctness( + target_type, source_type); + } + +private: + does_remove_constt does_remove_const; +}; + +#endif // CPROVER__ANALYSES_DOES_REMOVE_CONST_DOES_REMOVE_CONST_UTIL_H diff --git a/unit/analyses/does_remove_const/does_type_preserve_const_correctness.cpp b/unit/analyses/does_remove_const/does_type_preserve_const_correctness.cpp new file mode 100644 index 00000000000..0f10081c49b --- /dev/null +++ b/unit/analyses/does_remove_const/does_type_preserve_const_correctness.cpp @@ -0,0 +1,265 @@ +/*******************************************************************\ + + Module: Does Remove Const Unit Tests + + Author: DiffBlue Limited. All rights reserved. + +\*******************************************************************/ + +/// \file +/// Does Remove Const Unit Tests + +#include + +#include +#include +#include +#include +#include +#include + +SCENARIO("does_type_preserve_const_correctness", + "[core][analyses][does_remove_const][does_type_preserve_const_correctness]") +{ + symbol_tablet symbol_table; + namespacet ns(symbol_table); + goto_programt program; + does_remove_constt does_remove_const(program, ns); + does_remove_const_testt does_remove_const_test(does_remove_const); + + GIVEN("Const and non-const primitive and pointers to primitives") + { + c_qualifierst const_qualifier; + const_qualifier.is_constant=true; + + // const int + typet const_primitive_type=integer_typet(); + const_qualifier.write(const_primitive_type); + + // int + typet non_const_primitive_type=integer_typet(); + + // pointer (can be reassigned) + // to int (value can be changed) + // int * + typet pointer_to_int_type=pointer_typet(non_const_primitive_type); + + // const pointer (can't be reassigned) + // to int (value can be changed) + // int * const + typet const_pointer_to_int_type=pointer_typet(non_const_primitive_type); + const_qualifier.write(const_pointer_to_int_type); + + // pointer (can be reassigned) + // to const int (value can't be changed) + // const int * + typet pointer_to_const_int_type=pointer_typet(const_primitive_type); + + // constant pointer (can't be reassigned) + // to const int (value can't be changed) + // const int * const + typet const_pointer_to_const_int_type=pointer_typet(const_primitive_type); + const_qualifier.write(const_pointer_to_const_int_type); + + WHEN("Comparing int to int") + { + THEN("The target type preserves the const-correctness of the source type") + { + bool result= + does_remove_const_test.does_type_preserve_const_correctness( + &non_const_primitive_type, &non_const_primitive_type); + REQUIRE(result); + } + } + WHEN("Comparing const int to int") + { + THEN("The target type preserves the const-correctness of the source type") + { + bool result= + does_remove_const_test.does_type_preserve_const_correctness( + &const_primitive_type, &non_const_primitive_type); + REQUIRE(result); + } + } + WHEN("Comparing int to const int") + { + THEN("The target type preserves the const-correctness of the source type") + { + bool result= + does_remove_const_test.does_type_preserve_const_correctness( + &non_const_primitive_type, &const_primitive_type); + REQUIRE(result); + } + } + WHEN("Comparing const int to const int") + { + THEN("The target type preserves the const-correctness of the source type") + { + bool result= + does_remove_const_test.does_type_preserve_const_correctness( + &const_primitive_type, &const_primitive_type); + REQUIRE(result); + } + } + WHEN("Comparing int * to int *") + { + THEN("The target type preserves the const-correctness of the source type") + { + bool result= + does_remove_const_test.does_type_preserve_const_correctness( + &pointer_to_int_type, &pointer_to_int_type); + REQUIRE(result); + } + } + WHEN("Comparing const int * to int *") + { + THEN("The target type preserves the const-correctness of the source type") + { + bool result= + does_remove_const_test.does_type_preserve_const_correctness( + &pointer_to_const_int_type, &pointer_to_int_type); + REQUIRE(result); + } + } + WHEN("Comparing int * b const to int *") + { + THEN("The target type preserves the const-correctness of the source type") + { + bool result= + does_remove_const_test.does_type_preserve_const_correctness( + &const_pointer_to_int_type, &pointer_to_int_type); + REQUIRE(result); + } + } + WHEN("Comparing const int * b const to int *") + { + THEN("The target type preserves the const-correctness of the source type") + { + bool result= + does_remove_const_test.does_type_preserve_const_correctness( + &const_pointer_to_const_int_type, &pointer_to_int_type); + REQUIRE(result); + } + } + WHEN("Comparing int * to const int *") + { + THEN("The target type loses const-correctness of the source type") + { + bool result= + does_remove_const_test.does_type_preserve_const_correctness( + &pointer_to_int_type, &pointer_to_const_int_type); + REQUIRE_FALSE(result); + } + } + WHEN("Comparing const int * to const int *") + { + THEN("The target type preserves the const-correctness of the source type") + { + bool result= + does_remove_const_test.does_type_preserve_const_correctness( + &pointer_to_const_int_type, &pointer_to_const_int_type); + REQUIRE(result); + } + } + WHEN("Comparing int * b const to const int *") + { + THEN("The target type loses const-correctness of the source type") + { + bool result= + does_remove_const_test.does_type_preserve_const_correctness( + &const_pointer_to_int_type, &pointer_to_const_int_type); + REQUIRE_FALSE(result); + } + } + WHEN("Comparing const int * b const to const int *") + { + THEN("The target type preserves the const-correctness of the source type") + { + bool result= + does_remove_const_test.does_type_preserve_const_correctness( + &const_pointer_to_const_int_type, &pointer_to_const_int_type); + REQUIRE(result); + } + } + WHEN("Comparing int * to int * const") + { + THEN("The target type preserves the const-correctness of the source type") + { + bool result= + does_remove_const_test.does_type_preserve_const_correctness( + &pointer_to_int_type, &const_pointer_to_int_type); + REQUIRE(result); + } + } + WHEN("Comparing const int * to int * const") + { + THEN("The target type preserves the const-correctness of the source type") + { + bool result= + does_remove_const_test.does_type_preserve_const_correctness( + &pointer_to_const_int_type, &const_pointer_to_int_type); + REQUIRE(result); + } + } + WHEN("Comparing int * b const to int * const") + { + THEN("The target type preserves the const-correctness of the source type") + { + bool result= + does_remove_const_test.does_type_preserve_const_correctness( + &const_pointer_to_int_type, &const_pointer_to_int_type); + REQUIRE(result); + } + } + WHEN("Comparing const int * b const to int * const") + { + THEN("The target type preserves the const-correctness of the source type") + { + bool result= + does_remove_const_test.does_type_preserve_const_correctness( + &const_pointer_to_const_int_type, &const_pointer_to_int_type); + REQUIRE(result); + } + } + WHEN("Comparing int * to const int * const") + { + THEN("The target type loses const-correctness of the source type") + { + bool result= + does_remove_const_test.does_type_preserve_const_correctness( + &pointer_to_int_type, &const_pointer_to_const_int_type); + REQUIRE_FALSE(result); + } + } + WHEN("Comparing const int * to const int * const") + { + THEN("The target type preserves the const-correctness of the source type") + { + bool result= + does_remove_const_test.does_type_preserve_const_correctness( + &pointer_to_const_int_type, &const_pointer_to_const_int_type); + REQUIRE(result); + } + } + WHEN("Comparing int * b const to const int * const") + { + THEN("The target type loses const-correctness of the source type") + { + bool result= + does_remove_const_test.does_type_preserve_const_correctness( + &const_pointer_to_int_type, &const_pointer_to_const_int_type); + REQUIRE_FALSE(result); + } + } + WHEN("Comparing const int * b const to const int * const") + { + THEN("The target type preserves the const-correctness of the source type") + { + bool result= + does_remove_const_test.does_type_preserve_const_correctness( + &const_pointer_to_const_int_type, &const_pointer_to_const_int_type); + REQUIRE(result); + } + } + } +} diff --git a/unit/analyses/does_remove_const/is_type_at_least_as_const_as.cpp b/unit/analyses/does_remove_const/is_type_at_least_as_const_as.cpp new file mode 100644 index 00000000000..cfb2c647536 --- /dev/null +++ b/unit/analyses/does_remove_const/is_type_at_least_as_const_as.cpp @@ -0,0 +1,265 @@ +/*******************************************************************\ + + Module: Does Remove Const Unit Tests + + Author: DiffBlue Limited. All rights reserved. + +\*******************************************************************/ + +/// \file +/// Does Remove Const Unit Tests + +#include + +#include +#include +#include +#include +#include +#include + +SCENARIO("is_type_at_least_as_const", + "[core][analyses][does_remove_const][is_type_at_least_as_const]") +{ + symbol_tablet symbol_table; + namespacet ns(symbol_table); + goto_programt program; + does_remove_constt does_remove_const(program, ns); + does_remove_const_testt does_remove_const_test(does_remove_const); + + GIVEN("Const and non-const primitive and pointers to primitives") + { + c_qualifierst const_qualifier; + const_qualifier.is_constant=true; + + // const int + typet const_primitive_type=integer_typet(); + const_qualifier.write(const_primitive_type); + + // int + typet non_const_primitive_type=integer_typet(); + + // pointer (can be reassigned) + // to int (value can be changed) + // int * + typet pointer_to_int_type=pointer_typet(non_const_primitive_type); + + // const pointer (can't be reassigned) + // to int (value can be changed) + // int * const + typet const_pointer_to_int_type=pointer_typet(non_const_primitive_type); + const_qualifier.write(const_pointer_to_int_type); + + // pointer (can be reassigned) + // to const int (value can't be changed) + // const int * + typet pointer_to_const_int_type=pointer_typet(const_primitive_type); + + // constant pointer (can't be reassigned) + // to const int (value can't be changed) + // const int * const + typet const_pointer_to_const_int_type=pointer_typet(const_primitive_type); + const_qualifier.write(const_pointer_to_const_int_type); + + WHEN("Comparing int to int") + { + THEN("The first type is at least as const as the second type") + { + bool result= + does_remove_const_test.is_type_at_least_as_const_as( + non_const_primitive_type, non_const_primitive_type); + REQUIRE(result); + } + } + WHEN("Comparing const int to int") + { + THEN("The first type is at least as const as the second type") + { + bool result= + does_remove_const_test.is_type_at_least_as_const_as( + const_primitive_type, non_const_primitive_type); + REQUIRE(result); + } + } + WHEN("Comparing int to const int") + { + THEN("The first type is less const than the second type") + { + bool result= + does_remove_const_test.is_type_at_least_as_const_as( + non_const_primitive_type, const_primitive_type); + REQUIRE_FALSE(result); + } + } + WHEN("Comparing const int to const int") + { + THEN("The first type is at least as const as the second type") + { + bool result= + does_remove_const_test.is_type_at_least_as_const_as( + const_primitive_type, const_primitive_type); + REQUIRE(result); + } + } + WHEN("Comparing int * to int *") + { + THEN("The first type is at least as const as the second type") + { + bool result= + does_remove_const_test.is_type_at_least_as_const_as( + pointer_to_int_type, pointer_to_int_type); + REQUIRE(result); + } + } + WHEN("Comparing const int * to int *") + { + THEN("The first type is at least as const as the second type") + { + bool result= + does_remove_const_test.is_type_at_least_as_const_as( + pointer_to_const_int_type, pointer_to_int_type); + REQUIRE(result); + } + } + WHEN("Comparing int * b const to int *") + { + THEN("The first type is at least as const as the second type") + { + bool result= + does_remove_const_test.is_type_at_least_as_const_as( + const_pointer_to_int_type, pointer_to_int_type); + REQUIRE(result); + } + } + WHEN("Comparing const int * b const to int *") + { + THEN("The first type is at least as const as the second type") + { + bool result= + does_remove_const_test.is_type_at_least_as_const_as( + const_pointer_to_const_int_type, pointer_to_int_type); + REQUIRE(result); + } + } + WHEN("Comparing int * to const int *") + { + THEN("The first type is at least as const as the second type") + { + bool result= + does_remove_const_test.is_type_at_least_as_const_as( + pointer_to_int_type, pointer_to_const_int_type); + REQUIRE(result); + } + } + WHEN("Comparing const int * to const int *") + { + THEN("The first type is at least as const as the second type") + { + bool result= + does_remove_const_test.is_type_at_least_as_const_as( + pointer_to_const_int_type, pointer_to_const_int_type); + REQUIRE(result); + } + } + WHEN("Comparing int * b const to const int *") + { + THEN("The first type is at least as const as the second type") + { + bool result= + does_remove_const_test.is_type_at_least_as_const_as( + const_pointer_to_int_type, pointer_to_const_int_type); + REQUIRE(result); + } + } + WHEN("Comparing const int * b const to const int *") + { + THEN("The first type is at least as const as the second type") + { + bool result= + does_remove_const_test.is_type_at_least_as_const_as( + const_pointer_to_const_int_type, pointer_to_const_int_type); + REQUIRE(result); + } + } + WHEN("Comparing int * to int * const") + { + THEN("The first type is less const as the second type") + { + bool result= + does_remove_const_test.is_type_at_least_as_const_as( + pointer_to_int_type, const_pointer_to_int_type); + REQUIRE_FALSE(result); + } + } + WHEN("Comparing const int * to int * const") + { + THEN("The first type is less const as the second type") + { + bool result= + does_remove_const_test.is_type_at_least_as_const_as( + pointer_to_const_int_type, const_pointer_to_int_type); + REQUIRE_FALSE(result); + } + } + WHEN("Comparing int * b const to int * const") + { + THEN("The first type is at least as const as the second type") + { + bool result= + does_remove_const_test.is_type_at_least_as_const_as( + const_pointer_to_int_type, const_pointer_to_int_type); + REQUIRE(result); + } + } + WHEN("Comparing const int * b const to int * const") + { + THEN("The first type is at least as const as the second type") + { + bool result= + does_remove_const_test.is_type_at_least_as_const_as( + const_pointer_to_const_int_type, const_pointer_to_int_type); + REQUIRE(result); + } + } + WHEN("Comparing int * to const int * const") + { + THEN("The first type is less const than the second type") + { + bool result= + does_remove_const_test.is_type_at_least_as_const_as( + pointer_to_int_type, const_pointer_to_const_int_type); + REQUIRE_FALSE(result); + } + } + WHEN("Comparing const int * to const int * const") + { + THEN("The first type is less const than the second type") + { + bool result= + does_remove_const_test.is_type_at_least_as_const_as( + pointer_to_const_int_type, const_pointer_to_const_int_type); + REQUIRE_FALSE(result); + } + } + WHEN("Comparing int * b const to const int * const") + { + THEN("The first type is at least as const as the second type") + { + bool result= + does_remove_const_test.is_type_at_least_as_const_as( + const_pointer_to_int_type, const_pointer_to_const_int_type); + REQUIRE(result); + } + } + WHEN("Comparing const int * b const to const int * const") + { + THEN("The first type is at least as const as the second type") + { + bool result= + does_remove_const_test.is_type_at_least_as_const_as( + const_pointer_to_const_int_type, const_pointer_to_const_int_type); + REQUIRE(result); + } + } + } +} diff --git a/unit/miniBDD.cpp b/unit/miniBDD.cpp index ecda45a4ff1..d0eba414184 100644 --- a/unit/miniBDD.cpp +++ b/unit/miniBDD.cpp @@ -18,7 +18,7 @@ void test1() mini_bddt x=mgr.Var("x"); mini_bddt y=mgr.Var("y"); mini_bddt z=mgr.Var("z"); - mini_bddt f=(x&y&z)|(!x&!y&z); + mini_bddt f=(x&y&z)|((!x)&(!y)&z); y.clear(); x.clear(); z.clear(); diff --git a/unit/miniBDD_new.cpp b/unit/miniBDD_new.cpp new file mode 100644 index 00000000000..0c176c7f82e --- /dev/null +++ b/unit/miniBDD_new.cpp @@ -0,0 +1,277 @@ +/*******************************************************************\ + + Module: Unit tests for miniBDD + + Author: DiffBlue Limited. All rights reserved. + +\*******************************************************************/ + +/// \file +/// Unit tests for miniBDD + +#include + +#include +#include + +#include +#include +#include + +#include + +class bdd_propt:public propt +{ +public: + mini_bdd_mgrt &mgr; + + explicit bdd_propt(mini_bdd_mgrt &_mgr):mgr(_mgr) + { + // True and False + bdd_map.push_back(mgr.False()); + bdd_map.push_back(mgr.True()); + } + + mini_bddt to_bdd(literalt a) + { + if(a.is_true()) + return mgr.True(); + if(a.is_false()) + return mgr.False(); + INVARIANT(a.var_no() bdd_map; + + bool has_set_to() const override { return false; } + bool cnf_handled_well() const override { return false; } +}; + +SCENARIO("miniBDD", "[core][solver][miniBDD]") +{ + GIVEN("A bdd for x&!x") + { + symbol_tablet symbol_table; + namespacet ns(symbol_table); + mini_bdd_mgrt bdd_mgr; + bdd_propt bdd_prop(bdd_mgr); + prop_conv_solvert solver(ns, bdd_prop); + + symbol_exprt var("x", bool_typet()); + literalt result= + solver.convert(and_exprt(var, not_exprt(var))); + + REQUIRE(result.is_false()); + } + + GIVEN("A bdd for x&!x==0") + { + symbol_tablet symbol_table; + namespacet ns(symbol_table); + mini_bdd_mgrt bdd_mgr; + bdd_propt bdd_prop(bdd_mgr); + boolbvt boolbv(ns, bdd_prop); + + unsignedbv_typet type(2); + symbol_exprt var("x", type); + equal_exprt equality( + bitand_exprt(var, bitnot_exprt(var)), + from_integer(0, type)); + + literalt result= + boolbv.convert(equality); + + REQUIRE(result.is_true()); + } + + GIVEN("A bdd for x+x==1") + { + symbol_tablet symbol_table; + namespacet ns(symbol_table); + mini_bdd_mgrt bdd_mgr; + bdd_propt bdd_prop(bdd_mgr); + boolbvt boolbv(ns, bdd_prop); + + unsignedbv_typet type(32); + symbol_exprt var("x", type); + equal_exprt equality( + plus_exprt(var, var), + from_integer(1, type)); + + literalt result= + boolbv.convert(equality); + + REQUIRE(result.is_false()); + } + + GIVEN("A bdd for x*y==y*x") + { + symbol_tablet symbol_table; + namespacet ns(symbol_table); + mini_bdd_mgrt bdd_mgr; + bdd_propt bdd_prop(bdd_mgr); + boolbvt boolbv(ns, bdd_prop); + + unsignedbv_typet type(4); + symbol_exprt var_x("x", type); + symbol_exprt var_y("y", type); + equal_exprt equality( + mult_exprt(var_x, var_y), + mult_exprt(var_y, var_x)); + + literalt result= + boolbv.convert(equality); + + REQUIRE(result.is_true()); + } + + GIVEN("A bdd for x*x==2") + { + symbol_tablet symbol_table; + namespacet ns(symbol_table); + mini_bdd_mgrt bdd_mgr; + bdd_propt bdd_prop(bdd_mgr); + boolbvt boolbv(ns, bdd_prop); + + unsignedbv_typet type(8); + symbol_exprt var_x("x", type); + equal_exprt equality( + mult_exprt(var_x, var_x), + from_integer(2, type)); + + literalt result= + boolbv.convert(equality); + + REQUIRE(result.is_false()); + } + + GIVEN("A bdd for x*x==4") + { + symbol_tablet symbol_table; + namespacet ns(symbol_table); + mini_bdd_mgrt bdd_mgr; + bdd_propt bdd_prop(bdd_mgr); + boolbvt boolbv(ns, bdd_prop); + + unsignedbv_typet type(8); + symbol_exprt var_x("x", type); + equal_exprt equality( + mult_exprt(var_x, var_x), + from_integer(4, type)); + + literalt result= + boolbv.convert(equality); + + REQUIRE(!result.is_constant()); + } +} diff --git a/unit/src/ansi-c/c_to_expr.cpp b/unit/src/ansi-c/c_to_expr.cpp new file mode 100644 index 00000000000..bb71d5fabb1 --- /dev/null +++ b/unit/src/ansi-c/c_to_expr.cpp @@ -0,0 +1,35 @@ +/*******************************************************************\ + + Module: Unit test utilities + + Author: DiffBlue Limited. All rights reserved. + +\*******************************************************************/ + +/// \file +/// Utility for converting strings in to exprt, throwing a CATCH exception +/// if this fails in any way. +/// +#include "c_to_expr.h" + +#include + +c_to_exprt::c_to_exprt(): + message_handler( + std::unique_ptr(new ui_message_handlert())) +{ + language.set_message_handler(*message_handler); +} + +/// Take an input string that should be a valid C rhs expression +/// \param input_string: The string to convert +/// \param ns: The global namespace +/// \return: A constructed expr representing the string +exprt c_to_exprt::operator()( + const std::string &input_string, const namespacet &ns) +{ + exprt expr; + bool result=language.to_expr(input_string, "", expr, ns); + REQUIRE(!result); + return expr; +} diff --git a/unit/src/ansi-c/c_to_expr.h b/unit/src/ansi-c/c_to_expr.h new file mode 100644 index 00000000000..dcaf0b0d1b7 --- /dev/null +++ b/unit/src/ansi-c/c_to_expr.h @@ -0,0 +1,35 @@ +/*******************************************************************\ + + Module: Unit test utilities + + Author: DiffBlue Limited. All rights reserved. + +\*******************************************************************/ + +/// \file +/// Utility for converting strings in to exprt, throwing a CATCH exception +/// if this fails in any way. + +#ifndef CPROVER_SRC_ANSI_C_C_TO_EXPR_H +#define CPROVER_SRC_ANSI_C_C_TO_EXPR_H + +#include + +#include +#include +#include +#include +#include + +class c_to_exprt +{ +public: + c_to_exprt(); + exprt operator()(const std::string &input_string, const namespacet &ns); + +private: + std::unique_ptr message_handler; + ansi_c_languaget language; +}; + +#endif // CPROVER_SRC_ANSI_C_C_TO_EXPR_H diff --git a/unit/src/expr/require_expr.cpp b/unit/src/expr/require_expr.cpp new file mode 100644 index 00000000000..e81b5a2d70a --- /dev/null +++ b/unit/src/expr/require_expr.cpp @@ -0,0 +1,76 @@ +/*******************************************************************\ + + Module: Unit test utilities + + Author: DiffBlue Limited. All rights reserved. + +\*******************************************************************/ + +/// \file +/// Helper functions for requiring specific expressions +/// If the expression is of the wrong type, throw a CATCH exception +/// Also checks associated properties and returns a casted version of the +/// expression. + +#include "require_expr.h" + +#include +#include + +/// Verify a given exprt is an index_exprt with a a constant value equal to the +/// expected value +/// \param expr: The expression. +/// \param expected_index: The constant value that should be the index. +/// \return The expr cast to an index_exprt +index_exprt require_expr::require_index(const exprt &expr, int expected_index) +{ + REQUIRE(expr.id()==ID_index); + const index_exprt &index_expr=to_index_expr(expr); + REQUIRE(index_expr.index().id()==ID_constant); + const constant_exprt &index_value=to_constant_expr(index_expr.index()); + mp_integer index_integer_value; + to_integer(index_value, index_integer_value); + REQUIRE(index_integer_value==expected_index); + + return index_expr; +} + +/// Verify a given exprt is an index_exprt with a nil value as its index +/// \param expr: The expression. +/// \return The expr cast to an index_exprt +index_exprt require_expr::require_top_index(const exprt &expr) +{ + REQUIRE(expr.id()==ID_index); + const index_exprt &index_expr=to_index_expr(expr); + REQUIRE(index_expr.index().id()==ID_nil); + return index_expr; +} + +/// Verify a given exprt is an member_exprt with a component name equal to the +/// component_identifier +/// \param expr: The expression. +/// \param component_identifier: The name of the component that should be being +/// accessed. +/// \return The expr cast to a member_exprt. +member_exprt require_expr::require_member( + const exprt &expr, const irep_idt &component_identifier) +{ + REQUIRE(expr.id()==ID_member); + const member_exprt &member_expr=to_member_expr(expr); + REQUIRE(member_expr.get_component_name()==component_identifier); + return member_expr; +} + +/// Verify a given exprt is an symbol_exprt with a identifier name equal to the +/// symbol_name. +/// \param expr: The expression. +/// \param symbol_name: The intended identifier of the symbol +/// \return The expr cast to a symbol_exprt +symbol_exprt require_expr::require_symbol( + const exprt &expr, const irep_idt &symbol_name) +{ + REQUIRE(expr.id()==ID_symbol); + const symbol_exprt &symbol_expr=to_symbol_expr(expr); + REQUIRE(symbol_expr.get_identifier()==symbol_name); + return symbol_expr; +} diff --git a/unit/src/expr/require_expr.h b/unit/src/expr/require_expr.h new file mode 100644 index 00000000000..83bdad2132d --- /dev/null +++ b/unit/src/expr/require_expr.h @@ -0,0 +1,33 @@ +/*******************************************************************\ + + Module: Unit test utilities + + Author: DiffBlue Limited. All rights reserved. + +\*******************************************************************/ + +/// \file +/// Helper functions for requiring specific expressions +/// If the expression is of the wrong type, throw a CATCH exception +/// Also checks associated properties and returns a casted version of the +/// expression. + +#ifndef CPROVER_SRC_EXPR_REQUIRE_EXPR_H +#define CPROVER_SRC_EXPR_REQUIRE_EXPR_H + +#include + +// NOLINTNEXTLINE(readability/namespace) +namespace require_expr +{ + index_exprt require_index(const exprt &expr, int expected_index); + index_exprt require_top_index(const exprt &expr); + + member_exprt require_member( + const exprt &expr, const irep_idt &component_identifier); + + symbol_exprt require_symbol( + const exprt &expr, const irep_idt &symbol_name); +} + +#endif // CPROVER_SRC_EXPR_REQUIRE_EXPR_H diff --git a/unit/unit_tests.cpp b/unit/unit_tests.cpp index a4ae333109f..8d007b83696 100644 --- a/unit/unit_tests.cpp +++ b/unit/unit_tests.cpp @@ -8,3 +8,11 @@ #define CATCH_CONFIG_MAIN #include "catch.hpp" +#include + +// Debug printer for irept +std::ostream &operator<<(std::ostream &os, const irept &value) +{ + os << value.pretty(); + return os; +}