From cb8fbf4772a0f2bbb1c04393662a5cacaaeea4f4 Mon Sep 17 00:00:00 2001 From: acqn Date: Mon, 29 Mar 2021 12:35:29 +0800 Subject: [PATCH] Removed the non-existing-in-C "struct/union scope" for structs/unions. Fixed handling of struct/union field declarations without identifiers, which do nothing. --- src/cc65/declare.c | 8 ++++---- src/cc65/symtab.c | 27 +++++++++++++++++++-------- src/cc65/symtab.h | 5 ++++- test/misc/bug1437.c | 23 ----------------------- test/val/bug1437.c | 35 +++++++++++++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 36 deletions(-) delete mode 100644 test/misc/bug1437.c create mode 100644 test/val/bug1437.c diff --git a/src/cc65/declare.c b/src/cc65/declare.c index d952d1049..787ed62b7 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -965,7 +965,7 @@ static SymEntry* ParseUnionDecl (const char* Name, unsigned* DSFlags) */ AddBitField (Decl.Ident, Decl.Type, 0, 0, FieldWidth, SignednessSpecified); - } else { + } else if (Decl.Ident[0] != '\0') { Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0); if (IsAnonName (Decl.Ident)) { Entry->V.A.ANumber = UnionTagEntry->V.S.ACount++; @@ -994,7 +994,7 @@ NextMember: if (CurTok.Tok != TOK_COMMA) { NextToken (); /* Remember the symbol table and leave the struct level */ - FieldTab = GetSymTab (); + FieldTab = GetFieldSymTab (); LeaveStructLevel (); /* Return a fictitious symbol if errors occurred during parsing */ @@ -1167,7 +1167,7 @@ static SymEntry* ParseStructDecl (const char* Name, unsigned* DSFlags) /* Add any full bytes to the struct size. */ StructSize += BitOffs / CHAR_BITS; BitOffs %= CHAR_BITS; - } else { + } else if (Decl.Ident[0] != '\0') { Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize); if (IsAnonName (Decl.Ident)) { Entry->V.A.ANumber = StructTagEntry->V.S.ACount++; @@ -1208,7 +1208,7 @@ NextMember: if (CurTok.Tok != TOK_COMMA) { NextToken (); /* Remember the symbol table and leave the struct level */ - FieldTab = GetSymTab (); + FieldTab = GetFieldSymTab (); LeaveStructLevel (); /* Return a fictitious symbol if errors occurred during parsing */ diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index db2b04f17..3d7176a83 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -92,6 +92,7 @@ static SymTable* SymTab0 = 0; static SymTable* SymTab = 0; static SymTable* TagTab0 = 0; static SymTable* TagTab = 0; +static SymTable* FieldTab = 0; static SymTable* LabelTab = 0; static SymTable* SPAdjustTab = 0; static SymTable* FailSafeTab = 0; /* For errors */ @@ -390,9 +391,9 @@ void EnterStructLevel (void) ** 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. */ - S = NewSymTable (SYMTAB_SIZE_BLOCK); - S->PrevTab = SymTab; - SymTab = S; + S = NewSymTable (SYMTAB_SIZE_STRUCT); + S->PrevTab = FieldTab; + FieldTab = S; } @@ -401,7 +402,7 @@ void LeaveStructLevel (void) /* Leave a nested block for a struct definition */ { /* Don't delete the table */ - SymTab = SymTab->PrevTab; + FieldTab = FieldTab->PrevTab; } @@ -850,7 +851,7 @@ SymEntry* AddBitField (const char* Name, const Type* T, unsigned Offs, /* Add a bit field to the local symbol table and return the symbol entry */ { /* Do we have an entry with this name already? */ - SymEntry* Entry = FindSymInTable (SymTab, Name, HashStr (Name)); + SymEntry* Entry = FindSymInTable (FieldTab, Name, HashStr (Name)); if (Entry) { /* We have a symbol with this name already */ @@ -882,7 +883,7 @@ SymEntry* AddBitField (const char* Name, const Type* T, unsigned Offs, } /* Add the entry to the symbol table */ - AddSymEntry (SymTab, Entry); + AddSymEntry (FieldTab, Entry); } @@ -1070,9 +1071,9 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags) SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs) -/* Add a local symbol and return the symbol entry */ +/* Add a local or struct/union field symbol and return the symbol entry */ { - SymTable* Tab = SymTab; + SymTable* Tab = (Flags & SC_STRUCTFIELD) == 0 ? SymTab : FieldTab; ident Ident; /* Do we have an entry with this name already? */ @@ -1267,6 +1268,16 @@ SymTable* GetGlobalSymTab (void) return SymTab0; } + + +SymTable* GetFieldSymTab (void) +/* Return the current field symbol table */ +{ + return FieldTab; +} + + + SymTable* GetLabelSymTab (void) /* Return the global symbol table */ { diff --git a/src/cc65/symtab.h b/src/cc65/symtab.h index 1231eb528..469a4ba77 100644 --- a/src/cc65/symtab.h +++ b/src/cc65/symtab.h @@ -166,7 +166,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags); /* Add a goto label to the symbol table */ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs); -/* Add a local symbol and return the symbol entry */ +/* Add a local or struct/union field symbol and return the symbol entry */ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags); /* Add an external or global symbol to the symbol table and return the entry */ @@ -185,6 +185,9 @@ SymTable* GetSymTab (void); SymTable* GetGlobalSymTab (void); /* Return the global symbol table */ +SymTable* GetFieldSymTab (void); +/* Return the current field symbol table */ + SymTable* GetLabelSymTab (void); /* Return the label symbol table */ diff --git a/test/misc/bug1437.c b/test/misc/bug1437.c deleted file mode 100644 index de6c7008d..000000000 --- a/test/misc/bug1437.c +++ /dev/null @@ -1,23 +0,0 @@ - -/* bug #1437 enum declaration in struct does not compile */ - -struct nodelist1 { - enum { DEAD1, LIVE1, ONCE1, TWICE1 } live1; -} firstnode1 = {ONCE1}; - -enum nodestate2 { DEAD2, LIVE2, ONCE2, TWICE2 } live2; - -struct nodelist2 { - enum nodestate2 live2; -} firstnode2 = {TWICE2}; - -int main (void) -{ - if (firstnode1.live1 != ONCE1) { - return 1; - } - if (firstnode2.live2 != TWICE2) { - return 1; - } - return 0; -} diff --git a/test/val/bug1437.c b/test/val/bug1437.c new file mode 100644 index 000000000..3424079e1 --- /dev/null +++ b/test/val/bug1437.c @@ -0,0 +1,35 @@ + +/* bug #1437 enum declaration in a struct/union is invisible in the scope where the struct/union is declared */ + +struct nodelist1 { + struct { + enum { DEAD1, LIVE1, ONCE1, TWICE1 } live1; + } s; +} firstnode1 = {ONCE1}; + +enum nodestate2 { DEAD2, LIVE2, ONCE2, TWICE2 } live2; + +union nodelist2 { + enum nodestate2 live2; +} firstnode2 = { {TWICE2} }; + +struct T { + int I; + int; + enum E { + I + }; +}; + +int failures = 0; + +int main (void) +{ + if (firstnode1.s.live1 != ONCE1) { + ++failures; + } + if (firstnode2.live2 != TWICE2) { + ++failures; + } + return failures; +}