Bug 28467 - Internal compiler error (ICE) with segmentation fault for valid C++ test case
Summary: Internal compiler error (ICE) with segmentation fault for valid C++ test case
Status: RESOLVED WORKSFORME
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 3.4.5
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-07-24 12:50 UTC by Prafull Thakare
Modified: 2011-05-11 10:24 UTC (History)
3 users (show)

See Also:
Host: i686-pc-linux
Target: sh*-unknown-linux
Build: i686-pc-linux
Known to work: 4.1.2, 4.4.3, 4.5.2, 4.6.0
Known to fail:
Last reconfirmed:


Attachments
test case (2.14 KB, text/plain)
2006-07-24 12:54 UTC, Prafull Thakare
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Prafull Thakare 2006-07-24 12:50:53 UTC
Hi,

I am working on a SH port with Gcc-3.4.5, and I am getting Internal Compiler 
Error( Segmentation Fault).
I have inlcuded a CPP test case that helps to reproduce this bug on 	
Fedora Core 2 when compiled with optimization option "-O2".

I have debugged the Gcc code for this particular test case and found that 	
in function 'fixup_match_2()' from file 'regmove.c', Gcc is trying to access 	
'call_used_regs' with in-valid index (i.e. pseudo register). 

Please refer to following code from 'regmove.c'.

/////////////////////////////////////////
if (call_used_regs[REGNO(dst)])
    || find_reg_fusage (p, CLOBBER, dst))
      break;
/////////////////////////////////////////

Here, I have noticed that, when the attached CPP test case is compiled with 		
optimization option "-O2", the "REGNO(dst)" returns pseudo register value 	
(i.e. 24647).

Therefore, on some OS platform like "Fedora Core 2", the above check results 		
into segmentation fault.	
Please note that, 'segmentation fault' may not occur on some other OS as the		
memory read requested by above check may fall within the allocated memory 		
space for executable 'cc1plus'.	

Please refer to following links, where similar behavior was reported 
for Gcc-4.0.2 also. 	
http://gcc.gnu.org/ml/gcc/2006-03/msg00318.html

The 'call_used_regs' is character array (for hard registers) with maximum size of 	
'FIRST_PSEUDO_REGISTER' (i.e. 153 for SH target). Refer to file 'regclass.c'.	

I have found a patch which adds a check for array index less than 'FIRST_PSEUDO_REGISTER',
	http://gcc.gnu.org/ml/gcc/2005-09/msg00368.html

However, I found that this patch is not accepted.	

Kindly let me know whether this patch is right fix for this bug.

Command used:
#sh-linux-gcc -m4 -ml -O2 testcase.cpp -c 

Test Case:
///////////////////////////////////////////////////////////////////////
namespace std
{
  template<typename _Alloc>
    class allocator;

  template<class _CharT>
    struct char_traits;
  
  template<typename _CharT, typename _Traits = char_traits<_CharT>,
           typename _Alloc = allocator<_CharT> >
    class basic_string;

  template<> struct char_traits<char>;

  typedef basic_string<char> string;
}

namespace __gnu_cxx
{
  template<typename _Tp>
    class new_allocator
    {
    public:
      typedef unsigned int size_type;
      new_allocator() throw() { }
      new_allocator(const new_allocator&) throw() { }
      ~new_allocator() throw() { }
    };
}
namespace std
{

  template<typename _Tp>
    class allocator: public __gnu_cxx::new_allocator<_Tp>
    {
   public:
      template<typename _Tp1>
        struct rebind
        {};
    };
}
namespace __gnu_cxx
{
  int  
  __attribute__ ((__unused__))
  __exchange_and_add(volatile int* __mem, int __val);

  void
  __attribute__ ((__unused__))
  __atomic_add(volatile int* __mem, int __val);
}

namespace std
{
  template<typename _CharT, typename _Traits, typename _Alloc>

    class basic_string
    {
    public:
     typedef typename _Alloc::size_type size_type;
    private:
      struct _Rep_base
      {
 size_type _M_length;
 size_type _M_capacity;
 int _M_refcount;
      };
      struct _Rep : _Rep_base
      {
        static size_type _Se_r_p[];
        static _Rep&
        _S_empty_rep()
        { return *reinterpret_cast<_Rep*>(&_Se_r_p); }

 _CharT*
 _M_refdata() throw()
 { return reinterpret_cast<_CharT*>(this + 1); }

 void
 _M_dispose(const _Alloc& __a)
 {

   if (__builtin_expect(this != &_S_empty_rep(), false))

     if (__gnu_cxx::__exchange_and_add(&this->_M_refcount, -1) <= 0)
       _M_destroy(__a);
 }

 void
 _M_destroy(const _Alloc&) throw();
      };

      struct _Alloc_hider : _Alloc
      {
 _Alloc_hider(_CharT* __dat, const _Alloc& __a)
 : _Alloc(__a), _M_p(__dat) { }

 _CharT* _M_p;
      };

    private:
      mutable _Alloc_hider _M_dataplus;

      _CharT*
      _M_data() const
      { return _M_dataplus._M_p; }

      _Rep*
      _M_rep() const
      { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }

      static _Rep&
      _S_empty_rep()
      { return _Rep::_S_empty_rep(); }

    public:

      inline
      basic_string();

      ~basic_string()
      { _M_rep()->_M_dispose(this->get_allocator()); }

      _Alloc
      get_allocator() const { return _M_dataplus; }
    };

  template<typename _CharT, typename _Traits, typename _Alloc>
    inline basic_string<_CharT, _Traits, _Alloc>::
    basic_string()

    : _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc()) { }
}

class CAbcDebugLog
{
  public:
 };

class My_Id
{
public:
 bool IsValid() const;
};

namespace abc{
enum ME_IS
{
    PST,
    
};
}

namespace abc {
enum UI_ERROR
{
  };
}

namespace abc {
enum MY_CODE{};
}


class Two_up 
{
public:

    bool CanCO(const My_Id &id, const abc::MY_CODE &tgtMw, abc::UI_ERROR &err);

    bool RemainCOCount( const My_Id &id, unsigned char & count );

    bool IsIt( const My_Id& a1, const My_Id& a2 );
};

namespace std
{
  template<typename _Tp, typename _Alloc>
    struct _Vector_base
    {
      struct _Vector_impl: public _Alloc {
      };
    };

  template<typename _Tp, typename _Alloc = allocator<_Tp> >

    class vector : protected _Vector_base<_Tp, _Alloc>
    {};
}

using namespace std;

//class CCstrCommon {};

class CCstr {
  private:
// CCstrCommon* m_pCommonStr;
 int Chk(const char* str);
  public:
 CCstr();
 ~CCstr();
};

namespace ABCD {
   typedef std::string FFP;
    enum LT_IS {
        LT_A =0,
    };

    enum ERROR {
       ER_OK =0x0,
    };

    struct MY_TIME {
        MY_TIME():hour(0),min(0),sec(0),msec(0),is(LT_A){}
        MY_TIME(unsigned short h,unsigned short m,unsigned short s,unsigned short ms, LT_IS l=LT_A)
            :hour(h),min(m),sec(s),msec(ms),is(l){}
        unsigned short hour;
        unsigned short min;
        unsigned short sec;
        unsigned short msec;
        LT_IS is;
        MY_TIME& operator-=( MY_TIME time){
            return *this;
        }
    };

    struct DATE {
        DATE():year(0){}
        unsigned short year;
    };

    enum HFT {
        HFU = -1,
    };

    typedef CCstr HT;
    typedef vector<ABCD::HT> HT_LIST;

    typedef std::string FILE_NAME;
    typedef std::string GF_URLNAME;

    struct SOME_NO {
        unsigned short rootNo;
        unsigned short folderNo;
        unsigned short RepNo;
        unsigned short aNo;

        SOME_NO(){ Init(); }
        void Init(){ aNo = RepNo = folderNo = rootNo = 0; }

      bool IsNull(void) const {}
      bool IsA(void) const{}
      bool operator ==(const SOME_NO &ctNo)const{}
    };

    enum GF_SOURCE_TYPE {
        GF_SOURCE_OTHER = 0,
    };

    struct GF_SOME {
        GF_SOME():formatType(HFU),
                        srcType(GF_SOURCE_OTHER),
                        rTimesRest(false),
                        rTermRest(false),
                        notDel(false),
                        readOnly(false),
                        coutNum(0),
                        netMdCheckout(true),
                        pk(0),
                        rms(0),
                        gnsd(0){}
        ABCD::SOME_NO contentNo;
        ABCD::HT tilt;
        ABCD::HT built;
        ABCD::HT genre;
        ABCD::MY_TIME totalTime;
        ABCD::HFT formatType;
        ABCD::GF_SOURCE_TYPE srcType;

        bool rTimesRest;
        bool rTermRest;
        bool notDel;
        bool readOnly;
        unsigned char coutNum;
        bool netMdCheckout;
        unsigned short chairs;
        unsigned short pk;
        unsigned short rms;
        unsigned short gnsd;
	ABCD::FFP orgcrt;
        ABCD::FFP jistS;
        ABCD::FFP jistM;
        ABCD::FFP xOrgcrt;
        ABCD::FFP xcrtS;
        ABCD::FFP xcrtM;
    };

    struct GF_SOME_DETAIL : GF_SOME {
      unsigned long fileSize;
        ABCD::HT label,tiltNR,xTl,xNR,gne,bNR;
	ABCD::DATE cD;
    };
};

class Pqr {
public:
    enum ERROR {
       ER_OK = ABCD::ER_OK,
    } ;
    typedef ABCD::GF_SOME SOME;
    typedef ABCD::GF_SOME_DETAIL SOME_DETAIL;
    static Pqr *Instance(void);
    virtual ERROR GetInfo(ABCD::SOME_NO contentNo, SOME *Info)=0;
};

class SomeUtility
{
public:
    static ABCD::SOME_NO SomeId( const My_Id &contentId );
};

bool Two_up::CanCO( const My_Id &id, const abc::MY_CODE &tgtMw,abc::UI_ERROR &err )
{
    Pqr::SOME Info;
    return ( 0);
}

bool Two_up::RemainCOCount(const My_Id & id,unsigned char& cnt)
{
    Pqr::SOME Info;
}

bool Two_up::IsIt ( const My_Id& a1, const My_Id& a2 )
{
    Pqr* pMW = Pqr::Instance();
    ABCD::SOME_NO tNo1 = SomeUtility::SomeId(a1);
    ABCD::SOME_NO tNo2 = SomeUtility::SomeId(a2);
    Pqr::ERROR retval = Pqr::ER_OK;
    abc::ME_IS meIs;
    Pqr::SOME tInfo1;
    Pqr::SOME tInfo2;

    if(a1.IsValid() == false) {
        retval = pMW->GetInfo(tNo2, &tInfo2);
        if( retval != Pqr::ER_OK ) 
            return false;
      if(abc::PST == meIs) 
            return false;
        if( retval == Pqr::ER_OK ) 
            return true;
         else 
            return false;
    }
    if(a2.IsValid() == false) {
       if(abc::PST == meIs) 
            return false;
        if( retval == Pqr::ER_OK ) 
           return true;
         else 
            return false;
    }
    if( retval != Pqr::ER_OK ) 
        return false;
    if( retval != Pqr::ER_OK ) 
        return false;
    Pqr::SOME_DETAIL Info1;
    Pqr::SOME_DETAIL Info2;
}
///////////////////////////////////////////////////////////////////////

Regards,
Prafulla Thakare
KPIT Cummins InfoSystems Ltd.
Pune, India

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Free download of GNU based tool-chains for Renesas' SH, H8 and M16 	
Series. The following site also offers free technical support to 	
its users. Visit http://www.kpitgnutools.com for details. 
Latest versions of KPIT GNU tools are released on June 1, 2006. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Comment 1 Prafull Thakare 2006-07-24 12:54:24 UTC
Created attachment 11927 [details]
test case
Comment 2 Jonathan Wakely 2011-05-11 10:24:19 UTC
no ICE in current releases