mirror of
https://github.com/byteworksinc/ORCA-C.git
synced 2024-12-22 07:30:54 +00:00
Treat the fields of const structs as const-qualified.
This causes an error to be produced when trying to assign to these fields, which was being allowed before. It is also necessary for correct behavior of _Generic in some cases.
This commit is contained in:
parent
99f5e2fc87
commit
2f7e71cd24
@ -578,7 +578,8 @@ kind2 := t2^.kind;
|
||||
if tqConst in t1^.qualifiers then
|
||||
if genCode then
|
||||
if checkConst then
|
||||
Error(93);
|
||||
if kind2 <> definedType then
|
||||
Error(93);
|
||||
if kind2 = definedType then
|
||||
AssignmentConversion(t1, t2^.dType, false, 0, genCode, checkConst)
|
||||
else if kind1 = definedType then
|
||||
@ -2527,13 +2528,17 @@ label 1;
|
||||
|
||||
var
|
||||
ip: identPtr; {for scanning for the field}
|
||||
qualifiers: typeQualifierSet; {type qualifiers}
|
||||
|
||||
begin {DoSelection}
|
||||
expressionType := intPtr; {set defaults in case there is an error}
|
||||
size := 0;
|
||||
if tree^.token.class = identifier then begin
|
||||
while lType^.kind = definedType do
|
||||
qualifiers := lType^.qualifiers;
|
||||
while lType^.kind = definedType do begin
|
||||
lType := lType^.dType;
|
||||
qualifiers := qualifiers + lType^.qualifiers;
|
||||
end; {while}
|
||||
if lType^.kind in [structType,unionType] then begin
|
||||
ip := lType^.fieldList; {find a matching field}
|
||||
while ip <> nil do begin
|
||||
@ -2541,7 +2546,7 @@ if tree^.token.class = identifier then begin
|
||||
if ip^.isForwardDeclared then
|
||||
ResolveForwardReference(ip);
|
||||
size := ip^.disp; {match found - record parameters}
|
||||
expressionType := ip^.itype;
|
||||
expressionType := MakeQualifiedType(ip^.itype, qualifiers);
|
||||
bitDisp := ip^.bitDisp;
|
||||
bitSize := ip^.bitSize;
|
||||
isBitField := (bitSize+bitDisp) <> 0;
|
||||
|
44
Parser.pas
44
Parser.pas
@ -3257,51 +3257,13 @@ while token.kind in allowedTokens do begin
|
||||
3:
|
||||
isForwardDeclared := myIsForwardDeclared;
|
||||
skipDeclarator := mySkipDeclarator;
|
||||
typeSpec := myTypeSpec;
|
||||
declarationModifiers := myDeclarationModifiers;
|
||||
if typeSpec = nil then begin
|
||||
typeSpec := intPtr; {under C89, default type is int}
|
||||
if myTypeSpec = nil then begin
|
||||
myTypeSpec := intPtr; {under C89, default type is int}
|
||||
if (lint & lintC99Syntax) <> 0 then
|
||||
Error(151);
|
||||
end; {if}
|
||||
if typeQualifiers <> [] then begin {handle a qualified type}
|
||||
new(tPtr);
|
||||
if typeSpec^.kind in [structType,unionType] then begin
|
||||
with tPtr^ do begin
|
||||
size := typeSpec^.size;
|
||||
kind := definedType;
|
||||
dType := typeSpec;
|
||||
saveDisp := 0;
|
||||
qualifiers := typeQualifiers;
|
||||
end; {with}
|
||||
end {if}
|
||||
else begin
|
||||
tPtr^ := typeSpec^;
|
||||
tPtr^.qualifiers := tPtr^.qualifiers + typeQualifiers;
|
||||
end; {else}
|
||||
typeSpec := tPtr;
|
||||
{move array type quals to element type}
|
||||
myTypeSpec := typeSpec;
|
||||
while myTypeSpec^.kind = arrayType do begin
|
||||
new(tPtr);
|
||||
if myTypeSpec^.aType^.kind in [structType,unionType] then begin
|
||||
with tPtr^ do begin
|
||||
size := myTypeSpec^.aType^.size;
|
||||
kind := definedType;
|
||||
dType := myTypeSpec^.aType;
|
||||
saveDisp := 0;
|
||||
qualifiers := typeQualifiers;
|
||||
end; {with}
|
||||
end {if}
|
||||
else begin
|
||||
tPtr^ := myTypeSpec^.aType^;
|
||||
tPtr^.qualifiers := tPtr^.qualifiers + typeQualifiers;
|
||||
end; {else}
|
||||
myTypeSpec^.aType := tPtr;
|
||||
myTypeSpec^.qualifiers := []; {remove for C23}
|
||||
myTypeSpec := tPtr;
|
||||
end; {if}
|
||||
end; {if}
|
||||
typeSpec := MakeQualifiedType(myTypeSpec, typeQualifiers); {apply type qualifiers}
|
||||
end; {DeclarationSpecifiers}
|
||||
|
||||
|
||||
|
66
Symbol.pas
66
Symbol.pas
@ -158,6 +158,18 @@ function LabelToDisp (lab: integer): integer; extern;
|
||||
{ lab - label number }
|
||||
|
||||
|
||||
function MakeQualifiedType (origType: typePtr; qualifiers: typeQualifierSet):
|
||||
typePtr;
|
||||
|
||||
{ make a qualified version of a type }
|
||||
{ }
|
||||
{ parameters: }
|
||||
{ origType - the original type }
|
||||
{ qualifiers - the type qualifier(s) to add }
|
||||
{ }
|
||||
{ returns: pointer to the qualified type }
|
||||
|
||||
|
||||
function NewSymbol (name: stringPtr; itype: typePtr; class: tokenEnum;
|
||||
space: spaceType; state: stateKind): identPtr;
|
||||
|
||||
@ -1575,6 +1587,60 @@ constCharPtr^.qualifiers := [tqConst];
|
||||
end; {InitSymbol}
|
||||
|
||||
|
||||
function MakeQualifiedType {origType: typePtr; qualifiers: typeQualifierSet):
|
||||
typePtr};
|
||||
|
||||
{ make a qualified version of a type }
|
||||
{ }
|
||||
{ parameters: }
|
||||
{ origType - the original type }
|
||||
{ qualifiers - the type qualifier(s) to add }
|
||||
{ }
|
||||
{ returns: pointer to the qualified type }
|
||||
|
||||
var
|
||||
tp: typePtr; {the qualified type}
|
||||
elemType: typePtr; {array element type}
|
||||
|
||||
begin {MakeQualifiedType}
|
||||
if qualifiers <> [] then begin {make qualified version of type}
|
||||
tp := pointer(Malloc(sizeof(typeRecord)));
|
||||
if origType^.kind in [structType,unionType] then begin
|
||||
tp^.size := origType^.size;
|
||||
tp^.kind := definedType;
|
||||
tp^.dType := origType;
|
||||
tp^.saveDisp := 0;
|
||||
tp^.qualifiers := qualifiers;
|
||||
end {if}
|
||||
else begin
|
||||
tp^ := origType^;
|
||||
tp^.qualifiers := tp^.qualifiers + qualifiers;
|
||||
end; {else}
|
||||
MakeQualifiedType := tp;
|
||||
{move array type quals to element type}
|
||||
while tp^.kind = arrayType do begin
|
||||
elemType := pointer(Malloc(sizeof(typeRecord)));
|
||||
if tp^.aType^.kind in [structType,unionType] then begin
|
||||
elemType^.size := tp^.aType^.size;
|
||||
elemType^.kind := definedType;
|
||||
elemType^.dType := tp^.aType;
|
||||
elemType^.saveDisp := 0;
|
||||
elemType^.qualifiers := qualifiers;
|
||||
end {if}
|
||||
else begin
|
||||
elemType^ := tp^.aType^;
|
||||
elemType^.qualifiers := elemType^.qualifiers + qualifiers;
|
||||
end; {else}
|
||||
tp^.aType := elemType;
|
||||
tp^.qualifiers := []; {remove for C23}
|
||||
tp := elemType;
|
||||
end; {if}
|
||||
end {if}
|
||||
else
|
||||
MakeQualifiedType := origType;
|
||||
end; {MakeQualifiedType}
|
||||
|
||||
|
||||
function NewSymbol {name: stringPtr; itype: typePtr; class: tokenEnum;
|
||||
space: spaceType; state: stateKind): identPtr};
|
||||
|
||||
|
2
cc.notes
2
cc.notes
@ -1219,6 +1219,8 @@ int foo(int[42]);
|
||||
|
||||
(Devin Reade)
|
||||
|
||||
164. The fields of const-qualified structs and unions were not treated as being const-qualified. Neither were the members of arrays declared like "const T a", where T is a typedef'd array type. Now such fields and array members are treated as const-qualified, so assignments to them will give errors.
|
||||
|
||||
-- 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