spirv-reader: GetMemoryObjectDeclarationForHandl can return null

It's valid to look for but not find an underlying memory object
declaration.

Bug: tint:109
Change-Id: I7296d79550a50050d2438996dc3e0c8d09a6babd
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/33140
Auto-Submit: David Neto <dneto@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
David Neto 2020-11-18 02:14:09 +00:00 committed by Commit Bot service account
parent 88091d3d17
commit 62c8f07015
3 changed files with 27 additions and 7 deletions

View File

@ -1579,8 +1579,12 @@ ParserImpl::GetMemoryObjectDeclarationForHandle(uint32_t id,
id = inst->GetSingleWordInOperand(0); id = inst->GetSingleWordInOperand(0);
break; break;
default: default:
// This is not valid. // Can't trace further.
return local_fail(); // Remember it as the answer for the whole path.
for (auto iter : visited) {
memo_table[iter] = nullptr;
}
return nullptr;
} }
} }
} }

View File

@ -379,14 +379,14 @@ class ParserImpl : Reader {
/// return the SPIR-V instruction that represents the memory object /// return the SPIR-V instruction that represents the memory object
/// declaration for the object. If we encounter an OpSampledImage along the /// declaration for the object. If we encounter an OpSampledImage along the
/// way, follow the image operand when follow_image is true; otherwise follow /// way, follow the image operand when follow_image is true; otherwise follow
/// the sampler operand. Returns null and emits an error if it can't trace /// the sampler operand. Returns nullptr if we can't trace back to a memory
/// back to a memory object declaration. /// object declaration. Emits an error and returns nullptr when the scan
/// This method can be used any time after BuildInternalModule has been /// fails due to a malformed module. This method can be used any time after
/// invoked. /// BuildInternalModule has been invoked.
/// @param id the SPIR-V ID of the sampler, image, or sampled image /// @param id the SPIR-V ID of the sampler, image, or sampled image
/// @param follow_image indicates whether to follow the image operand of /// @param follow_image indicates whether to follow the image operand of
/// OpSampledImage /// OpSampledImage
/// @returns the memory object declaration for the handle, or nullptr on error /// @returns the memory object declaration for the handle, or nullptr
const spvtools::opt::Instruction* GetMemoryObjectDeclarationForHandle( const spvtools::opt::Instruction* GetMemoryObjectDeclarationForHandle(
uint32_t id, uint32_t id,
bool follow_image); bool follow_image);

View File

@ -179,6 +179,22 @@ std::string CommonTypes() {
)"; )";
} }
TEST_F(SpvParserTest,
GetMemoryObjectDeclarationForHandle_WellFormedButNotAHandle) {
const auto assembly = Preamble() + CommonTypes() + R"(
%10 = OpConstantNull %ptr_sampler
%20 = OpConstantNull %ptr_f_texture_1d
)";
auto* p = parser(test::Assemble(assembly));
ASSERT_TRUE(p->BuildInternalModule());
const auto* sampler = p->GetMemoryObjectDeclarationForHandle(10, false);
const auto* image = p->GetMemoryObjectDeclarationForHandle(20, true);
EXPECT_EQ(sampler, nullptr);
EXPECT_EQ(image, nullptr);
EXPECT_TRUE(p->error().empty());
}
TEST_F(SpvParserTest, GetMemoryObjectDeclarationForHandle_Variable_Direct) { TEST_F(SpvParserTest, GetMemoryObjectDeclarationForHandle_Variable_Direct) {
const auto assembly = Preamble() + CommonTypes() + R"( const auto assembly = Preamble() + CommonTypes() + R"(
%10 = OpVariable %ptr_sampler UniformConstant %10 = OpVariable %ptr_sampler UniformConstant