diff --git a/source/val/validate.cpp b/source/val/validate.cpp index 6f1a26c6e5..e4123a4fb7 100644 --- a/source/val/validate.cpp +++ b/source/val/validate.cpp @@ -272,6 +272,7 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( return error; } + std::vector visited_entry_points; for (auto& instruction : vstate->ordered_instructions()) { { // In order to do this work outside of Process Instruction we need to be @@ -293,6 +294,24 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( vstate->RegisterEntryPoint(entry_point, execution_model, std::move(desc)); + + if (visited_entry_points.size() > 0) { + for (const Instruction* check_inst : visited_entry_points) { + const auto check_execution_model = + check_inst->GetOperandAs(0); + const char* check_str = reinterpret_cast( + check_inst->words().data() + inst->operand(2).offset); + const std::string check_name(check_str); + + if (desc.name == check_name && + execution_model == check_execution_model) { + return vstate->diag(SPV_ERROR_INVALID_DATA, inst) + << "2 Entry points cannot share the same name and " + "ExecutionMode."; + } + } + } + visited_entry_points.push_back(inst); } if (inst->opcode() == SpvOpFunctionCall) { if (!vstate->in_function_body()) { diff --git a/source/val/validate.h b/source/val/validate.h index b6c4072ee1..da3d0b8315 100644 --- a/source/val/validate.h +++ b/source/val/validate.h @@ -208,7 +208,7 @@ spv_result_t MiscPass(ValidationState_t& _, const Instruction* inst); spv_result_t ValidateExecutionLimitations(ValidationState_t& _, const Instruction* inst); -/// Validates restricted uses of 8- and 16-bit types. +/// Validates restricted uses of 8- and 16-bit types. /// /// Validates shaders that uses 8- or 16-bit storage capabilities, but not full /// capabilities only have appropriate uses of those types. diff --git a/test/val/CMakeLists.txt b/test/val/CMakeLists.txt index b6937b1107..d4bfe1d0c7 100644 --- a/test/val/CMakeLists.txt +++ b/test/val/CMakeLists.txt @@ -35,6 +35,7 @@ add_spvtools_unittest(TARGET val_abcde val_data_test.cpp val_decoration_test.cpp val_derivatives_test.cpp + val_entry_point.cpp val_explicit_reserved_test.cpp val_extensions_test.cpp val_ext_inst_test.cpp diff --git a/test/val/val_entry_point.cpp b/test/val/val_entry_point.cpp new file mode 100644 index 0000000000..f28cf5d19c --- /dev/null +++ b/test/val/val_entry_point.cpp @@ -0,0 +1,76 @@ +// Copyright (c) 2019 Samsung Inc +// +// 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 + +#include "gmock/gmock.h" +#include "test/unit_spirv.h" +#include "test/val/val_fixtures.h" + +namespace spvtools { +namespace { + +using ::testing::Eq; +using ::testing::HasSubstr; + +using ValidateEntryPoints = spvtest::ValidateBase; + +TEST_F(ValidateEntryPoints, DuplicateEntryPoints) { + const std::string body = R"( +OpCapability Shader +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %3 "foo" +OpEntryPoint GLCompute %4 "foo" +%1 = OpTypeVoid +%2 = OpTypeFunction %1 +%3 = OpFunction %1 None %2 +%20 = OpLabel +OpReturn +OpFunctionEnd +%4 = OpFunction %1 None %2 +%21 = OpLabel +OpReturn +OpFunctionEnd +)"; + + CompileSuccessfully(body); + EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Entry points cannot share the same name")); +} + +TEST_F(ValidateEntryPoints, UniqueEntryPoints) { + const std::string body = R"( +OpCapability Shader +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %3 "foo" +OpEntryPoint GLCompute %4 "foo2" +%1 = OpTypeVoid +%2 = OpTypeFunction %1 +%3 = OpFunction %1 None %2 +%20 = OpLabel +OpReturn +OpFunctionEnd +%4 = OpFunction %1 None %2 +%21 = OpLabel +OpReturn +OpFunctionEnd +)"; + + CompileSuccessfully(body); + EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + +} // namespace +} // namespace spvtools diff --git a/utils/check_copyright.py b/utils/check_copyright.py index 5a95e32282..cfeef80a6f 100755 --- a/utils/check_copyright.py +++ b/utils/check_copyright.py @@ -30,7 +30,8 @@ 'LunarG Inc.', 'Google Inc.', 'Google LLC', - 'Pierre Moreau'] + 'Pierre Moreau', + 'Samsung Inc'] CURRENT_YEAR='2019' YEARS = '(2014-2016|2015-2016|2016|2016-2017|2017|2018|2019)'