Avoid -Wvla-parameter for nontrivial bounds [PR97548].
authorMartin Sebor <msebor@redhat.com>
Thu, 15 Jul 2021 16:11:23 +0000 (10:11 -0600)
committerMartin Sebor <msebor@redhat.com>
Thu, 15 Jul 2021 16:22:06 +0000 (10:22 -0600)
Resolves:
PR c/101289 - bogus -Wvla-paramater warning when using const for vla param
PR c/97548 -  bogus -Wvla-parameter on a bound expression involving a parameter

gcc/c-family/ChangeLog:

PR c/101289
PR c/97548
* c-warn.c (warn_parm_array_mismatch): Use OEP_DECL_NAME.

gcc/c/ChangeLog:

PR c/101289
PR c/97548
* c-decl.c (get_parm_array_spec): Strip nops.

gcc/ChangeLog:

PR c/101289
PR c/97548
* fold-const.c (operand_compare::operand_equal_p): Handle OEP_DECL_NAME.
(operand_compare::verify_hash_value): Same.
* tree-core.h (OEP_DECL_NAME): New.

gcc/testsuite/ChangeLog:

* gcc.dg/Wvla-parameter-12.c: New test.

gcc/c-family/c-warn.c
gcc/c/c-decl.c
gcc/fold-const.c
gcc/testsuite/gcc.dg/Wvla-parameter-12.c [new file with mode: 0644]
gcc/tree-core.h

index 3495959..552a29f 100644 (file)
@@ -3646,7 +3646,8 @@ warn_parm_array_mismatch (location_t origloc, tree fndecl, tree newparms)
              /* The VLA bounds don't refer to other function parameters.
                 Compare them lexicographically to detect gross mismatches
                 such as between T[foo()] and T[bar()].  */
-             if (operand_equal_p (newbnd, curbnd, OEP_LEXICOGRAPHIC))
+             if (operand_equal_p (newbnd, curbnd,
+                                  OEP_DECL_NAME | OEP_LEXICOGRAPHIC))
                continue;
 
              if (warning_at (newloc, OPT_Wvla_parameter,
index 983d65e..234ee16 100644 (file)
@@ -5865,6 +5865,7 @@ get_parm_array_spec (const struct c_parm *parm, tree attrs)
 
       /* Each variable VLA bound is represented by a dollar sign.  */
       spec += "$";
+      STRIP_NOPS (nelts);
       vbchain = tree_cons (NULL_TREE, nelts, vbchain);
     }
 
index e0cdb75..7dcecc9 100644 (file)
@@ -3499,11 +3499,26 @@ operand_compare::operand_equal_p (const_tree arg0, const_tree arg1,
 
     case tcc_declaration:
       /* Consider __builtin_sqrt equal to sqrt.  */
-      return (TREE_CODE (arg0) == FUNCTION_DECL
-             && fndecl_built_in_p (arg0) && fndecl_built_in_p (arg1)
-             && DECL_BUILT_IN_CLASS (arg0) == DECL_BUILT_IN_CLASS (arg1)
-             && (DECL_UNCHECKED_FUNCTION_CODE (arg0)
-                 == DECL_UNCHECKED_FUNCTION_CODE (arg1)));
+      if (TREE_CODE (arg0) == FUNCTION_DECL)
+       return (fndecl_built_in_p (arg0) && fndecl_built_in_p (arg1)
+               && DECL_BUILT_IN_CLASS (arg0) == DECL_BUILT_IN_CLASS (arg1)
+               && (DECL_UNCHECKED_FUNCTION_CODE (arg0)
+                   == DECL_UNCHECKED_FUNCTION_CODE (arg1)));
+
+      if (DECL_P (arg0)
+         && (flags & OEP_DECL_NAME)
+         && (flags & OEP_LEXICOGRAPHIC))
+       {
+         /* Consider decls with the same name equal.  The caller needs
+            to make sure they refer to the same entity (such as a function
+            formal parameter).  */
+         tree a0name = DECL_NAME (arg0);
+         tree a1name = DECL_NAME (arg1);
+         const char *a0ns = a0name ? IDENTIFIER_POINTER (a0name) : NULL;
+         const char *a1ns = a1name ? IDENTIFIER_POINTER (a1name) : NULL;
+         return a0ns && a1ns && strcmp (a0ns, a1ns) == 0;
+       }
+      return false;
 
     case tcc_exceptional:
       if (TREE_CODE (arg0) == CONSTRUCTOR)
@@ -3914,14 +3929,14 @@ bool
 operand_compare::verify_hash_value (const_tree arg0, const_tree arg1,
                                    unsigned int flags, bool *ret)
 {
-  /* When checking, verify at the outermost operand_equal_p call that
-     if operand_equal_p returns non-zero then ARG0 and ARG1 has the same
-     hash value.  */
+  /* When checking and unless comparing DECL names, verify that if
+     the outermost operand_equal_p call returns non-zero then ARG0
+     and ARG1 have the same hash value.  */
   if (flag_checking && !(flags & OEP_NO_HASH_CHECK))
     {
       if (operand_equal_p (arg0, arg1, flags | OEP_NO_HASH_CHECK))
        {
-         if (arg0 != arg1)
+         if (arg0 != arg1 && !(flags & OEP_DECL_NAME))
            {
              inchash::hash hstate0 (0), hstate1 (0);
              hash_operand (arg0, hstate0, flags | OEP_HASH_CHECK);
diff --git a/gcc/testsuite/gcc.dg/Wvla-parameter-12.c b/gcc/testsuite/gcc.dg/Wvla-parameter-12.c
new file mode 100644 (file)
index 0000000..1be5e48
--- /dev/null
@@ -0,0 +1,36 @@
+/* PR c/101289 - bogus -Wvla-parameter warning when using const bound
+   { dg-do compile }
+   { dg-options "-Wall" } */
+
+void f1ci_can (const int n, char a[n]);
+void f1ci_can (const int n, char a[n]); // { dg-bogus "-Wvla-parameter" }
+
+void f2ci_can (const int m, char a[m]);
+void f2ci_can (int n,       char a[n]); // { dg-bogus "-Wvla-parameter" }
+
+void f3i_can (int n,       char a[n]);
+void f3i_can (const int n, char a[n]);  // { dg-bogus "-Wvla-parameter" }
+
+void f4i_can (int n,       char a[n]);
+void f4i_can (const int n, char a[(int)n]);   // { dg-bogus "-Wvla-parameter" }
+
+void f5i_can (int n,       char a[(char)n]);
+void f5i_can (const int n, char a[(char)n]);  // { dg-bogus "-Wvla-parameter" }
+
+void f6i_can (int m,       char a[(char)m]);
+void f6i_can (const int n, char a[(char)n]);  // { dg-bogus "-Wvla-parameter" "" { xfail *-*-* } }
+
+
+/* PR c/97548 - bogus -Wvla-parameter on a bound expression involving
+   a parameter */
+
+int n;
+
+void f7ianp1 (int, int[n + 1]);
+void f7ianp1 (int, int[n + 1]);
+void f7ianp1 (int, int[n + 2]);         // { dg-warning "-Wvla-parameter" }
+
+void f8iakp1 (int k, int [k + 1]);
+void f8iakp1 (int k, int [k + 1]);      // { dg-bogus "-Wvla-parameter" }
+void f8iakp1 (int k, int [1 + k]);      // { dg-bogus "-Wvla-parameter" }
+void f8iakp1 (int k, int [k + 2]);      // { dg-warning "-Wvla-parameter" }
index e15e6c6..23cd289 100644 (file)
@@ -888,6 +888,7 @@ enum size_type_kind {
   stk_type_kind_last
 };
 
+/* Flags controlling operand_equal_p() behavior.  */
 enum operand_equal_flag {
   OEP_ONLY_CONST = 1,
   OEP_PURE_SAME = 2,
@@ -902,7 +903,11 @@ enum operand_equal_flag {
   OEP_BITWISE = 128,
   /* For OEP_ADDRESS_OF of COMPONENT_REFs, only consider same fields as
      equivalent rather than also different fields with the same offset.  */
-  OEP_ADDRESS_OF_SAME_FIELD = 256
+  OEP_ADDRESS_OF_SAME_FIELD = 256,
+  /* In conjunction with OEP_LEXICOGRAPHIC considers names of declarations
+     of the same kind.  Used to compare VLA bounds involving parameters
+     across redeclarations of the same function.  */
+  OEP_DECL_NAME = 512
 };
 
 /* Enum and arrays used for tree allocation stats.