1 // Copyright (c) 2017 Pierre Moreau 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include <string> 16 17 #include "gmock/gmock.h" 18 #include "test/link/linker_fixture.h" 19 20 namespace spvtools { 21 namespace { 22 23 using ::testing::HasSubstr; 24 25 class EntryPointsAmountTest : public spvtest::LinkerTest { 26 public: 27 EntryPointsAmountTest() { binaries.reserve(0xFFFF); } 28 29 void SetUp() override { 30 binaries.push_back({SpvMagicNumber, 31 SpvVersion, 32 SPV_GENERATOR_CODEPLAY, 33 10u, // NOTE: Bound 34 0u, // NOTE: Schema; reserved 35 36 3u << SpvWordCountShift | SpvOpTypeFloat, 37 1u, // NOTE: Result ID 38 32u, // NOTE: Width 39 40 4u << SpvWordCountShift | SpvOpTypePointer, 41 2u, // NOTE: Result ID 42 SpvStorageClassInput, 43 1u, // NOTE: Type ID 44 45 2u << SpvWordCountShift | SpvOpTypeVoid, 46 3u, // NOTE: Result ID 47 48 3u << SpvWordCountShift | SpvOpTypeFunction, 49 4u, // NOTE: Result ID 50 3u, // NOTE: Return type 51 52 5u << SpvWordCountShift | SpvOpFunction, 53 3u, // NOTE: Result type 54 5u, // NOTE: Result ID 55 SpvFunctionControlMaskNone, 56 4u, // NOTE: Function type 57 58 2u << SpvWordCountShift | SpvOpLabel, 59 6u, // NOTE: Result ID 60 61 4u << SpvWordCountShift | SpvOpVariable, 62 2u, // NOTE: Type ID 63 7u, // NOTE: Result ID 64 SpvStorageClassFunction, 65 66 4u << SpvWordCountShift | SpvOpVariable, 67 2u, // NOTE: Type ID 68 8u, // NOTE: Result ID 69 SpvStorageClassFunction, 70 71 4u << SpvWordCountShift | SpvOpVariable, 72 2u, // NOTE: Type ID 73 9u, // NOTE: Result ID 74 SpvStorageClassFunction, 75 76 1u << SpvWordCountShift | SpvOpReturn, 77 78 1u << SpvWordCountShift | SpvOpFunctionEnd}); 79 for (size_t i = 0u; i < 2u; ++i) { 80 spvtest::Binary binary = { 81 SpvMagicNumber, 82 SpvVersion, 83 SPV_GENERATOR_CODEPLAY, 84 103u, // NOTE: Bound 85 0u, // NOTE: Schema; reserved 86 87 3u << SpvWordCountShift | SpvOpTypeFloat, 88 1u, // NOTE: Result ID 89 32u, // NOTE: Width 90 91 4u << SpvWordCountShift | SpvOpTypePointer, 92 2u, // NOTE: Result ID 93 SpvStorageClassInput, 94 1u // NOTE: Type ID 95 }; 96 97 for (uint32_t j = 0u; j < 0xFFFFu / 2u; ++j) { 98 binary.push_back(4u << SpvWordCountShift | SpvOpVariable); 99 binary.push_back(2u); // NOTE: Type ID 100 binary.push_back(j + 3u); // NOTE: Result ID 101 binary.push_back(SpvStorageClassInput); 102 } 103 binaries.push_back(binary); 104 } 105 } 106 void TearDown() override { binaries.clear(); } 107 108 spvtest::Binaries binaries; 109 }; 110 111 TEST_F(EntryPointsAmountTest, UnderLimit) { 112 spvtest::Binary linked_binary; 113 114 EXPECT_EQ(SPV_SUCCESS, Link(binaries, &linked_binary)); 115 EXPECT_THAT(GetErrorMessage(), std::string()); 116 } 117 118 TEST_F(EntryPointsAmountTest, OverLimit) { 119 binaries.push_back({SpvMagicNumber, 120 SpvVersion, 121 SPV_GENERATOR_CODEPLAY, 122 5u, // NOTE: Bound 123 0u, // NOTE: Schema; reserved 124 125 3u << SpvWordCountShift | SpvOpTypeFloat, 126 1u, // NOTE: Result ID 127 32u, // NOTE: Width 128 129 4u << SpvWordCountShift | SpvOpTypePointer, 130 2u, // NOTE: Result ID 131 SpvStorageClassInput, 132 1u, // NOTE: Type ID 133 134 4u << SpvWordCountShift | SpvOpVariable, 135 2u, // NOTE: Type ID 136 3u, // NOTE: Result ID 137 SpvStorageClassInput, 138 139 4u << SpvWordCountShift | SpvOpVariable, 140 2u, // NOTE: Type ID 141 4u, // NOTE: Result ID 142 SpvStorageClassInput}); 143 144 spvtest::Binary linked_binary; 145 146 EXPECT_EQ(SPV_ERROR_INTERNAL, Link(binaries, &linked_binary)); 147 EXPECT_THAT(GetErrorMessage(), 148 HasSubstr("The limit of global values, 65535, was exceeded; " 149 "65536 global values were found.")); 150 } 151 152 } // namespace 153 } // namespace spvtools 154