.NAME Explicit return statement

.DESCRIPTION
All exit paths from a function with non-void return 
type shall have an explicit return statement with an 
expression. 


.COMMENT V7.0

.SEVERITY Required

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

RULE LIMITATION: All return paths can't be detected by a static analyzer.
This rule actually checks that all non-void functions have at least one return statement, and that all of its return statements return an expression. 

.REQUIRED cpp_semantic

.COMMAND tcl

.CODE

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

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

proc check { node } {
	if {[::utilities::isTreeOperator $node fndef]} {
		set curScope [::Semantic::getScopeOfNode $node]
		if {[string equal [::Semantic::getAttribute $curScope scopeKind] FUNCTION]} {
			set funcName [::Semantic::getAttribute $curScope name]
			set classNode [::Semantic::getAttribute $curScope class]
			set className ""
			if {[string equal [string range $funcName 0 0 ] "~"]} {
				set funcName [string range $funcName 1 end]
			}
			if {$classNode != -1} {
				set className [::Semantic::getAttribute $classNode name]
			}
			
			if {![string equal $className $funcName]} {
				if {[::Semantic::exists $curScope type]} {
					set funcTypeName [::Semantic::getAttribute [::Semantic::getAttribute $curScope type] name]
					if {![string equal $funcTypeName void]} {
						checkFuncBody [::logiscope::treeGetSon $node FNBODY]
					}
				}
			}
		}
	}
	return 1
}

proc checkFuncBody {node} {
	variable nbReturns
	set nbReturns 0
	utilities::filterTree $node [list [namespace current]::check2]
	if {[expr $nbReturns == 0]} {
		::logiscope::addViolation $node
	}
}

proc check2 {node} {
	variable nbReturns
	if {[::utilities::isTreeOperator $node return]} {
		set contents [::utilities::getName [::logiscope::treeGetSon $node EXPR_OPT]]
		if {[string equal $contents none]} {
			::logiscope::addViolation $node
		}
		incr nbReturns
	}
	return 1
}