}
}
-int32_t spvOpcodeIsObject(const SpvOp opcode) {
- switch (opcode) {
- case SpvOpConstantTrue:
- case SpvOpConstantFalse:
- case SpvOpConstant:
- case SpvOpConstantComposite:
- // TODO: case SpvOpConstantSampler:
- case SpvOpConstantNull:
- case SpvOpSpecConstantTrue:
- case SpvOpSpecConstantFalse:
- case SpvOpSpecConstant:
- case SpvOpSpecConstantComposite:
- // TODO: case SpvOpSpecConstantOp:
- case SpvOpVariable:
- case SpvOpAccessChain:
- case SpvOpInBoundsAccessChain:
- case SpvOpConvertFToU:
- case SpvOpConvertFToS:
- case SpvOpConvertSToF:
- case SpvOpConvertUToF:
- case SpvOpUConvert:
- case SpvOpSConvert:
- case SpvOpFConvert:
- case SpvOpConvertPtrToU:
- // TODO: case SpvOpConvertUToPtr:
- case SpvOpPtrCastToGeneric:
- // TODO: case SpvOpGenericCastToPtr:
- case SpvOpBitcast:
- // TODO: case SpvOpGenericCastToPtrExplicit:
- case SpvOpSatConvertSToU:
- case SpvOpSatConvertUToS:
- case SpvOpVectorExtractDynamic:
- case SpvOpCompositeConstruct:
- case SpvOpCompositeExtract:
- case SpvOpCopyObject:
- case SpvOpTranspose:
- case SpvOpSNegate:
- case SpvOpFNegate:
- case SpvOpNot:
- case SpvOpIAdd:
- case SpvOpFAdd:
- case SpvOpISub:
- case SpvOpFSub:
- case SpvOpIMul:
- case SpvOpFMul:
- case SpvOpUDiv:
- case SpvOpSDiv:
- case SpvOpFDiv:
- case SpvOpUMod:
- case SpvOpSRem:
- case SpvOpSMod:
- case SpvOpVectorTimesScalar:
- case SpvOpMatrixTimesScalar:
- case SpvOpVectorTimesMatrix:
- case SpvOpMatrixTimesVector:
- case SpvOpMatrixTimesMatrix:
- case SpvOpOuterProduct:
- case SpvOpDot:
- case SpvOpShiftRightLogical:
- case SpvOpShiftRightArithmetic:
- case SpvOpShiftLeftLogical:
- case SpvOpBitwiseOr:
- case SpvOpBitwiseXor:
- case SpvOpBitwiseAnd:
- case SpvOpAny:
- case SpvOpAll:
- case SpvOpIsNan:
- case SpvOpIsInf:
- case SpvOpIsFinite:
- case SpvOpIsNormal:
- case SpvOpSignBitSet:
- case SpvOpLessOrGreater:
- case SpvOpOrdered:
- case SpvOpUnordered:
- case SpvOpLogicalOr:
- case SpvOpLogicalAnd:
- case SpvOpSelect:
- case SpvOpIEqual:
- case SpvOpFOrdEqual:
- case SpvOpFUnordEqual:
- case SpvOpINotEqual:
- case SpvOpFOrdNotEqual:
- case SpvOpFUnordNotEqual:
- case SpvOpULessThan:
- case SpvOpSLessThan:
- case SpvOpFOrdLessThan:
- case SpvOpFUnordLessThan:
- case SpvOpUGreaterThan:
- case SpvOpSGreaterThan:
- case SpvOpFOrdGreaterThan:
- case SpvOpFUnordGreaterThan:
- case SpvOpULessThanEqual:
- case SpvOpSLessThanEqual:
- case SpvOpFOrdLessThanEqual:
- case SpvOpFUnordLessThanEqual:
- case SpvOpUGreaterThanEqual:
- case SpvOpSGreaterThanEqual:
- case SpvOpFOrdGreaterThanEqual:
- case SpvOpFUnordGreaterThanEqual:
- case SpvOpDPdx:
- case SpvOpDPdy:
- case SpvOpFwidth:
- case SpvOpDPdxFine:
- case SpvOpDPdyFine:
- case SpvOpFwidthFine:
- case SpvOpDPdxCoarse:
- case SpvOpDPdyCoarse:
- case SpvOpFwidthCoarse:
- case SpvOpReturnValue:
- return true;
- default:
- return false;
- }
-}
-
int32_t spvOpcodeIsBasicTypeNullable(SpvOp opcode) {
switch (opcode) {
case SpvOpTypeBool:
<< "'s function parameter count is not zero.";
return false;
}
- auto returnType = usedefs_.FindDef(entryPoint.second.words[1]);
+ auto returnType = usedefs_.FindDef(entryPoint.second.type_id);
if (!returnType.first || SpvOpTypeVoid != returnType.second.opcode) {
DIAG(entryPointIndex) << "OpEntryPoint Entry Point <id> '"
<< inst->words[entryPointIndex]
return false;
}
auto constituentResultType =
- usedefs_.FindDef(constituent.second.words[1]);
+ usedefs_.FindDef(constituent.second.type_id);
if (!constituentResultType.first ||
componentType.second.opcode !=
constituentResultType.second.opcode) {
<< "' is not a constant composite.";
return false;
}
- auto vector = usedefs_.FindDef(constituent.second.words[1]);
+ auto vector = usedefs_.FindDef(constituent.second.type_id);
assert(vector.first);
spvCheck(columnType.second.opcode != vector.second.opcode,
DIAG(constituentIndex)
<< "' is not a constant.";
return false;
}
- auto constituentType = usedefs_.FindDef(constituent.second.words[1]);
+ auto constituentType = usedefs_.FindDef(constituent.second.type_id);
assert(constituentType.first);
spvCheck(elementType.second.id != constituentType.second.id,
DIAG(constituentIndex)
<< "' is not a constant.";
return false;
}
- auto constituentType = usedefs_.FindDef(constituent.second.words[1]);
+ auto constituentType = usedefs_.FindDef(constituent.second.type_id);
assert(constituentType.first);
auto memberType =
<< "' is not a pointer.";
return false;
}
- auto pointerType = usedefs_.FindDef(pointer.second.words[1]);
+ auto pointerType = usedefs_.FindDef(pointer.second.type_id);
if (!pointerType.first || pointerType.second.opcode != SpvOpTypePointer) {
DIAG(pointerIndex) << "OpLoad type for pointer <id> '"
<< inst->words[pointerIndex]
<< "' is not a pointer.";
return false;
}
- auto pointerType = usedefs_.FindDef(pointer.second.words[1]);
+ auto pointerType = usedefs_.FindDef(pointer.second.type_id);
assert(pointerType.first);
auto type = usedefs_.FindDef(pointerType.second.words[3]);
assert(type.first);
auto objectIndex = 2;
auto object = usedefs_.FindDef(inst->words[objectIndex]);
- if (!object.first || !spvOpcodeIsObject(object.second.opcode)) {
+ if (!object.first || !object.second.type_id) {
DIAG(objectIndex) << "OpStore Object <id> '" << inst->words[objectIndex]
- << "' in not an object.";
+ << "' is not an object.";
return false;
}
- auto objectType = usedefs_.FindDef(object.second.words[1]);
+ auto objectType = usedefs_.FindDef(object.second.type_id);
assert(objectType.first);
spvCheck(SpvOpTypeVoid == objectType.second.opcode,
DIAG(objectIndex) << "OpStore Object <id> '"
auto sourceIndex = 2;
auto source = usedefs_.FindDef(inst->words[sourceIndex]);
if (!source.first) return false;
- auto targetPointerType = usedefs_.FindDef(target.second.words[1]);
+ auto targetPointerType = usedefs_.FindDef(target.second.type_id);
assert(targetPointerType.first);
auto targetType = usedefs_.FindDef(targetPointerType.second.words[3]);
assert(targetType.first);
- auto sourcePointerType = usedefs_.FindDef(source.second.words[1]);
+ auto sourcePointerType = usedefs_.FindDef(source.second.type_id);
assert(sourcePointerType.first);
auto sourceType = usedefs_.FindDef(sourcePointerType.second.words[3]);
assert(sourceType.first);
auto sizeIndex = 3;
auto size = usedefs_.FindDef(inst->words[sizeIndex]);
if (!size.first) return false;
- auto targetPointerType = usedefs_.FindDef(target.second.words[1]);
- assert(targetPointerType.first);
- spvCheck(SpvOpTypePointer != targetPointerType.second.opcode,
+ auto targetPointerType = usedefs_.FindDef(target.second.type_id);
+ spvCheck(!targetPointerType.first ||
+ SpvOpTypePointer != targetPointerType.second.opcode,
DIAG(targetIndex) << "OpCopyMemorySized Target <id> '"
<< inst->words[targetIndex]
<< "' is not a pointer.";
return false);
- auto sourcePointerType = usedefs_.FindDef(source.second.words[1]);
- assert(sourcePointerType.first);
- spvCheck(SpvOpTypePointer != sourcePointerType.second.opcode,
+ auto sourcePointerType = usedefs_.FindDef(source.second.type_id);
+ spvCheck(!sourcePointerType.first ||
+ SpvOpTypePointer != sourcePointerType.second.opcode,
DIAG(sourceIndex) << "OpCopyMemorySized Source <id> '"
<< inst->words[sourceIndex]
<< "' is not a pointer.";
// clarification
case SpvOpConstant:
case SpvOpSpecConstant: {
- auto sizeType = usedefs_.FindDef(size.second.words[1]);
+ auto sizeType = usedefs_.FindDef(size.second.type_id);
assert(sizeType.first);
spvCheck(SpvOpTypeInt != sizeType.second.opcode,
DIAG(sizeIndex) << "OpCopyMemorySized Size <id> '"
return false);
} break;
case SpvOpVariable: {
- auto pointerType = usedefs_.FindDef(size.second.words[1]);
+ auto pointerType = usedefs_.FindDef(size.second.type_id);
assert(pointerType.first);
- auto sizeType = usedefs_.FindDef(pointerType.second.words[1]);
- assert(sizeType.first);
- spvCheck(SpvOpTypeInt != sizeType.second.opcode,
+ auto sizeType = usedefs_.FindDef(pointerType.second.type_id);
+ spvCheck(!sizeType.first || SpvOpTypeInt != sizeType.second.opcode,
DIAG(sizeIndex) << "OpCopyMemorySized Size <id> '"
<< inst->words[sizeIndex]
<< "'s variable type is not an integer type.";
<< inst->words[functionIndex] << "' is not a function.";
return false;
}
- auto returnType = usedefs_.FindDef(function.second.words[1]);
+ auto returnType = usedefs_.FindDef(function.second.type_id);
assert(returnType.first);
spvCheck(returnType.second.id != resultType.second.id,
DIAG(resultTypeIndex) << "OpFunctionCall Result Type <id> '"
argumentIndex < inst->words.size(); argumentIndex++, paramIndex++) {
auto argument = usedefs_.FindDef(inst->words[argumentIndex]);
if (!argument.first) return false;
- auto argumentType = usedefs_.FindDef(argument.second.words[1]);
+ auto argumentType = usedefs_.FindDef(argument.second.type_id);
assert(argumentType.first);
auto parameterType =
usedefs_.FindDef(functionType.second.words[paramIndex]);
<< "' does not represent a value.";
return false;
}
- auto valueType = usedefs_.FindDef(value.second.words[1]);
+ auto valueType = usedefs_.FindDef(value.second.type_id);
assert(valueType.first);
// NOTE: Find OpFunction
const spv_instruction_t* function = inst - 1;
#define CASE(OpCode) \
case Spv##OpCode: \
return isValid<Spv##OpCode>(inst, opcodeEntry);
-#define TODO(OpCode) \
- case Spv##OpCode: \
+#define TODO(OpCode) \
+ case Spv##OpCode: \
return true;
switch (inst->opcode) {
TODO(OpUndef)
CHECK(spirv, SPV_ERROR_INVALID_ID);
}
+TEST_F(ValidateID, OpStoreVoid) {
+ const char* spirv = R"(
+%1 = OpTypeVoid
+%2 = OpTypeInt 32 1
+%3 = OpTypePointer UniformConstant %2
+%4 = OpTypeFunction %1
+%6 = OpVariable %3 UniformConstant
+%7 = OpFunction %1 None %4
+%8 = OpLabel
+%9 = OpFunctionCall %1 %7
+ OpStore %6 %9
+ OpReturn
+ OpFunctionEnd)";
+ CHECK(spirv, SPV_ERROR_INVALID_ID);
+}
+
+TEST_F(ValidateID, OpStoreLabel) {
+ const char* spirv = R"(
+%1 = OpTypeVoid
+%2 = OpTypeInt 32 1
+%3 = OpTypePointer UniformConstant %2
+%4 = OpTypeFunction %1
+%6 = OpVariable %3 UniformConstant
+%7 = OpFunction %1 None %4
+%8 = OpLabel
+ OpStore %6 %8
+ OpReturn
+ OpFunctionEnd)";
+ CHECK(spirv, SPV_ERROR_INVALID_ID);
+}
+
+// TODO: enable when this bug is fixed: https://cvs.khronos.org/bugzilla/show_bug.cgi?id=15404
+TEST_F(ValidateID, DISABLED_OpStoreFunction) {
+ const char* spirv = R"(
+%2 = OpTypeInt 32 1
+%3 = OpTypePointer UniformConstant %2
+%4 = OpTypeFunction %2
+%5 = OpConstant %2 123
+%6 = OpVariable %3 UniformConstant
+%7 = OpFunction %2 None %4
+%8 = OpLabel
+ OpStore %6 %7
+ OpReturnValue %5
+ OpFunctionEnd)";
+ CHECK(spirv, SPV_ERROR_INVALID_ID);
+}
+
TEST_F(ValidateID, OpCopyMemoryGood) {
const char* spirv = R"(
%1 = OpTypeVoid