This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
internal compiler error
- To: egcs-bugs at egcs dot cygnus dot com
- Subject: internal compiler error
- From: joop renes <jj dot renes at hccnet dot nl>
- Date: Tue, 07 Mar 2000 14:52:33 +0100
Dear Sirs,
The attached header file and source code adapted from CUJ++ March 2000
generated the reported interna error.
Cheers
Joop Renes
//////////////////// UtilityMacros.h ///////////////// rado ////
// //
// Copyright (c) 1999 Radoslav Getov //
// //
// Permission to use, copy, modify and distribute this //
// software is granted without fee, provided that the above //
// copyright notice and this permission notice appear in the //
// modified source and the source files that #include it. //
// //
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
// //
// Collection of C and C++ preprocessor utility macros: //
// //
// ------ C and C++ ----- //
// REPEAT_xxx (text) //
// REPEAT_WC_xxx (text) //
// REPEAT (count, text) //
// REPEAT_WC (count, text) //
// //
// UNIQUE_NAME_WP (prefix) //
// UNIQUE_NAME //
// //
// LINE_STRING //
// HERE //
// //
// ONCE (execution_code) //
// SKIP (skip_count, execution_code) //
// REV_SKIP (skip_count, execution_code) //
// LOOP_C (count, execution_code) //
// //
// ------ C++ only ----- //
// LOOP (count) //
// //
// AT_START (execution_code) //
// AT_END (execution_code) //
// //
// DELAYED_ASSIGN_T (Type, var_reference, value) //
// SAVE_T (Type, var_reference) //
// DELAYED_ASSIGN (var_reference, value) //
// SAVE (var_reference) //
// //
////////////////////////////////////////////////////////////////
// ------------- include guards -----------------
#ifdef UTILITYMACROS_H
# error Multiple #included file!
#endif
#define UTILITYMACROS_H
// ------------- portability --------------------
#ifdef __cplusplus // defined for C++ mode compilation
# define CPP_MODE_COMPILATION 1
#else
# define CPP_MODE_COMPILATION 0
#endif
// --------------- definitions ------------------
//===================| #REPEAT_xxx (text) |=====================
// Textually repeat argument xxx times.
//
// Example: char* spaces = REPEAT_32 (" ");
//________________________________________________________rado__
#define REPEAT_2(x) x x
#define REPEAT_4(x) REPEAT_2 (x) REPEAT_2 (x)
#define REPEAT_8(x) REPEAT_4 (x) REPEAT_4 (x)
#define REPEAT_16(x) REPEAT_8 (x) REPEAT_8 (x)
#define REPEAT_32(x) REPEAT_16 (x) REPEAT_16 (x)
#define REPEAT_64(x) REPEAT_32 (x) REPEAT_32 (x)
#define REPEAT_128(x) REPEAT_64 (x) REPEAT_64 (x)
#define REPEAT_256(x) REPEAT_128 (x) REPEAT_128 (x)
#define REPEAT_512(x) REPEAT_256 (x) REPEAT_256 (x)
#define REPEAT_1024(x) REPEAT_512 (x) REPEAT_512 (x)
//===============| #REPEAT (count, what) |======================
// Textually repeat 'what' 'cnt' times.
//
// Example: char* spaces = REPEAT (32, " ");
//________________________________________________________rado__
#define REPEAT(count, what) REPEAT_##count (what)
//====================| #REPEAT_WC_xxx (text) |=================
// Textually repeat argument xxx times, delimited by comas.
//
// Example: int ones[] = { REPEAT_WC_16 (1) };
//________________________________________________________rado__
#define REPEAT_WC_2(x) x, x
#define REPEAT_WC_4(x) REPEAT_WC_2 (x), REPEAT_WC_2 (x)
#define REPEAT_WC_8(x) REPEAT_WC_4 (x), REPEAT_WC_4 (x)
#define REPEAT_WC_16(x) REPEAT_WC_8 (x), REPEAT_WC_8 (x)
#define REPEAT_WC_32(x) REPEAT_WC_16 (x), REPEAT_WC_16 (x)
#define REPEAT_WC_64(x) REPEAT_WC_32 (x), REPEAT_WC_32 (x)
#define REPEAT_WC_128(x) REPEAT_WC_64 (x), REPEAT_WC_64 (x)
#define REPEAT_WC_256(x) REPEAT_WC_128 (x), REPEAT_WC_128 (x)
#define REPEAT_WC_512(x) REPEAT_WC_256 (x), REPEAT_WC_256 (x)
#define REPEAT_WC_1024(x) REPEAT_WC_512 (x), REPEAT_WC_512 (x)
//=================| #REPEAT_WC (count, text) |=================
// Textually repeat 'what' 'cnt' times, delimited by comas.
//
// Example: int ones[16] = { REPEAT_WC (16, 1) };
//________________________________________________________rado__
#define REPEAT_WC(count, text) REPEAT_WC_##count (text)
//====================| #UNIQUE_NAME |==========================
// Expands to unique identifier on each line.
//
// Example: int UNIQUA_NAME = 0,
// UNIQUE_NAME = 1;
//________________________________________________________rado__
#define UNIQUE_NAME_1(prefix, x) prefix##x
#define UNIQUE_NAME_2(prefix, x) UNIQUE_NAME_1 (prefix, x)
#define UNIQUE_NAME_WP(prefix) UNIQUE_NAME_2 (prefix, __LINE__)
#define UNIQUE_NAME UNIQUE_NAME_WP (uniqueNameOnLine_)
//====================| #LINE_STRING |==========================
// __LINE__ as a string
//
// Example: printf (LINE_STRING);
//________________________________________________________rado__
#define LINE_STRING_1(x) #x
#define LINE_STRING_2(x) LINE_STRING_1 (x)
#define LINE_STRING LINE_STRING_2 (__LINE__)
//=====================| #HERE |================================
// File name and line number in string form like "File (1234):"
//
// Example (MSVC):
// #pragma message (HERE "Click here!")
//________________________________________________________rado__
#define HERE __FILE__ "(" LINE_STRING "):"
//===================| #ONCE(execution_code) |==================
// Executes 'execution_code' only the first time.
//
// Example: ONCE (cout << "Here we start"; )
//________________________________________________________rado__
#define ONCE(execution_code) \
{ \
static int UNIQUE_NAME = 0; \
if (!UNIQUE_NAME) \
{ \
UNIQUE_NAME = 1; \
{ execution_code } \
} \
}
//=====================| #SKIP(cnt,code) |======================
// Executes 'execution_code' once in 'skip_count' times.
//
// Example: SKIP (100, cout << '*' << endl; }
//________________________________________________________rado__
#define SKIP(skip_count, execution_code) \
{ \
static int UNIQUE_NAME = 0; \
if (++UNIQUE_NAME >= (skip_count)) \
{ \
UNIQUE_NAME = 0; \
{ execution_code } \
} \
}
//=====================| #REV_SKIP(cnt,code) |==================
// Executes 'execution_code' once in 'skip_count' times.
//
// Example: REF_SKIP (100, cout << '*' << endl; }
//________________________________________________________rado__
#define REV_SKIP(skip_count, execution_code) \
{ \
static int UNIQUE_NAME = 0; \
if (++UNIQUE_NAME >= (skip_count)) \
UNIQUE_NAME = 0; \
else \
{ \
execution_code \
} \
}
//=====================| #LOOP_C |==============================
// Execute 'loop_code' 'count' times
//
// Example: LOOP_C (100, cout << '*' << endl; )
//________________________________________________________rado__
#define LOOP_C(count, loop_code) \
\
{ \
int UNIQUE_NAME = (count); \
for (; UNIQUE_NAME > 0; --UNIQUE_NAME) \
{ loop_code } \
}
//////////// C++ compatible only templates and macros //////////
#if CPP_MODE_COMPILATION
//=====================| #LOOP |================================
// 'for' loop header for loop to be executed 'count' times.
// The statement, following it, is the loop body.
//
// Example: LOOP (rand() % 100)
// cout << '*';
//________________________________________________________rado__
#define LOOP(count) for (int UNIQUE_NAME = (count); \
UNIQUE_NAME > 0; \
--UNIQUE_NAME)
// loop body here
//========================| #AT_START |=========================
// Execute 'execution_code' upon globals initialization.
//
// Example:
// AT_START (cout << "executed before main()!\n")
//________________________________________________________rado__
#define AT_START(execution_code) \
\
static struct UNIQUE_NAME \
{ \
UNIQUE_NAME() \
{ \
execution_code \
} \
} \
UNIQUE_NAME_WP (atStartVarOnLine_);
//=======================| #AT_END |============================
// Execute 'execution_code' upon globals cleanup.
//
// Example:
// AT_END (cout << "executed AFTER main() return!\n")
//________________________________________________________rado__
#define AT_END(execution_code) \
\
static struct UNIQUE_NAME \
{ \
~UNIQUE_NAME() \
{ \
execution_code \
} \
} \
UNIQUE_NAME_WP (atStartVarOnLine_);
//*************| class DelayedAssigner_T_Base |*****************
// Base virtual class for DelayedAssigner_T<>
// Example: see DelayedAssigner_T<>
//________________________________________________________rado__
class DelayedAssigner_T_Base
{
public:
virtual ~DelayedAssigner_T_Base()
{}
};
//***************| class DelayedAssigner_T |********************
// Initialise 'itsVarRef' and 'itsValue' on construction;
// assign 'itsValue' to 'itsVarRef' upon destruction.
//
// Example: DelayedAssigner_T<int> saved_var (var);
//________________________________________________________rado__
template <class Type>
class DelayedAssigner_T : public DelayedAssigner_T_Base
{
Type& itsVarRef; // Reference to be assigned to
Type itsValue; // Value to be remembered and assigned
public:
DelayedAssigner_T (Type &var_ref)
: itsVarRef (var_ref)
, itsValue (var_ref)
{}
DelayedAssigner_T (Type &var_ref, const Type &value) // separate
: itsVarRef (var_ref)
, itsValue (value)
{}
~DelayedAssigner_T()
{
itsVarRef = itsValue;
}
};
//==================| #DELAYED_ASSIGN_T |=======================
// Assign 'value' to 'var_ref' upon destruction.
//
// Example: DELAYED_ASSIGN_T (Node*, n, n->next)
//________________________________________________________rado__
#define DELAYED_ASSIGN_T(Type, var_ref, value) \
\
DelayedAssigner_T<Type> UNIQUE_NAME (var_ref, value);
//===================| #SAVE_T |================================
// Restore initial value of 'var_ref' upon destruction.
//
// Example: SAVE_T (double, d)
//________________________________________________________rado__
#define SAVE_T(Type, var_ref) \
\
DelayedAssigner_T<Type> UNIQUE_NAME (var_ref);
//===============| makeDelayedAssigner_T |======================
// Return DelayedAssigner_T <Type> (deducing 'Type' from
// arguments)
//
// Example: see #define SAVE
//________________________________________________________rado__
template <class Type> inline
DelayedAssigner_T<Type> makeDelayedAssigner_T (Type &var)
{
return DelayedAssigner_T<Type> (var);
}
//===============| makeDelayedAssigner_T(2) |===================
// Returns DelayedAssigner_T <Type> (deducing 'Type' from
// arguments)
//
// Example: see #define DELAYED_ASSIGN
//________________________________________________________rado__
template <class Type> inline
DelayedAssigner_T <Type>
makeDelayedAssigner_T (Type &var, const Type& value)
{
return DelayedAssigner_T<Type> (var, value);
}
//==================| newDelayedAssigner_T |====================
// Allocate, initialize, and return pointer to a
// DelayedAssigner_T <Type> (deducing 'Type' from argument)
//
// Example: std::auto_ptr <DeleyedAssigner_T_Base>
// save_var (allocateDelayedAssigner_T (j);
//________________________________________________________rado__
template <class Type> inline
DelayedAssigner_T_Base* newDelayedAssigner_T (Type &var)
{
return new DelayedAssigner_T<Type> (var);
}
//======================| UnivesalStorage_T |===================
// Class that enables virtual storage, construction and
// destruction.
//
// Example:
// UnivesalStorage_T <BaseClass, sizeof (function())>
// auto_var (function());
//________________________________________________________rado__
template <class From>
class UniversalStorage
{
// Static checks for mismatched parameter type:
typedef char assertSize [sizeof (from) == SIZE];
// will not compile if sizeof 'From' is wrong
if (const Base* assertInheritence = &from)
0;// will not compile if 'From' is not : public Base
new (itsStorage) From (from); // placement new & copy ctor
};
template <class Base, size_t SIZE>
class UnivesalStorage_T
{
char itsStorage [SIZE]; // binary storage
public:
~UnivesalStorage_T()
{
((Base*)itsStorage)->~Base(); // hopefully virtual
}
};
//=====================| #SAVE(var_ref) |=======================
// Restore initial value of 'var_ref' upon destruction.
//
// Example: SAVE (k)
//________________________________________________________rado__
#define SAVE(var_ref) \
\
UnivesalStorage_T \
< DelayedAssigner_T_Base, \
sizeof (makeDelayedAssigner_T (var_ref)) > \
UNIQUE_NAME (makeDelayedAssigner_T (var_ref));
//======================| #DELAYED_ASSIGN |======================
// Assign 'value' to 'var_ref' upon destruction.
//
// Example: DELAYED_ASSIGN (n, n->next)
//________________________________________________________rado__
#define DELAYED_ASSIGN(var_ref, value) \
\
UnivesalStorage_T \
< DelayedAssigner_T_Base, \
sizeof (makeDelayedAssigner_T (var_ref)) > \
UNIQUE_NAME (makeDelayedAssigner_T ((var_ref), (value)));
#endif // CPP_MODE_COMPILATION
// ---------------------- end of file ------------------------
/////////////////// UtilityMacros.cpp ///////////////// rado ///
// //
// Copyright (c) 1999 Radoslav Getov //
// //
// Permission to use, copy, modify and distribute this //
// software is granted without fee, provided that the above //
// copyright notice and this permission notice appear in the //
// modified source and the source files that #include it. //
// //
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
// //
// Test for the macros defined in the header file. //
// //
////////////////////////////////////////////////////////////////
#include "utilitym.h"
#include <assert.h> // for assert()
#include <string.h> // for strlen()
#include <iostream> // for std::cout
//=======================| testREPEAT |=========================
// Test '#REPEAT_XXXX'
//________________________________________________________rado__
static void testREPEAT()
{
#define SIZEOF(array) (sizeof(array)/sizeof(*array))
std::cout << "testREPEAT()\n";
// Test REPEAT_xxx
char str[] = REPEAT (1024, " ");
assert (strlen (str) == 1024);
assert (SIZEOF (str) == 1025); // including trailing 0
int ones[] = { REPEAT_WC (1024, 1) };
assert (SIZEOF (ones) == 1024);
}
AT_START (
testREPEAT();
)
//=======================| test__LINE__ |=======================
// Test UNIQUE_NAME, LINE_STRING, HERE
//________________________________________________________rado__
static void test__LINE__()
{
std::cout << "test__LINE__()\n";
// Test UNIQUE_NAME
int UNIQUE_NAME = 1,
UNIQUE_NAME = 2;
// Test LINE_STRING & HERE
#pragma message (HERE " Click on me!") // MSVC++ 5.0+ only?
}
AT_START (
test__LINE__();
)
void x(int,int);
//======================| testControl |=========================
// Test for #LOOP, #ONCE, #SKIP, and #REV_SKIP
//________________________________________________________rado__
static void testControl()
{
std::cout << "testControl()\n";
int any = 0,
once = 0,
skip = 0,
rev_skip = 0;
LOOP (50)
{
any++; // 50*1 == 50
ONCE (once++;) // 0+1 == 1
SKIP (10, skip++; ) // 50/10 == 5
REV_SKIP (10, rev_skip++;) // 50 - 50/10 = 45
}
assert (any == 50 &&
once == 1 &&
skip == 5 &&
rev_skip == 45 );
LOOP_C (50, any++;) // 50 + 50 == 100
assert (any == 100);
}
AT_START (
testControl();
)
//======================| testSAVE |============================
// Test for SAVE, SAVE_T, DELAYED_ASSIGN and DELAYED_ASSIGN_T
//________________________________________________________rado__
static int iSAVE = 1,
iSAVE_T = 2,
iASS = 3,
iASS_T = 4;
static void testSAVE()
{
SAVE (iSAVE)
SAVE_T (int, iSAVE_T)
DELAYED_ASSIGN (iASS, 10);
DELAYED_ASSIGN_T (int, iASS_T, 20);
iSAVE = iSAVE_T = iASS = iASS_T = 0;
}
AT_START (
std::cout << "test SAVE\n";
testSAVE();
assert (iSAVE == 1 &&
iSAVE_T == 2 &&
iASS == 10 &&
iASS_T == 20 );
)
//====================| AT_START & AT_END |=====================
// Pay attention to the execution order.
//________________________________________________________rado__
AT_START ( printf ("Before main()\n" ); )
AT_START ( printf ("More before main()\n"); )
AT_END ( printf ("More after main()\n" ); )
AT_END ( printf ("After main()\n" ); )
//========================| main |==============================
// main() just for building
//________________________________________________________rado__
void main()
{
std::cout << "main()\n";
}
In file included from utilitym.cpp:37:
utilitym.h:695: Internal compiler error.
utilitym.h:695: Please submit a full bug report to `egcs-bugs@egcs.cygnus.com'.
utilitym.h:695: See <URL:http://egcs.cygnus.com/faq.html#bugreport> for details.