Add a lint flag for checking if _Noreturn functions may return.

Currently, this only flags return statements, not cases where they may execute to the end of the function. (Whether the function will actually return is not decidable in general, although it may be in special cases).
This commit is contained in:
Stephen Heumann 2020-01-29 19:26:45 -06:00
parent 4fd642abb4
commit 80c513bbf2
3 changed files with 9 additions and 2 deletions

View File

@ -92,6 +92,7 @@ const
lintPrintf = $0010; {check printf/scanf format flags}
lintOverflow = $0020; {check for overflows}
lintC99Syntax = $0040; {check for syntax that C99 disallows}
lintNoreturn = $0080; {check for return in _Noreturn funcs}
{bit masks for GetLInfo flags}
{----------------------------}

View File

@ -154,6 +154,7 @@ var
doingMain: boolean; {are we processing the main function?}
firstCompoundStatement: boolean; {are we doing a function level compound statement?}
fType: typePtr; {return type of the current function}
fIsNoreturn: boolean; {is the current function _Noreturn?}
isForwardDeclared: boolean; {is the field list component }
{ referencing a forward struct/union? }
isFunction: boolean; {is the declaration a function?}
@ -737,6 +738,9 @@ var
tk: tokenType; {structure name token}
begin {ReturnStatement}
if fIsNoreturn then
if (lint & lintNoreturn) <> 0 then
Error(153);
NextToken; {skip the 'return' token}
if token.kind <> semicolonch then {if present, evaluate the return value}
begin
@ -3568,6 +3572,7 @@ if isFunction then begin
ftype := fnType^.ftype; {record the type of the function}
while fType^.kind = definedType do
fType := fType^.dType;
fIsNoreturn := isNoreturn; {record if function is _Noreturn}
variable^.state := defined; {note that the function is defined}
pfunc := variable; {set the identifier for parm checks}
fnType^.isPascal := isPascal; {note if we have pascal parms}

View File

@ -182,7 +182,7 @@ const
{----}
defaultName = '13:ORCACDefs:Defaults.h'; {default include file name}
maxErr = 10; {max errors on one line}
maxLint = 152; {maximum lint error code}
maxLint = 153; {maximum lint error code}
type
errorType = record {record of a single error}
@ -677,6 +677,7 @@ if list or (numErr <> 0) then begin
150: msg := @'designated initializers are not supported by ORCA/C';
151: msg := @'lint: type specifier missing';
152: msg := @'lint: return with no value in non-void function';
153: msg := @'lint: return statement in function declared _Noreturn';
otherwise: Error(57);
end; {case}
writeln(msg^);
@ -3637,7 +3638,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,151,152];
lintErrors := [51,104,105,110,124,125,128,129,130,147,151,152,153];
new(mp); {__LINE__}
mp^.name := @'__LINE__';