CBMC
statement_list_typecheck.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Statement List Language Type Checking
4 
5 Author: Matthias Weiss, matthias.weiss@diffblue.com
6 
7 \*******************************************************************/
8 
11 
14 
16 
17 #include <util/cprover_prefix.h>
18 #include <util/message.h>
19 #include <util/namespace.h>
20 #include <util/pointer_expr.h>
21 #include <util/simplify_expr.h>
22 #include <util/std_code.h>
23 #include <util/symbol_table.h>
24 
26 #define STATEMENT_LIST_PTR_WIDTH 64
27 // TODO: Replace with more specific exception throws.
28 #define TYPECHECK_ERROR 0
29 #define DATA_BLOCK_PARAMETER_NAME "data_block"
31 #define DATA_BLOCK_TYPE_POSTFIX "_db"
33 #define CPROVER_ASSERT CPROVER_PREFIX "assert"
35 #define CPROVER_ASSUME CPROVER_PREFIX "assume"
37 #define CPROVER_TEMP_RLO CPROVER_PREFIX "temp_rlo"
39 
40 static const std::vector<irep_idt> logic_sequence_initializers = {
41  ID_statement_list_and,
42  ID_statement_list_and_not,
43  ID_statement_list_or,
44  ID_statement_list_or_not,
45  ID_statement_list_xor,
46  ID_statement_list_xor_not,
47  ID_statement_list_and_nested,
48  ID_statement_list_and_not_nested,
49  ID_statement_list_or_nested,
50  ID_statement_list_or_not_nested,
51  ID_statement_list_xor_nested,
52  ID_statement_list_xor_not_nested,
53 };
54 
55 static const std::vector<irep_idt> logic_sequence_terminators = {
56  ID_statement_list_set_rlo,
57  ID_statement_list_clr_rlo,
58  ID_statement_list_set,
59  ID_statement_list_reset,
60  ID_statement_list_assign,
61 };
62 
70  const struct_typet &data_block_type,
71  const irep_idt &function_block_name)
72 {
73  const pointer_typet db_ptr{data_block_type, STATEMENT_LIST_PTR_WIDTH};
74  code_typet::parametert param{db_ptr};
75  param.set_identifier(
76  id2string(function_block_name) + "::" + DATA_BLOCK_PARAMETER_NAME);
77  param.set_base_name(DATA_BLOCK_PARAMETER_NAME);
78  return param;
79 }
80 
82  const statement_list_parse_treet &parse_tree,
83  symbol_tablet &symbol_table,
84  const std::string &module,
85  message_handlert &message_handler)
86 {
87  statement_list_typecheckt stl_typecheck(
88  parse_tree, symbol_table, module, message_handler);
89 
90  return stl_typecheck.typecheck_main();
91 }
92 
94  exprt rlo_bit,
95  bool or_bit,
96  codet function_code)
97  : rlo_bit(rlo_bit), or_bit(or_bit), function_code(function_code)
98 {
99 }
100 
102  size_t nesting_depth,
103  bool jumps_permitted,
104  bool fc_false_required)
105  : nesting_depth(nesting_depth),
106  jumps_permitted(jumps_permitted),
107  fc_false_required(fc_false_required)
108 {
109 }
111  size_t nesting_depth,
112  bool sets_fc_false)
113  : nesting_depth(nesting_depth), sets_fc_false(sets_fc_false)
114 {
115 }
116 
120  const std::string &module,
125  module(module)
126 {
127 }
128 
130 {
131  // First fill the symbol table with function, tag and parameter declarations
132  // to be able to properly resolve block calls later.
139  // Temporary RLO symbol for certain operations.
140  add_temp_rlo();
141 
142  // Iterate through all networks to generate the function bodies.
145  {
148  }
150  {
151  symbolt &function_sym{symbol_table.get_writeable_ref(fc.name)};
152  typecheck_statement_list_networks(fc, function_sym);
153  }
154 }
155 
157  const statement_list_parse_treet::function_blockt &function_block)
158 {
159  // Create FB symbol.
160  symbolt function_block_sym;
161  function_block_sym.module = module;
162  function_block_sym.name = function_block.name;
163  function_block_sym.base_name = function_block_sym.name;
164  function_block_sym.pretty_name = function_block_sym.name;
165  function_block_sym.mode = ID_statement_list;
166 
167  // When calling function blocks, the passed parameters are value-copied to a
168  // corresponding instance data block. This block contains all input, inout,
169  // output and static variables. The function block reads and writes only
170  // those fields and does not modify the actual parameters. To simulate this
171  // behaviour, all function blocks are modeled as functions with a single
172  // parameter: An instance of their data block, whose members they modify.
173 
174  // Create and add DB type symbol.
175  const struct_typet data_block_type{
176  create_instance_data_block_type(function_block)};
177  type_symbolt data_block{data_block_type};
178  data_block.name =
179  id2string(function_block_sym.name) + DATA_BLOCK_TYPE_POSTFIX;
180  data_block.base_name = data_block.name;
181  data_block.mode = ID_statement_list;
182  symbol_table.add(data_block);
183 
184  // Create and add parameter symbol.
186  create_data_block_parameter(data_block_type, function_block_sym.name)};
187  parameter_symbolt param_sym;
188  param_sym.module = module;
189  param_sym.type = param.type();
190  param_sym.name = param.get_identifier();
192  param_sym.pretty_name = param_sym.base_name;
193  param_sym.mode = ID_statement_list;
194  symbol_table.add(param_sym);
195 
196  // Setup FB symbol type and value.
198  params.push_back(param);
199  code_typet fb_type{params, empty_typet()};
200  fb_type.set(ID_statement_list_type, ID_statement_list_function_block);
201  function_block_sym.type = fb_type;
202  symbol_table.add(function_block_sym);
203 }
204 
207 {
208  symbolt function_sym;
209  function_sym.module = module;
210  function_sym.name = function.name;
211  function_sym.base_name = function_sym.name;
212  function_sym.pretty_name = function_sym.name;
213  function_sym.mode = ID_statement_list;
216  function.var_input, params, function.name, ID_statement_list_var_input);
218  function.var_inout, params, function.name, ID_statement_list_var_inout);
220  function.var_output, params, function.name, ID_statement_list_var_output);
221 
222  code_typet fc_type{params, function.return_type};
223  fc_type.set(ID_statement_list_type, ID_statement_list_function);
224  function_sym.type = fc_type;
225  symbol_table.add(function_sym);
226 }
227 
229 {
230  for(const symbol_exprt &tag : parse_tree.tags)
231  {
232  symbolt tag_sym;
233  tag_sym.is_static_lifetime = true;
234  tag_sym.module = module;
235  tag_sym.name = tag.get_identifier();
236  tag_sym.base_name = tag_sym.name;
237  tag_sym.pretty_name = tag_sym.name;
238  tag_sym.type = tag.type();
239  tag_sym.mode = ID_statement_list;
240  symbol_table.add(tag_sym);
241  }
242 }
243 
245 {
246  symbolt temp_rlo;
247  temp_rlo.is_static_lifetime = true;
248  temp_rlo.module = module;
249  temp_rlo.name = CPROVER_TEMP_RLO;
250  temp_rlo.base_name = temp_rlo.name;
251  temp_rlo.pretty_name = temp_rlo.name;
252  temp_rlo.type = get_bool_type();
253  temp_rlo.mode = ID_statement_list;
254  symbol_table.add(temp_rlo);
255 }
256 
258  const statement_list_parse_treet::function_blockt &function_block)
259 {
262  function_block.var_input, components, ID_statement_list_var_input);
264  function_block.var_inout, components, ID_statement_list_var_inout);
266  function_block.var_output, components, ID_statement_list_var_output);
268  function_block.var_static, components, ID_statement_list_var_static);
269 
270  return struct_typet{components};
271 }
272 
276  const irep_idt &var_property)
277 {
278  for(const statement_list_parse_treet::var_declarationt &declaration :
279  var_decls)
280  {
281  const irep_idt &var_name{declaration.variable.get_identifier()};
282  const typet &var_type{declaration.variable.type()};
283  struct_union_typet::componentt component{var_name, var_type};
284  component.set(ID_statement_list_type, var_property);
285  components.push_back(component);
286  }
287 }
288 
291  code_typet::parameterst &params,
292  const irep_idt &function_name,
293  const irep_idt &var_property)
294 {
295  for(const statement_list_parse_treet::var_declarationt &declaration :
296  var_decls)
297  {
298  parameter_symbolt param_sym;
299  param_sym.module = module;
300  param_sym.type = declaration.variable.type();
301  param_sym.name = id2string(function_name) +
302  "::" + id2string(declaration.variable.get_identifier());
303  param_sym.base_name = declaration.variable.get_identifier();
304  param_sym.pretty_name = param_sym.base_name;
305  param_sym.mode = ID_statement_list;
306  symbol_table.add(param_sym);
307 
308  code_typet::parametert param{declaration.variable.type()};
309  param.set_identifier(param_sym.name);
310  param.set_base_name(declaration.variable.get_identifier());
311  param.set(ID_statement_list_type, var_property);
312  params.push_back(param);
313  }
314 }
315 
317  const statement_list_parse_treet::tia_modulet &tia_module,
318  symbolt &tia_symbol)
319 {
320  for(const statement_list_parse_treet::var_declarationt &declaration :
321  tia_module.var_temp)
322  {
323  symbolt temp_sym;
324  temp_sym.name = id2string(tia_symbol.name) +
325  "::" + id2string(declaration.variable.get_identifier());
326  temp_sym.base_name = declaration.variable.get_identifier();
327  temp_sym.pretty_name = temp_sym.base_name;
328  temp_sym.type = declaration.variable.type();
329  temp_sym.mode = ID_statement_list;
330  temp_sym.module = module;
331  symbol_table.add(temp_sym);
332 
333  const code_declt code_decl{temp_sym.symbol_expr()};
334  tia_symbol.value.add_to_operands(code_decl);
335  }
336 }
337 
339  const statement_list_parse_treet::tia_modulet &tia_module,
340  symbolt &tia_symbol)
341 {
342  // Leave value empty if there are no networks to iterate through.
343  if(tia_module.networks.empty())
344  return;
345  if(tia_symbol.value.is_nil())
346  tia_symbol.value = code_blockt{};
347 
349  typecheck_temp_var_decls(tia_module, tia_symbol);
350 
351  for(const auto &network : tia_module.networks)
352  {
354  for(const auto &instruction : network.instructions)
355  typecheck_statement_list_instruction(instruction, tia_symbol);
356  }
358 }
359 
361 {
362  if(!label_references.empty())
363  {
364  error() << "Unable to find the labels:";
365  for(auto pair : label_references)
366  {
367  error() << "\n";
368  error() << id2string(pair.first);
369  }
370  error() << eom;
371  throw TYPECHECK_ERROR;
372  }
373 }
374 
376  const statement_list_parse_treet::instructiont &instruction,
377  symbolt &tia_element)
378 {
379  const codet &op_code{instruction.tokens.back()};
380  typecheck_code(op_code, tia_element);
381 }
382 
384  const codet &instruction,
385  symbolt &tia_element)
386 {
387  const irep_idt statement{instruction.get_statement()};
388 
389  if(ID_label == statement)
390  typecheck_label(instruction, tia_element);
391  else if(ID_statement_list_load == statement)
392  typecheck_statement_list_load(instruction, tia_element);
393  else if(ID_statement_list_transfer == statement)
394  typecheck_statement_list_transfer(instruction, tia_element);
395  else if(ID_statement_list_accu_int_add == statement)
397  else if(ID_statement_list_accu_int_sub == statement)
399  else if(ID_statement_list_accu_int_mul == statement)
401  else if(ID_statement_list_accu_int_div == statement)
403  else if(ID_statement_list_accu_int_eq == statement)
405  else if(ID_statement_list_accu_int_neq == statement)
407  else if(ID_statement_list_accu_int_lt == statement)
409  else if(ID_statement_list_accu_int_gt == statement)
411  else if(ID_statement_list_accu_int_lte == statement)
413  else if(ID_statement_list_accu_int_gte == statement)
415  else if(ID_statement_list_accu_dint_add == statement)
417  else if(ID_statement_list_accu_dint_sub == statement)
419  else if(ID_statement_list_accu_dint_mul == statement)
421  else if(ID_statement_list_accu_dint_div == statement)
423  else if(ID_statement_list_accu_dint_eq == statement)
425  else if(ID_statement_list_accu_dint_neq == statement)
427  else if(ID_statement_list_accu_dint_lt == statement)
429  else if(ID_statement_list_accu_dint_gt == statement)
431  else if(ID_statement_list_accu_dint_lte == statement)
433  else if(ID_statement_list_accu_dint_gte == statement)
435  else if(ID_statement_list_accu_real_add == statement)
437  else if(ID_statement_list_accu_real_sub == statement)
439  else if(ID_statement_list_accu_real_mul == statement)
441  else if(ID_statement_list_accu_real_div == statement)
443  else if(ID_statement_list_accu_real_eq == statement)
445  else if(ID_statement_list_accu_real_neq == statement)
447  else if(ID_statement_list_accu_real_lt == statement)
449  else if(ID_statement_list_accu_real_gt == statement)
451  else if(ID_statement_list_accu_real_lte == statement)
453  else if(ID_statement_list_accu_real_gte == statement)
455  else if(ID_statement_list_not == statement)
456  typecheck_statement_list_not(instruction);
457  else if(ID_statement_list_and == statement)
458  typecheck_statement_list_and(instruction, tia_element);
459  else if(ID_statement_list_and_not == statement)
460  typecheck_statement_list_and_not(instruction, tia_element);
461  else if(ID_statement_list_or == statement)
462  typecheck_statement_list_or(instruction, tia_element);
463  else if(ID_statement_list_or_not == statement)
464  typecheck_statement_list_or_not(instruction, tia_element);
465  else if(ID_statement_list_xor == statement)
466  typecheck_statement_list_xor(instruction, tia_element);
467  else if(ID_statement_list_xor_not == statement)
468  typecheck_statement_list_xor_not(instruction, tia_element);
469  else if(ID_statement_list_and_nested == statement)
471  else if(ID_statement_list_and_not_nested == statement)
473  else if(ID_statement_list_or_nested == statement)
475  else if(ID_statement_list_or_not_nested == statement)
477  else if(ID_statement_list_xor_nested == statement)
479  else if(ID_statement_list_xor_not_nested == statement)
481  else if(ID_statement_list_nesting_closed == statement)
483  else if(ID_statement_list_assign == statement)
484  typecheck_statement_list_assign(instruction, tia_element);
485  else if(ID_statement_list_set_rlo == statement)
487  else if(ID_statement_list_clr_rlo == statement)
489  else if(ID_statement_list_set == statement)
490  typecheck_statement_list_set(instruction, tia_element);
491  else if(ID_statement_list_reset == statement)
492  typecheck_statement_list_reset(instruction, tia_element);
493  else if(ID_statement_list_jump_unconditional == statement)
494  typecheck_statement_list_jump_unconditional(instruction, tia_element);
495  else if(ID_statement_list_jump_conditional == statement)
496  typecheck_statement_list_jump_conditional(instruction, tia_element);
497  else if(ID_statement_list_jump_conditional_not == statement)
498  typecheck_statement_list_jump_conditional_not(instruction, tia_element);
499  else if(ID_statement_list_nop == statement)
500  return;
501  else if(ID_statement_list_call == statement)
502  typecheck_statement_list_call(instruction, tia_element);
503  else
504  {
505  error() << "OP code of instruction not found: "
506  << instruction.get_statement() << eom;
507  throw TYPECHECK_ERROR;
508  }
509 }
510 
512  const codet &instruction,
513  symbolt &tia_element)
514 {
515  const code_labelt &label = to_code_label(instruction);
516 
517  // Check if label is duplicate (not allowed in STL).
518  if(stl_labels.find(label.get_label()) != end(stl_labels))
519  {
520  error() << "Multiple definitions of label " << id2string(label.get_label())
521  << eom;
522  throw TYPECHECK_ERROR;
523  }
524 
525  // Determine the properties of this location in the code.
527 
528  // Store the implicit RLO in order to correctly separate the different
529  // blocks of logic.
530  if(location.jumps_permitted)
531  save_rlo_state(tia_element);
532 
533  // Now check if there are any jumps that referenced that label before and
534  // validate these.
535  typecheck_jump_locations(label, location);
536 
537  // Only add the label to the code if jumps are permitted. Proceed as normal
538  // if they are not. An added label will always point at an empty code
539  // location due to the way how the typecheck works.
540  if(location.jumps_permitted)
541  tia_element.value.add_to_operands(
542  code_labelt{label.get_label(), code_skipt{}});
543 
544  // Recursive call to check the label target.
545  typecheck_code(label.code(), tia_element);
546 }
547 
550 {
551  // Jumps to a label are only allowed if one of the following conditions
552  // applies:
553  //
554  // a) The /FC bit is false when encountering the instruction (pointing at the
555  // beginning of a logic sequence or no sequence at all).
556  // b) The /FC bit is set to false after processing the instruction (pointing
557  // at the termination of a logic sequence). This excludes nesting-open
558  // operations since although they terminate the current sequence, it will
559  // be resumed later.
560  //
561  // Labels at locations where this does not hold true compile, but actual
562  // jumps to them do not.
563  //
564  // Additionally, jumps to instructions that mark the beginning of a logic
565  // sequence are only allowed if the jump instruction itself sets the /FC bit
566  // to false.
567 
568  bool jumps_permitted = false;
569  bool fc_false_required = false;
570  if(!fc_bit)
571  {
572  jumps_permitted = true;
573  // Check if label points to new logic sequence.
574  for(const irep_idt &op_code : logic_sequence_initializers)
575  if(op_code == label.code().get_statement())
576  {
577  fc_false_required = true;
578  break;
579  }
580  }
581  else // Check if the label's instruction terminates the logic sequence.
582  {
583  for(const irep_idt &op_code : logic_sequence_terminators)
584  if(op_code == label.code().get_statement())
585  {
586  jumps_permitted = true;
587  break;
588  }
589  }
590 
591  // Add the label to map.
592  stl_label_locationt location{
593  nesting_stack.size(), jumps_permitted, fc_false_required};
594  stl_labels.emplace(label.get_label(), location);
595  return location;
596 }
597 
599  const code_labelt &label,
601 {
602  // Now check if there are any jumps that referenced that label before and
603  // validate these.
604  auto reference_it = label_references.find(label.get_label());
605  if(reference_it != end(label_references))
606  {
607  if(!location.jumps_permitted)
608  {
609  error() << "Not allowed to jump to label " << id2string(label.get_label())
610  << eom;
611  throw TYPECHECK_ERROR;
612  }
613  for(auto jump_location_it = begin(reference_it->second);
614  jump_location_it != end(reference_it->second);
615  ++jump_location_it)
616  {
617  if(location.fc_false_required && !jump_location_it->sets_fc_false)
618  {
619  error() << "Jump to label " << id2string(label.get_label())
620  << " can not be unconditional" << eom;
621  throw TYPECHECK_ERROR;
622  }
623  if(nesting_stack.size() != jump_location_it->nesting_depth)
624  {
625  error() << "Jump to label " << id2string(label.get_label())
626  << " violates brace scope" << eom;
627  throw TYPECHECK_ERROR;
628  }
629  }
630  // Remove entry after validation.
631  label_references.erase(label.get_label());
632  }
633 }
634 
636  const codet &op_code,
637  const symbolt &tia_element)
638 {
639  const symbol_exprt *const symbol =
640  expr_try_dynamic_cast<symbol_exprt>(op_code.op0());
641  if(symbol)
642  {
643  const irep_idt &identifier{symbol->get_identifier()};
644  const exprt val{typecheck_identifier(tia_element, identifier)};
645  accumulator.push_back(val);
646  }
647  else if(can_cast_expr<constant_exprt>(op_code.op0()))
648  accumulator.push_back(op_code.op0());
649  else
650  {
651  error() << "Instruction is not followed by symbol or constant" << eom;
652  throw TYPECHECK_ERROR;
653  }
654 }
655 
657  const codet &op_code,
658  symbolt &tia_element)
659 {
661  const exprt lhs{typecheck_identifier(tia_element, op.get_identifier())};
662  if(lhs.type() != accumulator.back().type())
663  {
664  error() << "Types of transfer assignment do not match" << eom;
665  throw TYPECHECK_ERROR;
666  }
667  const code_assignt assignment{lhs, accumulator.back()};
668  tia_element.value.add_to_operands(assignment);
669 }
670 
672  const codet &op_code)
673 {
675 
676  // Pop first operand, peek second.
677  const exprt accu1{accumulator.back()};
678  accumulator.pop_back();
679  const exprt &accu2{accumulator.back()};
680  const plus_exprt operation{accu2, accu1};
681  accumulator.push_back(operation);
682 }
683 
685  const codet &op_code)
686 {
688 
689  // Pop first operand, peek second.
690  const exprt accu1{accumulator.back()};
691  accumulator.pop_back();
692  const exprt &accu2{accumulator.back()};
693  const minus_exprt operation{accu2, accu1};
694  accumulator.push_back(operation);
695 }
696 
698  const codet &op_code)
699 {
701 
702  // Pop first operand, peek second.
703  const exprt accu1{accumulator.back()};
704  accumulator.pop_back();
705  const exprt &accu2{accumulator.back()};
706  const mult_exprt operation{accu2, accu1};
707  accumulator.push_back(operation);
708 }
709 
711  const codet &op_code)
712 {
714 
715  // Pop first operand, peek second.
716  const exprt accu1{accumulator.back()};
717  accumulator.pop_back();
718  const exprt &accu2{accumulator.back()};
719  const div_exprt operation{accu2, accu1};
720  accumulator.push_back(operation);
721 }
722 
724  const codet &op_code)
725 {
728 }
729 
731  const codet &op_code)
732 {
735 }
736 
738  const codet &op_code)
739 {
742 }
743 
745  const codet &op_code)
746 {
749 }
750 
752  const codet &op_code)
753 {
756 }
757 
759  const codet &op_code)
760 {
763 }
764 
766  const codet &op_code)
767 {
769 
770  // Pop first operand, peek second.
771  const exprt accu1{accumulator.back()};
772  accumulator.pop_back();
773  const exprt &accu2{accumulator.back()};
774  const plus_exprt operation{accu2, accu1};
775  accumulator.push_back(operation);
776 }
777 
779  const codet &op_code)
780 {
782 
783  // Pop first operand, peek second.
784  const exprt accu1{accumulator.back()};
785  accumulator.pop_back();
786  const exprt &accu2{accumulator.back()};
787  const minus_exprt operation{accu2, accu1};
788  accumulator.push_back(operation);
789 }
790 
792  const codet &op_code)
793 {
795 
796  // Pop first operand, peek second.
797  const exprt accu1{accumulator.back()};
798  accumulator.pop_back();
799  const exprt &accu2{accumulator.back()};
800  const mult_exprt operation{accu2, accu1};
801  accumulator.push_back(operation);
802 }
803 
805  const codet &op_code)
806 {
808 
809  // Pop first operand, peek second.
810  const exprt accu1{accumulator.back()};
811  accumulator.pop_back();
812  const exprt &accu2{accumulator.back()};
813  const div_exprt operation{accu2, accu1};
814  accumulator.push_back(operation);
815 }
816 
818  const codet &op_code)
819 {
822 }
823 
825  const codet &op_code)
826 {
829 }
830 
832  const codet &op_code)
833 {
836 }
837 
839  const codet &op_code)
840 {
843 }
844 
846  const codet &op_code)
847 {
850 }
851 
853  const codet &op_code)
854 {
857 }
858 
860  const codet &op_code)
861 {
863 
864  // Pop first operand, peek second.
865  const exprt accu1{accumulator.back()};
866  accumulator.pop_back();
867  const exprt &accu2{accumulator.back()};
868  const plus_exprt operation{accu2, accu1};
869  accumulator.push_back(operation);
870 }
871 
873  const codet &op_code)
874 {
876 
877  // Pop first operand, peek second.
878  const exprt accu1{accumulator.back()};
879  accumulator.pop_back();
880  const exprt &accu2{accumulator.back()};
881  const minus_exprt operation{accu2, accu1};
882  accumulator.push_back(operation);
883 }
884 
886  const codet &op_code)
887 {
889 
890  // Pop first operand, peek second.
891  const exprt accu1{accumulator.back()};
892  accumulator.pop_back();
893  const exprt &accu2{accumulator.back()};
894  const mult_exprt operation{accu2, accu1};
895  accumulator.push_back(operation);
896 }
897 
899  const codet &op_code)
900 {
902 
903  // Pop first operand, peek second.
904  const exprt accu1{accumulator.back()};
905  accumulator.pop_back();
906  const exprt &accu2{accumulator.back()};
907  const div_exprt operation{accu2, accu1};
908  accumulator.push_back(operation);
909 }
910 
912  const codet &op_code)
913 {
916 }
917 
919  const codet &op_code)
920 {
923 }
924 
926  const codet &op_code)
927 {
930 }
931 
933  const codet &op_code)
934 {
937 }
938 
940  const codet &op_code)
941 {
944 }
945 
947  const codet &op_code)
948 {
951 }
952 
954  const codet &op_code)
955 {
957  const not_exprt unsimplified{rlo_bit};
958  rlo_bit = simplify_expr(unsimplified, namespacet(symbol_table));
959 }
960 
962  const codet &op_code,
963  const symbolt &tia_element)
964 {
965  exprt op{
966  typecheck_simple_boolean_instruction_operand(op_code, tia_element, false)};
967 
968  // If inside of a bit string and if the OR bit is not set, create an 'and'
969  // expression with the operand and the current contents of the rlo bit. If
970  // the OR bit is set then this instruction is part of an 'and-before-or'
971  // block and needs to be added to the rlo in a special way.
972  if(fc_bit && or_bit)
974  else if(fc_bit)
975  {
976  const and_exprt unsimplified{rlo_bit, op};
977  rlo_bit = simplify_expr(unsimplified, namespacet(symbol_table));
978  }
979  else
981 }
982 
984  const codet &op_code,
985  const symbolt &tia_element)
986 {
987  exprt op{
988  typecheck_simple_boolean_instruction_operand(op_code, tia_element, true)};
989 
990  // If inside of a bit string and if the OR bit is not set, create an 'and'
991  // expression with the operand and the current contents of the rlo bit. If
992  // the OR bit is set then this instruction is part of an 'and-before-or'
993  // block and needs to be added to the rlo in a special way.
994  if(or_bit && fc_bit)
996  else if(fc_bit)
997  {
998  const and_exprt unsimplified{rlo_bit, op};
999  rlo_bit = simplify_expr(unsimplified, namespacet(symbol_table));
1000  }
1001  else
1003 }
1004 
1006  const codet &op_code,
1007  const symbolt &tia_element)
1008 {
1009  if(op_code.operands().empty())
1010  {
1012  return;
1013  }
1014  const symbol_exprt &sym{
1016  const exprt op{typecheck_identifier(tia_element, sym.get_identifier())};
1017 
1018  // If inside of a bit string, create an 'or' expression with the operand and
1019  // the current contents of the rlo bit.
1020  if(fc_bit)
1021  {
1022  const or_exprt unsimplified{rlo_bit, op};
1023  rlo_bit = simplify_expr(unsimplified, namespacet(symbol_table));
1024  or_bit = false;
1025  }
1026  else
1028 }
1029 
1031  const codet &op_code,
1032  const symbolt &tia_element)
1033 {
1034  const symbol_exprt &sym{
1036  const exprt op{typecheck_identifier(tia_element, sym.get_identifier())};
1037  const not_exprt not_op{op};
1038 
1039  // If inside of a bit string, create an 'or' expression with the operand and
1040  // the current contents of the rlo bit.
1041  if(fc_bit)
1042  {
1043  const or_exprt unsimplified{rlo_bit, not_op};
1044  rlo_bit = simplify_expr(unsimplified, namespacet(symbol_table));
1045  or_bit = false;
1046  }
1047  else
1048  initialize_bit_expression(not_op);
1049 }
1050 
1052  const codet &op_code,
1053  const symbolt &tia_element)
1054 {
1055  const symbol_exprt &sym{
1057  const exprt op{typecheck_identifier(tia_element, sym.get_identifier())};
1058 
1059  // If inside of a bit string, create an 'xor' expression with the operand and
1060  // the current contents of the rlo bit.
1061  if(fc_bit)
1062  {
1063  const xor_exprt unsimplified{rlo_bit, op};
1064  rlo_bit = simplify_expr(unsimplified, namespacet(symbol_table));
1065  or_bit = false;
1066  }
1067  else
1069 }
1070 
1072  const codet &op_code,
1073  const symbolt &tia_element)
1074 {
1075  const symbol_exprt &sym{
1077  const exprt op{typecheck_identifier(tia_element, sym.get_identifier())};
1078  const not_exprt not_op{op};
1079 
1080  // If inside of a bit string, create an 'xor not' expression with the
1081  // operand and the current contents of the rlo bit.
1082  if(fc_bit)
1083  {
1084  const xor_exprt unsimplified{rlo_bit, not_op};
1085  rlo_bit = simplify_expr(unsimplified, namespacet(symbol_table));
1086  or_bit = false;
1087  }
1088  else
1089  initialize_bit_expression(not_op);
1090 }
1091 
1093 {
1094  if(fc_bit)
1095  {
1097  or_bit = true;
1098  }
1099  else
1100  return; // Instruction has no semantic influence.
1101 }
1102 
1104  const codet &op_code)
1105 {
1106  // Set the rlo to true implicitly so that the value of the AND instruction
1107  // is being loaded in case of a new bit string.
1109 }
1110 
1112  const codet &op_code)
1113 {
1114  // Set the rlo to true implicitly so that the value of the AND instruction
1115  // is being loaded in case of a new bit string.
1117 }
1118 
1120  const codet &op_code)
1121 {
1122  // Set the rlo to false implicitly so that the value of the OR instruction
1123  // is being loaded in case of a new bit string.
1125 }
1126 
1128  const codet &op_code)
1129 {
1130  // Set the rlo to false implicitly so that the value of the OR instruction
1131  // is being loaded in case of a new bit string.
1133 }
1134 
1136  const codet &op_code)
1137 {
1138  // Set the rlo to false implicitly so that the value of the XOR instruction
1139  // is being loaded in case of a new bit string.
1141 }
1142 
1144  const codet &op_code)
1145 {
1146  // Set the rlo to false implicitly so that the value of the XOR instruction
1147  // is being loaded in case of a new bit string.
1149 }
1150 
1152  const codet &op_code)
1153 {
1155  if(nesting_stack.empty())
1156  {
1157  error() << "Wrong order of brackets (Right parenthesis is not preceded by "
1158  "nesting)"
1159  << eom;
1160  throw TYPECHECK_ERROR;
1161  }
1162  or_bit = nesting_stack.back().or_bit;
1163  fc_bit = true;
1164  const irep_idt &statement{nesting_stack.back().function_code.get_statement()};
1165  if(ID_statement_list_and_nested == statement)
1166  {
1167  if(or_bit)
1168  {
1169  const exprt op{rlo_bit};
1170  rlo_bit = nesting_stack.back().rlo_bit;
1172  }
1173  else
1174  rlo_bit = and_exprt{nesting_stack.back().rlo_bit, rlo_bit};
1175  }
1176  else if(ID_statement_list_and_not_nested == statement)
1177  {
1178  if(or_bit)
1179  {
1180  const not_exprt op{rlo_bit};
1181  rlo_bit = nesting_stack.back().rlo_bit;
1183  }
1184  else
1185  rlo_bit = and_exprt{nesting_stack.back().rlo_bit, not_exprt{rlo_bit}};
1186  }
1187  else if(ID_statement_list_or_nested == statement)
1188  {
1189  or_bit = false;
1190  rlo_bit = or_exprt{nesting_stack.back().rlo_bit, rlo_bit};
1191  }
1192  else if(ID_statement_list_or_not_nested == statement)
1193  {
1194  or_bit = false;
1195  rlo_bit = or_exprt{nesting_stack.back().rlo_bit, not_exprt{rlo_bit}};
1196  }
1197  else if(ID_statement_list_xor_nested == statement)
1198  {
1199  or_bit = false;
1200  rlo_bit = xor_exprt{nesting_stack.back().rlo_bit, rlo_bit};
1201  }
1202  else if(ID_statement_list_xor_not_nested == statement)
1203  {
1204  or_bit = false;
1205  rlo_bit = xor_exprt{nesting_stack.back().rlo_bit, not_exprt{rlo_bit}};
1206  }
1207  nesting_stack.pop_back();
1208 }
1209 
1211  const codet &op_code,
1212  symbolt &tia_element)
1213 {
1215  const exprt lhs{typecheck_identifier(tia_element, op.get_identifier())};
1216 
1217  if(lhs.type() != rlo_bit.type())
1218  {
1219  error() << "Types of assign do not match" << eom;
1220  throw TYPECHECK_ERROR;
1221  }
1222  const code_assignt assignment{lhs, rlo_bit};
1223  tia_element.value.add_to_operands(assignment);
1224  fc_bit = false;
1225  or_bit = false;
1226  // Set RLO to assigned operand in order to prevent false results if a symbol
1227  // that's implicitly part of the RLO was changed by the assignment.
1228  rlo_bit = lhs;
1229 }
1230 
1232  const codet &op_code)
1233 {
1235  fc_bit = false;
1236  or_bit = false;
1237  rlo_bit = true_exprt();
1238 }
1239 
1241  const codet &op_code)
1242 {
1244  fc_bit = false;
1245  or_bit = false;
1246  rlo_bit = false_exprt();
1247 }
1248 
1250  const codet &op_code,
1251  symbolt &tia_element)
1252 {
1254  const irep_idt &identifier{op.get_identifier()};
1255 
1256  save_rlo_state(tia_element);
1257 
1258  const exprt lhs{typecheck_identifier(tia_element, identifier)};
1259  const code_assignt assignment{lhs, true_exprt()};
1260  const code_ifthenelset ifthen{rlo_bit, assignment};
1261  tia_element.value.add_to_operands(ifthen);
1262  fc_bit = false;
1263  or_bit = false;
1264 }
1265 
1267  const codet &op_code,
1268  symbolt &tia_element)
1269 {
1271  const irep_idt &identifier{op.get_identifier()};
1272 
1273  save_rlo_state(tia_element);
1274 
1275  const exprt lhs{typecheck_identifier(tia_element, identifier)};
1276  const code_assignt assignment{lhs, false_exprt()};
1277  const code_ifthenelset ifthen{rlo_bit, assignment};
1278  tia_element.value.add_to_operands(ifthen);
1279  fc_bit = false;
1280  or_bit = false;
1281 }
1282 
1284  const codet &op_code,
1285  symbolt &tia_element)
1286 {
1288  const irep_idt &identifier{op.get_identifier()};
1289  if(symbol_table.has_symbol(identifier))
1290  typecheck_called_tia_element(op_code, tia_element);
1291  else if(identifier == CPROVER_ASSUME)
1292  typecheck_CPROVER_assume(op_code, tia_element);
1293  else if(identifier == CPROVER_ASSERT)
1294  typecheck_CPROVER_assert(op_code, tia_element);
1295  else
1296  {
1297  error() << "Called function could not be found" << eom;
1298  throw TYPECHECK_ERROR;
1299  }
1300  fc_bit = false;
1301  or_bit = false;
1302 }
1303 
1305  const codet &op_code,
1306  symbolt &tia_element)
1307 {
1308  const symbol_exprt &label{
1310  typecheck_label_reference(label.get_identifier(), false);
1311 
1312  save_rlo_state(tia_element);
1313  code_gotot unconditional{label.get_identifier()};
1314  tia_element.value.add_to_operands(unconditional);
1315 }
1316 
1318  const codet &op_code,
1319  symbolt &tia_element)
1320 {
1321  const symbol_exprt &label{
1323  typecheck_label_reference(label.get_identifier(), true);
1324 
1325  save_rlo_state(tia_element);
1326  code_gotot jump{label.get_identifier()};
1327  code_ifthenelset conditional{rlo_bit, jump};
1328  tia_element.value.add_to_operands(conditional);
1329 
1330  fc_bit = false;
1331  or_bit = false;
1332  rlo_bit = true_exprt{};
1333 }
1334 
1336  const codet &op_code,
1337  symbolt &tia_element)
1338 {
1339  const symbol_exprt &label{
1341  typecheck_label_reference(label.get_identifier(), true);
1342 
1343  save_rlo_state(tia_element);
1344  code_gotot jump{label.get_identifier()};
1345  code_ifthenelset not_conditional{not_exprt{rlo_bit}, jump};
1346  tia_element.value.add_to_operands(not_conditional);
1347 
1348  fc_bit = false;
1349  or_bit = false;
1350  rlo_bit = true_exprt{};
1351 }
1352 
1354  const codet &op_code)
1355 {
1357  const exprt &accu1{accumulator.back()};
1358  const exprt &accu2{accumulator.at(accumulator.size() - 2)};
1359 
1360  // Are both operands integers?
1361  const signedbv_typet *const accu_type1 =
1362  type_try_dynamic_cast<signedbv_typet>(accu1.type());
1363  const signedbv_typet *const accu_type2 =
1364  type_try_dynamic_cast<signedbv_typet>(accu2.type());
1365  if(
1366  !accu_type1 || !accu_type2 || accu_type1->get_width() != STL_INT_WIDTH ||
1367  accu_type2->get_width() != STL_INT_WIDTH)
1368  {
1369  error() << "Operands of integer addition are no integers" << eom;
1370  throw TYPECHECK_ERROR;
1371  }
1372 }
1373 
1375  const codet &op_code)
1376 {
1378  const exprt &accu1{accumulator.back()};
1379  const exprt &accu2{accumulator.at(accumulator.size() - 2)};
1380 
1381  // Are both operands double integers?
1382  const signedbv_typet *const accu_type1 =
1383  type_try_dynamic_cast<signedbv_typet>(accu1.type());
1384  const signedbv_typet *const accu_type2 =
1385  type_try_dynamic_cast<signedbv_typet>(accu2.type());
1386  if(
1387  !accu_type1 || !accu_type2 || accu_type1->get_width() != STL_DINT_WIDTH ||
1388  accu_type2->get_width() != STL_DINT_WIDTH)
1389  {
1390  error() << "Operands of double integer addition are no double integers"
1391  << eom;
1392  throw TYPECHECK_ERROR;
1393  }
1394 }
1395 
1397  const codet &op_code)
1398 {
1400  const exprt &accu1{accumulator.back()};
1401  const exprt &accu2{accumulator.at(accumulator.size() - 2)};
1402 
1403  // Are both operands real types?
1404  if(!(can_cast_type<floatbv_typet>(accu1.type()) &&
1405  can_cast_type<floatbv_typet>(accu2.type())))
1406  {
1407  error() << "Operands of Real addition do not have the type Real" << eom;
1408  throw TYPECHECK_ERROR;
1409  }
1410 }
1411 
1413  const irep_idt &comparison)
1414 {
1415  const exprt &accu1{accumulator.back()};
1416  const exprt &accu2{accumulator.at(accumulator.size() - 2)};
1417  // STL behaviour: ACCU2 is lhs, ACCU1 is rhs.
1418  const binary_relation_exprt operation{accu2, comparison, accu1};
1419  rlo_bit = operation;
1420 }
1421 
1423  const irep_idt &label,
1424  bool sets_fc_false)
1425 {
1426  // If the label is already present in the list, check if it matches the
1427  // criteria.
1428  auto label_it = stl_labels.find(label);
1429  if(label_it != end(stl_labels))
1430  {
1431  if(!label_it->second.jumps_permitted)
1432  {
1433  error() << "Not allowed to jump to label " << id2string(label_it->first)
1434  << eom;
1435  throw TYPECHECK_ERROR;
1436  }
1437 
1438  if(label_it->second.fc_false_required && !sets_fc_false)
1439  {
1440  error() << "Jump to label " << id2string(label_it->first)
1441  << " can not be unconditional" << eom;
1442  throw TYPECHECK_ERROR;
1443  }
1444 
1445  if(label_it->second.nesting_depth != nesting_stack.size())
1446  {
1447  error() << "Jump to label " << id2string(label_it->first)
1448  << " violates brace scope" << eom;
1449  throw TYPECHECK_ERROR;
1450  }
1451  }
1452  else // If it was not encountered yet, create a new reference entry.
1453  {
1454  stl_jump_locationt location{nesting_stack.size(), sets_fc_false};
1455  auto reference_it = label_references.find(label);
1456  if(reference_it == end(label_references))
1457  {
1458  std::vector<stl_jump_locationt> locations;
1459  locations.push_back(location);
1460  label_references.emplace(label, locations);
1461  }
1462  else
1463  reference_it->second.push_back(location);
1464  }
1465 }
1466 
1467 const symbol_exprt &
1469  const codet &op_code)
1470 {
1471  const symbol_exprt *const symbol =
1472  expr_try_dynamic_cast<symbol_exprt>(op_code.op0());
1473 
1474  if(symbol)
1475  return *symbol;
1476 
1477  error() << "Instruction is not followed by symbol" << eom;
1478  throw TYPECHECK_ERROR;
1479 }
1480 
1482  const codet &op_code)
1483 {
1484  if(op_code.operands().size() > 0)
1485  {
1486  error() << "Instruction is followed by operand" << eom;
1487  throw TYPECHECK_ERROR;
1488  }
1489 }
1490 
1492  const codet &op_code)
1493 {
1495  if(accumulator.size() < 2)
1496  {
1497  error() << "Not enough operands in the accumulator" << eom;
1498  throw TYPECHECK_ERROR;
1499  }
1500 }
1501 
1503  const codet &op_code,
1504  const exprt &rlo_value)
1505 {
1507  // If inside of a bit string use the value of the rlo. If this is the first
1508  // expression of a bit string, load the value of the nested operation by
1509  // implicitly setting the rlo to the specified value.
1510  if(!fc_bit)
1511  rlo_bit = rlo_value;
1512  const nesting_stack_entryt stack_entry{rlo_bit, or_bit, op_code};
1513  nesting_stack.push_back(stack_entry);
1514  fc_bit = false;
1515  or_bit = false;
1516 }
1517 
1519  const codet &op_code,
1520  const symbolt &tia_element,
1521  bool negate)
1522 {
1523  const symbol_exprt &sym{
1525  const exprt op{typecheck_identifier(tia_element, sym.get_identifier())};
1526  const not_exprt not_op{op};
1527  return negate ? not_op : op;
1528 }
1529 
1531  const symbolt &tia_element,
1532  const irep_idt &identifier)
1533 {
1534  const code_typet &element_type{to_code_type(tia_element.type)};
1535 
1536  // Check for temporary variables.
1538  id2string(tia_element.name) + "::" + id2string(identifier)))
1539  {
1540  const symbolt &sym{symbol_table.lookup_ref(
1541  id2string(tia_element.name) + "::" + id2string(identifier))};
1542  return sym.symbol_expr();
1543  }
1544 
1545  // Check for global tags.
1546  if(symbol_table.has_symbol(identifier))
1547  return symbol_table.lookup_ref(identifier).symbol_expr();
1548 
1549  if(
1550  element_type.get(ID_statement_list_type) ==
1551  ID_statement_list_function_block)
1552  {
1553  // Check for variables inside of the function block interface.
1554  const symbolt &data_block{symbol_table.get_writeable_ref(
1555  id2string(tia_element.name) + "::" + DATA_BLOCK_PARAMETER_NAME)};
1556  const symbol_exprt db_expr = data_block.symbol_expr();
1557  const struct_typet *const db_type = type_try_dynamic_cast<struct_typet>(
1558  to_type_with_subtype(db_expr.type()).subtype());
1559  if(!db_type)
1560  UNREACHABLE;
1561  for(const struct_union_typet::componentt &member : db_type->components())
1562  {
1563  if(member.get_name() == identifier)
1564  {
1565  const dereference_exprt deref_db{db_expr};
1566  const member_exprt val{deref_db, member.get_name(), member.type()};
1567  return val;
1568  }
1569  }
1570  }
1571  else if(
1572  element_type.get(ID_statement_list_type) == ID_statement_list_function)
1573  {
1574  // Check for variables inside of the function interface.
1575  for(const auto &member : element_type.parameters())
1576  {
1577  if(member.get_base_name() == identifier)
1578  {
1579  const symbolt &par{
1580  symbol_table.get_writeable_ref(member.get_identifier())};
1581  return par.symbol_expr();
1582  }
1583  }
1584  }
1585  else
1586  UNREACHABLE; // Variable declarations should only be checked for FCs or FBs
1587 
1588  error() << "Identifier could not be found in project" << eom;
1589  throw TYPECHECK_ERROR;
1590 }
1591 
1593  const codet &op_code,
1594  symbolt &tia_element)
1595 {
1596  if(
1597  const auto assignment =
1598  expr_try_dynamic_cast<code_frontend_assignt>(op_code.op1()))
1599  {
1600  const code_assertt assertion{
1601  typecheck_function_call_argument_rhs(tia_element, assignment->rhs())};
1602  tia_element.value.add_to_operands(assertion);
1603  }
1604  else
1605  {
1606  error() << "No assignment found for assertion" << eom;
1607  throw TYPECHECK_ERROR;
1608  }
1609 }
1610 
1612  const codet &op_code,
1613  symbolt &tia_element)
1614 {
1615  if(
1616  const auto assignment =
1617  expr_try_dynamic_cast<code_frontend_assignt>(op_code.op1()))
1618  {
1619  const code_assumet assumption{
1620  typecheck_function_call_argument_rhs(tia_element, assignment->rhs())};
1621  tia_element.value.add_to_operands(assumption);
1622  }
1623  else
1624  {
1625  error() << "No assignment found for assumption" << eom;
1626  throw TYPECHECK_ERROR;
1627  }
1628 }
1629 
1631  const codet &op_code,
1632  symbolt &tia_element)
1633 {
1634  const symbol_exprt &call_operand{to_symbol_expr(op_code.op0())};
1635  const symbolt &called_function{
1636  symbol_table.lookup_ref(call_operand.get_identifier())};
1637  const code_typet &called_type{to_code_type(called_function.type)};
1638  // Is it a STL function or STL function block?
1639  if(
1640  called_type.get(ID_statement_list_type) == ID_statement_list_function_block)
1641  typecheck_called_function_block(op_code, tia_element);
1642  else if(called_type.get(ID_statement_list_type) == ID_statement_list_function)
1643  typecheck_called_function(op_code, tia_element);
1644  else
1645  {
1646  error() << "Tried to call element that is no function or function block"
1647  << eom;
1648  throw TYPECHECK_ERROR;
1649  }
1650 }
1651 
1653  const codet &op_code,
1654  symbolt &tia_element)
1655 {
1656  const symbol_exprt call_operand{to_symbol_expr(op_code.op0())};
1657  const symbolt &called_function_sym{
1658  symbol_table.lookup_ref(call_operand.get_identifier())};
1659  const symbol_exprt called_function_expr{called_function_sym.symbol_expr()};
1660  const code_typet &called_type{to_code_type(called_function_sym.type)};
1661 
1662  // Check if function name is followed by data block.
1664  {
1665  error() << "Function calls should not address instance data blocks" << eom;
1666  throw TYPECHECK_ERROR;
1667  }
1668 
1669  // Check if function interface matches the call and fill argument list.
1670  const code_typet::parameterst &params{called_type.parameters()};
1672  std::vector<code_frontend_assignt> assignments;
1673  for(const auto &expr : op_code.operands())
1674  {
1675  if(auto assign = expr_try_dynamic_cast<code_frontend_assignt>(expr))
1676  assignments.push_back(*assign);
1677  }
1678 
1679  for(const code_typet::parametert &param : params)
1680  args.emplace_back(
1681  typecheck_function_call_arguments(assignments, param, tia_element));
1682 
1683  // Check the return value if present.
1684  if(called_type.return_type().is_nil())
1685  tia_element.value.add_to_operands(
1686  code_function_callt{called_function_expr, args});
1687  else
1688  {
1690  assignments, called_type.return_type(), tia_element)};
1691  tia_element.value.add_to_operands(
1692  code_function_callt{lhs, called_function_expr, args});
1693  }
1694 }
1695 
1697  const codet &op_code,
1698  symbolt &tia_element)
1699 {
1700  // TODO: Implement support for function block calls.
1701  // Needs code statements which assign the parameters to the instance data
1702  // block, call the function and write the result back to the parameters
1703  // afterwards.
1704  error() << "Calls to function blocks are not supported yet" << eom;
1705  throw TYPECHECK_ERROR;
1706 }
1707 
1709  const std::vector<code_frontend_assignt> &assignments,
1710  const code_typet::parametert &param,
1711  const symbolt &tia_element)
1712 {
1713  const irep_idt &param_name = param.get_base_name();
1714  const typet &param_type = param.type();
1715  for(const auto &assignment : assignments)
1716  {
1717  const symbol_exprt &lhs{to_symbol_expr(assignment.lhs())};
1718  if(param_name == lhs.get_identifier())
1719  {
1720  exprt assigned_variable{
1721  typecheck_function_call_argument_rhs(tia_element, assignment.rhs())};
1722 
1723  if(param_type == assigned_variable.type())
1724  return assigned_variable;
1725  else
1726  {
1727  error() << "Types of parameter assignment do not match: "
1728  << param.type().id() << " != " << assigned_variable.type().id()
1729  << eom;
1730  throw TYPECHECK_ERROR;
1731  }
1732  }
1733  }
1734  error() << "No assignment found for function parameter "
1735  << param.get_identifier() << eom;
1736  throw TYPECHECK_ERROR;
1737 }
1738 
1740  const symbolt &tia_element,
1741  const exprt &rhs)
1742 {
1743  exprt assigned_operand;
1744  const symbol_exprt *const symbol_rhs =
1745  expr_try_dynamic_cast<symbol_exprt>(rhs);
1746  if(symbol_rhs)
1747  assigned_operand =
1748  typecheck_identifier(tia_element, symbol_rhs->get_identifier());
1749  else // constant_exprt.
1750  assigned_operand = rhs;
1751  return assigned_operand;
1752 }
1753 
1755  const std::vector<code_frontend_assignt> &assignments,
1756  const typet &return_type,
1757  const symbolt &tia_element)
1758 {
1759  for(const auto &assignment : assignments)
1760  {
1761  const symbol_exprt &lhs{to_symbol_expr(assignment.lhs())};
1762  if(ID_statement_list_return_value_id == lhs.get_identifier())
1763  {
1764  const symbol_exprt &rhs{to_symbol_expr(assignment.rhs())};
1765  const exprt assigned_variable{
1766  typecheck_identifier(tia_element, rhs.get_identifier())};
1767  if(return_type == assigned_variable.type())
1768  return assigned_variable;
1769  else
1770  {
1771  error() << "Types of return value assignment do not match: "
1772  << return_type.id() << " != " << assigned_variable.type().id()
1773  << eom;
1774  throw TYPECHECK_ERROR;
1775  }
1776  }
1777  }
1778  error() << "No assignment found for function return value" << eom;
1779  throw TYPECHECK_ERROR;
1780 }
1781 
1783 {
1784  or_exprt or_wrapper{to_or_expr(rlo_bit)};
1785 
1786  if(can_cast_expr<constant_exprt>(or_wrapper.op1()))
1787  or_wrapper.op1();
1788  else if(can_cast_expr<and_exprt>(or_wrapper.op1()))
1789  {
1790  and_exprt &and_op{to_and_expr(or_wrapper.op1())};
1791  and_op.add_to_operands(op);
1792  or_wrapper.op1() = and_op;
1793  }
1794  else
1795  {
1796  and_exprt and_op{or_wrapper.op1(), op};
1797  or_wrapper.op1() = and_op;
1798  }
1799  rlo_bit = or_wrapper;
1800 }
1801 
1803 {
1804  fc_bit = true;
1805  or_bit = false;
1806  rlo_bit = op;
1807 }
1808 
1810 {
1811  rlo_bit = true_exprt{};
1812  fc_bit = false;
1813  or_bit = false;
1814  nesting_stack.clear();
1815 }
1816 
1818 {
1820  label_references.clear();
1821  stl_labels.clear();
1822 }
1823 
1825 {
1826  symbol_exprt temp_rlo{
1828  const code_assignt rlo_assignment{temp_rlo, rlo_bit};
1829  tia_element.value.add_to_operands(rlo_assignment);
1830  rlo_bit = std::move(temp_rlo);
1831 }
statement_list_typecheckt::create_instance_data_block_type
struct_typet create_instance_data_block_type(const statement_list_parse_treet::function_blockt &function_block)
Creates a data block type for the given function block.
Definition: statement_list_typecheck.cpp:257
statement_list_typecheckt::typecheck_statement_list_nested_and_not
void typecheck_statement_list_nested_and_not(const codet &op_code)
Performs a typecheck on a nested And Not instruction.
Definition: statement_list_typecheck.cpp:1111
UNREACHABLE
#define UNREACHABLE
This should be used to mark dead code.
Definition: invariant.h:503
struct_union_typet::components
const componentst & components() const
Definition: std_types.h:147
statement_list_typecheckt::typecheck_return_value_assignment
exprt typecheck_return_value_assignment(const std::vector< code_frontend_assignt > &assignments, const typet &return_type, const symbolt &tia_element)
Checks if there is a return value assignment inside of the assignment list of a function call and ret...
Definition: statement_list_typecheck.cpp:1754
symbol_table_baset::has_symbol
bool has_symbol(const irep_idt &name) const
Check whether a symbol exists in the symbol table.
Definition: symbol_table_base.h:87
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
code_blockt
A codet representing sequential composition of program statements.
Definition: std_code.h:129
statement_list_typecheckt::typecheck_statement_list_and_not
void typecheck_statement_list_and_not(const codet &op_code, const symbolt &tia_element)
Performs a typecheck on a STL boolean And Not instruction.
Definition: statement_list_typecheck.cpp:983
symbol_tablet
The symbol table.
Definition: symbol_table.h:13
symbol_table_baset::lookup_ref
const symbolt & lookup_ref(const irep_idt &name) const
Find a symbol in the symbol table for read-only access.
Definition: symbol_table_base.h:104
statement_list_typecheckt::typecheck_statement_list_reset
void typecheck_statement_list_reset(const codet &op_code, symbolt &tia_element)
Performs a typecheck on a STL 'R' instruction and saves the result to the given symbol.
Definition: statement_list_typecheck.cpp:1266
statement_list_typecheckt::typecheck_statement_list_and_before_or
void typecheck_statement_list_and_before_or()
Performs a typecheck on a STL operand-less Or instruction.
Definition: statement_list_typecheck.cpp:1092
statement_list_typecheckt::typecheck_statement_list_accu_int_arith
void typecheck_statement_list_accu_int_arith(const codet &op_code)
Performs a typecheck on a STL Accumulator instruction for integers.
Definition: statement_list_typecheck.cpp:1353
statement_list_typecheckt::typecheck_statement_list_accu_int_gt
void typecheck_statement_list_accu_int_gt(const codet &op_code)
Performs a typecheck on a STL accumulator greater than comparison instruction for integers.
Definition: statement_list_typecheck.cpp:744
statement_list_typecheckt::typecheck_statement_list_jump_conditional
void typecheck_statement_list_jump_conditional(const codet &op_code, symbolt &tia_element)
Performs a typecheck on a conditional jump instruction (JC) and adds it to the given symbol.
Definition: statement_list_typecheck.cpp:1317
statement_list_typecheck.h
STL_DINT_WIDTH
#define STL_DINT_WIDTH
Definition: statement_list_types.h:16
codet::op0
exprt & op0()
Definition: expr.h:125
statement_list_parse_treet::tia_modulet::networks
networkst networks
List of all networks of this module.
Definition: statement_list_parse_tree.h:98
goto_instruction_code.h
statement_list_typecheckt::typecheck_code
void typecheck_code(const codet &instruction, symbolt &tia_element)
Performs a typecheck for the specified instruction in code form.
Definition: statement_list_typecheck.cpp:383
statement_list_typecheckt::typecheck_statement_list_not
void typecheck_statement_list_not(const codet &op_code)
Performs a typecheck on a STL boolean NOT instruction.
Definition: statement_list_typecheck.cpp:953
statement_list_typecheckt::typecheck_CPROVER_assert
void typecheck_CPROVER_assert(const codet &op_code, symbolt &tia_element)
Performs a typecheck on a call of __CPOVER_ASSERT and saves the result to the given symbol.
Definition: statement_list_typecheck.cpp:1592
statement_list_typecheckt::module
const irep_idt module
Name of the module this typecheck belongs to.
Definition: statement_list_typecheck.h:68
statement_list_typecheckt::typecheck_statement_list_nested_or_not
void typecheck_statement_list_nested_or_not(const codet &op_code)
Performs a typecheck on a nested Or Not instruction.
Definition: statement_list_typecheck.cpp:1127
statement_list_parse_treet::var_declarationst
std::list< var_declarationt > var_declarationst
Definition: statement_list_parse_tree.h:39
statement_list_typecheckt::typecheck_statement_list_call
void typecheck_statement_list_call(const codet &op_code, symbolt &tia_element)
Performs a typecheck on a STL Call instruction and saves the result to the given symbol.
Definition: statement_list_typecheck.cpp:1283
can_cast_expr< code_frontend_assignt >
bool can_cast_expr< code_frontend_assignt >(const exprt &base)
Definition: std_code.h:103
typet
The type of an expression, extends irept.
Definition: type.h:28
code_typet::parameterst
std::vector< parametert > parameterst
Definition: std_types.h:541
statement_list_parse_treet::tia_modulet::var_temp
var_declarationst var_temp
Temp variable declarations.
Definition: statement_list_parse_tree.h:93
logic_sequence_initializers
static const std::vector< irep_idt > logic_sequence_initializers
Definition: statement_list_typecheck.cpp:40
symbolt::type
typet type
Type of symbol.
Definition: symbol.h:31
dereference_exprt
Operator to dereference a pointer.
Definition: pointer_expr.h:659
statement_list_typecheckt::typecheck_statement_list_accu_real_eq
void typecheck_statement_list_accu_real_eq(const codet &op_code)
Performs a typecheck on a STL accumulator equality comparison instruction for double integers.
Definition: statement_list_typecheck.cpp:911
code_typet::parametert::set_identifier
void set_identifier(const irep_idt &identifier)
Definition: std_types.h:580
statement_list_typecheckt::typecheck_statement_list_accu_real_sub
void typecheck_statement_list_accu_real_sub(const codet &op_code)
Performs a typecheck on a STL accumulator subtract instruction for reals.
Definition: statement_list_typecheck.cpp:872
statement_list_typecheckt::typecheck_statement_list_nested_and
void typecheck_statement_list_nested_and(const codet &op_code)
Performs a typecheck on a nested And instruction.
Definition: statement_list_typecheck.cpp:1103
statement_list_typecheckt::typecheck_statement_list_accu_dint_sub
void typecheck_statement_list_accu_dint_sub(const codet &op_code)
Performs a typecheck on a STL accumulator subtract instruction for double integers.
Definition: statement_list_typecheck.cpp:778
xor_exprt
Boolean XOR.
Definition: std_expr.h:2241
statement_list_typecheckt::typecheck_statement_list_assign
void typecheck_statement_list_assign(const codet &op_code, symbolt &tia_element)
Performs a typecheck on a STL assign instruction and saves the result to the given symbol.
Definition: statement_list_typecheck.cpp:1210
statement_list_typecheckt::typecheck_statement_list_accu_int_lte
void typecheck_statement_list_accu_int_lte(const codet &op_code)
Performs a typecheck on a STL accumulator less than or equal comparison instruction for integers.
Definition: statement_list_typecheck.cpp:751
code_declt
A goto_instruction_codet representing the declaration of a local variable.
Definition: goto_instruction_code.h:204
code_assertt
A non-fatal assertion, which checks a condition then permits execution to continue.
Definition: std_code.h:269
and_exprt
Boolean AND.
Definition: std_expr.h:2070
to_type_with_subtype
const type_with_subtypet & to_type_with_subtype(const typet &type)
Definition: type.h:193
statement_list_parse_treet::var_declarationt
Struct for a single variable declaration in Statement List.
Definition: statement_list_parse_tree.h:28
plus_exprt
The plus expression Associativity is not specified.
Definition: std_expr.h:946
statement_list_parse_treet::tia_modulet::var_input
var_declarationst var_input
Input variable declarations.
Definition: statement_list_parse_tree.h:87
statement_list_typecheckt::typecheck_statement_list_accu_real_add
void typecheck_statement_list_accu_real_add(const codet &op_code)
Performs a typecheck on a STL accumulator add instruction for reals.
Definition: statement_list_typecheck.cpp:859
CPROVER_TEMP_RLO
#define CPROVER_TEMP_RLO
Name of the RLO symbol used in some operations.
Definition: statement_list_typecheck.cpp:38
exprt
Base class for all expressions.
Definition: expr.h:55
struct_union_typet::componentst
std::vector< componentt > componentst
Definition: std_types.h:140
symbolt::base_name
irep_idt base_name
Base (non-scoped) name.
Definition: symbol.h:46
statement_list_typecheckt::symbol_table
symbol_tablet & symbol_table
Reference to the symbol table that should be filled during the typecheck.
Definition: statement_list_typecheck.h:65
statement_list_parse_treet::instructiont
Represents a regular Statement List instruction which consists out of one or more codet tokens.
Definition: statement_list_parse_tree.h:43
statement_list_parse_treet::tia_modulet
Base element of all modules in the Totally Integrated Automation (TIA) portal by Siemens.
Definition: statement_list_parse_tree.h:79
component
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
Definition: std_expr.cpp:76
statement_list_typecheckt::typecheck_statement_list_accu_dint_arith
void typecheck_statement_list_accu_dint_arith(const codet &op_code)
Performs a typecheck on a STL Accumulator instruction for double integers.
Definition: statement_list_typecheck.cpp:1374
statement_list_typecheckt::save_rlo_state
void save_rlo_state(symbolt &tia_element)
Saves the current RLO bit to a temporary variable to prevent false overrides when modifying boolean v...
Definition: statement_list_typecheck.cpp:1824
statement_list_parse_treet::var_declarationt::variable
symbol_exprt variable
Representation of the variable, including identifier and type.
Definition: statement_list_parse_tree.h:31
statement_list_typecheckt::typecheck_label_reference
void typecheck_label_reference(const irep_idt &label, bool sets_fc_false)
Checks if the given label is already present and compares the current state with it.
Definition: statement_list_typecheck.cpp:1422
messaget::eom
static eomt eom
Definition: message.h:297
statement_list_typecheckt::rlo_bit
exprt rlo_bit
Result of Logic Operation (Part of the TIA status word).
Definition: statement_list_typecheck.h:80
statement_list_typecheckt::typecheck_statement_list_accu_int_neq
void typecheck_statement_list_accu_int_neq(const codet &op_code)
Performs a typecheck on a STL accumulator inequality comparison instruction for integers.
Definition: statement_list_typecheck.cpp:730
div_exprt
Division.
Definition: std_expr.h:1096
symbol_exprt
Expression to hold a symbol (variable)
Definition: std_expr.h:112
statement_list_typecheckt::typecheck_statement_list_instruction
void typecheck_statement_list_instruction(const statement_list_parse_treet::instructiont &instruction, symbolt &tia_element)
Performs a typecheck on a single instruction and saves the result to the given symbol body if necessa...
Definition: statement_list_typecheck.cpp:375
statement_list_typecheckt::typecheck_statement_list_accu_int_add
void typecheck_statement_list_accu_int_add(const codet &op_code)
Performs a typecheck on a STL accumulator add instruction for integers.
Definition: statement_list_typecheck.cpp:671
namespace.h
CPROVER_ASSUME
#define CPROVER_ASSUME
Name of the CBMC assume function.
Definition: statement_list_typecheck.cpp:36
statement_list_typecheckt::typecheck_temp_var_decls
void typecheck_temp_var_decls(const statement_list_parse_treet::tia_modulet &tia_module, symbolt &tia_symbol)
Performs a typecheck on the temp variables of a TIA module and saves the result to the given symbol v...
Definition: statement_list_typecheck.cpp:316
statement_list_typecheckt::typecheck_statement_list_accu_real_div
void typecheck_statement_list_accu_real_div(const codet &op_code)
Performs a typecheck on a STL accumulator divide instruction for reals.
Definition: statement_list_typecheck.cpp:898
statement_list_typecheckt::nesting_stack_entryt::nesting_stack_entryt
nesting_stack_entryt(exprt rlo_bit, bool or_bit, codet function_code)
Definition: statement_list_typecheck.cpp:93
statement_list_typecheckt::typecheck_tag_list
void typecheck_tag_list()
Performs a typecheck on the tag list of the referenced parse tree and adds symbols for its contents t...
Definition: statement_list_typecheck.cpp:228
statement_list_parse_treet::function_blockt
Structure for a simple function block in Statement List.
Definition: statement_list_parse_tree.h:146
code_ifthenelset
codet representation of an if-then-else statement.
Definition: std_code.h:459
statement_list_typecheckt::typecheck_statement_list_accu_dint_lte
void typecheck_statement_list_accu_dint_lte(const codet &op_code)
Performs a typecheck on a STL accumulator less than or equal comparison instruction for double intege...
Definition: statement_list_typecheck.cpp:845
code_labelt::code
codet & code()
Definition: std_code.h:977
symbolt::pretty_name
irep_idt pretty_name
Language-specific display name.
Definition: symbol.h:52
statement_list_typecheckt::stl_label_locationt::jumps_permitted
const bool jumps_permitted
States if jumps to this location are permitted or if the location is invalid.
Definition: statement_list_typecheck.h:126
statement_list_typecheckt::typecheck_statement_list_nested_xor_not
void typecheck_statement_list_nested_xor_not(const codet &op_code)
Performs a typecheck on a nested XOR Not instruction.
Definition: statement_list_typecheck.cpp:1143
statement_list_typecheckt::typecheck_statement_list_or
void typecheck_statement_list_or(const codet &op_code, const symbolt &tia_element)
Performs a typecheck on a STL boolean Or instruction.
Definition: statement_list_typecheck.cpp:1005
TYPECHECK_ERROR
#define TYPECHECK_ERROR
Definition: statement_list_typecheck.cpp:28
statement_list_typecheckt::typecheck_statement_list_accu_int_sub
void typecheck_statement_list_accu_int_sub(const codet &op_code)
Performs a typecheck on a STL accumulator subtract instruction for integers.
Definition: statement_list_typecheck.cpp:684
statement_list_typecheckt::stl_label_locationt::fc_false_required
const bool fc_false_required
States if jump instructions to this location need to set the /FC bit to false.
Definition: statement_list_typecheck.h:130
statement_list_typecheckt::typecheck_CPROVER_assume
void typecheck_CPROVER_assume(const codet &op_code, symbolt &tia_element)
Performs a typecheck on a call of __CPOVER_ASSUME and saves the result to the given symbol.
Definition: statement_list_typecheck.cpp:1611
statement_list_typecheckt::typecheck_called_tia_element
void typecheck_called_tia_element(const codet &op_code, symbolt &tia_element)
Performs a typecheck on a call of a TIA element and saves the result to the given symbol.
Definition: statement_list_typecheck.cpp:1630
namespacet
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:90
statement_list_typecheckt::typecheck_statement_list_networks
void typecheck_statement_list_networks(const statement_list_parse_treet::tia_modulet &tia_module, symbolt &tia_symbol)
Performs a typecheck on the networks of a TIA module and saves the result to the given symbol.
Definition: statement_list_typecheck.cpp:338
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:84
code_function_callt
goto_instruction_codet representation of a function call statement.
Definition: goto_instruction_code.h:271
can_cast_expr< and_exprt >
bool can_cast_expr< and_exprt >(const exprt &base)
Definition: std_expr.h:2107
statement_list_typecheckt::typecheck_statement_list_accu_dint_eq
void typecheck_statement_list_accu_dint_eq(const codet &op_code)
Performs a typecheck on a STL accumulator equality comparison instruction for double integers.
Definition: statement_list_typecheck.cpp:817
statement_list_typecheckt::typecheck_statement_list_accu_int_gte
void typecheck_statement_list_accu_int_gte(const codet &op_code)
Performs a typecheck on a STL accumulator greater than or equal comparison instruction for integers.
Definition: statement_list_typecheck.cpp:758
to_code_type
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
Definition: std_types.h:744
statement_list_typecheckt::typecheck_statement_list_accu_real_gt
void typecheck_statement_list_accu_real_gt(const codet &op_code)
Performs a typecheck on a STL accumulator greater than comparison instruction for double integers.
Definition: statement_list_typecheck.cpp:932
statement_list_typecheckt::nesting_stack
nesting_stackt nesting_stack
Representation of the nesting stack.
Definition: statement_list_typecheck.h:114
symbolt::mode
irep_idt mode
Language mode.
Definition: symbol.h:49
messaget::error
mstreamt & error() const
Definition: message.h:399
code_typet::parametert::get_base_name
const irep_idt & get_base_name() const
Definition: std_types.h:595
statement_list_typecheckt::typecheck_statement_list_accu_real_lt
void typecheck_statement_list_accu_real_lt(const codet &op_code)
Performs a typecheck on a STL accumulator less than comparison instruction for double integers.
Definition: statement_list_typecheck.cpp:925
empty_typet
The empty type.
Definition: std_types.h:50
or_exprt
Boolean OR.
Definition: std_expr.h:2178
statement_list_typecheckt::typecheck_statement_list_load
void typecheck_statement_list_load(const codet &op_code, const symbolt &tia_element)
Performs a typecheck on a STL load instruction.
Definition: statement_list_typecheck.cpp:635
statement_list_typecheckt::typecheck_binary_accumulator_instruction
void typecheck_binary_accumulator_instruction(const codet &op_code)
Performs a typecheck on a STL instruction that uses two accumulator entries.
Definition: statement_list_typecheck.cpp:1491
statement_list_typecheckt::add_temp_rlo
void add_temp_rlo()
Adds a symbol for the RLO to the symbol table.
Definition: statement_list_typecheck.cpp:244
statement_list_typecheckt::typecheck_statement_list_xor_not
void typecheck_statement_list_xor_not(const codet &op_code, const symbolt &tia_element)
Performs a typecheck on a STL boolean XOR Not instruction.
Definition: statement_list_typecheck.cpp:1071
statement_list_typecheckt::typecheck_statement_list_or_not
void typecheck_statement_list_or_not(const codet &op_code, const symbolt &tia_element)
Performs a typecheck on a STL boolean Or Not instruction.
Definition: statement_list_typecheck.cpp:1030
symbol_table_baset::get_writeable_ref
symbolt & get_writeable_ref(const irep_idt &name)
Find a symbol in the symbol table for read-write access.
Definition: symbol_table_base.h:121
id2string
const std::string & id2string(const irep_idt &d)
Definition: irep.h:47
statement_list_typecheckt::typecheck_statement_list_accu_int_eq
void typecheck_statement_list_accu_int_eq(const codet &op_code)
Performs a typecheck on a STL accumulator equality comparison instruction for integers.
Definition: statement_list_typecheck.cpp:723
statement_list_typecheckt::typecheck_function_var_decls
void typecheck_function_var_decls(const statement_list_parse_treet::var_declarationst &var_decls, code_typet::parameterst &params, const irep_idt &function_name, const irep_idt &var_property)
Performs a typecheck on a variable declaration list and saves the result to the given component eleme...
Definition: statement_list_typecheck.cpp:289
statement_list_typecheckt::typecheck_statement_list_accu_real_neq
void typecheck_statement_list_accu_real_neq(const codet &op_code)
Performs a typecheck on a STL accumulator inequality comparison instruction for double integers.
Definition: statement_list_typecheck.cpp:918
statement_list_typecheckt::typecheck_statement_list_accu_real_mul
void typecheck_statement_list_accu_real_mul(const codet &op_code)
Performs a typecheck on a STL accumulator multiply instruction for reals.
Definition: statement_list_typecheck.cpp:885
irept::set
void set(const irep_idt &name, const irep_idt &value)
Definition: irep.h:420
code_gotot
codet representation of a goto statement.
Definition: std_code.h:840
statement_list_typecheckt::typecheck_statement_list_accu_dint_gt
void typecheck_statement_list_accu_dint_gt(const codet &op_code)
Performs a typecheck on a STL accumulator greater than comparison instruction for double integers.
Definition: statement_list_typecheck.cpp:838
code_labelt
codet representation of a label for branch targets.
Definition: std_code.h:958
multi_ary_exprt::op1
exprt & op1()
Definition: std_expr.h:883
statement_list_typecheckt::typecheck_function_block_declaration
void typecheck_function_block_declaration(const statement_list_parse_treet::function_blockt &function_block)
Performs a typecheck on a function block declaration inside of the parse tree and adds symbols for it...
Definition: statement_list_typecheck.cpp:156
symbol_exprt::get_identifier
const irep_idt & get_identifier() const
Definition: std_expr.h:142
statement_list_parse_treet::function_blocks
function_blockst function_blocks
List of function blocks this parse tree includes.
Definition: statement_list_parse_tree.h:173
statement_list_parse_treet::tia_modulet::name
const irep_idt name
Name of the module.
Definition: statement_list_parse_tree.h:82
statement_list_typecheckt::typecheck_statement_list_accu_dint_gte
void typecheck_statement_list_accu_dint_gte(const codet &op_code)
Performs a typecheck on a STL accumulator greater than or equal comparison instruction for double int...
Definition: statement_list_typecheck.cpp:852
statement_list_typecheck
bool statement_list_typecheck(const statement_list_parse_treet &parse_tree, symbol_tablet &symbol_table, const std::string &module, message_handlert &message_handler)
Create a new statement_list_typecheckt object and perform a type check to fill the symbol table.
Definition: statement_list_typecheck.cpp:81
code_assumet
An assumption, which must hold in subsequent code.
Definition: std_code.h:216
signedbv_typet
Fixed-width bit-vector with two's complement interpretation.
Definition: bitvector_types.h:207
statement_list_typecheckt::typecheck_label_location
stl_label_locationt typecheck_label_location(const code_labelt &label)
Converts the properties of the current typecheck state to a label location.
Definition: statement_list_typecheck.cpp:549
statement_list_typecheckt::label_references
label_referencest label_references
Holds associations between labels and jumps that are referencing it.
Definition: statement_list_typecheck.h:174
to_code_label
const code_labelt & to_code_label(const codet &code)
Definition: std_code.h:1004
symbolt::symbol_expr
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
Definition: symbol.cpp:121
pointer_expr.h
statement_list_typecheckt::typecheck_statement_list_set
void typecheck_statement_list_set(const codet &op_code, symbolt &tia_element)
Performs a typecheck on a STL 'S' instruction and saves the result to the given symbol.
Definition: statement_list_typecheck.cpp:1249
exprt::op1
exprt & op1()
Definition: expr.h:128
mult_exprt
Binary multiplication Associativity is not specified.
Definition: std_expr.h:1051
simplify_expr
exprt simplify_expr(exprt src, const namespacet &ns)
Definition: simplify_expr.cpp:2931
statement_list_typecheckt::typecheck_function_declaration
void typecheck_function_declaration(const statement_list_parse_treet::functiont &function)
Performs a typecheck on a function declaration inside of the parse tree and adds symbols for it and i...
Definition: statement_list_typecheck.cpp:205
statement_list_typecheckt::typecheck_statement_list_accu_real_arith
void typecheck_statement_list_accu_real_arith(const codet &op_code)
Performs a typecheck on a STL Accumulator instruction for reals.
Definition: statement_list_typecheck.cpp:1396
statement_list_typecheckt::typecheck_instruction_without_operand
void typecheck_instruction_without_operand(const codet &op_code)
Performs a typecheck on an operand-less STL instruction.
Definition: statement_list_typecheck.cpp:1481
statement_list_typecheckt::typecheck_called_function_block
void typecheck_called_function_block(const codet &op_code, symbolt &tia_element)
Performs a typecheck on a call of a TIA function block and saves the result to the given symbol.
Definition: statement_list_typecheck.cpp:1696
statement_list_parse_treet::instructiont::tokens
std::vector< codet > tokens
Data structure for all tokens of the instruction.
Definition: statement_list_parse_tree.h:46
to_symbol_expr
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition: std_expr.h:222
code_typet
Base type of functions.
Definition: std_types.h:538
statement_list_typecheckt::stl_jump_locationt
Holds information about the properties of a jump instruction.
Definition: statement_list_typecheck.h:149
statement_list_typecheckt::typecheck_label
void typecheck_label(const codet &instruction, symbolt &tia_element)
Performs a typecheck for the given label in code form.
Definition: statement_list_typecheck.cpp:511
irept::is_nil
bool is_nil() const
Definition: irep.h:376
irept::id
const irep_idt & id() const
Definition: irep.h:396
message_handlert
Definition: message.h:27
code_function_callt::argumentst
exprt::operandst argumentst
Definition: goto_instruction_code.h:281
false_exprt
The Boolean constant false.
Definition: std_expr.h:3016
statement_list_typecheckt::typecheck_statement_list_accu_int_mul
void typecheck_statement_list_accu_int_mul(const codet &op_code)
Performs a typecheck on a STL accumulator multiply instruction for integers.
Definition: statement_list_typecheck.cpp:697
cprover_prefix.h
std_code.h
statement_list_typecheckt::statement_list_typecheckt
statement_list_typecheckt(const statement_list_parse_treet &parse_tree, symbol_tablet &symbol_table, const std::string &module, message_handlert &message_handler)
Creates a new instance of statement_list_typecheckt.
Definition: statement_list_typecheck.cpp:117
logic_sequence_terminators
static const std::vector< irep_idt > logic_sequence_terminators
Definition: statement_list_typecheck.cpp:55
minus_exprt
Binary minus.
Definition: std_expr.h:1005
statement_list_typecheckt::typecheck_statement_list_accu_dint_neq
void typecheck_statement_list_accu_dint_neq(const codet &op_code)
Performs a typecheck on a STL accumulator inequality comparison instruction for double integers.
Definition: statement_list_typecheck.cpp:824
simplify_expr.h
statement_list_typecheckt::typecheck_statement_list_accu_int_lt
void typecheck_statement_list_accu_int_lt(const codet &op_code)
Performs a typecheck on a STL accumulator less than comparison instruction for integers.
Definition: statement_list_typecheck.cpp:737
bitvector_typet::get_width
std::size_t get_width() const
Definition: std_types.h:876
to_or_expr
const or_exprt & to_or_expr(const exprt &expr)
Cast an exprt to a or_exprt.
Definition: std_expr.h:2226
statement_list_parse_treet::function_blockt::var_static
var_declarationst var_static
FB-exclusive static variable declarations.
Definition: statement_list_parse_tree.h:149
statement_list_typecheckt::typecheck
void typecheck() override
Performs the actual typecheck by using the parse tree with which the object was initialized and modif...
Definition: statement_list_typecheck.cpp:129
code_labelt::get_label
const irep_idt & get_label() const
Definition: std_code.h:967
statement_list_typecheckt::typecheck_statement_list_nesting_closed
void typecheck_statement_list_nesting_closed(const codet &op_code)
Performs a typecheck on a Nesting Closed instruction.
Definition: statement_list_typecheck.cpp:1151
STATEMENT_LIST_PTR_WIDTH
#define STATEMENT_LIST_PTR_WIDTH
Size of pointers in Siemens TIA.
Definition: statement_list_typecheck.cpp:26
statement_list_typecheckt::typecheck_statement_list_nested_or
void typecheck_statement_list_nested_or(const codet &op_code)
Performs a typecheck on a nested Or instruction.
Definition: statement_list_typecheck.cpp:1119
symbol_table_baset::add
bool add(const symbolt &symbol)
Add a new symbol to the symbol table.
Definition: symbol_table_base.cpp:18
member_exprt
Extract member of struct or union.
Definition: std_expr.h:2793
struct_union_typet::componentt
Definition: std_types.h:68
statement_list_typecheckt::typecheck_instruction_with_non_const_operand
const symbol_exprt & typecheck_instruction_with_non_const_operand(const codet &op_code)
Performs a typecheck on a STL instruction with an additional operand that should be no constant.
Definition: statement_list_typecheck.cpp:1468
statement_list_parse_treet
Intermediate representation of a parsed Statement List file before converting it into a goto program.
Definition: statement_list_parse_tree.h:20
symbolt::value
exprt value
Initial value of symbol.
Definition: symbol.h:34
statement_list_typecheckt::typecheck_identifier
exprt typecheck_identifier(const symbolt &tia_element, const irep_idt &identifier)
Performs a typecheck on the given identifier and returns its symbol.
Definition: statement_list_typecheck.cpp:1530
statement_list_typecheckt::stl_jump_locationt::stl_jump_locationt
stl_jump_locationt(size_t nesting_depth, bool sets_fc_false)
Constructs a new location with the specified properties.
Definition: statement_list_typecheck.cpp:110
statement_list_typecheckt::typecheck_statement_list_set_rlo
void typecheck_statement_list_set_rlo(const codet &op_code)
Performs a typecheck on a STL 'SET' instruction and modifies the RLO, OR and FC bit.
Definition: statement_list_typecheck.cpp:1231
messaget::message_handler
message_handlert * message_handler
Definition: message.h:439
struct_typet
Structure type, corresponds to C style structs.
Definition: std_types.h:230
statement_list_typecheckt::typecheck_statement_list_transfer
void typecheck_statement_list_transfer(const codet &op_code, symbolt &tia_element)
Performs a typecheck on a STL transfer instruction and saves the result to the given symbol.
Definition: statement_list_typecheck.cpp:656
code_skipt
A codet representing a skip statement.
Definition: std_code.h:321
statement_list_typecheckt::typecheck_statement_list_accu_real_gte
void typecheck_statement_list_accu_real_gte(const codet &op_code)
Performs a typecheck on a STL accumulator greater than or equal comparison instruction for double int...
Definition: statement_list_typecheck.cpp:946
statement_list_typecheckt::typecheck_accumulator_compare_instruction
void typecheck_accumulator_compare_instruction(const irep_idt &comparison)
Performs a typecheck on an STL comparison instruction.
Definition: statement_list_typecheck.cpp:1412
statement_list_typecheckt::parse_tree
const statement_list_parse_treet & parse_tree
Parse tree which is used to fill the symbol table.
Definition: statement_list_typecheck.h:62
statement_list_typecheckt::stl_labels
stl_labelst stl_labels
Data structure that contains data about the labels of the current module.
Definition: statement_list_typecheck.h:146
statement_list_typecheckt::stl_label_locationt
Holds information about the instruction and the nesting depth to which a label points.
Definition: statement_list_typecheck.h:118
statement_list_typecheckt::initialize_bit_expression
void initialize_bit_expression(const exprt &op)
Initializes the FC, RLO an OR bits for the scenario when a new boolean instruction was encontered.
Definition: statement_list_typecheck.cpp:1802
statement_list_parse_treet::tags
std::vector< symbol_exprt > tags
List of tags that were included in the source.
Definition: statement_list_parse_tree.h:177
statement_list_typecheckt::clear_network_state
void clear_network_state()
Modifies the state of the typecheck to resemble the beginning of a new network.
Definition: statement_list_typecheck.cpp:1809
symbolt
Symbol table entry.
Definition: symbol.h:27
statement_list_typecheckt::typecheck_function_call_arguments
exprt typecheck_function_call_arguments(const std::vector< code_frontend_assignt > &assignments, const code_typet::parametert &param, const symbolt &tia_element)
Checks if the given parameter is inside of the assignment list of a function call and returns the exp...
Definition: statement_list_typecheck.cpp:1708
statement_list_typecheckt::typecheck_statement_list_accu_dint_div
void typecheck_statement_list_accu_dint_div(const codet &op_code)
Performs a typecheck on a STL accumulator divide instruction for double integers.
Definition: statement_list_typecheck.cpp:804
statement_list_typecheckt::typecheck_statement_list_nested_xor
void typecheck_statement_list_nested_xor(const codet &op_code)
Performs a typecheck on a nested XOR instruction.
Definition: statement_list_typecheck.cpp:1135
binary_relation_exprt
A base class for relations, i.e., binary predicates whose two operands have the same type.
Definition: std_expr.h:706
statement_list_typecheckt::typecheck_statement_list_jump_conditional_not
void typecheck_statement_list_jump_conditional_not(const codet &op_code, symbolt &tia_element)
Performs a typecheck on a inverted conditional jump instruction (JCN) and adds it to the given symbol...
Definition: statement_list_typecheck.cpp:1335
code_typet::parametert::get_identifier
const irep_idt & get_identifier() const
Definition: std_types.h:590
code_typet::parametert
Definition: std_types.h:555
exprt::add_to_operands
void add_to_operands(const exprt &expr)
Add the given argument to the end of exprt's operands.
Definition: expr.h:162
symbolt::is_static_lifetime
bool is_static_lifetime
Definition: symbol.h:65
statement_list_typecheckt::typecheck_label_references
void typecheck_label_references()
Checks if all jumps reference labels that exist.
Definition: statement_list_typecheck.cpp:360
create_data_block_parameter
static code_typet::parametert create_data_block_parameter(const struct_typet &data_block_type, const irep_idt &function_block_name)
Creates the artificial data block parameter with a generic name and the specified type.
Definition: statement_list_typecheck.cpp:69
type_symbolt
Symbol table entry describing a data type.
Definition: symbol.h:132
statement_list_typecheckt::typecheck_statement_list_accu_dint_mul
void typecheck_statement_list_accu_dint_mul(const codet &op_code)
Performs a typecheck on a STL accumulator divide instruction for double integers.
Definition: statement_list_typecheck.cpp:791
statement_list_typecheckt::typecheck_statement_list_accu_dint_lt
void typecheck_statement_list_accu_dint_lt(const codet &op_code)
Performs a typecheck on a STL accumulator less than comparison instruction for double integers.
Definition: statement_list_typecheck.cpp:831
statement_list_typecheckt::nesting_stack_entryt
Every time branching occurs inside of a boolean expression string in STL, the current value of the RL...
Definition: statement_list_typecheck.h:97
type_with_subtypet::subtype
const typet & subtype() const
Definition: type.h:172
code_typet::return_type
const typet & return_type() const
Definition: std_types.h:645
statement_list_typecheckt::typecheck_statement_list_xor
void typecheck_statement_list_xor(const codet &op_code, const symbolt &tia_element)
Performs a typecheck on a STL boolean XOR instruction.
Definition: statement_list_typecheck.cpp:1051
statement_list_typecheckt::stl_label_locationt::stl_label_locationt
stl_label_locationt(size_t nesting_depth, bool jumps_permitted, bool fc_false_required)
Constructs a new location with the specified properties.
Definition: statement_list_typecheck.cpp:101
statement_list_typecheckt::typecheck_simple_boolean_instruction_operand
exprt typecheck_simple_boolean_instruction_operand(const codet &op_code, const symbolt &tia_element, bool negate)
Performs a typecheck on the operand of a not nested boolean instruction and returns the result.
Definition: statement_list_typecheck.cpp:1518
statement_list_typecheckt::typecheck_statement_list_accu_real_lte
void typecheck_statement_list_accu_real_lte(const codet &op_code)
Performs a typecheck on a STL accumulator less than or equal comparison instruction for integers.
Definition: statement_list_typecheck.cpp:939
statement_list_typecheckt::typecheck_statement_list_and
void typecheck_statement_list_and(const codet &op_code, const symbolt &tia_element)
Performs a typecheck on a STL boolean And instruction.
Definition: statement_list_typecheck.cpp:961
statement_list_typecheckt::typecheck_jump_locations
void typecheck_jump_locations(const code_labelt &label, const stl_label_locationt &location)
Performs a typecheck on all references for the given label.
Definition: statement_list_typecheck.cpp:598
can_cast_expr< constant_exprt >
bool can_cast_expr< constant_exprt >(const exprt &base)
Definition: std_expr.h:2976
exprt::operands
operandst & operands()
Definition: expr.h:94
parameter_symbolt
Symbol table entry of function parameter.
Definition: symbol.h:170
codet::op1
exprt & op1()
Definition: expr.h:128
statement_list_typecheckt::typecheck_statement_list_accu_int_div
void typecheck_statement_list_accu_int_div(const codet &op_code)
Performs a typecheck on a STL accumulator divide instruction for integers.
Definition: statement_list_typecheck.cpp:710
typecheckt
Definition: typecheck.h:15
STL_INT_WIDTH
#define STL_INT_WIDTH
Definition: statement_list_types.h:15
statement_list_parse_treet::tia_modulet::var_inout
var_declarationst var_inout
Inout variable declarations.
Definition: statement_list_parse_tree.h:89
symbol_table.h
Author: Diffblue Ltd.
pointer_typet
The pointer type These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (they ...
Definition: pointer_expr.h:23
statement_list_parse_treet::functiont
Structure for a simple function in Statement List.
Definition: statement_list_parse_tree.h:127
code_assignt
A goto_instruction_codet representing an assignment in the program.
Definition: goto_instruction_code.h:22
message.h
statement_list_parse_treet::tia_modulet::var_output
var_declarationst var_output
Output variable declarations.
Definition: statement_list_parse_tree.h:91
true_exprt
The Boolean constant true.
Definition: std_expr.h:3007
codet::get_statement
const irep_idt & get_statement() const
Definition: std_code_base.h:65
statement_list_typecheckt::accumulator
std::vector< exprt > accumulator
Representation of the accumulator of a TIA element.
Definition: statement_list_typecheck.h:75
symbolt::module
irep_idt module
Name of module the symbol belongs to.
Definition: symbol.h:43
statement_list_typecheckt::typecheck_statement_list_jump_unconditional
void typecheck_statement_list_jump_unconditional(const codet &op_code, symbolt &tia_element)
Performs a typecheck on an unconditional jump instruction (JU) and adds the jump to the given symbol.
Definition: statement_list_typecheck.cpp:1304
typecheckt::typecheck_main
virtual bool typecheck_main()
Definition: typecheck.cpp:14
CPROVER_ASSERT
#define CPROVER_ASSERT
Name of the CBMC assert function.
Definition: statement_list_typecheck.cpp:34
get_bool_type
bool_typet get_bool_type()
Creates a new type that resembles the 'Bool' type of the Siemens PLC languages.
Definition: statement_list_types.cpp:29
statement_list_typecheckt::clear_module_state
void clear_module_state()
Modifies the state of the typecheck to resemble the beginning of a new module.
Definition: statement_list_typecheck.cpp:1817
statement_list_typecheckt::typecheck_function_block_var_decls
void typecheck_function_block_var_decls(const statement_list_parse_treet::var_declarationst &var_decls, struct_union_typet::componentst &components, const irep_idt &var_property)
Performs a typecheck on a variable declaration list and saves the result to the given component eleme...
Definition: statement_list_typecheck.cpp:273
can_cast_type< floatbv_typet >
bool can_cast_type< floatbv_typet >(const typet &type)
Check whether a reference to a typet is a floatbv_typet.
Definition: bitvector_types.h:354
symbolt::name
irep_idt name
The unique identifier.
Definition: symbol.h:40
statement_list_parse_treet::functions
functionst functions
List of functions this parse tree includes.
Definition: statement_list_parse_tree.h:175
statement_list_typecheckt::add_to_or_rlo_wrapper
void add_to_or_rlo_wrapper(const exprt &op)
Adds the given expression to the operands of the Or expression that is saved in the RLO.
Definition: statement_list_typecheck.cpp:1782
to_and_expr
const and_exprt & to_and_expr(const exprt &expr)
Cast an exprt to a and_exprt.
Definition: std_expr.h:2118
statement_list_typecheckt::typecheck_nested_boolean_instruction
void typecheck_nested_boolean_instruction(const codet &op_code, const exprt &rlo_value)
Performs a typecheck on a STL instruction that initializes a new boolean nesting.
Definition: statement_list_typecheck.cpp:1502
statement_list_typecheckt::typecheck_statement_list_clr_rlo
void typecheck_statement_list_clr_rlo(const codet &op_code)
Performs a typecheck on a STL 'CLR' instruction and modifies the RLO, OR and FC bit.
Definition: statement_list_typecheck.cpp:1240
statement_list_typecheckt::typecheck_called_function
void typecheck_called_function(const codet &op_code, symbolt &tia_element)
Performs a typecheck on a call of a TIA function and saves the result to the given symbol.
Definition: statement_list_typecheck.cpp:1652
DATA_BLOCK_TYPE_POSTFIX
#define DATA_BLOCK_TYPE_POSTFIX
Postfix for the type of a data block.
Definition: statement_list_typecheck.cpp:32
statement_list_typecheckt
Class for encapsulating the current state of the type check.
Definition: statement_list_typecheck.h:39
statement_list_typecheckt::fc_bit
bool fc_bit
First Check (Part of the TIA status word).
Definition: statement_list_typecheck.h:86
DATA_BLOCK_PARAMETER_NAME
#define DATA_BLOCK_PARAMETER_NAME
Artificial name for the data block interface of a function block.
Definition: statement_list_typecheck.cpp:30
statement_list_types.h
statement_list_typecheckt::typecheck_function_call_argument_rhs
exprt typecheck_function_call_argument_rhs(const symbolt &tia_element, const exprt &rhs)
Checks if the given assigned expression is a variable or a constant and returns the typechecked versi...
Definition: statement_list_typecheck.cpp:1739
codet
Data structure for representing an arbitrary statement in a program.
Definition: std_code_base.h:28
statement_list_typecheckt::or_bit
bool or_bit
Or (Part of the TIA status word).
Definition: statement_list_typecheck.h:91
not_exprt
Boolean negation.
Definition: std_expr.h:2277
statement_list_typecheckt::typecheck_statement_list_accu_dint_add
void typecheck_statement_list_accu_dint_add(const codet &op_code)
Performs a typecheck on a STL accumulator add instruction for double integers.
Definition: statement_list_typecheck.cpp:765