Class: AdLint::Cc1::ExpressionInterpreter

Inherits:
SubInterpreter show all
Includes:
BranchGroupOptions, BranchOptions, ExpressionEvaluator
Defined in:
lib/adlint/cc1/interp.rb

Constant Summary

Constants included from BranchGroupOptions

BranchGroupOptions::COMPLETE, BranchGroupOptions::ITERATION

Constants included from BranchOptions

BranchOptions::COMPLEMENTAL, BranchOptions::FINAL, BranchOptions::FIRST, BranchOptions::IMPLICIT_COND, BranchOptions::NARROWING, BranchOptions::SMOTHER_BREAK, BranchOptions::WIDENING

Constants included from InterpreterOptions

InterpreterOptions::QUIET, InterpreterOptions::WITHOUT_SIDE_EFFECTS

Instance Attribute Summary

Attributes inherited from SubInterpreter

#target_node_class

Instance Method Summary collapse

Methods included from ExpressionEvaluator

#visit_additive_expression, #visit_address_expression, #visit_alignof_expression, #visit_alignof_type_expression, #visit_and_expression, #visit_array_subscript_expression, #visit_bit_access_by_pointer_expression, #visit_bit_access_by_value_expression, #visit_cast_expression, #visit_comma_separated_expression, #visit_compound_assignment_expression, #visit_compound_literal_expression, #visit_constant_specifier, #visit_equality_expression, #visit_error_expression, #visit_exclusive_or_expression, #visit_function_call_expression, #visit_grouped_expression, #visit_inclusive_or_expression, #visit_indirection_expression, #visit_logical_and_expression, #visit_logical_or_expression, #visit_member_access_by_pointer_expression, #visit_member_access_by_value_expression, #visit_multiplicative_expression, #visit_null_constant_specifier, #visit_object_specifier, #visit_postfix_decrement_expression, #visit_postfix_increment_expression, #visit_prefix_decrement_expression, #visit_prefix_increment_expression, #visit_relational_expression, #visit_shift_expression, #visit_simple_assignment_expression, #visit_sizeof_expression, #visit_sizeof_type_expression, #visit_string_literal_specifier, #visit_unary_arithmetic_expression

Methods included from AdLint::Cc1::ExpressionEvaluator::Impl

#eval_additive_expr, #eval_address_expr, #eval_and_expr, #eval_array_subscript_expr, #eval_bit_access_by_pointer_expr, #eval_bit_access_by_value_expr, #eval_cast_expr, #eval_compound_assignment_expr, #eval_compound_literal_expr, #eval_equality_expr, #eval_exclusive_or_expr, #eval_function_call_expr, #eval_inclusive_or_expr, #eval_indirection_expr, #eval_member_access_by_pointer_expr, #eval_member_access_by_value_expr, #eval_multiplicative_expr, #eval_object_specifier, #eval_postfix_decrement_expr, #eval_postfix_increment_expr, #eval_prefix_decrement_expr, #eval_prefix_increment_expr, #eval_relational_expr, #eval_shift_expr, #eval_simple_assignment_expr, #eval_unary_arithmetic_expr

Methods included from Conversion

#do_conversion, #do_default_argument_promotion, #do_integer_promotion, #do_usual_arithmetic_conversion, #untyped_pointer_conversion?

Methods included from ConstantEvaluator

#eval_constant

Methods included from LogUtil

#log_debug, #log_error, #log_fatal, #log_info, #log_warn

Methods included from MonitorUtil

#checkpoint, #monitored_region

Methods included from InterpreterMediator

#constant_expression?, #current_branch, #interpret, #object_to_pointer, #object_to_variable, #pointer_value_of, #reset_environment, #scalar_value_of, #scalar_value_of_arbitrary, #scalar_value_of_false, #scalar_value_of_null, #scalar_value_of_true, #value_of

Methods included from InterpSyntaxBridge

#_interp_syntax_bridge_

Methods included from InterpObjectBridge

#_interp_object_bridge_

Methods included from ArithmeticAccessor

#arithmetic, #logical_right_shift?

Methods included from FunctionTableMediator

#declare_explicit_function, #declare_implicit_function, #define_anonymous_function, #define_explicit_function

Methods included from VariableTableMediator

#create_tmpvar, #local_variables

Methods included from MemoryPoolMediator

#pointee_of

Methods inherited from SyntaxTreeVisitor

#visit_abbreviated_function_declarator, #visit_additive_expression, #visit_address_expression, #visit_alignof_expression, #visit_alignof_type_expression, #visit_and_expression, #visit_ansi_function_declarator, #visit_ansi_function_definition, #visit_array_abstract_declarator, #visit_array_declarator, #visit_array_subscript_expression, #visit_bit_access_by_pointer_expression, #visit_bit_access_by_value_expression, #visit_break_statement, #visit_c99_for_statement, #visit_case_labeled_statement, #visit_cast_expression, #visit_comma_separated_expression, #visit_compound_assignment_expression, #visit_compound_literal_expression, #visit_compound_statement, #visit_constant_specifier, #visit_continue_statement, #visit_declaration, #visit_declaration_specifiers, #visit_default_labeled_statement, #visit_do_statement, #visit_enum_specifier, #visit_enum_type_declaration, #visit_enumerator, #visit_equality_expression, #visit_error_expression, #visit_error_statement, #visit_exclusive_or_expression, #visit_expression_statement, #visit_for_statement, #visit_function_abstract_declarator, #visit_function_call_expression, #visit_function_declaration, #visit_generic_labeled_statement, #visit_goto_statement, #visit_grouped_abstract_declarator, #visit_grouped_declarator, #visit_grouped_expression, #visit_identifier_declarator, #visit_if_else_statement, #visit_if_statement, #visit_inclusive_or_expression, #visit_indirection_expression, #visit_init_declarator, #visit_initializer, #visit_kandr_function_declarator, #visit_kandr_function_definition, #visit_logical_and_expression, #visit_logical_or_expression, #visit_member_access_by_pointer_expression, #visit_member_access_by_value_expression, #visit_member_declaration, #visit_multiplicative_expression, #visit_null_constant_specifier, #visit_object_specifier, #visit_parameter_declaration, #visit_parameter_definition, #visit_parameter_type_list, #visit_pointer_abstract_declarator, #visit_postfix_decrement_expression, #visit_postfix_increment_expression, #visit_prefix_decrement_expression, #visit_prefix_increment_expression, #visit_relational_expression, #visit_return_statement, #visit_shift_expression, #visit_simple_assignment_expression, #visit_sizeof_expression, #visit_sizeof_type_expression, #visit_specifier_qualifier_list, #visit_standard_type_specifier, #visit_string_literal_specifier, #visit_struct_declaration, #visit_struct_declarator, #visit_struct_specifier, #visit_struct_type_declaration, #visit_switch_statement, #visit_translation_unit, #visit_type_name, #visit_typedef_declaration, #visit_typedef_type_specifier, #visit_typeof_type_specifier, #visit_unary_arithmetic_expression, #visit_union_specifier, #visit_union_type_declaration, #visit_variable_declaration, #visit_variable_definition, #visit_while_statement

Constructor Details

#initialize(owner) ⇒ ExpressionInterpreter

Returns a new instance of ExpressionInterpreter.



1665
1666
1667
# File 'lib/adlint/cc1/interp.rb', line 1665

def initialize(owner)
  super(owner, Expression)
end

Instance Method Details

#unify_then_and_else_var(then_var, else_var) ⇒ Object



1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
# 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) ⇒ Object



1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
# 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