An interesting little bug. We're just emitting what appears to me to be
a silly warning.
By the time the array-bounds checker runs we have this statement in the IL:
MEM[(int *)_42 + -4B] ={v} {CLOBBER(eob)};
Naturally that looks like an out of bounds array index and we warn.
Which seems dubious at best. My first thought is we shouldn't be trying
to analyze a gimple clobber for out of bounds array indexes.
But like most things in GCC, it's never that simple.
It looks like we're relying on warning for that case for
Warray-bounds-20.C.
<bb 2> [local count: 1073741824]:
MEM[(struct D1 *)&a + 1B] ={v} {CLOBBER(bob)};
MEM[(struct B *)&a + 1B]._vptr.B = &MEM <int (*) ()> [(void *)&_ZTC2D10_1B +
24B];
MEM[(struct A *)&a + 9B]._vptr.A = &MEM <int (*) ()> [(void *)&_ZTC2D10_1B +
64B];
C::C (&MEM[(struct D1 *)&a + 1B].D.3003, &MEM <const void *[8]> [(void
*)&_ZTT2D1 + 48B]);
My sense is that this test is passing more by accident than by design
and that the warning really should be triggered by one of the other
statements. Martin just got it wrong here AFAICT. I did go back and
check the original BZ (pr98266). It's unaffected as it doesn't have the
gimple clobbers.
I'd propose a patch like the following, but I also realize this might be
considered somewhat controversial, particularly since I think we could
be missing diagnostics, particularly around placement-new that we now
kind of pick up by accident (though not reliably as can be seen in other
subtests withing Warray-bounds-20.C which were already xfail'd).
Thoughts?
Jeff
diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc
index 22286cbb4cc..dff1a6e13db 100644
--- a/gcc/gimple-array-bounds.cc
+++ b/gcc/gimple-array-bounds.cc
@@ -794,6 +794,15 @@ array_bounds_checker::check_array_bounds (tree *tp, int
*walk_subtree,
tree t = *tp;
struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
+ /* There's no point in analyzing a gimple clobber statement for an
+ out of bounds array index and if we do try, we may trip bogus
+ warnings. See pr117829. */
+ if (gimple_clobber_p (wi->stmt))
+ {
+ *walk_subtree = false;
+ return NULL_TREE;
+ }
+
location_t location;
if (EXPR_HAS_LOCATION (t))
diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-20.C
b/gcc/testsuite/g++.dg/warn/Warray-bounds-20.C
index 5fc55293074..f0d5cb8c34b 100644
--- a/gcc/testsuite/g++.dg/warn/Warray-bounds-20.C
+++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-20.C
@@ -26,7 +26,7 @@ struct D1: virtual B, virtual C
/* The warning would ideally point to the assignment but instead points
to the opening brace. */
D1 ()
- { // { dg-warning "\\\[-Warray-bounds" "brace" }
+ { // { dg-warning "\\\[-Warray-bounds" "brace" {
xfail *-*-* } }
ci = 0; // { dg-warning "\\\[-Warray-bounds" "assign" {
xfail lp64 } }
}
};
@@ -35,8 +35,8 @@ void sink (void*);
void warn_derived_ctor_access_new_decl ()
{
- char a[sizeof (D1)]; // { dg-message "at offset 1 into object 'a' of
size 40" "LP64 note" { target lp64} }
- // { dg-message "at offset 1 into object 'a' of
size 20" "LP64 note" { target ilp32} .-1 }
+ char a[sizeof (D1)]; // { dg-message "at offset 1 into object 'a' of
size 40" "LP64 note" { target { lp64 } xfail { lp64} } }
+ // { dg-message "at offset 1 into object 'a' of
size 20" "LP64 note" { target { ilp32 } xfail { ilp32 } .-1 } }
char *p = a;
++p;
D1 *q = new (p) D1;
@@ -45,7 +45,7 @@ void warn_derived_ctor_access_new_decl ()
void warn_derived_ctor_access_new_alloc ()
{
- char *p = (char*)operator new (sizeof (D1)); // { dg-message "at offset 1
into object of size \\d+ allocated by '\[^\n\r]*operator new\[^\n\r]*'" "note" }
+ char *p = (char*)operator new (sizeof (D1)); // { dg-message "at offset 1
into object of size \\d+ allocated by '\[^\n\r]*operator new\[^\n\r]*'" "note"
{ xfail *-*-* } }
++p;
D1 *q = new (p) D1;
sink (q);