Skip to content

Commit 2bb336c

Browse files
committed
strengthen expression class typing
Objects with specific expression class types are casted up to that type. This avoids direct, unguarded accesses to exprt::op0, op1, etc.
1 parent 4407973 commit 2bb336c

26 files changed

+459
-490
lines changed

src/ebmc/bdd_engine.cpp

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -412,10 +412,8 @@ void bdd_enginet::check_property(propertyt &property)
412412
if(property.expr.id()==ID_AG ||
413413
property.expr.id()==ID_sva_always)
414414
{
415-
assert(property.expr.operands().size()==1);
416-
417415
// recursive call
418-
const exprt &sub_expr=property.expr.op0();
416+
const exprt &sub_expr = to_unary_expr(property.expr).op();
419417
BDD p=property2BDD(sub_expr);
420418

421419
// Start with !p, and go backwards until saturation or we hit an
@@ -535,8 +533,8 @@ bdd_enginet::BDD bdd_enginet::property2BDD(const exprt &expr)
535533
else if(expr.id()==ID_implies ||
536534
expr.id()==ID_sva_overlapped_implication)
537535
{
538-
assert(expr.operands().size()==2);
539-
return (!property2BDD(expr.op0())) | property2BDD(expr.op1());
536+
return (!property2BDD(to_binary_expr(expr).lhs())) |
537+
property2BDD(to_binary_expr(expr).rhs());
540538
}
541539
else if(expr.id()==ID_and)
542540
{
@@ -554,18 +552,14 @@ bdd_enginet::BDD bdd_enginet::property2BDD(const exprt &expr)
554552
}
555553
else if(expr.id()==ID_sva_non_overlapped_implication)
556554
{
557-
assert(expr.operands().size()==2);
558-
559555
// use sva_nexttime for this
560-
unary_predicate_exprt tmp(ID_sva_nexttime, expr.op1());
561-
return (!property2BDD(expr.op0())) | property2BDD(tmp);
556+
unary_predicate_exprt tmp(ID_sva_nexttime, to_binary_expr(expr).rhs());
557+
return (!property2BDD(to_binary_expr(expr).lhs())) | property2BDD(tmp);
562558
}
563559
else if(expr.id()==ID_sva_nexttime)
564560
{
565-
assert(expr.operands().size()==1);
566-
567561
// recursive call
568-
const exprt &sub_expr=expr.op0();
562+
const exprt &sub_expr = to_unary_expr(expr).op();
569563
BDD p=property2BDD(sub_expr);
570564

571565
// make 'p' be expressed in terms of 'next' variables
@@ -587,10 +581,8 @@ bdd_enginet::BDD bdd_enginet::property2BDD(const exprt &expr)
587581
}
588582
else if(expr.id()==ID_sva_eventually)
589583
{
590-
assert(expr.operands().size()==1);
591-
592584
// recursive call
593-
const exprt &sub_expr=expr.op0();
585+
const exprt &sub_expr = to_unary_expr(expr).op();
594586
BDD p=property2BDD(sub_expr);
595587
BDD states=p;
596588

@@ -626,10 +618,8 @@ bdd_enginet::BDD bdd_enginet::property2BDD(const exprt &expr)
626618
else if(expr.id()==ID_AG ||
627619
expr.id()==ID_sva_always)
628620
{
629-
assert(expr.operands().size()==1);
630-
631621
// recursive call
632-
const exprt &sub_expr=expr.op0();
622+
const exprt &sub_expr = to_unary_expr(expr).op();
633623
BDD p=property2BDD(sub_expr);
634624
BDD states=p;
635625

src/ebmc/k_induction.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,8 @@ int k_inductiont::induction_step()
165165
error() << "unsupported property - only SVA always or AG implemented" << eom;
166166
return 1;
167167
}
168-
169-
assert(property.operands().size()==1);
170168

171-
const exprt &p=property.op0();
169+
const exprt &p = to_unary_expr(property).op();
172170

173171
// assumption: time frames 0,...,k-1
174172
for(unsigned c=0; c<no_timeframes-1; c++)

src/ebmc/negate_property.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ exprt negate_property(const exprt &expr)
8484
{
8585
// rewrite using 'next'
8686
assert(expr.operands().size()==2);
87-
unary_predicate_exprt next(ID_sva_nexttime, expr.op1());
87+
unary_predicate_exprt next(ID_sva_nexttime, to_binary_expr(expr).rhs());
8888
binary_exprt result=to_binary_expr(expr);
8989
result.op1()=negate_property(next);
9090
return std::move(result);

src/ebmc/output_verilog.cpp

Lines changed: 53 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,13 @@ Function: output_verilog_netlistt::is_symbol
6060

6161
bool output_verilog_netlistt::is_symbol(const exprt &expr) const
6262
{
63-
if(expr.id()==ID_extractbit ||
64-
expr.id()==ID_extractbits)
63+
if(expr.id() == ID_extractbit)
6564
{
66-
assert(expr.operands().size()>=1);
67-
return is_symbol(expr.op0());
65+
return is_symbol(to_extractbit_expr(expr).src());
66+
}
67+
else if(expr.id() == ID_extractbits)
68+
{
69+
return is_symbol(to_extractbits_expr(expr).src());
6870
}
6971
else if(expr.id()==ID_symbol)
7072
{
@@ -182,10 +184,9 @@ void output_verilog_netlistt::assign_symbol(
182184
{
183185
assert(rhs.type().id()==ID_bool);
184186
assert(lhs.type().id()==ID_bool);
185-
assert(rhs.operands().size()==1);
186187

187-
std::string tmp=make_symbol_expr(rhs.op0(), "");
188-
188+
std::string tmp = make_symbol_expr(to_not_expr(rhs).op(), "");
189+
189190
out << " " << rhs.id() << " g" << (++count) << "("
190191
<< symbol_string(lhs) << tmp
191192
<< ");" << '\n' << '\n';
@@ -195,23 +196,23 @@ void output_verilog_netlistt::assign_symbol(
195196
rhs.id()==ID_mult)
196197
{
197198
if(rhs.operands().size()==1)
198-
assign_symbol(lhs, rhs.op0());
199+
assign_symbol(lhs, to_multi_ary_expr(rhs).op0());
199200
else
200201
{
201202
std::string tmp;
202203

203204
assert(rhs.operands().size()!=0);
204205

205206
if(rhs.operands().size()==2)
206-
tmp=make_symbol_expr(rhs.op0(), "")+", "+
207-
make_symbol_expr(rhs.op1(), "");
207+
tmp = make_symbol_expr(to_multi_ary_expr(rhs).op0(), "") + ", " +
208+
make_symbol_expr(to_multi_ary_expr(rhs).op1(), "");
208209
else
209210
{
210211
exprt tmp_rhs(rhs);
211212
tmp_rhs.operands().erase(tmp_rhs.operands().begin());
212-
213-
tmp=make_symbol_expr(rhs.op0(), "")+", "+
214-
make_symbol_expr(tmp_rhs, "");
213+
214+
tmp = make_symbol_expr(to_multi_ary_expr(rhs).op0(), "") + ", " +
215+
make_symbol_expr(tmp_rhs, "");
215216
}
216217

217218
out << " RTL_";
@@ -275,19 +276,18 @@ void output_verilog_rtlt::assign_symbol(
275276
{
276277
if(lhs.id()==ID_extractbits)
277278
{
278-
assert(lhs.operands().size()==3);
279+
auto &lhs_extractbits = to_extractbits_expr(lhs);
279280

280281
// redundant?
281282
mp_integer from, to;
282283

283284
if(
284-
!to_integer_non_constant(lhs.op1(), to) &&
285-
!to_integer_non_constant(lhs.op2(), from))
285+
!to_integer_non_constant(lhs_extractbits.upper(), to) &&
286+
!to_integer_non_constant(lhs_extractbits.lower(), from))
286287
{
287-
if(from==0 &&
288-
to==width(lhs.op0().type())-1)
288+
if(from == 0 && to == width(lhs_extractbits.src().type()) - 1)
289289
{
290-
assign_symbol(lhs.op0(), rhs);
290+
assign_symbol(lhs_extractbits.src(), rhs);
291291
return;
292292
}
293293
}
@@ -307,7 +307,7 @@ void output_verilog_rtlt::assign_symbol(
307307
throw 0;
308308
}
309309

310-
symbol_expr=lhs.op0();
310+
symbol_expr = to_extractbit_expr(lhs).src();
311311
}
312312
else if(lhs.id()==ID_extractbits)
313313
{
@@ -318,7 +318,7 @@ void output_verilog_rtlt::assign_symbol(
318318
throw 0;
319319
}
320320

321-
symbol_expr=lhs.op0();
321+
symbol_expr = to_extractbits_expr(lhs).src();
322322
}
323323

324324
if(symbol_expr.id()!=ID_symbol &&
@@ -342,8 +342,10 @@ void output_verilog_rtlt::assign_symbol(
342342

343343
// replace the next_symbol
344344
exprt tmp(lhs);
345-
if(tmp.id()==ID_extractbit || tmp.id()==ID_extractbits)
346-
tmp.op0().id(ID_symbol);
345+
if(tmp.id() == ID_extractbit)
346+
to_extractbit_expr(tmp).src().id(ID_symbol);
347+
else if(tmp.id() == ID_extractbits)
348+
to_extractbits_expr(tmp).src().id(ID_symbol);
347349
else
348350
tmp.id(ID_symbol);
349351

@@ -406,62 +408,58 @@ std::string output_verilog_netlistt::symbol_string(const exprt &expr)
406408

407409
if(expr.id()==ID_extractbit)
408410
{
409-
assert(expr.operands().size()==2);
411+
auto &src = to_extractbit_expr(expr).src();
412+
auto &index = to_extractbit_expr(expr).index();
410413

411414
mp_integer i;
412-
if(to_integer_non_constant(expr.op1(), i))
415+
if(to_integer_non_constant(index, i))
413416
{
414-
error().source_location=expr.op1().find_source_location();
415-
error() << "failed to convert constant "
416-
<< expr.op1().pretty() << eom;
417+
error().source_location = index.find_source_location();
418+
error() << "failed to convert constant " << index.pretty() << eom;
417419
throw 0;
418420
}
419421

420-
std::size_t offset=atoi(expr.op0().type().get("#offset").c_str());
421-
422+
std::size_t offset = atoi(src.type().get("#offset").c_str());
423+
422424
assert(i>=offset);
423-
424-
return
425-
symbol_string(expr.op0())+
426-
'['+integer2string(i-offset)+']';
425+
426+
return symbol_string(src) + '[' + integer2string(i - offset) + ']';
427427
}
428428
else if(expr.id()==ID_extractbits)
429429
{
430-
assert(expr.operands().size()==3);
430+
auto &src = to_extractbits_expr(expr).src();
431+
auto &upper = to_extractbits_expr(expr).upper();
432+
auto &lower = to_extractbits_expr(expr).lower();
431433

432434
mp_integer from;
433-
if(to_integer_non_constant(expr.op1(), from))
435+
if(to_integer_non_constant(upper, from))
434436
{
435-
error().source_location=expr.op1().find_source_location();
436-
error() << "failed to convert constant "
437-
<< expr.op1().pretty() << eom;
437+
error().source_location = upper.find_source_location();
438+
error() << "failed to convert constant " << upper.pretty() << eom;
438439
throw 0;
439440
}
440441

441442
mp_integer to;
442-
if(to_integer_non_constant(expr.operands()[2], to))
443+
if(to_integer_non_constant(lower, to))
443444
{
444-
error().source_location=expr.operands()[2].find_source_location();
445-
error() << "failed to convert constant "
446-
<< expr.operands()[2].pretty() << eom;
445+
error().source_location = lower.find_source_location();
446+
error() << "failed to convert constant " << lower.pretty() << eom;
447447
throw 0;
448448
}
449449

450-
std::size_t offset=atoi(expr.op0().type().get("#offset").c_str());
451-
450+
std::size_t offset = atoi(src.type().get("#offset").c_str());
451+
452452
assert(from>=offset);
453453
assert(to>=offset);
454454

455455
assert(to>=from);
456-
457-
return
458-
symbol_string(expr.op0())+
459-
'['+integer2string(to-offset)+
460-
':'+integer2string(from-offset)+']';
456+
457+
return symbol_string(src) + '[' + integer2string(to - offset) + ':' +
458+
integer2string(from - offset) + ']';
461459
}
462460
else if(expr.id()==ID_symbol)
463461
{
464-
const irep_idt &identifier=expr.get(ID_identifier);
462+
const irep_idt &identifier = to_symbol_expr(expr).get_identifier();
465463
symbol_tablet::symbolst::const_iterator s_it=
466464
symbol_table.symbols.find(identifier);
467465

@@ -885,8 +883,8 @@ void output_verilog_baset::invariant(const exprt &expr)
885883
}
886884
else if(expr.id()==ID_equal)
887885
{
888-
assert(expr.operands().size()==2);
889-
assign_symbol(expr.op0(), expr.op1());
886+
auto &equal_expr = to_equal_expr(expr);
887+
assign_symbol(equal_expr.lhs(), equal_expr.rhs());
890888
}
891889
else
892890
{
@@ -941,9 +939,9 @@ void output_verilog_baset::next_state(const exprt &expr)
941939
return;
942940

943941
assert(expr.id()==ID_equal);
944-
assert(expr.operands().size()==2);
945942

946-
assign_symbol(expr.op0(), expr.op1());
943+
auto &equal_expr = to_equal_expr(expr);
944+
assign_symbol(equal_expr.lhs(), equal_expr.rhs());
947945
}
948946

949947
/*******************************************************************\

src/hw-cbmc/next_timeframe.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,11 @@ void add_next_timeframe(
7474

7575
if(top_level_inputs.find(name)!=top_level_inputs.end()) continue;
7676

77-
const exprt member_expr1 = member_exprt(struct_symbol_expr, name, type);
78-
const exprt member_expr2=member_exprt(index_expr, name, type);
77+
const auto member_expr1 = member_exprt(struct_symbol_expr, name, type);
78+
const auto member_expr2 = member_exprt(index_expr, name, type);
7979

80-
CHECK_RETURN(member_expr1.op0().type() == member_expr2.op0().type());
80+
CHECK_RETURN(
81+
member_expr1.compound().type() == member_expr2.compound().type());
8182
const code_assignt member_assignment(member_expr1, member_expr2);
8283
block.add(member_assignment);
8384
}

src/ic3/r1ead_input.cc

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,9 @@ void ic3_enginet::find_prop_lit()
3636
bool found = find_prop(Prop);
3737

3838
assert(found);
39-
assert(Prop.expr.id()==ID_sva_always);
39+
assert(Prop.expr.id() == ID_sva_always);
4040

41-
assert(Prop.expr.operands().size()==1);
42-
43-
exprt Oper = Prop.expr.op0();
41+
exprt Oper = to_unary_expr(Prop.expr).op();
4442

4543
found = banned_expr(Oper);
4644
if (found) {

0 commit comments

Comments
 (0)