class AdLint::Exam::CBuiltin::W0103

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 2399
def initialize(phase_ctxt)
  super
  @interp = phase_ctxt[:cc1_interpreter]
  @interp.on_function_started   += T(:start_function)
  @interp.on_function_ended     += T(:end_function)
  @interp.on_variable_defined   += T(:add_local_variable)
  @interp.on_parameter_defined  += T(:add_local_variable)
  @interp.on_return_stmt_evaled += T(:check_return_statement)
  @lvars = nil
end

Private Instance Methods

add_local_variable(*, var) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 2419
def add_local_variable(*, var)
  return unless var.binding.memory.dynamic?

  if @lvars && var.named?
    @lvars.add(var.name)
  end
end
check_return_statement(ret_stmt, ret_var) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 2427
def check_return_statement(ret_stmt, ret_var)
  return unless @lvars
  return unless ret_var && ret_var.type.pointer?

  if pointee = pointee_of(ret_var)
    if pointee.variable? && pointee.named?
      # NOTE: An array typed parameter can be considered as an alias of the
      #       corresponding argument.  So, it is safe to return an address
      #       of the argument.
      return if pointee.type.parameter? && pointee.type.array?
      if @lvars.include?(pointee.name)
        W(ret_stmt.location)
      end
    end
  end
end
end_function(*) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 2415
def end_function(*)
  @lvars = nil
end
interpreter() click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 2444
def interpreter
  @interp
end
start_function(*) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 2411
def start_function(*)
  @lvars = Set.new
end