void infer_output_taint()

in source/Transfer.cpp [1299:1353]


void infer_output_taint(
    MethodContext* context,
    Root root,
    const TaintTree& taint) {
  for (const auto& [path, sources] : taint.elements()) {
    auto partitioned_by_artificial_sources = sources.partition_by_kind<bool>(
        [&](const Kind* kind) { return kind == Kinds::artificial_source(); });

    auto real_sources = partitioned_by_artificial_sources.find(false);
    if (real_sources != partitioned_by_artificial_sources.end()) {
      for (const auto& source : real_sources->second) {
        auto generation = source;
        generation.add_inferred_features(FeatureMayAlwaysSet::make_always(
            context->model.attach_to_sources(root)));
        auto port = AccessPath(root, path);
        LOG_OR_DUMP(
            context,
            4,
            "Inferred generation for port {}: {}",
            port,
            generation);
        context->model.add_inferred_generations(
            std::move(port), Taint{std::move(generation)});
      }
    }

    auto artificial_sources = partitioned_by_artificial_sources.find(true);
    if (artificial_sources != partitioned_by_artificial_sources.end()) {
      for (const auto& source : artificial_sources->second) {
        for (const auto& artificial_source : source) {
          if (artificial_source.callee_port().root() != root) {
            const auto& input = artificial_source.callee_port();
            auto output = AccessPath(root, path);
            auto features = artificial_source.features();
            features.add_always(
                context->model.attach_to_propagations(input.root()));
            features.add_always(context->model.attach_to_propagations(root));
            auto propagation = Propagation(
                input,
                /* inferred_features */ features,
                /* user_features */ FeatureSet::bottom());
            LOG_OR_DUMP(
                context,
                4,
                "Inferred propagation {} to {}",
                propagation,
                output);
            context->model.add_inferred_propagation(
                std::move(propagation), std::move(output));
          }
        }
      }
    }
  }
}