https://gcc.gnu.org/g:dcd83c656ef1c00d5b5a70deb7ba608e68a8aea4

commit r17-1146-gdcd83c656ef1c00d5b5a70deb7ba608e68a8aea4
Author: Martin Uecker <[email protected]>
Date:   Sat May 30 16:30:50 2026 +0200

    c: fix false positive for -Wvla-parameter [PR98539]
    
    In case of VLAs that are multi-dimensional arrays with unspecified sizes,
    the test in the warning code did not work correctly.  Fix this by
    explicitely checking that there are specified or unspecified size
    expressions to determine the presence of a VLA.
    
            PR c/98539
    
    gcc/c-family/ChangeLog:
            * c-warn.cc (warn_parm_array_mismatch): Check number of size
            expressions.
    
    gcc/testsuite/ChangeLog:
            * gcc.dg/pr98539.c: New test.

Diff:
---
 gcc/c-family/c-warn.cc         | 27 +++++++++++++++++++++------
 gcc/testsuite/gcc.dg/pr98539.c |  6 ++++++
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/gcc/c-family/c-warn.cc b/gcc/c-family/c-warn.cc
index 07d15c0b09c7..1767d2dc090c 100644
--- a/gcc/c-family/c-warn.cc
+++ b/gcc/c-family/c-warn.cc
@@ -3479,9 +3479,28 @@ warn_parm_array_mismatch (location_t origloc, rdwr_map 
*cur_idx,
       cura->ptrarg = parmpos;
     }
 
+
+  unsigned newbnds = 0;
+  unsigned newunspec = 0;
+
+  if (newa->internal_p)
+    {
+      newbnds = newa->vla_bounds (&newunspec);
+      newbnds += newunspec;
+    }
+
+  unsigned curbnds = 0;
+  unsigned curunspec = 0;
+
+  if (cura->internal_p)
+    {
+      curbnds = cura->vla_bounds (&curunspec);
+      curbnds += curunspec;
+    }
+
   /* Set if the parameter is [re]declared as a VLA.  */
-  const bool cur_vla_p = cura->size || cura->minsize == HOST_WIDE_INT_M1U;
-  const bool new_vla_p = newa->size || newa->minsize == HOST_WIDE_INT_M1U;
+  const bool cur_vla_p = cura->minsize == HOST_WIDE_INT_M1U || 0 < curbnds;
+  const bool new_vla_p = newa->minsize == HOST_WIDE_INT_M1U || 0 < newbnds;
 
   if (DECL_P (curp))
     origloc = DECL_SOURCE_LOCATION (curp);
@@ -3560,10 +3579,6 @@ warn_parm_array_mismatch (location_t origloc, rdwr_map 
*cur_idx,
 
   if (newa->size || cura->size)
     {
-      unsigned newunspec, curunspec;
-      unsigned newbnds = newa->vla_bounds (&newunspec) + newunspec;
-      unsigned curbnds = cura->vla_bounds (&curunspec) + curunspec;
-
       if (newbnds != curbnds)
        {
          if (warning_n (newloc, OPT_Wvla_parameter, newbnds,
diff --git a/gcc/testsuite/gcc.dg/pr98539.c b/gcc/testsuite/gcc.dg/pr98539.c
new file mode 100644
index 000000000000..32e118dd10aa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr98539.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c99 -Wvla-parameter" } */
+
+void foo(int n, double x[3][*]);
+void foo(int n, double x[3][n]) { }
+

Reply via email to