@@ -371,6 +371,19 @@ class code_declt:public codet
371
371
{
372
372
return symbol ().get_identifier ();
373
373
}
374
+
375
+ static void check (
376
+ const codet &code,
377
+ const validation_modet vm = validation_modet::INVARIANT)
378
+ {
379
+ DATA_CHECK (
380
+ vm, code.operands ().size () == 1 , " declaration must have one operand" );
381
+ DATA_CHECK (
382
+ vm,
383
+ code.op0 ().id () == ID_symbol,
384
+ " declaring a non-symbol: " +
385
+ id2string (to_symbol_expr (code.op0 ()).get_identifier ()));
386
+ }
374
387
};
375
388
376
389
template <> inline bool can_cast_expr<code_declt>(const exprt &base)
@@ -430,6 +443,21 @@ class code_deadt:public codet
430
443
{
431
444
return symbol ().get_identifier ();
432
445
}
446
+
447
+ static void check (
448
+ const codet &code,
449
+ const validation_modet vm = validation_modet::INVARIANT)
450
+ {
451
+ DATA_CHECK (
452
+ vm,
453
+ code.operands ().size () == 1 ,
454
+ " removal (code_deadt) must have one operand" );
455
+ DATA_CHECK (
456
+ vm,
457
+ code.op0 ().id () == ID_symbol,
458
+ " removing a non-symbol: " +
459
+ id2string (to_symbol_expr (code.op0 ()).get_identifier ()) + " from scope" );
460
+ }
433
461
};
434
462
435
463
template <> inline bool can_cast_expr<code_deadt>(const exprt &base)
@@ -510,6 +538,11 @@ inline code_assumet &to_code_assume(codet &code)
510
538
return static_cast <code_assumet &>(code);
511
539
}
512
540
541
+ inline void validate_expr (const code_assumet &x)
542
+ {
543
+ validate_operands (x, 1 , " assume must have one operand" );
544
+ }
545
+
513
546
// / A non-fatal assertion, which checks a condition then permits execution to
514
547
// / continue.
515
548
class code_assertt :public codet
@@ -557,6 +590,11 @@ inline code_assertt &to_code_assert(codet &code)
557
590
return static_cast <code_assertt &>(code);
558
591
}
559
592
593
+ inline void validate_expr (const code_assertt &x)
594
+ {
595
+ validate_operands (x, 1 , " assert must have one operand" );
596
+ }
597
+
560
598
// / Create a fatal assertion, which checks a condition and then halts if it does
561
599
// / not hold. Equivalent to `ASSERT(condition); ASSUME(condition)`.
562
600
// /
@@ -1046,6 +1084,51 @@ class code_function_callt:public codet
1046
1084
{
1047
1085
return op2 ().operands ();
1048
1086
}
1087
+
1088
+ static void check (
1089
+ const codet &code,
1090
+ const validation_modet vm = validation_modet::INVARIANT)
1091
+ {
1092
+ DATA_CHECK (
1093
+ vm,
1094
+ code.operands ().size () == 3 ,
1095
+ " function calls must have three operands:\n 1) expression to store the "
1096
+ " returned values\n 2) the function being called\n 3) the vector of "
1097
+ " arguments" );
1098
+ }
1099
+
1100
+ static void validate (
1101
+ const codet &code,
1102
+ const namespacet &ns,
1103
+ const validation_modet vm = validation_modet::INVARIANT)
1104
+ {
1105
+ check (code, vm);
1106
+
1107
+ if (code.op0 ().id () == ID_nil)
1108
+ DATA_CHECK (
1109
+ vm,
1110
+ to_code_type (code.op1 ().type ()).return_type ().id () == ID_empty,
1111
+ " void function should not return value" );
1112
+ else
1113
+ DATA_CHECK (
1114
+ vm,
1115
+ base_type_eq (
1116
+ code.op0 ().type (), to_code_type (code.op1 ().type ()).return_type (), ns),
1117
+ " function returns expression of wrong type" );
1118
+ }
1119
+
1120
+ static void validate_full (
1121
+ const codet &code,
1122
+ const namespacet &ns,
1123
+ const validation_modet vm = validation_modet::INVARIANT)
1124
+ {
1125
+ for (const exprt &op : code.operands ())
1126
+ {
1127
+ validate_full_expr (op, ns, vm);
1128
+ }
1129
+
1130
+ validate (code, ns, vm);
1131
+ }
1049
1132
};
1050
1133
1051
1134
template <> inline bool can_cast_expr<code_function_callt>(const exprt &base)
@@ -1068,6 +1151,11 @@ inline code_function_callt &to_code_function_call(codet &code)
1068
1151
return static_cast <code_function_callt &>(code);
1069
1152
}
1070
1153
1154
+ inline void validate_expr (const code_function_callt &x)
1155
+ {
1156
+ validate_operands (x, 3 , " function calls must have three operands" );
1157
+ }
1158
+
1071
1159
// / \ref codet representation of a "return from a function" statement.
1072
1160
class code_returnt :public codet
1073
1161
{
@@ -1099,6 +1187,13 @@ class code_returnt:public codet
1099
1187
return false ; // backwards compatibility
1100
1188
return return_value ().is_not_nil ();
1101
1189
}
1190
+
1191
+ static void check (
1192
+ const codet &code,
1193
+ const validation_modet vm = validation_modet::INVARIANT)
1194
+ {
1195
+ DATA_CHECK (vm, code.operands ().size () == 1 , " return must have one operand" );
1196
+ }
1102
1197
};
1103
1198
1104
1199
template <> inline bool can_cast_expr<code_returnt>(const exprt &base)
@@ -1121,6 +1216,11 @@ inline code_returnt &to_code_return(codet &code)
1121
1216
return static_cast <code_returnt &>(code);
1122
1217
}
1123
1218
1219
+ inline void validate_expr (const code_returnt &x)
1220
+ {
1221
+ validate_operands (x, 1 , " return must have one operand" );
1222
+ }
1223
+
1124
1224
// / \ref codet representation of a label for branch targets.
1125
1225
class code_labelt :public codet
1126
1226
{
0 commit comments