public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
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

  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).