Using C++14 code in LLVM

On the one hand, I like this proposal. But that is because every system I care about has or can easily acquire a GCC 4.9 baseline compiler. So when I imagine that you want to move to GCC 5 instead of GCC 4.9, I get extremely nervous.

I do think we should be prepared to move the baseline forward though. We picked GCC 4.7 a very long time ago.

I understand that there are systems without GCC 4.9 now, but there were systems without GCC 4.7 when we raised the minimum requirements to that version. For me, the question is more how easily users on those systems could update. If it is reasonably straight forward, I would be fine moving the baseline up. If there are reasons why installing a newer GCC would be very hard, that would be more concerning to me.

I do think moving past GCC 4.9 presents a unique challenge due to the ABI break which took place between GCC 4.9 and GCC 5. For example, for me, “just installing” a newer version of GCC works great right up until GCC 5 where it starts to break for ABI reasons.

However, once all of that is settled and we know what the baseline compilers are, I’m 100% in favor of adopting essentially all of the features they support and that work reliably. If we can get most of C++14, great, let’s do it. To Pete’s point, I do think C++17 has more exciting features in the pipeline, but I think we should take a greedy approach here, and adopt as many features as are beneficial as early as we can get away with given the host compilers we support.

Which means the primary question is about the host compilers IMO.

-Chandler

I understand that there are systems without GCC 4.9 now, but there were
systems without GCC 4.7 when we raised the minimum requirements to that
version.

Moving to 4.7 was a long time ago, when the usage / development
patterns were quite different. At that time, LLVM was more
experimental to most people than it is now, and products based on LLVM
were mostly done by big companies. Nowadays, Clang is in Linux and BSD
distributions, as well as part of a lot more projects (open source or
not).

I agree we should be prepared to move. I just want to make sure the
default is one that doesn't push users/developers away, or, in our
case, break most of our buildbots.

For me, the question is more how easily users on those systems
could update. If it is reasonably straight forward, I would be fine moving
the baseline up. If there are reasons why installing a newer GCC would be
very hard, that would be more concerning to me.

Yup.

Also, for the vast majority of systems, Clang *cannot* be used alone.
So claiming that Clang is such and such version, "therefore we don't
care about GCC" is a fallacy we shouldn't get ourselves into.

So we're talking here about successfully compiling all LLVM
sub-projects with a "simple enough" toolchain for the targets that we
normally do. This involves native *and* cross compilation on all major
targets, with cross *at least* from x86_64.

The Clang driver support for cross compiling is a mess, compiler-rt
can't yet cross-compile properly and I'm not sure libc++ et al has
even been tested properly in that area. The problem starts when
different OSs have different sysroot and multilib/multiarch styles,
which renders binary tarballs (like Linaro releases) practically
useless out of their tested environments as a sysroot for Clang.

Not to mention that in pre-built binary land, 5.x is already the old
version, with 6.x being current stable and 7.x merge window closing a
few weeks from now. Trunk, releases and distros are usually more than
a year apart from each other.

I do think moving past GCC 4.9 presents a unique challenge due to the ABI
break which took place between GCC 4.9 and GCC 5. For example, for me, "just
installing" a newer version of GCC works great right up until GCC 5 where it
starts to break for ABI reasons.

We are moving all our buildbots to Ubuntu Xenial 16.04 LTS, which
means GCC 5.4.0, binutils 2.26 and glibc 2.23. They also use 48-bit
VMA which will likely be the new standard for AArch64 kernels from now
on.

But we need to fix a lot of bugs before moving, and any change window
right now will put us in a tight spot. For example, one of the bugs we
found had to be fixed in binutils, which just got merged to master
last week. That means we can't rely on Ubuntu's toolchain anymore, and
will likely force us to use Linaro's toolchain from now on, which is
yet another big move (and more Clang driver changes, which won't go
into Clang 3.9).

So, while I welcome change, and we're working towards it, we may need
more time to move above 4.8. If people are happy to move to 4.8 now,
then 5.x later, I'm game. If people want to wait and move to 5.x when
everyone is ready, I'm also game. But moving to 4.9 now will break *a
lot* of stuff for us, and likely not give us much time to fix them
properly.

cheers,
--renato

We use CentOS 5 for the same reason. The compiler is gcc 4.8.2, coming
from the Developer Toolset 2.

Bumping C++ requirements to C++14 may force us to switch our build
machine to CentOS 6, and abandon support for users of older versions of
RHEL and CentOS.

Regards

Antoine.

I wasn't able to find that information on the distrowatch page you linked, but I will assume that it is talking about the available ports, e.g. packages external to the FreeBSD base system. In the FreeBSD ports collection, we have clang 3.3 through 3.9 available, and a 4.0 trunk snapshot as of 2016-08-24.

On the other hand, the base system is a little different, in the sense that we use clang to bootstrap the whole system, and use the FreeBSD build system instead of llvm/clang's native build system. Also, we don't have all the additional tools like llc, opt, and so on, by default.

FreeBSD 10.3 currently has clang 3.4.1, with libc++ from around that time, plus a bunch of patches. I think it will be able to do most of C++14, except maybe some corner cases.

FreeBSD 11.0 (which is going to ship any day now) has clang 3.8.0, with libc++ 3.8.0.

I'm currently working on importing clang 3.9.0 into FreeBSD 12 (the development version) together with libc++ 3.9.0, compiler-rt 3.9.0 and so on. These will hopefully land before the end of this month. After about a month, I will merge it all into FreeBSD 11, so it will end up in FreeBSD 11.1.

-Dimitry

I see a lot of people talking about c++14 and *maybe* clang-N.N.N will
support it, but is there any tests which can be used to
actually/tangibly verify this?

Is there tests for the features being proposed to take advantage of?
It would be prudent to ensure there's tests available to verify on
buildbots before any decision to switch is made.

Break this into steps and it becomes a plan instead of just tossing
opinions around.

From what I read so far - I'd speculate that only old Linux and NetBSD

will have an issue with the bump. Worst case those platforms need an
extra step to bootstrap, but should that hold everything back? Either
newer clang is good enough to replace the older version or it's not.
However, testing as a pre-cursor and getting facts is important.

#1 Tests for the features
#2 Bug tracker to identify any regressions blocking updating
#3 Buildbots to verify

It’s documented here

http://clang.llvm.org/cxx_status.html

We have a similar setup and would have similar problems, but at a slightly later gcc version. We're currently using gcc-4.9.2. We could probably work around this, but I'd really rather not do so unless there's a good reason.

(I know the current discussion is around moving to 4.9 as a baseline. We'd be fine with this, I'm mostly chiming in since 5.2 was mentioned earlier in the thread and that would be a problem.)

Philip

I believe that's correct. We have a few cases wrt compilers in the
base system, in supported FreeBSD branches:

1) GCC 4.2.1 is /usr/bin/cc, Clang 3.4.1 or later is available as /usr/bin/clang
2) GCC 4.2.1 is /usr/bin/cc, Clang is not available
3) Clang 3.4.1 or later is /usr/bin/cc

As long as the minimum Clang version required to build LLVM doesn't
move past 3.4.1 we have a way to build with the system tool chain for
1 and 3. As you point out Case 2 already has a tricky bootstrapping
path, and this proposal doesn't really make it any harder.

Oh it's "documented" - great.. well that doesn't give any weight to if
it works and how robust. Is there tests for these features or not? I
know if I wanted to add or change *anything* a test would be required.

By the same logic, why wouldn’t there be tests for these features? How would one go about adding core C++ language constructs to clang without adding tests for them?

From: "C Bergström via llvm-dev" <llvm-dev@lists.llvm.org>
To: "Zachary Turner" <zturner@google.com>
Cc: "LLVM Developers Mailing List" <llvm-dev@lists.llvm.org>
Sent: Monday, October 3, 2016 11:11:03 AM
Subject: Re: [llvm-dev] Using C++14 code in LLVM

Oh it's "documented" - great.. well that doesn't give any weight to
if
it works and how robust. Is there tests for these features or not? I
know if I wanted to add or change *anything* a test would be
required.

What kind of tests do you mean? Of course all of the individual features have regression tests, and as documented, we believe the feature set to be complete. We don't have any kind of omnibus C++14 test or a separate test directory just for C++14 conformance.

-Hal

What concerns me the most is not “is this feature present?”, but rather “is it good enough to build trunk?”.
The fact that clang-3.4 shipped with support for a specific feature does not mean the compiler couldn’t crash or miscompile under some very specific conditions when using this feature.

So I don’t see much interested in a test that shows the feature “works” with (rather “is present in”) clang-3.4, I’m interested in continuously testing that clang-3.4 can build trunk, always.

Even today, we claim to support building with clang-3.1 but are we testing it? Is there a bot building trunk with 3.1?

Mehdi Amini via llvm-dev <llvm-dev@lists.llvm.org> writes:

What concerns me the most is not “is this feature present?”, but
rather “is it good enough to build trunk?”.
The fact that clang-3.4 shipped with support for a specific feature
does not mean the compiler couldn’t crash or miscompile under some
very specific conditions when using this feature.

So I don’t see much interested in a test that shows the feature
“works” with (rather “is present in”) clang-3.4, I’m interested in
continuously testing that clang-3.4 can build trunk, always.

Even today, we claim to support building with clang-3.1 but are we
testing it? Is there a bot building trunk with 3.1?

The claim that we support building with clang 3.1 is a blatant lie. For
example, that version of clang won't even allow the override keyword
without also specifying virtual (which we explicitly choose not to do in
LLVM style).

Realistically, our actual minimum version of clang today is 3.3 or 3.4,
and no, we aren't currently testing this at all.

Zachary Turner via llvm-dev <llvm-dev@lists.llvm.org> writes:

A thread was started over the summer to discuss the timeline for bumping
LLVM up to Visual Studio 2015 to enable the use of various new language
features. Currently the ETA for this is sometime in mid-October, so within
2-3 weeks.

With this happening imminently, I thought it would be worth tossing this
out there and seeing what people think.

With VS on 2015, the major lagging compiler is going to be GCC. Our
minimum GCC requirement is 4.7, which is quite old (almost 4 years for
anyone keeping count). What are the challenges with pushing this forward?

With VS2015, the biggest remaining missing C++14 features are variable
templates, sized allocation, and extended constexpr. But it gains generic
lambdas, init-captures, decltype(auto) return, and auto return without
requiring the trailing -> decltype syntax.

I'm not convinced that the cost is worth the gain for these features.
Most of these are relatively straight forward (with more boilerplate) to
work around in C++11, and I'd rather we not get into a situation where
to bootstrap clang you need to build a C++11 compatible version so that
you can build a C++14 compatible one so that you can build a C++17
compatible one, etc. Consider that -std=c++17 isn't yet a valid flag on
trunk clang, so if we bump to C++14 now then we're practically
guaranteed that when we want to update to 17 we'll run into multi-stage
bootstrapping problems.

While GCC doesn't claim to "fully" support C++14 until 5.2 (which is only
about 1 year old), you can get all of the above features with GCC 4.9

So if we're willing to allow "partial" C++14 support in LLVM (i.e a
whitelisted set of features), we may be able to get many of the most useful
features by going to GCC 4.9, which is still a good 2.5 years old.

I'd be much happier getting to requiring "full" C++11 support than going
to partial C++14 support - having partial support for C++11 has meant
that many issues are only caught by bots, and I much prefer the compiler
to complain when I use some feature we're not allowed to use yet.

…I think we should take a greedy approach here, and adopt as many features as are beneficial as early as we can get away with given the host compilers we support.

+1!

If we can move to C++14 I’d want it for the generalized lambda captures alone.

Cheers,
Lang.

I didn’t quite get this last part, can you elaborate please?

Thanks,

Mehdi Amini <mehdi.amini@apple.com> writes:

Zachary Turner via llvm-dev <llvm-dev@lists.llvm.org
<mailto:llvm-dev@lists.llvm.org>> writes:

A thread was started over the summer to discuss the timeline for bumping
LLVM up to Visual Studio 2015 to enable the use of various new language
features. Currently the ETA for this is sometime in mid-October, so within
2-3 weeks.

With this happening imminently, I thought it would be worth tossing this
out there and seeing what people think.

With VS on 2015, the major lagging compiler is going to be GCC. Our
minimum GCC requirement is 4.7, which is quite old (almost 4 years for
anyone keeping count). What are the challenges with pushing this forward?

With VS2015, the biggest remaining missing C++14 features are variable
templates, sized allocation, and extended constexpr. But it gains generic
lambdas, init-captures, decltype(auto) return, and auto return without
requiring the trailing -> decltype syntax.

I'm not convinced that the cost is worth the gain for these features.
Most of these are relatively straight forward (with more boilerplate) to
work around in C++11, and I'd rather we not get into a situation where
to bootstrap clang you need to build a C++11 compatible version so that
you can build a C++14 compatible one so that you can build a C++17
compatible one, etc. Consider that -std=c++17 isn't yet a valid flag on
trunk clang, so if we bump to C++14 now then we're practically
guaranteed that when we want to update to 17 we'll run into multi-stage
bootstrapping problems.

I didn’t quite get this last part, can you elaborate please?

Consider if we adopt C++14 features today. Then to build clang-4.0 you
need a C++14 compatible compiler (Maybe clang-3.4, probably more like
clang-3.5 or clang-3.6 based on our current clang-3.1 claim). So to
bootstrap you build clang-3.5 (I think that's before we required C++11)
and then build clang-4.0.

That's not too bad, but then lets say we switch to requiring C++17 in
clang-4.4 - now, you need to build clang-3.5 first so that you can build
clang-4.0, *then* you use clang-4.0 to build clang-4.4. What I'm nervous
about here is increasing the number of steps to get to a working
compiler - I don't think we want to require C++14 before we can even
build C++17.

OK, got it.

That is my concern as well. It seems quite a bit like "Oh new, shinny,
want!" Keep in mind that LLVM is now integral part of the Mesa
toolchain. The requirements here do not only affect developers, but
there are a lot of users impacted directly by the choices made.

Joerg

I’m not in favor of dropping GCC 4.8 support yet. It’s the default compiler for Ubuntu Trusty, which is from 2014, which isn’t that old. I think it’s important that LLVM build out of the box with the commonly installed system compiler.

We made an exception when we went to C++11 because it was worth it. I don’t think the features provided by C++14 are quite as compelling as what we got for the pain of raising our minimum GCC version to 4.7.1.