ICE (compiler crash), probably related to try-catch in lambda - by Alf P. Steinbach, except MS doesn't accept it

Status : 

  Fixed<br /><br />
		This item has been fixed in the current or upcoming version of this product.<br /><br />
		A more detailed explanation for the resolution of this particular item may have been provided in the comments section.


1
0
Sign in
to vote
ID 734023 Comments
Status Closed Workarounds
Type Bug Repros 0
Opened 3/28/2012 5:54:43 PM
Access Restriction Public
Moderator Decision Sent to Engineering Team for consideration

Description

ICE with reference to compiler's own source code 'msc1.cpp', line 1420.
Sign in to post a comment.
Posted by Microsoft on 3/30/2012 at 4:55 PM
Thank you for the code defect report. We're happy to say this has already been fix and the fix will be part of the next release.

Tanveer Gani
Visual C++ Team
Posted by MS-Moderator09 [Feedback Moderator] on 3/28/2012 at 11:22 PM
Thank you for submitting feedback on Visual Studio 2010 and .NET Framework. Your issue has been routed to the appropriate VS development team for review. We will contact you if we require any additional information.
Posted by MS-Moderator01 on 3/28/2012 at 6:55 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)
Posted by Alf P. Steinbach, except MS doesn't accept it on 3/28/2012 at 5:58 PM
<code>
#undef UNICODE
#define UNICODE
#undef STRICT
#define STRICT
#undef NOMINMAX
#define NOMINMAX
#include <windows.h>

#include    <assert.h>         // assert
#include    <exception>         // std::throw_with_nested
#include    <functional>        // std::function
#include    <iostream>         // std::wcout, std::endl
#include    <stddef.h>         // ptrdiff_t
#include    <stdexcept>         // std::runtime_error, std::exception
#include    <string>            // std::string
#include    <utility>         // std::move
using namespace std;

namespace cpp {
    typedef ptrdiff_t     Size;

    inline bool hopefully( bool const c ) { return c; }

    inline bool throwX( string const& s ) { throw runtime_error( s ); }

    inline bool throwX( string const& s, exception const& reasonX )
    {
        throwX( s + "\n!- " + reasonX.what() );
    }

    class ScopeGuard
    {
    private:
        function<void()> cleanup_;

        ScopeGuard( ScopeGuard const& );                // No such.
        ScopeGuard& operator=( ScopeGuard const& );     // No such.

    public:
        ~ScopeGuard() { cleanup_(); }

        ScopeGuard( function<void()> const cleanup )
            : cleanup_( cleanup )
        {}
    };

    class SubstringRef
    {
    private:
        wchar_t const* start_;
        wchar_t const* end_;

    public:
        Size length() const             { return end_ - start_; }
        wchar_t const* start() const    { return start_; }
        wchar_t const* end() const     { return end_; }

        SubstringRef( wchar_t const* start, wchar_t const* end )
            : start_( start )
            , end_( end )
        {}
    };

    inline void skipWhitespace( wchar_t const*& p )
    {
        while( *p != L'\0' && iswspace( *p ) ) { ++p; }
    }

    inline wchar_t const* theAfterWhitespacePart( wchar_t const* p )
    {
        skipWhitespace( p );
        return p;
    }

    inline void invert( bool& b ) { b = !b; }
} // namespace cpp

namespace winapi {
    using cpp::hopefully;
    using cpp::invert;
    using cpp::Size;
    using cpp::skipWhitespace;
    using cpp::SubstringRef;
    using cpp::theAfterWhitespacePart;
    using cpp::throwX;

    namespace raw {
        typedef HANDLE                 Handle;
        typedef PROCESS_INFORMATION     ProcessInformation;
    } // namespace raw

    // The following logic is mainly a workaround for a bug in CommandLineToArgvW.
    // See [http://preview.tinyurl.com/CommandLineToArgvWBug].
    inline SubstringRef nextArgumentIn( wchar_t const* const commandLine )
    {
        wchar_t const* p = commandLine;
    
        skipWhitespace( p );
        wchar_t const* const    start = p;

        bool isInQuotedPart = false;
        while( *p != L'\0' && (isInQuotedPart || !iswspace( *p ) ) )
        {
            if( *p == L'\"' ) { invert( isInQuotedPart ); }
            ++p;
        }
        return SubstringRef( start, p );
    }

    // This corresponds essentially to the argument of wWinMain(...).
    inline wchar_t const* commandLineArgPart()
    {
        SubstringRef const programSpec = nextArgumentIn( GetCommandLine() );
        return theAfterWhitespacePart( GetCommandLine() + programSpec.length() );
    }

    class ProcessInfo
    {
    private:
        raw::ProcessInformation info_;

        ProcessInfo( ProcessInfo const& );             // No such.
        ProcessInfo& operator=( ProcessInfo const& ); // No such.

    public:
        raw::ProcessInformation& raw()     { return info_; }
        raw::Handle handle() const         { return info_.hProcess; }

        ~ProcessInfo()
        {
            ::CloseHandle( info_.hThread );
            ::CloseHandle( info_.hProcess );
        }

        ProcessInfo(): info_() {}

        ProcessInfo( ProcessInfo&& other )
            : info_( move( other.info_ ) )
        {}
    };

    inline ProcessInfo createProcess( wchar_t const commandLine[] )
    {
        STARTUPINFO         startupInfo;
        ProcessInfo         processInfo;
        wstring             mutableCommandLine( commandLine );

        mutableCommandLine += L'\0';
        GetStartupInfo( &startupInfo );
        bool const creationSucceeded = !!CreateProcess (
            nullptr,                // LPCTSTR lpApplicationName,
            &mutableCommandLine[0], // LPTSTR lpCommandLine,
            nullptr,                // LPSECURITY_ATTRIBUTES lpProcessAttributes,
            nullptr,                // LPSECURITY_ATTRIBUTES lpThreadAttributes,
            true,                 // BOOL bInheritHandles,
            NORMAL_PRIORITY_CLASS, // DWORD dwCreationFlags,
            nullptr,                // LPVOID lpEnvironment,
            nullptr,                // LPCTSTR lpCurrentDirectory,
            &startupInfo,         // LPSTARTUPINFO lpStartupInfo,
            &processInfo.raw()     // LPPROCESS_INFORMATION lpProcessInformation
            );
        hopefully( creationSucceeded )
            || throwX( "winapi::createProcess: CreateProcess failed" );
        return processInfo;
    }
} // namespace winapi

void cppMain()
{
    using cpp::hopefully;
    using cpp::throwX;
    using winapi::commandLineArgPart;
    using winapi::createProcess;
    using winapi::nextArgumentIn;
    using winapi::ProcessInfo;

    wchar_t const* const    otherCommandLine    = commandLineArgPart();

    hopefully( nextArgumentIn( otherCommandLine ).length() > 0 )
        || throwX( "Usage: timep command ..." );

    ProcessInfo const process = [=]() {
        try
        {
            createProcess( otherCommandLine );
        }
        catch( exception const& x )
        {
            throwX( "Error starting process.", x );
        }
    } ();
}

int main()
{
    try
    {
        cppMain();
        return EXIT_SUCCESS;
    }
    catch( exception const& x )
    {
        wcerr << "!" << x.what() << endl;
    }
    return EXIT_FAILURE;
}
</code>