From: mcgrant@isl.stanford.edu (Michael C. Grant)
Subject: bug in template instantiation
Organization: GNUs Not Usenet
Distribution: gnu
Date: Thu, 5 Nov 1992 03:37:20 GMT

Version:
Reading specs from /usr/local/lib/gcc-lib/sparc/2.3.1/specs
gcc version 2.3.1
on a Sun sparc workstation

Bug in template instantiation: I have a 

template < class T, enum Types Tcode, const char* Name >

and the following INCORRECT C++ code crashes g++, saying

cd /u2/mcgrant/src/qdes/ver2/
g++ -DNOINLINE -c bug1.C
In file included from bug1.C:10:
qdesVarI.C:2: incorrect number of parameters (1, should be 3) in template expansion
/usr/local/bin/gcc: Internal compiler error: program cc1plus got fatal signal 11

Compilation exited abnormally with code 1 at Wed Nov  4 19:35:48

g++ -E -DNOINLINE qdesVar.C >! bug1.C

# 1 "qdesVar.C"
# 1 "qdesVar.H" 1


#pragma interface



# 1 "Variable.H" 1


#pragma inteface



class VarRep;
class VarCover;
class ostream;

enum Types { Typeless = 0, Int, Real, Cplx, String, RealPoly, CplxPoly, 
             RealRational, CplxRational, IntMatrix, IntRegVect,
             RealMatrix, CplxMatrix, StringMatrix, RealRegVect, CplxRegVect,
             RealPolyMatrix, CplxPolyMatrix, RealRationalMatrix,
             CplxRationalMatrix, TransferFunction, DynamicSystem, numTypes };

class varException {
    const char** strlist;
    int numstr;
    int active;
public:
    varException( void );
    varException( const char*, ... );
    operator int ( void ) const;
    friend ostream& operator << ( ostream&, varException& );
    void reset( void );
};

class VarRep {
public:
    VarRep( Types ntype );
    VarRep( const VarRep& p );
    virtual ~VarRep( void ) {}

    VarRep* ref( void );
    void    deref( void );
    int     shared( void ) const;
    virtual VarRep* clone( void ) const = 0;

    Types type( void ) const;
    virtual const char* typeName( void ) const = 0;
    virtual void output( ostream& ) const = 0;
    friend ostream& operator << ( ostream&, const VarRep& );
private:
    int refs;
    Types _type;
};

typedef VarRep* (*unaryOp)(const VarRep&);
struct unaryStruct {
    Types type;
    unaryOp fptr;
};

class unaryVtable {
    friend class unaryRegister;
    unaryOp funcs[numTypes];
protected:
    const char* name;
public:
    unaryVtable( const char* );
    VarRep* operator()( const VarRep* ) const;
    virtual VarRep* error( const VarRep* ) const = 0;
};

class unaryOperator : public unaryVtable {
public:
    unaryOperator( const char* );
    VarRep* error( const VarRep* ) const;
};

class unaryMethod : public unaryVtable {
    static VarRep* error( const VarRep& );
public:
    unaryMethod( const char* );
    VarRep* error( const VarRep* ) const;
};

class unaryRegister {
public:
    unaryRegister( unaryVtable&, const unaryStruct* );
};

typedef VarRep* (*binaryOp)(const VarRep&,const VarRep&);
struct binaryStruct {
    Types type1,type2;
    binaryOp fptr;
};

class binaryVtable {
    friend class binaryRegister;
    binaryOp funcs[numTypes][numTypes];
protected:
    const char* name;
public:
    binaryVtable( const char* );
    VarRep* operator()( const VarRep*, const VarRep* ) const;
    virtual VarRep* error( const VarRep*, const VarRep* ) const = 0;
};

class binaryRegister {
public:
    binaryRegister( binaryVtable&, const binaryStruct* );
};

class binaryOperator : public binaryVtable {
public:
    binaryOperator( const char* );
    VarRep* error( const VarRep*, const VarRep* ) const;
};

class binaryMethod : public binaryVtable {
public:
    binaryMethod( const char* );
    VarRep* error( const VarRep*, const VarRep* ) const;
};

class Variable {
public:
    static binaryOperator add, sub, mul, ldv, rdv, pow;
    static unaryOperator  neg;
    static unaryMethod    sqrt;
    static varException   exception;
};







# 7 "qdesVar.H" 2


template <class T,Types Tcode,const char* Name>
class qdesVar : public VarRep, public T {
public:
    qdesVar( const T& p ) : VarRep( Tcode ), T( p );
    qdesVar( const qdesVar& p ) : VarRep( Tcode ), T( p );
    
    VarRep* clone( void ) const;
    const char* typeName( void ) const;
    void output( ostream& ) const;
};

template <class T,Types Tcode, const char* Name>
class qdesBase : public VarRep {
    T data;
public:
    qdesBase( const T& p );
    qdesBase( const qdesBase& p );
    operator T& ( void );
    operator const T& ( void );

    VarRep* clone( void ) const;
    const char* typeName( void ) const;
    void output( ostream& cout ) const;
};






# 1 "qdesVar.C" 2

# 1 "RegVect.H" 1


#pragma interface



template <class T>
class RegVect {
    T start, finish, space;
    long len, len1;
public:
    RegVect( const T&, const T&, const T& );
    RegVect( const T&, const T&, long = -1 );

    T operator[]( int ndx );
    RegVect operator[]( int ndx1, int ndx2 );

    RegVect  operator+( const RegVect& ) const;
    RegVect& operator+=( const RegVect& );
    RegVect  operator+( const T& ) const;
    RegVect& operator+=( const T& );
    friend RegVect operator+( const T&, const RegVect& );

    RegVect  operator-( const RegVect& ) const;
    RegVect& operator-=( const RegVect& );
    RegVect  operator-( const T& ) const;
    RegVect& operator-=( const T& );
    friend RegVect operator-( const T&, const RegVect& );

    RegVect operator-( void ) const;

    RegVect operator*( const T& ) const;
    RegVect& operator*=( const T& );
    friend RegVect operator*( const T&, const RegVect& );

    RegVect operator/( const T& ) const;
    RegVect& operator/=( const T& );
};






# 2 "qdesVar.C" 2



#pragma implementation




# 1 "qdesVarI.C" 1
template <class T,Types Tcode,const char* Name>
  qdesVar<T>::qdesVar( const T& p ) : VarRep( Tcode ), T( p ) {}

template <class T,Types Tcode,const char* Name>
  qdesVar<T>::qdesVar( const qdesVar<T>& p )
: VarRep( Tcode ), T( p ) {}

template <class T,Types Tcode,const char* Name>
  qdesBase<T>::qdesBase( const T& p )
: VarRep( Tcode ), data(p) {}

template <class T,Types Tcode,const char* Name>
  qdesBase<T>::qdesBase( const qdesBase<T>& p )
: VarRep( Tcode ), data(p.data) {}

template <class T,Types Tcode,const char* Name>
  qdesBase<T>::operator T& ( void ) { return data; }

template <class T,Types Tcode,const char* Name>
  qdesBase<T>::operator const T& ( void ) { return data; }

# 10 "qdesVar.C" 2




template <class T,Types Tcode,const char* Name>
inline VarRep* qdesVar<T>::clone( void ) const { 
    return new qdesVar<T>( *this ); 
}

template <class T,Types Tcode,const char* Name>
inline const char* qdesVar<T>::typeName( void ) const { return Name; }

template <class T,Types Tcode,const char* Name>
inline void qdesVar<T>::output( ostream& cout ) const { 
    cout << *((const T*)this); 
}

template <class T,Types Tcode,const char* Name>
inline VarRep* qdesBase<T>::clone( void ) const { 
    return new qdesBase<T>( *this ); 
}

template <class T,Types Tcode,const char* Name>
inline const char* qdesBase<T>::typeName( void ) const { 
    return Name; 
}

template <class T,Types Tcode,const char* Name>
inline void qdesBase<T>::output( ostream& cout ) const { 
    cout << *((const T*)this); 
}

typedef qdesBase<long,Int,"integer scalar"> intScalar;
typedef qdesBase<double,Real,"real scalar"> realScalar;
typedef qdesBase<complex,Cplx,"complex scalar"> cplxScalar;

typedef qdesVar<RegVect<long>,IntRegVect,"integer regular vector"> intRegVect;
typedef qdesVar<RegVect<double>,RealRegVect,"real regular vector"> realRegVect;
typedef qdesVar<RegVect<complex>,CplxRegVect,"complex regular vector"> cplxRegVect;


Newsgroups: gnu.g++.bug