X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Fvalidate.cpp;h=fdff3fe657aa56972690304c587e5bf61e8b3816;hb=59347f76bc985e8c9c769d4a3eee672cba9c920b;hp=62f997bb5c29ad6d8a507620c3d78745118fc80f;hpb=ea489c40680f9e8e90eeb163d17c8dddd53981d4;p=libs%2Fgl.git diff --git a/source/glsl/validate.cpp b/source/glsl/validate.cpp index 62f997bb..fdff3fe6 100644 --- a/source/glsl/validate.cpp +++ b/source/glsl/validate.cpp @@ -699,6 +699,52 @@ void ExpressionValidator::visit(Return &ret) } +FlowControlValidator::FlowControlValidator(): + reachable(true) +{ } + +void FlowControlValidator::visit(Block &block) +{ + for(NodeList::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(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; +} + + int StageInterfaceValidator::get_location(const Layout &layout) { for(vector::const_iterator i=layout.qualifiers.begin(); i!=layout.qualifiers.end(); ++i) @@ -769,7 +815,7 @@ void GlobalInterfaceValidator::apply(Module &module) void GlobalInterfaceValidator::check_uniform(const Uniform &uni) { - map::const_iterator i = used_names.find(uni.name); + map::const_iterator i = used_names.find(uni.name); if(i!=used_names.end()) { if(uni.location>=0 && i->second->location>=0 && i->second->location!=uni.location)