1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-23 04:30:10 +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:
Bob Andrews 2022-02-14 17:31:45 +01:00 committed by GitHub
commit 24c8de87c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 119 additions and 37 deletions

View File

@ -1462,7 +1462,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers,
case TOK_IDENT: case TOK_IDENT:
/* This could be a label */ /* This could be a label */
if (NextTok.Tok != TOK_COLON) { if (NextTok.Tok != TOK_COLON || GetLexicalLevel () == LEX_LEVEL_STRUCT) {
Entry = FindSym (CurTok.Ident); Entry = FindSym (CurTok.Ident);
if (Entry && SymIsTypeDef (Entry)) { if (Entry && SymIsTypeDef (Entry)) {
/* It's a typedef */ /* It's a typedef */
@ -1485,7 +1485,7 @@ static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers,
** long as it has no qualifiers. ** long as it has no qualifiers.
*/ */
D->Flags |= DS_DEF_TYPE; D->Flags |= DS_DEF_TYPE;
D->Type[0].C = T_QUAL_NONE; D->Type[0].C = T_INT;
D->Type[1].C = T_END; D->Type[1].C = T_END;
break; break;
} }

View File

@ -88,7 +88,8 @@ SymTable EmptySymTab = {
#define SYMTAB_SIZE_LABEL 7U #define SYMTAB_SIZE_LABEL 7U
/* The current and root symbol tables */ /* 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* SymTab0 = 0;
static SymTable* SymTab = 0; static SymTable* SymTab = 0;
static SymTable* TagTab0 = 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) unsigned GetLexicalLevel (void)
/* Return the current lexical level */ /* 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 */ /* Enter the program global lexical level */
{ {
/* Safety */ /* 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 */ /* Create and assign the symbol table */
SymTab0 = SymTab = NewSymTable (SYMTAB_SIZE_GLOBAL); SymTab0 = SymTab = NewSymTable (SYMTAB_SIZE_GLOBAL);
@ -246,7 +286,7 @@ void LeaveGlobalLevel (void)
/* Leave the program global lexical level */ /* Leave the program global lexical level */
{ {
/* Safety */ /* Safety */
PRECONDITION (LexicalLevel-- == LEX_LEVEL_GLOBAL); PRECONDITION (GetLexicalLevel () == LEX_LEVEL_GLOBAL);
/* Check the tables */ /* Check the tables */
CheckSymTable (SymTab0); CheckSymTable (SymTab0);
@ -260,6 +300,9 @@ void LeaveGlobalLevel (void)
/* Don't delete the symbol and struct tables! */ /* Don't delete the symbol and struct tables! */
SymTab = 0; SymTab = 0;
TagTab = 0; TagTab = 0;
/* Exit global lexical level */
PopLexicalLevel ();
} }
@ -269,8 +312,8 @@ void EnterFunctionLevel (void)
{ {
SymTable* S; SymTable* S;
/* New lexical level */ /* Enter function lexical level */
++LexicalLevel; PushLexicalLevel (LEX_LEVEL_FUNCTION);
/* Get a new symbol table and make it current */ /* Get a new symbol table and make it current */
S = NewSymTable (SYMTAB_SIZE_FUNCTION); S = NewSymTable (SYMTAB_SIZE_FUNCTION);
@ -293,8 +336,11 @@ void EnterFunctionLevel (void)
void RememberFunctionLevel (struct FuncDesc* F) void RememberFunctionLevel (struct FuncDesc* F)
/* Remember the symbol tables for the level and leave the level without checks */ /* Remember the symbol tables for the level and leave the level without checks */
{ {
/* Leave the lexical level */ /* Safety */
--LexicalLevel; PRECONDITION (GetLexicalLevel () == LEX_LEVEL_FUNCTION);
/* Leave function lexical level */
PopLexicalLevel ();
/* Remember the tables */ /* Remember the tables */
F->SymTab = SymTab; F->SymTab = SymTab;
@ -311,8 +357,8 @@ void RememberFunctionLevel (struct FuncDesc* F)
void ReenterFunctionLevel (struct FuncDesc* F) void ReenterFunctionLevel (struct FuncDesc* F)
/* Reenter the function lexical level using the existing tables from F */ /* Reenter the function lexical level using the existing tables from F */
{ {
/* New lexical level */ /* Enter function lexical level */
++LexicalLevel; PushLexicalLevel (LEX_LEVEL_FUNCTION);
/* Make the tables current again */ /* Make the tables current again */
F->SymTab->PrevTab = SymTab; F->SymTab->PrevTab = SymTab;
@ -330,8 +376,11 @@ void ReenterFunctionLevel (struct FuncDesc* F)
void LeaveFunctionLevel (void) void LeaveFunctionLevel (void)
/* Leave function lexical level */ /* Leave function lexical level */
{ {
/* Leave the lexical level */ /* Safety */
--LexicalLevel; PRECONDITION (GetLexicalLevel () == LEX_LEVEL_FUNCTION);
/* Leave function lexical level */
PopLexicalLevel ();
/* Check the tables */ /* Check the tables */
CheckSymTable (SymTab); CheckSymTable (SymTab);
@ -355,8 +404,8 @@ void EnterBlockLevel (void)
{ {
SymTable* S; SymTable* S;
/* New lexical level */ /* Enter block lexical level */
++LexicalLevel; PushLexicalLevel (LEX_LEVEL_BLOCK);
/* Get a new symbol table and make it current */ /* Get a new symbol table and make it current */
S = NewSymTable (SYMTAB_SIZE_BLOCK); S = NewSymTable (SYMTAB_SIZE_BLOCK);
@ -374,8 +423,11 @@ void EnterBlockLevel (void)
void LeaveBlockLevel (void) void LeaveBlockLevel (void)
/* Leave a nested block in a function */ /* Leave a nested block in a function */
{ {
/* Leave the lexical level */ /* Safety */
--LexicalLevel; PRECONDITION (GetLexicalLevel () == LEX_LEVEL_BLOCK);
/* Leave block lexical level */
PopLexicalLevel ();
/* Check the tables */ /* Check the tables */
CheckSymTable (SymTab); CheckSymTable (SymTab);
@ -392,6 +444,9 @@ void EnterStructLevel (void)
{ {
SymTable* S; SymTable* S;
/* Enter struct lexical level */
PushLexicalLevel (LEX_LEVEL_STRUCT);
/* Get a new symbol table and make it current. Note: Structs and enums /* 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 ** 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. ** outside scope. So we will NOT create a new struct or enum table.
@ -406,6 +461,12 @@ void EnterStructLevel (void)
void LeaveStructLevel (void) void LeaveStructLevel (void)
/* Leave a nested block for a struct definition */ /* Leave a nested block for a struct definition */
{ {
/* Safety */
PRECONDITION (GetLexicalLevel () == LEX_LEVEL_STRUCT);
/* Leave struct lexical level */
PopLexicalLevel ();
/* Don't delete the table */ /* Don't delete the table */
FieldTab = FieldTab->PrevTab; FieldTab = FieldTab->PrevTab;
} }
@ -1398,7 +1459,7 @@ void EmitDebugInfo (void)
/* For cosmetic reasons in the output file, we will insert two tabs /* For cosmetic reasons in the output file, we will insert two tabs
** on global level and just one on local level. ** on global level and just one on local level.
*/ */
if (LexicalLevel == LEX_LEVEL_GLOBAL) { if (GetLexicalLevel () == LEX_LEVEL_GLOBAL) {
Head = "\t.dbg\t\tsym"; Head = "\t.dbg\t\tsym";
} else { } else {
Head = "\t.dbg\tsym"; Head = "\t.dbg\tsym";

View File

@ -65,12 +65,22 @@ struct SymTable {
/* An empty symbol table */ /* An empty symbol table */
extern SymTable EmptySymTab; extern SymTable EmptySymTab;
/* Forwards */ /* Lexical level linked list node type */
struct FuncDesc; typedef struct LexicalLevel LexicalLevel;
struct LexicalLevel {
LexicalLevel* PrevLex;
unsigned CurrentLevel;
};
/* Predefined lexical levels */ /* Predefined lexical levels */
#define LEX_LEVEL_NONE 0U
#define LEX_LEVEL_GLOBAL 1U #define LEX_LEVEL_GLOBAL 1U
#define LEX_LEVEL_FUNCTION 2U #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); unsigned GetLexicalLevel (void);
/* Return the current lexical level */ /* 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); void EnterGlobalLevel (void);
/* Enter the program global lexical level */ /* Enter the program global lexical level */

View File

@ -26,8 +26,10 @@
static unsigned char failures = 0; static unsigned char failures = 0;
typedef unsigned int field_type;
static struct four_bits { static struct four_bits {
unsigned int x : 4; field_type x : 4;
} fb = {1}; } fb = {1};
static void test_four_bits(void) static void test_four_bits(void)
@ -57,8 +59,8 @@ static void test_four_bits(void)
*/ */
static struct four_bits_with_int { static struct four_bits_with_int {
unsigned int x : 4; field_type x : 4;
unsigned int y; field_type y;
} fbi = {1, 2}; } fbi = {1, 2};
static void test_four_bits_with_int(void) static void test_four_bits_with_int(void)
@ -95,8 +97,8 @@ static void test_four_bits_with_int(void)
} }
static struct overlap { static struct overlap {
unsigned int x : 10; field_type x : 10;
unsigned int y : 10; field_type y : 10;
} o = {11, 22}; } o = {11, 22};
/* Tests that bit-fields can share allocation units. */ /* Tests that bit-fields can share allocation units. */
@ -133,9 +135,9 @@ static void test_overlap(void)
} }
static struct overlap_with_int { static struct overlap_with_int {
unsigned int x : 10; field_type x : 10;
unsigned int y : 10; field_type y : 10;
unsigned int z; field_type z;
} oi = {111, 222, 333}; } oi = {111, 222, 333};
static void test_overlap_with_int(void) static void test_overlap_with_int(void)
@ -183,8 +185,8 @@ static void test_overlap_with_int(void)
} }
static struct full_width { static struct full_width {
unsigned int x : 8; field_type x : 8;
unsigned int y : 16; field_type y : 16;
} fw = {255, 17}; } fw = {255, 17};
static void test_full_width(void) static void test_full_width(void)
@ -220,13 +222,13 @@ static void test_full_width(void)
} }
static struct aligned_end { static struct aligned_end {
unsigned int : 2; field_type : 2;
unsigned int x : 6; field_type x : 6;
unsigned int : 3; field_type : 3;
unsigned int y : 13; field_type y : 13;
/* z crosses a byte boundary, but fits in a byte when shifted. */ /* z crosses a byte boundary, but fits in a byte when shifted. */
unsigned int : 6; field_type : 6;
unsigned int z : 7; field_type z : 7;
} ae = {63, 17, 100}; } ae = {63, 17, 100};
static void test_aligned_end(void) static void test_aligned_end(void)