+FlowControlValidator::FlowControlValidator():
+ reachable(true)
+{ }
+
+void FlowControlValidator::visit(Block &block)
+{
+ for(NodeList<Statement>::const_iterator i=block.body.begin(); i!=block.body.end(); ++i)
+ {
+ if(!reachable)
+ {
+ diagnose(**i, Diagnostic::WARN, "Unreachable code detected");
+ break;
+ }
+ (*i)->visit(*this);
+ }
+}
+
+void FlowControlValidator::visit(FunctionDeclaration &func)
+{
+ func.body.visit(*this);
+
+ if(func.definition==&func && func.return_type_declaration)
+ {
+ const BasicTypeDeclaration *basic_ret = dynamic_cast<const BasicTypeDeclaration *>(func.return_type_declaration);
+ if(reachable && (!basic_ret || basic_ret->kind!=BasicTypeDeclaration::VOID))
+ error(func, "Missing return statement at the end of a function not returning 'void'");
+ }
+ reachable = true;
+}
+
+void FlowControlValidator::visit(Conditional &cond)
+{
+ cond.body.visit(*this);
+ bool reachable_if_true = reachable;
+ reachable = true;
+ cond.else_body.visit(*this);
+ reachable |= reachable_if_true;
+}
+
+void FlowControlValidator::visit(Iteration &iter)
+{
+ iter.body.visit(*this);
+ reachable = true;
+}
+
+