c++/2784: gcc emits duplicate assembly symbol (regression from gcc 2.95)

snyder@fnal.gov snyder@fnal.gov
Tue May 8 23:16:00 GMT 2001


>Number:         2784
>Category:       c++
>Synopsis:       gcc emits duplicate assembly symbol (regression from gcc 2.95)
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          wrong-code
>Submitter-Id:   net
>Arrival-Date:   Tue May 08 23:16:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     scott snyder
>Release:        3.0 20010507 (prerelease)
>Organization:
>Environment:
System: Linux karma 2.2.16-22 #1 Tue Aug 22 16:49:06 EDT 2000 i686 unknown
Architecture: i686

	
host: i686-pc-linux-gnu
build: i686-pc-linux-gnu
target: i686-pc-linux-gnu
configured with: ../egcs/configure --prefix=/usr/local/egcs --enable-threads=posix --enable-long-long
>Description:

When i compile the compile the source below, gcc emits the symbol
`fabs' twice, causing an assembler error:

$ g++ -c x.cc
/tmp/ccPAnMzA.s: Assembler messages:
/tmp/ccPAnMzA.s:491: Fatal error: Symbol fabs already defined.
$ g++ -c x.cc -S
$ grep fabs x.s
        call    fabs
        call    fabs
        .section        .gnu.linkonce.t.fabs,"ax",@progbits
        .weak   fabs
        .type   fabs,@function
fabs:
        fabs
        .size   fabs,.Lfe7-fabs
        .weak   fabs
        .type   fabs,@function
fabs:
        fabs
        .size   fabs,.Lfe8-fabs
$

>How-To-Repeat:

extern "C" {
  inline double fabs (double __x) throw()
  { return __builtin_fabs (__x); }
}


namespace std 
{
  inline double 
  fabs(double __x) { return __builtin_fabs(__x); }
}








typedef int _Atomic_word;

static inline _Atomic_word 
__attribute__ ((__unused__))
__exchange_and_add (volatile _Atomic_word *__mem, int __val)
{
  register _Atomic_word __result;
  __asm__ __volatile__ ("lock; xaddl %0,%2"
			: "=r" (__result) 
                        : "0" (__val), "m" (*__mem) 
                        : "memory");
  return __result;
}






namespace std {

class allocator {
public:
  allocator() throw() {}
  allocator(const allocator&) throw() {}
  ~allocator() throw() {}
};


  template<typename _CharT>
    class basic_string
    {
    private:
      struct _Rep
      {
	_Atomic_word		_M_references;
	
	void 
	_M_dispose(const allocator& __a)
	{ 
	  if (__exchange_and_add(&_M_references, -1) <= 0)  
	    _M_destroy(); 
	}

	void 
	_M_destroy();
      };

      struct allocator_hider : allocator
      {
	char* _M_p; // The actual data.
      };


    private:
      mutable allocator_hider 	_M_dataplus;


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


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


    public:

      basic_string(const char* __s, const allocator& __a = allocator());

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



    public:


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


} // namespace std




class Hep3Vector {

public:

  Hep3Vector () : dx(0), dy(0) {}
  ~Hep3Vector() {}

  double dx;
  double dy;
};




class SpaceVector : public Hep3Vector {
public:
  SpaceVector(double x=0, double y=0)  {}
  ~SpaceVector() {}
}; // SpaceVector



class SpacePath
{
public:  // methods
  double dx( ) const;
  double dy( ) const;
};



class TrfVector {};


class PtrException {
public:
  PtrException(std::basic_string<char> message= "");
};



class Surface
{
public:
  virtual int get_pure_type() const = 0;
};


template<class T>
class Ptr {
public:
  Surface* _point;

  bool is_valid() const {
    return _point!=0;
  }

  Surface* pointer() const { 
    if ( _point ) return _point;
    else return 0;
  }



  Surface* operator->() const
  {
    if ( ! is_valid() ) throw PtrException();
    return pointer();
  }
  

};


typedef Ptr<Surface> SurfacePtr;


class VTrack
{

public:
  SurfacePtr _psrf;
  TrfVector _vec;


  virtual ~VTrack();


  const SurfacePtr& get_surface( ) const { 
    return _psrf;
  };
  const TrfVector& get_vector() const { return _vec; };
  SpacePath space_vector() const;
};



class VTrackParameters 
{
public:
  VTrackParameters(VTrack *track);
  virtual ~VTrackParameters () {}
  VTrack* _track;
  SpaceVector			m_momentum;
  int				m_charge;
};


inline
VTrackParameters::VTrackParameters(VTrack *track)
  :  _track(track)
{
  if( track->get_surface()->get_pure_type() == 1 ) {

    TrfVector tvec = _track->get_vector();
    double qpt = 0;
    m_charge = static_cast<int> (fabs(qpt));
     
    SpacePath path = _track->space_vector();
    SpaceVector vec = SpaceVector(path.dx(), path.dy());
    m_momentum = 0;

  } else if(track->get_surface()->get_pure_type() == 2) {
    
    TrfVector tvec = _track->get_vector();
    double qpt = 2;
    m_charge = static_cast<int> (fabs(qpt));
  }
}




void
vec_dir_prop(VTrack &trv)
{
  VTrackParameters tim_track(&trv);
}



>Fix:
	
>Release-Note:
>Audit-Trail:
>Unformatted:



More information about the Gcc-bugs mailing list