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