C++ Inliner Bug?
Gerald Pfeifer
pfeifer@dbai.tuwien.ac.at
Wed Mar 1 07:25:00 GMT 2000
I came across what might be a C++ inliner bug.
Compiled with GCC 2.95 -O1 and current CVS -O1 -fno-inline the heavily
destilled example below works fine, with current CVS -O1, however, the
objects destructed are not those that have been constructed:
NAMES_ITEM(const char*) "one" (this=0xbfbfd940, name=0x8062030)
-> NAMES_ITEM(NAMES_ITEM&) "one" (this=0xbfbfd910, name=0x8062040)
NAMES_ITEM(NAMES_ITEM&) "one" (this=0xbfbfd920, name=0x8062050)
NAMES_ITEM(NAMES_ITEM&) "one" (this=0x8061028, name=0x8062060)
~NAMES_ITEM() "one" (this=0xbfbfd920, name=0x8062050)
-> ~NAMES_ITEM() " (this=0xbfbfd910, name=0x8061018)
-> a.out in free(): warning: modified (chunk-) pointer.
~NAMES_ITEM() "one" (this=0xbfbfd940, name=0x8062030)
~NAMES_ITEM() "one" (this=0x8061028, name=0x8062060)
Tested on sparc-sun-solaris2.6 with todays CVS sources and
i386-unknown-freebsdelf3.3 with CVS sources dated February 25th.
If you #define AVOID, the problems goes away.
Gerald
-------- cut --------
#include <map>
#include <string>
#include <vector>
template <class T>
class NAMESTABLE
{
public:
typedef size_t index_t;
private:
typedef map<T,index_t,less<T> > lookup_t;
lookup_t lookup;
public:
NAMESTABLE() : lookup()
{
}
pair<index_t,bool> add(const T &item)
{
pair<typename lookup_t::const_iterator,bool> result;
#ifndef AVOID
result = lookup.insert(pair<T,index_t>(item,0));
#else
pair<T,index_t> pp(item,0);
result = lookup.insert(pp);
#endif
return pair<index_t,bool>(0,result.second);
}
};
//////////////////////////////////////////////////////////////////////////////
class NAMES_ITEM
//
{
public:
char *name;
NAMES_ITEM()
{
assert( 0 );
}
NAMES_ITEM(const NAMES_ITEM& item2)
{
size_t length=strlen(item2.name);
name=new char[length+1];
memcpy(name,item2.name,length+1);
cerr << " NAMES_ITEM(NAMES_ITEM&) ";
printDebug(cerr);
}
NAMES_ITEM(const char* name2)
{
size_t length=strlen(name2);
name=new char[length+1];
memcpy(name,name2,length+1);
cerr << " NAMES_ITEM(const char*) ";
printDebug(cerr);
}
~NAMES_ITEM()
{
cerr << " ~NAMES_ITEM() ";
printDebug(cerr);
delete[] name;
name=0;
}
void operator=(const NAMES_ITEM&)
{
assert( 0 );
}
bool operator==(const NAMES_ITEM& n) const
{
return (strcmp(name,n.name) == 0);
}
void NAMES_ITEM::printDebug(ostream &out) const
{
out << '\"' << name << '\"'
<< " (this=" << (const void*)this
<< ", name=" << (const void*)name << ") "
<< endl;
}
};
inline bool operator<(const NAMES_ITEM& n1, const NAMES_ITEM& n2)
{
return (strcmp(n1.name,n2.name) < 0);
}
main()
{
NAMESTABLE<NAMES_ITEM> P;
P.add("one");
P.add("two");
}
More information about the Gcc-bugs
mailing list