billyquith / ponder

C++ reflection library with Lua binding, and JSON and XML serialisation.
http://billyquith.github.io/ponder/
Other
647 stars 95 forks source link

Investigate MSVC 2015 compiler crash #6

Closed billyquith closed 8 years ago

billyquith commented 8 years ago

Debug build.

c:\program files (x86)\microsoft visual studio 14.0\vc\include\type_traits(1416): fatal error C1001: An internal error has occurred in the compiler.
1>  (compiler file 'f:\dd\vctools\compiler\utc\src\p2\main.c', line 246)
1>   To work around this problem, try simplifying or changing the program near the locations listed above.
1>  Please choose the Technical Support command on the Visual C++
1>   Help menu, or open the Technical Support help file for more information

apparently related to:

template<class _Callable,
    class... _Types> inline
    auto invoke(_Callable&& _Obj, _Types&&... _Args)
    -> decltype(_Invoker<_Callable, _Types...>::_Call(
        _STD forward<_Callable>(_Obj), _STD forward<_Types>(_Args)...))
    {   // INVOKE a callable object
    return (_Invoker<_Callable, _Types...>::_Call(
        _STD forward<_Callable>(_Obj), _STD forward<_Types>(_Args)...));
    }

in <type_traits>.

billyquith commented 8 years ago

After some investigation there seem to be some problems which are compiler bugs, which seem to disappear when MSVC 2015 Update 2 is installed. There is one test left which has been temporarily removed. I will perhaps contact Microsoft about this.

I added a test in config.hpp for the correct MSVC compiler.

billyquith commented 8 years ago

Adding the array property causes MCVC 2015 Update 2 to crash with the above messages.

ponder::Class::declare<MyClass>("ClassVisitorTest::MyClass")
            .property("array", &MyClass::arrayProp);  // causes crash

This appears to be caused by the std::function getter being initialised in the Accessor constructor in ponder/include/ponder/detail/propertyfactory.hpp line 210.

template <typename C, typename R>
class Accessor1<C, R, typename std::enable_if< ObjectTraits<R>::isWritable>::type >
{
public:

    typedef ObjectTraits<R> Traits;
    typedef typename Traits::DataType DataType;
    typedef C ClassType;

    enum
    {
        canRead = true,
        canWrite = true
    };

    template <typename F>
    Accessor1(F getter)
        : m_getter(getter)   // *** comment this line out to stop the problem ***
    {
    }

    typename ReturnHelper<R>::Type get(C& object) const
    {
        return ReturnHelper<R>::get(m_getter(object));
    }

    bool set(C& object, const Value& value) const
    {
        return CopyHelper<DataType>::copy(*Traits::getPointer(m_getter(object)), value);
    }

private:

    std::function<R (C&)> m_getter;
};
billyquith commented 8 years ago

Reported on the Microsoft support site.

billyquith commented 8 years ago

Asked by MS to add /Bd flag.

With /Bd enabled, each execution in the build is preceded by a description written to standard error. Each execution is typically described as a command, showing the module or program that will be executed, together with its command line.

This gives:

1>------ Build started: Project: pondertest, Configuration: Debug Win32 ------
1>  classvisitor.cpp
1>  ENC_CWD=C:\Code\libs\ponder\test
1>  ENC_CL=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\CL.exe
1>  ENC_SRC=C:\Code\libs\ponder\test\classvisitor.cpp
1>  ENC_PDB=C:\Code\libs\ponder\test\pondertest.dir\Debug\vc140.pdb
1>  ENC_CMD=-c -IC:\Code\libs\ponder\include -Zi -nologo -W3 -WX- -Od -Ob0 -Oy- -DWIN32 -D_WINDOWS -D_DEBUG -DPONDER_STATIC -DCMAKE_INTDIR=\"Debug\" -D_MBCS -Gm- -EHs -EHc -RTC1 -MDd -GS -fp:precise -Zc:wchar_t -Zc:forScope -Zc:inline -GR -Gd -TP -analyze- -errorreport:prompt -Bd -I"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include" -I"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\atlmfc\include" -I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\8.1\Include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\Include\shared" -I"C:\Program Files (x86)\Windows Kits\8.1\Include\winrt" -X
1>  `C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\c1xx.dll -zm0x01349DA0 -il C:\Users\Nick\AppData\Local\Temp\_CL_eda91d23 -typedil -f C:\Code\libs\ponder\test\classvisitor.cpp -Ze -D_MSC_EXTENSIONS -Zp8 -ZB64 -D_INTEGRAL_MAX_BITS=64 -Gs -pc \:/ -D_MSC_VER=1900 -D_MSC_FULL_VER=190023918 -D_MSC_BUILD=0 -D_WIN32 -D_M_IX86=600 -D_M_IX86_FP=2 -I C:\Code\libs\ponder\include -Zi -nologo -W 3 -Ot -DWIN32 -D_WINDOWS -D_DEBUG -DPONDER_STATIC -DCMAKE_INTDIR="Debug" -D_MBCS -EHs -D_CPPUNWIND -EHc -D__MSVC_RUNTIME_CHECKS -RTCs -RTCu -D_DEBUG -D_MT -D_DLL -GS -D_M_FP_PRECISE -Zc:wchar_t -Zc:forScope -GR -D_CPPRTTI -Fopondertest.dir\Debug\classvisitor.obj -Fdpondertest.dir\Debug\vc140.pdb -Gd -errorreport:prompt -Bd -I C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include -I C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\atlmfc\include -I C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt -I C:\Program Files (x86)\Windows Kits\8.1\Include\um -I C:\Program Files (x86)\Windows Kits\8.1\Include\shared -I C:\Program Files (x86)\Windows Kits\8.1\Include\winrt -sqm C:\Users\Nick\AppData\Local\Microsoft\VSCommon\14.0\SQM\sqmcpp.log'
1>  `C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\c2.dll -il C:\Users\Nick\AppData\Local\Temp\_CL_eda91d23 -typedil -f C:\Code\libs\ponder\test\classvisitor.cpp -Gs4096 -dos -Zi -W 3 -Ob0 -EHs -MDd -GS -FitObjFunc -FitObjData -Fopondertest.dir\Debug\classvisitor.obj -Fdpondertest.dir\Debug\vc140.pdb -errorreport:prompt -Bd'
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\Microsoft.CppCommon.targets(356,5): error MSB6006: "CL.exe" exited with code -1073741819.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
billyquith commented 8 years ago

Since I can't seem to now post or edit the thread on the MS support site I'll post info here.

From Sera YuPactera (MSFT CSG):

If no error messages have been emitted prior to the internal compiler error, then the next step is to determine which pass of the compiler is emitting the internal compiler error. This can be determined by recompiling the application with the /Bd option included. The /Bd option will cause each pass to print its name and arguments when it is invoked. The last pass invoked before the error is emitted is the one responsible. If the pass indicated is P1, then the likely problem is still error recovery, as in number one above, but it is happening before the compiler has had a chance to emit the error message for the error it has just discovered.

If the pass indicated is P2, then the problem can usually be fixed by removing one or more optimization options (or using a different code generator). You can determine which option is at fault by removing them one at a time and recompiling until the message goes away.

More rarely, such errors occur at very low optimization levels or even when optimization is disabled. In such cases, rewriting the line where the error is reported (or possibly several lines including the one causing the error) may be a solution.

If none of these options works, consult the technical support help file or the technical support section in one of your manuals.

1>  `C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\c2.dll 
      -il C:\Users\Nick\AppData\Local\Temp\_CL_eda91d23 -typedil 
      -f C:\Code\libs\ponder\test\classvisitor.cpp -Gs4096 -dos -Zi -W 3 -Ob0 -EHs -MDd -GS 
      -FitObjFunc -FitObjData -Fopondertest.dir\Debug\classvisitor.obj 
      -Fdpondertest.dir\Debug\vc140.pdb -errorreport:prompt -Bd'

So I think the above error points to this being P2, because of c2, so we can try altering the optimisation flags from the command previous to the crash:

1>  ENC_CMD=-c -IC:\Code\libs\ponder\include -Zi -nologo -W3 -WX- -Od -Ob0 -Oy- 
      -DWIN32 -D_WINDOWS -D_DEBUG -DPONDER_STATIC -DCMAKE_INTDIR=\"Debug\" 
      -D_MBCS -Gm- -EHs -EHc -RTC1 -MDd -GS -fp:precise -Zc:wchar_t -Zc:forScope 
      -Zc:inline -GR -Gd -TP -analyze- -errorreport:prompt -Bd 
      -I"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include" 
      -I"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\atlmfc\include" 
      -I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt"
      -I"C:\Program Files (x86)\Windows Kits\8.1\Include\um"
      -I"C:\Program Files (x86)\Windows Kits\8.1\Include\shared"
      -I"C:\Program Files (x86)\Windows Kits\8.1\Include\winrt" -X

We are compiling in debug. Flags are -Od -Ob0 -Oy-

Since we are in debug and none of these flags seems troubling I think this is a compiler bug. Will report.

billyquith commented 8 years ago

To recreate this crash go to test/classvisitor.cpp and comment in lines 114-6:

#if !defined(_MSC_VER) // TODO - This causes a compiler crash on MSVC 2015
            .property("array", &MyClass::arrayProp) 
#endif
billyquith commented 8 years ago

I now have Travis tests passing for clang and GCC on Ubuntu 14.04. 😁

billyquith commented 8 years ago

Compiler no longer crashes, which was a problem as not clear what the source of the error was. No notification from MS so may just be fixed with other compiler bugs. All tests should be running the same on all compilers now.

Also changed typeof to decltype as typeof seemed to confuse MSVC (but not clang and GCC). decltype more modern anyway.