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:
EntryPointsAmountTest()27 EntryPointsAmountTest() { binaries.reserve(0xFFFF); }
28
SetUp()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 }
TearDown()106 void TearDown() override { binaries.clear(); }
107
108 spvtest::Binaries binaries;
109 };
110
TEST_F(EntryPointsAmountTest,UnderLimit)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
TEST_F(EntryPointsAmountTest,OverLimit)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