Global uninitialized variable is only a tentative definition.
Closes #204
This commit is contained in:
@@ -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 */
|
||||||
|
|||||||
Reference in New Issue
Block a user