From 490617133e2153bfcb646fee8ec04e8d2dfabfd8 Mon Sep 17 00:00:00 2001 From: Ehsan Nasiri Date: Mon, 28 Nov 2016 13:04:32 -0500 Subject: [PATCH] Validate the number of arguments in OpTypeFunction According to the SPIR-V spec (section 2.17: Universal Limits), the OpTypeFunction instruction may not take more than 255 arguments for the function. Also added unit tests for it. --- source/validate_id.cpp | 13 ++++++++++--- test/val/val_limits_test.cpp | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/source/validate_id.cpp b/source/validate_id.cpp index a486362..9e4d942 100644 --- a/source/validate_id.cpp +++ b/source/validate_id.cpp @@ -411,8 +411,9 @@ bool idUsage::isValid(const spv_instruction_t* inst, << inst->words[returnTypeIndex] << "' is not a type."; return false; } + size_t num_args = 0; for (size_t paramTypeIndex = 3; paramTypeIndex < inst->words.size(); - ++paramTypeIndex) { + ++paramTypeIndex, ++num_args) { auto paramType = module_.FindDef(inst->words[paramTypeIndex]); if (!paramType || !spvOpcodeGeneratesType(paramType->opcode())) { DIAG(paramTypeIndex) << "OpTypeFunction Parameter Type '" @@ -420,6 +421,13 @@ bool idUsage::isValid(const spv_instruction_t* inst, return false; } } + if (num_args > 255) { + DIAG(returnTypeIndex) << "OpTypeFunction may not take more than 255 " + "arguments. OpTypeFunction '" + << inst->words[1] << "' has " << num_args + << " arguments."; + return false; + } return true; } @@ -746,8 +754,7 @@ bool idUsage::isValid(const spv_instruction_t* inst, // to OpPhi instructions or OpSelect instructions, or any instructions other // than the image lookup and query instructions specified to take an operand // whose type is OpTypeSampledImage. - std::vector consumers = - module_.getSampledImageConsumers(resultID); + std::vector consumers = module_.getSampledImageConsumers(resultID); if (!consumers.empty()) { for (auto consumer_id : consumers) { auto consumer_instr = module_.FindDef(consumer_id); diff --git a/test/val/val_limits_test.cpp b/test/val/val_limits_test.cpp index 5188ca3..0d34259 100644 --- a/test/val/val_limits_test.cpp +++ b/test/val/val_limits_test.cpp @@ -162,3 +162,35 @@ OpFunctionEnd "exceeds the limit (16383).")); } +// Valid: OpTypeFunction with 255 arguments. +TEST_F(ValidateLimits, OpTypeFunctionGood) { + int num_args = 255; + std::ostringstream spirv; + spirv << header << R"( +%1 = OpTypeInt 32 0 +%2 = OpTypeFunction %1)"; + // add parameters + for (int i = 0; i < num_args; ++i) { + spirv << " %1"; + } + CompileSuccessfully(spirv.str()); + EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +// Invalid: OpTypeFunction with 256 arguments. (limit is 255 according to the +// spec Universal Limits (2.17). +TEST_F(ValidateLimits, OpTypeFunctionBad) { + int num_args = 256; + std::ostringstream spirv; + spirv << header << R"( +%1 = OpTypeInt 32 0 +%2 = OpTypeFunction %1)"; + for (int i = 0; i < num_args; ++i) { + spirv << " %1"; + } + CompileSuccessfully(spirv.str()); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpTypeFunction may not take more than 255 arguments. " + "OpTypeFunction '2' has 256 arguments.")); +} -- 2.7.4