Relax function call parameter check (#2448)

Fixes #2447

* Allow sub-objects for UniformConstant storage class
* Updated tests
diff --git a/source/val/validate_function.cpp b/source/val/validate_function.cpp
index 7c29260..5609008 100644
--- a/source/val/validate_function.cpp
+++ b/source/val/validate_function.cpp
@@ -301,7 +301,8 @@
               sc == SpvStorageClassStorageBuffer;
           const bool wg_vptr =
               _.features().variable_pointers && sc == SpvStorageClassWorkgroup;
-          if (!ssbo_vptr && !wg_vptr) {
+          const bool uc_ptr = sc == SpvStorageClassUniformConstant;
+          if (!ssbo_vptr && !wg_vptr && !uc_ptr) {
             return _.diag(SPV_ERROR_INVALID_ID, inst)
                    << "Pointer operand " << _.getIdName(argument_id)
                    << " must be a memory object declaration";
diff --git a/test/val/val_function_test.cpp b/test/val/val_function_test.cpp
index f3dd15e..6c0e8a1 100644
--- a/test/val/val_function_test.cpp
+++ b/test/val/val_function_test.cpp
@@ -321,13 +321,15 @@
   std::string spirv = GenerateShaderAccessChain(storage_class, "", "");
 
   const std::vector<std::string> valid_storage_classes = {
-      "UniformConstant", "Function", "Private", "Workgroup", "AtomicCounter"};
+      "Function", "Private", "Workgroup", "AtomicCounter"};
   bool valid_sc =
       std::find(valid_storage_classes.begin(), valid_storage_classes.end(),
                 storage_class) != valid_storage_classes.end();
 
   CompileSuccessfully(spirv);
-  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+  spv_result_t expected_result =
+      storage_class == "UniformConstant" ? SPV_SUCCESS : SPV_ERROR_INVALID_ID;
+  EXPECT_EQ(expected_result, ValidateInstructions());
   if (valid_sc) {
     EXPECT_THAT(
         getDiagnosticString(),
@@ -338,7 +340,7 @@
       EXPECT_THAT(getDiagnosticString(),
                   HasSubstr("StorageBuffer pointer operand 2[%gep] requires a "
                             "variable pointers capability"));
-    } else {
+    } else if (storage_class != "UniformConstant") {
       EXPECT_THAT(
           getDiagnosticString(),
           HasSubstr("Invalid storage class for pointer operand 2[%gep]"));
@@ -355,12 +357,12 @@
       "OpExtension \"SPV_KHR_variable_pointers\"");
 
   const std::vector<std::string> valid_storage_classes = {
-      "UniformConstant", "Function",      "Private",
-      "Workgroup",       "StorageBuffer", "AtomicCounter"};
+      "Function", "Private", "Workgroup", "StorageBuffer", "AtomicCounter"};
   bool valid_sc =
       std::find(valid_storage_classes.begin(), valid_storage_classes.end(),
                 storage_class) != valid_storage_classes.end();
-  bool validate = storage_class == "StorageBuffer";
+  bool validate =
+      storage_class == "StorageBuffer" || storage_class == "UniformConstant";
 
   CompileSuccessfully(spirv);
   if (validate) {
@@ -388,13 +390,13 @@
                                 "OpExtension \"SPV_KHR_variable_pointers\"");
 
   const std::vector<std::string> valid_storage_classes = {
-      "UniformConstant", "Function",      "Private",
-      "Workgroup",       "StorageBuffer", "AtomicCounter"};
+      "Function", "Private", "Workgroup", "StorageBuffer", "AtomicCounter"};
   bool valid_sc =
       std::find(valid_storage_classes.begin(), valid_storage_classes.end(),
                 storage_class) != valid_storage_classes.end();
-  bool validate =
-      storage_class == "StorageBuffer" || storage_class == "Workgroup";
+  bool validate = storage_class == "StorageBuffer" ||
+                  storage_class == "Workgroup" ||
+                  storage_class == "UniformConstant";
 
   CompileSuccessfully(spirv);
   if (validate) {