From 3a2f191d9edd7c61d49cae1e979fa7633b2aaf8b Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Tue, 15 Aug 2017 08:52:13 -0700 Subject: Handle possibility of bad types in varying input/output signature. Fixes #160 If the front-end runs into a type it doesn't understand in the parameter list of an entry point, it will create an `ErrorType` for that parameter, but then the parameter binding/layout rules will fail to create a `TypeLayout` for the prameter (and return `NULL`). There were some places where the code was expecting that operation to succeed unconditionally, and so would crash when there was a bad type. The specific case in the bug report was when the return type of a shader entry point was bad: // `vec4` is not an HLSL type vec4 main(...) { ... } Note that the specific case in the buf report only manifests in "rewriter" mode (when the Slang compiler isn't allowed to issue error messages from the front-end), but the same basic thing would happen if the varying parameter/output had used a type that is invalid for varying input/output: Texture2D main(...) { ... } I'm not 100% happy with just adding more `NULL` checks for this, because there is no easy way to tell if they are exhaustive. A better solution in the longer term might be to construct a kind of `ErrorTypeLayout` to represent cases where we wanted a type layout, but none could be constructed. --- source/slang/parameter-binding.cpp | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'source/slang/parameter-binding.cpp') diff --git a/source/slang/parameter-binding.cpp b/source/slang/parameter-binding.cpp index 877597640..757662101 100644 --- a/source/slang/parameter-binding.cpp +++ b/source/slang/parameter-binding.cpp @@ -1253,15 +1253,18 @@ static RefPtr processEntryPointParameter( state, fieldVarLayout); - fieldVarLayout->typeLayout = fieldTypeLayout; - - for (auto rr : fieldTypeLayout->resourceInfos) + if(fieldTypeLayout) { - SLANG_RELEASE_ASSERT(rr.count != 0); + fieldVarLayout->typeLayout = fieldTypeLayout; + + for (auto rr : fieldTypeLayout->resourceInfos) + { + SLANG_RELEASE_ASSERT(rr.count != 0); - auto structRes = structLayout->findOrAddResourceInfo(rr.kind); - fieldVarLayout->findOrAddResourceInfo(rr.kind)->index = structRes->count; - structRes->count += rr.count; + auto structRes = structLayout->findOrAddResourceInfo(rr.kind); + fieldVarLayout->findOrAddResourceInfo(rr.kind)->index = structRes->count; + structRes->count += rr.count; + } } structLayout->fields.Add(fieldVarLayout); @@ -1404,13 +1407,16 @@ static void collectEntryPointParameters( state, resultLayout); - resultLayout->typeLayout = resultTypeLayout; - - for (auto rr : resultTypeLayout->resourceInfos) + if( resultTypeLayout ) { - auto entryPointRes = entryPointLayout->findOrAddResourceInfo(rr.kind); - resultLayout->findOrAddResourceInfo(rr.kind)->index = entryPointRes->count; - entryPointRes->count += rr.count; + resultLayout->typeLayout = resultTypeLayout; + + for (auto rr : resultTypeLayout->resourceInfos) + { + auto entryPointRes = entryPointLayout->findOrAddResourceInfo(rr.kind); + resultLayout->findOrAddResourceInfo(rr.kind)->index = entryPointRes->count; + entryPointRes->count += rr.count; + } } entryPointLayout->resultLayout = resultLayout; -- cgit v1.2.3