- 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 15:55:09 +02:00
parent 77a65f5668
commit 821b950993
2 changed files with 60 additions and 8 deletions

View File

@ -1600,11 +1600,12 @@ public final class Parser
/* Will consume the `}` (or `;` if wantsBody-false) */
funcDefPair pair = parseFuncDef(wantsBody);
// TODO: Add a check here that the last statement must be a ReturnStmt if this
// ... is a non-void function (just for exietence, `parseFuncDef` will ensure ordering)
// FIXME: This will actualy trigger when efunc is used, so must only run this
// ... when wantsBody is TRUE!
if(type != "void")
/**
* 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)
@ -1616,6 +1617,7 @@ public final class Parser
}
}
// Error if no return statement exists
if(!hasReturn)
{
expect("Function '"~identifier~"' declared with return type does not contain a return statement");
@ -2758,6 +2760,8 @@ int thing()
{
int discardExpr = function(&j);
int** l;
return 0;
}
`;
LexerInterface currentLexer = new BasicLexer(sourceCode);
@ -3037,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;
}