Implement strict type checking for enum types.

If strict type checking is enabled, this will prohibit redefinition of enums, like:

enum E {a,b,c};
enum E {x,y,z};

It also prohibits use of an "enum E" type specifier if the enum has not been previously declared (with its constants).

These things were historically supported by ORCA/C, but they are prohibited by constraints in section 6.7.2.3 of C99 and later. (The C90 wording was different and less clear, but I think they were not intended to be valid there either.)
This commit is contained in:
Stephen Heumann 2022-07-18 21:55:07 -05:00
parent d576f19ede
commit 6e3fca8b82
3 changed files with 15 additions and 6 deletions

View File

@ -3185,10 +3185,16 @@ while token.kind in allowedTokens do begin
NextToken; NextToken;
variable := variable :=
FindSymbol(ttoken, tagSpace, token.kind = lbracech, true); FindSymbol(ttoken, tagSpace, token.kind = lbracech, true);
if variable <> nil then if token.kind = lbracech then begin
if variable^.itype^.kind = enumType then if (variable <> nil) and (variable^.itype^.kind = enumType) then
if token.kind <> lbracech then if not looseTypeChecks then
goto 1; Error(53);
end {if}
else
if (variable <> nil) and (variable^.itype^.kind = enumType) then
goto 1
else if not looseTypeChecks then
Error(171);
tPtr := pointer(Malloc(sizeof(typeRecord))); tPtr := pointer(Malloc(sizeof(typeRecord)));
tPtr^.size := cgWordSize; tPtr^.size := cgWordSize;
tPtr^.saveDisp := 0; tPtr^.saveDisp := 0;

View File

@ -633,7 +633,7 @@ if list or (numErr <> 0) then begin
50: msg := @'only parameters or types may be declared here'; 50: msg := @'only parameters or types may be declared here';
51: msg := @'lint: undefined function'; 51: msg := @'lint: undefined function';
52: msg := @'you cannot initialize a type'; 52: msg := @'you cannot initialize a type';
53: msg := @'the structure or union has already been defined'; 53: msg := @'the struct, union, or enum has already been defined';
54: msg := @'bit fields must be less than 32 bits wide'; 54: msg := @'bit fields must be less than 32 bits wide';
55: msg := @'a value cannot be zero bits wide'; 55: msg := @'a value cannot be zero bits wide';
{56: msg := @'bit fields in unions are not supported by ORCA/C';} {56: msg := @'bit fields in unions are not supported by ORCA/C';}
@ -751,6 +751,7 @@ if list or (numErr <> 0) then begin
168: msg := @'malformed hexadecimal floating constant'; 168: msg := @'malformed hexadecimal floating constant';
169: msg := @'struct or array may not contain a struct with a flexible array member'; 169: msg := @'struct or array may not contain a struct with a flexible array member';
170: msg := @'lint: no whitespace after macro name'; 170: msg := @'lint: no whitespace after macro name';
171: msg := @'use of an incomplete enum type is not allowed';
otherwise: Error(57); otherwise: Error(57);
end; {case} end; {case}
writeln(msg^); writeln(msg^);

View File

@ -606,7 +606,7 @@ Bit 2 (a value of 4) controls whether spurious tokens are allowed after an #endi
Bit 4 (a value of 16) controls whether ORCA/C follows C99-style rules for declaration placement and block scopes. See "New Language Features," above. Bit 4 (a value of 16) controls whether ORCA/C follows C99-style rules for declaration placement and block scopes. See "New Language Features," above.
Bit 5 (a value of 32) controls whether type compatibility checks should strictly follow the C standards, or whether looser rules should be used in certain cases. If this bit is set, the looser rules will be followed, matching ORCA/C's historical behavior. Bit 5 is currently set by default, but new code should not rely on this. There are four situations where bit 5 currently has an effect: Bit 5 (a value of 32) controls whether type compatibility checks should strictly follow the C standards, or whether looser rules should be used in certain cases. If this bit is set, the looser rules will be followed, matching ORCA/C's historical behavior. Bit 5 is currently set by default, but new code should not rely on this. There are five situations where bit 5 currently has an effect:
First, setting bit 5 causes pointer assignments that discard type qualifiers to be allowed. For example, this affects an assignment from an expression of type "const int *" to a variable of type "int *", because it discards the "const" qualifier from the type pointed to. These assignments are prohibited by the C standards, but ORCA/C historically allowed them. If bit 5 is set it will still allow them, but if bit 5 is clear it will give an error. First, setting bit 5 causes pointer assignments that discard type qualifiers to be allowed. For example, this affects an assignment from an expression of type "const int *" to a variable of type "int *", because it discards the "const" qualifier from the type pointed to. These assignments are prohibited by the C standards, but ORCA/C historically allowed them. If bit 5 is set it will still allow them, but if bit 5 is clear it will give an error.
@ -616,6 +616,8 @@ Third, setting bit 5 causes certain comparisons involving pointers, as well as c
Fourth, setting bit 5 causes ORCA/C to treat basic types with the same representation as mutually compatible. This affects the following pairs of types: short and int, unsigned short and unsigned int, char and unsigned char. Historically, ORCA/C essentially treated each of these pairs as being the same type, so it never reported type conflicts between them. If bit 5 is set, it will continue to do so. If bit 5 is clear, it will treat all of the above types as distinct and mutually incompatible, as specified by the C standards. Fourth, setting bit 5 causes ORCA/C to treat basic types with the same representation as mutually compatible. This affects the following pairs of types: short and int, unsigned short and unsigned int, char and unsigned char. Historically, ORCA/C essentially treated each of these pairs as being the same type, so it never reported type conflicts between them. If bit 5 is set, it will continue to do so. If bit 5 is clear, it will treat all of the above types as distinct and mutually incompatible, as specified by the C standards.
Fifth, setting bit 5 allows enum types to be redefined within a single scope (with different constants) or used before their constants are defined. If bit 5 is clear, these things are prohibited, as specified by the C standards.
Note that _Generic expressions always use the stricter type compatibility rules for determining which association to use, regardless of the setting of bit 5. Note that _Generic expressions always use the stricter type compatibility rules for determining which association to use, regardless of the setting of bit 5.
(Mike Westerfield, Kelvin Sherlock, Stephen Heumann) (Mike Westerfield, Kelvin Sherlock, Stephen Heumann)