Bug 102316 - Unexpected stringop-overflow Warnings on POWER CPU
Summary: Unexpected stringop-overflow Warnings on POWER CPU
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 11.2.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2021-09-13 20:15 UTC by David Christensen
Modified: 2021-09-14 07:05 UTC (History)
1 user (show)

See Also:
Host:
Target: powerpc64le
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description David Christensen 2021-09-13 20:15:57 UTC
Building DPDK with gcc (GCC) 11.1.1 20210531 (Red Hat 11.1.1-3) on a POWER9 host and powerpc64le-linux-gnu-gcc (GCC) 11.2.1 20210802 (Advance-Toolchain 15.0-0) [ebcfb7a665c2] on an x86_64 cross-compile host, generates the warning:

In function ‘i40e_flow_parse_fdir_pattern’,
    inlined from ‘i40e_flow_parse_fdir_filter’ at ../drivers/net/i40e/i40e_flow.c:3274:8:
../drivers/net/i40e/i40e_flow.c:3052:69: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
 3052 |                                 filter->input.flow_ext.flexbytes[j] =
      |                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
 3053 |                                         raw_spec->pattern[i];
      |                                         ~~~~~~~~~~~~~~~~~~~~
In file included from ../drivers/net/i40e/i40e_flow.c:25:
../drivers/net/i40e/i40e_flow.c: In function ‘i40e_flow_parse_fdir_filter’:
../drivers/net/i40e/i40e_ethdev.h:630:17: note: at offset 16 into destination object ‘flexbytes’ of size 16
  630 |         uint8_t flexbytes[RTE_ETH_FDIR_MAX_FLEXLEN];
      |                 ^~~~~~~~~

See https://bugs.dpdk.org/show_bug.cgi?id=743 for additional details on DPDK build failure.  

Running cvise to reduce the failing code yields the following simplified test failure:

#include <stdlib.h>

#define LEN 16
struct {
  char c[LEN]
} d;

int a = LEN;
char* b;

int p() {
  for (int i = 0; i < a; i++) {
    d.c[i] = b[i];
  }
  return 0;
}

int main () {
  int r = 0;
  b = malloc(sizeof(char) * (LEN + 1));
  r = p();
  return r;
}


$ gcc -O3 test.c
test.c:6:1: warning: no semicolon at end of struct or union
    6 | } d;
      | ^
test.c: In function 'p':
test.c:13:12: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
   13 |     d.c[i] = b[i];
      |     ~~~~~~~^~~~~~
test.c:5:8: note: at offset 16 into destination object 'c' of size 16
    5 |   char c[LEN]
      |        ^
test.c:13:12: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
   13 |     d.c[i] = b[i];
      |     ~~~~~~~^~~~~~
test.c:5:8: note: at offset 17 into destination object 'c' of size 16
    5 |   char c[LEN]
      |        ^
test.c:13:12: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
   13 |     d.c[i] = b[i];
      |     ~~~~~~~^~~~~~
test.c:5:8: note: at offset 18 into destination object 'c' of size 16
    5 |   char c[LEN]
      |        ^
test.c:13:12: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
   13 |     d.c[i] = b[i];
      |     ~~~~~~~^~~~~~
test.c:5:8: note: at offset 19 into destination object 'c' of size 16
    5 |   char c[LEN]
      |        ^
test.c:13:12: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
   13 |     d.c[i] = b[i];
      |     ~~~~~~~^~~~~~
test.c:5:8: note: at offset 20 into destination object 'c' of size 16
    5 |   char c[LEN]
      |        ^
test.c:13:12: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
   13 |     d.c[i] = b[i];
      |     ~~~~~~~^~~~~~
test.c:5:8: note: at offset 21 into destination object 'c' of size 16
    5 |   char c[LEN]
      |        ^
test.c:13:12: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
   13 |     d.c[i] = b[i];
      |     ~~~~~~~^~~~~~
test.c:5:8: note: at offset 22 into destination object 'c' of size 16
    5 |   char c[LEN]
      |        ^
test.c:13:12: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
   13 |     d.c[i] = b[i];
      |     ~~~~~~~^~~~~~
test.c:5:8: note: at offset 23 into destination object 'c' of size 16
    5 |   char c[LEN]
      |        ^
test.c:13:12: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
   13 |     d.c[i] = b[i];
      |     ~~~~~~~^~~~~~
test.c:5:8: note: at offset 24 into destination object 'c' of size 16
    5 |   char c[LEN]
      |        ^
test.c:13:12: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
   13 |     d.c[i] = b[i];
      |     ~~~~~~~^~~~~~
test.c:5:8: note: at offset 25 into destination object 'c' of size 16
    5 |   char c[LEN]
      |        ^
test.c:13:12: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
   13 |     d.c[i] = b[i];
      |     ~~~~~~~^~~~~~
test.c:5:8: note: at offset 26 into destination object 'c' of size 16
    5 |   char c[LEN]
      |        ^
test.c:13:12: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
   13 |     d.c[i] = b[i];
      |     ~~~~~~~^~~~~~
test.c:5:8: note: at offset 27 into destination object 'c' of size 16
    5 |   char c[LEN]
      |        ^
test.c:13:12: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
   13 |     d.c[i] = b[i];
      |     ~~~~~~~^~~~~~
test.c:5:8: note: at offset 28 into destination object 'c' of size 16
    5 |   char c[LEN]
      |        ^
test.c:13:12: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
   13 |     d.c[i] = b[i];
      |     ~~~~~~~^~~~~~
test.c:5:8: note: at offset 29 into destination object 'c' of size 16
    5 |   char c[LEN]
      |        ^
test.c:13:12: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
   13 |     d.c[i] = b[i];
      |     ~~~~~~~^~~~~~
test.c:5:8: note: at offset 30 into destination object 'c' of size 16
    5 |   char c[LEN]
      |        ^

Compiling both the original DPDK and simplified code with -O3 for POWER systems generates the given warnings, but compiling the code with -O2 for POWER systems does not generate the warning.

Compiling the simplified code with either -O3 or -O2 for x86_64 systems does not generate a warning.
Comment 1 Andrew Pinski 2021-09-13 20:22:07 UTC
Looks like it is unrolling ...
Comment 2 Tee KOBAYASHI 2021-09-14 05:31:31 UTC
A workaround would be to __builtin_unreachable(), as usual:

@@ -9,6 +9,7 @@
 char* b;
 
 int p() {
+  if (a > LEN) __builtin_unreachable();
   for (int i = 0; i < a; i++) {
     d.c[i] = b[i];
   }