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:
commit
24c8de87c2
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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";
|
||||||
|
@ -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 */
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user