summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2025-01-17 14:52:28 -0800
committerGitHub <noreply@github.com>2025-01-17 14:52:28 -0800
commitd046082c501d3501a24c143dff2cfa42939549b9 (patch)
treeba9859ca11c7b295968005624249ee1abf5d07a9 /source
parentdc69d85f89e42eb2fe914e1105a8cbb68e9a8ca4 (diff)
Add diagnostic for function body followed by a `;`;. (#6122)
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-diagnostic-defs.h6
-rw-r--r--source/slang/slang-parser.cpp17
2 files changed, 21 insertions, 2 deletions
diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h
index 7eddc16a9..915ed9b42 100644
--- a/source/slang/slang-diagnostic-defs.h
+++ b/source/slang/slang-diagnostic-defs.h
@@ -487,7 +487,11 @@ DIAGNOSTIC(
Warning,
unintendedEmptyStatement,
"potentially unintended empty statement at this location; use {} instead.")
-
+DIAGNOSTIC(
+ 20102,
+ Error,
+ unexpectedBodyAfterSemicolon,
+ "unexpected function body after signature declaration, is this ';' a typo?")
DIAGNOSTIC(30102, Error, declNotAllowed, "$0 is not allowed here.")
// 29xxx - Snippet parsing and inline asm
diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp
index 98cfd121c..81619b700 100644
--- a/source/slang/slang-parser.cpp
+++ b/source/slang/slang-parser.cpp
@@ -1802,9 +1802,17 @@ public:
/// Parse an optional body statement for a declaration that can have a body.
static Stmt* parseOptBody(Parser* parser)
{
- if (AdvanceIf(parser, TokenType::Semicolon))
+ Token semiColonToken;
+ if (AdvanceIf(parser, TokenType::Semicolon, &semiColonToken))
{
// empty body
+ // if we see a `{` after a `;`, it is very likely an user error to
+ // have the `;`, so we will provide a better diagnostic for it.
+ if (peekTokenType(parser) == TokenType::LBrace)
+ {
+ parser->sink->diagnose(semiColonToken.loc, Diagnostics::unexpectedBodyAfterSemicolon);
+ return parser->parseBlockStatement();
+ }
return nullptr;
}
else
@@ -4841,6 +4849,13 @@ static DeclBase* ParseDeclWithModifiers(
// We shouldn't be seeing an LBrace or an LParent when expecting a decl.
// However recovery logic may lead us here. In this case we just
// skip the whole `{}` block and return an empty decl.
+ if (!parser->isRecovering)
+ {
+ parser->sink->diagnose(
+ loc,
+ Diagnostics::unexpectedToken,
+ parser->tokenReader.peekToken());
+ }
SkipBalancedToken(&parser->tokenReader);
decl = parser->astBuilder->create<EmptyDecl>();
decl->loc = loc;