1// Copyright (c) 2018 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 20namespace spvtools { 21namespace { 22 23using ::testing::HasSubstr; 24using PartialLinkage = spvtest::LinkerTest; 25 26TEST_F(PartialLinkage, Allowed) { 27 const std::string body1 = R"( 28OpCapability Linkage 29OpCapability Addresses 30OpCapability Kernel 31OpMemoryModel Physical64 OpenCL 32OpDecorate %1 LinkageAttributes "foo" Import 33OpDecorate %2 LinkageAttributes "bar" Import 34%3 = OpTypeFloat 32 35%1 = OpVariable %3 Uniform 36%2 = OpVariable %3 Uniform 37)"; 38 const std::string body2 = R"( 39OpCapability Linkage 40OpCapability Addresses 41OpCapability Kernel 42OpMemoryModel Physical64 OpenCL 43OpDecorate %1 LinkageAttributes "bar" Export 44%2 = OpTypeFloat 32 45%3 = OpConstant %2 3.1415 46%1 = OpVariable %2 Uniform %3 47)"; 48 49 spvtest::Binary linked_binary; 50 LinkerOptions linker_options; 51 linker_options.SetAllowPartialLinkage(true); 52 ASSERT_EQ(SPV_SUCCESS, 53 AssembleAndLink({body1, body2}, &linked_binary, linker_options)) 54 << GetErrorMessage(); 55 56 const std::string expected_res = R"(OpCapability Linkage 57OpCapability Addresses 58OpCapability Kernel 59OpMemoryModel Physical64 OpenCL 60OpModuleProcessed "Linked by SPIR-V Tools Linker" 61OpDecorate %1 LinkageAttributes "foo" Import 62%2 = OpTypeFloat 32 63%1 = OpVariable %2 Uniform 64%3 = OpConstant %2 3.1415 65%4 = OpVariable %2 Uniform %3 66)"; 67 std::string res_body; 68 SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER); 69 ASSERT_EQ(SPV_SUCCESS, Disassemble(linked_binary, &res_body)) 70 << GetErrorMessage(); 71 EXPECT_EQ(expected_res, res_body); 72} 73 74TEST_F(PartialLinkage, Disallowed) { 75 const std::string body1 = R"( 76OpCapability Linkage 77OpCapability Addresses 78OpCapability Kernel 79OpMemoryModel Physical64 OpenCL 80OpDecorate %1 LinkageAttributes "foo" Import 81OpDecorate %2 LinkageAttributes "bar" Import 82%3 = OpTypeFloat 32 83%1 = OpVariable %3 Uniform 84%2 = OpVariable %3 Uniform 85)"; 86 const std::string body2 = R"( 87OpCapability Linkage 88OpCapability Addresses 89OpCapability Kernel 90OpMemoryModel Physical64 OpenCL 91OpDecorate %1 LinkageAttributes "bar" Export 92%2 = OpTypeFloat 32 93%3 = OpConstant %2 3.1415 94%1 = OpVariable %2 Uniform %3 95)"; 96 97 spvtest::Binary linked_binary; 98 EXPECT_EQ(SPV_ERROR_INVALID_BINARY, 99 AssembleAndLink({body1, body2}, &linked_binary)); 100 EXPECT_THAT(GetErrorMessage(), 101 HasSubstr("Unresolved external reference to \"foo\".")); 102} 103 104} // namespace 105} // namespace spvtools 106