aboutsummaryrefslogtreecommitdiff
path: root/source/val
diff options
context:
space:
mode:
authorAndrey Tuganov <andreyt@google.com>2017-02-23 16:07:52 -0500
committerDavid Neto <dneto@google.com>2017-02-28 22:27:08 -0500
commit0e9c24fdd112e7742b9b5dcff35aee32e71a66fd (patch)
treecc83eb4584800fd0bd14ce88da2bdf62416fc160 /source/val
parent4ef3b3e0b98d36083cb330c6b386feb51421b811 (diff)
downloadspirv-tools-0e9c24fdd112e7742b9b5dcff35aee32e71a66fd.tar.gz
Issue 559: check type declaration uniqueness
Adds PassTypeUnique to the validator. Disallows repeated declarations of all types except for aggregates.
Diffstat (limited to 'source/val')
-rw-r--r--source/val/validation_state.cpp19
-rw-r--r--source/val/validation_state.h11
2 files changed, 30 insertions, 0 deletions
diff --git a/source/val/validation_state.cpp b/source/val/validation_state.cpp
index d125c8cf..7a9c5915 100644
--- a/source/val/validation_state.cpp
+++ b/source/val/validation_state.cpp
@@ -400,4 +400,23 @@ void ValidationState_t::RegisterSampledImageConsumer(uint32_t sampled_image_id,
uint32_t ValidationState_t::getIdBound() const { return id_bound_; }
void ValidationState_t::setIdBound(const uint32_t bound) { id_bound_ = bound; }
+
+bool ValidationState_t::RegisterUniqueTypeDeclaration(
+ const spv_parsed_instruction_t& inst) {
+ std::vector<uint32_t> key;
+ key.push_back(static_cast<uint32_t>(inst.opcode));
+ for (int index = 0; index < inst.num_operands; ++index) {
+ const spv_parsed_operand_t& operand = inst.operands[index];
+
+ if (operand.type == SPV_OPERAND_TYPE_RESULT_ID) continue;
+
+ const int words_begin = operand.offset;
+ const int words_end = words_begin + operand.num_words;
+ assert(words_end <= static_cast<int>(inst.num_words));
+
+ key.insert(key.end(), inst.words + words_begin, inst.words + words_end);
+ }
+
+ return unique_type_declarations_.insert(std::move(key)).second;
+}
} /// namespace libspirv
diff --git a/source/val/validation_state.h b/source/val/validation_state.h
index ac845b04..686685ed 100644
--- a/source/val/validation_state.h
+++ b/source/val/validation_state.h
@@ -16,6 +16,7 @@
#define LIBSPIRV_VAL_VALIDATIONSTATE_H_
#include <deque>
+#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
@@ -304,6 +305,10 @@ class ValidationState_t {
// Returns the state of optional features.
const Feature& features() const { return features_; }
+ /// Adds the instruction data to unique_type_declarations_.
+ /// Returns false if an identical type declaration already exists.
+ bool RegisterUniqueTypeDeclaration(const spv_parsed_instruction_t& inst);
+
private:
ValidationState_t(const ValidationState_t&);
@@ -371,6 +376,12 @@ class ValidationState_t {
/// Stores the list of decorations for a given <id>
std::unordered_map<uint32_t, std::vector<Decoration>> id_decorations_;
+ /// Stores type declarations which need to be unique (i.e. non-aggregates),
+ /// in the form [opcode, operand words], result_id is not stored.
+ /// Using ordered set to avoid the need for a vector hash function.
+ /// The size of this container is expected not to exceed double-digits.
+ std::set<std::vector<uint32_t>> unique_type_declarations_;
+
AssemblyGrammar grammar_;
SpvAddressingModel addressing_model_;