Skip to content

Commit e38465b

Browse files
authored
Merge pull request #1507 from diffblue/invalid_width1
SMV: allow any expression in SMV types
2 parents 4f930c8 + 61bd6c2 commit e38465b

File tree

4 files changed

+56
-16
lines changed

4 files changed

+56
-16
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
invalid_width1.smv
3+
4+
^file .* line 6: expected constant expression$
5+
^EXIT=2$
6+
^SIGNAL=0$
7+
--
8+
^warning: ignoring
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
MODULE main
2+
3+
VAR width : 1..10;
4+
5+
-- The width must be constant
6+
VAR word_var : word[width];

src/smvlang/parser.y

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -556,25 +556,25 @@ type_specifier:
556556
;
557557

558558
simple_type_specifier:
559-
array_Token integer_constant DOTDOT_Token integer_constant of_Token simple_type_specifier
559+
array_Token basic_expr DOTDOT_Token basic_expr of_Token simple_type_specifier
560560
{
561561
init($$, ID_smv_array);
562562
stack_type($$).set(ID_from, stack_expr($2));
563563
stack_type($$).set(ID_to, stack_expr($4));
564564
stack_type($$).add_subtype()=stack_type($6);
565565
}
566566
| boolean_Token { init($$, ID_bool); }
567-
| word_Token '[' integer_constant ']'
567+
| word_Token '[' basic_expr ']'
568568
{
569569
init($$, ID_smv_word);
570570
stack_type($$).set(ID_width, stack_expr($3));
571571
}
572-
| signed_Token word_Token '[' integer_constant ']'
572+
| signed_Token word_Token '[' basic_expr ']'
573573
{
574574
init($$, ID_smv_signed_word);
575575
stack_type($$).set(ID_width, stack_expr($4));
576576
}
577-
| unsigned_Token word_Token '[' integer_constant ']'
577+
| unsigned_Token word_Token '[' basic_expr ']'
578578
{
579579
init($$, ID_smv_unsigned_word);
580580
stack_type($$).set(ID_width, stack_expr($4));

src/smvlang/smv_typecheck.cpp

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ class smv_typecheckt:public typecheckt
144144
return id;
145145
}
146146

147+
mp_integer require_integer_constant(const irept &) const;
148+
147149
void lower_node(exprt &) const;
148150

149151
void lower(typet &) const;
@@ -363,6 +365,36 @@ void smv_typecheckt::instantiate(
363365

364366
/*******************************************************************\
365367
368+
Function: smv_typecheckt::require_integer_constant
369+
370+
Inputs:
371+
372+
Outputs:
373+
374+
Purpose:
375+
376+
\*******************************************************************/
377+
378+
mp_integer smv_typecheckt::require_integer_constant(const irept &irep) const
379+
{
380+
auto &as_expr = static_cast<const exprt &>(irep);
381+
if(as_expr.id() != ID_constant)
382+
{
383+
throw errort().with_location(as_expr.source_location())
384+
<< "expected constant expression";
385+
}
386+
387+
if(as_expr.type().id() != ID_integer)
388+
{
389+
throw errort().with_location(as_expr.source_location())
390+
<< "expected integer expression";
391+
}
392+
393+
return numeric_cast_v<mp_integer>(to_constant_expr(as_expr));
394+
}
395+
396+
/*******************************************************************\
397+
366398
Function: smv_typecheckt::check_type
367399
368400
Inputs:
@@ -377,10 +409,8 @@ void smv_typecheckt::check_type(typet &type)
377409
{
378410
if(type.id() == ID_smv_array)
379411
{
380-
auto from = numeric_cast_v<mp_integer>(
381-
to_constant_expr(static_cast<const exprt &>(type.find(ID_from))));
382-
auto to = numeric_cast_v<mp_integer>(
383-
to_constant_expr(static_cast<const exprt &>(type.find(ID_to))));
412+
auto from = require_integer_constant(type.find(ID_from));
413+
auto to = require_integer_constant(type.find(ID_to));
384414

385415
if(to < from)
386416
throw errort().with_location(type.source_location())
@@ -402,10 +432,8 @@ void smv_typecheckt::check_type(typet &type)
402432
}
403433
else if(type.id() == ID_smv_range)
404434
{
405-
auto from = numeric_cast_v<mp_integer>(
406-
to_constant_expr(static_cast<const exprt &>(type.find(ID_from))));
407-
auto to = numeric_cast_v<mp_integer>(
408-
to_constant_expr(static_cast<const exprt &>(type.find(ID_to))));
435+
auto from = require_integer_constant(type.find(ID_from));
436+
auto to = require_integer_constant(type.find(ID_to));
409437

410438
if(from > to)
411439
throw errort().with_location(type.source_location()) << "range is empty";
@@ -416,8 +444,7 @@ void smv_typecheckt::check_type(typet &type)
416444
}
417445
else if(type.id() == ID_smv_signed_word)
418446
{
419-
auto width = numeric_cast_v<mp_integer>(
420-
to_constant_expr(static_cast<const exprt &>(type.find(ID_width))));
447+
auto width = require_integer_constant(type.find(ID_width));
421448

422449
if(width < 1)
423450
throw errort().with_location(type.source_location())
@@ -428,8 +455,7 @@ void smv_typecheckt::check_type(typet &type)
428455
}
429456
else if(type.id() == ID_smv_word || type.id() == ID_smv_unsigned_word)
430457
{
431-
auto width = numeric_cast_v<mp_integer>(
432-
to_constant_expr(static_cast<const exprt &>(type.find(ID_width))));
458+
auto width = require_integer_constant(type.find(ID_width));
433459

434460
if(width < 1)
435461
throw errort().with_location(type.source_location())

0 commit comments

Comments
 (0)