.NAME Definition of label for goto

.DESCRIPTION
	Any label referenced by a goto statement shall be 
declared in the same block, or in a block enclosing the 
goto statement. 

.COMMENT V7.0

.SEVERITY Required

.COMMENT
Please refer to the MISRA C++:2008 document for further details (www.misra-cpp.com)

.COMMAND tcl

.CODE

::logiscope::include -once common utilities.tcl

proc compute {standardName tree} {
  variable CurrentParameterList
  # Check all ... nodes
  utilities::filterTree $tree [list [namespace current]::check]
}

proc check { node } {
	# Look for a goto node
	if { [::utilities::isTreeOperator $node goto] } {
	  # Get the destination label to which the goto points
	  set gotoLabel [::utilities::getName [::logiscope::treeGetSon $node IDENTIFIER]]
	  set nbViolations 0
	  # For each brother node of the "goto" node, look for definitions of the destination label
	  # and produce a violation if they are found
	  ::logiscope::forobj curChild [::logiscope::treeUp $node] treeChild {
		  if { ![::utilities::isTreeOperator $curChild label] } {
			if {[expr [findLabelDefinition $curChild $gotoLabel] >= 1]} {
			  incr nbViolations
			}
		  }
	  }
	  # If a definition of the destination label was found in a sub-level, violations will have been produced
	  # Return 0 if violations were found
	  if {[expr $nbViolations > 0]} {
	    return 0
	  }
	}
return 1
}

# This recursive procedure looks for a definition of a specific label
# and produce a violation if it is found
proc findLabelDefinition {node label} {
  if { [::utilities::isTreeOperator $node label] } {
    set labelId [::utilities::getName [::logiscope::treeDown $node 0]]
	# If the current node is a label with the searched name, a violation is generated
    if {[string equal $labelId $label]} {
 	  ::logiscope::addViolation $node
	}
    return 1
  } else {
    # If the current node is not a label, recurse the search on its children
    set foundLabel 0
    ::logiscope::forobj curChild $node treeChild {
      set foundLabel [expr $foundLabel + [findLabelDefinition $curChild $label]]
    }
  }
  return $foundLabel
}
