[Bug gcov-profile/101618] New: [GCOV] Wrong coverage caused by call site in a "for" statement
njuwy at smail dot nju.edu.cn
gcc-bugzilla@gcc.gnu.org
Sun Jul 25 07:55:50 GMT 2021
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101618
Bug ID: 101618
Summary: [GCOV] Wrong coverage caused by call site in a "for"
statement
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
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct obstack {};
struct bitmap_head_def;
typedef struct bitmap_head_def *bitmap;
typedef const struct bitmap_head_def *const_bitmap;
typedef unsigned long BITMAP_WORD;
typedef struct bitmap_obstack {
struct bitmap_element_def *elements;
struct bitmap_head_def *heads;
struct obstack obstack;
} bitmap_obstack;
typedef struct bitmap_element_def {
struct bitmap_element_def *next;
struct bitmap_element_def *prev;
unsigned int indx;
BITMAP_WORD bits[((128 + (8 * 8 * 1u) - 1) / (8 * 8 * 1u))];
} bitmap_element;
struct bitmap_descriptor;
typedef struct bitmap_head_def {
bitmap_element *first;
bitmap_element *current;
unsigned int indx;
bitmap_obstack *obstack;
} bitmap_head;
bitmap_element bitmap_zero_bits;
typedef struct {
bitmap_element *elt1;
bitmap_element *elt2;
unsigned word_no;
BITMAP_WORD bits;
} bitmap_iterator;
static void __attribute__((noinline))
bmp_iter_set_init(bitmap_iterator *bi, const_bitmap map, unsigned start_bit,
unsigned *bit_no) {
bi->elt1 = map->first;
bi->elt2 = ((void *)0);
while (1) {
if (!bi->elt1) {
bi->elt1 = &bitmap_zero_bits;
break;
}
if (bi->elt1->indx >=
start_bit / (((128 + (8 * 8 * 1u) - 1) / (8 * 8 * 1u)) * (8 * 8 * 1u)))
break;
bi->elt1 = bi->elt1->next;
}
if (bi->elt1->indx !=
start_bit / (((128 + (8 * 8 * 1u) - 1) / (8 * 8 * 1u)) * (8 * 8 * 1u)))
start_bit = bi->elt1->indx *
(((128 + (8 * 8 * 1u) - 1) / (8 * 8 * 1u)) * (8 * 8 * 1u));
bi->word_no =
start_bit / (8 * 8 * 1u) % ((128 + (8 * 8 * 1u) - 1) / (8 * 8 * 1u));
bi->bits = bi->elt1->bits[bi->word_no];
bi->bits >>= start_bit % (8 * 8 * 1u);
start_bit += !bi->bits;
*bit_no = start_bit;
}
static void __attribute__((noinline))
bmp_iter_next(bitmap_iterator *bi, unsigned *bit_no) {
bi->bits >>= 1;
*bit_no += 1;
}
static unsigned char __attribute__((noinline))
bmp_iter_set_tail(bitmap_iterator *bi, unsigned *bit_no) {
while (!(bi->bits & 1)) {
bi->bits >>= 1;
*bit_no += 1;
}
return 1;
}
static __inline__ unsigned char bmp_iter_set(bitmap_iterator *bi,
unsigned *bit_no) {
unsigned bno = *bit_no;
BITMAP_WORD bits = bi->bits;
bitmap_element *elt1;
if (bits) {
while (!(bits & 1)) {
bits >>= 1;
bno += 1;
}
*bit_no = bno;
return 1;
}
*bit_no = ((bno + 64 - 1) / 64 * 64);
bi->word_no++;
elt1 = bi->elt1;
while (1) {
while (bi->word_no != 2) {
bi->bits = elt1->bits[bi->word_no];
if (bi->bits) {
bi->elt1 = elt1;
return bmp_iter_set_tail(bi, bit_no);
}
*bit_no += 64;
bi->word_no++;
}
elt1 = elt1->next;
if (!elt1) {
bi->elt1 = elt1;
return 0;
}
*bit_no = elt1->indx * (2 * 64);
bi->word_no = 0;
}
}
extern void abort(void);
static void __attribute__((noinline)) catchme(int i) {
if (i != 0 && i != 64)
abort();
}
static void __attribute__((noinline)) foobar(bitmap_head *chain) {
bitmap_iterator rsi;
unsigned int regno;
for (bmp_iter_set_init(&(rsi), (chain), (0), &(regno));
bmp_iter_set(&(rsi), &(regno)); bmp_iter_next(&(rsi), &(regno)))
catchme(regno);
}
int main() {
bitmap_element elem = {(void *)0, (void *)0, 0, {1, 1}};
bitmap_head live_throughout = {&elem, &elem, 0, (void *)0};
foobar(&live_throughout);
return 0;
}
$ gcc -O0 --coverage test.c;./a.out;gcov test;cat test.c.gcov
File 'test.c'
Lines executed:80.88% of 68
Creating 'test.c.gcov'
-: 0:Source:test.c
-: 0:Graph:test.gcno
-: 0:Data:test.gcda
-: 0:Runs:1
-: 1:#include <setjmp.h>
-: 2:#include <stdio.h>
-: 3:#include <stdlib.h>
-: 4:#include <string.h>
-: 5:struct obstack {};
-: 6:struct bitmap_head_def;
-: 7:typedef struct bitmap_head_def *bitmap;
-: 8:typedef const struct bitmap_head_def *const_bitmap;
-: 9:typedef unsigned long BITMAP_WORD;
-: 10:typedef struct bitmap_obstack {
-: 11: struct bitmap_element_def *elements;
-: 12: struct bitmap_head_def *heads;
-: 13: struct obstack obstack;
-: 14:} bitmap_obstack;
-: 15:typedef struct bitmap_element_def {
-: 16: struct bitmap_element_def *next;
-: 17: struct bitmap_element_def *prev;
-: 18: unsigned int indx;
-: 19: BITMAP_WORD bits[((128 + (8 * 8 * 1u) - 1) / (8 * 8 * 1u))];
-: 20:} bitmap_element;
-: 21:
-: 22:struct bitmap_descriptor;
-: 23:
-: 24:typedef struct bitmap_head_def {
-: 25: bitmap_element *first;
-: 26: bitmap_element *current;
-: 27: unsigned int indx;
-: 28: bitmap_obstack *obstack;
-: 29:} bitmap_head;
-: 30:
-: 31:bitmap_element bitmap_zero_bits;
-: 32:
-: 33:typedef struct {
-: 34: bitmap_element *elt1;
-: 35: bitmap_element *elt2;
-: 36: unsigned word_no;
-: 37: BITMAP_WORD bits;
-: 38:} bitmap_iterator;
-: 39:
-: 40:static void __attribute__((noinline))
1: 41:bmp_iter_set_init(bitmap_iterator *bi, const_bitmap map,
unsigned start_bit,
-: 42: unsigned *bit_no) {
1: 43: bi->elt1 = map->first;
1: 44: bi->elt2 = ((void *)0);
-: 45:
-: 46: while (1) {
1: 47: if (!bi->elt1) {
#####: 48: bi->elt1 = &bitmap_zero_bits;
#####: 49: break;
-: 50: }
-: 51:
1: 52: if (bi->elt1->indx >=
1: 53: start_bit / (((128 + (8 * 8 * 1u) - 1) / (8 * 8 * 1u))
* (8 * 8 * 1u)))
1: 54: break;
#####: 55: bi->elt1 = bi->elt1->next;
-: 56: }
-: 57:
1: 58: if (bi->elt1->indx !=
1: 59: start_bit / (((128 + (8 * 8 * 1u) - 1) / (8 * 8 * 1u)) *
(8 * 8 * 1u)))
#####: 60: start_bit = bi->elt1->indx *
-: 61: (((128 + (8 * 8 * 1u) - 1) / (8 * 8 * 1u)) * (8
* 8 * 1u));
-: 62:
1: 63: bi->word_no =
1: 64: start_bit / (8 * 8 * 1u) % ((128 + (8 * 8 * 1u) - 1) / (8
* 8 * 1u));
1: 65: bi->bits = bi->elt1->bits[bi->word_no];
1: 66: bi->bits >>= start_bit % (8 * 8 * 1u);
-: 67:
1: 68: start_bit += !bi->bits;
-: 69:
1: 70: *bit_no = start_bit;
1: 71:}
-: 72:
-: 73:static void __attribute__((noinline))
2: 74:bmp_iter_next(bitmap_iterator *bi, unsigned *bit_no) {
2: 75: bi->bits >>= 1;
2: 76: *bit_no += 1;
2: 77:}
-: 78:
-: 79:static unsigned char __attribute__((noinline))
1: 80:bmp_iter_set_tail(bitmap_iterator *bi, unsigned *bit_no) {
1: 81: while (!(bi->bits & 1)) {
#####: 82: bi->bits >>= 1;
#####: 83: *bit_no += 1;
-: 84: }
1: 85: return 1;
-: 86:}
-: 87:
3: 88:static __inline__ unsigned char bmp_iter_set(bitmap_iterator
*bi,
-: 89: unsigned *bit_no)
{
3: 90: unsigned bno = *bit_no;
3: 91: BITMAP_WORD bits = bi->bits;
-: 92: bitmap_element *elt1;
-: 93:
3: 94: if (bits) {
1: 95: while (!(bits & 1)) {
#####: 96: bits >>= 1;
#####: 97: bno += 1;
-: 98: }
1: 99: *bit_no = bno;
1: 100: return 1;
-: 101: }
-: 102:
2: 103: *bit_no = ((bno + 64 - 1) / 64 * 64);
2: 104: bi->word_no++;
-: 105:
2: 106: elt1 = bi->elt1;
-: 107: while (1) {
2: 108: while (bi->word_no != 2) {
1: 109: bi->bits = elt1->bits[bi->word_no];
1: 110: if (bi->bits) {
1: 111: bi->elt1 = elt1;
1: 112: return bmp_iter_set_tail(bi, bit_no);
-: 113: }
#####: 114: *bit_no += 64;
#####: 115: bi->word_no++;
-: 116: }
1: 117: elt1 = elt1->next;
1: 118: if (!elt1) {
1: 119: bi->elt1 = elt1;
1: 120: return 0;
-: 121: }
#####: 122: *bit_no = elt1->indx * (2 * 64);
#####: 123: bi->word_no = 0;
-: 124: }
-: 125:}
-: 126:
-: 127:extern void abort(void);
-: 128:
2: 129:static void __attribute__((noinline)) catchme(int i) {
2: 130: if (i != 0 && i != 64)
#####: 131: abort();
2: 132:}
1: 133:static void __attribute__((noinline)) foobar(bitmap_head
*chain) {
-: 134: bitmap_iterator rsi;
-: 135: unsigned int regno;
4: 136: for (bmp_iter_set_init(&(rsi), (chain), (0), &(regno));
3: 137: bmp_iter_set(&(rsi), &(regno)); bmp_iter_next(&(rsi),
&(regno)))
2: 138: catchme(regno);
1: 139:}
-: 140:
1: 141:int main() {
1: 142: bitmap_element elem = {(void *)0, (void *)0, 0, {1, 1}};
1: 143: bitmap_head live_throughout = {&elem, &elem, 0, (void *)0};
1: 144: foobar(&live_throughout);
1: 145: return 0;
-: 146:}
The coverage of line 136 was wrongly marked as 4
More information about the Gcc-bugs
mailing list