When a symbol is multiply declared, form the composite type.

Previously, it generally just used the later type (except for function types where only the earlier one included a prototype). One effect of this is that if a global array is first declared with a size and then redeclared without one, the size information is lost, causing the proper space not to be allocated.

See C17 section 6.2.7 p4.

Here is an example affected by the array issue (dump the object file to see the size allocated):

int foo[50];
int foo[];
This commit is contained in:
Stephen Heumann 2022-10-30 18:54:40 -05:00
parent d4c4d18a55
commit 9a7dc23c5d
2 changed files with 10 additions and 4 deletions

View File

@ -2040,12 +2040,10 @@ if space <> fieldListSpace then begin {are we defining a function?}
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;
if not itype^.prototyped then begin
itype^.prototyped := cs^.itype^.prototyped;
itype^.parameterList := cs^.itype^.parameterList;
end; {if}
end; {if}
end {if}
else if (itype <> nil) and (itype^.kind in [structType,unionType])
@ -2059,6 +2057,9 @@ if space <> fieldListSpace then begin {are we defining a function?}
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;
end; {if}
@ -2072,6 +2073,9 @@ if class = staticsy then {statics go in the global symbol table}
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}

View File

@ -1962,6 +1962,8 @@ int foo(int[42]);
216. Preprocessing directive names could be subject to macro replacement, potentially altering their behavior (e.g. due to a definition like "#define ifdef ifndef"). Now directive names are not expanded as macros, even if there is a macro of the same name.
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.
-- Bugs from C 2.1.0 that have been fixed -----------------------------------
1. In some situations, fread() reread the first 1K or so of the file.