From patchwork Thu Jan 28 08:21:33 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Stefan Liebler X-Patchwork-Id: 10651 Received: (qmail 121831 invoked by alias); 28 Jan 2016 08:22:00 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 121819 invoked by uid 89); 28 Jan 2016 08:21:58 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.1 required=5.0 tests=AWL, BAYES_50, RCVD_IN_DNSWL_LOW, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 spammy=580, 416, 807, nss X-HELO: plane.gmane.org To: libc-alpha@sourceware.org From: Stefan Liebler Subject: S390: Silence gcc 5.1 array-bounds warnings if build with -O3. Date: Thu, 28 Jan 2016 09:21:33 +0100 Lines: 834 Message-ID: Mime-Version: 1.0 X-Mozilla-News-Host: news://news.gmane.org:119 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.5.0 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 . (_res_hconf_trim_domain): Ignore array-bounds warning. * resolv/gethnamaddr.c: Include . (addrsort): Ignore array-bounds warning. * resolv/nss_dns/dns-host.c: Likewise. * locale/programs/ld-ctype.c: Include . (ctype_read): Ignore array-bounds warning. * string/test-string.h: Include . Define FUNC_LIST_MAX. (FOR_EACH_IMPL): Add assert before accessing func_list[f]. * posix/bug-regex11.c: Include . 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 . Define RM_MAX. (do_test): Add assert before accessing rm[n] and tests[i].rm[n]. * posix/bug-regex30.c: Likewise. 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 +#include /* 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 #include #include +#include + +#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 #include #include +#include + +#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 #include #include +#include + +#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 #include #include +#include + +#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 #include #include +#include #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 #include +#include + #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 #include +#include #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 #include #include +#include #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 \