<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 - Extend clang to link C code with C++ libraries, that are compiled with -fsanitize=undefined"
href="https://bugs.llvm.org/show_bug.cgi?id=45948">45948</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>Extend clang to link C code with C++ libraries, that are compiled with -fsanitize=undefined
</td>
</tr>
<tr>
<th>Product</th>
<td>compiler-rt
</td>
</tr>
<tr>
<th>Version</th>
<td>10.0
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</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>ubsan
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>dilyan.palauzov@aegee.org
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>I create a file d.cpp:
struct D {
bool d;
};
struct E : virtual D {
int e;
};
extern "C" {
void f();
}
void f() {
D g = E();
};
and compile it with clang 10.0
$ clang++ -fsanitize=undefined -shared -fpic -o libd.so d.cpp
Then I create a file h.c:
void f();
int main() {
f();
return 0;
}
and compile it with:
$ clang -fsanitize=undefined -L. -ld h.c
/usr/local/bin/ld: ./libd.so: undefined reference to `__ubsan_vptr_type_cache'
/usr/local/bin/ld: ./libd.so: undefined reference to
`__ubsan_handle_dynamic_type_cache_miss'
clang-10: error: linker command failed with exit code 1 (use -v to see
invocation)
If I use instead
$ clang -fsanitize=undefined -L. -ld h.c -lubsan
then it magically works. But libubsan is from gcc, sometimes does not contain
the symbols that clang emits and UBSAN is not supposed to work this way.
If I take instead j.cpp:
extern "C" {
void f();
}
int main() {
f();
return 0;
}
then
$ clang++ -fsanitize=undefined -L. -ld j.cpp
does work. If I put in h.c the f() declarition withing extern "C" {}, then
$ clang++ -fsanitize=undefined -L. -ld h.c
clang-10: warning: treating 'c' input as 'c++' when in C++ mode, this behavior
is deprecated [-Wdeprecated]
works somehow.
If I use:
$ clang -fsanitize=undefined -c -o h.o h.c
$ clang++ -fsanitize=undefined h.o -L. -ld -o h
then it also works, but build tools do not know that they cannot short-circuit
to
$ clang -fsanitize=undefined -o h -L. -ld h.c
<a href="https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html#usage">https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html#usage</a> says for
Clang 11 (I use 10): “Use clang++ to compile and link your program with
-fsanitize=undefined flag. … You can use clang instead of clang++ if you’re
compiling/linking C code.”
Now, I am compiling C code, but linking it with C++ code. There are real-world
use cases: ICU and WebKIT are in C++, but can be used from C code. So to
verify the whole linking C code using clang, with C++ libraries must also work.
See also <a href="https://sourceware.org/bugzilla/show_bug.cgi?id=25940">https://sourceware.org/bugzilla/show_bug.cgi?id=25940</a> .
⇒ Enhance `clang -fsanitize=undefined -ld` to link with the d-library, even
when that library is in C++ and was compiled with `clang++
-fsanitize=undefined`.</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>