In libc++ the test suite supports all C++ language versions. Tests have filters which to determine which language versions they are not available in. For example, a feature that is introduced in C++26 will be filtered like
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
This list grows with every released C++ Standard. A real issue is that some features added to C++ are deprecated and eventually removed. In libc++ we use annotations for deprecation and test these. For example a feature deprecated in C++17 and removed in C++26 looks like
// UNSUPPORTED: c++03, c++11, c++14, c++26
This test will break once we add support for C++29. Then we need to manually update the test to
// UNSUPPORTED: c++03, c++11, c++14, c++26, c++29
In the libc++ header code C++ language versions are guarded with #ifdef
’s like
#if _LIBCPP_STD_VER <= 17
or
#if _LIBCPP_STD_VER >= 17
I propose to add allow a similar syntax in lit. This means the first example becomes
// UNSUPPORTED: <=c++23
and the second example becomes
// UNSUPPORTED: <=c++14, >=c++26
If we decide we like this feature I would propose to write new tests in a different way. To me, the examples above require mental gymnastics. For the first example I propose we write
// REQUIRES: >=c++26
The second example needs mental gymnastics to determine the feature was deprecated in C++17 and removed in C++26, I propose to simplify this to
// REQUIRES: >=c++17
// UNSUPPORTED: >=c++26
I feel the latter two examples are much easier to understand and thus to write and to teach to new new contributors.
Note the REQUIRES syntax is already supported in lit. At the moment, we can’t use it for language filtering since it requires updating tests when a new C++ Standard is introduced. The new syntax >=c++xy
does not have this limitation.
The proposal is to add these features, but not to do a mass conversion, I only want to convert the deprecation/removal tests, since they will break with C++29.
Since the characters < and > are not supported by lit, this requires a minor change in lit.
The implementation works by adding several new feature flags in the tests,
<=c++03
… <=c++26
and >=c++03
… >= c++26
. It would be possible to add <c++03
… <c++26
and >c++03
… >c++26
too. The motivation not to do this is that I prefer to have a uniform syntax in our tests. So always use
// REQUIRES: >=c++26
Adding >c++23
would allow
// REQUIRES: >c++23
By not adding >c++23
this syntax won’t work and we guide developers to do the right thing.
Implementing this is quite trivial; a proof-of-concept is available. I’ve tested the number of executed tests remains stable before and after the change. (This patch needs work before being reviewable, including adding documentation.)