From 8ef34472486a80a5f24031c6f764ee195737eba2 Mon Sep 17 00:00:00 2001 From: cuz Date: Fri, 15 Nov 2002 13:19:46 +0000 Subject: [PATCH] Fixed an error in struct compare. For one, the behaviour was not standard compliant, because struct tags were not compare, second, this lead to an endless loop of recursive calls for a special case of wrong C code. git-svn-id: svn://svn.cc65.org/cc65/trunk@1523 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/cc65/anonname.c | 24 ++++++++++++++++++++++-- src/cc65/anonname.h | 3 +++ src/cc65/symentry.c | 11 ++++++++++- src/cc65/symentry.h | 3 +++ src/cc65/typecmp.c | 26 +++++++++++++++++++++++--- 5 files changed, 61 insertions(+), 6 deletions(-) diff --git a/src/cc65/anonname.c b/src/cc65/anonname.c index b10ca3c1d..499532f93 100644 --- a/src/cc65/anonname.c +++ b/src/cc65/anonname.c @@ -34,13 +34,25 @@ #include +#include +/* cc65 */ #include "anonname.h" /*****************************************************************************/ -/* Code */ +/* Data */ +/*****************************************************************************/ + + + +static const char AnonTag[] = "$anon"; + + + +/*****************************************************************************/ +/* Code */ /*****************************************************************************/ @@ -51,9 +63,17 @@ char* AnonName (char* Buf, const char* Spec) */ { static unsigned ACount = 0; - sprintf (Buf, "$anon-%s-%04X", Spec, ++ACount); + sprintf (Buf, "%s-%s-%04X", AnonTag, Spec, ++ACount); return Buf; } +int IsAnonName (const char* Name) +/* Check if the given symbol name is that of an anonymous symbol */ +{ + return (strncmp (Name, AnonTag, sizeof (AnonTag) - 1) == 0); +} + + + diff --git a/src/cc65/anonname.h b/src/cc65/anonname.h index 123a9cf26..90c9e0af8 100644 --- a/src/cc65/anonname.h +++ b/src/cc65/anonname.h @@ -49,6 +49,9 @@ char* AnonName (char* Buf, const char* Spec); * to be IDENTSIZE characters long. A pointer to the buffer is returned. */ +int IsAnonName (const char* Name); +/* Check if the given symbol name is that of an anonymous symbol */ + /* End of anonname.h */ diff --git a/src/cc65/symentry.c b/src/cc65/symentry.c index 578c6c005..8882cdb62 100644 --- a/src/cc65/symentry.c +++ b/src/cc65/symentry.c @@ -39,6 +39,7 @@ #include "xmalloc.h" /* cc65 */ +#include "anonname.h" #include "symentry.h" @@ -166,7 +167,7 @@ void ChangeSymType (SymEntry* Entry, type* Type) void ChangeAsmName (SymEntry* Entry, const char* NewAsmName) -/* Change the assembler name of the symbol */ +/* Change the assembler name of the symbol */ { xfree (Entry->AsmName); Entry->AsmName = xstrdup (NewAsmName); @@ -174,3 +175,11 @@ void ChangeAsmName (SymEntry* Entry, const char* NewAsmName) +int HasAnonName (const SymEntry* Entry) +/* Return true if the symbol entry has an anonymous name */ +{ + return IsAnonName (Entry->Name); +} + + + diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h index ba8723644..299b0b08e 100644 --- a/src/cc65/symentry.h +++ b/src/cc65/symentry.h @@ -154,6 +154,9 @@ void ChangeSymType (SymEntry* Entry, type* Type); void ChangeAsmName (SymEntry* Entry, const char* NewAsmName); /* Change the assembler name of the symbol */ +int HasAnonName (const SymEntry* Entry); +/* Return true if the symbol entry has an anonymous name */ + /* End of symentry.h */ diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index d9677fb15..3a101011c 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -33,6 +33,9 @@ +#include + +/* cc65 */ #include "funcdesc.h" #include "symtab.h" #include "typecmp.h" @@ -78,8 +81,8 @@ static int EqualFuncParams (SymTable* Tab1, SymTable* Tab2) Sym2 = Sym2->NextSym; } - /* Check both pointers against NULL or a non parameter to compare the - * field count + /* Check both pointers against NULL or a non parameter to compare the + * field count */ return (Sym1 == 0 || (Sym1->Flags & SC_PARAM) == 0) && (Sym2 == 0 || (Sym2->Flags & SC_PARAM) == 0); @@ -97,7 +100,15 @@ static int EqualSymTables (SymTable* Tab1, SymTable* Tab2) /* Compare the fields */ while (Sym1 && Sym2) { - /* Compare this field */ + /* Compare the names of this field */ + if (!HasAnonName (Sym1) || !HasAnonName (Sym2)) { + if (strcmp (Sym1->Name, Sym2->Name) != 0) { + /* Names are not identical */ + return 0; + } + } + + /* Compare the types of this field */ if (TypeCmp (Sym1->Type, Sym2->Type) < TC_EQUAL) { /* Field types not equal */ return 0; @@ -283,6 +294,15 @@ static void DoCompare (const type* lhs, const type* rhs, typecmp_t* Result) Sym1 = DecodePtr (lhs+1); Sym2 = DecodePtr (rhs+1); + /* If one symbol has a name, the names must be identical */ + if (!HasAnonName (Sym1) || !HasAnonName (Sym2)) { + if (strcmp (Sym1->Name, Sym2->Name) != 0) { + /* Names are not identical */ + SetResult (Result, TC_INCOMPATIBLE); + return; + } + } + /* Get the field tables from the struct entry */ Tab1 = Sym1->V.S.SymTab; Tab2 = Sym2->V.S.SymTab;