class AdLint::Exam::CBuiltin::W0499::AmbiguousExpressionDetector

Public Class Methods

new(phase_ctxt, expr) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 11357
def initialize(phase_ctxt, expr)
  @phase_ctxt      = phase_ctxt
  @target_expr     = expr
  @encl_expr_stack = [expr]
  @shr_exprs       = Hash.new(0)
  @shl_exprs       = Hash.new(0)
  @lt_exprs        = Hash.new(0)
  @gt_exprs        = Hash.new(0)
  @le_exprs        = Hash.new(0)
  @ge_exprs        = Hash.new(0)
  @eq_exprs        = Hash.new(0)
  @ne_exprs        = Hash.new(0)
end

Public Instance Methods

execute() click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 11371
def execute
  @target_expr.accept(self)
end
visit_array_subscript_expression(node) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 11381
def visit_array_subscript_expression(node)
  AmbiguousExpressionDetector.new(@phase_ctxt,
                                  node.array_subscript).execute
end
visit_conditional_expression(node) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 11437
def visit_conditional_expression(node)
  cond_expr = node.condition
  then_expr = node.then_expression
  else_expr = node.else_expression
  AmbiguousExpressionDetector.new(@phase_ctxt, cond_expr).execute
  AmbiguousExpressionDetector.new(@phase_ctxt, then_expr).execute
  AmbiguousExpressionDetector.new(@phase_ctxt, else_expr).execute
end
visit_equality_expression(node) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 11424
def visit_equality_expression(node)
  cur_encl = current_encl_expr
  case node.operator.type
  when "=="
    @eq_exprs[cur_encl] += 1
    W(cur_encl.head_location) if include_ambiguous_expr?
  when "!="
    @ne_exprs[cur_encl] += 1
    W(cur_encl.head_location) if include_ambiguous_expr?
  end
  super
end
visit_function_call_expression(node) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 11386
def visit_function_call_expression(node)
  node.argument_expressions.each do |expr|
    AmbiguousExpressionDetector.new(@phase_ctxt, expr).execute
  end
end
visit_grouped_expression(node) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 11375
def visit_grouped_expression(node)
  @encl_expr_stack.push(node)
  super
  @encl_expr_stack.pop
end
visit_relational_expression(node) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 11405
def visit_relational_expression(node)
  cur_encl = current_encl_expr
  case node.operator.type
  when "<"
    @lt_exprs[cur_encl] += 1
    W(cur_encl.head_location) if include_ambiguous_expr?
  when ">"
    @gt_exprs[cur_encl] += 1
    W(cur_encl.head_location) if include_ambiguous_expr?
  when "<="
    @le_exprs[cur_encl] += 1
    W(cur_encl.head_location) if include_ambiguous_expr?
  when ">="
    @ge_exprs[cur_encl] += 1
    W(cur_encl.head_location) if include_ambiguous_expr?
  end
  super
end
visit_shift_expression(node) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 11392
def visit_shift_expression(node)
  cur_encl = current_encl_expr
  case node.operator.type
  when "<<"
    @shl_exprs[cur_encl] += 1
    W(cur_encl.head_location) if include_ambiguous_expr?
  when ">>"
    @shr_exprs[cur_encl] += 1
    W(cur_encl.head_location) if include_ambiguous_expr?
  end
  super
end

Private Instance Methods

current_encl_expr() click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 11467
def current_encl_expr
  @encl_expr_stack.last
end
include_ambiguous_expr?() click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 11447
def include_ambiguous_expr?
  cur_encl = current_encl_expr

  shl_expr_num = @shl_exprs[cur_encl]
  shr_expr_num = @shr_exprs[cur_encl]
  lt_expr_num  = @lt_exprs[cur_encl]
  gt_expr_num  = @gt_exprs[cur_encl]
  le_expr_num  = @le_exprs[cur_encl]
  ge_expr_num  = @ge_exprs[cur_encl]
  eq_expr_num  = @eq_exprs[cur_encl]
  ne_expr_num  = @ne_exprs[cur_encl]

  shl_expr_num > 0 && shr_expr_num > 0 or
  lt_expr_num > 0 && (gt_expr_num + le_expr_num + ge_expr_num) > 0 or
  gt_expr_num > 0 && (lt_expr_num + le_expr_num + ge_expr_num) > 0 or
  le_expr_num > 0 && (lt_expr_num + gt_expr_num + ge_expr_num) > 0 or
  ge_expr_num > 0 && (lt_expr_num + gt_expr_num + le_expr_num) > 0 or
  eq_expr_num > 0 && ne_expr_num > 0
end
suppressors() click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 11479
def suppressors
  @phase_ctxt[:suppressors]
end