This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


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

Internal compiler error for -fall-virtual for 2.95.2


I have been unable to get g++ 2.95.2 to emit all the binary for a sub-class. 
I've used objdump and nm to verify that the typeinfo, virtual tables,
constructors, and some member functions are not emitted.  In an attempt to
discover a work-around for this bug, I tried using -fall-virtual, which yielded
the following error:


mcoletti@nmdrp332~/projects/gmu/miniAQ:149> gmake Attribute.o
c++ -DPACKAGE=\"miniAQ\" -DVERSION=\"0.0\" -DYYTEXT_POINTER=1  -I. -I/home/mcoletti/include -I./boost    -ggdb3 -fall-virtual -c Attribute.cpp
In file included from /usr/include/g++-2/std/bastring.h:36,
                 from /usr/include/g++-2/string:6,
                 from Attribute.h:10,
                 from Attribute.cpp:5:
/usr/include/g++-2/std/straits.h:132: Internal compiler error.
/usr/include/g++-2/std/straits.h:132: Please submit a full bug report to `egcs-bugs@egcs.cygnus.com'.
/usr/include/g++-2/std/straits.h:132: See <URL:http://egcs.cygnus.com/faq.html#bugreport> for details.
gmake: *** [Attribute.o] Error 1


I've attached the minimal set of source files needed to reproduce the error. 
An Attribute.o built by these source files will have incomplete binaries and
tables for AttributeNominal.

Cheers!

Mark
-- 
  mailto:mcoletti+nospam@clark.net | http://www.clark.net/~mcoletti
Pauli's exclusive, Heisenberg's uncertain, and Schroedinger just waves.
//  Boost smart_ptr.hpp header file  -----------------------------------------//

//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. Permission to copy,
//  use, modify, sell and distribute this software is granted provided this
//  copyright notice appears in all copies. This software is provided "as is"
//  without express or implied warranty, and with no claim as to its
//  suitability for any purpose.

//  See http://www.boost.org for most recent version including documentation.

//  Revision History
//   1 Feb 00  Additional shared_ptr BOOST_NO_MEMBER_TEMPLATES workarounds
//             (Dave Abrahams)
//  31 Dec 99  Condition tightened for no member template friend workaround
//             (Dave Abrahams)
//  30 Dec 99  Moved BOOST_NMEMBER_TEMPLATES compatibility code to config.hpp
//             (Dave Abrahams)
//  30 Nov 99  added operator ==, operator !=, and std::swap and std::less
//             specializations for shared types (Darin Adler)
//  11 Oct 99  replaced op[](int) with op[](std::size_t) (Ed Brey, Valentin
//             Bonnard), added shared_ptr workaround for no member template
//             friends (Matthew Langston)
//  25 Sep 99  added shared_ptr::swap and shared_array::swap (Luis Coelho).
//  20 Jul 99  changed name to smart_ptr.hpp, #include <boost/config.hpp>,
//             #include <boost/utility.hpp> and use boost::noncopyable
//  17 May 99  remove scoped_array and shared_array operator*() as
//             unnecessary (Beman Dawes)
//  14 May 99  reorder code so no effects when bad_alloc thrown (Abrahams/Dawes)
//  13 May 99  remove certain throw() specifiers to avoid generated try/catch
//             code cost (Beman Dawes)
//  11 May 99  get() added, conversion to T* placed in macro guard (Valentin
//             Bonnard, Dave Abrahams, and others argued for elimination
//             of the automatic conversion)
//  28 Apr 99  #include <memory> fix (Valentin Bonnard)
//  28 Apr 99  rename transfer() to share() for clarity (Dave Abrahams)
//  28 Apr 99  remove unsafe shared_array template conversions(Valentin Bonnard)
//  28 Apr 99  p(r) changed to p(r.px) for clarity (Dave Abrahams)
//  21 Apr 99  reset() self assignment fix (Valentin Bonnard)
//  21 Apr 99  dispose() provided to improve clarity (Valentin Bonnard)
//  27 Apr 99  leak when new throws fixes (Dave Abrahams)
//  21 Oct 98  initial Version (Greg Colvin/Beman Dawes)

#ifndef BOOST_SMART_PTR_HPP
#define BOOST_SMART_PTR_HPP

#include <boost/config.hpp>   // for broken compiler workarounds
#include <cstddef>            // for std::size_t
#include <memory>             // for std::auto_ptr
#include <algorithm>          // for std::swap
#include <boost/utility.hpp>  // for boost::noncopyable
#include <functional>         // for std::less

namespace boost {

//  scoped_ptr  --------------------------------------------------------------//

//  scoped_ptr mimics a built-in pointer except that it guarantees deletion
//  of the object pointed to, either on destruction of the scoped_ptr or via
//  an explicit reset().  scoped_ptr is a simple solution for simple needs;
//  see shared_ptr (below) or std::auto_ptr if your needs are more complex.

template<typename T> class scoped_ptr : noncopyable {

  T* ptr;

 public:
  typedef T element_type;

  explicit scoped_ptr( T* p=0 ) throw() : ptr(p) {}
  ~scoped_ptr()                 { delete ptr; }

  void reset( T* p=0 )          { if ( ptr != p ) { delete ptr; ptr = p; } }
  T& operator*() const throw()  { return *ptr; }
  T* operator->() const throw() { return ptr; }
  T* get() const throw()        { return ptr; }
#ifdef BOOST_SMART_PTR_CONVERSION
  // get() is safer! Define BOOST_SMART_PTR_CONVERSION at your own risk!
  operator T*() const throw()   { return ptr; } 
#endif
  };  // scoped_ptr

//  scoped_array  ------------------------------------------------------------//

//  scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to
//  is guaranteed, either on destruction of the scoped_array or via an explicit
//  reset(). See shared_array or std::vector if your needs are more complex.

template<typename T> class scoped_array : noncopyable {

  T* ptr;

 public:
  typedef T element_type;

  explicit scoped_array( T* p=0 ) throw() : ptr(p) {}
  ~scoped_array()                    { delete [] ptr; }

  void reset( T* p=0 )               { if ( ptr != p ) {delete [] ptr; ptr=p;} }

  T* get() const throw()             { return ptr; }
#ifdef BOOST_SMART_PTR_CONVERSION
  // get() is safer! Define BOOST_SMART_PTR_CONVERSION at your own risk!
  operator T*() const throw()        { return ptr; }
#else 
  T& operator[](std::size_t i) const throw() { return ptr[i]; }
#endif
  };  // scoped_array

//  shared_ptr  --------------------------------------------------------------//

//  An enhanced relative of scoped_ptr with reference counted copy semantics.
//  The object pointed to is deleted when the last shared_ptr pointing to it
//  is destroyed or reset.

template<typename T> class shared_ptr {
  public:
   typedef T element_type;

   explicit shared_ptr(T* p =0) : px(p) {
      try { pn = new long(1); }  // fix: prevent leak if new throws
      catch (...) { delete p; throw; } 
   }

   shared_ptr(const shared_ptr& r) throw() : px(r.px) { ++*(pn = r.pn); }

   ~shared_ptr() { dispose(); }

   shared_ptr& operator=(const shared_ptr& r) {
      share(r.px,r.pn);
      return *this;
   }

#if !defined( BOOST_NO_MEMBER_TEMPLATES )
   template<typename Y>
      shared_ptr(const shared_ptr<Y>& r) throw() : px(r.px) { 
         ++*(pn = r.pn); 
      }

   template<typename Y>
      shared_ptr(std::auto_ptr<Y>& r) { 
         pn = new long(1); // may throw
         px = r.release(); // fix: moved here to stop leak if new throws
      } 

   template<typename Y>
      shared_ptr& operator=(const shared_ptr<Y>& r) { 
         share(r.px,r.pn);
         return *this;
      }

   template<typename Y>
      shared_ptr& operator=(std::auto_ptr<Y>& r) {
         // code choice driven by guarantee of "no effect if new throws"
         if (*pn == 1) { delete px; }
         else { // allocate new reference counter
           long * tmp = new long(1); // may throw
           --*pn; // only decrement once danger of new throwing is past
           pn = tmp;
         } // allocate new reference counter
         px = r.release(); // fix: moved here so doesn't leak if new throws 
         return *this;
      }
#else
      shared_ptr(std::auto_ptr<T>& r) { 
         pn = new long(1); // may throw
         px = r.release(); // fix: moved here to stop leak if new throws
      } 

      shared_ptr& operator=(std::auto_ptr<T>& r) {
         // code choice driven by guarantee of "no effect if new throws"
         if (*pn == 1) { delete px; }
         else { // allocate new reference counter
           long * tmp = new long(1); // may throw
           --*pn; // only decrement once danger of new throwing is past
           pn = tmp;
         } // allocate new reference counter
         px = r.release(); // fix: moved here so doesn't leak if new throws 
         return *this;
      }
#endif

   void reset(T* p=0) {
      if ( px == p ) return;  // fix: self-assignment safe
      if (--*pn == 0) { delete px; }
      else { // allocate new reference counter
        try { pn = new long; }  // fix: prevent leak if new throws
        catch (...) {
          ++*pn;  // undo effect of --*pn above to meet effects guarantee 
          delete p;
          throw;
        } // catch
      } // allocate new reference counter
      *pn = 1;
      px = p;
   } // reset

   T& operator*() const throw()  { return *px; }
   T* operator->() const throw() { return px; }
   T* get() const throw()        { return px; }
 #ifdef BOOST_SMART_PTR_CONVERSION
   // get() is safer! Define BOOST_SMART_PTR_CONVERSION at your own risk!
   operator T*() const throw()   { return px; } 
 #endif

   long use_count() const throw(){ return *pn; }
   bool unique() const throw()   { return *pn == 1; }

   void swap(shared_ptr<T>& other) throw()
     { std::swap(px,other.px); std::swap(pn,other.pn); }

// Tasteless as this may seem, making all members public allows member templates
// to work in the absence of member template friends. (Matthew Langston)
#if defined(BOOST_NO_MEMBER_TEMPLATES) \
    || !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS )
   private:
#endif

   T*     px;     // contained pointer
   long*  pn;     // ptr to reference counter

#if !defined( BOOST_NO_MEMBER_TEMPLATES ) \
    && !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS )
   template<typename Y> friend class shared_ptr;
#endif

   void dispose() { if (--*pn == 0) { delete px; delete pn; } }

   void share(T* rpx, long* rpn) {
      if (pn != rpn) {
         dispose();
         px = rpx;
         ++*(pn = rpn);
      }
   } // share
};  // shared_ptr

template<typename T, typename U>
  inline bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b)
    { return a.get() == b.get(); }

template<typename T, typename U>
  inline bool operator!=(const shared_ptr<T>& a, const shared_ptr<U>& b)
    { return a.get() != b.get(); }

//  shared_array  ------------------------------------------------------------//

//  shared_array extends shared_ptr to arrays.
//  The array pointed to is deleted when the last shared_array pointing to it
//  is destroyed or reset.

template<typename T> class shared_array {
  public:
   typedef T element_type;

   explicit shared_array(T* p =0) : px(p) {
      try { pn = new long(1); }  // fix: prevent leak if new throws
      catch (...) { delete [] p; throw; } 
   }

   shared_array(const shared_array& r) throw() : px(r.px) { ++*(pn = r.pn); }

   ~shared_array() { dispose(); }

   shared_array& operator=(const shared_array& r) {
      if (pn != r.pn) {
         dispose();
         px = r.px;
         ++*(pn = r.pn);
      }
      return *this;
   } // operator=

   void reset(T* p=0) {
      if ( px == p ) return;  // fix: self-assignment safe
      if (--*pn == 0) { delete [] px; }
      else { // allocate new reference counter
        try { pn = new long; }  // fix: prevent leak if new throws
        catch (...) {
          ++*pn;  // undo effect of --*pn above to meet effects guarantee 
          delete [] p;
          throw;
        } // catch
      } // allocate new reference counter
      *pn = 1;
      px = p;
   } // reset

   T* get() const throw()             { return px; }
 #ifdef BOOST_SMART_PTR_CONVERSION
   // get() is safer! Define BOOST_SMART_PTR_CONVERSION at your own risk!
   operator T*() const throw()        { return px; }
 #else 
   T& operator[](std::size_t i) const throw() { return px[i]; }
 #endif

   long use_count() const throw()     { return *pn; }
   bool unique() const throw()        { return *pn == 1; }

   void swap(shared_array<T>& other) throw()
     { std::swap(px,other.px); std::swap(pn,other.pn); }

  private:

   T*     px;     // contained pointer
   long*  pn;     // ptr to reference counter

   void dispose() { if (--*pn == 0) { delete [] px; delete pn; } }

};  // shared_array

template<typename T>
  inline bool operator==(const shared_array<T>& a, const shared_array<T>& b)
    { return a.get() == b.get(); }

template<typename T>
  inline bool operator!=(const shared_array<T>& a, const shared_array<T>& b)
    { return a.get() != b.get(); }

} // namespace boost

//  specializations for things in namespace std  -----------------------------//

#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

namespace std {

// Specialize std::swap to use the fast, non-throwing swap that's provided
// as a member function instead of using the default algorithm which creates
// a temporary and uses assignment.

template<typename T>
  inline void swap(boost::shared_ptr<T>& a, boost::shared_ptr<T>& b)
    { a.swap(b); }

template<typename T>
  inline void swap(boost::shared_array<T>& a, boost::shared_array<T>& b)
    { a.swap(b); }

// Specialize std::less so we can use shared pointers and arrays as keys in
// associative collections.

// It's still a controversial question whether this is better than supplying
// a full range of comparison operators (<, >, <=, >=).

template<typename T>
  struct less< boost::shared_ptr<T> >
    : binary_function<boost::shared_ptr<T>, boost::shared_ptr<T>, bool>
  {
    bool operator()(const boost::shared_ptr<T>& a,
        const boost::shared_ptr<T>& b) const
      { return less<T*>()(a.get(),b.get()); }
  };

template<typename T>
  struct less< boost::shared_array<T> >
    : binary_function<boost::shared_array<T>, boost::shared_array<T>, bool>
  {
    bool operator()(const boost::shared_array<T>& a,
        const boost::shared_array<T>& b) const
      { return less<T*>()(a.get(),b.get()); }
  };

} // namespace std

#endif  // ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

#endif  // BOOST_SMART_PTR_HPP

//
// Attribute.h
//
// $Id: Attribute.h,v 1.13 2000/05/02 04:29:15 mcoletti Exp $
//

#ifndef ATTRIBUTE_H
#define ATTRIBUTE_H

#include <string>
#include <map>

#include <cassert>

#include <boost/smart_ptr.hpp>


class ostream;


class Attribute  
{
   public:
	
      Attribute() 
         : cost_( 1 ),          // XXX what does a cost of 1 mean?
         id_( "" )
      {}

      Attribute( std::string const & id, 
                 int cost = 1 )
         : cost_( cost ),       // XXX what does a cost of 1 mean?
         id_( "" )
      {}

      virtual ~Attribute() {}

    
      int  cost() const;	
      // return the attribute cose
    
      void cost( int );
      // set the attribute cost


      std::string const & id() const   { return id_; }
      // return the attribute id or name

      void id( std::string const &id ) { id_ = id; }
      // set the attribute id


      void print( ostream & ) const;


      virtual void addFeature( std::string const & feature ) = 0;
      // add a new feature to the attribute


   protected:

      virtual void print_( ostream& ) const = 0;
      /// over-ridden by children and invoked by print()


   private:

      int         cost_;
      std::string id_;

      friend ostream& operator<<( ostream &, Attribute const & );

}; // Attribute




class AttributeNominal : public Attribute  
{
   public:
    
      ~AttributeNominal() {}
    
      void addFeature( std::string const & feature );
      // add a new feature to the attribute

      int  domainSize() const;
      // essentially the number of bits needed to represent all the
      // features

   protected:

      void print_( ostream & ) const;
    

   private:

      std::map< std::string, int > feature_map_;
      //
      // this is used to map a feature name to a binary position; each
      // addFeature call will take the given string and assign it to
      // this map with the feature_map_.size()'th bit position for the
      // AtomNominals that will belong to this attribute

      int foo_;

}; // class AttributeNominal




class AttributeContinuous : public Attribute  
{
   public:

      AttributeContinuous()
         : lower_bound_( -1.0 ),
           upper_bound_( 1.0 )
      {}

      AttributeContinuous( std::string const & id )
         : Attribute( id ),
           lower_bound_( -1.0 ),
           upper_bound_( 1.0 )
      {}

      AttributeContinuous( std::string const & id, 
                           double lb, 
                           double ub )
         : Attribute( id ),
           lower_bound_( lb ),
           upper_bound_( ub )
      {}

      ~AttributeContinuous() {}
    
      void   lowerBound( double lb );
      double lowerBound() const;
    
      void   upperBound( double ub ); 
      double upperBound() const;
    
      void addFeature( std::string const & feature )
      {
         // XXX temporarily a NOP
      }

   protected:

      void print_( ostream & ) const;


   private:

      double   lower_bound_;
      double   upper_bound_;

}; // class AttributeContinuous




typedef boost::shared_ptr<Attribute> AttributePtr;
// reference counted smart pointer used for heterogenous containers of
// attributes




#endif 
//
// Attribute.cpp
//

#include "Attribute.h"

#include <iostream>


static const char* ident_ = 
   "$Id: Attribute.cpp,v 1.5 2000/05/02 04:29:15 mcoletti Exp $";


//
// Attribute
//

int
Attribute::cost() const
{
   return cost_;
} // Attribute::getCost()


void
Attribute::cost( int cost )
{
   cost_ = cost;
} // Attribute::setCost



void
Attribute::print( ostream & os ) const
{
   os << id() << ": " << "cost( " << cost() << " )";

   print_( os );                // child specific information
} // Attribute::print( ostream & os )



ostream&
operator<<( ostream& os, Attribute const & attribute )
{
   attribute.print( os );

   return os;
} // operator<<( Attribute )



//
// AttributeContinous
//

double
AttributeContinuous::upperBound() const
{
   return upper_bound_;
} // AttributeContinuous::upperBound()


void
AttributeContinuous::upperBound( double ub )
{
   upper_bound_ = ub;
} // AttributeContinuous::upperBound


double
AttributeContinuous::lowerBound() const
{
   return lower_bound_;
} // AttributeContinuous::lowerBound()


void
AttributeContinuous::lowerBound( double lb )
{
   lower_bound_ = lb;
} // AttributeContinuous::lowerBound


void
AttributeContinuous::print_( ostream & os ) const
{
   os << "continuous [" 
      << lower_bound_
      << ".."
      << upper_bound_
      << "]\n";

} // AttributeContinuous::print( ostream & os )


//
// AttributeNominal
//

int
AttributeNominal::domainSize() const
{
   return feature_map_.size();
} // AttributeNominal::domainSize() const


void
AttributeNominal::print_( ostream & os ) const
{
   std::map< std::string, int >::const_iterator i = 
      feature_map_.begin();

   os << "nominal\n";

   for ( ; i != feature_map_.end(); i++ )
   {
      os << "\t" << i->first << " <- " << i->second << "\n";
   }

} // AttributeNominal::print( ostream & os )

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