Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions regression/cbmc/rational1/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
int main()
{
__CPROVER_rational x;
__CPROVER_rational y;
x = 6 / 10;
y = 3 / 5;

__CPROVER_assert(y + 1 != x, "should pass");
__CPROVER_assert(y != x, "should fail");
}
10 changes: 10 additions & 0 deletions regression/cbmc/rational1/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CORE smt-backend broken-cprover-smt-backend no-new-smt
main.c
--trace --smt2
^\[main.assertion.2\] line 9 should fail: FAILURE$
^\s*x=3/5
^\s*y=3/5
^\*\* 1 of 2 failed
^EXIT=10$
^SIGNAL=0$
--
8 changes: 8 additions & 0 deletions regression/cbmc/rational1/typecheck.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CORE
main.c
--show-goto-functions
^[[:space:]]*ASSIGN main::1::x := 3/5
^[[:space:]]*ASSIGN main::1::y := 3/5
^EXIT=0$
^SIGNAL=0$
--
9 changes: 9 additions & 0 deletions regression/cbmc/real-assignments1/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
int main()
{
__CPROVER_real a, b;
a = 0;
b = a;
b++;
b *= 100;
__CPROVER_assert(0, "");
}
7 changes: 7 additions & 0 deletions regression/cbmc/real-assignments1/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CORE smt-backend broken-cprover-smt-backend no-new-smt
main.c
--trace --smt2
^EXIT=10$
^SIGNAL=0$
^ b=100
--
8 changes: 8 additions & 0 deletions regression/cbmc/real-assignments1/typecheck.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CORE
main.c
--show-goto-functions
^[[:space:]]*ASSIGN main::1::b := main::1::b \* cast\(100, ℝ\)$
^EXIT=0$
^SIGNAL=0$
--
^[[:space:]]*ASSIGN main::1::b := main::1::b \* 100$
2 changes: 2 additions & 0 deletions regression/validate-trace-xml-schema/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
['enum_is_in_range', 'enum_test3-simplified.desc'],
['enum_is_in_range', 'format.desc'],
['r_w_ok9', 'simplify.desc'],
['rational1', 'typecheck.desc'],
['reachability-slice-interproc2', 'test.desc'],
['real-assignments1', 'typecheck.desc'],
['saturating_arithmetric', 'output-goto.desc'],
# this one wants show-properties instead producing a trace
['show_properties1', 'test.desc'],
Expand Down
2 changes: 2 additions & 0 deletions src/ansi-c/ansi_c_internal_additions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,9 @@ void ansi_c_internal_additions(std::string &code, bool support_float16_type)
" " CPROVER_PREFIX "ssize_t;\n"
"const unsigned " CPROVER_PREFIX "constant_infinity_uint;\n"
"typedef void " CPROVER_PREFIX "integer;\n"
"typedef void " CPROVER_PREFIX "natural;\n"
"typedef void " CPROVER_PREFIX "rational;\n"
"typedef void " CPROVER_PREFIX "real;\n"
"extern unsigned char " CPROVER_PREFIX "memory["
CPROVER_PREFIX "constant_infinity_uint];\n"

Expand Down
125 changes: 74 additions & 51 deletions src/ansi-c/c_typecast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,22 @@ Author: Daniel Kroening, [email protected]

#include "c_typecast.h"

#include <algorithm>

#include <util/arith_tools.h>
#include <util/c_types.h>
#include <util/config.h>
#include <util/expr_util.h>
#include <util/mathematical_types.h>
#include <util/namespace.h>
#include <util/pointer_expr.h>
#include <util/rational.h>
#include <util/rational_tools.h>
#include <util/simplify_expr.h>
#include <util/std_expr.h>

#include "c_qualifiers.h"

#include <algorithm>

bool c_implicit_typecast(
exprt &expr,
const typet &dest_type,
Expand Down Expand Up @@ -102,30 +104,28 @@ bool check_c_implicit_typecast(

if(src_type_id==ID_natural)
{
if(dest_type.id()==ID_bool ||
dest_type.id()==ID_c_bool ||
dest_type.id()==ID_integer ||
dest_type.id()==ID_real ||
dest_type.id()==ID_complex ||
dest_type.id()==ID_unsignedbv ||
dest_type.id()==ID_signedbv ||
dest_type.id()==ID_floatbv ||
dest_type.id()==ID_complex)
if(
dest_type.id() == ID_bool || dest_type.id() == ID_c_bool ||
dest_type.id() == ID_integer || dest_type.id() == ID_rational ||
dest_type.id() == ID_real || dest_type.id() == ID_complex ||
dest_type.id() == ID_unsignedbv || dest_type.id() == ID_signedbv ||
dest_type.id() == ID_floatbv || dest_type.id() == ID_complex)
{
return false;
}
}
else if(src_type_id==ID_integer)
{
if(dest_type.id()==ID_bool ||
dest_type.id()==ID_c_bool ||
dest_type.id()==ID_real ||
dest_type.id()==ID_complex ||
dest_type.id()==ID_unsignedbv ||
dest_type.id()==ID_signedbv ||
dest_type.id()==ID_floatbv ||
dest_type.id()==ID_fixedbv ||
dest_type.id()==ID_pointer ||
dest_type.id()==ID_complex)
if(
dest_type.id() == ID_bool || dest_type.id() == ID_c_bool ||
dest_type.id() == ID_natural || dest_type.id() == ID_rational ||
dest_type.id() == ID_real || dest_type.id() == ID_complex ||
dest_type.id() == ID_unsignedbv || dest_type.id() == ID_signedbv ||
dest_type.id() == ID_floatbv || dest_type.id() == ID_fixedbv ||
dest_type.id() == ID_pointer || dest_type.id() == ID_complex)
{
return false;
}
}
else if(src_type_id==ID_real)
{
Expand All @@ -139,49 +139,46 @@ bool check_c_implicit_typecast(
}
else if(src_type_id==ID_rational)
{
if(dest_type.id()==ID_bool ||
dest_type.id()==ID_c_bool ||
dest_type.id()==ID_complex ||
dest_type.id()==ID_floatbv ||
dest_type.id()==ID_fixedbv ||
dest_type.id()==ID_complex)
if(
dest_type.id() == ID_bool || dest_type.id() == ID_c_bool ||
dest_type.id() == ID_real || dest_type.id() == ID_complex ||
dest_type.id() == ID_floatbv || dest_type.id() == ID_fixedbv ||
dest_type.id() == ID_complex)
{
return false;
}
}
else if(src_type_id==ID_bool)
{
if(dest_type.id()==ID_c_bool ||
dest_type.id()==ID_integer ||
dest_type.id()==ID_real ||
dest_type.id()==ID_unsignedbv ||
dest_type.id()==ID_signedbv ||
dest_type.id()==ID_pointer ||
dest_type.id()==ID_floatbv ||
dest_type.id()==ID_fixedbv ||
dest_type.id()==ID_c_enum ||
dest_type.id()==ID_c_enum_tag ||
dest_type.id()==ID_complex)
if(
dest_type.id() == ID_c_bool || dest_type.id() == ID_integer ||
dest_type.id() == ID_natural || dest_type.id() == ID_rational ||
dest_type.id() == ID_real || dest_type.id() == ID_unsignedbv ||
dest_type.id() == ID_signedbv || dest_type.id() == ID_pointer ||
dest_type.id() == ID_floatbv || dest_type.id() == ID_fixedbv ||
dest_type.id() == ID_c_enum || dest_type.id() == ID_c_enum_tag ||
dest_type.id() == ID_complex)
{
return false;
}
}
else if(src_type_id==ID_unsignedbv ||
src_type_id==ID_signedbv ||
src_type_id==ID_c_enum ||
src_type_id==ID_c_enum_tag ||
src_type_id==ID_c_bool)
{
if(dest_type.id()==ID_unsignedbv ||
dest_type.id()==ID_bool ||
dest_type.id()==ID_c_bool ||
dest_type.id()==ID_integer ||
dest_type.id()==ID_real ||
dest_type.id()==ID_rational ||
dest_type.id()==ID_signedbv ||
dest_type.id()==ID_floatbv ||
dest_type.id()==ID_fixedbv ||
dest_type.id()==ID_pointer ||
dest_type.id()==ID_c_enum ||
dest_type.id()==ID_c_enum_tag ||
dest_type.id()==ID_complex)
if(
dest_type.id() == ID_unsignedbv || dest_type.id() == ID_bool ||
dest_type.id() == ID_c_bool || dest_type.id() == ID_integer ||
dest_type.id() == ID_natural || dest_type.id() == ID_rational ||
dest_type.id() == ID_real || dest_type.id() == ID_signedbv ||
dest_type.id() == ID_floatbv || dest_type.id() == ID_fixedbv ||
dest_type.id() == ID_pointer || dest_type.id() == ID_c_enum ||
dest_type.id() == ID_c_enum_tag || dest_type.id() == ID_complex)
{
return false;
}
}
else if(src_type_id==ID_floatbv ||
src_type_id==ID_fixedbv)
Expand Down Expand Up @@ -415,6 +412,8 @@ c_typecastt::c_typet c_typecastt::get_c_type(
}
else if(type.id() == ID_integer)
return INTEGER;
else if(type.id() == ID_natural)
return NATURAL;

return OTHER;
}
Expand Down Expand Up @@ -454,6 +453,9 @@ void c_typecastt::implicit_typecast_arithmetic(
case RATIONAL: new_type=rational_typet(); break;
case REAL: new_type=real_typet(); break;
case INTEGER: new_type=integer_typet(); break;
case NATURAL:
new_type = natural_typet();
break;
case COMPLEX:
case OTHER:
case VOIDPTR:
Expand Down Expand Up @@ -776,6 +778,27 @@ void c_typecastt::do_typecast(exprt &expr, const typet &dest_type)
{
expr=is_not_zero(expr, ns);
}
else if(dest_type.id() == ID_rational)
{
if(auto div_expr = expr_try_dynamic_cast<div_exprt>(expr))
{
auto op1 = numeric_cast<mp_integer>(div_expr->lhs());
auto op2 = numeric_cast<mp_integer>(div_expr->rhs());
if(op1.has_value() && op2.has_value())
{
rationalt numerator{*op1};
expr = from_rational(rationalt{*op1} / rationalt{*op2});
return;
}
}
else if(auto int_const = numeric_cast<mp_integer>(expr))
{
expr = from_integer(*int_const, dest_type);
return;
}

expr = typecast_exprt(expr, dest_type);
}
else
{
expr = typecast_exprt(expr, dest_type);
Expand Down
42 changes: 29 additions & 13 deletions src/ansi-c/c_typecast.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,35 @@ class c_typecastt

// these are in promotion order

enum c_typet { BOOL,
CHAR, UCHAR,
SHORT, USHORT,
INT, UINT,
LONG, ULONG,
LONGLONG, ULONGLONG,
LARGE_SIGNED_INT, LARGE_UNSIGNED_INT,
INTEGER, // these are unbounded integers, non-standard
FIXEDBV, // fixed-point, non-standard
SINGLE, DOUBLE, LONGDOUBLE, FLOAT128, // float
RATIONAL, REAL, // infinite precision, non-standard
COMPLEX,
VOIDPTR, PTR, OTHER };
enum c_typet
{
BOOL,
CHAR,
UCHAR,
SHORT,
USHORT,
INT,
UINT,
LONG,
ULONG,
LONGLONG,
ULONGLONG,
LARGE_SIGNED_INT,
LARGE_UNSIGNED_INT,
INTEGER, // these are unbounded integers, non-standard
NATURAL, // these are unbounded natural numbers, non-standard
FIXEDBV, // fixed-point, non-standard
SINGLE,
DOUBLE,
LONGDOUBLE,
FLOAT128, // float
RATIONAL, // infinite precision, non-standard
REAL, // infinite precision, non-standard
COMPLEX,
VOIDPTR,
PTR,
OTHER
};

c_typet get_c_type(const typet &type) const;

Expand Down
8 changes: 8 additions & 0 deletions src/ansi-c/c_typecheck_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1686,6 +1686,14 @@ void c_typecheck_baset::typecheck_typedef_type(typet &type)
{
type=integer_typet();
}
else if(symbol.base_name == CPROVER_PREFIX "natural")
{
type = natural_typet();
}
else if(symbol.base_name == CPROVER_PREFIX "real")
{
type = real_typet();
}
}

void c_typecheck_baset::adjust_function_parameter(typet &type) const
Expand Down
16 changes: 7 additions & 9 deletions src/ansi-c/expr2c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,11 +245,11 @@ std::string expr2ct::convert_rec(
{
return q + CPROVER_PREFIX + "string" + d;
}
else if(src.id()==ID_natural ||
src.id()==ID_integer ||
src.id()==ID_rational)
else if(
src.id() == ID_natural || src.id() == ID_integer ||
src.id() == ID_rational || src.id() == ID_real)
{
return q+src.id_string()+d;
return q + CPROVER_PREFIX + src.id_string() + d;
}
else if(src.id()==ID_empty)
{
Expand Down Expand Up @@ -1796,9 +1796,9 @@ std::string expr2ct::convert_constant(
const irep_idt value=src.get_value();
std::string dest;

if(type.id()==ID_integer ||
type.id()==ID_natural ||
type.id()==ID_rational)
if(
type.id() == ID_integer || type.id() == ID_natural ||
type.id() == ID_rational || type.id() == ID_real)
{
dest=id2string(value);
}
Expand Down Expand Up @@ -1837,8 +1837,6 @@ std::string expr2ct::convert_constant(
else
return "/*enum*/" + value_as_string;
}
else if(type.id()==ID_rational)
return convert_norep(src, precedence);
else if(type.id()==ID_bv)
{
// used for _BitInt
Expand Down
8 changes: 8 additions & 0 deletions src/solvers/flattening/boolbv_width.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,14 @@ const boolbv_widtht::entryt &boolbv_widtht::get_entry(const typet &type) const
{
cache_entry = defined_entryt{0};
}
else if(
type_id == ID_rational || type_id == ID_real || type_id == ID_integer ||
type_id == ID_natural)
{
// these have unbounded width, but we warn about this elsewhere and
// shouldn't fail in get_entry
cache_entry = defined_entryt{1};
}
else
{
UNIMPLEMENTED_FEATURE(
Expand Down
Loading
Loading