public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* S390: Silence gcc 5.1 array-bounds warnings if build with -O3.
@ 2016-01-28  8:22 Stefan Liebler
  2016-01-28  9:20 ` Andreas Schwab
  2016-01-28  9:27 ` Florian Weimer
  0 siblings, 2 replies; 5+ messages in thread
From: Stefan Liebler @ 2016-01-28  8:22 UTC (permalink / raw)
  To: libc-alpha

[-- Attachment #1: Type: text/plain, Size: 11170 bytes --]

Hi,

The gcc 5.1 reports some "array subscript is above array bounds"
warnings if compiled with -O3 on s390x. There are no warnings with -O2.
Older or newer GCCs do not report these warnings.

This patch silences these warnings with DIAG_* macros,
except the test-cases, where an assert is included.

Does anybody see these warnings on other architectures, too?
Is it okay to silence these warnings?


Here are the warnings with some comments:

gcc res_hconf.c -c -O3 ...
res_hconf.c: In function ‘_res_hconf_trim_domains’:
res_hconf.c:580:47: error: array subscript is above array bounds 
[-Werror=array-bounds]
        const char *trim = _res_hconf.trimdomain[i];

trimdomain is accessed in a loop in function _res_hconf_trim_domain(),
which is called in _res_hconf_trim_domains():
for (i = 0; i < _res_hconf.num_trimdomains; ++i)
{
   const char *trim = _res_hconf.trimdomain[i];
...

and is declared in resolv/res_hconf.h:
  #define TRIMDOMAINS_MAX 4
struct hconf
{
...
   int num_trimdomains;
   const char *trimdomain[TRIMDOMAINS_MAX];
...
};
extern struct hconf _res_hconf;

and defined in resolv/res_hconf.c:
struct hconf _res_hconf;

_res_hconf.num_trimdomains is only incremented in
static fucntion arg_trimdomain_list():
if (_res_hconf.num_trimdomains >= TRIMDOMAINS_MAX)
{
...
   return 0;
}
_res_hconf.trimdomain[_res_hconf.num_trimdomains++] = __strndup (start, 
len);
...


arg_trimdomain_list() is only called via do_init(), which is called via
__libc_once in _res_hconf_init().
As far as I saw, _res_hconf_trim_domains() is called after _res_hconf_init()
in inet/gethstbyad_r.c, which includes nss/getXXbyYY_r.c.






gcc gethnamaddr.c -c O3 ...
gethnamaddr.c: In function ‘addrsort’:
gethnamaddr.c:968:21: error: array subscript is above array bounds 
[-Werror=array-bounds]
    if (_res.sort_list[j].addr.s_addr ==
gethnamaddr.c:969:57: error: array subscript is above array bounds 
[-Werror=array-bounds]
       (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))

The same warning occurs in resolv/nss_dns/dns-host.c.
_res.sort_list is accessed in function addrsort() in gethnamaddr.c | 
resolv/nss_dns/dns-host.c:
for (j = 0 ; (unsigned)j < _res.nsort; j++)
{
   if (_res.sort_list[j].addr.s_addr ==
     (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))
       break;
...

It is declared in resolv/resolv.h:
  # define MAXRESOLVSORT 10 /* number of net to sort on */
struct __res_state {
...
   unsigned nsort:4; /* number of elements in sort_list[] */
...
   struct {
     struct in_addr addr;
     u_int32_t mask;
   } sort_list[MAXRESOLVSORT];
...
}
typedef struct __res_state *res_state;

and defined in resolv/res_libc.c:
struct __res_state _res __attribute__ ((nocommon));
__thread struct __res_state *__resp = &_res;
extern __thread struct __res_state *__libc_resp
   __attribute__ ((alias ("__resp"))) attribute_hidden;

_res is a macro define:
include/resolv.h:21:# define _res (*__resp)
resolv/resolv.h:251:#define _res (*__res_state())
__res_state() returns __resp. See:
nptl/res.c:23:__res_state (void)
resolv/res-state.c:23:__res_state (void)

_res.nsort is only incremented in function __res_vinit() in 
resolv/res_init.c:
__res_vinit(res_state statp, int preinit)
{
...
   int nsort = 0;
...
   while (nsort < MAXRESOLVSORT) {
...
     nsort++;
...
   }
...
   statp->nsort = nsort;


addrsort() is called in resolv/gethnamaddr.c:
static struct hostent *getanswer () {
...
463: addrsort(h_addr_ptrs, haveanswer);
...
}
which is called in:
struct hostent *gethostbyname2 (const char *name, int af) {...
	if (__res_maybe_init (&_res, 0) == -1) {
		__set_h_errno (NETDB_INTERNAL);
		return (NULL);
	}
...
628:	ret = getanswer(buf.buf, n, name, type);
...}

struct hostent * gethostbyaddr (const void *addr, socklen_t len, int af) 
{...
	if (__res_maybe_init (&_res, 0) == -1) {
		__set_h_errno (NETDB_INTERNAL);
		return (NULL);
...
727:	hp = getanswer(buf.buf, n, qbuf, T_PTR);
...}

addrsort() is called in resolv/nss_dns/dns-host.c, too:
static enum nss_status getanswer_r () { ...
957:addrsort (host_data->h_addr_ptrs, haveanswer);
..}
which is called in:
enum nss_status _nss_dns_gethostbyname3_r () {...
   if (__res_maybe_init (&_res, 0) == -1)
     return NSS_STATUS_UNAVAIL;
...
245:  status = getanswer_r (host_buffer.buf, n, name, type, result, 
buffer, buflen,
			errnop, h_errnop, map, ttlp, canonp);
...}
or in enum nss_status _nss_dns_gethostbyaddr2_r () {...
   if (__res_maybe_init (&_res, 0) == -1)
     return NSS_STATUS_UNAVAIL;
...
507:  status = getanswer_r (host_buffer.buf, n, qbuf, T_PTR, result, 
buffer, buflen,
...}			errnop, h_errnop, 0 /* XXX */, ttlp, NULL);





gcc programs/ld-ctype.c -c -O3
In file included from ../include/bits/string2.h:1:0,
                  from ../string/string.h:630,
                  from ../include/string.h:51,
                  from ../malloc/obstack.h:136,
                  from ../include/obstack.h:1,
                  from programs/ld-ctype.c:27:
programs/ld-ctype.c: In function ‘ctype_read’:
../string/bits/string2.h:807:7: error: array subscript is above array 
bounds [-Werror=array-bounds]
        : (__builtin_constant_p (s1) && __string2_1bptr_p (s1)        \
        ^
programs/ld-ctype.c:2538:7: note: in expansion of macro ‘strcmp’
    if (strcmp (now->val.str.startmb, ctype->mapnames[cnt]) == 0)
        ^
../string/bits/string2.h:807:7: error: array subscript is above array 
bounds [-Werror=array-bounds]
        : (__builtin_constant_p (s1) && __string2_1bptr_p (s1)        \
        ^
programs/ld-ctype.c:2821:10: note: in expansion of macro ‘strcmp’
       if (strcmp (now->val.str.startmb, ctype->mapnames[cnt]) == 0)
           ^

ctype->mapnames and ctype->classnames is accessed in function ctype_read():
void ctype_read(..) {...
   struct locale_ctype_t *ctype;
...
   ctype_startup (ldfile, result, charmap, copy_locale, ignore_content);
   ctype = result->categories[LC_CTYPE].ctype;
...
   ctype_class_new (.., ctype, ..);
...
   ctype_map_new (.., ctype, ..);
...
   for (cnt = 2; cnt < ctype->map_collection_nr; ++cnt)
     if (strcmp (now->val.str.startmb, ctype->mapnames[cnt]) == 0)
       break;
...
   for (cnt = 0; cnt < ctype->nr_charclass; ++cnt)
     if (strcmp (now->val.str.startmb, ctype->classnames[cnt]) == 0)
       break;
...}

Both are declared in ld-ctype.c:
struct locale_ctype_t
{
  #define MAX_NR_CHARCLASS (8 * sizeof (uint32_t))
   size_t nr_charclass;
   const char *classnames[MAX_NR_CHARCLASS];
  #define MAX_NR_CHARMAP 16
   const char *mapnames[MAX_NR_CHARMAP];
   size_t map_collection_nr;
}

nr_charclass is only incremented in ctype_class_new(), which is called 
in ctype_startup() or ctype_read():
static void ctype_class_new (struct linereader *lr, struct 
locale_ctype_t *ctype,
		 const char *name) {...
   if (ctype->nr_charclass == MAX_NR_CHARCLASS)
     error ();
   ctype->classnames[ctype->nr_charclass++] = name;
}

map_collection_nr is only incremented in ctype_map_new(), which is 
called in ctype_startup() or ctype_read():
static void ctype_map_new (struct linereader *lr, struct locale_ctype_t 
*ctype,
	       const char *name, const struct charmap_t *charmap) {...
   if (ctype->map_collection_nr == MAX_NR_CHARMAP)
     error ();
...
   ++ctype->map_collection_nr;
...}





gcc test-wmemcmp.c -c -O3 ...
In file included from ../string/test-memcmp.c:27:0,
                  from test-wmemcmp.c:2:
../string/test-memcmp.c: In function ‘check1’:
../string/test-string.h:135:19: warning: array subscript is above array 
bounds [-Warray-bounds]
       if (func_list[f].usable)     \
                    ^
../string/test-memcmp.c:446:7: note: in expansion of macro ‘FOR_EACH_IMPL’
        FOR_EACH_IMPL (impl, 0)
        ^
../string/test-string.h:137:22: warning: array subscript is above array 
bounds [-Warray-bounds]
    a->name = func_list[f].name;    \
                       ^
../string/test-memcmp.c:446:7: note: in expansion of macro ‘FOR_EACH_IMPL’
        FOR_EACH_IMPL (impl, 0)
        ^
../string/test-string.h:138:20: warning: array subscript is above array 
bounds [-Warray-bounds]
    a->fn = func_list[f].fn;    \
                     ^
../string/test-memcmp.c:446:7: note: in expansion of macro ‘FOR_EACH_IMPL’
        FOR_EACH_IMPL (impl, 0)
        ^

func_list is accessed in FOR_EACH_IMPL, which is defined in 
string/test-string.h:
  #ifdef TEST_NAME
/* Increase size of FUNC_LIST if assert is triggered at run-time.  */
  # define FUNC_LIST_MAX 32
static struct libc_ifunc_impl func_list[FUNC_LIST_MAX];
..
  # define FOR_EACH_IMPL(impl, notall) \
..
   for (f = 0; f < func_count; f++) \
     { \
       if (func_list[f].usable) \
...

func_count is setup in test_init() via a call to __libc_ifunc_impl_list(),
which is platform-dependent.
Thus I added an assert to check func_count.
static void test_init (void)
{
  #ifdef TEST_NAME
   func_count = __libc_ifunc_impl_list (TEST_NAME, func_list,
        (sizeof func_list
/ sizeof func_list[0]));
  #endif






gcc bug-regex17.c -c -O3
bug-regex17.c: In function ‘do_test’:
bug-regex17.c:91:8: error: array subscript is above array bounds 
[-Werror=array-bounds]
   if (rm[n].rm_so != tests[i].rm[n].rm_so
         ^
bug-regex17.c:91:32: error: array subscript is above array bounds 
[-Werror=array-bounds]
   if (rm[n].rm_so != tests[i].rm[n].rm_so
                                 ^
bug-regex17.c:92:20: error: array subscript is above array bounds 
[-Werror=array-bounds]
                || rm[n].rm_eo != tests[i].rm[n].rm_eo)
                     ^
bug-regex17.c:92:44: error: array subscript is above array bounds 
[-Werror=array-bounds]
                || rm[n].rm_eo != tests[i].rm[n].rm_eo)
                                             ^

The same applies to the bug-regex11|18|30.c files.

After a regexec () call, the test compares the results in rm
with the expected results in tests[i].rm:
for (n = 0; n < tests[i].nmatch; ++n)
{
   if (rm[n].rm_so != tests[i].rm[n].rm_so
       || rm[n].rm_eo != tests[i].rm[n].rm_eo)
     {
       if (tests[i].rm[n].rm_so == -1 && tests[i].rm[n].rm_eo == -1)
	break;
...

Both rm[] and tests[i].rm[] arrays have 5 elements.
The highest tests[i].nmatch is 5 in bug-regex11.c and < 5 in the other 
tests.
I've added an assert to check the bounds.



ChangeLog:

	* resolv/res_hconf.c: Include <libc-internal.h>.
	(_res_hconf_trim_domain): Ignore array-bounds warning.
	* resolv/gethnamaddr.c: Include <libc-internal.h>.
	(addrsort): Ignore array-bounds warning.
	* resolv/nss_dns/dns-host.c: Likewise.
	* locale/programs/ld-ctype.c: Include <libc-internal.h>.
	(ctype_read): Ignore array-bounds warning.
	* string/test-string.h: Include <assert.h>.
	Define FUNC_LIST_MAX.
	(FOR_EACH_IMPL): Add assert before accessing func_list[f].
	* posix/bug-regex11.c: Include <assert.h>.
	Define RM_MAX.
	(main): Add assert before accessing rm[n] and tests[i].rm[n].
	* posix/bug-regex18.c: Likewise.
	* posix/bug-regex17.c: Include <assert.h>.
	Define RM_MAX.
	(do_test): Add assert before accessing rm[n] and tests[i].rm[n].
	* posix/bug-regex30.c: Likewise.


[-- Attachment #2: 20160128_gcc51_O3_build_warnings.patch --]
[-- Type: text/x-patch, Size: 12846 bytes --]

diff --git a/locale/programs/ld-ctype.c b/locale/programs/ld-ctype.c
index 0fd141c..b43a640 100644
--- a/locale/programs/ld-ctype.c
+++ b/locale/programs/ld-ctype.c
@@ -41,6 +41,7 @@
 #include "locfile.h"
 
 #include <assert.h>
+#include <libc-internal.h>
 
 
 /* The bit used for representing a special class.  */
@@ -2535,8 +2536,16 @@ with character code range values one must use the absolute ellipsis `...'"));
 	      size_t cnt;
 
 	      for (cnt = 2; cnt < ctype->map_collection_nr; ++cnt)
-		if (strcmp (now->val.str.startmb, ctype->mapnames[cnt]) == 0)
-		  break;
+		{
+		  /* GCC 5.1 emits a "array subscript is above array bounds"
+		     warning if compiled with -O3. It does not occur with -O2.
+		     Older or newer GCCs does not emit this warning.  */
+		  DIAG_PUSH_NEEDS_COMMENT;
+		  DIAG_IGNORE_NEEDS_COMMENT (5.1, "-Warray-bounds");
+		  if (strcmp (now->val.str.startmb, ctype->mapnames[cnt]) == 0)
+		    break;
+		  DIAG_POP_NEEDS_COMMENT;
+		}
 
 	      if (cnt < ctype->map_collection_nr)
 		free (now->val.str.startmb);
@@ -2808,8 +2817,16 @@ previous definition was here")));
 	  /* This could mean one of several things.  First test whether
 	     it's a character class name.  */
 	  for (cnt = 0; cnt < ctype->nr_charclass; ++cnt)
-	    if (strcmp (now->val.str.startmb, ctype->classnames[cnt]) == 0)
-	      break;
+	    {
+	      /* GCC 5.1 emits a "array subscript is above array bounds"
+		 warning if compiled with -O3. It does not occur with -O2.
+		 Older or newer GCCs does not emit this warning.  */
+	      DIAG_PUSH_NEEDS_COMMENT;
+	      DIAG_IGNORE_NEEDS_COMMENT (5.1, "-Warray-bounds");
+	      if (strcmp (now->val.str.startmb, ctype->classnames[cnt]) == 0)
+		break;
+	      DIAG_POP_NEEDS_COMMENT;
+	    }
 	  if (cnt < ctype->nr_charclass)
 	    {
 	      class_bit = _ISwbit (cnt);
@@ -2818,8 +2835,16 @@ previous definition was here")));
 	      goto read_charclass;
 	    }
 	  for (cnt = 0; cnt < ctype->map_collection_nr; ++cnt)
-	    if (strcmp (now->val.str.startmb, ctype->mapnames[cnt]) == 0)
-	      break;
+	    {
+	      /* GCC 5.1 emits a "array subscript is above array bounds"
+		 warning if compiled with -O3. It does not occur with -O2.
+		 Older or newer GCCs does not emit this warning.  */
+	      DIAG_PUSH_NEEDS_COMMENT;
+	      DIAG_IGNORE_NEEDS_COMMENT (5.1, "-Warray-bounds");
+	      if (strcmp (now->val.str.startmb, ctype->mapnames[cnt]) == 0)
+		break;
+	      DIAG_POP_NEEDS_COMMENT;
+	    }
 	  if (cnt < ctype->map_collection_nr)
 	    {
 	      mapidx = cnt;
diff --git a/posix/bug-regex11.c b/posix/bug-regex11.c
index d3abe73..6497064 100644
--- a/posix/bug-regex11.c
+++ b/posix/bug-regex11.c
@@ -22,6 +22,9 @@
 #include <regex.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <assert.h>
+
+#define RM_MAX 5
 
 /* Tests supposed to match.  */
 struct
@@ -29,7 +32,7 @@ struct
   const char *pattern;
   const char *string;
   int flags, nmatch;
-  regmatch_t rm[5];
+  regmatch_t rm[RM_MAX];
 } tests[] = {
   /* Test for newline handling in regex.  */
   { "[^~]*~", "\nx~y", 0, 2, { { 0, 3 }, { -1, -1 } } },
@@ -93,7 +96,7 @@ int
 main (void)
 {
   regex_t re;
-  regmatch_t rm[5];
+  regmatch_t rm[RM_MAX];
   size_t i;
   int n, ret = 0;
 
@@ -120,16 +123,19 @@ main (void)
 	}
 
       for (n = 0; n < tests[i].nmatch; ++n)
-	if (rm[n].rm_so != tests[i].rm[n].rm_so
-              || rm[n].rm_eo != tests[i].rm[n].rm_eo)
-	  {
-	    if (tests[i].rm[n].rm_so == -1 && tests[i].rm[n].rm_eo == -1)
+	{
+	  assert (n < RM_MAX);
+	  if (rm[n].rm_so != tests[i].rm[n].rm_so
+	      || rm[n].rm_eo != tests[i].rm[n].rm_eo)
+	    {
+	      if (tests[i].rm[n].rm_so == -1 && tests[i].rm[n].rm_eo == -1)
+		break;
+	      printf ("%s: regexec %zd match failure rm[%d] %d..%d\n",
+		      tests[i].pattern, i, n, rm[n].rm_so, rm[n].rm_eo);
+	      ret = 1;
 	      break;
-	    printf ("%s: regexec %zd match failure rm[%d] %d..%d\n",
-		    tests[i].pattern, i, n, rm[n].rm_so, rm[n].rm_eo);
-	    ret = 1;
-	    break;
-	  }
+	    }
+	}
 
       regfree (&re);
     }
diff --git a/posix/bug-regex17.c b/posix/bug-regex17.c
index 8b9edfb..0168103 100644
--- a/posix/bug-regex17.c
+++ b/posix/bug-regex17.c
@@ -23,6 +23,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <locale.h>
+#include <assert.h>
+
+#define RM_MAX 5
 
 /* Tests supposed to match.  */
 struct
@@ -30,7 +33,7 @@ struct
   const char *pattern;
   const char *string;
   int flags, nmatch;
-  regmatch_t rm[5];
+  regmatch_t rm[RM_MAX];
 } tests[] = {
   /* U+00C4	\xc3\x84	LATIN CAPITAL LETTER A WITH DIAERESIS
      U+00D6	\xc3\x96	LATIN CAPITAL LETTER O WITH DIAERESIS
@@ -62,7 +65,7 @@ static int
 do_test (void)
 {
   regex_t re;
-  regmatch_t rm[5];
+  regmatch_t rm[RM_MAX];
   size_t i;
   int n, ret = 0;
 
@@ -88,16 +91,19 @@ do_test (void)
 	}
 
       for (n = 0; n < tests[i].nmatch; ++n)
-	if (rm[n].rm_so != tests[i].rm[n].rm_so
-              || rm[n].rm_eo != tests[i].rm[n].rm_eo)
-	  {
-	    if (tests[i].rm[n].rm_so == -1 && tests[i].rm[n].rm_eo == -1)
+	{
+	  assert (n < RM_MAX);
+	  if (rm[n].rm_so != tests[i].rm[n].rm_so
+	      || rm[n].rm_eo != tests[i].rm[n].rm_eo)
+	    {
+	      if (tests[i].rm[n].rm_so == -1 && tests[i].rm[n].rm_eo == -1)
+		break;
+	      printf ("regexec match failure rm[%d] %d..%d\n",
+		      n, rm[n].rm_so, rm[n].rm_eo);
+	      ret = 1;
 	      break;
-	    printf ("regexec match failure rm[%d] %d..%d\n",
-		    n, rm[n].rm_so, rm[n].rm_eo);
-	    ret = 1;
-	    break;
-	  }
+	    }
+	}
 
       regfree (&re);
     }
diff --git a/posix/bug-regex18.c b/posix/bug-regex18.c
index 6902f52..1a9c91b 100644
--- a/posix/bug-regex18.c
+++ b/posix/bug-regex18.c
@@ -23,6 +23,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <locale.h>
+#include <assert.h>
+
+#define RM_MAX 5
 
 /* Tests supposed to match.  */
 struct
@@ -30,7 +33,7 @@ struct
   const char *pattern;
   const char *string;
   int flags, nmatch;
-  regmatch_t rm[5];
+  regmatch_t rm[RM_MAX];
 } tests[] = {
   /* \xc4\xb0		LATIN CAPITAL LETTER I WITH DOT ABOVE
      \xc4\xb1		LATIN SMALL LETTER DOTLESS I
@@ -55,7 +58,7 @@ int
 main (void)
 {
   regex_t re;
-  regmatch_t rm[5];
+  regmatch_t rm[RM_MAX];
   size_t i;
   int n, ret = 0;
 
@@ -81,16 +84,19 @@ main (void)
 	}
 
       for (n = 0; n < tests[i].nmatch; ++n)
-	if (rm[n].rm_so != tests[i].rm[n].rm_so
-              || rm[n].rm_eo != tests[i].rm[n].rm_eo)
-	  {
-	    if (tests[i].rm[n].rm_so == -1 && tests[i].rm[n].rm_eo == -1)
+	{
+	  assert (n < RM_MAX);
+	  if (rm[n].rm_so != tests[i].rm[n].rm_so
+	      || rm[n].rm_eo != tests[i].rm[n].rm_eo)
+	    {
+	      if (tests[i].rm[n].rm_so == -1 && tests[i].rm[n].rm_eo == -1)
+		break;
+	      printf ("regexec match failure rm[%d] %d..%d\n",
+		      n, rm[n].rm_so, rm[n].rm_eo);
+	      ret = 1;
 	      break;
-	    printf ("regexec match failure rm[%d] %d..%d\n",
-		    n, rm[n].rm_so, rm[n].rm_eo);
-	    ret = 1;
-	    break;
-	  }
+	    }
+	}
 
       regfree (&re);
     }
diff --git a/posix/bug-regex30.c b/posix/bug-regex30.c
index e1ddf08..18362e0 100644
--- a/posix/bug-regex30.c
+++ b/posix/bug-regex30.c
@@ -23,6 +23,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <locale.h>
+#include <assert.h>
+
+#define RM_MAX 5
 
 /* Tests supposed to match.  */
 struct
@@ -30,7 +33,7 @@ struct
   const char *pattern;
   const char *string;
   int flags, nmatch;
-  regmatch_t rm[5];
+  regmatch_t rm[RM_MAX];
 } tests[] = {
   /* U+0413	\xd0\x93	CYRILLIC CAPITAL LETTER GHE
      U+0420	\xd0\xa0        CYRILLIC CAPITAL LETTER ER
@@ -61,7 +64,7 @@ do_test (void)
   for (size_t i = 0; i < sizeof (tests) / sizeof (tests[0]); ++i)
     {
       regex_t re;
-      regmatch_t rm[5];
+      regmatch_t rm[RM_MAX];
       int n = regcomp (&re, tests[i].pattern, tests[i].flags);
       if (n != 0)
 	{
@@ -81,16 +84,19 @@ do_test (void)
 	}
 
       for (n = 0; n < tests[i].nmatch; ++n)
-	if (rm[n].rm_so != tests[i].rm[n].rm_so
+	{
+	  assert (n < RM_MAX);
+	  if (rm[n].rm_so != tests[i].rm[n].rm_so
 	      || rm[n].rm_eo != tests[i].rm[n].rm_eo)
-	  {
-	    if (tests[i].rm[n].rm_so == -1 && tests[i].rm[n].rm_eo == -1)
+	    {
+	      if (tests[i].rm[n].rm_so == -1 && tests[i].rm[n].rm_eo == -1)
+		break;
+	      printf ("regexec match failure rm[%d] %d..%d\n",
+		      n, rm[n].rm_so, rm[n].rm_eo);
+	      ret = 1;
 	      break;
-	    printf ("regexec match failure rm[%d] %d..%d\n",
-		    n, rm[n].rm_so, rm[n].rm_eo);
-	    ret = 1;
-	    break;
-	  }
+	    }
+	}
 
       regfree (&re);
     }
diff --git a/resolv/gethnamaddr.c b/resolv/gethnamaddr.c
index 3a8e9b1..502c883 100644
--- a/resolv/gethnamaddr.c
+++ b/resolv/gethnamaddr.c
@@ -71,6 +71,7 @@ static char sccsid[] = "@(#)gethostnamadr.c	8.1 (Berkeley) 6/4/93";
 #include <ctype.h>
 #include <errno.h>
 #include <syslog.h>
+#include <libc-internal.h>
 
 #define RESOLVSORT
 
@@ -965,9 +966,17 @@ addrsort (char **ap, int num)
 	p = ap;
 	for (i = 0; i < num; i++, p++) {
 	    for (j = 0 ; (unsigned)j < _res.nsort; j++)
+	      {
+		/* GCC 5.1 emits a "array subscript is above array bounds"
+		   warning if compiled with -O3. It does not occur with -O2.
+		   Older or newer GCCs does not emit this warning.  */
+		DIAG_PUSH_NEEDS_COMMENT;
+		DIAG_IGNORE_NEEDS_COMMENT (5.1, "-Warray-bounds");
 		if (_res.sort_list[j].addr.s_addr ==
 		    (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))
 			break;
+		DIAG_POP_NEEDS_COMMENT;
+	      }
 	    aval[i] = j;
 	    if (needsort == 0 && i > 0 && j < aval[i-1])
 		needsort = i;
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index a255d5e..a27e776 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -86,6 +86,8 @@
 #include <resolv/mapv4v6addr.h>
 #include <resolv/mapv4v6hostent.h>
 
+#include <libc-internal.h>
+
 #define RESOLVSORT
 
 #if PACKETSZ > 65536
@@ -562,9 +564,17 @@ addrsort (char **ap, int num)
   for (i = 0; i < num; i++, p++)
     {
       for (j = 0 ; (unsigned)j < _res.nsort; j++)
-	if (_res.sort_list[j].addr.s_addr ==
-	    (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))
-	  break;
+	{
+	  /* GCC 5.1 emits a "array subscript is above array bounds"
+	     warning if compiled with -O3. It does not occur with -O2.
+	     Older or newer GCCs does not emit this warning.  */
+	  DIAG_PUSH_NEEDS_COMMENT;
+	  DIAG_IGNORE_NEEDS_COMMENT (5.1, "-Warray-bounds");
+	  if (_res.sort_list[j].addr.s_addr ==
+	      (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))
+	    break;
+	  DIAG_POP_NEEDS_COMMENT;
+	}
       aval[i] = j;
       if (needsort == 0 && i > 0 && j < aval[i-1])
 	needsort = i;
diff --git a/resolv/res_hconf.c b/resolv/res_hconf.c
index 5cd1289..1d95dba 100644
--- a/resolv/res_hconf.c
+++ b/resolv/res_hconf.c
@@ -46,6 +46,7 @@
 #include "res_hconf.h"
 #include <wchar.h>
 #include <atomic.h>
+#include <libc-internal.h>
 
 #if IS_IN (libc)
 # define fgets_unlocked __fgets_unlocked
@@ -577,7 +578,13 @@ _res_hconf_trim_domain (char *hostname)
 
   for (i = 0; i < _res_hconf.num_trimdomains; ++i)
     {
+      /* GCC 5.1 emits a "array subscript is above array bounds" warning
+	 if compiled with -O3. It does not occur with -O2.
+	 Older or newer GCCs does not emit this warning.  */
+      DIAG_PUSH_NEEDS_COMMENT;
+      DIAG_IGNORE_NEEDS_COMMENT (5.1, "-Warray-bounds");
       const char *trim = _res_hconf.trimdomain[i];
+      DIAG_POP_NEEDS_COMMENT;
 
       trim_len = strlen (trim);
       if (hostname_len > trim_len
diff --git a/string/test-string.h b/string/test-string.h
index 728a7c2..9e35aaf 100644
--- a/string/test-string.h
+++ b/string/test-string.h
@@ -51,6 +51,7 @@ extern impl_t __start_impls[], __stop_impls[];
 #include <errno.h>
 #include <time.h>
 #include <ifunc-impl-list.h>
+#include <assert.h>
 #define GL(x) _##x
 #define GLRO(x) _##x
 
@@ -106,7 +107,8 @@ size_t iterations = 100000;
 
 #ifdef TEST_NAME
 /* Increase size of FUNC_LIST if assert is triggered at run-time.  */
-static struct libc_ifunc_impl func_list[32];
+# define FUNC_LIST_MAX 32
+static struct libc_ifunc_impl func_list[FUNC_LIST_MAX];
 static int func_count;
 static int impl_count = -1;
 static impl_t *impl_array;
@@ -132,13 +134,16 @@ static impl_t *impl_array;
 	    if (impl != skip)						\
 	      *a++ = *impl;						\
 	  for (f = 0; f < func_count; f++)				\
-	    if (func_list[f].usable)					\
-	      {								\
-		a->name = func_list[f].name;				\
-		a->fn = func_list[f].fn;				\
-		a->test = 1;						\
-		a++;							\
-	      }								\
+	    {								\
+	      assert (f < FUNC_LIST_MAX);				\
+	      if (func_list[f].usable)					\
+		{							\
+		  a->name = func_list[f].name;				\
+		  a->fn = func_list[f].fn;				\
+		  a->test = 1;						\
+		  a++;							\
+		}							\
+	    }								\
 	  impl_count = a - impl_array;					\
 	}								\
       else								\

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

* Re: S390: Silence gcc 5.1 array-bounds warnings if build with -O3.
  2016-01-28  8:22 S390: Silence gcc 5.1 array-bounds warnings if build with -O3 Stefan Liebler
@ 2016-01-28  9:20 ` Andreas Schwab
  2016-01-29  9:45   ` Stefan Liebler
  2016-01-28  9:27 ` Florian Weimer
  1 sibling, 1 reply; 5+ messages in thread
From: Andreas Schwab @ 2016-01-28  9:20 UTC (permalink / raw)
  To: Stefan Liebler; +Cc: libc-alpha

Stefan Liebler <stli@linux.vnet.ibm.com> writes:

> The gcc 5.1 reports some "array subscript is above array bounds"
> warnings if compiled with -O3 on s390x. There are no warnings with -O2.
> Older or newer GCCs do not report these warnings.

If they are bugs in just a single (obsolete) version of gcc then we
shouldn't clutter the source just for that version.  Those that are
affected can always use --disable-werror.

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

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

* Re: S390: Silence gcc 5.1 array-bounds warnings if build with -O3.
  2016-01-28  8:22 S390: Silence gcc 5.1 array-bounds warnings if build with -O3 Stefan Liebler
  2016-01-28  9:20 ` Andreas Schwab
@ 2016-01-28  9:27 ` Florian Weimer
  2016-01-29  9:44   ` Stefan Liebler
  1 sibling, 1 reply; 5+ messages in thread
From: Florian Weimer @ 2016-01-28  9:27 UTC (permalink / raw)
  To: Stefan Liebler; +Cc: libc-alpha

On 01/28/2016 09:21 AM, Stefan Liebler wrote:
> The gcc 5.1 reports some "array subscript is above array bounds"
> warnings if compiled with -O3 on s390x. There are no warnings with -O2.
> Older or newer GCCs do not report these warnings.
> 
> This patch silences these warnings with DIAG_* macros,
> except the test-cases, where an assert is included.
> 
> Does anybody see these warnings on other architectures, too?
> Is it okay to silence these warnings?

Do you know if these warnings are related to GCC optimization decisions,
or are just there to educate the programmer?

Florian

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

* Re: S390: Silence gcc 5.1 array-bounds warnings if build with -O3.
  2016-01-28  9:27 ` Florian Weimer
@ 2016-01-29  9:44   ` Stefan Liebler
  0 siblings, 0 replies; 5+ messages in thread
From: Stefan Liebler @ 2016-01-29  9:44 UTC (permalink / raw)
  To: libc-alpha

On 01/28/2016 10:27 AM, Florian Weimer wrote:
> Do you know if these warnings are related to GCC optimization decisions,
> or are just there to educate the programmer?
No I don't. I've only recognized them while building with different 
versions in gcc 5 series.

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

* Re: S390: Silence gcc 5.1 array-bounds warnings if build with -O3.
  2016-01-28  9:20 ` Andreas Schwab
@ 2016-01-29  9:45   ` Stefan Liebler
  0 siblings, 0 replies; 5+ messages in thread
From: Stefan Liebler @ 2016-01-29  9:45 UTC (permalink / raw)
  To: libc-alpha

On 01/28/2016 10:19 AM, Andreas Schwab wrote:
> If they are bugs in just a single (obsolete) version of gcc then we
> shouldn't clutter the source just for that version.  Those that are
> affected can always use --disable-werror.
>
> Andreas.
>
That sounds fair.

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

end of thread, other threads:[~2016-01-29  9:45 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-28  8:22 S390: Silence gcc 5.1 array-bounds warnings if build with -O3 Stefan Liebler
2016-01-28  9:20 ` Andreas Schwab
2016-01-29  9:45   ` Stefan Liebler
2016-01-28  9:27 ` Florian Weimer
2016-01-29  9:44   ` Stefan Liebler

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