Home Dashboard Directory Help
Search

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


Status: 

Closed
 as Fixed Help for as Fixed


1
0
Sign in
to vote
Type: Bug
ID: 734023
Opened: 3/28/2012 5:54:43 PM
Access Restriction: Public
Moderator Decision: Sent to Engineering Team for consideration
0
Workaround(s)
view
0
User(s) can reproduce this bug

Description

ICE with reference to compiler's own source code 'msc1.cpp', line 1420.
Details
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>
Sign in to post a workaround.
File Name Submitted By Submitted On File Size  
main.cpp 3/28/2012 5 KB