From: Ian Lance Taylor <iant@google.com>
To: "Peter A. Felvegi" <petschy@praire-chicken.com>
Cc: gcc@gcc.gnu.org
Subject: Re: array subscript is below array bounds : false positive?
Date: Tue, 15 Sep 2009 14:56:00 -0000 [thread overview]
Message-ID: <m3bplcfe8r.fsf@google.com> (raw)
In-Reply-To: <4AAF6A13.2090303@praire-chicken.com> (Peter A. Felvegi's message of "Tue\, 15 Sep 2009 12\:18\:59 +0200")
"Peter A. Felvegi" <petschy@praire-chicken.com> writes:
> I've run into this strange warning when compiling w/ optimization:
> gcc-4.3 -O2 -Werror -Wall -c -o t.o t.c
> cc1: warnings being treated as errors
> t.c: In function ‘foo’:
> t.c:25: error: array subscript is below array bounds
This question is appropriate for gcc-help@gcc.gnu.org, not
gcc@gcc.gnu.org. Please take any followups to gcc-help. Thanks.
> t.c is :
> ---->8---->8---->8---->8---->8---->8---->8---->8---->8---->8----
> #define ASSERT(x) if (x) { } else { __asm__("int $0x03"); }
> #define SIZE 5
>
> char hnd[SIZE];
> char flg[SIZE];
>
> char crd();
> int idx(char);
> void set(int i, char v);
>
> #if 1
> void set(int i, char v)
> {
> ASSERT(i >=0 && i < SIZE);
> flg[i] = v;
> }
> #endif
>
>
> void foo()
> {
> char c = crd();
> int i = idx(0);
> ASSERT(i != -1);
> hnd[i] = c; // array subscript is below array bounds
> set(i, 1);
> }
> ---->8---->8---->8---->8---->8---->8---->8---->8---->8---->8----
>
> Suppose that idx(c) returns the position of c in an array, an the
> return value of -1 means that c is not in the array. The assertion
> checks that.
>
> The funny thing is, if I change the source a bit, the warning goes away:
> 1) set '#if 1' to '#if 0' so that only the prototype of set() is visible
> 2) comment out the ASSERT() int set()
> 3) comment out ASSERT() just before the marked line
> 4) comment out set(i, 1) just after the marked line
>
> The warning is not present under -O2.
gcc is getting fooled because of your ASSERT macro. The optimizer is
pulling the reference to hnd[i] into the ASSERT branches, because it can
then optimize the reference knowing that i == -1. That is:
ASSERT (i != -1)
hnd[i] = c;
=>
if (i != -1) { } else { __asm__ (""); }
hnd[i] = c;
=>
if (i != -1) { hnd[i] = c; } else { __asm__ (""); hnd[-1] = c; }
You can avoid this kind of thing by telling gcc that your assert
condition does not return.
void assert_failure () __attribute__ ((noreturn, always_inline));
void assert_failure() { __asm__ ("int $0x03"); }
#define ASSERT(x) if (x) { } else { assert_failure(); }
Ian
next prev parent reply other threads:[~2009-09-15 14:56 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-09-15 10:19 Peter A. Felvegi
2009-09-15 10:30 ` Basile STARYNKEVITCH
2009-09-15 14:56 ` Ian Lance Taylor [this message]
2009-09-15 16:19 ` Richard Henderson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m3bplcfe8r.fsf@google.com \
--to=iant@google.com \
--cc=gcc@gcc.gnu.org \
--cc=petschy@praire-chicken.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).