This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix for PR libstdc++/51142 causes incompatibility when mixing C++98 and C++11 code with gcc-4.6.3 and later


Hello!

We found that the fix for PR 51142
<URL:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51142>, which was
checked in in SVN r181427
<URL:http://gcc.gnu.org/viewcvs?view=revision&revision=181394>, causes
code to break when different C++ versions are used.

A minimal example is attached. It results in a segfault. Cause is that
the wrong erase function is called:
#11 0x0804894d in std::multimap<int, int, std::less<int>,
std::allocator<std::pair<int const, int> > >::erase (this=0x804d288,
__position=...) at /usr/include/c++/4.6/bits/stl_multimap.h:540
#12 0x080490c3 in Old_Map::RemoveElements (this=0xffffcbf8) at old.cc:14
#13 0x08049492 in main () at main.cc:10

The two erase functions have the same parameters, but different return
value (void vs. iterator).

When optimizations are enabled or on 64-bit architectures, return values
are handled differently, so the problem does not necessarily appear.

Is linking together several object files compiled with different C++
versions not supported?

Thanks
-- 
Nico
#include "old.h"
#include "new.h"

using namespace std;

int main() {
    New_Map foo_new;
    Old_Map foo;
    foo_new.RemoveElements();
    foo.RemoveElements();
    return 0;
}
#include <map>
#include "new.h"

using namespace std;

New_Map::New_Map() {
    for(int i = 0; i < 20; i++) {
        iMap.insert(pair<int, int>(i, 2 * i));
    }
}

void New_Map::RemoveElements() {
    multimap<int, int>::iterator it = iMap.begin();
    iMap.erase(it);
}
#ifndef NEW_MAP_
#define NEW_MAP_ 1

#include <map>

class New_Map {
  public:
    void RemoveElements();
    New_Map();
  private:
    std::multimap<int, int> iMap;
};

#endif
#include <map>
#include "old.h"

using namespace std;

Old_Map::Old_Map() {
    for(int i = 0; i < 20; i++) {
        iMap.insert(pair<int, int>(i, 2 * i));
    }
}

void Old_Map::RemoveElements() {
    multimap<int, int>::iterator it = iMap.begin();
    iMap.erase(it);
}
#ifndef OLD_MAP_
#define OLD_MAP_ 1

#include <map>

class Old_Map {
  public:
    void RemoveElements();
    Old_Map();
  private: 
    std::multimap<int, int> iMap;
};

#endif

Attachment: build.sh
Description: Bourne shell script


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]