Aul: Warn on empty controlled statement

Aul will now emit a warning if you type something like
    if (...); return true;
(note the semicolon right after the condition). It will also warn on an
empty 'else' branch. If you actually intended to have a no-op there, use
an empty block '{}'.
alut-include-path
Nicolas Hake 2017-02-05 14:17:37 +01:00
parent 9a201441d5
commit a33d98ee71
2 changed files with 33 additions and 5 deletions

View File

@ -1574,8 +1574,19 @@ void C4AulCompiler::CodegenAstVisitor::visit(const ::aul::ast::If *n)
{
SafeVisit(n->cond);
int jump = AddBCC(n->loc, AB_CONDN);
// Warn if we're controlling a no-op ("if (...);")
if (dynamic_cast<::aul::ast::Noop*>(n->iftrue.get()))
{
Warn(target_host, host, n->iftrue->loc, Fn, "empty controlled statement found (use '{}' if this is intentional)");
}
if (SafeVisit(n->iftrue))
MaybePopValueOf(n->iftrue);
if (dynamic_cast<::aul::ast::Noop*>(n->iffalse.get()))
{
Warn(target_host, host, n->iffalse->loc, Fn, "empty controlled statement found (use '{}' if this is intentional)");
}
if (n->iffalse)
{
int jumpout = AddBCC(n->loc, AB_JUMP);

View File

@ -283,11 +283,28 @@ TEST_F(AulTest, Conditionals)
TEST_F(AulTest, Warnings)
{
ErrorHandler errh;
EXPECT_CALL(errh, OnWarning(::testing::_)).Times(3);
EXPECT_EQ(C4Value(), RunScript("func Main(string s, object o, array a) { Sin(s); }"));
EXPECT_EQ(C4Value(), RunScript("func Main(string s, object o, array a) { Sin(o); }"));
EXPECT_EQ(C4Value(), RunScript("func Main(string s, object o, array a) { Sin(a); }"));
{
ErrorHandler errh;
EXPECT_CALL(errh, OnWarning(::testing::_)).Times(3);
EXPECT_EQ(C4Value(), RunScript("func Main(string s, object o, array a) { Sin(s); }"));
EXPECT_EQ(C4Value(), RunScript("func Main(string s, object o, array a) { Sin(o); }"));
EXPECT_EQ(C4Value(), RunScript("func Main(string s, object o, array a) { Sin(a); }"));
}
{
ErrorHandler errh;
EXPECT_CALL(errh, OnWarning(::testing::StartsWith("empty controlled statement")));
RunCode("if (true);");
}
{
ErrorHandler errh;
EXPECT_CALL(errh, OnWarning(::testing::StartsWith("empty controlled statement")));
RunCode("if (true) { return; } else;");
}
{
ErrorHandler errh;
EXPECT_CALL(errh, OnWarning(::testing::StartsWith("empty controlled statement"))).Times(0);
RunCode("if (true) {} else {}");
}
}
TEST_F(AulTest, NoWarnings)