From 6e3fca8b828386f87bef63a06f72a23c5e724229 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Mon, 18 Jul 2022 21:55:07 -0500 Subject: [PATCH] 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.) --- Parser.pas | 14 ++++++++++---- Scanner.pas | 3 ++- cc.notes | 4 +++- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Parser.pas b/Parser.pas index 89985bd..3deb97c 100644 --- a/Parser.pas +++ b/Parser.pas @@ -3185,10 +3185,16 @@ while token.kind in allowedTokens do begin NextToken; variable := FindSymbol(ttoken, tagSpace, token.kind = lbracech, true); - if variable <> nil then - if variable^.itype^.kind = enumType then - if token.kind <> lbracech then - goto 1; + if token.kind = lbracech then begin + if (variable <> nil) and (variable^.itype^.kind = enumType) then + if not looseTypeChecks then + 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^.size := cgWordSize; tPtr^.saveDisp := 0; diff --git a/Scanner.pas b/Scanner.pas index 0061078..89462c1 100644 --- a/Scanner.pas +++ b/Scanner.pas @@ -633,7 +633,7 @@ if list or (numErr <> 0) then begin 50: msg := @'only parameters or types may be declared here'; 51: msg := @'lint: undefined function'; 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'; 55: msg := @'a value cannot be zero bits wide'; {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'; 169: msg := @'struct or array may not contain a struct with a flexible array member'; 170: msg := @'lint: no whitespace after macro name'; + 171: msg := @'use of an incomplete enum type is not allowed'; otherwise: Error(57); end; {case} writeln(msg^); diff --git a/cc.notes b/cc.notes index 30a8e96..328248c 100644 --- a/cc.notes +++ b/cc.notes @@ -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 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. @@ -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. +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. (Mike Westerfield, Kelvin Sherlock, Stephen Heumann)