[llvm] r336170 - [ADT] Try to work around a crash in MSVC.
Chandler Carruth via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 2 22:46:20 PDT 2018
Author: chandlerc
Date: Mon Jul 2 22:46:20 2018
New Revision: 336170
URL: http://llvm.org/viewvc/llvm-project?rev=336170&view=rev
Log:
[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.
Modified:
llvm/trunk/include/llvm/ADT/FunctionExtras.h
Modified: llvm/trunk/include/llvm/ADT/FunctionExtras.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/FunctionExtras.h?rev=336170&r1=336169&r2=336170&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/FunctionExtras.h (original)
+++ llvm/trunk/include/llvm/ADT/FunctionExtras.h Mon Jul 2 22:46:20 2018
@@ -46,6 +46,13 @@ template <typename ReturnT, typename...
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
More information about the llvm-commits
mailing list