in source/Interprocedural.cpp [107:169]
Model analyze(
Context& global_context,
const Registry& registry,
const Model& old_model) {
Timer timer;
Model model = old_model;
auto* method = model.method();
if (!method) {
return model;
}
auto method_context =
std::make_unique<MethodContext>(global_context, registry, model);
LOG_OR_DUMP(
method_context, 3, "Analyzing `\033[33m{}\033[0m`...", method->show());
auto* code = method->get_code();
if (!code) {
throw std::runtime_error(fmt::format(
"Attempting to analyze method `{}` with no code!", method->show()));
}
if (!code->cfg_built()) {
throw std::runtime_error(fmt::format(
"Attempting to analyze method `{}` with no control flow graph!",
method->show()));
} else {
LOG_OR_DUMP(
method_context, 4, "Code:\n{}", show_control_flow_graph(code->cfg()));
}
auto fixpoint =
FixpointIterator(code->cfg(), CombinedTransfer(method_context.get()));
fixpoint.run(AnalysisEnvironment::initial());
model.collapse_invalid_paths(global_context);
model.approximate();
LOG_OR_DUMP(
method_context, 4, "Computed model for `{}`: {}", method->show(), model);
global_context.statistics->log_time(method, timer);
auto duration = timer.duration_in_seconds();
if (duration > 10.0) {
WARNING(1, "Analyzing `{}` took {:.2f}s!", method->show(), duration);
}
auto slow_method_bound =
global_context.options->maximum_method_analysis_time();
if (slow_method_bound && *slow_method_bound <= duration) {
LOG(1,
"Analyzing `{}` took {:.2f}s, setting default taint-in-taint-out.",
method->show(),
duration);
model.add_mode(Model::Mode::AddViaObscureFeature, global_context);
model.add_mode(Model::Mode::SkipAnalysis, global_context);
model.add_mode(Model::Mode::NoJoinVirtualOverrides, global_context);
model.add_mode(Model::Mode::TaintInTaintOut, global_context);
model.add_mode(Model::Mode::TaintInTaintThis, global_context);
}
return model;
}