mirror of
https://github.com/byteworksinc/ORCA-C.git
synced 2025-01-01 13:29:32 +00:00
Revise NewSymbol to more closely align with standards.
Function declarations within a block are now entered within its symbol table rather than moved to the global one. Several error checks are also added or tightened. This fixes at least one bug: if a function declared within a block had the same name as a variable in an outer scope, the symbol table entry for that variable could be corrupted, leading to spurious errors or incorrect code generation. This example program illustrates the problem: /* This should compile without errors and return 2 */ int f(void) {return 1;} int g(void) {return 2;} int main(void) { int (*f)(void) = g; { int f(void); } f = g; return f(); } Errors now detected include: *Duplicate declarations of a static variable within a block (with the second one initialized) *Duplicate declarations of the same variable as static and non-static *Declaration of the same identifier as a typedef and a variable (at file scope)
This commit is contained in:
parent
d3ba8b5551
commit
83147655d2
67
Symbol.pas
67
Symbol.pas
@ -2009,6 +2009,7 @@ var
|
||||
cs: identPtr; {current symbol}
|
||||
hashPtr: ^identPtr; {pointer to hash bucket in symbol table}
|
||||
i: integer; {loop variable}
|
||||
isFunction: boolean; {is this the symbol for a function?}
|
||||
isGlobal: boolean; {are we using the global table?}
|
||||
lUseGlobalPool: boolean; {use the global symbol pool?}
|
||||
needSymbol: boolean; {do we need to declare it?}
|
||||
@ -2020,68 +2021,45 @@ begin {NewSymbol}
|
||||
needSymbol := true; {assume we need a symbol}
|
||||
cs := nil; {no current symbol found}
|
||||
isGlobal := false; {set up defaults}
|
||||
isFunction := false;
|
||||
lUseGlobalPool := useGlobalPool;
|
||||
tk.name := name;
|
||||
tk.symbolPtr := nil;
|
||||
if space <> fieldListSpace then begin {are we defining a function?}
|
||||
if (itype <> nil) and (itype^.kind = functionType) then begin
|
||||
isGlobal := true;
|
||||
useGlobalPool := true;
|
||||
isFunction := true;
|
||||
if class in [autosy, ident] then
|
||||
class := externsy;
|
||||
if not lUseGlobalPool then begin
|
||||
np := pointer(Malloc(length(name^)+1));
|
||||
CopyString(pointer(np), pointer(name));
|
||||
tk.name := np;
|
||||
name := np;
|
||||
end; {if}
|
||||
cs := FindSymbol(tk, space, false, true);
|
||||
if cs <> nil then begin
|
||||
if cs^.state = defined then
|
||||
if state = defined then
|
||||
Error(42);
|
||||
if cs^.itype <> nil then
|
||||
itype := MakeCompositeType(cs^.itype, itype);
|
||||
p := cs;
|
||||
needSymbol := false;
|
||||
end; {if}
|
||||
end {if}
|
||||
else if (itype <> nil) and (itype^.kind in [structType,unionType])
|
||||
and (itype^.fieldList = nil) and doingParameters then begin
|
||||
useGlobalPool := true;
|
||||
end; {else if}
|
||||
cs := FindSymbol(tk, space, true, false); {check for duplicates}
|
||||
cs := FindSymbol(tk, space, true, true); {check for duplicates}
|
||||
if cs <> nil then begin
|
||||
if (not CompTypes(cs^.itype, itype))
|
||||
if ((itype = nil)
|
||||
or (cs^.itype = nil)
|
||||
or (not CompTypes(cs^.itype, itype))
|
||||
or ((cs^.state = initialized) and (state = initialized))
|
||||
or (globalTable <> table) then
|
||||
if (not doingParameters) or (cs^.state <> declared) then
|
||||
Error(42);
|
||||
if itype <> nil then
|
||||
if cs^.itype <> nil then
|
||||
itype := MakeCompositeType(cs^.itype, itype);
|
||||
p := cs;
|
||||
needSymbol := false;
|
||||
or ((class = typedefsy) <> (cs^.class = typedefsy))
|
||||
or ((globalTable <> table)
|
||||
and ((class <> externsy) or (cs^.class <> externsy))))
|
||||
and ((not doingParameters) or (cs^.state <> declared))
|
||||
then
|
||||
Error(42)
|
||||
else begin
|
||||
itype := MakeCompositeType(cs^.itype, itype);
|
||||
p := cs;
|
||||
needSymbol := false;
|
||||
end; {else}
|
||||
end; {if}
|
||||
end; {if}
|
||||
if class = staticsy then {statics go in the global symbol table}
|
||||
if not isGLobal then
|
||||
if not isFunction then
|
||||
if globalTable <> table then begin
|
||||
cs := FindSymbol(tk, space, true, true);
|
||||
if cs <> nil then begin {check for duplicates}
|
||||
if (not CompTypes(cs^.itype, itype))
|
||||
or ((cs^.state = defined) and (state <> initialized))
|
||||
or (cs^.state = initialized) then
|
||||
Error(42);
|
||||
if itype <> nil then
|
||||
if cs^.itype <> nil then
|
||||
itype := MakeCompositeType(cs^.itype, itype);
|
||||
p := cs;
|
||||
needSymbol := false;
|
||||
end; {if}
|
||||
isGlobal := true; {note that we will use the global table}
|
||||
useGlobalPool := true;
|
||||
np := pointer(GMalloc(length(name^)+6));
|
||||
np := pointer(GMalloc(length(name^)+6)); {form static name}
|
||||
np^[0] := chr(5+length(name^));
|
||||
for i := 1 to 5 do
|
||||
np^[i] := table^.staticNum[i];
|
||||
@ -2096,6 +2074,7 @@ if needSymbol then begin
|
||||
p^.state := state; {set the state}
|
||||
{p^.isForwardDeclared := false;} {assume no forward declarations are used}
|
||||
p^.name := name; {record the name}
|
||||
{p^.next := nil;}
|
||||
if space <> fieldListSpace then {insert the symbol in the hash bucket}
|
||||
begin
|
||||
if itype = nil then
|
||||
@ -2108,9 +2087,7 @@ if needSymbol then begin
|
||||
hashPtr := pointer(ord4(hashPtr) + 4*(hashSize+1));
|
||||
p^.next := hashPtr^;
|
||||
hashPtr^ := p;
|
||||
end {if}
|
||||
else
|
||||
p^.next := nil;
|
||||
end; {if}
|
||||
end; {if}
|
||||
if space = fieldListSpace then {check and set the storage class}
|
||||
p^.storage := none
|
||||
|
2
cc.notes
2
cc.notes
@ -1964,6 +1964,8 @@ int foo(int[42]);
|
||||
|
||||
217. If there were multiple declarations of a variable with internal or external linkage, only the type from the latest declaration would be used, rather than properly forming the composite type from the various declarations. If a global array was first declared with a size specified and subsequently redeclared without a size, this could cause the proper storage not to be allocated for it.
|
||||
|
||||
218. If a function declared within a block had the same name as a variable in an outer scope, the symbol table entry for that variable could be corrupted, leading to spurious errors or incorrect code generation.
|
||||
|
||||
-- Bugs from C 2.1.0 that have been fixed -----------------------------------
|
||||
|
||||
1. In some situations, fread() reread the first 1K or so of the file.
|
||||
|
Loading…
Reference in New Issue
Block a user