Skip to content

Commit f5eedc4

Browse files
author
Daniel Kroening
authored
Merge pull request #3421 from diffblue/smt2-fapp-type-checking
SMT2 type checking for define-fun
2 parents 7cf33ff + be0c338 commit f5eedc4

File tree

7 files changed

+94
-4
lines changed

7 files changed

+94
-4
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CORE
2+
function-application1.smt2
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^unsat$
7+
--
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
(set-logic QF_BV)
2+
3+
(define-fun min ((a (_ BitVec 8)) (b (_ BitVec 8))) (_ BitVec 8)
4+
(ite (bvule a b) a b))
5+
6+
(define-fun p1 () Bool (= (min #x01 #x02) #x01))
7+
(define-fun p2 () Bool (= (min #xff #xfe) #xfe))
8+
9+
; all must be true
10+
11+
(assert (not (and p1 p2)))
12+
13+
(check-sat)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CORE
2+
function-application2.smt2
3+
4+
^EXIT=134$
5+
^SIGNAL=0$
6+
^line 5: type mismatch in function definition: expected `\(_ BitVec 16\)' but got `\(_ BitVec 8\)'$
7+
--
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
(set-logic QF_BV)
2+
3+
; the range type doesn't match!
4+
(define-fun min ((a (_ BitVec 8)) (b (_ BitVec 8))) (_ BitVec 16)
5+
(ite (bvule a b) a b))
6+
7+
(define-fun p1 () Bool (= (min #x01 #x02) #x01))
8+
(define-fun p2 () Bool (= (min #xff #xfe) #xfe))
9+
10+
; all must be true
11+
12+
(assert (not (and p1 p2)))
13+
14+
(check-sat)

scripts/delete_failing_smt2_solver_tests

+2
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,14 @@ rm Float8/test.desc
5858
rm Free2/test.desc
5959
rm Function1/test.desc
6060
rm Function_Pointer3/test.desc
61+
rm Initialization6/test.desc
6162
rm Linking4/test.desc
6263
rm Linking7/test.desc
6364
rm Malloc17/test.desc
6465
rm Malloc18/test.desc
6566
rm Malloc19/test.desc
6667
rm Malloc20/test.desc
68+
rm Malloc21/test.desc
6769
rm Malloc23/test.desc
6870
rm Malloc24/test.desc
6971
rm Memmove1/test.desc

src/solvers/smt2/smt2_parser.cpp

+40-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,22 @@ Author: Daniel Kroening, [email protected]
1010

1111
#include <util/arith_tools.h>
1212

13+
std::ostream &operator<<(std::ostream &out, const smt2_parsert::smt2_format &f)
14+
{
15+
if(f.type.id() == ID_unsignedbv)
16+
out << "(_ BitVec " << to_unsignedbv_type(f.type).get_width() << ')';
17+
else if(f.type.id() == ID_bool)
18+
out << "Bool";
19+
else if(f.type.id() == ID_integer)
20+
out << "Int";
21+
else if(f.type.id() == ID_real)
22+
out << "Real";
23+
else
24+
out << "? " << f.type.id();
25+
26+
return out;
27+
}
28+
1329
void smt2_parsert::command_sequence()
1430
{
1531
exit=false;
@@ -360,8 +376,8 @@ exprt smt2_parsert::multi_ary(irep_idt id, const exprt::operandst &op)
360376
{
361377
error() << "expression must have operands with matching types,"
362378
" but got `"
363-
<< op[0].type().pretty()
364-
<< "' and `" << op[i].type().pretty() << '\'' << eom;
379+
<< smt2_format(op[0].type()) << "' and `"
380+
<< smt2_format(op[i].type()) << '\'' << eom;
365381
return nil_exprt();
366382
}
367383
}
@@ -385,8 +401,8 @@ exprt smt2_parsert::binary_predicate(irep_idt id, const exprt::operandst &op)
385401
{
386402
error() << "expression must have operands with matching types,"
387403
" but got `"
388-
<< op[0].type().pretty()
389-
<< "' and `" << op[1].type().pretty() << '\'' << eom;
404+
<< smt2_format(op[0].type()) << "' and `"
405+
<< smt2_format(op[1].type()) << '\'' << eom;
390406
return nil_exprt();
391407
}
392408

@@ -1187,6 +1203,26 @@ void smt2_parsert::command(const std::string &c)
11871203
auto signature=function_signature_definition();
11881204
exprt body=expression();
11891205

1206+
// check type of body
1207+
if(signature.id() == ID_mathematical_function)
1208+
{
1209+
const auto &f_signature = to_mathematical_function_type(signature);
1210+
if(body.type() != f_signature.codomain())
1211+
{
1212+
error() << "type mismatch in function definition: expected `"
1213+
<< smt2_format(f_signature.codomain()) << "' but got `"
1214+
<< smt2_format(body.type()) << '\'' << eom;
1215+
return;
1216+
}
1217+
}
1218+
else if(body.type() != signature)
1219+
{
1220+
error() << "type mismatch in function definition: expected `"
1221+
<< smt2_format(signature) << "' but got `"
1222+
<< smt2_format(body.type()) << '\'' << eom;
1223+
return;
1224+
}
1225+
11901226
// set up the entry
11911227
auto &entry=id_map[id];
11921228
entry.type=signature;

src/solvers/smt2/smt2_parser.h

+11
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,15 @@ class smt2_parsert:public smt2_tokenizert
4343
using id_mapt=std::map<irep_idt, idt>;
4444
id_mapt id_map;
4545

46+
struct smt2_format
47+
{
48+
explicit smt2_format(const typet &_type) : type(_type)
49+
{
50+
}
51+
52+
const typet type;
53+
};
54+
4655
protected:
4756
bool exit;
4857
void command_sequence();
@@ -82,4 +91,6 @@ class smt2_parsert:public smt2_tokenizert
8291
exprt cast_bv_to_unsigned(const exprt &);
8392
};
8493

94+
std::ostream &operator<<(std::ostream &, const smt2_parsert::smt2_format &);
95+
8596
#endif // CPROVER_SOLVERS_SMT2_SMT2_PARSER_H

0 commit comments

Comments
 (0)