in source/Model.cpp [251:333]
Model Model::at_callsite(
const Method* caller,
const Position* call_position,
Context& context,
const std::vector<const DexType * MT_NULLABLE>& source_register_types,
const std::vector<std::optional<std::string>>& source_constant_arguments)
const {
const auto* callee = method_;
Model model;
model.modes_ = modes_;
auto maximum_source_sink_distance =
context.options->maximum_source_sink_distance();
// Add special features that cannot be done in model generators.
mt_assert(context.features != nullptr);
auto extra_features = context.class_properties->propagate_features(
caller, callee, *context.features);
generations_.visit(
[&model,
caller,
callee,
call_position,
maximum_source_sink_distance,
&extra_features,
&context,
&source_register_types,
&source_constant_arguments](
const AccessPath& callee_port, const Taint& generations) {
model.generations_.write(
callee_port,
generations.propagate(
caller,
callee,
callee_port,
call_position,
maximum_source_sink_distance,
extra_features,
context,
source_register_types,
source_constant_arguments),
UpdateKind::Weak);
});
sinks_.visit([&model,
caller,
callee,
call_position,
maximum_source_sink_distance,
&extra_features,
&context,
&source_register_types,
&source_constant_arguments](
const AccessPath& callee_port, const Taint& sinks) {
model.sinks_.write(
callee_port,
sinks.propagate(
caller,
callee,
callee_port,
call_position,
maximum_source_sink_distance,
extra_features,
context,
source_register_types,
source_constant_arguments),
UpdateKind::Weak);
});
model.propagations_ = propagations_;
model.add_features_to_arguments_ = add_features_to_arguments_;
model.inline_as_ = inline_as_;
if (inline_as_.is_bottom()) {
// This is bottom when the method was never analyzed.
// Set it to top to be sound when joining models.
model.inline_as_.set_to_top();
}
return model;
}