diff mbox series

Fix Warray-bounds-3.c on Visium

Message ID 3394833.P0ZvxX0x16@polaris
State New
Headers show
Series Fix Warray-bounds-3.c on Visium | expand

Commit Message

Eric Botcazou Jan. 16, 2018, 11:12 p.m. UTC
This test fails on Visium because of 3 separate issues.  The first one is 
benign, it's a warning about a pointer mismatch between int32_t* and int*
(On most newlib targets, int32_t is long int instead of int) in the test.
The other 2 are in the code itself (but cancel each other on most targets):
builtin_memref::builtin_memref contains these lines:

      /* Determine the base object or pointer of the reference
	 and its constant offset from the beginning of the base.  */
      base = get_addr_base_and_unit_offset (oper, &off);

      HOST_WIDE_INT const_off;
      if (base && off.is_constant (&const_off))
	{
	  offrange[0] += const_off;
	  offrange[1] += const_off;

	  /* Stash the reference for offset validation.  */
	  ref = oper;

	  /* Also stash the constant offset for offset validation.  */
	  tree_code code = TREE_CODE (oper);
	  if (code == COMPONENT_REF)
	    {
	      tree field = TREE_OPERAND (ref, 1);
	      tree fldoff = DECL_FIELD_OFFSET (field);
	      if (TREE_CODE (fldoff) == INTEGER_CST)
		refoff = const_off + wi::to_offset (fldoff);
	    }
	}

The first problem is that DECL_FIELD_OFFSET doesn't return the offset of a 
field, it's byte_position because DECL_FIELD_BIT_OFFSET needs to be taken into 
account:

/* In a FIELD_DECL, this is the offset, in bits, of the first bit of the
   field from DECL_FIELD_OFFSET.  This field may be nonzero even for fields
   that are not bit fields (since DECL_OFFSET_ALIGN may be larger than the
   natural alignment of the field's type).  */
#define DECL_FIELD_BIT_OFFSET(NODE) \
  (FIELD_DECL_CHECK (NODE)->field_decl.bit_offset)

But replacing DECL_FIELD_OFFSET with byte_position is actually worse, because 
the offset of the field is then counted twice in refoff since it is already 
comprised in const_off.  In the end, the correct thing to do is just to equate 
refoff and const_off.

Tested on visium-elf & x86_64-suse-linux, applied on the mainline as obvious.


2018-01-16  Eric Botcazou  <ebotcazou@adacore.com>

	* gimple-ssa-warn-restrict.c (builtin_memref::builtin_memref): For an
	ADDR_EXPR, do not count the offset of a COMPONENT_REF twice.


2018-01-16  Eric Botcazou  <ebotcazou@adacore.com>

	* c-c++-common/Warray-bounds-3.c (test_memmove_bounds): Fix mismatch.
diff mbox series

Patch

Index: gimple-ssa-warn-restrict.c
===================================================================
--- gimple-ssa-warn-restrict.c	(revision 256562)
+++ gimple-ssa-warn-restrict.c	(working copy)
@@ -312,11 +312,11 @@  builtin_memref::builtin_memref (tree exp
   if (TREE_CODE (expr) == ADDR_EXPR)
     {
       poly_int64 off;
-      tree oper = TREE_OPERAND (expr, 0);
+      tree op = TREE_OPERAND (expr, 0);
 
       /* Determine the base object or pointer of the reference
 	 and its constant offset from the beginning of the base.  */
-      base = get_addr_base_and_unit_offset (oper, &off);
+      base = get_addr_base_and_unit_offset (op, &off);
 
       HOST_WIDE_INT const_off;
       if (base && off.is_constant (&const_off))
@@ -325,17 +325,11 @@  builtin_memref::builtin_memref (tree exp
 	  offrange[1] += const_off;
 
 	  /* Stash the reference for offset validation.  */
-	  ref = oper;
+	  ref = op;
 
 	  /* Also stash the constant offset for offset validation.  */
-	  tree_code code = TREE_CODE (oper);
-	  if (code == COMPONENT_REF)
-	    {
-	      tree field = TREE_OPERAND (ref, 1);
-	      tree fldoff = DECL_FIELD_OFFSET (field);
-	      if (TREE_CODE (fldoff) == INTEGER_CST)
-		refoff = const_off + wi::to_offset (fldoff);
-	    }
+	  if (TREE_CODE (op) == COMPONENT_REF)
+	    refoff = const_off;
 	}
       else
 	{
Index: testsuite/c-c++-common/Warray-bounds-3.c
===================================================================
--- testsuite/c-c++-common/Warray-bounds-3.c	(revision 256562)
+++ testsuite/c-c++-common/Warray-bounds-3.c	(working copy)
@@ -199,7 +199,8 @@  void test_memmove_bounds (char *d, const
   T (int,  2, a + SR ( 1, 3), pi, n);
   T (int,  2, a + SR ( 2, 3), pi, n);
 
-  T (int32_t, 2, a + SR ( 3, 4), pi, n);      /* { dg-warning "offset \\\[12, 16] is out of the bounds \\\[0, 8] of object .\[^\n\r]+. with type .int32_t ?\\\[2]." } */
+  const int32_t *pi32 = (const int32_t*)s;
+  T (int32_t, 2, a + SR ( 3, 4), pi32, n);      /* { dg-warning "offset \\\[12, 16] is out of the bounds \\\[0, 8] of object .\[^\n\r]+. with type .int32_t ?\\\[2]." } */
 }