예제 #1
0
def while_loop(ast, i, o):
  '''Reachability for a while loop.
  L: while (true) S
  In[S] = In[L]
  Out[L] = No

  L: while (false) S
  In[S] = No
  Out[L] = In[L]

  L: while (E) S
  In[S] = In[L]
  Out[L] = In[L]'''

  # Make sure that the while expression is a Boolean.
  if ast.expression.expr_type != ast_type.ASTType.ASTBoolean:
    raise reachability.ReachabilityError('While expression is not a boolean.')

  # The first two cases, where the expression has been resolved to True or
  # False.
  if ast.expression.const_value is not None:
    if ast.expression.const_value:
      # Though it doesn't affect our return value, check the children
      # statements for reachability.
      if ast.statement:
        reachability.check_block_or_statement(ast.statement, in_value=o)
      return o, NO
    else:
      # This while loop is unreachable.
      return NO, o

  # The last case, where our expression is not a constant.
  if ast.statement is not None:
    reachability.check_block_or_statement(ast.statement, in_value=o)
  return o, o
예제 #2
0
def if_statement(ast, i, o):
  '''Reachability for an IF statement.
  L: if (E) S_1 else S_2
  In[S_1] = In[L]
  In[S_2] = In[L]
  Out[L] = Out[S_1] or Out[S_2]'''

  if ast.if_statement is not None:
    if_in, if_out = reachability.check_block_or_statement(
        ast.if_statement, in_value=o)

  if ast.else_statement is not None:
    else_in, else_out = reachability.check_block_or_statement(
        ast.else_statement, in_value=o)

    # The out value is the OR between the if and else out values.
    new_out = (MAYBE if if_out == MAYBE or else_out == MAYBE else NO)
    return o, new_out

  # If statement with no else:
  #   Out[L] = Out[S_1] OR In[L] = In[L] = o
  return o, o
예제 #3
0
def for_loop(ast, i, o):
  '''Reachability for a for loop.
  L: for (S_1; false; S_2) S_3
  In[S] = No
  Out[L] = In[L]

  L: for (S_1; true; S_2) S_3
  In[S] = In[L]
  Out[L] = No

  L: for (S_1; E; S_2) S_3
  In[S] = In[L]
  Out[L] = In[L]'''
  has_expr = (ast.expression is not None)

  # Make sure the for expression is a Boolean if it exists.
  if has_expr and ast.expression.expr_type != ast_type.ASTType.ASTBoolean:
    raise reachability.ReachabilityError('For expression is not a boolean.')

  # The first two cases, where the condition expression is a constant.
  if has_expr and ast.expression.const_value is not None:
    if ast.expression.const_value:
      # Check all children statements for reachability.
      if ast.init:
        reachability.check_block_or_statement(ast.init, in_value=o)
      if ast.update:
        reachability.check_block_or_statement(ast.update, in_value=o)
      if ast.statement:
        reachability.check_block_or_statement(ast.statement, in_value=o)

      return o, NO
    else:
      # The for loop is unreachable.
      return NO, o

  # Our expression is not a constant.
  # Check all children statements for reachability.
  if ast.init:
    reachability.check_block_or_statement(ast.init, in_value=o)
  if ast.update:
    reachability.check_block_or_statement(ast.update, in_value=o)
  if ast.statement:
    reachability.check_block_or_statement(ast.statement, in_value=o)

  # If there is no expression, the for loop runs forever.
  if not has_expr:
    return o, NO

  return o, o