module AdLint::Cc1::NegativePathsTracing

Public Instance Methods

trace_negative_paths(report, loc, traced) click to toggle source
# File lib/adlint/cc1/trace.rb, line 61
def trace_negative_paths(report, loc, traced)
  trans = traceable_negative_contribs.map { |mval| mval.transition }
  branches = trans.map { |tr| tr.last.tag.at }.flatten
  sorted_branches = sort_branches_by_groups(branches)
  branches = branches.to_set

  rch_groups = []
  unr_groups = []

  sorted_branches.each_key.with_object([]) { |gr, msgs|
    case
    when gr.branches_to_trunk.any? { |upper| branches.include?(upper) }
      next
    when gr.complete? && gr.branches.size == sorted_branches[gr].size
      unr_groups.push(gr)
    else
      rch_groups.push(gr)
      sorted_branches[gr].each do |br|
        emit_negative_ctrlexpr(msgs, report, loc, traced, br.ctrlexpr)
      end
    end
  } + emit_remaining_paths(report, loc, traced, rch_groups, unr_groups)
end

Private Instance Methods

emit_negative_ctrlexpr(msgs, report, loc, traced, ctrlexpr) click to toggle source
# File lib/adlint/cc1/trace.rb, line 122
def emit_negative_ctrlexpr(msgs, report, loc, traced, ctrlexpr)
  if ctrlexpr and expr = ctrlexpr.to_expr
    if expr.location && expr.location < loc && !traced.include?(expr)
      msgs.push(report.C(:C1002, expr.location))
      traced.add(expr)
    end
  end
end
emit_positive_ctrlexpr(msgs, report, loc, traced, ctrlexpr) click to toggle source
# File lib/adlint/cc1/trace.rb, line 113
def emit_positive_ctrlexpr(msgs, report, loc, traced, ctrlexpr)
  if ctrlexpr and expr = ctrlexpr.to_expr
    if expr.location && expr.location < loc && !traced.include?(expr)
      msgs.push(report.C(:C1001, expr.location))
      traced.add(expr)
    end
  end
end
emit_remaining_paths(report, loc, traced, rch_groups, unr_groups) click to toggle source
# File lib/adlint/cc1/trace.rb, line 86
def emit_remaining_paths(report, loc, traced, rch_groups, unr_groups)
  traced_groups = Set.new
  rch_groups.each_with_object([]) { |gr, msgs|
    cur_br = gr.trunk
    while cur_br
      emit_positive_ctrlexpr(msgs, report, loc, traced, cur_br.ctrlexpr)
      traced_groups.add(cur_br.group)
      cur_br = cur_br.trunk
    end
  } + unr_groups.each_with_object([]) { |gr, msgs|
    cur_br = gr.trunk
    while cur_br
      unless traced_groups.include?(cur_br.group)
        emit_negative_ctrlexpr(msgs, report, loc, traced, cur_br.ctrlexpr)
        break
      end
      cur_br = cur_br.trunk
    end
  }
end
sort_branches_by_groups(branches) click to toggle source
# File lib/adlint/cc1/trace.rb, line 107
def sort_branches_by_groups(branches)
  branches.each_with_object(Hash.new { |h, k| h[k] = [] }) do |br, groups|
    groups[br.group].push(br)
  end
end