in source/Transfer.cpp [880:933]
bool Transfer::analyze_invoke(
MethodContext* context,
const IRInstruction* instruction,
AnalysisEnvironment* environment) {
log_instruction(context, instruction);
auto callee = get_callee(context, environment, instruction);
const AnalysisEnvironment previous_environment = *environment;
TaintTree result_taint;
check_flows(context, &previous_environment, instruction, callee);
apply_propagations(
context,
&previous_environment,
environment,
instruction,
callee,
result_taint);
apply_generations(context, environment, instruction, callee, result_taint);
if (callee.resolved_base_method &&
callee.resolved_base_method->returns_void()) {
LOG_OR_DUMP(context, 4, "Resetting the result register");
environment->assign(k_result_register, MemoryLocationsDomain::bottom());
} else if (
auto* memory_location =
try_inline_invoke(context, environment, instruction, callee)) {
LOG_OR_DUMP(
context, 4, "Setting result register to {}", show(memory_location));
environment->assign(k_result_register, memory_location);
} else {
// Check if the method can alias existing memory location
memory_location =
try_alias_this_location(context, environment, callee, instruction);
// Assume the method call returns a new memory location,
// that does not alias with anything.
if (memory_location == nullptr) {
memory_location = context->memory_factory.make_location(instruction);
}
LOG_OR_DUMP(
context, 4, "Setting result register to {}", show(memory_location));
environment->assign(k_result_register, memory_location);
LOG_OR_DUMP(
context, 4, "Tainting {} with {}", show(memory_location), result_taint);
environment->write(memory_location, result_taint, UpdateKind::Weak);
}
analyze_artificial_calls(context, instruction, environment);
return false;
}