public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* array subscript is below array bounds : false positive?
@ 2009-09-15 10:19 Peter A. Felvegi
  2009-09-15 10:30 ` Basile STARYNKEVITCH
  2009-09-15 14:56 ` Ian Lance Taylor
  0 siblings, 2 replies; 4+ messages in thread
From: Peter A. Felvegi @ 2009-09-15 10:19 UTC (permalink / raw)
  To: gcc

Hello,

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

gcc-4.4 gives the same warning/error, however, gcc 4.1 and 4.2 compiles 
the source.

gcc-4.1 -v says:
Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++ 
--prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib 
--without-included-gettext --enable-threads=posix --enable-nls 
--with-gxx-include-dir=/usr/include/c++/4.1.3 --program-suffix=-4.1 
--enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug 
--with-tune=generic --enable-checking=release x86_64-linux-gnu
Thread model: posix
gcc version 4.1.3 20080704 (prerelease) (Debian 4.1.2-27)

gcc-4.2 -v says:
Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v 
--enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr 
--enable-shared --with-system-zlib --libexecdir=/usr/lib 
--without-included-gettext --enable-threads=posix --enable-nls 
--with-gxx-include-dir=/usr/include/c++/4.2 --program-suffix=-4.2 
--enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc 
--enable-mpfr --with-tune=generic --enable-checking=release 
--build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.2.4 (Debian 4.2.4-6)

gcc-4.3 -v says:
Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.3.4-2' 
--with-bugurl=file:///usr/share/doc/gcc-4.3/README.Bugs 
--enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr 
--enable-shared --enable-multiarch --enable-linker-build-id 
--with-system-zlib --libexecdir=/usr/lib --without-included-gettext 
--enable-threads=posix --enable-nls 
--with-gxx-include-dir=/usr/include/c++/4.3 --program-suffix=-4.3 
--enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc 
--enable-mpfr --with-tune=generic --enable-checking=release 
--build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.3.4 (Debian 4.3.4-2)

gcc-4.4 -v says:
Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.4.1-1' 
--with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs 
--enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr 
--enable-shared --enable-multiarch --enable-linker-build-id 
--with-system-zlib --libexecdir=/usr/lib --without-included-gettext 
--enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 
--program-suffix=-4.4 --enable-nls --enable-clocale=gnu 
--enable-libstdcxx-debug --enable-mpfr --enable-objc-gc 
--with-arch-32=i486 --with-tune=generic --enable-checking=release 
--build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.4.1 (Debian 4.4.1-1)

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.

Is this warning legal?

Cheers, Peter

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: array subscript is below array bounds : false positive?
  2009-09-15 10:19 array subscript is below array bounds : false positive? Peter A. Felvegi
@ 2009-09-15 10:30 ` Basile STARYNKEVITCH
  2009-09-15 14:56 ` Ian Lance Taylor
  1 sibling, 0 replies; 4+ messages in thread
From: Basile STARYNKEVITCH @ 2009-09-15 10:30 UTC (permalink / raw)
  To: Peter A. Felvegi; +Cc: gcc

Peter A. Felvegi wrote:
> Hello,
> ---->8---->8---->8---->8---->8---->8---->8---->8---->8---->8----
> #define ASSERT(x)    if (x) { } else { __asm__("int $0x03"); }
With the trunk, that is future 4.5, I would suggest
#define ASSERT(x) if (x) {} else {__builtin_unreachable ();}

or at least, if the int$03 is important,

#define ASSERT(x) if (!(x)) \
    { volatile __asm__("int $0x03");__builtin_unreachable ();}

See
http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins

Regards.

-- 
Basile STARYNKEVITCH         http://starynkevitch.net/Basile/
email: basile<at>starynkevitch<dot>net mobile: +33 6 8501 2359
8, rue de la Faiencerie, 92340 Bourg La Reine, France
*** opinions {are only mines, sont seulement les miennes} ***

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: array subscript is below array bounds : false positive?
  2009-09-15 10:19 array subscript is below array bounds : false positive? Peter A. Felvegi
  2009-09-15 10:30 ` Basile STARYNKEVITCH
@ 2009-09-15 14:56 ` Ian Lance Taylor
  2009-09-15 16:19   ` Richard Henderson
  1 sibling, 1 reply; 4+ messages in thread
From: Ian Lance Taylor @ 2009-09-15 14:56 UTC (permalink / raw)
  To: Peter A. Felvegi; +Cc: gcc

"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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: array subscript is below array bounds : false positive?
  2009-09-15 14:56 ` Ian Lance Taylor
@ 2009-09-15 16:19   ` Richard Henderson
  0 siblings, 0 replies; 4+ messages in thread
From: Richard Henderson @ 2009-09-15 16:19 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Peter A. Felvegi, gcc

On 09/15/2009 09:56 AM, Ian Lance Taylor wrote:
> void assert_failure () __attribute__ ((noreturn, always_inline));
> void assert_failure() { __asm__ ("int $0x03"); }
> #define ASSERT(x) if (x) { } else { assert_failure(); }

Incidentally, there's a __builtin_trap() that you may wish to use.  It 
won't invoke interrupt 3 like you currently do, but it will abort the 
program, and you'll be able to see from whence in the debugger.

Additionally, there are targets for which there exists a conditional 
trap instruction, e.g. sparc:

    cmp 0, %i0	// x in register %i0
    tne 0	// invoke trap vector 0 if compare is "not-equal"


r~

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2009-09-15 16:19 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-15 10:19 array subscript is below array bounds : false positive? Peter A. Felvegi
2009-09-15 10:30 ` Basile STARYNKEVITCH
2009-09-15 14:56 ` Ian Lance Taylor
2009-09-15 16:19   ` Richard Henderson

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