class AdLint::Exam::CBuiltin::W0708

Public Class Methods

new(phase_ctxt) click to toggle source
Calls superclass method AdLint::Examination::new
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 17101
def initialize(phase_ctxt)
  super
  @interp = phase_ctxt[:cc1_interpreter]
  @interp.on_for_stmt_started       += T(:enter_for_stmt)
  @interp.on_for_stmt_ended         += T(:leave_for_stmt)
  @interp.on_c99_for_stmt_started   += T(:enter_c99_for_stmt)
  @interp.on_c99_for_stmt_ended     += T(:leave_c99_for_stmt)
  @interp.on_variable_value_updated += T(:update_variable)
  @ctrl_var_stack = []
end

Private Instance Methods

contain_expr?(node, expr) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 17175
def contain_expr?(node, expr)
  node ? Visitor.new(expr).tap { |v| node.accept(v) }.result : false
end
deduct_ctrl_variable_name(node, inited_var_names) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 17149
def deduct_ctrl_variable_name(node, inited_var_names)
  var_names = inited_var_names + node.varying_variable_names
  histo = var_names.each_with_object({}) { |name, hash| hash[name] = 0 }

  ctrlexpr, * = node.deduct_controlling_expression
  collect_object_specifiers(ctrlexpr).map { |obj_spec|
    obj_spec.identifier.value
  }.each { |obj_name| histo.include?(obj_name) and histo[obj_name] += 1 }

  histo.to_a.sort { |a, b| b.last <=> a.last }.map(&:first).find do |name|
    var = variable_named(name) and !var.type.const?
  end
end
enter_c99_for_stmt(node) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 17127
def enter_c99_for_stmt(node)
  inited_var_names =
    collect_identifier_declarators(node.declaration).map { |id|
      id.identifier.value
    }
  if ctrl_var_name = deduct_ctrl_variable_name(node, inited_var_names)
    @ctrl_var_stack.push([ctrl_var_name, node])
  end
end
enter_for_stmt(node) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 17113
def enter_for_stmt(node)
  inited_var_names =
    collect_object_specifiers(node.initial_statement).map { |os|
      os.identifier.value
    }
  if ctrl_var_name = deduct_ctrl_variable_name(node, inited_var_names)
    @ctrl_var_stack.push([ctrl_var_name, node])
  end
end
in_ctrl_part(for_or_c99_for_stmt, expr) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 17163
def in_ctrl_part(for_or_c99_for_stmt, expr)
  case for_or_c99_for_stmt
  when Cc1::ForStatement
    contain_expr?(for_or_c99_for_stmt.initial_statement, expr)     ||
      contain_expr?(for_or_c99_for_stmt.condition_statement, expr) ||
      contain_expr?(for_or_c99_for_stmt.expression, expr)
  when Cc1::C99ForStatement
    contain_expr?(for_or_c99_for_stmt.condition_statement, expr) ||
      contain_expr?(for_or_c99_for_stmt.expression, expr)
  end
end
interpreter() click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 17179
def interpreter
  @interp
end
leave_c99_for_stmt(*) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 17137
def leave_c99_for_stmt(*)
  @ctrl_var_stack.pop
end
leave_for_stmt(*) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 17123
def leave_for_stmt(*)
  @ctrl_var_stack.pop
end
update_variable(expr, var) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 17141
def update_variable(expr, var)
  if var.named? and ctrl_vars = @ctrl_var_stack.last
    if ctrl_vars.first == var.name && !in_ctrl_part(ctrl_vars.last, expr)
      W(expr.location, var.name)
    end
  end
end