Checks that \c var is listed as an interface in all the entry points that use it.
| 74 | // Checks that \c var is listed as an interface in all the entry points that use |
| 75 | // it. |
| 76 | spv_result_t check_interface_variable(ValidationState_t& _, |
| 77 | const Instruction* var) { |
| 78 | std::vector<const Function*> functions; |
| 79 | std::vector<const Instruction*> uses; |
| 80 | for (auto use : var->uses()) { |
| 81 | uses.push_back(use.first); |
| 82 | } |
| 83 | for (uint32_t i = 0; i < uses.size(); ++i) { |
| 84 | const auto user = uses[i]; |
| 85 | if (const Function* func = user->function()) { |
| 86 | functions.push_back(func); |
| 87 | } else { |
| 88 | // In the rare case that the variable is used by another instruction in |
| 89 | // the global scope, continue searching for an instruction used in a |
| 90 | // function. |
| 91 | for (auto use : user->uses()) { |
| 92 | uses.push_back(use.first); |
| 93 | } |
| 94 | } |
| 95 | } |
| 96 | |
| 97 | std::sort(functions.begin(), functions.end(), |
| 98 | [](const Function* lhs, const Function* rhs) { |
| 99 | return lhs->id() < rhs->id(); |
| 100 | }); |
| 101 | functions.erase(std::unique(functions.begin(), functions.end()), |
| 102 | functions.end()); |
| 103 | |
| 104 | std::vector<uint32_t> entry_points; |
| 105 | for (const auto func : functions) { |
| 106 | for (auto id : _.FunctionEntryPoints(func->id())) { |
| 107 | entry_points.push_back(id); |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | std::sort(entry_points.begin(), entry_points.end()); |
| 112 | entry_points.erase(std::unique(entry_points.begin(), entry_points.end()), |
| 113 | entry_points.end()); |
| 114 | |
| 115 | for (auto id : entry_points) { |
| 116 | for (const auto& desc : _.entry_point_descriptions(id)) { |
| 117 | bool found = false; |
| 118 | for (auto interface : desc.interfaces) { |
| 119 | if (var->id() == interface) { |
| 120 | found = true; |
| 121 | break; |
| 122 | } |
| 123 | } |
| 124 | if (!found) { |
| 125 | return _.diag(SPV_ERROR_INVALID_ID, var) |
| 126 | << "Interface variable id <" << var->id() |
| 127 | << "> is used by entry point '" << desc.name << "' id <" << id |
| 128 | << ">, but is not listed as an interface"; |
| 129 | } |
| 130 | } |
| 131 | } |
| 132 | |
| 133 | if (spvIsVulkanEnv(_.context()->target_env)) { |
no test coverage detected