in source/Model.cpp [335:402]
void Model::collapse_invalid_paths(Context& context) {
if (!method_) {
return;
}
using FieldTypesAccumulator = std::unordered_set<const DexType*>;
auto is_valid = [this, &context](
const FieldTypesAccumulator& previous_field_types,
Path::Element field) {
FieldTypesAccumulator current_field_types;
for (const auto* previous_field_type : previous_field_types) {
if (previous_field_type == type::java_lang_Object()) {
// Object is too generic to determine the set of possible field names.
continue;
}
const auto& cached_types =
context.field_cache->field_types(previous_field_type, field);
current_field_types.insert(cached_types.begin(), cached_types.end());
}
if (current_field_types.empty()) {
LOG(5,
"Model for method `{}` has invalid path element `{}`",
show(method_),
show(field));
return std::make_pair(false, current_field_types);
}
return std::make_pair(true, current_field_types);
};
auto initial_accumulator = [this](const Root& root) {
// Leaf ports appear in callee ports. This only applies to caller ports.
mt_assert(!root.is_leaf_port());
DexType* MT_NULLABLE root_type = nullptr;
if (root.is_argument()) {
root_type = method_->parameter_type(root.parameter_position());
} else if (root.is_return()) {
root_type = method_->return_type();
}
if (root_type == nullptr) {
// This can happen when there is an invalid model, e.g. model defined
// on an argument that does not exist, usually from a model-generator.
// Returning an empty list of types will collapse all paths.
ERROR(
1,
"Could not find root type for method `{}`, root: `{}`",
show(method_),
show(root));
return FieldTypesAccumulator{};
}
return FieldTypesAccumulator{root_type};
};
generations_.collapse_invalid_paths<FieldTypesAccumulator>(
is_valid, initial_accumulator);
parameter_sources_.collapse_invalid_paths<FieldTypesAccumulator>(
is_valid, initial_accumulator);
sinks_.collapse_invalid_paths<FieldTypesAccumulator>(
is_valid, initial_accumulator);
propagations_.collapse_invalid_paths<FieldTypesAccumulator>(
is_valid, initial_accumulator);
}