Bug 84051

Summary: [7/8/9 Regression] missing -Warray-bounds on an out-of-bounds access via an array pointer
Product: gcc Reporter: Martin Sebor <msebor>
Component: middle-endAssignee: Martin Sebor <msebor>
Status: RESOLVED FIXED    
Severity: normal CC: aldyh, dimhen, jakub, jeffreyalaw, rguenth
Priority: P3 Keywords: diagnostic
Version: 8.0   
Target Milestone: 11.0   
Host: Target:
Build: Known to work: 4.5.4
Known to fail: 4.6.4, 4.7.4, 4.8.4, 4.9.4, 5.5.0, 6.4.0, 7.2.0, 8.0 Last reconfirmed: 2018-01-26 00:00:00
Bug Depends on:    
Bug Blocks: 56456    

Description Martin Sebor 2018-01-26 03:23:28 UTC
GCC used to diagnose out-of-bounds accesses made by pointers to arrays of a fixed bound.  The test case below shows it can no longer do that.   Clang and ICC bot detect this bug.

typedef int A4[4];

int f (A4 *p)
{
  return (*p)[7];
}
Comment 1 Martin Sebor 2018-01-26 03:27:00 UTC
Bisection points to either r158060 or r158060, both committed into GCC 4.6.  The latter seems like the more likely culprit:

2010-04-07  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/43270
	* tree-vrp.c (check_array_ref): Fix flexible array member
	detection.
	* tree-ssa-sccvn.h (fully_constant_vn_reference_p): Declare.
	* tree-ssa-pre.c (phi_translate_1): Adjust.
	(fully_constant_expression): Split out vn_reference handling to ...
	* tree-ssa-sccvn.c (fully_constant_vn_reference_p): ... here.
	Fold reads from constant strings.
	(vn_reference_lookup): Handle fully constant references.
	(vn_reference_lookup_pieces): Likewise.
	* Makefile.in (expmed.o-warn): Add -Wno-error.
Comment 2 Aldy Hernandez 2018-01-26 19:02:06 UTC
Confirmed.
Comment 3 Richard Biener 2018-12-20 11:06:18 UTC
int A4[4] is a trailing array so this was an intended change.
Comment 4 Martin Sebor 2018-12-20 16:51:46 UTC
I see GCC warns for this case with -Warray-bounds=2 and it's being tested in gcc.dg/Warray-bounds-11.c.

I think it would make sense to warn on the pointer to array case even at level 1.  It seems quite unlikely for a pointer to an array of a known bound to be set to point to a larger array and used to access elements beyond that bound.

Separately, I also wonder if it would make sense to warn for out-of-bounds accesses to trailing arrays with more than 1 element.  Those too seem unlikely, and the recommendation is to use either flexible array members or zero-length arrays for such things.

By warning on these cases GCC would help detect more bugs and encourage working code to migrate to the recommended solutions.

Perhaps for GCC 10.
Comment 5 Martin Sebor 2020-07-21 21:31:28 UTC
Testing a simple enhancement teaching gimple-array-bounds.cc how to detect this case.
Comment 6 GCC Commits 2020-09-19 23:57:41 UTC
The master branch has been updated by Martin Sebor <msebor@gcc.gnu.org>:

https://gcc.gnu.org/g:3f9a497d1b0dd9da87908a11b59bf364ad40ddca

commit r11-3306-g3f9a497d1b0dd9da87908a11b59bf364ad40ddca
Author: Martin Sebor <msebor@redhat.com>
Date:   Sat Sep 19 17:47:29 2020 -0600

    Extend -Warray-bounds to detect out-of-bounds accesses to array parameters.
    
    gcc/ChangeLog:
    
            PR middle-end/82608
            PR middle-end/94195
            PR c/50584
            PR middle-end/84051
            * gimple-array-bounds.cc (get_base_decl): New function.
            (get_ref_size): New function.
            (trailing_array): New function.
            (array_bounds_checker::check_array_ref): Call them.  Handle arrays
            declared in function parameters.
            (array_bounds_checker::check_mem_ref):  Same.  Handle references to
            dynamically allocated arrays.
    
    gcc/testsuite/ChangeLog:
    
            PR middle-end/82608
            PR middle-end/94195
            PR c/50584
            PR middle-end/84051
            * c-c++-common/Warray-bounds.c: Adjust.
            * gcc.dg/Wbuiltin-declaration-mismatch-9.c: Adjust.
            * gcc.dg/Warray-bounds-63.c: New test.
            * gcc.dg/Warray-bounds-64.c: New test.
            * gcc.dg/Warray-bounds-65.c: New test.
            * gcc.dg/Warray-bounds-66.c: New test.
            * gcc.dg/Warray-bounds-67.c: New test.
Comment 7 Martin Sebor 2020-09-20 00:09:32 UTC
GCC 11 issues the following warning for the test case in comment #0:

$ gcc -O2 -S -Wall pr84851.c
pr84851.c: In function ‘f’:
pr84851.c:5:14: warning: array subscript 7 is above array bounds of ‘A4’ {aka ‘int[4]’} [-Warray-bounds]
    5 |   return (*p)[7];
      |          ~~~~^~~
pr84851.c:3:12: note: while referencing ‘p’
    3 | int f (A4 *p)
      |        ~~~~^