gcc 4.6 has now arrived as the default compiler on my desktop, and as previously reported, it throws a bunch of warnings, foiling my life-long plan of compiling PostgreSQL with -Werror.
So looking more aggressively into fixing some of these, let's look at this case: gistutil.c: In function ‘gistMakeUnionKey’: gistutil.c:263:16: warning: array subscript is above array bounds [-Warray-bounds] gistutil.c:268:16: warning: array subscript is above array bounds [-Warray-bounds] gistutil.c:273:16: warning: array subscript is above array bounds [-Warray-bounds] The code in question is this: typedef struct { int32 n; /* number of elements */ GISTENTRY vector[1]; /* variable-length array */ } GistEntryVector; Not sure why the new gcc is confused about this when -Warray-bounds has existed for a while. But thinking a bit further, the "proper" fix for this would be to use flexible array members like this: typedef struct { int32 n; /* number of elements */ GISTENTRY vector[]; } GistEntryVector; This is C99, but with some gentle standard autoconf seasoning, it can be made transparent. See attached patch. Is this a route we want to go down? It looks as though other compilers could also benefit from this. clang throws even more warnings of this kind, and the clang static analyzer even more. One thing that is a bit concerning is that throwing more flexible array members around the code wherever variable-length arrays are used results in crash and burn. Probably some places are using sizeof or offsetof on these structures in incompatible ways. So each place would have to be examined separately.
diff --git i/configure.in w/configure.in index ddc4cc9..e873c7b 100644 --- i/configure.in +++ w/configure.in @@ -1110,6 +1110,7 @@ AC_C_BIGENDIAN AC_C_CONST PGAC_C_INLINE AC_C_STRINGIZE +AC_C_FLEXIBLE_ARRAY_MEMBER PGAC_C_SIGNED AC_C_VOLATILE PGAC_C_FUNCNAME_SUPPORT diff --git i/src/include/access/gist.h w/src/include/access/gist.h index df9f39c..f3dfcaa 100644 --- i/src/include/access/gist.h +++ w/src/include/access/gist.h @@ -144,7 +144,7 @@ typedef struct GISTENTRY typedef struct { int32 n; /* number of elements */ - GISTENTRY vector[1]; /* variable-length array */ + GISTENTRY vector[FLEXIBLE_ARRAY_MEMBER]; } GistEntryVector; #define GEVHDRSZ (offsetof(GistEntryVector, vector)) diff --git i/src/include/pg_config.h.in w/src/include/pg_config.h.in index 5d38f25..19f38cc 100644 --- i/src/include/pg_config.h.in +++ w/src/include/pg_config.h.in @@ -61,6 +61,15 @@ (--enable-thread-safety) */ #undef ENABLE_THREAD_SAFETY +/* Define to nothing if C supports flexible array members, and to 1 if it does + not. That way, with a declaration like `struct s { int n; double + d[FLEXIBLE_ARRAY_MEMBER]; };', the struct hack can be used with pre-C99 + compilers. When computing the size of such an object, don't use 'sizeof + (struct s)' as it overestimates the size. Use 'offsetof (struct s, d)' + instead. Don't use 'offsetof (struct s, d[0])', as this doesn't work with + MSVC and with C++ compilers. */ +#undef FLEXIBLE_ARRAY_MEMBER + /* float4 values are passed by value if 'true', by reference if 'false' */ #undef FLOAT4PASSBYVAL
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers