From 1f018b0fb8a666cc1b4be56abab6b141a93ea605 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Tue, 3 Nov 2020 10:51:56 +0100 Subject: [PATCH] Parser: Don't assume OpTypePointer will always take a SPIRType. Possible to receive a function prototype here. Don't try to do anything smart here, just don't crash during parsing. --- .../function-pointer.invalid.asm.comp.json | 18 ++++++++++++++++++ .../comp/function-pointer.invalid.asm.comp | 19 +++++++++++++++++++ spirv_parser.cpp | 11 ++++++++--- 3 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 reference/shaders-reflection/comp/function-pointer.invalid.asm.comp.json create mode 100644 shaders-reflection/comp/function-pointer.invalid.asm.comp diff --git a/reference/shaders-reflection/comp/function-pointer.invalid.asm.comp.json b/reference/shaders-reflection/comp/function-pointer.invalid.asm.comp.json new file mode 100644 index 00000000..bed59455 --- /dev/null +++ b/reference/shaders-reflection/comp/function-pointer.invalid.asm.comp.json @@ -0,0 +1,18 @@ +{ + "entryPoints" : [ + { + "name" : "main", + "mode" : "comp", + "workgroup_size" : [ + 1, + 1, + 1 + ], + "workgroup_size_is_spec_constant_id" : [ + false, + false, + false + ] + } + ] +} \ No newline at end of file diff --git a/shaders-reflection/comp/function-pointer.invalid.asm.comp b/shaders-reflection/comp/function-pointer.invalid.asm.comp new file mode 100644 index 00000000..440f3311 --- /dev/null +++ b/shaders-reflection/comp/function-pointer.invalid.asm.comp @@ -0,0 +1,19 @@ +; SPIR-V +; Version: 1.5 +; Generator: Khronos SPIR-V Tools Assembler; 0 +; Bound: 7 +; Schema: 0 +OpCapability Shader +%1 = OpExtInstImport "GLSL.std.450" +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %2 "main" +OpExecutionMode %2 LocalSize 1 1 1 +OpSource GLSL 450 +OpName %2 "main" +%3 = OpTypeVoid +%4 = OpTypeFunction %3 +%5 = OpTypePointer Private %4 +%2 = OpFunction %3 None %4 +%6 = OpLabel +OpReturn +OpFunctionEnd diff --git a/spirv_parser.cpp b/spirv_parser.cpp index 49c429cd..92db5287 100644 --- a/spirv_parser.cpp +++ b/spirv_parser.cpp @@ -623,10 +623,15 @@ void Parser::parse(const Instruction &instruction) { uint32_t id = ops[0]; - auto &base = get(ops[2]); + // Very rarely, we might receive a FunctionPrototype here. + // We won't be able to compile it, but we shouldn't crash when parsing. + // We should be able to reflect. + auto *base = maybe_get(ops[2]); auto &ptrbase = set(id); - ptrbase = base; + if (base) + ptrbase = *base; + ptrbase.pointer = true; ptrbase.pointer_depth++; ptrbase.storage = static_cast(ops[1]); @@ -634,7 +639,7 @@ void Parser::parse(const Instruction &instruction) if (ptrbase.storage == StorageClassAtomicCounter) ptrbase.basetype = SPIRType::AtomicCounter; - if (base.forward_pointer) + if (base && base->forward_pointer) forward_pointer_fixups.push_back({ id, ops[2] }); ptrbase.parent_type = ops[2];