// Copyright (c) 2017 Pierre Moreau // // 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. #include "gmock/gmock.h" #include "linker_fixture.h" namespace { using ::testing::HasSubstr; class EntryPoints : public spvtest::LinkerTest { public: EntryPoints() { binaries.reserve(0xFFFF); } virtual void SetUp() override { binaries.push_back({SpvMagicNumber, SpvVersion, SPV_GENERATOR_CODEPLAY, 10u, // NOTE: Bound 0u, // NOTE: Schema; reserved 3u << SpvWordCountShift | SpvOpTypeFloat, 1u, // NOTE: Result ID 32u, // NOTE: Width 4u << SpvWordCountShift | SpvOpTypePointer, 2u, // NOTE: Result ID SpvStorageClassInput, 1u, // NOTE: Type ID 2u << SpvWordCountShift | SpvOpTypeVoid, 3u, // NOTE: Result ID 3u << SpvWordCountShift | SpvOpTypeFunction, 4u, // NOTE: Result ID 3u, // NOTE: Return type 5u << SpvWordCountShift | SpvOpFunction, 3u, // NOTE: Result type 5u, // NOTE: Result ID SpvFunctionControlMaskNone, 4u, // NOTE: Function type 2u << SpvWordCountShift | SpvOpLabel, 6u, // NOTE: Result ID 4u << SpvWordCountShift | SpvOpVariable, 2u, // NOTE: Type ID 7u, // NOTE: Result ID SpvStorageClassFunction, 4u << SpvWordCountShift | SpvOpVariable, 2u, // NOTE: Type ID 8u, // NOTE: Result ID SpvStorageClassFunction, 4u << SpvWordCountShift | SpvOpVariable, 2u, // NOTE: Type ID 9u, // NOTE: Result ID SpvStorageClassFunction, 1u << SpvWordCountShift | SpvOpReturn, 1u << SpvWordCountShift | SpvOpFunctionEnd}); for (size_t i = 0u; i < 2u; ++i) { spvtest::Binary binary = { SpvMagicNumber, SpvVersion, SPV_GENERATOR_CODEPLAY, 103u, // NOTE: Bound 0u, // NOTE: Schema; reserved 3u << SpvWordCountShift | SpvOpTypeFloat, 1u, // NOTE: Result ID 32u, // NOTE: Width 4u << SpvWordCountShift | SpvOpTypePointer, 2u, // NOTE: Result ID SpvStorageClassInput, 1u // NOTE: Type ID }; for (uint32_t j = 0u; j < 0xFFFFu / 2u; ++j) { binary.push_back(4u << SpvWordCountShift | SpvOpVariable); binary.push_back(2u); // NOTE: Type ID binary.push_back(j + 3u); // NOTE: Result ID binary.push_back(SpvStorageClassInput); } binaries.push_back(binary); } } virtual void TearDown() override { binaries.clear(); } spvtest::Binaries binaries; }; TEST_F(EntryPoints, UnderLimit) { spvtest::Binary linked_binary; EXPECT_EQ(SPV_SUCCESS, Link(binaries, &linked_binary)); EXPECT_THAT(GetErrorMessage(), std::string()); } TEST_F(EntryPoints, OverLimit) { binaries.push_back({SpvMagicNumber, SpvVersion, SPV_GENERATOR_CODEPLAY, 5u, // NOTE: Bound 0u, // NOTE: Schema; reserved 3u << SpvWordCountShift | SpvOpTypeFloat, 1u, // NOTE: Result ID 32u, // NOTE: Width 4u << SpvWordCountShift | SpvOpTypePointer, 2u, // NOTE: Result ID SpvStorageClassInput, 1u, // NOTE: Type ID 4u << SpvWordCountShift | SpvOpVariable, 2u, // NOTE: Type ID 3u, // NOTE: Result ID SpvStorageClassInput, 4u << SpvWordCountShift | SpvOpVariable, 2u, // NOTE: Type ID 4u, // NOTE: Result ID SpvStorageClassInput}); spvtest::Binary linked_binary; EXPECT_EQ(SPV_ERROR_INTERNAL, Link(binaries, &linked_binary)); EXPECT_THAT(GetErrorMessage(), HasSubstr("The limit of global values, 65535, was exceeded; " "65536 global values were found.")); } } // anonymous namespace