Skip to content

Commit

Permalink
Disallow override specifiers on class constructor declarations
Browse files Browse the repository at this point in the history
  • Loading branch information
MikePopoloski committed Oct 11, 2024
1 parent 5cb3233 commit f31d20e
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 10 deletions.
25 changes: 15 additions & 10 deletions source/parsing/Parser_members.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -682,8 +682,8 @@ FunctionPrototypeSyntax& Parser::parseFunctionPrototype(SyntaxKind parentKind,
else
keyword = expect(TokenKind::FunctionKeyword);

auto specifiers = parseClassSpecifierList(
options.has(FunctionOptions::AllowOverrideSpecifiers));
const bool allowSpecifiers = options.has(FunctionOptions::AllowOverrideSpecifiers);
auto specifiers = parseClassSpecifierList(allowSpecifiers);

auto lifetime = parseLifetime();
if (lifetime && options.has(FunctionOptions::IsPrototype))
Expand Down Expand Up @@ -728,15 +728,20 @@ FunctionPrototypeSyntax& Parser::parseFunctionPrototype(SyntaxKind parentKind,
else if (constructor)
addDiag(diag::TaskConstructor, keyword.location()) << name.sourceRange();
}
else if (constructor && returnType->kind != SyntaxKind::ImplicitType) {
addDiag(diag::ConstructorReturnType, name.getFirstToken().location())
<< returnType->sourceRange();
}
else if (constructor && name.kind != SyntaxKind::ScopedName &&
parentKind != SyntaxKind::ClassDeclaration) {
addDiag(diag::ConstructorOutsideClass, keyword.location()) << name.sourceRange();
else if (constructor) {
if (returnType->kind != SyntaxKind::ImplicitType) {
addDiag(diag::ConstructorReturnType, name.getFirstToken().location())
<< returnType->sourceRange();
}
else if (name.kind != SyntaxKind::ScopedName &&
parentKind != SyntaxKind::ClassDeclaration) {
addDiag(diag::ConstructorOutsideClass, keyword.location()) << name.sourceRange();
}
else if (allowSpecifiers && !specifiers.empty()) {
addDiag(diag::SpecifiersNotAllowed, specifiers[0]->sourceRange()) << name.sourceRange();
}
}
else if (!constructor && !options.has(FunctionOptions::AllowImplicitReturn) &&
else if (!options.has(FunctionOptions::AllowImplicitReturn) &&
returnType->kind == SyntaxKind::ImplicitType) {
addDiag(diag::ImplicitNotAllowed, name.getFirstToken().location());
}
Expand Down
14 changes: 14 additions & 0 deletions tests/unittests/parsing/MemberParsingTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1508,3 +1508,17 @@ program A ; final randcase 0 : matches A = # 0 0 ; endcase endprogram

REQUIRE(diagnostics.size() == 16);
}

TEST_CASE("Override specifiers on class constructor") {
auto& text = R"(
class cls;
function :initial :final new();
endfunction
endclass
)";

parseCompilationUnit(text, LanguageVersion::v1800_2023);

REQUIRE(diagnostics.size() == 1);
CHECK(diagnostics[0].code == diag::SpecifiersNotAllowed);
}

0 comments on commit f31d20e

Please sign in to comment.