Detect and give errors for various illegal uses of _Alignas.

This commit is contained in:
Stephen Heumann 2020-01-19 17:06:01 -06:00
parent a130e79929
commit 49dea49cb8
2 changed files with 40 additions and 11 deletions

View File

@ -177,7 +177,9 @@ var
{-------------------------------------} {-------------------------------------}
storageClass: tokenEnum; {storage class of the declaration} storageClass: tokenEnum; {storage class of the declaration}
{ typeSpec: typePtr; (in CCommon) {type specifier} { typeSpec: typePtr; (in CCommon) {type specifier}
functionSpecifiers: tokenSet; {function specifiers in the declaration} declarationModifiers: tokenSet; {all storage class specifiers, type }
{qualifiers, function specifiers, & }
{alignment specifiers in declaration}
{syntactic classes of tokens} {syntactic classes of tokens}
{---------------------------} {---------------------------}
@ -2544,7 +2546,9 @@ procedure DeclarationSpecifiers (allowedTokens: tokenSet;
{ skipDeclarator - for enum,struct,union with no } { skipDeclarator - for enum,struct,union with no }
{ declarator } { declarator }
{ typespec - type specifier } { typespec - type specifier }
{ functionSpecifiers - function specifiers in this decl. } { declarationModifiers - all storage class specifiers, }
{ type qualifiers, function specifiers, and }
{ alignment specifiers in this declaration }
label 1,2,3; label 1,2,3;
@ -2570,7 +2574,7 @@ var
myIsForwardDeclared: boolean; {value of isForwardDeclared to generate} myIsForwardDeclared: boolean; {value of isForwardDeclared to generate}
mySkipDeclarator: boolean; {value of skipDeclarator to generate} mySkipDeclarator: boolean; {value of skipDeclarator to generate}
myTypeSpec: typePtr; {value of typeSpec to generate} myTypeSpec: typePtr; {value of typeSpec to generate}
myFunctionSpecifiers: tokenSet; {function specifiers in this declaration} myDeclarationModifiers: tokenSet; {all modifiers in this declaration}
procedure FieldList (tp: typePtr; kind: typeKind); procedure FieldList (tp: typePtr; kind: typeKind);
@ -2592,6 +2596,7 @@ var
maxDisp: longint; {for determining union sizes} maxDisp: longint; {for determining union sizes}
variable: identPtr; {variable being defined} variable: identPtr; {variable being defined}
didFlexibleArray: boolean; {have we seen a flexible array member?} didFlexibleArray: boolean; {have we seen a flexible array member?}
alignmentSpecified: boolean; {was alignment explicitly specified?}
begin {FieldList} begin {FieldList}
ldoingParameters := doingParameters; {allow fields in K&R dec. area} ldoingParameters := doingParameters; {allow fields in K&R dec. area}
@ -2612,6 +2617,7 @@ var
end; {if} end; {if}
typeSpec := wordPtr; {default type specifier is an integer} typeSpec := wordPtr; {default type specifier is an integer}
DeclarationSpecifiers(specifierQualifierListElement, ident); DeclarationSpecifiers(specifierQualifierListElement, ident);
alignmentSpecified := _Alignassy in declarationModifiers;
if not skipDeclarator then if not skipDeclarator then
repeat {declare the variables...} repeat {declare the variables...}
if didFlexibleArray then if didFlexibleArray then
@ -2664,6 +2670,8 @@ var
[cgByte,cgUByte,cgWord,cgUWord,cgLong,cgULong]) [cgByte,cgUByte,cgWord,cgUWord,cgLong,cgULong])
or (expressionValue > tPtr^.size*8) then or (expressionValue > tPtr^.size*8) then
Error(115); Error(115);
if alignmentSpecified then
Error(142);
end {if} end {if}
else if variable <> nil then begin else if variable <> nil then begin
if bitdisp <> 0 then begin if bitdisp <> 0 then begin
@ -2792,7 +2800,7 @@ begin {DeclarationSpecifiers}
myTypeSpec := typeSpec; myTypeSpec := typeSpec;
myIsForwardDeclared := false; {not doing a forward reference (yet)} myIsForwardDeclared := false; {not doing a forward reference (yet)}
mySkipDeclarator := false; {declarations are required (so far)} mySkipDeclarator := false; {declarations are required (so far)}
myFunctionSpecifiers := []; myDeclarationModifiers := [];
typeSpecifiers := []; typeSpecifiers := [];
typeDone := false; typeDone := false;
isConstant := false; isConstant := false;
@ -2800,6 +2808,7 @@ while token.kind in allowedTokens do begin
case token.kind of case token.kind of
{storage class specifiers} {storage class specifiers}
autosy,externsy,registersy,staticsy,typedefsy: begin autosy,externsy,registersy,staticsy,typedefsy: begin
myDeclarationModifiers := myDeclarationModifiers + [token.kind];
if storageClass <> ident then begin if storageClass <> ident then begin
if typeDone or (typeSpecifiers <> []) then if typeDone or (typeSpecifiers <> []) then
UnexpectedTokenError(expectedNext) UnexpectedTokenError(expectedNext)
@ -2829,31 +2838,37 @@ while token.kind in allowedTokens do begin
end; end;
_Thread_localsy: begin _Thread_localsy: begin
myDeclarationModifiers := myDeclarationModifiers + [token.kind];
Error(139); Error(139);
NextToken; NextToken;
end; end;
{function specifiers} {function specifiers}
inlinesy,_Noreturnsy,asmsy,pascalsy: begin inlinesy,_Noreturnsy,asmsy,pascalsy: begin
myFunctionSpecifiers := myFunctionSpecifiers + [token.kind]; myDeclarationModifiers := myDeclarationModifiers + [token.kind];
NextToken; NextToken;
end; end;
{type qualifiers} {type qualifiers}
constsy: begin constsy: begin
myDeclarationModifiers := myDeclarationModifiers + [token.kind];
isConstant := true; isConstant := true;
NextToken; NextToken;
end; end;
volatilesy: begin volatilesy: begin
myDeclarationModifiers := myDeclarationModifiers + [token.kind];
volatile := true; volatile := true;
NextToken; NextToken;
end; end;
restrictsy: restrictsy: begin
myDeclarationModifiers := myDeclarationModifiers + [token.kind];
NextToken; NextToken;
end;
_Atomicsy: begin _Atomicsy: begin
myDeclarationModifiers := myDeclarationModifiers + [token.kind];
Error(137); Error(137);
NextToken; NextToken;
if token.kind = lparench then begin if token.kind = lparench then begin
@ -3060,6 +3075,7 @@ while token.kind in allowedTokens do begin
{alignment specifier} {alignment specifier}
_Alignassy: begin _Alignassy: begin
myDeclarationModifiers := myDeclarationModifiers + [token.kind];
NextToken; NextToken;
Match(lparench, 13); Match(lparench, 13);
if token.kind in specifierQualifierListElement then begin if token.kind in specifierQualifierListElement then begin
@ -3086,7 +3102,7 @@ while token.kind in allowedTokens do begin
isForwardDeclared := myIsForwardDeclared; isForwardDeclared := myIsForwardDeclared;
skipDeclarator := mySkipDeclarator; skipDeclarator := mySkipDeclarator;
typeSpec := myTypeSpec; typeSpec := myTypeSpec;
functionSpecifiers := myFunctionSpecifiers; declarationModifiers := myDeclarationModifiers;
if isconstant then begin {handle a constant type} if isconstant then begin {handle a constant type}
new(tPtr); new(tPtr);
if typeSpec^.kind in [structType,unionType] then begin if typeSpec^.kind in [structType,unionType] then begin
@ -3123,6 +3139,7 @@ var
isAsm: boolean; {has the asm modifier been used?} isAsm: boolean; {has the asm modifier been used?}
isInline: boolean; {has the inline specifier been used?} isInline: boolean; {has the inline specifier been used?}
isNoreturn: boolean; {has the _Noreturn specifier been used?} isNoreturn: boolean; {has the _Noreturn specifier been used?}
alignmentSpecified: boolean; {was an alignment explicitly specified?}
lDoingParameters: boolean; {local copy of doingParameters} lDoingParameters: boolean; {local copy of doingParameters}
lisPascal: boolean; {local copy of isPascal} lisPascal: boolean; {local copy of isPascal}
lp,tlp,tlp2: identPtr; {for tracing parameter list} lp,tlp,tlp2: identPtr; {for tracing parameter list}
@ -3365,10 +3382,11 @@ typeSpec := wordPtr; {default type specifier is an integer}
if token.kind in declarationSpecifiersElement then if token.kind in declarationSpecifiersElement then
typeFound := true; typeFound := true;
DeclarationSpecifiers(declarationSpecifiersElement, ident); DeclarationSpecifiers(declarationSpecifiersElement, ident);
isPascal := pascalsy in functionSpecifiers; isPascal := pascalsy in declarationModifiers;
isAsm := asmsy in functionSpecifiers; isAsm := asmsy in declarationModifiers;
isInline := inlinesy in functionSpecifiers; isInline := inlinesy in declarationModifiers;
isNoreturn := _Noreturnsy in functionSpecifiers; isNoreturn := _Noreturnsy in declarationModifiers;
alignmentSpecified := _Alignassy in declarationModifiers;
lisPascal := isPascal; lisPascal := isPascal;
if not skipDeclarator then begin if not skipDeclarator then begin
variable := nil; variable := nil;
@ -3417,6 +3435,8 @@ if isFunction then begin
if isInline then if isInline then
if storageClass <> staticsy then if storageClass <> staticsy then
Error(120); Error(120);
if alignmentSpecified then
Error(142);
if isPascal then begin {reverse prototyped parameters} if isPascal then begin {reverse prototyped parameters}
p1 := fnType^.parameterList; p1 := fnType^.parameterList;
if p1 <> nil then begin if p1 <> nil then begin
@ -3640,6 +3660,9 @@ if isFunction then begin
{handle a variable declaration} {handle a variable declaration}
else {if not isFunction then} begin else {if not isFunction then} begin
noFDefinitions := true; noFDefinitions := true;
if alignmentSpecified then
if storageClass in [typedefsy,registersy] then
Error(142);
if not SkipDeclarator then if not SkipDeclarator then
repeat repeat
if isPascal then begin if isPascal then begin
@ -3886,6 +3909,11 @@ begin {TypeName}
typeSpec := wordPtr; typeSpec := wordPtr;
DeclarationSpecifiers(specifierQualifierListElement, rparench); DeclarationSpecifiers(specifierQualifierListElement, rparench);
{_Alignas is not allowed in most uses of type names. }
{It would be allowed in compound literals, if we supported them.}
if _Alignassy in declarationModifiers then
Error(142);
{handle the abstract-declarator part} {handle the abstract-declarator part}
tl := nil; {no types so far} tl := nil; {no types so far}
AbstractDeclarator; {create the type list} AbstractDeclarator; {create the type list}

View File

@ -663,6 +663,7 @@ if list or (numErr <> 0) then begin
139: msg := @'thread-local storage is not supported by ORCA/C'; 139: msg := @'thread-local storage is not supported by ORCA/C';
140: msg := @'unexpected token'; 140: msg := @'unexpected token';
141: msg := @'_Noreturn specifier is only allowed on functions'; 141: msg := @'_Noreturn specifier is only allowed on functions';
142: msg := @'_Alignas may not be used in this declaration or type name';
otherwise: Error(57); otherwise: Error(57);
end; {case} end; {case}
writeln(msg^); writeln(msg^);