Question

Working through a an update of VS2010 to 2012 here, and there are a couple of unittests failing due to either bad code generation or programming error but I'm not sure which. The code I'm posting is nearly equal to the orginal, and also reproduces the problems.

Here's a case; all classes/implementations are in seperate files.

class Base
{
public:
  virtual ~Base(){}
  void DoIt(){ DoItImpl(); }
protected:
  virtual void DoItImpl() = 0;
};

class Base2 : public Base
{
public:
  virtual void DoStuff() = 0;
};

class Impl : public Base2
{
public:
  Impl();
  void DoStuff();
protected:
  void DoItImpl();
};

void Impl::DoStuff()
{
  throw std::runtime_error( "oops" );
}

void Impl::DoItImpl()
{
  throw std::runtime_error( "oops" );
}

The above resides in a dll, and is tested using unittest++ in an exe (I epanded the CHECK_THROW macro for clarity, doesn't change a thing though):

SUITE( Base )
{
  TEST( Impl )
  {
    Impl c;
    bool caught = false;
    try
    {
      c.DoIt();
    }
    catch( const std::exception& )
    {
      caught = true;
    }

    //this point is never reached, instead control goes to the
    //try/catch in unittest++'s ExecuteTest function
    CHECK( caught );
  }
}

Whether it's a bug or not, is there a workaround I can use immediately, or some general rules on how to avoid this?

edit Added implementation of DoStuff(), if I call that instead of DoIt() there is no problem!

edit This should rule out the possibility of the unittest framework or any other code being the problem, or catching by const reference, or the compiler not knowing runtime_error derives from exception; I expanded the unittest macros to show what they actually do, and created a new project containing just this source file:

namespace SuiteImpl
{
  class TestImpl
  {
  public:
    TestImpl() {}
    virtual void RunImpl() const;
  };

  void TestImpl::RunImpl() const
  {
    xxx::Impl c;
    try
    {
      c.DoIt();
    }
    catch( std::exception& )
    {
      std::cout << "good" << std::endl;
    }
  }
}

int main()
{
  SuiteImpl::TestImpl impl;

  try
  {
    impl.RunImpl();
  }
  catch( const std::exception& )
  {
    std::cout << "not good" << std::endl;
  }
}

The output is not good.

Was it helpful?

Solution

This is confirmed to be an optimizer bug and they're hoping to fix it VS2012 Update 4.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top