From 3da828d2dd12e20ba2afc152db8d7236c7a48c13 Mon Sep 17 00:00:00 2001
From: Ian Romanick <ian.d.romanick@intel.com>
Date: Fri, 23 Jan 2026 09:58:26 -0800
Subject: [PATCH] spirv: Use STACK_ARRAY instead of NIR_VLA

The number of fields comes from the shader, so it could be a value large
enough that using alloca would be problematic.

Fixes: 2a023f30a64 ("nir/spirv: Add basic support for types")
Reviewed-by: Caio Oliveira <caio.oliveira@intel.com>
Reviewed-by: Ryan Neph <ryanneph@google.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39866>
---
 src/compiler/spirv/spirv_to_nir.c | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

Index: mesa-23.3.4/src/compiler/spirv/spirv_to_nir.c
===================================================================
--- mesa-23.3.4.orig/src/compiler/spirv/spirv_to_nir.c
+++ mesa-23.3.4/src/compiler/spirv/spirv_to_nir.c
@@ -27,7 +27,6 @@
 
 #include "glsl_types.h"
 #include "vtn_private.h"
-#include "nir/nir_vla.h"
 #include "nir/nir_control_flow.h"
 #include "nir/nir_constant_expressions.h"
 #include "nir/nir_deref.h"
@@ -40,6 +39,24 @@
 
 #include <stdio.h>
 
+#include <stdlib.h>
+
+#define STACK_ARRAY_SIZE 8
+
+/* Sometimes gcc may claim -Wmaybe-uninitialized for the stack array in some
+ * places it can't verify that when size is 0 nobody down the call chain reads
+ * the array. Please don't try to fix it by zero-initializing the array here
+ * since it's used in a lot of different places. An "if (size == 0) return;"
+ * may work for you.
+ */
+#define STACK_ARRAY(type, name, size) \
+   type _stack_##name[STACK_ARRAY_SIZE]; \
+   type *const name = \
+     ((size) <= STACK_ARRAY_SIZE ? _stack_##name : (type *)malloc((size) * sizeof(type)))
+
+#define STACK_ARRAY_FINISH(name) \
+   if (name != _stack_##name) free(name)
+
 #ifndef NDEBUG
 uint32_t mesa_spirv_debug = 0;
 
@@ -1013,7 +1030,7 @@ vtn_type_get_nir_type(struct vtn_builder
       case vtn_base_type_struct: {
          bool need_new_struct = false;
          const uint32_t num_fields = type->length;
-         NIR_VLA(struct glsl_struct_field, fields, num_fields);
+         STACK_ARRAY(struct glsl_struct_field, fields, num_fields);
          for (unsigned i = 0; i < num_fields; i++) {
             fields[i] = *glsl_get_struct_field_data(type->type, i);
             const struct glsl_type *field_nir_type =
@@ -1023,20 +1040,25 @@ vtn_type_get_nir_type(struct vtn_builder
                need_new_struct = true;
             }
          }
+
+         const struct glsl_type *result;
          if (need_new_struct) {
             if (glsl_type_is_interface(type->type)) {
-               return glsl_interface_type(fields, num_fields,
-                                          /* packing */ 0, false,
-                                          glsl_get_type_name(type->type));
+               result = glsl_interface_type(fields, num_fields,
+                                            /* packing */ 0, false,
+                                            glsl_get_type_name(type->type));
             } else {
-               return glsl_struct_type(fields, num_fields,
-                                       glsl_get_type_name(type->type),
-                                       glsl_struct_type_is_packed(type->type));
+               result = glsl_struct_type(fields, num_fields,
+                                         glsl_get_type_name(type->type),
+                                         glsl_struct_type_is_packed(type->type));
             }
          } else {
             /* No changes, just pass it on */
-            return type->type;
+            result = type->type;
          }
+
+         STACK_ARRAY_FINISH(fields);
+         return result;
       }
 
       case vtn_base_type_image:
@@ -1647,7 +1669,7 @@ vtn_handle_type(struct vtn_builder *b, S
       val->type->offsets = ralloc_array(b, unsigned, num_fields);
       val->type->packed = false;
 
-      NIR_VLA(struct glsl_struct_field, fields, count);
+      STACK_ARRAY(struct glsl_struct_field, fields, count);
       for (unsigned i = 0; i < num_fields; i++) {
          val->type->members[i] = vtn_get_type(b, w[i + 2]);
          const char *name = NULL;
@@ -1703,6 +1725,8 @@ vtn_handle_type(struct vtn_builder *b, S
                                             name ? name : "struct",
                                             val->type->packed);
       }
+
+      STACK_ARRAY_FINISH(fields);
       break;
    }
 
