mirror of
https://github.com/byteworksinc/ORCA-C.git
synced 2025-01-04 02:30:40 +00:00
Give an error for declarations that do not declare anything.
This enforces the constraint from C17 section 6.7 p2 that declarations "shall declare at least a declarator (other than the parameters of a function or the members of a structure or union), a tag, or the members of an enumeration." Somewhat relaxed rules are used for enums in the default loose type checking mode, similar to what GCC and Clang do.
This commit is contained in:
parent
995ded07a5
commit
f263066f61
32
Parser.pas
32
Parser.pas
@ -196,6 +196,7 @@ var
|
|||||||
compoundLiteralNumber: integer; {number of compound literal}
|
compoundLiteralNumber: integer; {number of compound literal}
|
||||||
compoundLiteralToAllocate: identPtr; {compound literal that needs space allocated}
|
compoundLiteralToAllocate: identPtr; {compound literal that needs space allocated}
|
||||||
vaInfoLLN: integer; {label number of internal va info (0 for none)}
|
vaInfoLLN: integer; {label number of internal va info (0 for none)}
|
||||||
|
declaredTagOrEnumConst: boolean; {was a tag or enum const declared?}
|
||||||
|
|
||||||
{parameter processing variables}
|
{parameter processing variables}
|
||||||
{------------------------------}
|
{------------------------------}
|
||||||
@ -2755,6 +2756,8 @@ procedure DeclarationSpecifiers (var declSpecifiers: declSpecifiersRecord;
|
|||||||
{ referencing a forward struct/union? }
|
{ referencing a forward struct/union? }
|
||||||
{ skipDeclarator - for enum,struct,union with no }
|
{ skipDeclarator - for enum,struct,union with no }
|
||||||
{ declarator }
|
{ declarator }
|
||||||
|
{ declaredTagOrEnumConst - set if a tag or an enum const }
|
||||||
|
{ is declared (otherwise unchanged) }
|
||||||
|
|
||||||
label 1,2,3;
|
label 1,2,3;
|
||||||
|
|
||||||
@ -3178,9 +3181,16 @@ while token.kind in allowedTokens do begin
|
|||||||
end {if}
|
end {if}
|
||||||
else
|
else
|
||||||
if (variable <> nil) and (variable^.itype^.kind = enumType) then
|
if (variable <> nil) and (variable^.itype^.kind = enumType) then
|
||||||
goto 1
|
begin
|
||||||
else if not looseTypeChecks then
|
if looseTypeChecks then
|
||||||
Error(171);
|
declaredTagOrEnumConst := true;
|
||||||
|
goto 1;
|
||||||
|
end {if}
|
||||||
|
else begin
|
||||||
|
declaredTagOrEnumConst := true;
|
||||||
|
if not looseTypeChecks then
|
||||||
|
Error(171);
|
||||||
|
end; {else}
|
||||||
tPtr := pointer(Malloc(sizeof(typeRecord)));
|
tPtr := pointer(Malloc(sizeof(typeRecord)));
|
||||||
tPtr^.size := cgWordSize;
|
tPtr^.size := cgWordSize;
|
||||||
tPtr^.saveDisp := 0;
|
tPtr^.saveDisp := 0;
|
||||||
@ -3193,6 +3203,7 @@ while token.kind in allowedTokens do begin
|
|||||||
Error(9);
|
Error(9);
|
||||||
enumVal := 0; {set the default value}
|
enumVal := 0; {set the default value}
|
||||||
if token.kind = lbracech then begin
|
if token.kind = lbracech then begin
|
||||||
|
declaredTagOrEnumConst := true;
|
||||||
NextToken; {skip the '{'}
|
NextToken; {skip the '{'}
|
||||||
repeat {declare the enum constants}
|
repeat {declare the enum constants}
|
||||||
tPtr := pointer(Malloc(sizeof(typeRecord)));
|
tPtr := pointer(Malloc(sizeof(typeRecord)));
|
||||||
@ -3263,6 +3274,10 @@ while token.kind in allowedTokens do begin
|
|||||||
structPtr := FindSymbol(token, tagSpace, true, true);
|
structPtr := FindSymbol(token, tagSpace, true, true);
|
||||||
ttoken := token; {record the structure name}
|
ttoken := token; {record the structure name}
|
||||||
NextToken; {skip the structure name}
|
NextToken; {skip the structure name}
|
||||||
|
if (token.kind = lbracech) or
|
||||||
|
((token.kind = semicolonch) and (myDeclarationModifiers = []))
|
||||||
|
then
|
||||||
|
declaredTagOrEnumConst := true;
|
||||||
if structPtr = nil then begin {if the name hasn't been defined then...}
|
if structPtr = nil then begin {if the name hasn't been defined then...}
|
||||||
if token.kind <> lbracech then
|
if token.kind <> lbracech then
|
||||||
if (token.kind <> semicolonch) or
|
if (token.kind <> semicolonch) or
|
||||||
@ -3289,19 +3304,23 @@ while token.kind in allowedTokens do begin
|
|||||||
structPtr := NewSymbol(ttoken.name, structTypePtr, ident,
|
structPtr := NewSymbol(ttoken.name, structTypePtr, ident,
|
||||||
tagSpace, defined);
|
tagSpace, defined);
|
||||||
structTypePtr^.sName := structPtr^.name;
|
structTypePtr^.sName := structPtr^.name;
|
||||||
|
declaredTagOrEnumConst := true;
|
||||||
end;
|
end;
|
||||||
end {if}
|
end {if}
|
||||||
{the name has been defined, so...}
|
{the name has been defined, so...}
|
||||||
else if structPtr^.itype^.kind <> tKind then begin
|
else if structPtr^.itype^.kind <> tKind then begin
|
||||||
Error(42); {it's an error if it's not a struct}
|
Error(42); {it's an error if it's not a struct}
|
||||||
|
declaredTagOrEnumConst := true; {avoid extra errors}
|
||||||
structPtr := nil;
|
structPtr := nil;
|
||||||
end {else}
|
end {else}
|
||||||
else begin {record the existing structure type}
|
else begin {record the existing structure type}
|
||||||
structTypePtr := structPtr^.itype;
|
structTypePtr := structPtr^.itype;
|
||||||
end; {else}
|
end; {else}
|
||||||
end {if}
|
end {if}
|
||||||
else if token.kind <> lbracech then
|
else if token.kind <> lbracech then begin
|
||||||
Error(9); {its an error if there's no name or struct}
|
Error(9); {its an error if there's no name or struct}
|
||||||
|
declaredTagOrEnumConst := true; {avoid extra errors}
|
||||||
|
end; {else if}
|
||||||
2: if token.kind = lbracech then {handle a structure definition...}
|
2: if token.kind = lbracech then {handle a structure definition...}
|
||||||
begin {error if we already have one!}
|
begin {error if we already have one!}
|
||||||
if (structTypePtr <> defaultStruct)
|
if (structTypePtr <> defaultStruct)
|
||||||
@ -3651,12 +3670,17 @@ inhibitHeader := true; {block imbedded includes in headers}
|
|||||||
lUseGlobalPool := useGlobalPool;
|
lUseGlobalPool := useGlobalPool;
|
||||||
{handle a TypeSpecifier/declarator}
|
{handle a TypeSpecifier/declarator}
|
||||||
typeFound := token.kind in declarationSpecifiersElement;
|
typeFound := token.kind in declarationSpecifiersElement;
|
||||||
|
declaredTagOrEnumConst := false;
|
||||||
DeclarationSpecifiers(declSpecifiers, declarationSpecifiersElement, ident);
|
DeclarationSpecifiers(declSpecifiers, declarationSpecifiersElement, ident);
|
||||||
isPascal := pascalsy in declSpecifiers.declarationModifiers;
|
isPascal := pascalsy in declSpecifiers.declarationModifiers;
|
||||||
isAsm := asmsy in declSpecifiers.declarationModifiers;
|
isAsm := asmsy in declSpecifiers.declarationModifiers;
|
||||||
isInline := inlinesy in declSpecifiers.declarationModifiers;
|
isInline := inlinesy in declSpecifiers.declarationModifiers;
|
||||||
isNoreturn := _Noreturnsy in declSpecifiers.declarationModifiers;
|
isNoreturn := _Noreturnsy in declSpecifiers.declarationModifiers;
|
||||||
alignmentSpecified := _Alignassy in declSpecifiers.declarationModifiers;
|
alignmentSpecified := _Alignassy in declSpecifiers.declarationModifiers;
|
||||||
|
if token.kind = semicolonch then
|
||||||
|
if not doingPrototypes then
|
||||||
|
if not declaredTagOrEnumConst then
|
||||||
|
Error(176);
|
||||||
if not skipDeclarator then begin
|
if not skipDeclarator then begin
|
||||||
variable := nil;
|
variable := nil;
|
||||||
Declarator(declSpecifiers, variable, variableSpace, doingPrototypes);
|
Declarator(declSpecifiers, variable, variableSpace, doingPrototypes);
|
||||||
|
@ -759,6 +759,7 @@ if list or (numErr <> 0) then begin
|
|||||||
173: msg := @'''#'' must be followed by a macro parameter';
|
173: msg := @'''#'' must be followed by a macro parameter';
|
||||||
174: msg := @'''__VA_ARGS__'' may only be used in a variadic macro';
|
174: msg := @'''__VA_ARGS__'' may only be used in a variadic macro';
|
||||||
175: msg := @'duplicate macro parameter name';
|
175: msg := @'duplicate macro parameter name';
|
||||||
|
176: msg := @'declarator expected';
|
||||||
otherwise: Error(57);
|
otherwise: Error(57);
|
||||||
end; {case}
|
end; {case}
|
||||||
writeln(msg^);
|
writeln(msg^);
|
||||||
|
Loading…
Reference in New Issue
Block a user