Work around ICC 16 beta compiler bug in SFINAE expansion
authorThiago Macieira <thiago.macieira@intel.com>
Fri, 31 Jul 2015 07:30:00 +0000 (00:30 -0700)
committerThiago Macieira <thiago.macieira@intel.com>
Fri, 31 Jul 2015 17:02:12 +0000 (17:02 +0000)
Calling std::vector<int>'s constructor (or assign()) with two ints can
select one of two different overloads: the (size_t, value_type) overload
which fills with n copies of the value or (iterator, iterator) overload,
which would copy a range.

libstdc++ had some workarounds for this scenario, by using an indirect
dispatch to determine whether it was a pair of integrals or not. But
ever since the resolution of DR1234 (https://gcc.gnu.org/bugzilla/
show_bug.cgi?id=43813) with C++11's more expressive SFINAE, the
dispatching is done actually by the outer template by adding an extra
template parameter that requires std::iterator_traite<T> to expand.

That's where ICC fails: it expands std::iterator_traits<int> and that
fails. It should have ignored the expansion and discarded that overload.

The workaround is simple: pass different types as the parameters, which
means the compiler cannot select the overload containing a pair of
iterators.

/usr/include/c++/5/bits/stl_iterator_base_types.h(154): error: name followed by "::" must be a class or namespace name
        typedef typename _Iterator::iterator_category iterator_category;
                         ^
          detected during:
            instantiation of class "std::__iterator_traits<_Iterator, void> [with _Iterator=int]" at line 163
            instantiation of class "std::iterator_traits<_Iterator> [with _Iterator=int]" at line 876 of "compiler/qv4ssa.cpp"

Change-Id: I52dd43c12685407bb9a6ffff13f5f783820213a5
Reviewed-by: Erik Verbruggen <erik.verbruggen@theqtcompany.com>
src/qml/compiler/qv4ssa.cpp

index e61a602e64c5a3f236d956c31863c7e22fb1d114..c0669d3e4731b99e3c520747760ae35ab8544cd9 100644 (file)
@@ -530,7 +530,7 @@ class DominatorTree
         const int bbCount = function->basicBlockCount();
         d->vertex = std::vector<int>(bbCount, InvalidBasicBlockIndex);
         d->parent = std::vector<int>(bbCount, InvalidBasicBlockIndex);
-        d->dfnum = std::vector<int>(bbCount, 0);
+        d->dfnum = std::vector<int>(size_t(bbCount), 0);
         d->semi = std::vector<BasicBlockIndex>(bbCount, InvalidBasicBlockIndex);
         d->ancestor = std::vector<BasicBlockIndex>(bbCount, InvalidBasicBlockIndex);
         idom = std::vector<BasicBlockIndex>(bbCount, InvalidBasicBlockIndex);
@@ -873,7 +873,7 @@ private:
     //      - set the current node's depth to that of immediate dominator + 1
     std::vector<int> calculateNodeDepths() const
     {
-        std::vector<int> nodeDepths(function->basicBlockCount(), -1);
+        std::vector<int> nodeDepths(size_t(function->basicBlockCount()), -1);
         nodeDepths[0] = 0;
         foreach (BasicBlock *bb, function->basicBlocks()) {
             if (bb->isRemoved())