Global uninitialized variable is only a tentative definition.

Closes #204
This commit is contained in:
Piotr Fusik
2017-02-13 21:04:45 +01:00
parent 1f12a06f7c
commit 730d01a25f

View File

@@ -154,7 +154,7 @@ static void Parse (void)
(Decl.StorageClass & (SC_EXTERN|SC_STATIC)) == SC_STATIC)) { (Decl.StorageClass & (SC_EXTERN|SC_STATIC)) == SC_STATIC)) {
/* We will allocate storage */ /* We will allocate storage */
Decl.StorageClass |= SC_STORAGE | SC_DEF; Decl.StorageClass |= SC_STORAGE;
} }
/* If this is a function declarator that is not followed by a comma /* If this is a function declarator that is not followed by a comma
@@ -187,6 +187,9 @@ static void Parse (void)
/* Allow initialization */ /* Allow initialization */
if (CurTok.Tok == TOK_ASSIGN) { if (CurTok.Tok == TOK_ASSIGN) {
/* This is a definition */
Entry->Flags |= SC_DEF;
/* We cannot initialize types of unknown size, or /* We cannot initialize types of unknown size, or
** void types in ISO modes. ** void types in ISO modes.
*/ */
@@ -234,18 +237,14 @@ static void Parse (void)
Entry->Flags &= ~(SC_STORAGE | SC_DEF); Entry->Flags &= ~(SC_STORAGE | SC_DEF);
} }
/* Allocate storage if it is still needed */ /* A global (including static) uninitialized variable
if (Entry->Flags & SC_STORAGE) { ** is only a tentative definition. For example, this is valid:
** int i;
/* Switch to the BSS segment */ ** int i;
g_usebss (); ** static int j;
** static int j = 42;
/* Define a label */ ** Code for these will be generated in FinishCompile.
g_defgloblabel (Entry->Name); */
/* Allocate space for uninitialized variable */
g_res (Size);
}
} }
} }
@@ -300,7 +299,7 @@ void Compile (const char* FileName)
struct tm* TM; struct tm* TM;
/* Since strftime is locale dependent, we need the abbreviated month names /* Since strftime is locale dependent, we need the abbreviated month names
** in english. ** in English.
*/ */
static const char MonthNames[12][4] = { static const char MonthNames[12][4] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jan", "Feb", "Mar", "Apr", "May", "Jun",
@@ -397,20 +396,26 @@ void Compile (const char* FileName)
void FinishCompile (void) void FinishCompile (void)
/* Emit literals, externals, debug info, do cleanup and optimizations */ /* Emit literals, externals, debug info, do cleanup and optimizations */
{ {
SymTable* SymTab; SymEntry* Entry;
SymEntry* Func;
/* Walk over all functions, doing cleanup, optimizations ... */ /* Walk over all global symbols:
SymTab = GetGlobalSymTab (); ** - for functions do cleanup, optimizations ...
Func = SymTab->SymHead; ** - generate code for uninitialized global variables
while (Func) { */
if (SymIsOutputFunc (Func)) { for (Entry = GetGlobalSymTab ()->SymHead; Entry; Entry = Entry->NextSym) {
if (SymIsOutputFunc (Entry)) {
/* Function which is defined and referenced or extern */ /* Function which is defined and referenced or extern */
MoveLiteralPool (Func->V.F.LitPool); MoveLiteralPool (Entry->V.F.LitPool);
CS_MergeLabels (Func->V.F.Seg->Code); CS_MergeLabels (Entry->V.F.Seg->Code);
RunOpt (Func->V.F.Seg->Code); RunOpt (Entry->V.F.Seg->Code);
} else if ((Entry->Flags & (SC_STORAGE | SC_DEF | SC_STATIC)) == (SC_STORAGE | SC_STATIC)) {
/* Tentative definition of uninitialized global variable */
g_usebss ();
g_defgloblabel (Entry->Name);
g_res (SizeOf (Entry->Type));
/* Mark as defined, so that it will be exported not imported */
Entry->Flags |= SC_DEF;
} }
Func = Func->NextSym;
} }
/* Output the literal pool */ /* Output the literal pool */