{"action":"created","issue":{"url":"https://api.github.com/repos/KhronosGroup/glslang/issues/610","repository_url":"https://api.github.com/repos/KhronosGroup/glslang","labels_url":"https://api.github.com/repos/KhronosGroup/glslang/issues/610/labels{/name}","comments_url":"https://api.github.com/repos/KhronosGroup/glslang/issues/610/comments","events_url":"https://api.github.com/repos/KhronosGroup/glslang/issues/610/events","html_url":"https://github.com/KhronosGroup/glslang/issues/610","id":193274703,"number":610,"title":"Assert in Builder::getContainedTypeId while compiling code with missing function definitions","user":{"login":"zeux","id":1106629,"avatar_url":"https://avatars.githubusercontent.com/u/1106629?v=3","gravatar_id":"","url":"https://api.github.com/users/zeux","html_url":"https://github.com/zeux","followers_url":"https://api.github.com/users/zeux/followers","following_url":"https://api.github.com/users/zeux/following{/other_user}","gists_url":"https://api.github.com/users/zeux/gists{/gist_id}","starred_url":"https://api.github.com/users/zeux/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zeux/subscriptions","organizations_url":"https://api.github.com/users/zeux/orgs","repos_url":"https://api.github.com/users/zeux/repos","events_url":"https://api.github.com/users/zeux/events{/privacy}","received_events_url":"https://api.github.com/users/zeux/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":2,"created_at":"2016-12-03T08:28:59Z","updated_at":"2016-12-05T17:18:55Z","closed_at":null,"body":"When compiling code like this with entrypoint `main`:\r\n\r\n```\r\nfloat4 main(): SV_Target0 { return 0; }\r\nstruct Surface { float3 albedo; };\r\nSurface surfaceShader(float fade);\r\nSurface surfaceShaderExec()\r\n{\r\n    float fade = 0;\r\n    return surfaceShader(0);\r\n}\r\n```\r\n\r\nThere is an assertion `assert(0)` that happens in Builder::getContainedTypeId with the following stack:\r\n\r\n```\r\nspv::Builder::getContainedTypeId(unsigned int typeId, int member) Line 582\tC++\r\n`anonymous namespace'::TGlslangToSpvTraverser::multiTypeStore(const glslang::TType & type, unsigned int rValue) Line 2431\tC++\r\n`anonymous namespace'::TGlslangToSpvTraverser::visitBranch(glslang::TVisit __formal, glslang::TIntermBranch * node) Line 1903\tC++\r\nglslang::TIntermBranch::traverse(glslang::TIntermTraverser * it) Line 264\tC++\r\nglslang::TIntermAggregate::traverse(glslang::TIntermTraverser * it) Line 170\tC++\r\nglslang::TIntermAggregate::traverse(glslang::TIntermTraverser * it) Line 170\tC++\r\n`anonymous namespace'::TGlslangToSpvTraverser::visitFunctions(const glslang::TVector<TIntermNode *> & glslFunctions) Line 2638\tC++\r\n`anonymous namespace'::TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TIntermAggregate * node) Line 1358\tC++\r\nglslang::TIntermAggregate::traverse(glslang::TIntermTraverser * it) Line 152\tC++\r\nglslang::GlslangToSpv(const glslang::TIntermediate & intermediate, std::vector<unsigned int,std::allocator<unsigned int> > & spirv, spv::SpvBuildLogger * logger) Line 5126\tC++\r\nglslang::GlslangToSpv(const glslang::TIntermediate & intermediate, std::vector<unsigned int,std::allocator<unsigned int> > & spirv) Line 5110\tC++\r\n```\r\n\r\nWhat happens here is that during compiling the function call, the check in the first line of `TGlslangToSpvTraverser::handleUserFunctionCall` says that there is no function and it returns 0.\r\n\r\nThis causes the type checking during return processing (`TGlslangToSpvTraverser::visitBranch`, `EOpReturn` case) to consider the types as different because the IR essentially is malformed (the function call refers to the wrong instruction as a result of early-out in `handleUserFunctionCall`, triggering an assert.\r\n\r\nFirst, it seems like there's some proper error handling that's missing here. I'm not sure if there is a valid case where handleUserFunctionCall should return 0 if the function isn't found - it does not seem like there is one?\r\n\r\nSecond, is there any way to resolve this so that the shader *does* get successfully converted to SPIR-V? I'm not very familiar with SPIR-V - in this case the correct thing to do would probably be to emit some sort of \"extern\" symbol for the `surfaceShader` function?"},"comment":{"url":"https://api.github.com/repos/KhronosGroup/glslang/issues/comments/264915974","html_url":"https://github.com/KhronosGroup/glslang/issues/610#issuecomment-264915974","issue_url":"https://api.github.com/repos/KhronosGroup/glslang/issues/610","id":264915974,"user":{"login":"johnkslang","id":5607714,"avatar_url":"https://avatars.githubusercontent.com/u/5607714?v=3","gravatar_id":"","url":"https://api.github.com/users/johnkslang","html_url":"https://github.com/johnkslang","followers_url":"https://api.github.com/users/johnkslang/followers","following_url":"https://api.github.com/users/johnkslang/following{/other_user}","gists_url":"https://api.github.com/users/johnkslang/gists{/gist_id}","starred_url":"https://api.github.com/users/johnkslang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/johnkslang/subscriptions","organizations_url":"https://api.github.com/users/johnkslang/orgs","repos_url":"https://api.github.com/users/johnkslang/repos","events_url":"https://api.github.com/users/johnkslang/events{/privacy}","received_events_url":"https://api.github.com/users/johnkslang/received_events","type":"User","site_admin":false},"created_at":"2016-12-05T17:18:55Z","updated_at":"2016-12-05T17:18:55Z","body":"FYI, I'm considering instead of not bringing over dead subgraphs of the call graph. Have to finish checking on a few things before deciding (there are other DCE efforts)."}}
{"actor":{"display_login":"johnkslang"}}