Home Dashboard Directory Help
Search

Possible bug in Visual Studio 2012 C++ compiler related to intrinsic math functions by jcr_


Status: 

Closed
 as Fixed Help for as Fixed


5
0
Sign in
to vote
Type: Bug
ID: 776885
Opened: 1/18/2013 2:42:24 AM
Access Restriction: Public
0
Workaround(s)
view
3
User(s) can reproduce this bug

Description

cl.exe version: Microsoft (R) C/C++ Optimizing Compiler Version 17.00.51106.1 for x86
Visual Studio Professional 2012 Version 11.0.51106.01 Update 1

When using #pragma intrinsic to use intrinsic version of some math functions (eg fabs, sqrt, etc), the compiler will generate code that produces stack corruption caught when compiling with /RTC1. This appears to only happen in 32-bit and not 64-bit, and this same code has worked in VS2010, VS2008, and possibly earlier so I believe this behavior is new to VS2012.

The issue can be worked around by 1) not using the intrinsic version of certain math functions, 2) using #pragma function to force the function version of one or more math functions, or 3) avoid calling certain intrinsic math functions in succession.
Details
Sign in to post a comment.
Posted by Microsoft on 4/29/2014 at 12:29 PM
Thank you for reporting this issue. This issue has been fixed in Visual Studio 2013. You can install a trial version of Visual Studio 2013 with the fix from: http://go.microsoft.com/?linkid=9832436
Posted by Charles Fu on 2/24/2014 at 11:21 PM
This bug has been fixed in Visual Studio 2013 RTM.

Charles Fu
Visual Studio C++ Team.
Posted by scandella on 2/21/2014 at 4:22 AM
Why is this bug marked as closed? In Visual Studio 2012 (Update 4) this bug is still present. What's the status?
Posted by RTempete on 7/23/2013 at 12:42 AM
Hello

Tested with VS2012 Version 11.0.60610.01 Update 3 and bug still present.
Posted by jcr_ on 4/10/2013 at 10:22 AM
Should this be fixed in VS 2012 Update 2?
Posted by Microsoft on 3/26/2013 at 12:07 PM
This issue has been fixed and will be part of the next Visual Studio release.
Thanks.
Posted by Microsoft on 1/20/2013 at 7:06 PM
Thanks for your feedback.

We are rerouting this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue.
Posted by Microsoft on 1/18/2013 at 2:50 AM
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 jcr_ on 1/18/2013 at 2:49 AM
I don't see the attachment .zip file showing up, so I'll post the contents of the .zip in this comment just in case.


build.bat:
-----------
@echo off
cl /MP /GS /W4 /Zi /Gm- /Od /fp:precise /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /WX- /RTC1 /Gd /Oy- /MDd /EHsc /nologo /Ferepro.exe /I. main.cpp /link /DYNAMICBASE:NO /SUBSYSTEM:CONSOLE /DEBUG /MACHINE:x86 /INCREMENTAL /ERRORREPORT:PROMPT /NOLOGO /TLBID:1


test_framework.hpp:
------------------------

#pragma once

#include <vector>
#include <string>
#include <iostream>
#include <sstream>

class test_failure
{
public:
    test_failure(const std::string& name,
                 const std::string& condition)
        : m_name(name) {
        m_failure = "Condition not met: ";
        m_failure += condition;
    }

    test_failure(const std::string& name,
                 const std::string& expected,
                 const std::string& actual)
        : m_name(name) {
        m_failure = "Expected result ";
        m_failure += expected;
        m_failure += " was not achieved. The actual result was ";
        m_failure += actual;
    }

    const std::string& name() const {
        return m_name;
    }

    const std::string& failure() const {
        return m_failure;
    }

private:
    std::string m_name;
    std::string m_failure;
};

class test_result
{
public:
    void begin() {
        m_test_count = 0;
        m_failed_count = 0;
        m_check_count = 0;
    }

    void add_failure(test_failure& f) {
        std::cout << "Test failed: " << f.name() << std::endl;
        std::cout << "\t" << f.failure() << std::endl;
        m_failed_count++;
    }

    void ran_test() {
        m_test_count++;
    }

    void ran_check() {
        m_check_count++;
    }

    void end() const {
        std::cout << m_test_count << " test(s), "
                 << m_check_count << " check(s), "
                 << m_failed_count << " failure(s)" << std::endl;
    }

    bool failed() const {
        return m_failed_count != 0;
    }

private:
    size_t m_test_count;
    size_t m_failed_count;
    size_t m_check_count;
};

class test_case
{
public:
    test_case(const std::string& name)
        : m_test_name(name) {
    }

    virtual ~test_case() {}

    virtual void run(test_result& r) = 0;

protected:
    std::string m_test_name;
};

#define CHECK(exp) \
    r.ran_check(); \
    if( !(exp) ) { \
        test_failure tf(m_test_name, #exp); \
        r.add_failure(tf); \
        return; \
    }


math_test.hpp:
------------------

#pragma once

#include "test_framework.hpp"
#include <cmath>

// Commenting either of the following will resolve
// the issue
#pragma intrinsic(fabs)
#pragma intrinsic(sqrt)

// Uncommenting either of the following will resolve the
// issue.
//#pragma function(sqrt)
//#pragma function(fabs)

class intrinsic_math : public test_case {
public:
    intrinsic_math()
        : test_case("intrinsic::math") {
    }

    void run(test_result& r) {
        // Commenting either of the following will resolve
        // the issue
        CHECK(0.0 == std::sqrt(0.0));
        CHECK(0.0 == std::fabs(0.0));
    }
};


main.cpp:
------------

#include <iostream>

#include "test_framework.hpp"
#include "math_test.hpp"

int main(int, char **) {
    test_result r;

    std::cout << "Running tests..." << std::endl;

    r.begin();
    intrinsic_math im;
    im.run(r);
    r.end();

    return r.failed();
}
Sign in to post a workaround.
File Name Submitted By Submitted On File Size  
vs11bug.zip 1/18/2013 1 KB
vs11bug.zip 1/18/2013 1 KB