module AdLint::Cc1::Conversion

Public Instance Methods

do_conversion(orig_var, to_type) click to toggle source

NOTE: Host class of this module must include InterpreterMediator.

# File lib/adlint/cc1/conv.rb, line 38
def do_conversion(orig_var, to_type)
  if orig_var.type.coercible?(to_type)
    # NOTE: Value will be coerced into the destination type in
    #       VariableTableMediator#create_tmpvar.
    create_tmpvar(to_type, wrap_around_value(orig_var, to_type))
  else
    nil
  end
end
do_default_argument_promotion(orig_var) click to toggle source
# File lib/adlint/cc1/conv.rb, line 81
def do_default_argument_promotion(orig_var)
  promoted_type = orig_var.type.argument_promoted_type
  if orig_var.type.same_as?(promoted_type)
    orig_var
  else
    do_conversion(orig_var, promoted_type) || orig_var
  end
end
do_integer_promotion(orig_var) click to toggle source
# File lib/adlint/cc1/conv.rb, line 48
def do_integer_promotion(orig_var)
  return orig_var unless orig_var.type.integer?

  promoted_type = orig_var.type.integer_promoted_type
  if orig_var.type.same_as?(promoted_type)
    orig_var
  else
    do_conversion(orig_var, promoted_type) || orig_var
  end
end
do_usual_arithmetic_conversion(lhs_orig, rhs_orig) click to toggle source
# File lib/adlint/cc1/conv.rb, line 59
def do_usual_arithmetic_conversion(lhs_orig, rhs_orig)
  if lhs_orig.type.pointer? && rhs_orig.type.pointer?
    return lhs_orig, rhs_orig
  end

  arith_type = lhs_orig.type.arithmetic_type_with(rhs_orig.type)

  if lhs_orig.type.same_as?(arith_type)
    lhs_conved = lhs_orig
  else
    lhs_conved = do_conversion(lhs_orig, arith_type) || lhs_orig
  end

  if rhs_orig.type.same_as?(arith_type)
    rhs_conved = rhs_orig
  else
    rhs_conved = do_conversion(rhs_orig, arith_type) || rhs_orig
  end

  return lhs_conved, rhs_conved
end
untyped_pointer_conversion?(from_type, to_type, from_val) click to toggle source
# File lib/adlint/cc1/conv.rb, line 90
def untyped_pointer_conversion?(from_type, to_type, from_val)
  return false unless to_type.pointer?

  # NOTE: Untyped pointer conversion is defined as below;
  #
  #           from_type     |     to_type      |      result
  #       ------------------+------------------+-----------------
  #        void pointer     | void pointer     | true
  #        void pointer     | non-void pointer | true
  #        non-void pointer | void pointer     | true
  #        non-void pointer | non-void pointer | false
  #        non-enum integer | void pointer     | from_val == 0
  #        non-enum integer | non-void pointer | from_val == 0
  #        enum             | void pointer     | false
  #        enum             | non-void pointer | false
  #        other            | void pointer     | true
  #        other            | non-void pointer | false
  case
  when from_type.pointer?
    void_pointer?(from_type) || void_pointer?(to_type)
  when from_type.integer?
    !from_type.enum? && from_val.test_must_be_null.true?
  else
    void_pointer?(to_type)
  end
end

Private Instance Methods

void_pointer?(type) click to toggle source
# File lib/adlint/cc1/conv.rb, line 137
def void_pointer?(type)
  unqual_type = type.unqualify
  unqual_type.pointer? && unqual_type.base_type.void?
end
wrap_around_value(orig_var, to_type) click to toggle source
# File lib/adlint/cc1/conv.rb, line 118
def wrap_around_value(orig_var, to_type)
  return orig_var.value unless orig_var.type.scalar? && to_type.scalar?

  case
  when orig_var.type.signed? && to_type.unsigned?
    min_val = scalar_value_of(to_type.min)
    if (orig_var.value < min_val).test_may_be_true.true?
      return min_val - orig_var.value + scalar_value_of(1)
    end
  when orig_var.type.unsigned? && to_type.signed?
    max_val = scalar_value_of(to_type.max)
    if (orig_var.value > max_val).test_may_be_true.true?
      return max_val - orig_var.value + scalar_value_of(1)
    end
  end

  orig_var.value
end