layers: Fix mishandling of VI vs VS validation (Gitlab#69)

This wasn't quite correct. We'd end up trying to run it_a off beyond attribs.end(),
which is invalid and upsets the MS debug stdlib. This is most likely the root cause
of the weirdness that caused people to add _at_end, _first, etc to this function long ago,
so that can all disappear -- but for now, let's just deal with the actual bug.

Signed-off-by: Chris Forbes <chrisforbes@google.com>
diff --git a/layers/draw_state.cpp b/layers/draw_state.cpp
index eabec54..b9d1388 100644
--- a/layers/draw_state.cpp
+++ b/layers/draw_state.cpp
@@ -881,14 +881,14 @@
         bool b_at_end = inputs.size() == 0  || it_b == inputs.end();
         auto a_first = a_at_end ? 0 : it_a->first;
         auto b_first = b_at_end ? 0 : it_b->first;
-        if (b_at_end || a_first < b_first) {
+        if (!a_at_end && (b_at_end || a_first < b_first)) {
             if (log_msg(my_data->report_data, VK_DEBUG_REPORT_PERF_WARN_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, /*dev*/0, __LINE__, SHADER_CHECKER_OUTPUT_NOT_CONSUMED, "SC",
                     "Vertex attribute at location %d not consumed by VS", a_first)) {
                 pass = false;
             }
             it_a++;
         }
-        else if (a_at_end || b_first < a_first) {
+        else if (!b_at_end && (a_at_end || b_first < a_first)) {
             if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, /*dev*/0, __LINE__, SHADER_CHECKER_INPUT_NOT_PRODUCED, "SC",
                     "VS consumes input at location %d but not provided", b_first)) {
                 pass = false;
diff --git a/tests/layer_validation_tests.cpp b/tests/layer_validation_tests.cpp
index ee3aa57..40f1b4b 100644
--- a/tests/layer_validation_tests.cpp
+++ b/tests/layer_validation_tests.cpp
@@ -4815,6 +4815,66 @@
     }
 }
 
+TEST_F(VkLayerTest, CreatePipelineAttribLocationMismatch)
+{
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERF_WARN_BIT_EXT,
+        "location 0 not consumed by VS");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    VkVertexInputBindingDescription input_binding;
+    memset(&input_binding, 0, sizeof(input_binding));
+
+    VkVertexInputAttributeDescription input_attrib;
+    memset(&input_attrib, 0, sizeof(input_attrib));
+    input_attrib.format = VK_FORMAT_R32_SFLOAT;
+
+    char const *vsSource =
+        "#version 400\n"
+        "#extension GL_ARB_separate_shader_objects: require\n"
+        "#extension GL_ARB_shading_language_420pack: require\n"
+        "\n"
+        "layout(location=1) in float x;\n"
+        "out gl_PerVertex {\n"
+        "    vec4 gl_Position;\n"
+        "};\n"
+        "void main(){\n"
+        "   gl_Position = vec4(x);\n"
+        "}\n";
+    char const *fsSource =
+        "#version 400\n"
+        "#extension GL_ARB_separate_shader_objects: require\n"
+        "#extension GL_ARB_shading_language_420pack: require\n"
+        "\n"
+        "layout(location=0) out vec4 color;\n"
+        "void main(){\n"
+        "   color = vec4(1);\n"
+        "}\n";
+
+    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+
+    VkPipelineObj pipe(m_device);
+    pipe.AddColorAttachment();
+    pipe.AddShader(&vs);
+    pipe.AddShader(&fs);
+
+    pipe.AddVertexInputBindings(&input_binding, 1);
+    pipe.AddVertexInputAttribs(&input_attrib, 1);
+
+    VkDescriptorSetObj descriptorSet(m_device);
+    descriptorSet.AppendDummy();
+    descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
+
+    pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
+
+    if (!m_errorMonitor->DesiredMsgFound()) {
+        m_errorMonitor->DumpFailureMsgs();
+        FAIL() << "Did not receive Warning 'location 0 not consumed by VS'";
+    }
+}
+
 TEST_F(VkLayerTest, CreatePipelineAttribNotProvided)
 {
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,