class AdLint::Exam::CBuiltin::W0043

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 1095
def initialize(phase_ctxt)
  super
  trav = phase_ctxt[:cc1_ast_traversal]
  trav.enter_variable_definition += T(:enter_variable_definition)
end

Private Instance Methods

check_flattened(ary_type, inits, parent_init) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 1138
def check_flattened(ary_type, inits, parent_init)
  unless total_length = total_length(ary_type)
    # NOTE: Cannot check the incomplete array.
    return
  end

  flattener = lambda { |init|
    init.expression || init.initializers.map(&flattener)
  }
  exprs = inits.map { |init| flattener.call(init) }.flatten.compact

  if !exprs.empty? && exprs.size < total_length
    if exprs.size == 1 and fst = exprs.first
      if fst.kind_of?(Cc1::ObjectSpecifier) && fst.constant.value != "0"
        warn(fst, parent_init)
      end
    else
      warn(exprs.first, parent_init)
    end
  end
end
check_well_balanced(ary_type, inits, parent_init) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 1115
def check_well_balanced(ary_type, inits, parent_init)
  return unless ary_type.length

  if !inits.empty? && inits.size < ary_type.length
    if inits.size == 1 and expr = inits.first.expression
      unless expr.kind_of?(Cc1::ConstantSpecifier) &&
          expr.constant.value == "0"
        warn(expr, parent_init)
      end
    else
      warn(inits.first, parent_init)
    end
  end

  if ary_type.base_type.array?
    inits.each do |init|
      if init.initializers
        check_well_balanced(ary_type.base_type, init.initializers, init)
      end
    end
  end
end
enter_variable_definition(node) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 1102
def enter_variable_definition(node)
  return unless node.initializer
  return unless node.type.array?

  if inits = node.initializer.initializers
    if initializer_depth(node.initializer) == type_depth(node.type)
      check_well_balanced(node.type, inits, node.initializer)
    else
      check_flattened(node.type, inits, node.initializer)
    end
  end
end
initializer_depth(init) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 1168
def initializer_depth(init)
  if inits = init.initializers
    1 + inits.map { |i| initializer_depth(i) }.max
  else
    0
  end
end
total_length(ary_type) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 1188
def total_length(ary_type)
  total_len = 1
  type = ary_type
  while type.array?
    if type.length
      total_len *= type.length
      type = type.base_type
    else
      return nil
    end
  end
  total_len
end
type_depth(type) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 1176
def type_depth(type)
  case
  when type.array?
    1 + type_depth(type.base_type)
  when type.composite?
    type.members.empty? ?
      1 : 1 + type.members.map { |memb| type_depth(memb.type) }.max
  else
    0
  end
end
warn(node, parant_init) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 1160
def warn(node, parant_init)
  if parant_init
    W(parant_init.location)
  else
    W(node.location)
  end
end