🐞 Bugfix: Ensure that typed functions contain a return statement (#17)

* Parser

- Added TODO for checking for non-`void` function's return statements

* Parser

- If a `ReturnStmt` is not found after calling `parseFuncDef()`

* Parser

- Added a FIXME comment that needs to be completed soon

* Parser

- Only check that a `ReturnStmt` is present in a function definition when `wantsBody` is true ELSE we'd expect it for `efunc` `extern`'d statements
- Fixed a unit test which had a missing `return <expr>`
- Added a unit test which tests for a function definition with a body with a non-void return type that it DOES fail
- Removed two now-completed TODOs and FIXMEs

Test cases

- Fixed test case in `typecheck/simple_function_call.t` to now include the required `return <expr>` statements
This commit is contained in:
Tristan B. Velloza Kildaire 2023-07-16 18:22:56 +02:00 committed by GitHub
parent 4c99b56677
commit ddedc0d806
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 77 additions and 3 deletions

View File

@ -1600,6 +1600,30 @@ public final class Parser
/* Will consume the `}` (or `;` if wantsBody-false) */
funcDefPair pair = parseFuncDef(wantsBody);
/**
* If this function definition has a body (i.e. `wantsBody == true`)
* and if the return type is non-void, THEN ensure we have a `ReturnStmt`
* (return statement)
*/
if(wantsBody && type != "void")
{
bool hasReturn;
foreach(Statement stmt; pair.bodyStatements)
{
if(cast(ReturnStmt)stmt)
{
hasReturn = true;
break;
}
}
// Error if no return statement exists
if(!hasReturn)
{
expect("Function '"~identifier~"' declared with return type does not contain a return statement");
}
}
generated = new Function(identifier, type, pair.bodyStatements, pair.params);
import std.stdio;
@ -2736,6 +2760,8 @@ int thing()
{
int discardExpr = function(&j);
int** l;
return 0;
}
`;
LexerInterface currentLexer = new BasicLexer(sourceCode);
@ -3015,4 +3041,52 @@ void function()
{
assert(false);
}
}
/**
* Function test case
*
* Test: A function of a non-void return type
* must have a return statement
*/
unittest
{
string sourceCode = `
module myModule;
int wrongFunction()
{
}
`;
LexerInterface currentLexer = new BasicLexer(sourceCode);
try
{
(cast(BasicLexer)currentLexer).performLex();
assert(true);
}
catch(LexerException e)
{
assert(false);
}
Parser parser = new Parser(currentLexer);
try
{
Module modulle = parser.parse();
assert(false);
}
catch(ParserException e)
{
// TODO: Try make errors specific enough to yank them out
assert(true);
}
catch(TError)
{
assert(false);
}
}

View File

@ -5,15 +5,15 @@ j = 2+func(j,test());
int func(int x1, byte x2)
{
return 1;
}
byte t2()
{
return 1;
}
byte test()
{
return 1;
}