bool ValidationState_t::in_function_body() const { return in_function_; }
bool ValidationState_t::in_block() const {
- return module_functions_.back().get_current_block() != nullptr;
+ return module_functions_.empty() == false &&
+ module_functions_.back().get_current_block() != nullptr;
}
void ValidationState_t::RegisterCapability(SpvCapability cap) {
break;
default:
- if (_.getLayoutSection() == kLayoutFunctionDeclarations) {
+ if (_.getLayoutSection() == kLayoutFunctionDeclarations &&
+ _.in_function_body()) {
return _.diag(SPV_ERROR_INVALID_LAYOUT)
<< "A function must begin with a label";
} else {
using std::tuple;
using std::vector;
-using ::testing::HasSubstr;
+using ::testing::StrEq;
using libspirv::spvResultToString;
ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions());
}
+TEST_F(ValidateLayout, InstructionAppearBeforeFunctionDefinition) {
+ string str = R"(
+ OpCapability Kernel
+ OpMemoryModel Logical OpenCL
+%voidt = OpTypeVoid
+%uintt = OpTypeInt 32 0
+%funct = OpTypeFunction %voidt
+%udef = OpUndef %uintt
+%func = OpFunction %voidt None %funct
+%entry = OpLabel
+ OpReturn
+ OpFunctionEnd
+)";
+
+ CompileSuccessfully(str);
+ ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(), StrEq("Undef must appear in a block"));
+}
+
using ValidateOpFunctionParameter = spvtest::ValidateBase<int>;
TEST_F(ValidateOpFunctionParameter, OpLineBetweenParameters) {