Skip to content

Commit

Permalink
Merge pull request cc65#2112 from bbbradsmith/extern-static-conflict-…
Browse files Browse the repository at this point in the history
…error

Error/warning for extern/static linkage declaration conflict
  • Loading branch information
mrdudz committed May 12, 2023
2 parents 79018fd + 5a30d74 commit 55723f4
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 10 deletions.
15 changes: 9 additions & 6 deletions src/cc65/symtab.c
Original file line number Diff line number Diff line change
Expand Up @@ -1340,15 +1340,14 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags)
Name);
Entry = 0;
} else if ((Flags & SC_ESUTYPEMASK) != SC_TYPEDEF) {
/* If a static declaration follows a non-static declaration, then
** diagnose the conflict. It will warn and compile an extern
** declaration if both declarations are global, otherwise give an
** error.
/* If a static declaration follows a non-static declaration, then the result is undefined.
** Most compilers choose to either give an error at compile time,
** or remove the extern property for a link time error if used.
*/
if (SymTab == SymTab0 &&
(Flags & SC_EXTERN) == 0 &&
(Entry->Flags & SC_EXTERN) != 0) {
Warning ("Static declaration of '%s' follows non-static declaration", Name);
Error ("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) {
Expand All @@ -1360,8 +1359,12 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags)
*/
if (Entry->Owner == SymTab0) {
if ((Flags & SC_STORAGE) == 0) {
/* Linkage must be unchanged */
/* Linkage must be unchanged.
** The C standard specifies that a later extern declaration will be ignored,
** and will use the previous linkage instead. Giving a warning for this case.
*/
Flags &= ~SC_EXTERN;
Warning ("Extern declaration of '%s' follows static declaration, extern ignored", Name);
} else {
Error ("Non-static declaration of '%s' follows static declaration", Name);
}
Expand Down
7 changes: 3 additions & 4 deletions test/val/decl-static-extern.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@

/*
see: https://github.com/cc65/cc65/issues/191
https://github.com/cc65/cc65/issues/2111
*/

#pragma warn(error, on)

static int n = 0;
extern int n; /* should not give an error */
static int n; /* should not give an error */
extern int n; /* extern is ignored, gives a warning but keeps previous static definiton */
static int n; /* no error or warning, the previous static is still in effect */

int main(void)
{
Expand Down

0 comments on commit 55723f4

Please sign in to comment.