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.
This commit is contained in:
Ehsan Nasiri 2016-11-28 13:04:32 -05:00 committed by David Neto
parent 5f2d40915e
commit 490617133e
2 changed files with 42 additions and 3 deletions

View File

@ -411,8 +411,9 @@ bool idUsage::isValid<SpvOpTypeFunction>(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 <id> '"
@ -420,6 +421,13 @@ bool idUsage::isValid<SpvOpTypeFunction>(const spv_instruction_t* inst,
return false;
}
}
if (num_args > 255) {
DIAG(returnTypeIndex) << "OpTypeFunction may not take more than 255 "
"arguments. OpTypeFunction <id> '"
<< inst->words[1] << "' has " << num_args
<< " arguments.";
return false;
}
return true;
}
@ -746,8 +754,7 @@ bool idUsage::isValid<SpvOpSampledImage>(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<uint32_t> consumers =
module_.getSampledImageConsumers(resultID);
std::vector<uint32_t> consumers = module_.getSampledImageConsumers(resultID);
if (!consumers.empty()) {
for (auto consumer_id : consumers) {
auto consumer_instr = module_.FindDef(consumer_id);

View File

@ -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 <id> '2' has 256 arguments."));
}