[Bug middle-end/99630] New: missing -Warray-bounds accessing a trailing array of a virtual base class
msebor at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed Mar 17 16:57:37 GMT 2021
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99630
Bug ID: 99630
Summary: missing -Warray-bounds accessing a trailing array of a
virtual base class
Product: gcc
Version: 11.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: msebor at gcc dot gnu.org
Target Milestone: ---
GCC issues -Warray-bounds for the out of bounds access to an object with an
ordinary base class in f() but not for the same out of bounds access to an
object with a virtual base class in g(). Both access should be diagnosed.
The problem is that trailing_array() calls array_at_struct_end_p() which
returns true for trailing array members without considering the type of the
enclosing object.
$ cat u.C && gcc -O2 -S -Wall -fdump-tree-vrp1=/dev/stdout u.C
struct A1
{
virtual ~A1 ();
int a1a[1];
};
struct A2
{
virtual ~A2 ();
int a2a[1];
};
struct B1: A1 { };
struct B2: A2 { };
struct D1: B1, B2 { };
void f (D1 *p)
{
extern D1 d1;
p->a1a[0] = (char*)d1.a1a - (char*)&d1;
p->a1a[1] = (char*)d1.a2a - (char*)&d1; // -Warray-bounds (good)
}
struct V1: virtual A1 { };
struct V2: virtual A2 { };
struct D2: V1, V2 { };
void f (D2 *p)
{
extern D2 d2;
p->a1a[0] = (char*)d2.a1a - (char*)&d2;
p->a1a[1] = (char*)d2.a2a - (char*)&d2; // missing -Warray-bounds
}
;; Function f (_Z1fP2D1, funcdef_no=0, decl_uid=2468, cgraph_uid=1,
symbol_order=0)
;; 1 loops found
;;
;; Loop 0
;; header 0, latch 1
;; depth 0, outer -1
;; nodes: 0 1 2
;; 2 succs { 1 }
SSA replacement table
N_i -> { O_1 ... O_j } means that N_i replaces O_1, ..., O_j
p_5 -> { p_2(D) }
Incremental SSA update started at block: 2
Number of blocks in CFG: 3
Number of blocks to update: 1 ( 33%)
Value ranges after VRP:
p_2(D): struct D1 * VARYING
p_5: struct D1 * [1B, +INF] EQUIVALENCES: { p_2(D) } (1 elements)
u.C: In function ‘void f(D1*)’:
u.C:21:11: warning: array subscript 1 is above array bounds of ‘int [1]’
[-Warray-bounds]
21 | p->a1a[1] = (char*)d1.a2a - (char*)&d1; // -Warray-bounds (good)
| ~~~~~~~~^
u.C:4:7: note: while referencing ‘A1::a1a’
4 | int a1a[1];
| ^~~
void f (struct D1 * p)
{
<bb 2> [local count: 1073741824]:
p_2(D)->D.2450.D.2409.a1a[0] = 8;
p_2(D)->D.2450.D.2409.a1a[1] = 24;
return;
}
;; Function f (_Z1fP2D2, funcdef_no=1, decl_uid=2566, cgraph_uid=2,
symbol_order=1)
;; 1 loops found
;;
;; Loop 0
;; header 0, latch 1
;; depth 0, outer -1
;; nodes: 0 1 2
;; 2 succs { 1 }
SSA replacement table
N_i -> { O_1 ... O_j } means that N_i replaces O_1, ..., O_j
_9 -> { _4 }
p_10 -> { p_6(D) }
Incremental SSA update started at block: 2
Number of blocks in CFG: 3
Number of blocks to update: 1 ( 33%)
Value ranges after VRP:
_1: int (*) () * VARYING
_2: long int VARYING
_3: sizetype VARYING
_4: struct D2 * [1B, +INF]
p_6(D): struct D2 * VARYING
_9: struct D2 * [1B, +INF] EQUIVALENCES: { _4 } (1 elements)
p_10: struct D2 * [1B, +INF] EQUIVALENCES: { p_6(D) } (1 elements)
void f (struct D2 * p)
{
int (*) () * _1;
long int _2;
sizetype _3;
struct D2 * _4;
<bb 2> [local count: 1073741824]:
_1 = p_6(D)->D.2549._vptr.V1;
_2 = MEM[(long int *)_1 + -24B];
_3 = (sizetype) _2;
_4 = p_6(D) + _3;
MEM[(struct A1 *)_4].a1a[0] = 24;
MEM[(struct A1 *)_4].a1a[1] = 40; <<< _4's type is D2 and a1a[1] overlaps
its _vptr
return;
}
More information about the Gcc-bugs
mailing list