Skip to content

Commit 40eb301

Browse files
authored
spirv-opt: Fix crash if shader uses linkage decoration (KhronosGroup#6191)
As for some optimization pass, which will get all operands of decoration and add these to type. We assume that these operands are always one word. As for linkage attributes decoration, it's an error because one of operand is literal string, that means that operand is variable length word.
1 parent 604c3e7 commit 40eb301

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

source/opt/type_manager.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1067,7 +1067,11 @@ void TypeManager::AttachDecoration(const Instruction& inst, Type* type) {
10671067
const auto count = inst.NumOperands();
10681068
std::vector<uint32_t> data;
10691069
for (uint32_t i = 1; i < count; ++i) {
1070-
data.push_back(inst.GetSingleWordOperand(i));
1070+
// LinkageAttributes has a literal string as an operand, which is a
1071+
// varible length word. We cannot assume that all operands are single
1072+
// word.
1073+
const Operand::OperandData& words = inst.GetOperand(i).words;
1074+
data.insert(data.end(), words.begin(), words.end());
10711075
}
10721076
type->AddDecoration(std::move(data));
10731077
} break;

test/opt/type_manager_test.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,6 +1248,35 @@ TEST(TypeManager, CircularPointerToStruct) {
12481248
EXPECT_EQ(id, 1201);
12491249
}
12501250

1251+
TEST(TypeManager, AttachLinkageDecoration) {
1252+
const std::string text = R"(
1253+
OpCapability Shader
1254+
OpCapability Linkage
1255+
OpMemoryModel Logical GLSL450
1256+
OpDecorate %1000 LinkageAttributes "_1000" Export
1257+
%800 = OpTypeInt 32 0
1258+
%1000 = OpTypeStruct %800
1259+
%1200 = OpTypeStruct %800
1260+
)";
1261+
1262+
std::unique_ptr<IRContext> context =
1263+
BuildModule(SPV_ENV_UNIVERSAL_1_5, nullptr, text,
1264+
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
1265+
TypeManager manager(nullptr, context.get());
1266+
1267+
constexpr uint32_t source_id = 1000u;
1268+
constexpr uint32_t target_id = 1200u;
1269+
std::vector<Instruction*> decorations =
1270+
context->get_decoration_mgr()->GetDecorationsFor(source_id, true);
1271+
Type* type = context->get_type_mgr()->GetType(target_id);
1272+
for (auto dec : decorations) {
1273+
manager.AttachDecoration(*dec, type);
1274+
}
1275+
EXPECT_FALSE(type->decoration_empty());
1276+
EXPECT_TRUE(
1277+
type->HasSameDecorations(context->get_type_mgr()->GetType(source_id)));
1278+
}
1279+
12511280
} // namespace
12521281
} // namespace analysis
12531282
} // namespace opt

0 commit comments

Comments
 (0)