// Copyright (c) 2017 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Validation tests for ilegal literals #include #include #include "gmock/gmock.h" #include "test/val/val_fixtures.h" namespace spvtools { namespace val { namespace { using ::testing::HasSubstr; using ValidateLiterals = spvtest::ValidateBase; using ValidateLiteralsShader = spvtest::ValidateBase; using ValidateLiteralsKernel = spvtest::ValidateBase; std::string GenerateShaderCode() { std::string str = R"( OpCapability Shader OpCapability Linkage OpCapability Int16 OpCapability Int64 OpCapability Float16 OpCapability Float64 OpMemoryModel Logical GLSL450 %int16 = OpTypeInt 16 1 %uint16 = OpTypeInt 16 0 %int32 = OpTypeInt 32 1 %uint32 = OpTypeInt 32 0 %int64 = OpTypeInt 64 1 %uint64 = OpTypeInt 64 0 %half = OpTypeFloat 16 %float = OpTypeFloat 32 %double = OpTypeFloat 64 %10 = OpTypeVoid )"; return str; } std::string GenerateKernelCode() { std::string str = R"( OpCapability Kernel OpCapability Addresses OpCapability Linkage OpCapability Int8 OpMemoryModel Physical64 OpenCL %uint8 = OpTypeInt 8 0 )"; return str; } TEST_F(ValidateLiterals, LiteralsShaderGood) { std::string str = GenerateShaderCode() + R"( %11 = OpConstant %int16 !0x00007FFF %12 = OpConstant %int16 !0xFFFF8000 %13 = OpConstant %int16 !0xFFFFABCD %14 = OpConstant %uint16 !0x0000ABCD %15 = OpConstant %int16 -32768 %16 = OpConstant %uint16 65535 %17 = OpConstant %int32 -2147483648 %18 = OpConstant %uint32 4294967295 %19 = OpConstant %int64 -9223372036854775808 %20 = OpConstant %uint64 18446744073709551615 %21 = OpConstant %half !0x0000FFFF %22 = OpConstant %float !0xFFFFFFFF %23 = OpConstant %double !0xFFFFFFFF !0xFFFFFFFF )"; CompileSuccessfully(str); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } TEST_P(ValidateLiteralsShader, LiteralsShaderBad) { std::string str = GenerateShaderCode() + GetParam(); std::string inst_id = "11"; CompileSuccessfully(str); EXPECT_EQ(SPV_ERROR_INVALID_VALUE, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), HasSubstr("The high-order bits of a literal number in instruction " + inst_id + " must be 0 for a floating-point type, " "or 0 for an integer type with Signedness of 0, " "or sign extended when Signedness is 1")); } INSTANTIATE_TEST_CASE_P( LiteralsShaderCases, ValidateLiteralsShader, ::testing::Values("%11 = OpConstant %int16 !0xFFFF0000", // Sign bit is 0 "%11 = OpConstant %int16 !0x00008000", // Sign bit is 1 "%11 = OpConstant %int16 !0xABCD8000", // Sign bit is 1 "%11 = OpConstant %int16 !0xABCD0000", "%11 = OpConstant %uint16 !0xABCD0000", "%11 = OpConstant %half !0xABCD0000", "%11 = OpConstant %half !0x00010000")); TEST_F(ValidateLiterals, LiteralsKernelGood) { std::string str = GenerateKernelCode() + R"( %4 = OpConstant %uint8 !0x000000AB %6 = OpConstant %uint8 255 )"; CompileSuccessfully(str); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } TEST_P(ValidateLiteralsKernel, LiteralsKernelBad) { std::string str = GenerateKernelCode() + GetParam(); std::string inst_id = "2"; CompileSuccessfully(str); EXPECT_EQ(SPV_ERROR_INVALID_VALUE, ValidateInstructions()); EXPECT_THAT( getDiagnosticString(), HasSubstr("The high-order bits of a literal number in instruction " + inst_id + " must be 0 for a floating-point type, " "or 0 for an integer type with Signedness of 0, " "or sign extended when Signedness is 1")); } INSTANTIATE_TEST_CASE_P( LiteralsKernelCases, ValidateLiteralsKernel, ::testing::Values("%2 = OpConstant %uint8 !0xABCDEF00", "%2 = OpConstant %uint8 !0xABCDEFFF")); } // namespace } // namespace val } // namespace spvtools