diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2018-07-03 05:46:20 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2018-07-03 05:46:20 +0000 |
commit | 83e5f81d264fa927e7f0388535b31f707b1d9bea (patch) | |
tree | affc53907e1da1e2622b45b5d28dc71f13823d01 | |
parent | 6121699b110e12df972d11e05e705794cc0a58e0 (diff) | |
download | bcm5719-llvm-83e5f81d264fa927e7f0388535b31f707b1d9bea.tar.gz bcm5719-llvm-83e5f81d264fa927e7f0388535b31f707b1d9bea.zip |
[ADT] Try to work around a crash in MSVC.
Putting `sizeof(T) <= 16` into the parameter of a `std::conditional`
causes every version of MSVC I've tried to crash:
https://godbolt.org/g/eqVULL
Really frustrating, but an extra layer of indirection through an
instantiated type gives a working way to access this computed constant.
llvm-svn: 336170
-rw-r--r-- | llvm/include/llvm/ADT/FunctionExtras.h | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/llvm/include/llvm/ADT/FunctionExtras.h b/llvm/include/llvm/ADT/FunctionExtras.h index 2cce7b32320..95b30541c79 100644 --- a/llvm/include/llvm/ADT/FunctionExtras.h +++ b/llvm/include/llvm/ADT/FunctionExtras.h @@ -46,6 +46,13 @@ template <typename ReturnT, typename... ParamTs> class unique_function<ReturnT(ParamTs...)> { static constexpr int InlineStorageSize = sizeof(void *) * 3; + // MSVC has a bug and ICEs if we give it a particular dependent value + // expression as part of the `std::conditional` below. To work around this, + // we build that into a template struct's constexpr bool. + template <typename T> struct IsSizeLessThanThresholdT { + static constexpr bool value = sizeof(T) <= (2 * sizeof(void *)); + }; + // Provide a type function to map parameters that won't observe extra copies // or moves and which are small enough to likely pass in register to values // and all other types to l-value reference types. We use this to compute the @@ -60,7 +67,7 @@ class unique_function<ReturnT(ParamTs...)> { !std::is_reference<T>::value && llvm::is_trivially_copy_constructible<T>::value && llvm::is_trivially_move_constructible<T>::value && - sizeof(T) <= (2 * sizeof(void *)), + IsSizeLessThanThresholdT<T>::value, T, T &>::type; // The type of the erased function pointer we use as a callback to dispatch to |