diff --git a/CCommon.pas b/CCommon.pas index 0c23aac..d327b48 100644 --- a/CCommon.pas +++ b/CCommon.pas @@ -91,6 +91,7 @@ const lintPragmas = $0008; {flag unknown pragmas} lintPrintf = $0010; {check printf/scanf format flags} lintOverflow = $0020; {check for overflows} + lintC99Syntax = $0040; {check for syntax that C99 disallows} {bit masks for GetLInfo flags} {----------------------------} diff --git a/Expression.pas b/Expression.pas index 8adf5f5..668c0b6 100644 --- a/Expression.pas +++ b/Expression.pas @@ -824,7 +824,7 @@ var np := pointer(GMalloc(length(fToken.name^)+1)); CopyString(pointer(np), pointer(fToken.name)); id := NewSymbol(np, fnPtr, ident, variableSpace, declared); - if (lint & lintUndefFn) <> 0 then + if ((lint & lintUndefFn) <> 0) or ((lint & lintC99Syntax) <> 0) then Error(51); end {if} else if kind = preprocessorExpression then begin diff --git a/Parser.pas b/Parser.pas index 6f3d3b5..03abacb 100644 --- a/Parser.pas +++ b/Parser.pas @@ -2634,7 +2634,6 @@ var DoStaticAssert; goto 1; end; {if} - typeSpec := wordPtr; {default type specifier is an integer} DeclarationSpecifiers(specifierQualifierListElement, ident); alignmentSpecified := _Alignassy in declarationModifiers; if not skipDeclarator then @@ -2816,7 +2815,7 @@ var begin {DeclarationSpecifiers} -myTypeSpec := typeSpec; +myTypeSpec := nil; myIsForwardDeclared := false; {not doing a forward reference (yet)} mySkipDeclarator := false; {declarations are required (so far)} myDeclarationModifiers := []; @@ -3138,6 +3137,11 @@ isForwardDeclared := myIsForwardDeclared; skipDeclarator := mySkipDeclarator; typeSpec := myTypeSpec; declarationModifiers := myDeclarationModifiers; +if typeSpec = nil then begin + typeSpec := wordPtr; {under C89, default type is int} + if (lint & lintC99Syntax) <> 0 then + Error(151); + end; {if} if isconstant then begin {handle a constant type} new(tPtr); if typeSpec^.kind in [structType,unionType] then begin @@ -3399,7 +3403,6 @@ if token.kind = _Static_assertsy then begin end; {if} lDoingParameters := doingParameters; {record the status} noFDefinitions := false; {are function definitions inhibited?} -typeFound := false; {no explicit type found, yet} if doingPrototypes then {prototypes implies a parm list} doingParameters := true else @@ -3412,10 +3415,8 @@ if not doingFunction then {handle any segment statements} inhibitHeader := true; {block imbedded includes in headers} lUseGlobalPool := useGlobalPool; storageClass := ident; -typeSpec := wordPtr; {default type specifier is an integer} {handle a TypeSpecifier/declarator} -if token.kind in declarationSpecifiersElement then - typeFound := true; +typeFound := token.kind in declarationSpecifiersElement; DeclarationSpecifiers(declarationSpecifiersElement, ident); isPascal := pascalsy in declarationModifiers; isAsm := asmsy in declarationModifiers; @@ -3443,7 +3444,8 @@ isPascal := lisPascal; if isFunction then begin if not typeFound then if (lint & lintNoFnType) <> 0 then - Error(104); + if (lint & lintC99Syntax) = 0 then + Error(104); end {if} else if not typeFound then @@ -3581,7 +3583,7 @@ if isFunction then begin while tlp <> nil do begin if tlp^.itype = nil then begin tlp^.itype := wordPtr; - if (lint & lintNoFnType) <> 0 then + if (lint & lintC99Syntax) <> 0 then if (lint & lintNotPrototyped) = 0 then Error(147); {C99+ require K&R params to be declared} end; {if} @@ -3950,7 +3952,6 @@ var begin {TypeName} {read and process the type specifier} -typeSpec := wordPtr; DeclarationSpecifiers(specifierQualifierListElement, rparench); {_Alignas is not allowed in most uses of type names. } diff --git a/Scanner.pas b/Scanner.pas index d46c620..9a8c48e 100644 --- a/Scanner.pas +++ b/Scanner.pas @@ -182,7 +182,7 @@ const {----} defaultName = '13:ORCACDefs:Defaults.h'; {default include file name} maxErr = 10; {max errors on one line} - maxLint = 147; {maximum lint error code} + maxLint = 151; {maximum lint error code} type errorType = record {record of a single error} @@ -675,6 +675,7 @@ if list or (numErr <> 0) then begin 148: msg := @'all parameters must have a complete type'; 149: msg := @'invalid universal character name for use in an identifier'; 150: msg := @'designated initializers are not supported by ORCA/C'; + 151: msg := @'lint: type specifier missing'; otherwise: Error(57); end; {case} writeln(msg^); @@ -3635,7 +3636,7 @@ lintIsError := true; {lint messages are considered errors} {error codes for lint messages} {if changed, also change maxLint} -lintErrors := [51,104,105,110,124,125,128,129,130,147]; +lintErrors := [51,104,105,110,124,125,128,129,130,147,151]; new(mp); {__LINE__} mp^.name := @'__LINE__';