Visual C++ 2013 compiler bugs

Back to Blog

Here are some of the bugs I have found in the Visual C++ 2013 compiler.

SFINAE does not work with alias templates

The following does not compile, although it should.

#include <type_traits>

template <bool Condition>
using EnableIf = typename std::enable_if<Condition, void>::type;

template <typename Type>
EnableIf<!std::is_integral<Type>::value> f(const Type& that)
{
}

template <typename Type>
EnableIf<std::is_integral<Type>::value> f(const Type& that)
{
}

int main()
{
    f(5);
    return 0;
}

Initializer list ambiguates in a really weird way

The following does not compile, although it should.

#include <initializer_list>

struct A 
{
    A(int) {}
};

struct Tuple
{
    Tuple() {}
    Tuple(const A& x, const A& y) {}
    void f(const Tuple& that) {}
    void f(const std::initializer_list<A>& that) {}
};

int main()
{
    Tuple a;
    // Ok
    a.f({ 1 });
    // Fails
    a.f({ 1, 2 });
    // Ok
    a.f({ 1, 2, 3 });
    return 0;
}

Actual results:

error C2668: 'Tuple::f' : ambiguous call to overloaded function

Incorrect illegal member initialization

The following does not compile, although it should.

class A {};

class B
{
public:
    typedef A T;
};

template <typename T>
class N
    : public T
{
public:
    N()
        : T()
    {
    }
};

class C
{
public:
    C()
    {
        typedef N<B> E;
        new E;
    }
};

int main()
{
    return 0;
}

Actual results:

error C2614: 'N<B>' : illegal member initialization: 'T' is not a base or member

Initializer-list constructor of pairs

The following does not compile, although it should.

#include <initializer_list>
#include <utility>

class A
{
public:
    A(std::initializer_list<std::pair<int, int>> dataSet) {}
};

int main()
{
    A b({ { 0, 10 }, { 1, 11 }, { 2, 12 } });
    return 0;
}

Actual results:

error C2440: 'initializing' : cannot convert from 'initializer-list' to 'A' No constructor could take the source type, or constructor overload resolution was ambiguous

Simple function template deduction fails

The following does not compile, although it should. I reported this bug already in 2007.

template <int N>
class Vector {};

template <int M, int N>
class Matrix {};

template <int M, int N>
Vector<N> operator*(const Vector<M>& other,
                    const Matrix<M + 1, N>& that)
{
    return Vector<N>();
}

int main()
{
    Vector<3> a;
    Matrix<4, 4> m;

    a * m;

    return 0;
}

Actual results:

... could not deduce template argument for 'N'

Misleading error message ‘invalid explicit template argument’

The compiler is expected to emit an error message stating that the pure virtual function has no implementation. I reported this bug already in 2008.

template <typename Type>
class A
{
public:
    virtual Type operator()(
        const Type& x) const = 0;
};

template <typename Type>
class B
    : public A<Type>
{
public:
    template <typename Type>
    Type operator()(
        const Type& x) const
    {
        return x;
    }
};

template <typename Type>
B<Type> a()
{
    return B<Type>();
}

template <typename Type>
void f1()
{
    a<Type>();
}

template <typename Type>
void f2()
{
    a<Type>();
}

int main()
{
    f1<int>();
    f2<int>();

    return 0;
}

Actual results:

error C2770: invalid explicit template argument(s) for 'B<Type> a(void)'

Incomplete inner classes of a template class raise ‘use of undefined type’

The following does not compile, although it should. I reported this bug already in 2008.

template <typename Type>
class C
{
public:
    class A;
    class B;
};

template <typename Type>
class C<Type>::A
{
public:
    B f() const
    {
        return B();
    }
};

template <typename Type>
class C<Type>::B
{
};

int main()
{
    C<int> c;

    return 0;
}

Actual results:

error C2027: use of undefined type 'C<Type>::B'

‘Failed to specialize function’ connected to a ‘using’ declaration

The following does not compile, although it should. I reported this bug already in 2008.

class Base
{
public:
    enum {VALUE = 2};
};

class Derived
    : public Base
{
public:
    // If you comment this, this will compile.
    using Base::VALUE;
};

template <int N>
class Something {};

template <typename T>
Something<T::VALUE> f(T& that)
{
    return Something<T::VALUE>();
}

int main()
{
    Derived derived;
    f(derived);
    return 0;
}

Actual results:

error C2893: Failed to specialize function template 'Something<T::VALUE> f(T &)'

Signatures differing only by template parameter naming

The following does not compile, although it should. I reported this bug already in 2009.

template <int N>
void f(int x = N);

template <int M>
void f(int x)
{
}

int main()
{
    f<2>();
    return 0;
}

Actual results:

error C2065: 'N' : undeclared identifier

Incorrect warning about a base-class already being a base-class

This should compile without warnings. I reported this bug already in 2008.

template <typename Type>
class CommonBase
{
};

template <int N, typename Real, typename Derived>
class TupleBase
    : public CommonBase<Derived>
{
};

template <int N, typename Real>
class Tuple
    : public TupleBase<N, Real, Tuple<N, Real> >
{
};

template <int N, typename Real, typename Derived>
class VectorBase
    : public Tuple<N, Real>
    , public CommonBase<Derived>
{
};

template <int N, typename Real>
class Vector
    : public VectorBase<N, Real, Vector<N, Real> >
{
};

int main()
{
    return 0;
}

Actual results:

warning C4584: 'VectorBase<N,Real,Derived>' : base-class 'CommonBase<Derived>' is already a base-class of 'Tuple<N,Real>'

Base-class incorrectly “already initialized”

The following does not compile, although it should.

namespace N { class D {}; }

template <typename D>
class B    : public D
{
public:
    typedef D D_;
    B() : D_(){}
};

class A : public N::D {};

int main()
{
    B<A> b;
    return 0;
}

Actual results:

error C2437: 'D_' : already initialized

std::make_shared as a member initializer

The following does not compile, although it should.

#include <memory>

class A
{
public:
    std::shared_ptr<int> a = std::make_shared<int>();
};

int main()
{
    return 0;
}

Actual results:

error C2783: 'std::shared_ptr<_Ty> std::make_shared(_Types &&...)' : could not deduce template argument for '_Ty'

Overload ambiguity reporting is too vague

The compiler does not point out which overloads conflict with each other in case of an ambiguous overload resolution.

template <int N>
class A
{
};

template <>
class A<1>
{
public:
    A(int) {}
};

template <>
class A<6>
{
    A(int) {}
};

void f(A<1>) {}
void f(A<2>) {}
void f(A<3>) {}
void f(A<4>) {}
void f(A<5>) {}
void f(A<6>) {}

int main() 
{
    f(0);
    return 0;
}

Actual results:

error C2668: 'f' : ambiguous call to overloaded function
could be 'void f(A<6>)'
or     'void f(A<5>)'
or     'void f(A<4>)'
or     'void f(A<3>)'
or     'void f(A<2>)'
or     'void f(A<1>)'
while trying to match the argument list '(int)'

Expected results:

error: call of overloaded ‘f(int)’ is ambiguous
candidates are:
void f(A<1>)
void f(A<6>)

Variadic template deduction fails

The following does not compile, although it should.

template <typename T, typename S, bool C>
class A {};

template <typename... Type>
using B = A<Type..., false>;

int main()
{
    B<int, float> b;
    return 0;
}

Actual results:

error C2976: 'A' : too few template arguments

Ambiguity with a name in a dependent base-class

The following does not compile, although it should.

class A
{
public:
    class B {};
};

class B {};

template <typename Base>
class D
    : public Base
    , public B
{
public:
    using Base_ = B;
};

int main()
{
    D<A> u;
    return 0;
}

Actual results:

error C2385: ambiguous access of 'B'

Internal compiler error for a function template default type

The following triggers an internal compiler error. The compiler is expected to give an appropriate error about Real being a type, not an integer.

template <typename Settings>
class A {};

template <typename S, int N = typename S::Real>
void f(const A<S>& kdTree) {}

int main()
{
    struct Settings { using Real = float; };
    f(A<Settings>());
    return 0;
}

Internal compiler error for decltype(auto)

The following triggers an internal compiler error. The compiler is expected to give an appropriate error about incorrect syntax.

int main()
{
    decltype(auto) int a = 5;
    return 0;
}

decltype(auto) in a member function

The following does not compile, although it should.

template <typename T>
class A
{
public:
    decltype(auto) operator()()
    {
        return 8;
    }
};

template <typename T>
A<T> f(T input)
{
    return A<T>();
}

int main()
{
    auto tr = f(8);
    tr();
    return 0;
}

Actual results:

error C3779: 'A<int>::operator ()' : a function that returns 'decltype(auto)' cannot be used before it is defined

Ambiguous overload reporting is too vague, part 2

When a name has multiple matching overloads, the compiler does not provide the list of names which conflict. In this case the ambiguity is with the std::real() function of the complex numbers.

#include <complex>

namespace A { using real = double; }

using namespace A;
using namespace std;

int main()
{
    real a;
    return 0;
}

Actual results:

error C2872: 'real' : ambiguous symbol
could be 'real'
or     'test2.cpp(3) : A::real'

Expected results:

prog.cpp:10:5: error: reference to ‘real’ is ambiguous

/usr/include/c++/4.8/complex:1850:5: note: candidates are: 
template<class _Tp> typename __gnu_cxx::__promote<_Tp>::__type std::real(_Tp)

/usr/include/c++/4.8/complex:538:5: note: 
template<class _Tp> constexpr _Tp std::real(const std::complex<_Tp>&) real(const complex<_Tp>& __z)

prog.cpp:3:34: note: using real = double

Singular initializer list ambiguates with a scalar type

The following does not compile, although it should.

#include <initializer_list>

void f(int x) {}
void f(const std::initializer_list<int>& that) {}

int main()
{
    f(3);
    f({ 3 });
    return 0;
}

Actual results:

error C2668: 'f' : ambiguous call to overloaded function