public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-5354] Avoid pathological function redeclarations when checking access sizes [PR102759].
@ 2021-11-17 22:10 Martin Sebor
  0 siblings, 0 replies; only message in thread
From: Martin Sebor @ 2021-11-17 22:10 UTC (permalink / raw)
  To: gcc-cvs

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

commit r12-5354-gea9e0d6c27405d256b4888e9e860e469037c911d
Author: Martin Sebor <msebor@redhat.com>
Date:   Wed Nov 17 15:09:23 2021 -0700

    Avoid pathological function redeclarations when checking access sizes [PR102759].
    
    Resolves:
    PR tree-optimization/102759 - ICE: Segmentation fault in maybe_check_access_sizes since r12-2976-gb48d4e6818674898
    
    gcc/ChangeLog:
    
            PR tree-optimization/102759
            * gimple-array-bounds.cc (build_printable_array_type): Move...
            * gimple-ssa-warn-access.cc (build_printable_array_type): Avoid
            pathological function redeclarations that remove a previously
            declared prototype.
            Improve formatting of function arguments in informational notes.
            * pointer-query.cc (build_printable_array_type): ...to here.
            * pointer-query.h (build_printable_array_type): Declared.
    
    gcc/testsuite/ChangeLog:
    
            PR tree-optimization/102759
            * gcc.dg/Warray-parameter-10.c: New test.
            * gcc.dg/Wstringop-overflow-82.c: New test.

Diff:
---
 gcc/gimple-array-bounds.cc                   | 25 ---------------------
 gcc/gimple-ssa-warn-access.cc                | 33 +++++++++++++++++++---------
 gcc/pointer-query.cc                         | 30 +++++++++++++++++++++++++
 gcc/pointer-query.h                          |  3 +++
 gcc/testsuite/gcc.dg/Warray-parameter-10.c   | 20 +++++++++++++++++
 gcc/testsuite/gcc.dg/Wstringop-overflow-82.c | 29 ++++++++++++++++++++++++
 6 files changed, 105 insertions(+), 35 deletions(-)

diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc
index a3535598998..ddb99d263d1 100644
--- a/gcc/gimple-array-bounds.cc
+++ b/gcc/gimple-array-bounds.cc
@@ -372,31 +372,6 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
   return warned;
 }
 
-/* Wrapper around build_array_type_nelts that makes sure the array
-   can be created at all and handles zero sized arrays specially.  */
-
-static tree
-build_printable_array_type (tree eltype, unsigned HOST_WIDE_INT nelts)
-{
-  if (TYPE_SIZE_UNIT (eltype)
-      && TREE_CODE (TYPE_SIZE_UNIT (eltype)) == INTEGER_CST
-      && !integer_zerop (TYPE_SIZE_UNIT (eltype))
-      && TYPE_ALIGN_UNIT (eltype) > 1
-      && wi::zext (wi::to_wide (TYPE_SIZE_UNIT (eltype)),
-		   ffs_hwi (TYPE_ALIGN_UNIT (eltype)) - 1) != 0)
-    eltype = TYPE_MAIN_VARIANT (eltype);
-
-  if (nelts)
-    return build_array_type_nelts (eltype, nelts);
-
-  tree idxtype = build_range_type (sizetype, size_zero_node, NULL_TREE);
-  tree arrtype = build_array_type (eltype, idxtype);
-  arrtype = build_distinct_type_copy (TYPE_MAIN_VARIANT (arrtype));
-  TYPE_SIZE (arrtype) = bitsize_zero_node;
-  TYPE_SIZE_UNIT (arrtype) = size_zero_node;
-  return arrtype;
-}
-
 /* Checks one MEM_REF in REF, located at LOCATION, for out-of-bounds
    references to string constants.  If VRP can determine that the array
    subscript is a constant, check if it is outside valid range.
diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc
index 22c791d833a..48bf8aaff50 100644
--- a/gcc/gimple-ssa-warn-access.cc
+++ b/gcc/gimple-ssa-warn-access.cc
@@ -2978,10 +2978,16 @@ pass_waccess::maybe_check_access_sizes (rdwr_map *rwm, tree fndecl, tree fntype,
 	continue;
 
       tree ptrtype = fntype_argno_type (fntype, ptridx);
+      if (!ptrtype)
+	/* A function with a prototype was redeclared without one and
+	   the protype has been lost.  See pr102759.  Avoid dealing
+	   with this pathological case.  */
+	return;
+
       tree argtype = TREE_TYPE (ptrtype);
 
-      /* The size of the access by the call.  */
-      tree access_size;
+      /* The size of the access by the call in elements.  */
+      tree access_nelts;
       if (sizidx == -1)
 	{
 	  /* If only the pointer attribute operand was specified and
@@ -2991,17 +2997,17 @@ pass_waccess::maybe_check_access_sizes (rdwr_map *rwm, tree fndecl, tree fntype,
 	     if the pointer is also declared with attribute nonnull.  */
 	  if (access.second.minsize
 	      && access.second.minsize != HOST_WIDE_INT_M1U)
-	    access_size = build_int_cstu (sizetype, access.second.minsize);
+	    access_nelts = build_int_cstu (sizetype, access.second.minsize);
 	  else
-	    access_size = size_one_node;
+	    access_nelts = size_one_node;
 	}
       else
-	access_size = rwm->get (sizidx)->size;
+	access_nelts = rwm->get (sizidx)->size;
 
       /* Format the value or range to avoid an explosion of messages.  */
       char sizstr[80];
       tree sizrng[2] = { size_zero_node, build_all_ones_cst (sizetype) };
-      if (get_size_range (m_ptr_qry.rvals, access_size, stmt, sizrng, 1))
+      if (get_size_range (m_ptr_qry.rvals, access_nelts, stmt, sizrng, 1))
 	{
 	  char *s0 = print_generic_expr_to_str (sizrng[0]);
 	  if (tree_int_cst_equal (sizrng[0], sizrng[1]))
@@ -3059,6 +3065,8 @@ pass_waccess::maybe_check_access_sizes (rdwr_map *rwm, tree fndecl, tree fntype,
 	    }
 	}
 
+      /* The size of the access by the call in bytes.  */
+      tree access_size = NULL_TREE;
       if (tree_int_cst_sgn (sizrng[0]) >= 0)
 	{
 	  if (COMPLETE_TYPE_P (argtype))
@@ -3075,9 +3083,9 @@ pass_waccess::maybe_check_access_sizes (rdwr_map *rwm, tree fndecl, tree fntype,
 		    access_size = wide_int_to_tree (sizetype, minsize);
 		  }
 	    }
+	  else
+	    access_size = access_nelts;
 	}
-      else
-	access_size = NULL_TREE;
 
       if (integer_zerop (ptr))
 	{
@@ -3172,8 +3180,13 @@ pass_waccess::maybe_check_access_sizes (rdwr_map *rwm, tree fndecl, tree fntype,
       if (opt_warned != no_warning)
 	{
 	  if (access.second.internal_p)
-	    inform (loc, "referencing argument %u of type %qT",
-		    ptridx + 1, ptrtype);
+	    {
+	      unsigned HOST_WIDE_INT nelts =
+		access_nelts ? access.second.minsize : HOST_WIDE_INT_M1U;
+	      tree arrtype = build_printable_array_type (argtype, nelts);
+	      inform (loc, "referencing argument %u of type %qT",
+		      ptridx + 1, arrtype);
+	    }
 	  else
 	    /* If check_access issued a warning above, append the relevant
 	       attribute to the string.  */
diff --git a/gcc/pointer-query.cc b/gcc/pointer-query.cc
index a0e4543d8a3..2ead0271617 100644
--- a/gcc/pointer-query.cc
+++ b/gcc/pointer-query.cc
@@ -2358,3 +2358,33 @@ array_elt_at_offset (tree artype, HOST_WIDE_INT off,
 
   return NULL_TREE;
 }
+
+/* Wrapper around build_array_type_nelts that makes sure the array
+   can be created at all and handles zero sized arrays specially.  */
+
+tree
+build_printable_array_type (tree eltype, unsigned HOST_WIDE_INT nelts)
+{
+  if (TYPE_SIZE_UNIT (eltype)
+      && TREE_CODE (TYPE_SIZE_UNIT (eltype)) == INTEGER_CST
+      && !integer_zerop (TYPE_SIZE_UNIT (eltype))
+      && TYPE_ALIGN_UNIT (eltype) > 1
+      && wi::zext (wi::to_wide (TYPE_SIZE_UNIT (eltype)),
+		   ffs_hwi (TYPE_ALIGN_UNIT (eltype)) - 1) != 0)
+    eltype = TYPE_MAIN_VARIANT (eltype);
+
+  /* Consider excessive NELTS an array of unknown bound.  */
+  tree idxtype = NULL_TREE;
+  if (nelts < HOST_WIDE_INT_MAX)
+    {
+      if (nelts)
+	return build_array_type_nelts (eltype, nelts);
+      idxtype = build_range_type (sizetype, size_zero_node, NULL_TREE);
+    }
+
+  tree arrtype = build_array_type (eltype, idxtype);
+  arrtype = build_distinct_type_copy (TYPE_MAIN_VARIANT (arrtype));
+  TYPE_SIZE (arrtype) = bitsize_zero_node;
+  TYPE_SIZE_UNIT (arrtype) = size_zero_node;
+  return arrtype;
+}
diff --git a/gcc/pointer-query.h b/gcc/pointer-query.h
index c8215b681ef..fbea3316f14 100644
--- a/gcc/pointer-query.h
+++ b/gcc/pointer-query.h
@@ -275,4 +275,7 @@ extern tree array_elt_at_offset (tree, HOST_WIDE_INT,
 				 HOST_WIDE_INT * = nullptr,
 				 HOST_WIDE_INT * = nullptr);
 
+/* Helper to build an array type that can be printed.  */
+extern tree build_printable_array_type (tree, unsigned HOST_WIDE_INT);
+
 #endif   // GCC_POINTER_QUERY_H
diff --git a/gcc/testsuite/gcc.dg/Warray-parameter-10.c b/gcc/testsuite/gcc.dg/Warray-parameter-10.c
new file mode 100644
index 00000000000..378f8afbd34
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-parameter-10.c
@@ -0,0 +1,20 @@
+/* PR c/102759 - ICE calling a function taking an argument redeclared
+   without a prototype.
+   { dg-do compile }
+   { dg-options "-Wall" } */
+
+void f (void)
+{
+  void gia (int[2]);
+  void g ();
+}
+
+/* Redeclaring the g(int[]) above without a prototype loses it.  */
+void gia ();
+void g (int[2]);
+
+void h (void )
+{
+  gia (gia);
+  gia (g);
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-82.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-82.c
new file mode 100644
index 00000000000..ee2693dcea9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-82.c
@@ -0,0 +1,29 @@
+/* Verify that notes after warnings for array and VLA parameters show
+   the array form.
+   { dg-do compile }
+   { dg-options "-Wall" } */
+
+void fia5 (int[5]);
+
+void gia3_fia5 (void)
+{
+  int a[3];
+  fia5 (a);             // { dg-warning "-Wstringop-overflow" }
+                        // { dg-message "argument 1 of type 'int\\\[5]'" "note" { target *-*-* } .-1 }
+}
+
+
+/* The type of the argument would ideall be 'int[n]' but the variable
+   bound is lost/cleared by free-lang-data and never makes it into
+   the middle end.  An (inferior) alternative would be 'int[*]' but
+   the pretty printer doesn't know how to format the star.  A better
+   solution might be to introduce a new notation, like 'int[$1]',
+   where the $1 refers to the VLA argument bound.  */
+void fvla (int n, int[n]);
+
+void gia3_fvla (void)
+{
+  int a[3];
+  fvla (sizeof a, a);   // { dg-warning "-Wstringop-overflow" }
+                        // { dg-message "argument 2 of type 'int\\\[]'" "note" { target *-*-* } .-1 }
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-11-17 22:10 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-17 22:10 [gcc r12-5354] Avoid pathological function redeclarations when checking access sizes [PR102759] Martin Sebor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).