Skip to content

Commit 9a35f83

Browse files
Merge pull request swiftlang#71075 from ian-twilightcoder/no-exit-in-shims
[Concurrency] [shims] Don't declare `exit` in the concurrency shims
2 parents a2a8bca + 288f37b commit 9a35f83

File tree

13 files changed

+146
-32
lines changed

13 files changed

+146
-32
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@
5959
Having been [gated](https://github.com/apple/swift/pull/28171) behind a
6060
compiler warning since at least Swift 5.2, this syntax is now rejected.
6161

62+
* [bugfix][]:
63+
64+
\_SwiftConcurrencyShims used to declare the `exit` function, even though it
65+
might not be available. The declaration has been removed, and must be imported
66+
from the appropriate C library module (e.g. Darwin or SwiftGlibc)
67+
6268
## Swift 5.10
6369

6470
* Swift 5.10 closes all known static data-race safey holes in complete strict

lib/ClangImporter/ImportDecl.cpp

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3388,26 +3388,24 @@ namespace {
33883388
->getTopLevelModule()
33893389
->getFullModuleName() == n;
33903390
};
3391-
if ((decl->getOwningModule() &&
3392-
importer::isCxxStdModule(decl->getOwningModule()))) {
3391+
3392+
if (clang::Module *owningModule = decl->getOwningModule();
3393+
owningModule && importer::isCxxStdModule(owningModule)) {
33933394
if (isAlternativeCStdlibFunctionFromTextualHeader(decl)) {
33943395
return nullptr;
33953396
}
3396-
auto filename =
3397-
Impl.getClangPreprocessor().getSourceManager().getFilename(
3398-
decl->getLocation());
3399-
if (filename.endswith("cmath") || filename.endswith("math.h") ||
3400-
filename.endswith("stdlib.h") || filename.endswith("cstdlib")) {
3401-
return nullptr;
3397+
3398+
auto &sourceManager = Impl.getClangPreprocessor().getSourceManager();
3399+
if (const auto file = sourceManager.getFileEntryForID(
3400+
sourceManager.getFileID(decl->getLocation()))) {
3401+
auto filename = file->getName();
3402+
if ((file->getDir() == owningModule->Directory) &&
3403+
(filename.endswith("cmath") || filename.endswith("math.h") ||
3404+
filename.endswith("stdlib.h") || filename.endswith("cstdlib"))) {
3405+
return nullptr;
3406+
}
34023407
}
34033408
}
3404-
// Use the exit function from _SwiftConcurrency.h as it is platform
3405-
// agnostic.
3406-
if ((topLevelModuleEq(decl, "Darwin") ||
3407-
topLevelModuleEq(decl, "SwiftGlibc")) &&
3408-
decl->getDeclName().isIdentifier() && decl->getName() == "exit") {
3409-
return nullptr;
3410-
}
34113409
}
34123410

34133411
auto dc =

lib/SILGen/SILGen.cpp

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -450,16 +450,51 @@ FuncDecl *SILGenModule::getSwiftJobRun() {
450450

451451
FuncDecl *SILGenModule::getExit() {
452452
ASTContext &C = getASTContext();
453-
ModuleDecl *concurrencyShims =
454-
C.getModuleByIdentifier(C.getIdentifier("_SwiftConcurrencyShims"));
455453

456-
if (!concurrencyShims)
457-
return nullptr;
454+
// Try the most likely modules.
455+
Identifier mostLikelyIdentifier;
456+
const llvm::Triple &triple = C.LangOpts.Target;
457+
if (triple.isOSDarwin()) {
458+
mostLikelyIdentifier = C.getIdentifier("Darwin");
459+
} else if (triple.isOSWASI()) {
460+
mostLikelyIdentifier = C.getIdentifier("SwiftWASILibc");
461+
} else if (triple.isWindowsMSVCEnvironment()) {
462+
mostLikelyIdentifier = C.getIdentifier("ucrt");
463+
} else {
464+
mostLikelyIdentifier = C.getIdentifier("SwiftGlibc");
465+
}
466+
ModuleDecl *exitModule = C.getModuleByIdentifier(mostLikelyIdentifier);
467+
FuncDecl *exitFunction = nullptr;
468+
if (exitModule) {
469+
exitFunction = evaluateOrDefault(
470+
C.evaluator,
471+
LookupIntrinsicRequest{exitModule, C.getIdentifier("exit")},
472+
/*default=*/nullptr);
473+
}
474+
475+
if (!exitFunction) {
476+
// No go, look for it in any loaded module. Several of the internal
477+
// Swift modules or swift-corelibs modules may have absorbed <stdlib.h>
478+
// when buliding without fully specified clang modules in the OS/SDK.
479+
for (const auto &loadedModuleVector : C.getLoadedModules()) {
480+
if (loadedModuleVector.first == mostLikelyIdentifier) {
481+
continue;
482+
}
458483

459-
return evaluateOrDefault(
460-
C.evaluator,
461-
LookupIntrinsicRequest{concurrencyShims, C.getIdentifier("exit")},
462-
/*default=*/nullptr);
484+
ModuleDecl *loadedModule = loadedModuleVector.second;
485+
if (loadedModule) {
486+
exitFunction = evaluateOrDefault(
487+
C.evaluator,
488+
LookupIntrinsicRequest{loadedModule, C.getIdentifier("exit")},
489+
/*default=*/nullptr);
490+
}
491+
if (exitFunction) {
492+
break;
493+
}
494+
}
495+
}
496+
497+
return exitFunction;
463498
}
464499

465500
ProtocolConformance *SILGenModule::getNSErrorConformanceToError() {

lib/SILGen/SILGenTopLevel.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,23 @@ void SILGenFunction::emitCallToMain(FuncDecl *mainFunc) {
214214
B.createReturn(loc, exitCode);
215215
} else {
216216
FuncDecl *exitFuncDecl = SGM.getExit();
217-
assert(exitFuncDecl && "Failed to find exit function declaration");
217+
if (!exitFuncDecl) {
218+
// If it doesn't exist, we can conjure one up instead of crashing
219+
// @_extern(c)
220+
// func exit(_: Int32) -> Never
221+
ASTContext &ctx = getASTContext();
222+
ModuleDecl *moduleDecl = mainFunc->getModuleContext();
223+
ParameterList *params =
224+
ParameterList::createWithoutLoc(ParamDecl::createImplicit(
225+
ctx, Identifier(), Identifier(), ctx.getInt32Type(), moduleDecl));
226+
exitFuncDecl = FuncDecl::createImplicit(
227+
ctx, StaticSpellingKind::None,
228+
DeclName(ctx, DeclBaseName(ctx.getIdentifier("exit")), params), {},
229+
/*async*/ false, /*throws*/ false, /*thrownType*/ Type(), {}, params,
230+
ctx.getNeverType(), moduleDecl);
231+
exitFuncDecl->getAttrs().add(new (ctx) ExternAttr(
232+
llvm::None, llvm::None, ExternKind::C, /*implicit*/ true));
233+
}
218234
SILFunction *exitSILFunc = SGM.getFunction(
219235
SILDeclRef(exitFuncDecl, SILDeclRef::Kind::Func, /*isForeign*/ true),
220236
NotForDefinition);

stdlib/public/Concurrency/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#===----------------------------------------------------------------------===#
1212

1313
set(SWIFT_RUNTIME_CONCURRENCY_C_FLAGS)
14-
set(SWIFT_RUNTIME_CONCURRENCY_SWIFT_FLAGS)
14+
set(SWIFT_RUNTIME_CONCURRENCY_SWIFT_FLAGS -I${CMAKE_CURRENT_SOURCE_DIR}/InternalShims)
1515

1616
set(swift_concurrency_private_link_libraries)
1717
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module SwiftConcurrencyInternalShims {
2+
module stdlib {
3+
header "stdlib_shims.h"
4+
export *
5+
}
6+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//===--- stdlib_shims.h - Swift Concurrency Support -----------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// Forward declarations of <stdlib.h> interfaces so that Swift Concurrency
14+
// doesn't depend on the C library.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
#ifndef STDLIB_SHIMS_H
18+
#define STDLIB_SHIMS_H
19+
20+
#ifdef __cplusplus
21+
extern "C" [[noreturn]]
22+
#endif
23+
void exit(int);
24+
25+
#define EXIT_SUCCESS 0
26+
27+
#endif // STDLIB_SHIMS_H

stdlib/public/Concurrency/Task.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import Swift
1414
@_implementationOnly import _SwiftConcurrencyShims
15+
@_implementationOnly import SwiftConcurrencyInternalShims
1516

1617
// ==== Task -------------------------------------------------------------------
1718

stdlib/public/SwiftShims/swift/shims/_SwiftConcurrency.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,4 @@ typedef struct _SwiftContext {
3030
} // namespace swift
3131
#endif
3232

33-
#ifdef __cplusplus
34-
extern "C" [[noreturn]]
35-
#endif
36-
void exit(int);
37-
38-
#define EXIT_SUCCESS 0
39-
4033
#endif // SWIFT_CONCURRENCY_H

test/Backtracing/DwarfReader.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@
77
// REQUIRES: backtracing
88

99
@_spi(DwarfTest) import _Backtracing
10+
#if canImport(Darwin)
11+
import Darwin
12+
#elseif canImport(SwiftWASILibc)
13+
import SwiftWASILibc
14+
#elseif canImport(ucrt)
15+
import ucrt
16+
#elseif canImport(SwiftGlibc)
17+
import SwiftGlibc
18+
#endif
1019

1120
@main
1221
struct DwarfReader {

test/Backtracing/ElfReader.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,15 @@
1616
// REQUIRES: backtracing
1717

1818
@_spi(ElfTest) import _Backtracing
19+
#if canImport(Darwin)
20+
import Darwin
21+
#elseif canImport(SwiftWASILibc)
22+
import SwiftWASILibc
23+
#elseif canImport(ucrt)
24+
import ucrt
25+
#elseif canImport(SwiftGlibc)
26+
import SwiftGlibc
27+
#endif
1928

2029
@main
2130
struct ElfReader {

test/Backtracing/Inputs/Inlining.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
#if canImport(Darwin)
2+
import Darwin
3+
#elseif canImport(SwiftWASILibc)
4+
import SwiftWASILibc
5+
#elseif canImport(ucrt)
6+
import ucrt
7+
#elseif canImport(SwiftGlibc)
8+
import SwiftGlibc
9+
#endif
10+
111
func square(_ x: Int) -> Int {
212
return x * x
313
}

validation-test/SIL/verify_all_overlays.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@
4141
extra_args = ["-I", os.path.join(source_dir, "stdlib",
4242
"public", "Backtracing", "modules"),
4343
"-I", os.path.join(source_dir, "include")]
44+
# _Concurrency needs its own additional modules in the module path
45+
if module_name == "_Concurrency":
46+
extra_args = ["-I", os.path.join(source_dir, "stdlib",
47+
"public", "Concurrency", "InternalShims")]
4448

4549
print("# " + module_name)
4650

0 commit comments

Comments
 (0)