clang++ no longer ABI-compatible with g++

Bug #1488254 reported by Anders Kaseorg
76
This bug affects 14 people
Affects Status Importance Assigned to Milestone
LLVM
Confirmed
Medium
llvm-toolchain-3.6 (Ubuntu)
Confirmed
High
Unassigned
Nominated for Xenial by Jeremy Bícha
llvm-toolchain-3.8 (Ubuntu)
Fix Released
High
Unassigned
Nominated for Xenial by Jeremy Bícha

Bug Description

$ cat foo.cc
#include <string>
std::string hello = "Hello, world!\n";
$ cat bar.cc
#include <string>
#include <iostream>
extern std::string hello;
int main() {
    std::cout << hello;
    return 0;
}
$ g++ -c foo.cc && g++ foo.o bar.cc && ./a.out
Hello, world!
$ clang++ -c foo.cc && clang++ foo.o bar.cc && ./a.out
Hello, world!
$ g++ -c foo.cc && clang++ foo.o bar.cc && ./a.out
/tmp/bar-34fb23.o: In function `main':
bar.cc:(.text+0x14): undefined reference to `hello'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
$ clang++ -c foo.cc && g++ foo.o bar.cc && ./a.out
/tmp/ccqU38Mh.o: In function `main':
bar.cc:(.text+0x5): undefined reference to `hello[abi:cxx11]'
collect2: error: ld returned 1 exit status

In practice, this means that many programs using C++ libraries other than libstdc++ fail to compile with clang++. For example, mosh fails with undefined references to google::protobuf::internal::empty_string_, google::protobuf::MessageLite::InitializationErrorString() const, and google::protobuf::MessageLite::SerializeAsString() const.

Tags: patch
Revision history for this message
In , Bero-b (bero-b) wrote :

With the release of gcc 5.1, libstdc++ has started using the abi_tag attribute.

The attribute is documented here:
https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html

Its use in libstdc++ and effects on ABI compatibility between gcc and clang are pointed out here:
https://gcc.gnu.org/ml/gcc-patches/2015-04/msg00153.html

It would be great if clang could support the abi_tag attribute and remain abi compatible with gcc.

Revision history for this message
In , Renato Golin (rengolin) wrote :

If I understand the problem, even old GCCs will have such compatibility issues.

So, what GCC 5 is leading to, is a system that no other compiler can coexist without supporting abi_tags. This is bad not just for Clang, but for anyone experimenting with GCC 5 on a system based on 4.x, or reverting the compiler to work around 5.0 bugs.

If GCC 5 cannot work alongside compilers that don't support abi_tag, than maybe the abi_tag implementation needs to be reviewed, and rewritten so that they do.

Revision history for this message
In , Renato Golin (rengolin) wrote :

I've added a few people to the bug, as this looks like a watershed moment. I can't grasp the full extent of the problem right now, but I'm hoping that Clang folks are already aware of the changes in libstdc++ and have a plan. :)

I'd also like to make sure we don't move away from libstdc++ just because of that. We need to support all mainstream C++ libraries.

Revision history for this message
In , Richard-llvm (richard-llvm) wrote :

David has started looking into this. Apparently there are many implementation bugs on the GCC side (in addition to all the other problems with this attribute), and it's not yet clear how many of them we'll need to be compatible with.

Revision history for this message
In , Tim Northover (t-p-northover) wrote :

Isn't this precisely the kind of thing cxx-abi-dev exists to make saner? (Or would have, if it had been used).

Revision history for this message
In , Zeratul976 (zeratul976) wrote :

Is there any update on this? The current ABI incompatibility between the latest released versions of gcc and clang in their default configurations is very unfortunate.

Revision history for this message
In , Pablo Lezaeta (jristz) wrote :

Any news in this issue?
last real comment was from june and that near 3 months ago.

Changed in llvm:
importance: Unknown → Medium
status: Unknown → Confirmed
Revision history for this message
In , Lighttpd-2 (lighttpd-2) wrote :

Created attachment 14852
first attempt to add abi_tag support

As debian testing now moved to the new gcc abi and I still want to be able to use clang I tried patching it myself.

Certainly not perfect, and you'll notice some places where I am uncertain whether abi tags need to be emitted in the name mangling, and I wasn't able to get the NamedDecl pointer for the emitted identifier.

Patch was created against http://llvm.org/svn/llvm-project/cfe/trunk 246931.

Revision history for this message
In , Lighttpd-2 (lighttpd-2) wrote :

Created attachment 14868
second attempt to add abi_tag

I came up with a list of various tests and compared the results.. and worked hard to improve the patch :)

http://files.stbuehler.de/test-itanium-mangle.html shows the test results (produced with http://files.stbuehler.de/test-itanium-mangle.sh). Some of the mangling results from gcc could also be considered completely broken (unnecessary emitted tags, missing tags in guard variables).

I fear the performance of the patch might be less than optimal though.

Revision history for this message
In , Richard-llvm (richard-llvm) wrote :

Please post your patch to <email address hidden> for review; very few people will see it here.

Revision history for this message
In , Lighttpd-2 (lighttpd-2) wrote :

Created attachment 14872
abi-tag patch version 3

Revision history for this message
In , Lighttpd-2 (lighttpd-2) wrote :

Created attachment 14873
document abi-tag mangling

Revision history for this message
In , Lighttpd-2 (lighttpd-2) wrote :

Created attachment 14874
abi-tag patch version 4

Revision history for this message
In , Lighttpd-2 (lighttpd-2) wrote :

Tracking my patch now in http://reviews.llvm.org/D12834

summary: - clang++ no longer ABI-compatible with g++
+ clang++ no longer ABI-compatible with g++ in wily
Revision history for this message
Launchpad Janitor (janitor) wrote : Re: clang++ no longer ABI-compatible with g++ in wily

Status changed to 'Confirmed' because the bug affects multiple users.

Changed in llvm-toolchain-3.6 (Ubuntu):
status: New → Confirmed
Changed in llvm-toolchain-3.6 (Ubuntu):
importance: Undecided → High
summary: - clang++ no longer ABI-compatible with g++ in wily
+ clang++ no longer ABI-compatible with g++
Revision history for this message
In , Benzejaa (benzejaa) wrote :

*** Bug 24844 has been marked as a duplicate of this bug. ***

Revision history for this message
In , Rnk (rnk) wrote :

*** Bug 25656 has been marked as a duplicate of this bug. ***

Revision history for this message
In , İsmail Dönmez (ismaildonmez) wrote :

Any news on this? This is blocking any recent Linux distribution.

Revision history for this message
In , Steven Noonan (steven-valvesoftware) wrote :
Download full text (6.7 KiB)

I tried the "abi-tag patch version 4" attachment, and it appears to introduce some compiler crashes under 'make check-all'. Try out test/CodeGenCXX/static-local-in-local-class.cpp and you appear to get unbounded recursion:

$ gdb --args /home/steven/Development/llvm/build/Release/bin/clang -cc1 -internal-isystem /home/steven/Development/llvm/build/Release/bin/../lib/clang/3.7.0/include -nostdsysteminc -triple x86_64-linux -fblocks -emit-llvm -o - /home/steven/Development/llvm/tools/clang/test/CodeGenCXX/static-local-in-local-class.cpp -std=c++1y
[...]
(gdb) bt
[...]
#26382 0x00000000014814c3 in (anonymous namespace)::CXXNameMangler::mangleLocalName(clang::Decl const*, llvm::SmallVector<llvm::StringRef, 4u> const*, bool) ()
#26383 0x0000000001481ef7 in (anonymous namespace)::CXXNameMangler::mangleNameWithAbiTags(clang::NamedDecl const*, llvm::SmallVector<llvm::StringRef, 4u> const*, bool) ()
#26384 0x000000000147c030 in (anonymous namespace)::CXXNameMangler::mangleName(clang::NamedDecl const*, bool) ()
#26385 0x0000000001479308 in (anonymous namespace)::CXXNameMangler::mangleType(clang::QualType) ()
#26386 0x000000000147cb74 in (anonymous namespace)::CXXNameMangler::mangleFunctionEncoding(clang::FunctionDecl const*, bool) ()
#26387 0x00000000014814c3 in (anonymous namespace)::CXXNameMangler::mangleLocalName(clang::Decl const*, llvm::SmallVector<llvm::StringRef, 4u> const*, bool) ()
#26388 0x0000000001481ef7 in (anonymous namespace)::CXXNameMangler::mangleNameWithAbiTags(clang::NamedDecl const*, llvm::SmallVector<llvm::StringRef, 4u> const*, bool) ()
#26389 0x000000000147c030 in (anonymous namespace)::CXXNameMangler::mangleName(clang::NamedDecl const*, bool) ()
#26390 0x0000000001479308 in (anonymous namespace)::CXXNameMangler::mangleType(clang::QualType) ()
#26391 0x000000000147cb74 in (anonymous namespace)::CXXNameMangler::mangleFunctionEncoding(clang::FunctionDecl const*, bool) ()
#26392 0x00000000014814c3 in (anonymous namespace)::CXXNameMangler::mangleLocalName(clang::Decl const*, llvm::SmallVector<llvm::StringRef, 4u> const*, bool) ()
#26393 0x0000000001481ef7 in (anonymous namespace)::CXXNameMangler::mangleNameWithAbiTags(clang::NamedDecl const*, llvm::SmallVector<llvm::StringRef, 4u> const*, bool) ()
#26394 0x000000000147c030 in (anonymous namespace)::CXXNameMangler::mangleName(clang::NamedDecl const*, bool) ()
#26395 0x0000000001479308 in (anonymous namespace)::CXXNameMangler::mangleType(clang::QualType) ()
#26396 0x000000000147cb74 in (anonymous namespace)::CXXNameMangler::mangleFunctionEncoding(clang::FunctionDecl const*, bool) ()
#26397 0x0000000001481367 in (anonymous namespace)::ItaniumMangleContextImpl::mangleCXXName(clang::NamedDecl const*, llvm::raw_ostream&) ()
#26398 0x00000000009e9eae in clang::CodeGen::CodeGenModule::getMangledName(clang::GlobalDecl) ()
#26399 0x00000000009eb14a in clang::CodeGen::CodeGenModule::GetAddrOfFunction(clang::GlobalDecl, llvm::Type*, bool, bool) ()
#26400 0x0000000000abf7c0 in clang::CodeGen::CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(clang::CallExpr const*, clang::CXXMethodDecl const*, clang::CodeGen::ReturnValueSlot, bool, clang::NestedNameSpecifier*, bool, clang::Expr const*) ()
#2...

Read more...

Revision history for this message
In , T-hans (t-hans) wrote :

I'm not going to treat this as a release blocker as it's more of a feature request than a regression.

I'd still be open to merge a fix for this (though it seems unlikely), but I won't treat it as a blocker.

Revision history for this message
In , Daniel-f-starke (daniel-f-starke) wrote :

I admit that adding this new functionality sounds more like a feature request than a bug. But as I understood it, LLVM/Clang claims to support GCC and its libraries with a minimum version required.
No user would expect there to be an maximum version requirement.
I see two possible ways here for the next release:
1. State that LLVM/Clang only works up to GCC 4.9.
2. Add this attribute to be compatible to the most recent GCC release (5.3) again.
For future releases of LLVM/Clang this PR may as well be treated as a feature request IMHO.

Revision history for this message
In , Tim Jones (tim-mr-dog) wrote :

-1 for this being considered a feature request.

It's blocking anyone from updating their OSs in our company, which isn't going to happen, so we'll likely have to switch everything back to g++ only.

I'm sure we're not the only ones.

Revision history for this message
In , Renato Golin (rengolin) wrote :

(In reply to comment #19)
> But as I understood it, LLVM/Clang claims to support GCC
> and its libraries with a minimum version required.

I don't think we do. Our community has always sent a strong message that we'll be compatible with what makes sense AND allows us enough time to implement on our own.

> No user would expect there to be an maximum version requirement.

This doesn't make sense. We're not the same team, we can't possibly keep up with another community entirely AND develop our own software at instant speed.

If LLVM was a plugin to GCC, that could be true, but not *necessarily* so. Since it's not, this statement doesn't make sense.

> I see two possible ways here for the next release:
> 1. State that LLVM/Clang only works up to GCC 4.9.

LLVM "is known to work" with GCC up to "M.N". We never claimed full compatibility, nor I think we ever will.

> 2. Add this attribute to be compatible to the most recent GCC release (5.3)
> again.

If it was that simple, it would have been added already.

From comments in this very thread, it seems GCC's own implementation had several bugs, and implementing a bug for bug copy would be very silly indeed.

Revision history for this message
In , Giacomopoz (giacomopoz) wrote :

(In reply to comment #18)
> I'm not going to treat this as a release blocker as it's more of a feature
> request than a regression.

Since I upgraded to Ubuntu 15.10 I cannot build anymore with clang projects that include Boost (Ubuntu ships boost 1.58) because of this GCC 5 ABI changes.

The result is that I won't be able to use clang anymore till this issue gets fixed, making this a blocking issue.

Revision history for this message
In , James-molloy-u (james-molloy-u) wrote :

This is a feature, not a bug. Features do not block releases.

It's a feature because it's new behaviour to be added to Clang, not a regression in an old behaviour. That GCC designed and implemented this and that Linux distributions took that and ran with it is irritating, but does not make it a release blocker.

Implementing a new feature is not a one line fix, it's not something that can be merged to the release branch quickly - it needs design (especially in this case!) and soak testing.

It's nigh-on impossible for this to be done for the release, and therefore it makes no sense to have it block the release IMHO.

Revision history for this message
In , Hfinkel (hfinkel) wrote :

(In reply to comment #23)
> This is a feature, not a bug. Features do not block releases.
>
> It's a feature because it's new behaviour to be added to Clang, not a
> regression in an old behaviour. That GCC designed and implemented this and
> that Linux distributions took that and ran with it is irritating, but does
> not make it a release blocker.
>
> Implementing a new feature is not a one line fix, it's not something that
> can be merged to the release branch quickly - it needs design (especially in
> this case!) and soak testing.
>
> It's nigh-on impossible for this to be done for the release, and therefore
> it makes no sense to have it block the release IMHO.

James is right; we cannot block the release on the development of this feature.

Also, if you'd like to express your support for the development of this feature to the Clang/LLVM community, you'll need to do it on llvm-dev/cfe-dev, not here.

Revision history for this message
In , Renato Golin (rengolin) wrote :

Following up on the Linaro Toolchain list[1], I found out a few facts:

1. This feature was implemented in GCC and libstdc++ in 2012, after discussions on the cauldron with distro representatives.

2. The feature is poorly documented, and may have changed behaviour until recently. I have no evidence of changes, is anyone does, please update.

3. The problem only started because distros have chosen GCC 5 as their default compilers for the current releases, which defaults to C++11.

4. The fact that GCC developers didn't liaise with Clang developers is a shame, but understandable. The real issue here is the fact that distro representatives took an executive decision to change the object layout of core C++ classes in libstdc++ and to change the ABI without worrying about other compilers.

If they has asked Clang folks about the ABI change, (and they did, see this thread), they would have known that the ABI behaviour was poorly documented and a moving target (as they did, look at this bug), and should have taken the decision to mitigate the problems.

In this case, I'd expect distro folks to be the middle-men between GCC and Clang and to make sure that both compilers work well on their new releases. If you look at this bug and all of those that were marked as duplicate, you'll see that both Debian and RedHat based distros knew that Clang still didn't have the feature they needed and why.

True, we could have been more informative and made explicit every detail on why it was hard to know what to implement, but as middle-men, I expected distros to be more pro-active towards unification and less pro-active towards changing the ABI.

[1] https://lists.linaro.org/pipermail/linaro-toolchain/2016-January/005457.html

Revision history for this message
In , Octoploid (octoploid) wrote :

(In reply to comment #25)
> Following up on the Linaro Toolchain list[1], I found out a few facts:
>
> 1. This feature was implemented in GCC and libstdc++ in 2012, after
> discussions on the cauldron with distro representatives.

No. It was implemented in April this year, shortly before the gcc-5 release.
I've pointed out compatibility issue immediately:
https://gcc.gnu.org/ml/gcc-patches/2015-04/msg00153.html

> 2. The feature is poorly documented, and may have changed behaviour until
> recently. I have no evidence of changes, is anyone does, please update.

The were no behavioral changes at all after that patch went in.

> 3. The problem only started because distros have chosen GCC 5 as their
> default compilers for the current releases, which defaults to C++11.

No gcc-5 doesn't default to C++11 and the issue here has nothing to do with
C++98 vs. C++11.

Please try to get the facts strait, before posting long misleading replies.

Revision history for this message
In , Renato Golin (rengolin) wrote :

(In reply to comment #26)
> No. It was implemented in April this year, shortly before the gcc-5 release.
> I've pointed out compatibility issue immediately:
> https://gcc.gnu.org/ml/gcc-patches/2015-04/msg00153.html
(...)
> The were no behavioral changes at all after that patch went in.

In the Linaro thread, Jim points out to the abi_tag patch from 2012. Your mention is about "significant changes to attribute abi_tag". I can't see how I was wrong.

> No gcc-5 doesn't default to C++11 and the issue here has nothing to do with
> C++98 vs. C++11.
>
> Please try to get the facts strait, before posting long misleading replies.

This is what most of the documentation, email threads and conversations I had seem to point at. If you have a different opinion, than by all means, please share your knowledge.

Saying "it has nothing to do with" doesn't explain what it has to do with. I'm happy to be proven wrong here, as long as we get all the facts on the table. This bug doesn't seem to provide strong facts either.

Revision history for this message
In , Octoploid (octoploid) wrote :

(In reply to comment #27)
> (In reply to comment #26)
> > No. It was implemented in April this year, shortly before the gcc-5 release.
> > I've pointed out compatibility issue immediately:
> > https://gcc.gnu.org/ml/gcc-patches/2015-04/msg00153.html
> (...)
> > The were no behavioral changes at all after that patch went in.
>
> In the Linaro thread, Jim points out to the abi_tag patch from 2012. Your
> mention is about "significant changes to attribute abi_tag". I can't see how
> I was wrong.
>
>
> > No gcc-5 doesn't default to C++11 and the issue here has nothing to do with
> > C++98 vs. C++11.
> >
> > Please try to get the facts strait, before posting long misleading replies.
>
> This is what most of the documentation, email threads and conversations I
> had seem to point at. If you have a different opinion, than by all means,
> please share your knowledge.
>
> Saying "it has nothing to do with" doesn't explain what it has to do with.
> I'm happy to be proven wrong here, as long as we get all the facts on the
> table. This bug doesn't seem to provide strong facts either.

The incompatibility was introduced by gcc's "automatic tagging of functions and variables with tagged types where the tags are not already reflected in the mangled name".
Before that patch (https://gcc.gnu.org/ml/gcc-patches/2015-03/msg01029.html)
both gcc and clang could use the new ABI without any problem.

Now every library function with e.g a std::string return type causes linker errors.

To solve this issue, Clang only would have to implement the return type ABI tagging. All other ABI tags are irrelevant AFAIK.

Revision history for this message
In , Stephan-bergmann-secondary (stephan-bergmann-secondary) wrote :

(In reply to comment #27)
> (In reply to comment #26)
> > No gcc-5 doesn't default to C++11 and the issue here has nothing to do with
> > C++98 vs. C++11.
> >
> > Please try to get the facts strait, before posting long misleading replies.
>
> This is what most of the documentation, email threads and conversations I
> had seem to point at. If you have a different opinion, than by all means,
> please share your knowledge.

The relevant issue is whether libstdc++'s _GLIBCXX_USE_CXX11_ABI is enabled by default, see <https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html>.

Revision history for this message
In , Renato Golin (rengolin) wrote :

(In reply to comment #28)
> The incompatibility was introduced by gcc's "automatic tagging of functions
> and variables with tagged types where the tags are not already reflected in
> the mangled name".

So, the original patch would allow the tagging, but this patch made it automatic and compulsory?

I think one of the issues from the original patch is that we didn't need it until it was made compulsory, and that decision was taken and there was little discussion on the effects for Clang until this week, when all release tests started failing.

This was a major cock-up from all of us (me included). I'm not trying to blame people, just understand who should have what responsibility, so that we make sure this doesn't happen again.

> Now every library function with e.g a std::string return type causes linker
> errors.

On AArch64, we don't always get linker errors, but we do get segmentation fault on:

#include <iostream>
int main() { std::cout << "Hello World" << std::endl; }

On Debian unstable and I think the unreleased version of Ubuntu. RedHat, Suse and others may have the same trouble. I was told this was related to the same ABI tag problem, and reading that they've also changed the object layout (not just mangling), this makes a lot of sense. I haven't investigated more than that, I'm afraid.

> To solve this issue, Clang only would have to implement the return type ABI
> tagging. All other ABI tags are irrelevant AFAIK.

If I read correctly, one of the emails says this is only temporary, and wouldn't show in the final object, since C++ doesn't distinguish return types, that's most useful.

That seems to imply that we'd need IR representations, in addition to mangling, and that the back-ends will have to carry it all the way to assembly (but not object) output, which doesn't seem like a small change. If this needs to stay until emission, we can't use metadata, it needs to be a full-fledged IR construct.

Revision history for this message
In , Lighttpd-2 (lighttpd-2) wrote :

(In reply to comment #26)
> (In reply to comment #25)
> > 3. The problem only started because distros have chosen GCC 5 as their
> > default compilers for the current releases, which defaults to C++11.
>
> No gcc-5 doesn't default to C++11 and the issue here has nothing to do with
> C++98 vs. C++11.
>
> Please try to get the facts strait, before posting long misleading replies.

It is related to C++11; afaik one of the reasons to break the ABI was to
become C++11 standard compliant; also the new classes are tagged
"cxx11".

(In reply to comment #28)
> The incompatibility was introduced by gcc's "automatic tagging of functions
> and variables with tagged types where the tags are not already reflected in
> the mangled name".
>
> Now every library function with e.g a std::string return type causes linker
> errors.
>
> To solve this issue, Clang only would have to implement the return type ABI
> tagging. All other ABI tags are irrelevant AFAIK.

"Only" sounds like it would be easy and obvious. Sadly, this is not a
trivial problem.

The change was necessary to support dual-abi in one binary; you need to
be able to distinguish different ABIs in the return type.

(In reply to comment #29)
> The relevant issue is whether libstdc++'s _GLIBCXX_USE_CXX11_ABI is enabled
> by default, see
> <https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html>.

Yes. All distributions have the choice not to enable it by default in
the first place.

(In reply to comment #30)
> (In reply to comment #28)
> > To solve this issue, Clang only would have to implement the return type ABI
> > tagging. All other ABI tags are irrelevant AFAIK.
>
> If I read correctly, one of the emails says this is only temporary, and
> wouldn't show in the final object, since C++ doesn't distinguish return
> types, that's most useful.

No, it is not temporary.

Revision history for this message
In , Octoploid (octoploid) wrote :

(In reply to comment #31)
> (In reply to comment #26)
> > (In reply to comment #25)
> > > 3. The problem only started because distros have chosen GCC 5 as their
> > > default compilers for the current releases, which defaults to C++11.
> >
> > No gcc-5 doesn't default to C++11 and the issue here has nothing to do with
> > C++98 vs. C++11.
> >
> > Please try to get the facts strait, before posting long misleading replies.
>
> It is related to C++11; afaik one of the reasons to break the ABI was to
> become C++11 standard compliant; also the new classes are tagged
> "cxx11".

The new ABI is used for C++98 as well...

> (In reply to comment #28)
> > The incompatibility was introduced by gcc's "automatic tagging of functions
> > and variables with tagged types where the tags are not already reflected in
> > the mangled name".
> >
> > Now every library function with e.g a std::string return type causes linker
> > errors.
> >
> > To solve this issue, Clang only would have to implement the return type ABI
> > tagging. All other ABI tags are irrelevant AFAIK.
>
> "Only" sounds like it would be easy and obvious. Sadly, this is not a
> trivial problem.
>
> The change was necessary to support dual-abi in one binary; you need to
> be able to distinguish different ABIs in the return type.

No, the "automatic tagging of function return types" was unnecessary. The new
ABI was working perfectly fine with both compilers before that change.

Revision history for this message
In , Lighttpd-2 (lighttpd-2) wrote :

(In reply to comment #32)
> (In reply to comment #31)
> > (In reply to comment #28)
> > > The incompatibility was introduced by gcc's "automatic tagging of functions
> > > and variables with tagged types where the tags are not already reflected in
> > > the mangled name".
> > >
> > > Now every library function with e.g a std::string return type causes linker
> > > errors.
> > >
> > > To solve this issue, Clang only would have to implement the return type ABI
> > > tagging. All other ABI tags are irrelevant AFAIK.
> >
> > The change was necessary to support dual-abi in one binary; you need to
> > be able to distinguish different ABIs in the return type.
>
> No, the "automatic tagging of function return types" was unnecessary. The new
> ABI was working perfectly fine with both compilers before that change.

As long as you keep the ABIs completely separated it works, yes.

To get basic dual ABI support you could require manual tagging of all functions
which need tags (like, say, `std::string std::to_string(int)`) - but such
procedure would be way too much work and error prone.

Especially if you have third party libraries providing such functions (like boost),
which certainly would not start manual tagging, the linker could let you use
functions you really must not use.

I really see no option in this; if the return type is tagged, the tag must be
present in the signature somehow, or you can never mix different ABIs in the
same binary.

(I would have preferred to simply make tagged return (and variable!) types part
of the name, which would have been straightforward compared to the mess GCC
implemented: if the tag is already present in certain places, it is not added,
depending on the context it might not be added at all, ...)

Revision history for this message
In , Renato Golin (rengolin) wrote :

(In reply to comment #33)
> I really see no option in this; if the return type is tagged, the tag must be
> present in the signature somehow, or you can never mix different ABIs in the
> same binary.

This was probably already discussed, but if you mangle the return type, how can you mix this with previous mangling?

Say, you have:

int foo(int);

Old mangling would give you _Z3fooi. Then you add:

double foo(int);

With old mangling, you get an error. With new mangling (mixed with old mangling), you end up with three names. Say we mangle it before the function name:

_Z3fooi, _Z3ifooi, _Z3dfooi

Now, it's clear that _Z3fooi needs to be an alias to one of the other two, the question I can't answer is which one?

If you don't mix ABIs, then you only have two symbols and there is no problem.

And how different from this did GCC implement their mangling and why is it worse?

Revision history for this message
In , Octoploid (octoploid) wrote :

(In reply to comment #33)
> (In reply to comment #32)
> > (In reply to comment #31)
> > > (In reply to comment #28)
> > > > The incompatibility was introduced by gcc's "automatic tagging of functions
> > > > and variables with tagged types where the tags are not already reflected in
> > > > the mangled name".
> > > >
> > > > Now every library function with e.g a std::string return type causes linker
> > > > errors.
> > > >
> > > > To solve this issue, Clang only would have to implement the return type ABI
> > > > tagging. All other ABI tags are irrelevant AFAIK.
> > >
> > > The change was necessary to support dual-abi in one binary; you need to
> > > be able to distinguish different ABIs in the return type.
> >
> > No, the "automatic tagging of function return types" was unnecessary. The new
> > ABI was working perfectly fine with both compilers before that change.
>
> As long as you keep the ABIs completely separated it works, yes.
>
> To get basic dual ABI support you could require manual tagging of all
> functions
> which need tags (like, say, `std::string std::to_string(int)`) - but such
> procedure would be way too much work and error prone.
>
> Especially if you have third party libraries providing such functions (like
> boost),
> which certainly would not start manual tagging, the linker could let you use
> functions you really must not use.

I really think that implementing the full gcc abi-tag support is not
feasible for Clang.
So I would recommend to focus on compatibility with the single (new) ABI alone.

Distros that use the new ABI have recompiled all their C++ libraries,
so there isn't much need for the dual ABI anyway.

(After all the ABI tags are just a tool to help with the transition.)

> I really see no option in this; if the return type is tagged, the tag must be
> present in the signature somehow, or you can never mix different ABIs in the
> same binary.
>
> (I would have preferred to simply make tagged return (and variable!) types
> part
> of the name, which would have been straightforward compared to the mess GCC
> implemented: if the tag is already present in certain places, it is not
> added,
> depending on the context it might not be added at all, ...)

But this is all that's needed. Just change the mangling of the affected
return (and variable) types and you're set.

Revision history for this message
In , Renato Golin (rengolin) wrote :

(In reply to comment #35)
> I really think that implementing the full gcc abi-tag support is not
> feasible for Clang.
> So I would recommend to focus on compatibility with the single (new) ABI
> alone.

Wait, are you suggesting we move *all* users of *all* operating systems for *all* users of Clang and LLVM to change to the new GCC ABI because it's easier for Linux distributions that happen to have prematurely chosen to move?

This doesn't make sense...

Even if we segregate this for Linux only, which wouldn't be pretty, we're still forcing *all* other Linux distributions that may want to have a Clang package to move to the new GCC ABI just because other distros have.

Still doesn't make sense...

FWIW, Clang and GCC are running very well on my Arch Linux with GCC 5.3.0 and GLIBCXX_3.4.21.

Revision history for this message
In , Andrey Vihrov (andrey.vihrov) wrote :

> FWIW, Clang and GCC are running very well on my Arch Linux with GCC 5.3.0
> and GLIBCXX_3.4.21.

That's because Arch Linux is applying the patch from this bug report: https://projects.archlinux.org/svntogit/packages.git/tree/trunk/PKGBUILD?h=packages/llvm#n81

Revision history for this message
In , Lighttpd-2 (lighttpd-2) wrote :

(In reply to comment #34)
> (In reply to comment #33)
> > I really see no option in this; if the return type is tagged, the tag must be
> > present in the signature somehow, or you can never mix different ABIs in the
> > same binary.
>
> This was probably already discussed, but if you mangle the return type, how
> can you mix this with previous mangling?
> [...]

I said *tagged* return types, i.e. only those which need to break the ABI anyway.

> And how different from this did GCC implement their mangling and why is it
> worse?

(Also see my previous post)

- if the return (or variable) type is tagged, tag the function (or variable)
- if the tag is already present in other places in the name (say
  function arguments), it is not added
- depending on the context it might not be added at all (nested functions,
  special symbols). very complex rules.
- for more details see my patch (has some docs), if you want to see some
  examples: http://files.stbuehler.de/test-itanium-mangle.html

(In reply to comment #35)
> I really think that implementing the full gcc abi-tag support is not
> feasible for Clang.
> So I would recommend to focus on compatibility with the single (new) ABI
> alone.
>
> Distros that use the new ABI have recompiled all their C++ libraries,
> so there isn't much need for the dual ABI anyway.

The new ABI requires the full gcc abi-tag support to be compatible with
gcc. If you compile everything with clang and disable dual ABI support
you can get away with less, but what is the point? Just use the clang
libc++ instead, which requires no changes.

> (After all the ABI tags are just a tool to help with the transition.)

And a tool to help with future transitions (and in any other c++
libraries too). A nice tool, I might add, just not very well designed.

> But this is all that's needed. Just change the mangling of the affected
> return (and variable) types and you're set.

Please take a look at the examples (above), which need to work to make
clang compatible with gcc.
There is no shortcut.

Revision history for this message
In , Renato Golin (rengolin) wrote :

(In reply to comment #38)
> I said *tagged* return types, i.e. only those which need to break the ABI
> anyway.

Good point. Thanks for the distinction.

> The new ABI requires the full gcc abi-tag support to be compatible with
> gcc. If you compile everything with clang and disable dual ABI support
> you can get away with less, but what is the point? Just use the clang
> libc++ instead, which requires no changes.

I'm afraid it's not that simple. GNU libraries are the default on all Linux (and other) distributions, and mixing libc++ with libstdc++ is bound to create at least as many problems as it solves.

Moreover, FreeBSD had to take many short-cuts to get rid of libstdc++ on the base system, including making symlinks named after GNU libraries and tools to LLVM libraries and tools, and the mapping is NOT 1-to-1. See the libc++ + compiler-rt + libunwind vs. libgcc + libgcc_s + libgcc_eh connundrum.

We need libc++ to work on the supported architectures with and without GNU libraries. Getting rid of the GNU counterparts is out of the question for any practical purpose.

Revision history for this message
In , Lighttpd-2 (lighttpd-2) wrote :

(In reply to comment #39)
> (In reply to comment #38)
> > The new ABI requires the full gcc abi-tag support to be compatible with
> > gcc. If you compile everything with clang and disable dual ABI support
> > you can get away with less, but what is the point? Just use the clang
> > libc++ instead, which requires no changes.
>
> [...]
>
> We need libc++ to work on the supported architectures with and without GNU
> libraries. Getting rid of the GNU counterparts is out of the question for
> any practical purpose.

So you're saying there is a use case to compile everything with clang and libstdc++? If that is actually something you need, and you don't need to be compatible to any name mangling, you just need the part of the patch in D12834 accepting abi tags and you should be fine (no dual ABI support ofc); no modifications to the name mangling (lib/AST/ItaniumMangle.cpp) are necessary for that.

Revision history for this message
In , Renato Golin (rengolin) wrote :

(In reply to comment #40)
> So you're saying there is a use case to compile everything with clang and
> libstdc++?

Unfortunately, no.

A reasonably common scenario will also be to use libc++ on user code while having libstdc++ used on the core libraries (say, boost), and them two interface appropriately, statically and dynamically linked. Same with RT and libgcc.

Linux systems use GNU for everything as default. All packages are compiled with GCC, Glibc, binutils, libstdc++, etc. Users installing packages will end up getting GCC-mangled libraries. But I still want to use Clang there, for special cases, performance reasons, diagnostics, etc.

So, while in FreeBSD and Apple environments they can get rid of the GNU side, Linux is a lot more fragmented. For better or worse, we still need to be compatible with GCC 5 abi at all levels. Clang, libc++, compiler-rt need to all be aware (not necessarily change much) of this new ABI and what effects it'll have on them.

Some Linux distros are trying to change the compiler, but that has proven a lot harder than it should, due to decades abusing of the same bugs in one compiler alone. The new ABI change is just yet another added to the pile.

Revision history for this message
In , Bero-b (bero-b) wrote :

OpenMandriva has successfully changed the compiler to clang (3.7.1 for now, will update to 3.8 as it is released), but decided to stick with libstdc++ to preserve binary compatibility with other Linux distributions -- users want to run non-open source stuff like steam, and that stuff doesn't get built for OSes that don't have a giant user base.

OpenMandriva could switch system libraries etc. to libc++, but even then problems would likely arise (e.g. binary-only application links to Qt and expects Qt to be linked to libstdc++ -- the only "fix" would be providing 2 different versions of all C++ libraries and even then things would likely break, with e.g. libstdc++-Qt not being able to load style plugins built for libc++-Qt and vice versa, so custom installed widget themes wouldn't work for binary-only applications).

So yes, there indeed is a use case for building the entire OS with clang but not libc++ until we get to a point where relevant closed source stuff switches to libc++ (or better yet, gets open sourced so people can link it to any STL they like).

Revision history for this message
In , Renato Golin (rengolin) wrote :

(In reply to comment #42)
> OpenMandriva has successfully changed the compiler to clang (3.7.1 for now,
> will update to 3.8 as it is released), but decided to stick with libstdc++
> to preserve binary compatibility with other Linux distributions -- users
> want to run non-open source stuff like steam, and that stuff doesn't get
> built for OSes that don't have a giant user base.

If you ship GCC at all, and if that happens to be 5.x, and you happen to choose to enable the CXX11 ABI by default, you'll run into the exact same problem. Doesn't matter who's on top.

> OpenMandriva could switch system libraries etc. to libc++, but even then
> problems would likely arise (e.g. binary-only application links to Qt and
> expects Qt to be linked to libstdc++ -- the only "fix" would be providing 2
> different versions of all C++ libraries and even then things would likely
> break, with e.g. libstdc++-Qt not being able to load style plugins built for
> libc++-Qt and vice versa, so custom installed widget themes wouldn't work
> for binary-only applications).

That, in addition to multilib/multiarch will be a major pain for all distros. This really isn't a solution.

> So yes, there indeed is a use case for building the entire OS with clang but
> not libc++ until we get to a point where relevant closed source stuff
> switches to libc++ (or better yet, gets open sourced so people can link it
> to any STL they like).

Even if the day Clang and libc++ become the top dog on most Linux distributions ever comes, we'll still have to cope with legacy GCC and libstdc++ for a good number of decades from then on.

Coexisting is the only solution for this century.

Revision history for this message
In , Hfinkel (hfinkel) wrote :

(In reply to comment #43)
> (In reply to comment #42)
> > OpenMandriva has successfully changed the compiler to clang (3.7.1 for now,
> > will update to 3.8 as it is released), but decided to stick with libstdc++
> > to preserve binary compatibility with other Linux distributions -- users
> > want to run non-open source stuff like steam, and that stuff doesn't get
> > built for OSes that don't have a giant user base.
>
> If you ship GCC at all, and if that happens to be 5.x, and you happen to
> choose to enable the CXX11 ABI by default, you'll run into the exact same
> problem. Doesn't matter who's on top.
>
>
> > OpenMandriva could switch system libraries etc. to libc++, but even then
> > problems would likely arise (e.g. binary-only application links to Qt and
> > expects Qt to be linked to libstdc++ -- the only "fix" would be providing 2
> > different versions of all C++ libraries and even then things would likely
> > break, with e.g. libstdc++-Qt not being able to load style plugins built for
> > libc++-Qt and vice versa, so custom installed widget themes wouldn't work
> > for binary-only applications).
>
> That, in addition to multilib/multiarch will be a major pain for all
> distros. This really isn't a solution.
>
>
> > So yes, there indeed is a use case for building the entire OS with clang but
> > not libc++ until we get to a point where relevant closed source stuff
> > switches to libc++ (or better yet, gets open sourced so people can link it
> > to any STL they like).
>
> Even if the day Clang and libc++ become the top dog on most Linux
> distributions ever comes, we'll still have to cope with legacy GCC and
> libstdc++ for a good number of decades from then on.
>
> Coexisting is the only solution for this century.

As a practical manner, we'll never be able to compile all of our existing code against libc++, unless libc++ decides to implement the not-insignificant set of libstdc++ extensions (e.g. everything under __gnu_parallel::, _gnu_cxx::stdio_filebuf) [https://gcc.gnu.org/onlinedocs/libstdc++/manual/extensions.html].

Revision history for this message
In , Andreybokhanko (andreybokhanko) wrote :

Stefan [Bühler], do you plan to finish work on the patch? Do you need help with code review? (I just added Aaron Ballman, who is code owner for attributes).

Yours,
Andrey
======
Software Engineer
Intel Compiler Team
Intel

Revision history for this message
In , Yaron-keren (yaron-keren) wrote :

Happens with clang-compiled objects attempting to use gcc-5 precompiled packages such as boost, on Ubuntu 15.10, leading to

undefined reference to `_ZN5boost9unit_test9ut_detail24normalize_test_case_nameENS0_13basic_cstringIKcEE'

where normalize_test_case_name returns std:string.

  std::string normalize_test_case_name( const_string name )

Revision history for this message
In , Lighttpd-2 (lighttpd-2) wrote :

Hi Andrey,

(In reply to comment #45)
> Stefan [Bühler], do you plan to finish work on the patch? Do you need help
> with code review? (I just added Aaron Ballman, who is code owner for
> attributes).

I think the attributes part of the patch is quite good compared with
the mangling part... perhaps it should be split into a separate patch.

Regarding the mangling I'm not too happy with my patch. I don't understand
what most of the mangling code did before to actually know where
to insert the tagging code. This is C++ on a level I don't usually touch;
I'm not familiar with all the terms (<unscoped-template-name>,
<source-name>, ...) and just keep guessing what they do.

Also I don't like using recursion to determine the inherited abi tags;
I think using temporary strings instead of directly writing to the stream
would solve this.

All in all I hoped to get some feedbacks how things are done or should
look like; I don't mind if someone else wants to take over and rewrite
the mangling :)

I planned looking at the original gcc code some day, but didn't get around
doing that either; maybe others can help with the documentation too (how
the abi tag mangling actually should look like). More "examples" certainly
wouldn't hurt either.

Revision history for this message
In , Yaron-keren (yaron-keren) wrote :

*** Bug 26401 has been marked as a duplicate of this bug. ***

Revision history for this message
In , David-abdurachmanov (david-abdurachmanov) wrote :

"C++ PATCHes for abi_tag bugs" from Jason landed on gcc-patches, might be relevant.

https://gcc.gnu.org/ml/gcc-patches/2016-01/msg02374.html

Revision history for this message
In , Renato Golin (rengolin) wrote :

Hum, both sound like serious bugs. I'm surprised all distros bought in the new ABI so eagerly.

Revision history for this message
In , Andreybokhanko (andreybokhanko) wrote :

Hi Stefan,

(In reply to comment #47)
> I think the attributes part of the patch is quite good compared with
> the mangling part... perhaps it should be split into a separate patch.
>
> Regarding the mangling I'm not too happy with my patch. I don't understand
> what most of the mangling code did before to actually know where
> to insert the tagging code. This is C++ on a level I don't usually touch;
> I'm not familiar with all the terms (<unscoped-template-name>,
> <source-name>, ...) and just keep guessing what they do.
>
> Also I don't like using recursion to determine the inherited abi tags;
> I think using temporary strings instead of directly writing to the stream
> would solve this.
>
> All in all I hoped to get some feedbacks how things are done or should
> look like; I don't mind if someone else wants to take over and rewrite
> the mangling :)

Sure -- I will ask someone from Intel compiler team to handle mangling part. We are co-located with Intel GCC team, so it's easy for us to ask on intricacies of GCC implementation. :-)

I don't see attribute part of the patch to be reviewed, though -- we can help with this as well. (Though the real authority to approve it belongs to Aaron, so it's better to wait for his review (and ping if there is no reply from his after a week)).

Yours,
Andrey

Revision history for this message
In , Dmitry-polukhin (dmitry-polukhin) wrote :

I'll take a look to the change and will investigate why tests fail on the proposed patch. Failing tests are not abi_tag specific so it should be no changes on them.

Best regards,
Dmitry
======
Software Engineer
Intel Compiler Team

Revision history for this message
In , Dmitry-polukhin (dmitry-polukhin) wrote :

Hi Stefan,

This is an important issue in Clang and I would like to move on with patch http://reviews.llvm.org/D12834 (also see my last comment there). If you don't mind, I'll get your patch split it into smaller patches and start resolving reviewers comments. Please let me know if you have cycles and would like to keep working on this patch yourself.

Best regards,
Dmitry
======
Software Engineer
Intel Compiler Teaml

Revision history for this message
In , Lighttpd-2 (lighttpd-2) wrote :

Hi Dmitry,

(In reply to comment #53)
> Hi Stefan,
>
> This is an important issue in Clang and I would like to move on with patch
> http://reviews.llvm.org/D12834 (also see my last comment there). If you
> don't mind, I'll get your patch split it into smaller patches and start
> resolving reviewers comments. Please let me know if you have cycles and
> would like to keep working on this patch yourself.

I agree it is important, and it saddens me not having more time for this.

I'm perfectly fine with you (and others) taking this over - thanks!

regards,
Stefan

Revision history for this message
In , David-abdurachmanov (david-abdurachmanov) wrote :

More bug-fixing for abi_tag on GCC side: https://gcc.gnu.org/ml/gcc-patches/2016-02/msg01293.html

Revision history for this message
In , Jverg (jverg) wrote :

(In reply to comment #39)
> Moreover, FreeBSD had to take many short-cuts to get rid of libstdc++ on the
> base system, including making symlinks named after GNU libraries and tools
> to LLVM libraries and tools, and the mapping is NOT 1-to-1. See the libc++ +
> compiler-rt + libunwind vs. libgcc + libgcc_s + libgcc_eh connundrum.

There are not that many short-cuts and the primary issue was the desire to allow libstdc++ and libc++ to coexist. If it was just about using libc++, the issue is much simpler.

Revision history for this message
In , Giacomopoz (giacomopoz) wrote :

did this issue hit another roadblock ?

Revision history for this message
In , Richard-llvm (richard-llvm) wrote :

Jason Merrill said he'd write up some brief documentation for the attribute. We'd like to work from that rather than trying to guess GCC's intent from examples.

Revision history for this message
In , Renato Golin (rengolin) wrote :

(In reply to comment #58)
> Jason Merrill said he'd write up some brief documentation for the attribute.
> We'd like to work from that rather than trying to guess GCC's intent from
> examples.

That's most helpful, thanks!

What about Dmitry's patch?

Revision history for this message
In , Dmitry-polukhin (dmitry-polukhin) wrote :

My patch for Sema part with of the attribute under review is here http://reviews.llvm.org/D17567

Revision history for this message
In , Dmitry-polukhin (dmitry-polukhin) wrote :

Status update:
- Sema part was committed http://reviews.llvm.org/D17567
- Mangler part was sent for review http://reviews.llvm.org/D18035

Best regards,
Dmitry
======
Software Engineer
Intel Compiler Team

Revision history for this message
In , Syniurge (syniurge) wrote :

This is becoming more and more of an important issue as distributions switch to building all their packages against GCC + libstdc++ 5 and plaster their libraries with [abi:cxx11] tags.

Since Ubuntu 15.10 Clang is basically unusable, every library making use of std::string has to be recompiled with -D_GLIBCXX_USE_CXX11_ABI=0, or with GCC/libstdc++ 4.9 in order to prevent linking errors.

Surprising that Dmitry's patch isn't receiving more attention.

Revision history for this message
In , Tim Jones (tim-mr-dog) wrote :

Hi, any chance of an ETA guestimate / status update?

Cheers,
Tim

Revision history for this message
In , Giacomopoz (giacomopoz) wrote :

(In reply to comment #63)
> Hi, any chance of an ETA guestimate / status update?
>
> Cheers,
> Tim

The status is that there is a patch ready since 23rd March http://reviews.llvm.org/D18035#381281 and the author (and all users) is waiting for feedback from developers and/or for the patch to be merged.

Revision history for this message
In , Mclow-lists (mclow-lists) wrote :

Sounds like a chance for people to install the patch locally and start using it, and then provide feedback on any problems that crop up.

Revision history for this message
In , Tim Jones (tim-mr-dog) wrote :

I've been using the patched version for the past couple of days, no issues so far.

But, I'm not one of the developers and don't know this code base and just because it *seems* to work doesn't mean it's correct yet. I'm just going to continue with what works well enough for me at the moment, with patience.

Revision history for this message
In , Renato Golin (rengolin) wrote :

FWIW, Arch has applied both patches (as Andrey has stated in comment 37) and it is working fine.

Revision history for this message
In , Dmitry-polukhin (dmitry-polukhin) wrote :

abi_tag implementation was committed to Clang http://reviews.llvm.org/D18035 Please start testing on your apps and report issues.

Revision history for this message
Christian Convey (christian-convey) wrote :

Hi guys,

Anyone know when we might see this fix make it into Ubuntu 16.04's official repos? I'm doing some app development that's hindered by this bug.

(If there's a better forum for this question, I'd be grateful for a redirect.)

Thanks very much,
Christian

Revision history for this message
the paul (paul-thepaul) wrote :

I've made a first pass at adapting patches D17567 and D18035 to work with your clang-3.8 packages. It builds and passes its own build-time tests, and successfully builds and links a medium-size project we have at work on 16.04, but I can't vouch for it much more than that.

I can see that this particular bug is attached to llvm-toolchain-3.6 and not 3.8, but there doesn't seem to be a corresponding bug on 3.8, so hopefully this isn't a bad place to mention it. Haven't tried patching clang-3.6 yet.

Revision history for this message
Ubuntu Foundations Team Bug Bot (crichton) wrote :

The attachment "clang-3.8-abi_tag-ubuntu-changes.diff" seems to be a debdiff. The ubuntu-sponsors team has been subscribed to the bug report so that they can review and hopefully sponsor the debdiff. If the attachment isn't a patch, please remove the "patch" flag from the attachment, remove the "patch" tag, and if you are member of the ~ubuntu-sponsors, unsubscribe the team.

[This is an automated message performed by a Launchpad user owned by ~brian-murray, for any issue please contact him.]

tags: added: patch
Mathew Hodson (mhodson)
Changed in llvm-toolchain-3.8 (Ubuntu):
importance: Undecided → High
Revision history for this message
Launchpad Janitor (janitor) wrote :

Status changed to 'Confirmed' because the bug affects multiple users.

Changed in llvm-toolchain-3.8 (Ubuntu):
status: New → Confirmed
Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package llvm-toolchain-3.8 - 1:3.8.1-7ubuntu2

---------------
llvm-toolchain-3.8 (1:3.8.1-7ubuntu2) yakkety; urgency=medium

  * Ignore test results on i386, as done on any other architecture.
  * Don't use gold on powerpc, not supporting secure-plt.

 -- Matthias Klose <email address hidden> Sun, 07 Aug 2016 12:45:46 +0200

Changed in llvm-toolchain-3.8 (Ubuntu):
status: Confirmed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.