class AdLint::Cc1::ExpressionInterpreter

Public Class Methods

new(owner) click to toggle source
Calls superclass method AdLint::Cc1::SubInterpreter::new
# File lib/adlint/cc1/interp.rb, line 1665
def initialize(owner)
  super(owner, Expression)
end

Private Class Methods

def_eval_with_sequence_point(method_name) click to toggle source
# File lib/adlint/cc1/interp.rb, line 1669
    def self.def_eval_with_sequence_point(method_name)
      class_eval <<-EOS
        def #{method_name}(node)
          super
        ensure
          if seqp = node.subsequent_sequence_point
            notify_sequence_point_reached(seqp)
          end
        end
      EOS
    end

Public Instance Methods

unify_then_and_else_var(then_var, else_var) click to toggle source
# File lib/adlint/cc1/interp.rb, line 1777
def unify_then_and_else_var(then_var, else_var)
  if then_var.type.pointer? || else_var.type.pointer?
    case
    when pointee_of(then_var)
      return then_var
    when pointee_of(else_var)
      return else_var
    end
  end
  create_tmpvar(then_var.type,
                then_var.value.single_value_unified_with(else_var.value))
end
visit_conditional_expression(node) click to toggle source
# File lib/adlint/cc1/interp.rb, line 1721
def visit_conditional_expression(node)
  checkpoint(node.location)

  ctrlexpr = node.condition
  ctrlexpr_obj = interpret(ctrlexpr)
  ctrlexpr_var = object_to_variable(ctrlexpr_obj, ctrlexpr)
  ctrlexpr_val = value_of(ctrlexpr_var)
  notify_variable_value_referred(ctrlexpr, ctrlexpr_var)
  notify_sequence_point_reached(ctrlexpr.subsequent_sequence_point)
  ctrlexpr = ctrlexpr.to_normalized_logical

  then_var = nil
  if ctrlexpr_val.test_may_be_true.true?
    branched_eval(ctrlexpr, NARROWING, IMPLICIT_COND) do
      then_var = object_to_variable(interpret(node.then_expression),
                                    node.then_expression)
    end
  end

  else_var = nil
  if ctrlexpr_val.test_may_be_false.true?
    branched_eval(nil, NARROWING, FINAL, COMPLETE) do
      else_var = object_to_variable(interpret(node.else_expression),
                                    node.else_expression)
    end
  else
    branched_eval(nil, NARROWING, FINAL, COMPLETE) {}
  end

  case
  when then_var && else_var
    rslt_var = unify_then_and_else_var(then_var, else_var)
    # FIXME: Not to over-warn about discarding a function return value.
    #        Because the unified result is a new temporary variable, it is
    #        impossible to relate a reference of the unified result and a
    #        reference of the 2nd or 3rd expression's value.
    notify_variable_value_referred(node, then_var)
    notify_variable_value_referred(node, else_var)
  when then_var
    rslt_var = then_var
  when else_var
    rslt_var = else_var
  else
    # FIXME: Nevertheless, the then-expression is not reachable, the branch
    #        execution check may fail in evaluation of the else branch.
    rslt_var = create_tmpvar
  end

  notify_conditional_expr_evaled(node, ctrlexpr_var, rslt_var)
  rslt_var
ensure
  if seqp = node.subsequent_sequence_point
    notify_sequence_point_reached(seqp)
  end
end