[Bug gcov-profile/101193] New: [GCOV] Bit operation leads to wrong coverage information

njuwy at smail dot nju.edu.cn gcc-bugzilla@gcc.gnu.org
Thu Jun 24 13:04:20 GMT 2021


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101193

            Bug ID: 101193
           Summary: [GCOV]  Bit operation leads to wrong coverage
                    information
           Product: gcc
           Version: 10.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: gcov-profile
          Assignee: unassigned at gcc dot gnu.org
          Reporter: njuwy at smail dot nju.edu.cn
                CC: marxin at gcc dot gnu.org
  Target Milestone: ---

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/x86_64-pc-linux-gnu/10.2.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../configure -enable-checking=release -enable-languages=c,c++
-disable-multilib
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 10.2.0 (GCC) 

$ cat test.c
#ifdef __UINT32_TYPE__
typedef __UINT32_TYPE__ uint32_t;
#else
typedef __UINT32_TYPE__ unsigned;
#endif

struct bitfield {
  unsigned char f0 : 7;
  unsigned char : 1;
  unsigned char f1 : 7;
  unsigned char : 1;
  unsigned char f2 : 7;
  unsigned char : 1;
  unsigned char f3 : 7;
};

struct ok {
  unsigned char f0;
  unsigned char f1;
  unsigned char f2;
  unsigned char f3;
};

union bf_or_uint32 {
  struct ok inval;
  struct bitfield bfval;
};


__attribute__((noinline, noclone)) uint32_t
partial_read_le32(union bf_or_uint32 in) {
  return in.bfval.f0 | (in.bfval.f1 << 8) | (in.bfval.f2 << 16) |
         (in.bfval.f3 << 24);
}


int main() {
  union bf_or_uint32 bfin;
  uint32_t out;
  char cin[] = {0x83, 0x85, 0x87, 0x89};
  bfin.inval = (struct ok){0x83, 0x85, 0x87, 0x89};
  out = partial_read_le32(bfin);


  return 0;
}

$ gcc -O0 --coverage test.c;./a.out;gcov test;cat test.c.gcov
File 'test.c'
Lines executed:100.00% of 8
Creating 'test.c.gcov'

        -:    0:Source:test.c
        -:    0:Graph:test.gcno
        -:    0:Data:test.gcda
        -:    0:Runs:1
        -:    1:#ifdef __UINT32_TYPE__
        -:    2:typedef __UINT32_TYPE__ uint32_t;
        -:    3:#else
        -:    4:typedef __UINT32_TYPE__ unsigned;
        -:    5:#endif
        -:    6:
        -:    7:struct bitfield {
        -:    8:  unsigned char f0 : 7;
        -:    9:  unsigned char : 1;
        -:   10:  unsigned char f1 : 7;
        -:   11:  unsigned char : 1;
        -:   12:  unsigned char f2 : 7;
        -:   13:  unsigned char : 1;
        -:   14:  unsigned char f3 : 7;
        -:   15:};
        -:   16:
        -:   17:struct ok {
        -:   18:  unsigned char f0;
        -:   19:  unsigned char f1;
        -:   20:  unsigned char f2;
        -:   21:  unsigned char f3;
        -:   22:};
        -:   23:
        -:   24:union bf_or_uint32 {
        -:   25:  struct ok inval;
        -:   26:  struct bitfield bfval;
        -:   27:};
        -:   28:
        -:   29:
        -:   30:__attribute__((noinline, noclone)) uint32_t
        1:   31:partial_read_le32(union bf_or_uint32 in) {
        2:   32:  return in.bfval.f0 | (in.bfval.f1 << 8) | (in.bfval.f2 << 16)
|
        1:   33:         (in.bfval.f3 << 24);
        -:   34:}
        -:   35:
        -:   36:
        1:   37:int main() {
        -:   38:  union bf_or_uint32 bfin;
        -:   39:  uint32_t out;
        1:   40:  char cin[] = {0x83, 0x85, 0x87, 0x89};
        1:   41:  bfin.inval = (struct ok){0x83, 0x85, 0x87, 0x89};
        1:   42:  out = partial_read_le32(bfin);
        -:   43:
        -:   44:
        1:   45:  return 0;
        -:   46:}
        -:   47:
        -:   48:

Line 32 should be executed only once.


More information about the Gcc-bugs mailing list