mirror of
https://github.com/cc65/cc65.git
synced 2025-08-13 08:25:28 +00:00
Fixed checking conflitcing declarations with external vs other linkage.
This commit is contained in:
@@ -1045,6 +1045,22 @@ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs
|
|||||||
if (SymIsDef (Entry) && (Flags & SC_DEF) == SC_DEF) {
|
if (SymIsDef (Entry) && (Flags & SC_DEF) == SC_DEF) {
|
||||||
Error ("Multiple definition of '%s'", Entry->Name);
|
Error ("Multiple definition of '%s'", Entry->Name);
|
||||||
Entry = 0;
|
Entry = 0;
|
||||||
|
} else if ((Flags & (SC_AUTO | SC_REGISTER)) != 0 &&
|
||||||
|
(Entry->Flags & SC_EXTERN) != 0) {
|
||||||
|
/* Check for local storage class conflict */
|
||||||
|
Error ("Declaration of '%s' with no linkage follows extern declaration",
|
||||||
|
Name);
|
||||||
|
Entry = 0;
|
||||||
|
} else {
|
||||||
|
/* If a static declaration follows a non-static declaration,
|
||||||
|
** then it is an error.
|
||||||
|
*/
|
||||||
|
if ((Flags & SC_DEF) &&
|
||||||
|
(Flags & SC_EXTERN) == 0 &&
|
||||||
|
(Entry->Flags & SC_EXTERN) != 0) {
|
||||||
|
Error ("Static declaration of '%s' follows extern declaration", Name);
|
||||||
|
Entry = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1104,38 +1120,62 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags)
|
|||||||
if (Entry) {
|
if (Entry) {
|
||||||
/* We have a symbol with this name already */
|
/* We have a symbol with this name already */
|
||||||
if (HandleSymRedefinition (Entry, T, Flags)) {
|
if (HandleSymRedefinition (Entry, T, Flags)) {
|
||||||
/* Use the fail-safe table for fictitious symbols */
|
|
||||||
Tab = FailSafeTab;
|
|
||||||
Entry = 0;
|
Entry = 0;
|
||||||
|
} else if ((Entry->Flags & (SC_AUTO | SC_REGISTER)) != 0) {
|
||||||
} else {
|
/* Check for local storage class conflict */
|
||||||
|
Error ("Extern declaration of '%s' follows declaration with no linkage",
|
||||||
|
Name);
|
||||||
|
Entry = 0;
|
||||||
|
} else if ((Flags & SC_ESUTYPEMASK) != SC_TYPEDEF) {
|
||||||
/* If a static declaration follows a non-static declaration, then
|
/* If a static declaration follows a non-static declaration, then
|
||||||
** warn about the conflict. It will compile an extern declaration.
|
** diagnose the conflict. It will warn and compile an extern
|
||||||
|
** declaration if both declarations are global, otherwise give an
|
||||||
|
** error.
|
||||||
*/
|
*/
|
||||||
if ((Flags & SC_EXTERN) == 0 && (Entry->Flags & SC_EXTERN) != 0) {
|
if (Tab == SymTab0 &&
|
||||||
Warning ("static declaration follows non-static declaration of '%s'.", Name);
|
(Flags & SC_EXTERN) == 0 &&
|
||||||
|
(Entry->Flags & SC_EXTERN) != 0) {
|
||||||
|
Warning ("Static declaration of '%s' follows non-static declaration", Name);
|
||||||
|
} else if ((Flags & SC_EXTERN) != 0 &&
|
||||||
|
(Entry->Owner == SymTab0 || (Entry->Flags & SC_DEF) != 0) &&
|
||||||
|
(Entry->Flags & SC_EXTERN) == 0) {
|
||||||
|
/* It is OK if a global extern declaration follows a global
|
||||||
|
** non-static declaration, but an error if either of them is
|
||||||
|
** local, as the two would be referring to different objects.
|
||||||
|
** It is an error as well if a global non-static declaration
|
||||||
|
** follows a global static declaration.
|
||||||
|
*/
|
||||||
|
if (Entry->Owner == SymTab0) {
|
||||||
|
if ((Flags & SC_STORAGE) == 0) {
|
||||||
|
/* Linkage must be unchanged */
|
||||||
|
Flags &= ~SC_EXTERN;
|
||||||
|
} else {
|
||||||
|
Error ("Non-static declaration of '%s' follows static declaration", Name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Error ("Extern declaration of '%s' follows static declaration", Name);
|
||||||
|
Entry = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If an extern declaration follows a static declaration, then
|
if (Entry) {
|
||||||
** warn about the conflict. It will compile an extern declaration.
|
/* Update existing function type if this is a definition */
|
||||||
*/
|
if (IsTypeFunc (Entry->Type) &&
|
||||||
if ((Flags & SC_EXTERN) != 0 && (Entry->Flags & SC_EXTERN) == 0) {
|
!SymIsDef (Entry) &&
|
||||||
Warning ("extern declaration follows static declaration of '%s'.", Name);
|
(Flags & SC_DEF) == SC_DEF) {
|
||||||
}
|
TypeFree (Entry->Type);
|
||||||
|
Entry->Type = TypeDup (T);
|
||||||
|
}
|
||||||
|
|
||||||
/* Update existing function type if this is a definition */
|
/* Add the new flags */
|
||||||
if (IsTypeFunc (Entry->Type) &&
|
Entry->Flags |= Flags;
|
||||||
!SymIsDef (Entry) &&
|
|
||||||
(Flags & SC_DEF) == SC_DEF) {
|
|
||||||
TypeFree (Entry->Type);
|
|
||||||
Entry->Type = TypeDup (T);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the new flags */
|
|
||||||
Entry->Flags |= Flags & ~SC_EXTERN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Entry == 0) {
|
||||||
|
/* Use the fail-safe table for fictitious symbols */
|
||||||
|
Tab = FailSafeTab;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Entry == 0 || Entry->Owner != Tab) {
|
if (Entry == 0 || Entry->Owner != Tab) {
|
||||||
|
Reference in New Issue
Block a user