This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Compiler bug -- egcs-2.90.27 (egcs-1.0.2 release)
- To: egcs-bugs at cygnus dot com
- Subject: Compiler bug -- egcs-2.90.27 (egcs-1.0.2 release)
- From: djohnson at tinpan dot hd dot intel dot com
- Date: Fri, 17 Jul 98 14:48:50 -0400
- Cc: desmond dot johnson at intel dot com
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