Skip to content

Silence Clang -Wc++20-extensions - #737

Merged
Casey Carter (CaseyCarter) merged 1 commit into
microsoft:masterfrom
StephanTLavavej:silence
Apr 25, 2020
Merged

Casey Carter (CaseyCarter) merged 1 commit into
microsoft:masterfrom
StephanTLavavej:silence

Conversation

@StephanTLavavej

Copy link
Copy Markdown
Member

In pair, tuple, and optional, we use C++20 conditional explicit (aka explicit(bool)) to simplify constructors and improve compiler throughput, when compiler support is available:

STL/stl/inc/optional

Lines 182 to 193 in 0cbd1b2

#if _HAS_CONDITIONAL_EXPLICIT
template ::value, int> = 0>
constexpr explicit(!is_convertible_v<_Ty2, _Ty>) optional(_Ty2&& _Right)
: _Mybase(in_place, _STD forward<_Ty2>(_Right)) {}
#else // ^^^ _HAS_CONDITIONAL_EXPLICIT ^^^ / vvv !_HAS_CONDITIONAL_EXPLICIT vvv
template
enable_if_t, is_convertible<_Ty2, _Ty>>, int> = 0>
constexpr optional(_Ty2&& _Right) : _Mybase(in_place, _STD forward<_Ty2>(_Right)) {}
template
enable_if_t, negation>>, int> = 0>
constexpr explicit optional(_Ty2&& _Right) : _Mybase(in_place, _STD forward<_Ty2>(_Right)) {}
#endif // ^^^ !_HAS_CONDITIONAL_EXPLICIT ^^^

Like C++17 if constexpr, MSVC supports C++20 explicit(bool) in older Standard modes, with a suppressible warning. (This is because the feature requires novel syntax, so it can't be accidentally used, and it's extremely useful to library developers.) We suppress both warnings in STL headers:

STL/stl/inc/yvals_core.h

Lines 368 to 380 in 0cbd1b2

// warning C4984: 'if constexpr' is a C++17 language extension
#if !_HAS_CXX17 && _HAS_IF_CONSTEXPR
#define _STL_DISABLED_WARNING_C4984 4984
#else // !_HAS_CXX17 && _HAS_IF_CONSTEXPR
#define _STL_DISABLED_WARNING_C4984
#endif // !_HAS_CXX17 && _HAS_IF_CONSTEXPR
// warning C5053: support for 'explicit()' in C++17 and earlier is a vendor extension
#if !_HAS_CXX20 && _HAS_CONDITIONAL_EXPLICIT
#define _STL_DISABLED_WARNING_C5053 5053
#else // !_HAS_CXX20 && _HAS_CONDITIONAL_EXPLICIT
#define _STL_DISABLED_WARNING_C5053
#endif // !_HAS_CXX20 && _HAS_CONDITIONAL_EXPLICIT

Clang 9 supported explicit(bool) in C++20 mode, while Clang 10 added "downlevel" support similar to MSVC. When #708 changed the STL to require Clang 10, it also began using Clang 10's downlevel support for explicit(bool).

Curtis J Bezault (@cbezault) discovered that we forgot to suppress the warning that Clang emits for explicit(bool) in older Standard modes. We missed this because Clang (unlike MSVC) ordinarily suppresses warnings from "system headers". (-Wsystem-headers activates warnings in system headers, although this is rarely used because users are rarely interested in such warnings, and UCRT/WinSDK headers are still being cleaned up.)

This is a practical issue because anything on the INCLUDE path is considered to be a system header for warning purposes, while /I directories aren't (despite #include searching both INCLUDE and /I). During STL development, it is very convenient to be able to compile with /I S:\GitHub\STL\stl\inc and immediately consume updated STL headers without rebuilding (this is not possible when separately compiled changes are involved, of course), which will emit Clang warnings.

After this lengthy backstory, the fix is delightfully simple.

@BillyONeal

Copy link
Copy Markdown
Member

:sigh: I really wish clang had a 'there are no system headers' option :(

@CaseyCarter Casey Carter (CaseyCarter) changed the title Silence Clang -Wc++20-extensions. Silence Clang -Wc++20-extensions Apr 23, 2020
@CaseyCarter
Casey Carter (CaseyCarter) merged commit b64eeed into microsoft:master Apr 25, 2020
@CaseyCarter

Copy link
Copy Markdown
Contributor

Thanks for the cleanup!

@miscco

Copy link
Copy Markdown
Contributor

If we allow C++17 if constexpr in older code why are there still so many #ifdefs?
Is it solely because of EDG or could one get rid of all that old tag dispatch?

@CaseyCarter

Copy link
Copy Markdown
Contributor

If we allow C++17 if constexpr in older code why are there still so many #ifdefs?

Not all of our front ends allow if constexpr in C++14 mode: CUDA 9.2 is now the remaining problem child. Once we're done updating our required CUDA version to 10.1 update 2 (#639) we can remove the #ifdefs (#189).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Something can be improved

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants