array-bounds, v2: Fix up ICE on overaligned variables [PR99109]

Message ID 20210218083708.GA4020736@tucnak
State New
Headers show
Series
  • array-bounds, v2: Fix up ICE on overaligned variables [PR99109]
Related show

Commit Message

Jason Merrill via Gcc-patches Feb. 18, 2021, 8:37 a.m.
On Wed, Feb 17, 2021 at 02:38:04PM -0700, Martin Sebor via Gcc-patches wrote:
> How does build_printable_array_type sound?


This adjusted version also works and has been successfully
bootstrapped/regtested on x86_64-linux and i686-linux.

Ok for trunk?

2021-02-18  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/99109
	* gimple-array-bounds.cc (build_zero_elt_array_type): Rename to ...
	(build_printable_array_type): ... this.  Add nelts argument.  For
	overaligned eltype, use TYPE_MAIN_VARIANT (eltype) instead.  If
	nelts, call build_array_type_nelts.
	(array_bounds_checker::check_mem_ref): Use build_printable_array_type
	instead of build_zero_elt_array_type and build_array_type_nelts.

	* g++.dg/warn/Warray-bounds-17.C: New test.



	Jakub

Comments

Richard Biener Feb. 18, 2021, 8:41 a.m. | #1
On Thu, 18 Feb 2021, Jakub Jelinek wrote:

> On Wed, Feb 17, 2021 at 02:38:04PM -0700, Martin Sebor via Gcc-patches wrote:

> > How does build_printable_array_type sound?

> 

> This adjusted version also works and has been successfully

> bootstrapped/regtested on x86_64-linux and i686-linux.

> 

> Ok for trunk?


OK.

Richard.

> 2021-02-18  Jakub Jelinek  <jakub@redhat.com>

> 

> 	PR middle-end/99109

> 	* gimple-array-bounds.cc (build_zero_elt_array_type): Rename to ...

> 	(build_printable_array_type): ... this.  Add nelts argument.  For

> 	overaligned eltype, use TYPE_MAIN_VARIANT (eltype) instead.  If

> 	nelts, call build_array_type_nelts.

> 	(array_bounds_checker::check_mem_ref): Use build_printable_array_type

> 	instead of build_zero_elt_array_type and build_array_type_nelts.

> 

> 	* g++.dg/warn/Warray-bounds-17.C: New test.

> 

> --- gcc/gimple-array-bounds.cc.jj	2021-01-04 10:25:37.471249246 +0100

> +++ gcc/gimple-array-bounds.cc	2021-02-17 23:30:34.168721374 +0100

> @@ -372,12 +372,23 @@ array_bounds_checker::check_array_ref (l

>    return warned;

>  }

>  

> -/* Hack around the internal representation constraints and build a zero

> -   element array type that actually renders as T[0] in diagnostcs.  */

> +/* 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_zero_elt_array_type (tree eltype)

> +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));

> @@ -561,10 +572,7 @@ array_bounds_checker::check_mem_ref (loc

>  	return false;

>  

>        offset_int nelts = arrbounds[1] / eltsize;

> -      if (nelts == 0)

> -	reftype = build_zero_elt_array_type (reftype);

> -      else

> -	reftype = build_array_type_nelts (reftype, nelts.to_uhwi ());

> +      reftype = build_printable_array_type (reftype, nelts.to_uhwi ());

>      }

>    else if (TREE_CODE (arg) == ADDR_EXPR)

>      {

> @@ -675,7 +683,7 @@ array_bounds_checker::check_mem_ref (loc

>        /* Treat a reference to a non-array object as one to an array

>  	 of a single element.  */

>        if (TREE_CODE (reftype) != ARRAY_TYPE)

> -	reftype = build_array_type_nelts (reftype, 1);

> +	reftype = build_printable_array_type (reftype, 1);

>  

>        /* Extract the element type out of MEM_REF and use its size

>  	 to compute the index to print in the diagnostic; arrays

> --- gcc/testsuite/g++.dg/warn/Warray-bounds-17.C.jj	2021-02-16 17:24:14.178813304 +0100

> +++ gcc/testsuite/g++.dg/warn/Warray-bounds-17.C	2021-02-16 17:23:35.305251062 +0100

> @@ -0,0 +1,15 @@

> +// PR middle-end/99109

> +// { dg-do compile }

> +// { dg-options "-O2 -Warray-bounds" }

> +

> +typedef int A __attribute__((aligned (64)));

> +void foo (int *);

> +

> +void

> +bar (void)

> +{

> +  A b;			// { dg-message "while referencing" }

> +  int *p = &b;

> +  int *x = (p - 1);	// { dg-warning "outside array bounds" }

> +  foo (x);

> +}

> 

> 

> 	Jakub

> 

> 


-- 
Richard Biener <rguenther@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)

Patch

--- gcc/gimple-array-bounds.cc.jj	2021-01-04 10:25:37.471249246 +0100
+++ gcc/gimple-array-bounds.cc	2021-02-17 23:30:34.168721374 +0100
@@ -372,12 +372,23 @@  array_bounds_checker::check_array_ref (l
   return warned;
 }
 
-/* Hack around the internal representation constraints and build a zero
-   element array type that actually renders as T[0] in diagnostcs.  */
+/* 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_zero_elt_array_type (tree eltype)
+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));
@@ -561,10 +572,7 @@  array_bounds_checker::check_mem_ref (loc
 	return false;
 
       offset_int nelts = arrbounds[1] / eltsize;
-      if (nelts == 0)
-	reftype = build_zero_elt_array_type (reftype);
-      else
-	reftype = build_array_type_nelts (reftype, nelts.to_uhwi ());
+      reftype = build_printable_array_type (reftype, nelts.to_uhwi ());
     }
   else if (TREE_CODE (arg) == ADDR_EXPR)
     {
@@ -675,7 +683,7 @@  array_bounds_checker::check_mem_ref (loc
       /* Treat a reference to a non-array object as one to an array
 	 of a single element.  */
       if (TREE_CODE (reftype) != ARRAY_TYPE)
-	reftype = build_array_type_nelts (reftype, 1);
+	reftype = build_printable_array_type (reftype, 1);
 
       /* Extract the element type out of MEM_REF and use its size
 	 to compute the index to print in the diagnostic; arrays
--- gcc/testsuite/g++.dg/warn/Warray-bounds-17.C.jj	2021-02-16 17:24:14.178813304 +0100
+++ gcc/testsuite/g++.dg/warn/Warray-bounds-17.C	2021-02-16 17:23:35.305251062 +0100
@@ -0,0 +1,15 @@ 
+// PR middle-end/99109
+// { dg-do compile }
+// { dg-options "-O2 -Warray-bounds" }
+
+typedef int A __attribute__((aligned (64)));
+void foo (int *);
+
+void
+bar (void)
+{
+  A b;			// { dg-message "while referencing" }
+  int *p = &b;
+  int *x = (p - 1);	// { dg-warning "outside array bounds" }
+  foo (x);
+}