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]

Compiler bug -- egcs-2.90.27 (egcs-1.0.2 release)



The inclusion of hash_util.h, listed below, causes an "Internal compiler error". 
It will compile if the union declaration is moved outside of the compute_hash 
method.

By the way, this code compiled with previous version of the GNU C++ compiler 
(g++ version 2.7.2.3).

\Desmond


hash_util.h: In method `unsigned int Hash<T>::compute_hash(char *)':
In file included from ucp.h:85,
                 from uca_tok.cpp:194:
hash_util.h:69: Internal compiler error.
hash_util.h:69: Please submit a full bug report to gcs-bugs@cygnus.com'.

Distribution:	RedHat 5.1(intel)/Linux
Compiler:	egcs-2.90.27 980315 (egcs-1.0.2 release)
To re-reproduce: g++ -o foo foo.cpp
	

==================== foo.cpp =====================
#include <iostream.h>
#include "hash_util.h"

int main(int argc, char **argv)
{
   return(0);
}


====================== hash_util.h ====================

/*----------------------------------------------------------------------------
 *                                                                      
 *                  I N T E L   P R O P R I E T A R Y                   
 *                                                                      
 *     COPYRIGHT (c)  1998 BY  INTEL  CORPORATION.  ALL RIGHTS          
 *     RESERVED.   NO  PART  OF THIS PROGRAM  OR  PUBLICATION  MAY      
 *     BE  REPRODUCED,   TRANSMITTED,   TRANSCRIBED,   STORED  IN  A    
 *     RETRIEVAL SYSTEM, OR TRANSLATED INTO ANY LANGUAGE OR COMPUTER    
 *     LANGUAGE IN ANY FORM OR BY ANY MEANS, ELECTRONIC, MECHANICAL,    
 *     MAGNETIC,  OPTICAL,  CHEMICAL, MANUAL, OR OTHERWISE,  WITHOUT    
 *     THE PRIOR WRITTEN PERMISSION OF :                                
 *                                                                      
 *                        INTEL  CORPORATION                            
 *                                                                     
 *                     2200 MISSION COLLEGE BLVD                        
 *                                                                      
 *               SANTA  CLARA,  CALIFORNIA  95052-8119                  
 *                                                                      
//**************************************************************************
//
//
// File = $Id: $
//
//
// Edit History
//
// $Log: /base_level2/uca/hash_util.h $
 * 
 * 4     5/20/98 1:59p Jguilford
 * Change copyright notice to Intel
 * 
 * 3     3/12/98 4:36p Jguilford
 * Add Macro capability
 * 
 * 1     2/05/98 7:17p Jguilford
 * Integrating preprocessor into UCA & making DLL
*/

#ifndef HASH_UTIL_H
#define HASH_UTIL_H

// Class T needs a method "char* get_hash_key()"
template<class T> class Hash
{
private:
    int m_array_size;
    int m_array_mask;
    int m_keys_used;
    int m_keys_threshold;

    struct HashPtr {
        unsigned int hash_val;
        T *hash_data;
    } *m_array;

    enum {
        HASH_VALID_MASK  = 0x7FFFFFFF,
        HASH_INVALID_MASK = 0x80000000,
        HASH_DIV = 60013
    };

    unsigned int compute_hash(char *str)
    {
        union {
            unsigned int i;
            unsigned char c[4];
        } val;
        unsigned char c;
        val.i = 0;
        while (*str)
            val.i = (val.i << 2) + *str++;
        c = val.c[3];
        val.c[3] = val.c[0];
        val.c[0] = c;
        val.i &= HASH_VALID_MASK;
      return val.i;
    }
    void grow();
public:
    Hash(unsigned int size = 128);
    ~Hash();

    // find will return the value specified by key
    T *find(char *key);

    // add will attempt to add the new item. It returns true on success
    // or false if the item was already in place
    bool add(T *new_item);

    // remove will remove a key if it exists; if successful, it will
    // return the item removed.
    T *remove(char *str);

    // delete_all will delete all items in the hash table
    void delete_all();
};
    
template<class T>
Hash<T>::Hash(unsigned int size)
{
    int i;
    unsigned int s;

    /* see if it is not a multiple of two */
    if ((size & (size-1)) != 0) {
        for (s=1; s<size; s<<1);
        size = s;
    }

    m_array_size = size;
    m_array_mask = m_array_size-1;
    m_keys_used = 0;
    m_keys_threshold = m_array_size/3;

    m_array = new HashPtr[m_array_size];

    for (i=0; i<m_array_size; i++) {
        m_array[i].hash_data = NULL;
    }
}

template<class T>
Hash<T>::~Hash()
{
    delete [] m_array;
}

template<class T>
void
Hash<T>::delete_all()
{
    int i;
    for (i=0; i<m_array_size; i++) {
        if ((m_array[i].hash_data != NULL) &&
            (m_array[i].hash_val != HASH_INVALID_MASK))
            delete m_array[i].hash_data;
    }
}

template<class T>
T* 
Hash<T>::find(char *str)
{
    unsigned int val,i;
    HashPtr *ptr;

    val = compute_hash(str);
    i = (val % HASH_DIV) & m_array_mask;
    while (ptr = &m_array[i], ptr->hash_data != NULL) {
        if ((ptr->hash_val == val) &&
            (0 == strcmp(str, ptr->hash_data->get_hash_key())))
            return ptr->hash_data;
        i = (i+1) & m_array_mask;
    }
    return NULL;
}

template<class T>
T* 
Hash<T>::remove(char *str)
{
    unsigned int val,i;
    HashPtr *ptr;
    T *rv;

    val = compute_hash(str);
    i = (val % HASH_DIV) & m_array_mask;
    while (ptr = &m_array[i], ptr->hash_data != NULL) {
        if ((ptr->hash_val == val) &&
            (0 == strcmp(str, ptr->hash_data->get_hash_key()))) {
            rv = ptr->hash_data;
            ptr->hash_val = HASH_INVALID_MASK;
            ptr->hash_data = (T*) -1;
            return rv;
        }
        i = (i+1) & m_array_mask;
    }
    return NULL;
}

template<class T>
bool
Hash<T>::add(T *new_data)
{
    unsigned int val,i;
    HashPtr *ptr;
    char *str;

    if (m_keys_used == m_keys_threshold)
        grow();

    val = compute_hash(str = new_data->get_hash_key());
    i = (val % HASH_DIV) & m_array_mask;
    while (ptr = &m_array[i], ptr->hash_data != NULL) {
        if ((ptr->hash_val == val) &&
            (0 == strcmp(str, ptr->hash_data->get_hash_key())))
            return false;
        if (ptr->hash_val & HASH_INVALID_MASK)
            break;
        i = (i+1) & m_array_mask;
    } // end while
    if (ptr->hash_data == NULL)
        m_keys_used++;

    ptr->hash_val = val;
    ptr->hash_data = new_data;

    return true;
}

template<class T>
void
Hash<T>::grow()
{
    int array_size, array_mask, keys_used, keys_threshold;
    HashPtr *array;

    int i;
    unsigned int val, j;
    HashPtr *ptr;

    array_size = m_array_size * 2;
    array_mask = m_array_size-1;
    keys_used = 0;
    keys_threshold = array_size/3;

    array = new HashPtr[array_size];
    for (i=0; i<array_size; i++) {
        array[i].hash_data = NULL;
    }

    for (i=0; i<m_array_size; i++) {
        if ((m_array[i].hash_data != NULL) &&
            (m_array[i].hash_val != HASH_INVALID_MASK)) {

            // add new value
            val = m_array[i].hash_val;
            j = (val % HASH_DIV) & array_mask;
            while (ptr = &array[j], ptr->hash_data != NULL) {
                j = (j+1) & array_mask;
            } // end while
            keys_used++;

            ptr->hash_val = val;
            ptr->hash_data = m_array[i].hash_data;
            // end add new value

        } // end if valid record
    } // end for i

    delete [] m_array;
    m_array = array;
    m_array_size = array_size;
    m_array_mask = array_mask;
    m_keys_used = keys_used;
    m_keys_threshold = keys_threshold;
}

#endif // ifdef HASH_UTIL_H



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