class AdLint::Cc1::LogicalAnd

Public Class Methods

new(manip, node, lhs_manip, rhs_manip) click to toggle source
Calls superclass method AdLint::Cc1::ValueDomainNarrowing::new
# File lib/adlint/cc1/ctrlexpr.rb, line 772
def initialize(manip, node, lhs_manip, rhs_manip)
  super
  @lhs_manip = lhs_manip
  @rhs_manip = rhs_manip
end

Private Instance Methods

do_narrowing() click to toggle source
# File lib/adlint/cc1/ctrlexpr.rb, line 779
def do_narrowing
  @lhs_manip.execute!
  @lhs_manip.ensure_result_equal_to(scalar_value_of_true)
  lhs_var = object_to_variable(@lhs_manip.result, @node.lhs_operand)

  # NOTE: The ISO C99 standard says;
  #
  # 6.5.13 Logical AND operator
  #
  # Semantics
  #
  # 4 Unlike the bitwise binary & operator, the && operator guarantees
  #   left-to-right evaluation; there is a sequence point after the
  #   evaluation of the first operand.  If the first operand compares equal
  #   to 0, the second operand is not evaluated.
  notify_sequence_point_reached(SequencePoint.new(@node.lhs_operand))

  # TODO: Must look about the short-circuit evaluation.
  @rhs_manip.load_original_values!(@lhs_manip)
  @rhs_manip.execute!
  @rhs_manip.ensure_result_equal_to(scalar_value_of_true)
  rhs_var = object_to_variable(@rhs_manip.result, @node.rhs_operand)

  notify_sequence_point_reached(SequencePoint.new(@node.rhs_operand))

  narrowing_merge!(@lhs_manip, @rhs_manip)
  notify_variable_value_referred(@node, lhs_var)
  notify_variable_value_referred(@node, rhs_var)

  unless lhs_var.type.scalar? && rhs_var.type.scalar?
    return create_tmpvar(int_t)
  end

  unless lhs_var.value.scalar? && rhs_var.value.scalar?
    return create_tmpvar(int_t)
  end

  lhs_conved, rhs_conved =
    do_logical_arithmetic_conversion(@node, lhs_var, rhs_var)

  lhs_val = lhs_conved.value
  rhs_val = rhs_conved.value

  rslt_var = create_tmpvar(int_t, lhs_val.logical_and(rhs_val))
  notify_logical_and_expr_evaled(@node, lhs_conved, rhs_conved, rslt_var)
  rslt_var
end