Commit 8c3563f3 by Richard Biener Committed by Richard Biener

re PR tree-optimization/77291 (False positive for -Warray-bounds)

2017-12-18  Richard Biener  <rguenther@suse.de>

	PR middle-end/77291
	* tree.c (array_at_struct_end_p): Return true if the underlying
	object has space for at least one element in excess of what
	the array domain specifies.

	* gcc.dg/Warray-bounds-26.c: New testcase.

From-SVN: r255775
parent 040a4493
2017-12-18 Richard Biener <rguenther@suse.de>
PR middle-end/77291
* tree.c (array_at_struct_end_p): Return true if the underlying
object has space for at least one element in excess of what
the array domain specifies.
2017-12-17 Sandra Loosemore <sandra@codesourcery.com>
* doc/extend.texi (x86 Function Attributes): Reformat nocf_check
2017-12-18 Richard Biener <rguenther@suse.de>
PR middle-end/77291
* gcc.dg/Warray-bounds-26.c: New testcase.
2017-12-17 Uros Bizjak <ubizjak@gmail.com>
* gcc.dg/guality/guality.h (guality_check): Cast %lli arguments
......
/* { dg-do compile } */
/* { dg-options "-O2 -Warray-bounds" } */
struct Rec {
unsigned char data[1]; // actually variable length
};
union U {
unsigned char buf[42];
struct Rec rec;
};
int Load()
{
union U u;
return u.rec.data[1]; /* { dg-bogus "array bound" } */
}
......@@ -12644,6 +12644,7 @@ array_at_struct_end_p (tree ref)
if (TREE_CODE (ref) == STRING_CST)
return false;
tree ref_to_array = ref;
while (handled_component_p (ref))
{
/* If the reference chain contains a component reference to a
......@@ -12682,35 +12683,43 @@ array_at_struct_end_p (tree ref)
/* The array now is at struct end. Treat flexible arrays as
always subject to extend, even into just padding constrained by
an underlying decl. */
if (! TYPE_SIZE (atype))
if (! TYPE_SIZE (atype)
|| ! TYPE_DOMAIN (atype)
|| ! TYPE_MAX_VALUE (TYPE_DOMAIN (atype)))
return true;
tree size = NULL;
if (TREE_CODE (ref) == MEM_REF
&& TREE_CODE (TREE_OPERAND (ref, 0)) == ADDR_EXPR)
{
size = TYPE_SIZE (TREE_TYPE (ref));
ref = TREE_OPERAND (TREE_OPERAND (ref, 0), 0);
}
/* If the reference is based on a declared entity, the size of the array
is constrained by its given domain. (Do not trust commons PR/69368). */
if (DECL_P (ref)
/* Be sure the size of MEM_REF target match. For example:
char buf[10];
struct foo *str = (struct foo *)&buf;
str->trailin_array[2] = 1;
&& !(flag_unconstrained_commons
&& VAR_P (ref) && DECL_COMMON (ref))
&& DECL_SIZE_UNIT (ref)
&& TREE_CODE (DECL_SIZE_UNIT (ref)) == INTEGER_CST)
{
/* Check whether the array domain covers all of the available
padding. */
HOST_WIDE_INT offset;
if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (atype))) != INTEGER_CST
|| TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (atype))) != INTEGER_CST
|| TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (atype))) != INTEGER_CST)
return true;
if (! get_addr_base_and_unit_offset (ref_to_array, &offset))
return true;
is valid because BUF allocate enough space. */
/* If at least one extra element fits it is a flexarray. */
if (wi::les_p ((wi::to_offset (TYPE_MAX_VALUE (TYPE_DOMAIN (atype)))
- wi::to_offset (TYPE_MIN_VALUE (TYPE_DOMAIN (atype)))
+ 2)
* wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (atype))),
wi::to_offset (DECL_SIZE_UNIT (ref)) - offset))
return true;
&& (!size || (DECL_SIZE (ref) != NULL
&& operand_equal_p (DECL_SIZE (ref), size, 0)))
&& !(flag_unconstrained_commons
&& VAR_P (ref) && DECL_COMMON (ref)))
return false;
}
return true;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment