<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - [llvm-cov] The function array causes wrong coverage"
href="https://bugs.llvm.org/show_bug.cgi?id=51025">51025</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>[llvm-cov] The function array causes wrong coverage
</td>
</tr>
<tr>
<th>Product</th>
<td>Runtime Libraries
</td>
</tr>
<tr>
<th>Version</th>
<td>12.0
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>All
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>enhancement
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>libprofile library
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>byone.heng@gmail.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>$./clang -v
clang version 12.0.0 (<a href="https://github.com/llvm/llvm-project.git">https://github.com/llvm/llvm-project.git</a>
b6c8feb29fce39121884f7e08ec6eb0f58da3fb7)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/x/project/llvm-project/build/install/bin/.
Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/8
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.5.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/8
Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.5.0
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Candidate multilib: x32;@mx32
Selected multilib: .;@m64
$cat test.c
———————————————————
const volatile int true_var = 1;
static volatile unsigned int false_var = 0;
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int malloc_depth = 0;
static char memory[128* 1024];
static size_t memory_p = 0;
void f1(void) {}
void f2(void) {}
typedef void (*fun_t)(void);
static const fun_t funs[2] = { f1, f2, };
static void * malloc_impl(size_t size) {
void * r = &memory[memory_p];
/* The malloc() and calloc() functions return a pointer to the allocated
* memory, which is suitably aligned for any built-in type. Use 16
* bytes here as the basic alignment requirement for user-defined malloc
* and calloc. See PR97594 for the details. */
#define ROUND_UP_FOR_16B_ALIGNMENT(x) ((x + 15) & (-16))
memory_p += ROUND_UP_FOR_16B_ALIGNMENT(size);
// force TOPN profile
funs[size % 2]();
return r;
}
// Override default malloc, check it it get s called recursively
void * malloc(size_t size) {
// Must not be called recursively. Malloc implementation does not support
it.
if (malloc_depth != 0) __builtin_trap();
if( false_var > 0 )
{
++malloc_depth;
void * r = malloc_impl(size);
--malloc_depth;
return r;
}
++malloc_depth;
void * r = malloc_impl(size);
--malloc_depth;
return r;
}
// Called from gcov
void *calloc(size_t nmemb, size_t size) {
// Must not be called recursively. Malloc implementation does not support
it.
if (malloc_depth != 0) __builtin_trap();
++malloc_depth;
void * r = malloc_impl(size * nmemb);
memset(r, 0, size * nmemb);
--malloc_depth;
return r;
}
void free(void *ptr){}
int main() {
void * p = malloc(8);
return p != 0 ? 0 : 1;
}
——————————————————
$clang -O0 -g -fcoverage-mapping -fprofile-instr-generate=test.profraw test.c;
./a.out; llvm-profdata merge test.profraw -o test.profdata; llvm-cov show a.out
-instr-profile=test.profdata test.c > test.lcov; cat test.lcov
4| |const volatile int true_var = 1;
5| |static volatile unsigned int false_var = 0;
6| |
7| |#define _GNU_SOURCE
8| |
9| |#include <stdio.h>
10| |#include <stdlib.h>
11| |#include <string.h>
12| |
13| |static int malloc_depth = 0;
14| |
15| |static char memory[128* 1024];
16| |static size_t memory_p = 0;
17| |
18| 6|void f1(void) {}
19| 1|void f2(void) {}
20| |
21| |typedef void (*fun_t)(void);
22| |static const fun_t funs[2] = { f1, f2, };
23| |
24| 7|static void * malloc_impl(size_t size) {
25| 7| void * r = &memory[memory_p];
26| | /* The malloc() and calloc() functions return a pointer to
the allocated
27| | * memory, which is suitably aligned for any built-in type.
Use 16
28| | * bytes here as the basic alignment requirement for
user-defined malloc
29| | * and calloc. See PR97594 for the details. */
30| 7| #define ROUND_UP_FOR_16B_ALIGNMENT(x) ((x + 15) & (-16))
31| |
32| 7| memory_p += ROUND_UP_FOR_16B_ALIGNMENT(size);
33| |
34| | // force TOPN profile
35| 7| printf("%d\n",size%2);
36| 7| funs[size % 2]();
37| 7| return r;
38| 7|}
39| |
40| |// Override default malloc, check it it get s called recursively
41| 7|void * malloc(size_t size) {
42| | // Must not be called recursively. Malloc implementation does
not support it.
43| 7| if (malloc_depth != 0) __builtin_trap();
44| |
45| 7| if( false_var > 0 )
46| 0| {
47| 0| ++malloc_depth;
48| 0| void * r = malloc_impl(size);
49| 0| --malloc_depth;
50| 0| return r;
51| 0| }
52| 7| ++malloc_depth;
53| 7| void * r = malloc_impl(size);
54| 7| --malloc_depth;
55| 7| return r;
56| 7|}
57| |
58| |// Called from gcov
59| 0|void *calloc(size_t nmemb, size_t size) {
60| | // Must not be called recursively. Malloc implementation
does not support it.
61| 0| if (malloc_depth != 0) __builtin_trap();
62| |
63| 0| ++malloc_depth;
64| 0| void * r = malloc_impl(size * nmemb);
65| 0| memset(r, 0, size * nmemb);
66| 0| --malloc_depth;
67| 0| return r;
68| 0|}
69| |
70| 1|void free(void *ptr){}
71| |
72| 1|int main() {
73| 1| void * p = malloc(8);
74| 1| return p != 0 ? 0 : 1;
75| 1|}
In my opinion, line 18 should be executed 7 times, and line 19 should not be
executed.</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>