%1 = OpTypeInt 32 0)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpMemberName Type <id> '1' is not a struct type."));
}
TEST_F(ValidateIdWithMessage, OpMemberNameMemberBad) {
string spirv = kGLSL450MemoryModel + R"(
%2 = OpTypeStruct %1)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpMemberName Member <id> '1' index is larger than "
+ "Type <id> '1's member count."));
}
TEST_F(ValidateIdWithMessage, OpLineGood) {
}
TEST_F(ValidateIdWithMessage, OpLineFileBad) {
string spirv = kGLSL450MemoryModel + R"(
- OpLine %2 0 0
-%2 = OpTypeInt 32 0
-%3 = OpTypePointer Input %2
-%4 = OpVariable %3 Input)";
+ %1 = OpTypeInt 32 0
+ OpLine %1 0 0
+ )";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpLine Target <id> '1' is not an OpString."));
}
TEST_F(ValidateIdWithMessage, OpDecorateGood) {
%1 = OpTypeVoid)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("OpEntryPoint Entry Point <id> '1' is not a function."));
}
TEST_F(ValidateIdWithMessage, OpEntryPointParameterCountBad) {
string spirv = kGLSL450MemoryModel + R"(
OpFunctionEnd)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpEntryPoint Entry Point <id> '1's function parameter "
+ "count is not zero"));
}
TEST_F(ValidateIdWithMessage, OpEntryPointReturnTypeBad) {
string spirv = kGLSL450MemoryModel + R"(
OpFunctionEnd)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpEntryPoint Entry Point <id> '1's function return "
+ "type is not void."));
}
TEST_F(ValidateIdWithMessage, OpEntryPointInterfaceIsNotVariableTypeBad) {
OpFunctionEnd)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpExecutionMode Entry Point <id> '1' is not the Entry "
+ "Point operand of an OpEntryPoint."));
}
TEST_F(ValidateIdWithMessage, OpExecutionModeEntryPointBad) {
OpFunctionEnd)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpExecutionMode Entry Point <id> '2' is not the Entry "
+ "Point operand of an OpEntryPoint."));
}
TEST_F(ValidateIdWithMessage, OpTypeVectorFloat) {
%3 = OpTypeVector %2 4)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("OpTypeVector Component Type <id> '2' is not a scalar type."));
}
TEST_F(ValidateIdWithMessage, OpTypeMatrixGood) {
%2 = OpTypeMatrix %1 3)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Columns in a matrix must be of type vector."));
}
TEST_F(ValidateIdWithMessage, OpTypeSamplerGood) {
%3 = OpTypeArray %2 %2)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpTypeArray Element Type <id> '2' is not a type."));
}
// Signed or unsigned.
~OpTypeArrayLengthTest() { spvDiagnosticDestroy(diagnostic_); }
// Runs spvValidate() on v, printing any errors via spvDiagnosticPrint().
- spv_result_t Val(const SpirvVector& v) {
+ spv_result_t Val(const SpirvVector& v, const std::string &expected_err = "") {
spv_const_binary_t cbinary{v.data(), v.size()};
const auto status =
spvValidate(ScopedContext().context, &cbinary, &diagnostic_);
if (status != SPV_SUCCESS) {
spvDiagnosticPrint(diagnostic_);
+ EXPECT_THAT(std::string(diagnostic_->error), HasSubstr(expected_err));
}
return status;
}
TEST_P(OpTypeArrayLengthTest, LengthZero) {
const int width = GetParam();
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- Val(CompileSuccessfully(MakeArrayLength("0", kSigned, width))));
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- Val(CompileSuccessfully(MakeArrayLength("0", kUnsigned, width))));
+ EXPECT_EQ(
+ SPV_ERROR_INVALID_ID,
+ Val(CompileSuccessfully(MakeArrayLength("0", kSigned, width)),
+ "OpTypeArray Length <id> '2' default value must be at least 1."));
+ EXPECT_EQ(
+ SPV_ERROR_INVALID_ID,
+ Val(CompileSuccessfully(MakeArrayLength("0", kUnsigned, width)),
+ "OpTypeArray Length <id> '2' default value must be at least 1."));
}
TEST_P(OpTypeArrayLengthTest, LengthNegative) {
const int width = GetParam();
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- Val(CompileSuccessfully(MakeArrayLength("-1", kSigned, width))));
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- Val(CompileSuccessfully(MakeArrayLength("-2", kSigned, width))));
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- Val(CompileSuccessfully(MakeArrayLength("-123", kSigned, width))));
+ EXPECT_EQ(
+ SPV_ERROR_INVALID_ID,
+ Val(CompileSuccessfully(MakeArrayLength("-1", kSigned, width)),
+ "OpTypeArray Length <id> '2' default value must be at least 1."));
+ EXPECT_EQ(
+ SPV_ERROR_INVALID_ID,
+ Val(CompileSuccessfully(MakeArrayLength("-2", kSigned, width)),
+ "OpTypeArray Length <id> '2' default value must be at least 1."));
+ EXPECT_EQ(
+ SPV_ERROR_INVALID_ID,
+ Val(CompileSuccessfully(MakeArrayLength("-123", kSigned, width)),
+ "OpTypeArray Length <id> '2' default value must be at least 1."));
const string neg_max = "0x8" + string(width / 4 - 1, '0');
- EXPECT_EQ(SPV_ERROR_INVALID_ID,
- Val(CompileSuccessfully(MakeArrayLength(neg_max, kSigned, width))));
+ EXPECT_EQ(
+ SPV_ERROR_INVALID_ID,
+ Val(CompileSuccessfully(MakeArrayLength(neg_max, kSigned, width)),
+ "OpTypeArray Length <id> '2' default value must be at least 1."));
}
// The only valid widths for integers are 8, 16, 32, and 64.
%ary = OpTypeArray %i32 %len)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "OpTypeArray Length <id> '2' default value must be at least 1."));
}
TEST_F(ValidateIdWithMessage, OpTypeArrayLengthSpecConst) {
%3 = OpTypeRuntimeArray %2)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("OpTypeRuntimeArray Element Type <id> '2' is not a type."));
}
// TODO: Object of this type can only be created with OpVariable using the
// Unifrom Storage Class
%4 = OpTypeStruct %1 %2 %3)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpTypeStruct Member Type <id> '3' is not a type."));
}
TEST_F(ValidateIdWithMessage, OpTypePointerGood) {
%3 = OpTypePointer Input %2)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpTypePointer Type <id> '2' is not a type."));
}
TEST_F(ValidateIdWithMessage, OpTypeFunctionGood) {
%3 = OpTypeFunction %2)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpTypeFunction Return Type <id> '2' is not a type."));
}
TEST_F(ValidateIdWithMessage, OpTypeFunctionParameterBad) {
string spirv = kGLSL450MemoryModel + R"(
%4 = OpTypeFunction %1 %2 %3)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("OpTypeFunction Parameter Type <id> '3' is not a type."));
}
TEST_F(ValidateIdWithMessage, OpTypePipeGood) {
%2 = OpConstantTrue %1)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("OpConstantTrue Result Type <id> '1' is not a boolean type."));
}
TEST_F(ValidateIdWithMessage, OpConstantFalseGood) {
%2 = OpConstantFalse %1)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("OpConstantFalse Result Type <id> '1' is not a boolean type."));
}
TEST_F(ValidateIdWithMessage, OpConstantGood) {
%4 = OpConstantComposite %1 %3 %3 %3 %3)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "OpConstantComposite Result Type <id> '1' is not a composite type."));
}
TEST_F(ValidateIdWithMessage, OpConstantCompositeVectorConstituentTypeBad) {
string spirv = kGLSL450MemoryModel + R"(
%6 = OpConstantComposite %2 %3 %5 %3 %3)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("OpConstantComposite Constituent <id> '5's type does not match "
+ "Result Type <id> '2's vector element type."));
}
TEST_F(ValidateIdWithMessage,
OpConstantCompositeVectorConstituentUndefTypeBad) {
%6 = OpConstantComposite %2 %3 %5 %3 %3)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("OpConstantComposite Constituent <id> '5's type does not match "
+ "Result Type <id> '2's vector element type."));
}
TEST_F(ValidateIdWithMessage, OpConstantCompositeMatrixGood) {
string spirv = kGLSL450MemoryModel + R"(
%10 = OpConstantComposite %3 %6 %7 %8 %9)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpConstantComposite Constituent <id> '10' vector "
+ "component count does not match Result Type <id> '4's "
+ "vector component count."));
}
TEST_F(ValidateIdWithMessage,
OpConstantCompositeMatrixConstituentUndefTypeBad) {
%10 = OpConstantComposite %3 %6 %7 %8 %9)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpConstantComposite Constituent <id> '10' vector "
+ "component count does not match Result Type <id> '4's "
+ "vector component count."));
}
TEST_F(ValidateIdWithMessage, OpConstantCompositeMatrixColumnTypeBad) {
string spirv = kGLSL450MemoryModel + R"(
%10 = OpConstantComposite %5 %8 %9)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Columns in a matrix must be of type vector."));
}
TEST_F(ValidateIdWithMessage, OpConstantCompositeArrayGood) {
string spirv = kGLSL450MemoryModel + R"(
%4 = OpConstantComposite %3 %2 %2 %2 %1)"; // Uses a type as operand
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpConstantComposite Constituent <id> '1' is not a "
+ "constant or undef."));
}
TEST_F(ValidateIdWithMessage, OpConstantCompositeArrayConstituentTypeBad) {
string spirv = kGLSL450MemoryModel + R"(
%4 = OpConstantComposite %3 %2 %2 %2 %6)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpConstantComposite Constituent <id> '5's type does "
+ "not match Result Type <id> '3's array element type."));
}
TEST_F(ValidateIdWithMessage, OpConstantCompositeArrayConstituentUndefTypeBad) {
string spirv = kGLSL450MemoryModel + R"(
%4 = OpConstantComposite %3 %2 %2 %2 %6)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpConstantComposite Constituent <id> '5's type does "
+ "not match Result Type <id> '3's array element type."));
}
TEST_F(ValidateIdWithMessage, OpConstantCompositeStructGood) {
string spirv = kGLSL450MemoryModel + R"(
%6 = OpConstantComposite %3 %4 %5 %4)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpConstantComposite Constituent <id> '5' type does "
+ "not match the Result Type <id> '3's member type."));
}
TEST_F(ValidateIdWithMessage, OpConstantCompositeStructMemberUndefTypeBad) {
%6 = OpConstantComposite %3 %4 %5 %4)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpConstantComposite Constituent <id> '5' type does "
+ "not match the Result Type <id> '3's member type."));
}
TEST_F(ValidateIdWithMessage, OpConstantSamplerGood) {
%2 = OpConstantSampler %1 Clamp 0 Nearest)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "OpConstantSampler Result Type <id> '1' is not a sampler type."));
}
TEST_F(ValidateIdWithMessage, OpConstantNullGood) {
%2 = OpConstantNull %1)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "OpConstantNull Result Type <id> '1' cannot have a null value."));
}
TEST_F(ValidateIdWithMessage, OpConstantNullArrayBad) {
%6 = OpConstantNull %5)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "OpConstantNull Result Type <id> '4' cannot have a null value."));
}
TEST_F(ValidateIdWithMessage, OpConstantNullStructBad) {
%4 = OpConstantNull %3)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "OpConstantNull Result Type <id> '2' cannot have a null value."));
}
TEST_F(ValidateIdWithMessage, OpConstantNullRuntimeArrayBad) {
%null = OpConstantNull %array)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "OpConstantNull Result Type <id> '2' cannot have a null value."));
}
TEST_F(ValidateIdWithMessage, OpSpecConstantTrueGood) {
%2 = OpSpecConstantTrue %1)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Specialization constant must be a boolean type."));
}
TEST_F(ValidateIdWithMessage, OpSpecConstantFalseGood) {
%2 = OpSpecConstantFalse %1)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Specialization constant must be a boolean type."));
}
TEST_F(ValidateIdWithMessage, OpSpecConstantGood) {
// change over time, but this must always fail.
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Type Id 1 is not a scalar numeric type"));
}
// Valid: SpecConstantComposite specializes to a vector.
%2 = OpVariable %1 Input)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("OpVariable Result Type <id> '1' is not a pointer type."));
}
TEST_F(ValidateIdWithMessage, OpVariableInitializerIsTypeBad) {
string spirv = kGLSL450MemoryModel + R"(
)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpLoad Result Type <id> '3' does not match Pointer "
+ "<id> '5's type."));
}
TEST_F(ValidateIdWithMessage, OpLoadPointerBad) {
string spirv = kGLSL450MemoryModel + R"(
)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpLoad Pointer <id> '4' is not a pointer."));
}
TEST_F(ValidateIdWithMessage, OpStoreGood) {
OpFunctionEnd)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpStore Pointer <id> '3' is not a pointer."));
}
TEST_F(ValidateIdWithMessage, OpStoreObjectGood) {
string spirv = kGLSL450MemoryModel + R"(
OpFunctionEnd)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpStore Object <id> '7's type is void."));
}
TEST_F(ValidateIdWithMessage, OpStoreTypeBad) {
string spirv = kGLSL450MemoryModel + R"(
OpFunctionEnd)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpStore Pointer <id> '7's type does not match Object "
+ "<id> '3's type."));
}
TEST_F(ValidateIdWithMessage, OpStoreVoid) {
OpFunctionEnd)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpStore Object <id> '8's type is void."));
}
TEST_F(ValidateIdWithMessage, OpStoreLabel) {
OpFunctionEnd)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpStore Object <id> '7' is not an object."));
}
// TODO: enable when this bug is fixed:
)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpCopyMemory Target <id> '5's type does not match "
+ "Source <id> '2's type."));
}
// TODO: OpCopyMemorySized
OpFunctionEnd)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpCopyMemorySized Target <id> '9' is not a pointer."));
}
TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSourceBad) {
string spirv = kGLSL450MemoryModel + R"(
OpFunctionEnd)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpCopyMemorySized Source <id> '6' is not a pointer."));
}
TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSizeBad) {
string spirv = kGLSL450MemoryModel + R"(
OpFunctionEnd)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpCopyMemorySized Size <id> '6's variable type is not "
+ "an integer type."));
}
TEST_F(ValidateIdWithMessage, OpCopyMemorySizedSizeTypeBad) {
string spirv = kGLSL450MemoryModel + R"(
OpFunctionEnd)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "OpCopyMemorySized Size <id> '9's type is not an integer type."));
}
const char kDeeplyNestedStructureSetup[] = R"(
OpFunctionEnd)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpFunction Result Type <id> '2' does not match the "
+ "Function Type <id> '2's return type."));
}
TEST_F(ValidateIdWithMessage, OpFunctionFunctionTypeBad) {
string spirv = kGLSL450MemoryModel + R"(
OpFunctionEnd)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("OpFunction Function Type <id> '2' is not a function type."));
}
TEST_F(ValidateIdWithMessage, OpFunctionParameterGood) {
OpFunctionEnd)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("OpFunctionParameter Result Type <id> '1' does not match the "
+ "OpTypeFunction parameter type of the same index."));
}
TEST_F(ValidateIdWithMessage, OpFunctionCallGood) {
OpFunctionEnd)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("OpReturnValue Value <id> '1' does not represent a value."));
}
TEST_F(ValidateIdWithMessage, OpReturnValueIsLabel) {
OpFunctionEnd)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("OpReturnValue Value <id> '5' does not represent a value."));
}
TEST_F(ValidateIdWithMessage, OpReturnValueIsVoid) {
OpFunctionEnd)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("OpReturnValue value's type <id> '1' is missing or void."));
}
TEST_F(ValidateIdWithMessage, OpReturnValueIsVariableInPhysical) {
OpFunctionEnd)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpReturnValue value's type <id> '3' is a pointer, "
+ "which is invalid in the Logical addressing model."));
}
// TODO: enable when this bug is fixed:
)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Forward reference operands in an OpTypeStruct must "
+ "first be declared using OpTypeForwardPointer."));
}
TEST_F(ValidateIdWithMessage, UndefinedIdScope) {
)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(), HasSubstr("ID 7 has not been defined"));
}
TEST_F(ValidateIdWithMessage, UndefinedIdMemSem) {
)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(), HasSubstr("ID 7 has not been defined"));
}
TEST_F(ValidateIdWithMessage,
OpFunctionEnd)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("OpLoad type for pointer <id> '11' is not a pointer type."));
}
TEST_F(ValidateIdWithMessage, OpStoreBitcastPointerGood) {
string spirv = kOpenCLMemoryModel64 + R"(
OpFunctionEnd)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("OpStore type for pointer <id> '11' is not a pointer type."));
}
// Result <id> resulting from an instruction within a function may not be used