[cfe-dev] Question about libc++ basic_string methods, inline, and LTO linking in 3.5 vs 3.6

Jan Voung jvoung at chromium.org
Wed Feb 11 15:01:33 PST 2015


Hi all,

I hope someone could shed some light on the following.

Some basic_string methods have "_LIBCPP_INLINE_VISIBILITY" in the <string>
header, while others are not. Where can I look up the rules for which
should be inline and which should not?

Perhaps that is not the right question to ask, but it is related to a
problem I'm seeing in LTO linking with LLVM/Clang/libc++ 3.5 vs 3.6. The
string headers have not changed much so I'm thinking the relevant change is
in LLVM or Clang.

For PNaCl, we do linking in this manner:

Step (1) LTO link of bitcode using gold, and the gold plugin.

gold -plugin LLVMgold.so -plugin-opt=emit-llvm -o merged.bc bc.o bc2.o ...
-lapp_native1.a -lapp_native2.a ...  -lc++ -lm ...

For various reasons, the setup is such that bc{1,2,...}.o are bitcode,
libc++ and libm are bitcode, and the libapp_native{1,2,...}.a are x86.

Step (2) compile the merged.bc to x86 (as merged.o).

Step (3) link native code: gold -o a.out merged.o -lapp_native1.a
-lapp_native2.a ...

Note that there is no native version of libc++ and libm, so they are absent
in this step.

In LLVM 3.5, step (1) would produce a merged.bc where
"_ZNSt3__1plIcNS_11char_traitsIcEENS_9allocatorIcEEEENS_12basic_stringIT_T0_T1_EEPKS6_RKS9_"
(an operator+ variant) is defined, but in 3.6 it is just a declaration.

If I use the linker "-y _ZNSt3..." option in step (1), it explains that
there are a few references to operator+ from within libc++, but no
references from any of the bc.o, bc2.o. It is not defined in any of the
bc.o, bc2.o either, but it is defined in libapp_native1.a and libc++. This
is the same in 3.5 and 3.6.

Since the operator+ variant is not in merged.bc w/ 3.6, step (3) ends up
pulling the definition from a libapp_native1.a member. However, that member
depends on libm for log/exp. For some reason, step (1) does not pull
log/exp into merged.bc from the bitcode libm. So in the end, linking in
step (3) fails with undefined references to log/exp. In 3.5, step 3 never
needed to pull in that member of libapp_native1.a.

If the operator+ variant was marked inline, then it would end up in
merged.bc and there is no need to worry about log/exp either. That is why I
ask about the "inline" rules.

Otherwise, I'm wondering if it is a bug that, for reasons besides inline,
step (1) did not end up with the operator+ definition in merged.bc. Or, is
entirely reasonable for merged.bc to not have the definition of operator+
(deferring to libapp_native1), and the bug is that merged.bc doesn't end up
with the definition of log/exp? <speculation> Maybe a problem is that the
member thought to have supplied operator+ from libapp_native1.a in step (1)
is one that doesn't depend on log/exp, but the one ultimately chosen in
step (3) is one that does depend on log/exp </speculation>.

Or, is this whole setup of (1), (2), (3) unusual and not expected to work
well?

Thanks in advance,

- Jan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20150211/0bb7d03a/attachment.html>


More information about the cfe-dev mailing list