Don't emit duplicate decorations. (#3635)

It is invalid if the same decoration is applied to the same id multiple
times. This adds a check before adding a decoration that the decoration
is not already in the list. If it is, then the duplicate is not added.

Fixes #3627
This commit is contained in:
Steven Perron 2024-06-28 19:16:59 -04:00 committed by GitHub
parent 7c40de7aa2
commit 33c7e30860
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
575 changed files with 3482 additions and 3414 deletions

View file

@ -1979,7 +1979,7 @@ void Builder::addDecoration(Id id, Decoration decoration, int num)
if (num >= 0)
dec->addImmediateOperand(num);
decorations.push_back(std::unique_ptr<Instruction>(dec));
decorations.insert(std::unique_ptr<Instruction>(dec));
}
void Builder::addDecoration(Id id, Decoration decoration, const char* s)
@ -1993,7 +1993,7 @@ void Builder::addDecoration(Id id, Decoration decoration, const char* s)
dec->addImmediateOperand(decoration);
dec->addStringOperand(s);
decorations.push_back(std::unique_ptr<Instruction>(dec));
decorations.insert(std::unique_ptr<Instruction>(dec));
}
void Builder::addDecoration(Id id, Decoration decoration, const std::vector<unsigned>& literals)
@ -2008,7 +2008,7 @@ void Builder::addDecoration(Id id, Decoration decoration, const std::vector<unsi
for (auto literal : literals)
dec->addImmediateOperand(literal);
decorations.push_back(std::unique_ptr<Instruction>(dec));
decorations.insert(std::unique_ptr<Instruction>(dec));
}
void Builder::addDecoration(Id id, Decoration decoration, const std::vector<const char*>& strings)
@ -2023,7 +2023,7 @@ void Builder::addDecoration(Id id, Decoration decoration, const std::vector<cons
for (auto string : strings)
dec->addStringOperand(string);
decorations.push_back(std::unique_ptr<Instruction>(dec));
decorations.insert(std::unique_ptr<Instruction>(dec));
}
void Builder::addLinkageDecoration(Id id, const char* name, spv::LinkageType linkType) {
@ -2034,7 +2034,7 @@ void Builder::addLinkageDecoration(Id id, const char* name, spv::LinkageType lin
dec->addStringOperand(name);
dec->addImmediateOperand(linkType);
decorations.push_back(std::unique_ptr<Instruction>(dec));
decorations.insert(std::unique_ptr<Instruction>(dec));
}
void Builder::addDecorationId(Id id, Decoration decoration, Id idDecoration)
@ -2048,7 +2048,7 @@ void Builder::addDecorationId(Id id, Decoration decoration, Id idDecoration)
dec->addImmediateOperand(decoration);
dec->addIdOperand(idDecoration);
decorations.push_back(std::unique_ptr<Instruction>(dec));
decorations.insert(std::unique_ptr<Instruction>(dec));
}
void Builder::addDecorationId(Id id, Decoration decoration, const std::vector<Id>& operandIds)
@ -2064,7 +2064,7 @@ void Builder::addDecorationId(Id id, Decoration decoration, const std::vector<Id
for (auto operandId : operandIds)
dec->addIdOperand(operandId);
decorations.push_back(std::unique_ptr<Instruction>(dec));
decorations.insert(std::unique_ptr<Instruction>(dec));
}
void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, int num)
@ -2080,7 +2080,7 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat
if (num >= 0)
dec->addImmediateOperand(num);
decorations.push_back(std::unique_ptr<Instruction>(dec));
decorations.insert(std::unique_ptr<Instruction>(dec));
}
void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, const char *s)
@ -2095,7 +2095,7 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat
dec->addImmediateOperand(decoration);
dec->addStringOperand(s);
decorations.push_back(std::unique_ptr<Instruction>(dec));
decorations.insert(std::unique_ptr<Instruction>(dec));
}
void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, const std::vector<unsigned>& literals)
@ -2111,7 +2111,7 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat
for (auto literal : literals)
dec->addImmediateOperand(literal);
decorations.push_back(std::unique_ptr<Instruction>(dec));
decorations.insert(std::unique_ptr<Instruction>(dec));
}
void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, const std::vector<const char*>& strings)
@ -2127,7 +2127,7 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat
for (auto string : strings)
dec->addStringOperand(string);
decorations.push_back(std::unique_ptr<Instruction>(dec));
decorations.insert(std::unique_ptr<Instruction>(dec));
}
void Builder::addInstruction(std::unique_ptr<Instruction> inst) {
@ -4330,11 +4330,10 @@ void Builder::dumpSourceInstructions(std::vector<unsigned int>& out) const
dumpSourceInstructions(iItr->first, *iItr->second, out);
}
void Builder::dumpInstructions(std::vector<unsigned int>& out,
const std::vector<std::unique_ptr<Instruction> >& instructions) const
template <class Range> void Builder::dumpInstructions(std::vector<unsigned int>& out, const Range& instructions) const
{
for (int i = 0; i < (int)instructions.size(); ++i) {
instructions[i]->dump(out);
for (const auto& inst : instructions) {
inst->dump(out);
}
}
@ -4347,4 +4346,40 @@ void Builder::dumpModuleProcesses(std::vector<unsigned int>& out) const
}
}
bool Builder::DecorationInstructionLessThan::operator()(const std::unique_ptr<Instruction>& lhs,
const std::unique_ptr<Instruction>& rhs) const
{
// Order by the id to which the decoration applies first. This is more intuitive.
assert(lhs->isIdOperand(0) && rhs->isIdOperand(0));
if (lhs->getIdOperand(0) != rhs->getIdOperand(0)) {
return lhs->getIdOperand(0) < rhs->getIdOperand(0);
}
if (lhs->getOpCode() != rhs->getOpCode())
return lhs->getOpCode() < rhs->getOpCode();
// Now compare the operands.
int minSize = std::min(lhs->getNumOperands(), rhs->getNumOperands());
for (int i = 1; i < minSize; ++i) {
if (lhs->isIdOperand(i) != rhs->isIdOperand(i)) {
return lhs->isIdOperand(i) < rhs->isIdOperand(i);
}
if (lhs->isIdOperand(i)) {
if (lhs->getIdOperand(i) != rhs->getIdOperand(i)) {
return lhs->getIdOperand(i) < rhs->getIdOperand(i);
}
} else {
if (lhs->getImmediateOperand(i) != rhs->getImmediateOperand(i)) {
return lhs->getImmediateOperand(i) < rhs->getImmediateOperand(i);
}
}
}
if (lhs->getNumOperands() != rhs->getNumOperands())
return lhs->getNumOperands() < rhs->getNumOperands();
// In this case they are equal.
return false;
}
} // end spv namespace