This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Internal compiler error for -fall-virtual for 2.95.2
- To: egcs-bugs at egcs dot cygnus dot com
- Subject: Internal compiler error for -fall-virtual for 2.95.2
- From: Mark Coletti <mcoletti at nmdrp332 dot er dot usgs dot gov>
- Date: Tue, 2 May 2000 16:45:55 -0400
- Cc: mcoletti at clark dot net, gcervone at gmu dot edu (Guido), lpanait at cs dot gmu dot edu (Liviu Alexandre)
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 )