Skip to content

Commit 6c5d62c

Browse files
committed
Sema: Stop checking @main if no decl synthesized.
When requestifying the synthesis of the main function for the type annotated @main via SynthesizeMainFunctionRequest, what were previously were bailouts from AttributeChecker::visitMainTypeAttr had to become returns of nullptr from SynthesizeMainFunctionRequest::evaluate. Consequently, AttributeChecker::visitMainTypeAttr must check whether synthesis actually succeeded before proceeding to to register the main decl for a file. In simple cases, this happened to work because SourceFile::registerMainDecl would return early if the decl being registered was the same as the already registered main decl and in particular if the decl being registered was nullptr and the previously registered one was nullptr as well. When, however, there are multiple types annotated @main, if a function is successfully synthesized for one type but synthesis fails for the second, an attempt will be made to register nullptr as the main decl and will move past the check at the beginning of SourceFile::registerMainDecl, resulting in a crash. Here, we bail from AttributeChecker::visitMainTypeAttr if function synthesis fails and add an assert to SourceFile::registerMainDecl that the provided decl is non-null. rdar://75547146
1 parent 5709721 commit 6c5d62c

File tree

3 files changed

+14
-0
lines changed

3 files changed

+14
-0
lines changed

lib/AST/Module.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,6 +1419,7 @@ bool ModuleDecl::isBuiltinModule() const {
14191419
}
14201420

14211421
bool SourceFile::registerMainDecl(Decl *mainDecl, SourceLoc diagLoc) {
1422+
assert(mainDecl);
14221423
if (mainDecl == MainDecl)
14231424
return false;
14241425

lib/Sema/TypeCheckAttr.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2012,6 +2012,9 @@ void AttributeChecker::visitMainTypeAttr(MainTypeAttr *attr) {
20122012
SynthesizeMainFunctionRequest{D},
20132013
nullptr);
20142014

2015+
if (!func)
2016+
return;
2017+
20152018
// Register the func as the main decl in the module. If there are multiples
20162019
// they will be diagnosed.
20172020
if (file->registerMainDecl(func, attr->getLocation()))
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: not %target-swift-frontend %s -c -parse-as-library
2+
3+
@main struct M1 {
4+
static func main() {}
5+
}
6+
7+
@main struct M2<T> {
8+
static func main() {}
9+
}
10+

0 commit comments

Comments
 (0)