leapmotion / autowiring

A C++ Inversion of Control Framework
http://autowiring.io/
Apache License 2.0
148 stars 17 forks source link

Future issue with Visual C++ 2019 Update 1 #1065

Open JonCavesMSFT opened 5 years ago

JonCavesMSFT commented 5 years ago

Hi: Visual C++ 2019 Update 1 (which should be released later this year) has a completely rewritten lambda parser and one side-effect of this rewrite is that the format of the names of generated closure classes has changed (the generated name is now more similar to what gcc and clang would produce). In our internal testing of this release we have found that one of your tests is failing - specifically the first line of this test:

TEST_F(AutowiringDebugTest, IsLambdaTest) {
  auto fn = [] {};
  ASSERT_TRUE(autowiring::dbg::IsLambda(typeid(fn))) << "Lambda function not correctly detected";
  ASSERT_FALSE(autowiring::dbg::IsLambda(typeid(CoreThread))) << "Simple class incorrectly identified as a lambda function";
  ASSERT_FALSE(autowiring::dbg::IsLambda(typeid(std::vector<int>))) << "Template class incorrectly identified as a lambda function";
}

The test fails because of the code below which will not work in 2019 U1 because of the change to the generated name of the closure class:

#ifdef _MSC_VER
// On Windows, lambda functions start with the key string "class <"
bool autowiring::dbg::IsLambda(const std::type_info& ti) {
  return demangle(ti)[0] == '<';
}
#else

If you compiled the program below with 2019 U1:

#include <typeinfo>
#include <cstdio>

template<typename T>
void f(T&&)
{
        const auto& info = typeid(T);
        std::printf("%s\n", info.name());
}

int main()
{
        f([] {});
}

it would produce:

class `int __cdecl main(void)'::`2'::<lambda_1>

while Visual C++ 2019 (and earlier releases) would produce:

class <lambda_b70101a59c2c086aa644ada2623ed1ce>

If you have any questions feel free to contact me.

Thanks Jonathan Caves