mirror of
https://github.com/cc65/cc65.git
synced 2024-12-22 12:30:41 +00:00
Merge pull request #1662 from acqn/StructFix
[cc65] Fixed ICE on unnamed bit-fields declared with typedef'ed types
This commit is contained in:
commit
24c8de87c2
@ -1462,7 +1462,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers,
|
||||
|
||||
case TOK_IDENT:
|
||||
/* This could be a label */
|
||||
if (NextTok.Tok != TOK_COLON) {
|
||||
if (NextTok.Tok != TOK_COLON || GetLexicalLevel () == LEX_LEVEL_STRUCT) {
|
||||
Entry = FindSym (CurTok.Ident);
|
||||
if (Entry && SymIsTypeDef (Entry)) {
|
||||
/* It's a typedef */
|
||||
@ -1485,7 +1485,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers,
|
||||
** long as it has no qualifiers.
|
||||
*/
|
||||
D->Flags |= DS_DEF_TYPE;
|
||||
D->Type[0].C = T_QUAL_NONE;
|
||||
D->Type[0].C = T_INT;
|
||||
D->Type[1].C = T_END;
|
||||
break;
|
||||
}
|
||||
|
@ -88,7 +88,8 @@ SymTable EmptySymTab = {
|
||||
#define SYMTAB_SIZE_LABEL 7U
|
||||
|
||||
/* The current and root symbol tables */
|
||||
static unsigned LexicalLevel = 0; /* For safety checks */
|
||||
static unsigned LexLevelDepth = 0; /* For safety checks */
|
||||
static LexicalLevel* CurrentLex = 0;
|
||||
static SymTable* SymTab0 = 0;
|
||||
static SymTable* SymTab = 0;
|
||||
static SymTable* TagTab0 = 0;
|
||||
@ -213,10 +214,46 @@ static void CheckSymTable (SymTable* Tab)
|
||||
|
||||
|
||||
|
||||
unsigned GetLexicalLevelDepth (void)
|
||||
/* Return the current lexical level depth */
|
||||
{
|
||||
return LexLevelDepth;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned GetLexicalLevel (void)
|
||||
/* Return the current lexical level */
|
||||
{
|
||||
return LexicalLevel;
|
||||
if (CurrentLex != 0) {
|
||||
return CurrentLex->CurrentLevel;
|
||||
}
|
||||
return LEX_LEVEL_NONE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PushLexicalLevel (unsigned NewLevel)
|
||||
/* Enter the specified lexical level */
|
||||
{
|
||||
LexicalLevel* L = xmalloc (sizeof (LexicalLevel));
|
||||
L->PrevLex = CurrentLex;
|
||||
CurrentLex = L;
|
||||
CurrentLex->CurrentLevel = NewLevel;
|
||||
++LexLevelDepth;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PopLexicalLevel (void)
|
||||
/* Exit the current lexical level */
|
||||
{
|
||||
LexicalLevel* L;
|
||||
PRECONDITION (CurrentLex != 0 && LexLevelDepth > 0);
|
||||
L = CurrentLex;
|
||||
CurrentLex = L->PrevLex;
|
||||
xfree (L);
|
||||
--LexLevelDepth;
|
||||
}
|
||||
|
||||
|
||||
@ -225,7 +262,10 @@ void EnterGlobalLevel (void)
|
||||
/* Enter the program global lexical level */
|
||||
{
|
||||
/* Safety */
|
||||
PRECONDITION (++LexicalLevel == LEX_LEVEL_GLOBAL);
|
||||
PRECONDITION (GetLexicalLevel () == LEX_LEVEL_NONE);
|
||||
|
||||
/* Enter global lexical level */
|
||||
PushLexicalLevel (LEX_LEVEL_GLOBAL);
|
||||
|
||||
/* Create and assign the symbol table */
|
||||
SymTab0 = SymTab = NewSymTable (SYMTAB_SIZE_GLOBAL);
|
||||
@ -246,7 +286,7 @@ void LeaveGlobalLevel (void)
|
||||
/* Leave the program global lexical level */
|
||||
{
|
||||
/* Safety */
|
||||
PRECONDITION (LexicalLevel-- == LEX_LEVEL_GLOBAL);
|
||||
PRECONDITION (GetLexicalLevel () == LEX_LEVEL_GLOBAL);
|
||||
|
||||
/* Check the tables */
|
||||
CheckSymTable (SymTab0);
|
||||
@ -260,6 +300,9 @@ void LeaveGlobalLevel (void)
|
||||
/* Don't delete the symbol and struct tables! */
|
||||
SymTab = 0;
|
||||
TagTab = 0;
|
||||
|
||||
/* Exit global lexical level */
|
||||
PopLexicalLevel ();
|
||||
}
|
||||
|
||||
|
||||
@ -269,8 +312,8 @@ void EnterFunctionLevel (void)
|
||||
{
|
||||
SymTable* S;
|
||||
|
||||
/* New lexical level */
|
||||
++LexicalLevel;
|
||||
/* Enter function lexical level */
|
||||
PushLexicalLevel (LEX_LEVEL_FUNCTION);
|
||||
|
||||
/* Get a new symbol table and make it current */
|
||||
S = NewSymTable (SYMTAB_SIZE_FUNCTION);
|
||||
@ -293,8 +336,11 @@ void EnterFunctionLevel (void)
|
||||
void RememberFunctionLevel (struct FuncDesc* F)
|
||||
/* Remember the symbol tables for the level and leave the level without checks */
|
||||
{
|
||||
/* Leave the lexical level */
|
||||
--LexicalLevel;
|
||||
/* Safety */
|
||||
PRECONDITION (GetLexicalLevel () == LEX_LEVEL_FUNCTION);
|
||||
|
||||
/* Leave function lexical level */
|
||||
PopLexicalLevel ();
|
||||
|
||||
/* Remember the tables */
|
||||
F->SymTab = SymTab;
|
||||
@ -311,8 +357,8 @@ void RememberFunctionLevel (struct FuncDesc* F)
|
||||
void ReenterFunctionLevel (struct FuncDesc* F)
|
||||
/* Reenter the function lexical level using the existing tables from F */
|
||||
{
|
||||
/* New lexical level */
|
||||
++LexicalLevel;
|
||||
/* Enter function lexical level */
|
||||
PushLexicalLevel (LEX_LEVEL_FUNCTION);
|
||||
|
||||
/* Make the tables current again */
|
||||
F->SymTab->PrevTab = SymTab;
|
||||
@ -330,8 +376,11 @@ void ReenterFunctionLevel (struct FuncDesc* F)
|
||||
void LeaveFunctionLevel (void)
|
||||
/* Leave function lexical level */
|
||||
{
|
||||
/* Leave the lexical level */
|
||||
--LexicalLevel;
|
||||
/* Safety */
|
||||
PRECONDITION (GetLexicalLevel () == LEX_LEVEL_FUNCTION);
|
||||
|
||||
/* Leave function lexical level */
|
||||
PopLexicalLevel ();
|
||||
|
||||
/* Check the tables */
|
||||
CheckSymTable (SymTab);
|
||||
@ -355,8 +404,8 @@ void EnterBlockLevel (void)
|
||||
{
|
||||
SymTable* S;
|
||||
|
||||
/* New lexical level */
|
||||
++LexicalLevel;
|
||||
/* Enter block lexical level */
|
||||
PushLexicalLevel (LEX_LEVEL_BLOCK);
|
||||
|
||||
/* Get a new symbol table and make it current */
|
||||
S = NewSymTable (SYMTAB_SIZE_BLOCK);
|
||||
@ -374,8 +423,11 @@ void EnterBlockLevel (void)
|
||||
void LeaveBlockLevel (void)
|
||||
/* Leave a nested block in a function */
|
||||
{
|
||||
/* Leave the lexical level */
|
||||
--LexicalLevel;
|
||||
/* Safety */
|
||||
PRECONDITION (GetLexicalLevel () == LEX_LEVEL_BLOCK);
|
||||
|
||||
/* Leave block lexical level */
|
||||
PopLexicalLevel ();
|
||||
|
||||
/* Check the tables */
|
||||
CheckSymTable (SymTab);
|
||||
@ -392,6 +444,9 @@ void EnterStructLevel (void)
|
||||
{
|
||||
SymTable* S;
|
||||
|
||||
/* Enter struct lexical level */
|
||||
PushLexicalLevel (LEX_LEVEL_STRUCT);
|
||||
|
||||
/* Get a new symbol table and make it current. Note: Structs and enums
|
||||
** nested in struct scope are NOT local to the struct but visible in the
|
||||
** outside scope. So we will NOT create a new struct or enum table.
|
||||
@ -406,6 +461,12 @@ void EnterStructLevel (void)
|
||||
void LeaveStructLevel (void)
|
||||
/* Leave a nested block for a struct definition */
|
||||
{
|
||||
/* Safety */
|
||||
PRECONDITION (GetLexicalLevel () == LEX_LEVEL_STRUCT);
|
||||
|
||||
/* Leave struct lexical level */
|
||||
PopLexicalLevel ();
|
||||
|
||||
/* Don't delete the table */
|
||||
FieldTab = FieldTab->PrevTab;
|
||||
}
|
||||
@ -1398,7 +1459,7 @@ void EmitDebugInfo (void)
|
||||
/* For cosmetic reasons in the output file, we will insert two tabs
|
||||
** on global level and just one on local level.
|
||||
*/
|
||||
if (LexicalLevel == LEX_LEVEL_GLOBAL) {
|
||||
if (GetLexicalLevel () == LEX_LEVEL_GLOBAL) {
|
||||
Head = "\t.dbg\t\tsym";
|
||||
} else {
|
||||
Head = "\t.dbg\tsym";
|
||||
|
@ -65,12 +65,22 @@ struct SymTable {
|
||||
/* An empty symbol table */
|
||||
extern SymTable EmptySymTab;
|
||||
|
||||
/* Forwards */
|
||||
struct FuncDesc;
|
||||
/* Lexical level linked list node type */
|
||||
typedef struct LexicalLevel LexicalLevel;
|
||||
struct LexicalLevel {
|
||||
LexicalLevel* PrevLex;
|
||||
unsigned CurrentLevel;
|
||||
};
|
||||
|
||||
/* Predefined lexical levels */
|
||||
#define LEX_LEVEL_NONE 0U
|
||||
#define LEX_LEVEL_GLOBAL 1U
|
||||
#define LEX_LEVEL_FUNCTION 2U
|
||||
#define LEX_LEVEL_BLOCK 3U
|
||||
#define LEX_LEVEL_STRUCT 4U
|
||||
|
||||
/* Forwards */
|
||||
struct FuncDesc;
|
||||
|
||||
|
||||
|
||||
@ -80,9 +90,18 @@ struct FuncDesc;
|
||||
|
||||
|
||||
|
||||
unsigned GetLexicalLevelDepth (void);
|
||||
/* Return the current lexical level depth */
|
||||
|
||||
unsigned GetLexicalLevel (void);
|
||||
/* Return the current lexical level */
|
||||
|
||||
void PushLexicalLevel (unsigned NewLevel);
|
||||
/* Enter the specified lexical level */
|
||||
|
||||
void PopLexicalLevel (void);
|
||||
/* Exit the current lexical level */
|
||||
|
||||
void EnterGlobalLevel (void);
|
||||
/* Enter the program global lexical level */
|
||||
|
||||
|
@ -26,8 +26,10 @@
|
||||
|
||||
static unsigned char failures = 0;
|
||||
|
||||
typedef unsigned int field_type;
|
||||
|
||||
static struct four_bits {
|
||||
unsigned int x : 4;
|
||||
field_type x : 4;
|
||||
} fb = {1};
|
||||
|
||||
static void test_four_bits(void)
|
||||
@ -57,8 +59,8 @@ static void test_four_bits(void)
|
||||
*/
|
||||
|
||||
static struct four_bits_with_int {
|
||||
unsigned int x : 4;
|
||||
unsigned int y;
|
||||
field_type x : 4;
|
||||
field_type y;
|
||||
} fbi = {1, 2};
|
||||
|
||||
static void test_four_bits_with_int(void)
|
||||
@ -95,8 +97,8 @@ static void test_four_bits_with_int(void)
|
||||
}
|
||||
|
||||
static struct overlap {
|
||||
unsigned int x : 10;
|
||||
unsigned int y : 10;
|
||||
field_type x : 10;
|
||||
field_type y : 10;
|
||||
} o = {11, 22};
|
||||
|
||||
/* Tests that bit-fields can share allocation units. */
|
||||
@ -133,9 +135,9 @@ static void test_overlap(void)
|
||||
}
|
||||
|
||||
static struct overlap_with_int {
|
||||
unsigned int x : 10;
|
||||
unsigned int y : 10;
|
||||
unsigned int z;
|
||||
field_type x : 10;
|
||||
field_type y : 10;
|
||||
field_type z;
|
||||
} oi = {111, 222, 333};
|
||||
|
||||
static void test_overlap_with_int(void)
|
||||
@ -183,8 +185,8 @@ static void test_overlap_with_int(void)
|
||||
}
|
||||
|
||||
static struct full_width {
|
||||
unsigned int x : 8;
|
||||
unsigned int y : 16;
|
||||
field_type x : 8;
|
||||
field_type y : 16;
|
||||
} fw = {255, 17};
|
||||
|
||||
static void test_full_width(void)
|
||||
@ -220,13 +222,13 @@ static void test_full_width(void)
|
||||
}
|
||||
|
||||
static struct aligned_end {
|
||||
unsigned int : 2;
|
||||
unsigned int x : 6;
|
||||
unsigned int : 3;
|
||||
unsigned int y : 13;
|
||||
field_type : 2;
|
||||
field_type x : 6;
|
||||
field_type : 3;
|
||||
field_type y : 13;
|
||||
/* z crosses a byte boundary, but fits in a byte when shifted. */
|
||||
unsigned int : 6;
|
||||
unsigned int z : 7;
|
||||
field_type : 6;
|
||||
field_type z : 7;
|
||||
} ae = {63, 17, 100};
|
||||
|
||||
static void test_aligned_end(void)
|
||||
|
Loading…
Reference in New Issue
Block a user