Home | History | Annotate | Download | only in link
      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