mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-12-25 17:21:06 +00:00
Validate correct opcode uses of OpFunction
Fixes https://crbug.com/873457 * Filed Khronos SPIR-V issue 352 * Updated bad tests * Added new test
This commit is contained in:
parent
5fc011b453
commit
8cb949ad34
@ -14,6 +14,8 @@
|
||||
|
||||
#include "source/val/validate.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "source/opcode.h"
|
||||
#include "source/val/instruction.h"
|
||||
#include "source/val/validation_state.h"
|
||||
@ -38,6 +40,27 @@ spv_result_t ValidateFunction(ValidationState_t& _, const Instruction* inst) {
|
||||
<< "' does not match the Function Type's return type <id> '"
|
||||
<< _.getIdName(return_id) << "'.";
|
||||
}
|
||||
|
||||
for (auto& pair : inst->uses()) {
|
||||
const auto* use = pair.first;
|
||||
const std::vector<SpvOp> acceptable = {
|
||||
SpvOpFunctionCall,
|
||||
SpvOpEntryPoint,
|
||||
SpvOpEnqueueKernel,
|
||||
SpvOpGetKernelNDrangeSubGroupCount,
|
||||
SpvOpGetKernelNDrangeMaxSubGroupSize,
|
||||
SpvOpGetKernelWorkGroupSize,
|
||||
SpvOpGetKernelPreferredWorkGroupSizeMultiple,
|
||||
SpvOpGetKernelLocalSizeForSubgroupCount,
|
||||
SpvOpGetKernelMaxNumSubgroups};
|
||||
if (std::find(acceptable.begin(), acceptable.end(), use->opcode()) ==
|
||||
acceptable.end()) {
|
||||
return _.diag(SPV_ERROR_INVALID_ID, use)
|
||||
<< "Invalid use of function result id " << _.getIdName(inst->id())
|
||||
<< ".";
|
||||
}
|
||||
}
|
||||
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -477,9 +477,10 @@ TEST_P(ValidateCFG, BranchTargetFirstBlockBadSinceEntryBlock) {
|
||||
|
||||
TEST_P(ValidateCFG, BranchTargetFirstBlockBadSinceValue) {
|
||||
Block entry("entry");
|
||||
entry.SetBody("%undef = OpUndef %voidt\n");
|
||||
Block bad("bad");
|
||||
Block end("end", SpvOpReturn);
|
||||
Block badvalue("func"); // This referenes the function name.
|
||||
Block badvalue("undef"); // This referenes the OpUndef.
|
||||
std::string str = header(GetParam()) +
|
||||
nameOps("entry", "bad", std::make_pair("func", "Main")) +
|
||||
types_consts() +
|
||||
@ -493,11 +494,10 @@ TEST_P(ValidateCFG, BranchTargetFirstBlockBadSinceValue) {
|
||||
|
||||
CompileSuccessfully(str);
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions());
|
||||
EXPECT_THAT(
|
||||
getDiagnosticString(),
|
||||
MatchesRegex("Block\\(s\\) \\{.\\[Main\\]\\} are referenced but not "
|
||||
"defined in function .\\[Main\\]\n"
|
||||
" %Main = OpFunction %void None %10\n"))
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
MatchesRegex("Block\\(s\\) \\{..\\} are referenced but not "
|
||||
"defined in function .\\[Main\\]\n"
|
||||
" %Main = OpFunction %void None %10\n"))
|
||||
<< str;
|
||||
}
|
||||
|
||||
|
@ -2192,13 +2192,14 @@ TEST_F(ValidateIdWithMessage, OpStoreObjectGood) {
|
||||
%6 = OpVariable %3 UniformConstant
|
||||
%7 = OpFunction %1 None %4
|
||||
%8 = OpLabel
|
||||
OpStore %6 %7
|
||||
%9 = OpUndef %1
|
||||
OpStore %6 %9
|
||||
OpReturn
|
||||
OpFunctionEnd)";
|
||||
CompileSuccessfully(spirv.c_str());
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("OpStore Object <id> '7's type is void."));
|
||||
HasSubstr("OpStore Object <id> '9's type is void."));
|
||||
}
|
||||
TEST_F(ValidateIdWithMessage, OpStoreTypeBad) {
|
||||
std::string spirv = kGLSL450MemoryModel + R"(
|
||||
@ -3577,6 +3578,22 @@ OpFunctionEnd)";
|
||||
HasSubstr("OpFunction Function Type <id> '2' is not a function type."));
|
||||
}
|
||||
|
||||
TEST_F(ValidateIdWithMessage, OpFunctionUseBad) {
|
||||
const std::string spirv = kGLSL450MemoryModel + R"(
|
||||
%1 = OpTypeFloat 32
|
||||
%2 = OpTypeFunction %1
|
||||
%3 = OpFunction %1 None %2
|
||||
%4 = OpLabel
|
||||
OpReturnValue %3
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
CompileSuccessfully(spirv);
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("Invalid use of function result id 3."));
|
||||
}
|
||||
|
||||
TEST_F(ValidateIdWithMessage, OpFunctionParameterGood) {
|
||||
std::string spirv = kGLSL450MemoryModel + R"(
|
||||
%1 = OpTypeVoid
|
||||
|
Loading…
Reference in New Issue
Block a user