CBMC
Loading...
Searching...
No Matches
lift_clinit_calls.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Static initializer call lifting
4
5Author: Diffblue Ltd.
6
7\*******************************************************************/
8
10
11#include "lift_clinit_calls.h"
12
14
16
17#include <util/expr_iterator.h>
18
19#include <algorithm>
20
22{
23 // 1. Gather any clinit calls present in `input`:
24 std::vector<symbol_exprt> clinit_wrappers_called;
25
26 for(auto it = input.depth_begin(), itend = input.depth_end(); it != itend;
27 ++it)
28 {
29 if(const auto code = expr_try_dynamic_cast<codet>(*it))
30 {
31 if(code->get_statement() == ID_function_call)
32 {
33 if(
35 to_code_function_call(*code).function()))
36 {
37 if(is_clinit_wrapper_function(callee->get_identifier()))
38 {
40 // Replace call with skip:
41 it.mutate() = code_skipt();
42 }
43 }
44 }
45 }
46 }
47
48 if(clinit_wrappers_called.empty())
49 return input;
50
51 // 2. Unique, such that each clinit method is only called once:
52 std::sort(clinit_wrappers_called.begin(), clinit_wrappers_called.end());
53 auto delete_after =
54 std::unique(clinit_wrappers_called.begin(), clinit_wrappers_called.end());
56
57 // 3. Lift static init calls to top of function:
58 code_blockt result;
59 for(const auto &callee : clinit_wrappers_called)
60 {
62 // Nuke the source location, now that the call doesn't really relate to any
63 // one particular line:
64 new_call.function().drop_source_location();
65 result.add(new_call);
66 }
67
68 result.add(std::move(input));
69
70 return std::move(result);
71}
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
A codet representing sequential composition of program statements.
Definition std_code.h:130
void add(const codet &code)
Definition std_code.h:168
goto_instruction_codet representation of a function call statement.
A codet representing a skip statement.
Definition std_code.h:322
Data structure for representing an arbitrary statement in a program.
depth_iteratort depth_end()
Definition expr.cpp:249
depth_iteratort depth_begin()
Definition expr.cpp:247
Forward depth-first search iterators These iterators' copy operations are expensive,...
const code_function_callt & to_code_function_call(const goto_instruction_codet &code)
bool is_clinit_wrapper_function(const irep_idt &function_id)
Check if function_id is a clinit wrapper.
codet lift_clinit_calls(codet input)
file Static initializer call lifting