Skip to content

Commit 64e8a03

Browse files
committed
Sema: Diagnose if #_hasSymbol as unsupported on non-Darwin targets.
1 parent 631dd4c commit 64e8a03

File tree

5 files changed

+59
-27
lines changed

5 files changed

+59
-27
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6619,6 +6619,8 @@ WARNING(has_symbol_decl_must_be_weak,none,
66196619
(DescriptiveDeclKind, DeclName))
66206620
ERROR(has_symbol_invalid_expr,none,
66216621
"'#_hasSymbol' condition must refer to a declaration", ())
6622+
ERROR(has_symbol_unsupported,none,
6623+
"'#_hasSymbol' is unsupported on target '%0'", (StringRef))
66226624

66236625
//------------------------------------------------------------------------------
66246626
// MARK: Type erasure

lib/Sema/MiscDiagnostics.cpp

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4390,6 +4390,51 @@ checkImplicitPromotionsInCondition(const StmtConditionElement &cond,
43904390
}
43914391
}
43924392

4393+
/// Diagnoses a `if #_hasSymbol(...)` condition. Returns true if a diagnostic
4394+
/// was emitted.
4395+
static bool diagnoseHasSymbolCondition(PoundHasSymbolInfo *info,
4396+
DeclContext *DC) {
4397+
// If we have an invalid info, null expression, or expression without a type
4398+
// then type checking failed already for this condition.
4399+
if (info->isInvalid())
4400+
return false;
4401+
4402+
auto symbolExpr = info->getSymbolExpr();
4403+
if (!symbolExpr)
4404+
return false;
4405+
4406+
if (!symbolExpr->getType())
4407+
return false;
4408+
4409+
auto &ctx = DC->getASTContext();
4410+
if (!ctx.LangOpts.Target.isOSDarwin()) {
4411+
// SILGen for #_hasSymbol is currently implemented assuming the target OS
4412+
// is a Darwin platform.
4413+
ctx.Diags.diagnose(info->getStartLoc(), diag::has_symbol_unsupported,
4414+
ctx.LangOpts.Target.str());
4415+
return true;
4416+
}
4417+
4418+
auto decl = info->getReferencedDecl().getDecl();
4419+
if (!decl) {
4420+
// Diagnose because we weren't able to interpret the expression as one
4421+
// that uniquely identifies a single declaration.
4422+
ctx.Diags.diagnose(symbolExpr->getLoc(), diag::has_symbol_invalid_expr);
4423+
return true;
4424+
}
4425+
4426+
if (!decl->isWeakImported(DC->getParentModule())) {
4427+
// `if #_hasSymbol(someStronglyLinkedSymbol)` is functionally a no-op
4428+
// and may indicate the developer has mis-identified the declaration
4429+
// they want to check (or forgot to import the module weakly).
4430+
ctx.Diags.diagnose(symbolExpr->getLoc(), diag::has_symbol_decl_must_be_weak,
4431+
decl->getDescriptiveKind(), decl->getName());
4432+
return true;
4433+
}
4434+
4435+
return false;
4436+
}
4437+
43934438
/// Perform MiscDiagnostics for the conditions belonging to a \c
43944439
/// LabeledConditionalStmt.
43954440
static void checkLabeledStmtConditions(ASTContext &ctx,
@@ -4407,32 +4452,9 @@ static void checkLabeledStmtConditions(ASTContext &ctx,
44074452

44084453
case StmtConditionElement::CK_HasSymbol: {
44094454
auto info = elt.getHasSymbolInfo();
4410-
if (info->isInvalid())
4411-
break;
4412-
4413-
auto symbolExpr = info->getSymbolExpr();
4414-
if (!symbolExpr)
4415-
break;
4416-
4417-
if (!symbolExpr->getType())
4418-
break;
4419-
4420-
if (auto decl = info->getReferencedDecl().getDecl()) {
4421-
// `if #_hasSymbol(someStronglyLinkedSymbol)` is functionally a no-op
4422-
// and may indicate the developer has mis-identified the declaration
4423-
// they want to check (or forgot to import the module weakly).
4424-
if (!decl->isWeakImported(DC->getParentModule())) {
4425-
ctx.Diags.diagnose(symbolExpr->getLoc(),
4426-
diag::has_symbol_decl_must_be_weak,
4427-
decl->getDescriptiveKind(), decl->getName());
4428-
info->setInvalid();
4429-
}
4430-
} else {
4431-
// Diagnose because we weren't able to interpret the expression as one
4432-
// that uniquely identifies a single declaration.
4433-
ctx.Diags.diagnose(symbolExpr->getLoc(), diag::has_symbol_invalid_expr);
4455+
if (diagnoseHasSymbolCondition(info, DC))
44344456
info->setInvalid();
4435-
}
4457+
44364458
break;
44374459
}
44384460
}

test/Parse/has_symbol.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/Library.swiftmodule -parse-as-library %t/Library.swift -enable-library-evolution
44
// RUN: %target-swift-frontend -typecheck -verify %t/Client.swift -I %t
55

6-
// UNSUPPORTED: OS=windows-msvc
6+
// REQUIRES: VENDOR=apple
77

88
//--- Library.swift
99

test/Sema/has_symbol.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// RUN: %target-typecheck-verify-swift -disable-availability-checking -I %t
44
// RUN: %target-typecheck-verify-swift -disable-availability-checking -I %t -enable-experimental-feature ResultBuilderASTTransform
55

6-
// UNSUPPORTED: OS=windows-msvc
6+
// REQUIRES: VENDOR=apple
77

88
@_weakLinked import has_symbol_helper
99

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %target-typecheck-verify-swift
2+
// UNSUPPORTED: VENDOR=apple
3+
4+
// Verify that #_hasSymbol is rejected on non-Darwin platforms
5+
6+
func foo() {}
7+
8+
if #_hasSymbol(foo) { } // expected-error {{'#_hasSymbol' is unsupported on target}}

0 commit comments

Comments
 (0)