Skip to content

Commit ca0add4

Browse files
committed
[cxx-interop] Allow compiling with libc++ on Linux
This makes sure that Swift respects `-Xcc -stdlib=libc++` flags. Clang already has existing logic to discover the system-wide libc++ installation on Linux. We rely on that logic here. Importing a Swift module that was built with a different C++ stdlib is not supported and emits an error. The Cxx module can be imported when compiling with any C++ stdlib. The synthesized conformances, e.g. to CxxRandomAccessCollection also work. However, CxxStdlib currently cannot be imported when compiling with libc++, since on Linux it refers to symbols from libstdc++ which have different mangled names in libc++. rdar://118357548 / #69825
1 parent 536a889 commit ca0add4

27 files changed

+233
-9
lines changed

include/swift/AST/Decl.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,7 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
722722
HasAnyUnavailableDuringLoweringValues : 1
723723
);
724724

725-
SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1,
725+
SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1,
726726
/// If the module is compiled as static library.
727727
StaticLibrary : 1,
728728

@@ -780,6 +780,10 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
780780
/// Whether this module has been built with C++ interoperability enabled.
781781
HasCxxInteroperability : 1,
782782

783+
/// Whether this module uses the platform default C++ stdlib, or an
784+
/// overridden C++ stdlib.
785+
CXXStdlibKind : 1,
786+
783787
/// Whether this module has been built with -allow-non-resilient-access.
784788
AllowNonResilientAccess : 1,
785789

include/swift/AST/DiagnosticEngine.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ namespace swift {
5050
class ValueDecl;
5151
class SourceFile;
5252

53+
enum class CXXStdlibKind : uint8_t;
5354
enum class DescriptivePatternKind : uint8_t;
5455
enum class SelfAccessKind : uint8_t;
5556
enum class ReferenceOwnership : uint8_t;

include/swift/AST/DiagnosticsSema.def

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,13 @@ ERROR(need_cxx_interop_to_import_module,none,
942942
NOTE(enable_cxx_interop_docs,none,
943943
"visit https://www.swift.org/documentation/cxx-interop/project-build-setup to learn how to enable C++ interoperability", ())
944944

945+
ERROR(cxx_stdlib_kind_mismatch,none,
946+
"module %0 was built with "
947+
"%select{platform default C++ stdlib|libc++}1, "
948+
"but current compilation uses "
949+
"%select{platform default C++ stdlib|libc++}2",
950+
(Identifier, CXXStdlibKind, CXXStdlibKind))
951+
945952
ERROR(modularization_issue_decl_moved,Fatal,
946953
"reference to %select{top-level declaration|type}0 %1 broken by a context change; "
947954
"%1 was expected to be in %2, but now a candidate is found only in %3",

include/swift/AST/Module.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "swift/AST/Type.h"
2828
#include "swift/Basic/Assertions.h"
2929
#include "swift/Basic/BasicSourceInfo.h"
30+
#include "swift/Basic/CXXStdlibKind.h"
3031
#include "swift/Basic/Compiler.h"
3132
#include "swift/Basic/Debug.h"
3233
#include "swift/Basic/OptionSet.h"
@@ -705,6 +706,13 @@ class ModuleDecl
705706
Bits.ModuleDecl.HasCxxInteroperability = enabled;
706707
}
707708

709+
CXXStdlibKind getCXXStdlibKind() const {
710+
return static_cast<CXXStdlibKind>(Bits.ModuleDecl.CXXStdlibKind);
711+
}
712+
void setCXXStdlibKind(CXXStdlibKind kind) {
713+
Bits.ModuleDecl.CXXStdlibKind = static_cast<uint8_t>(kind);
714+
}
715+
708716
/// \returns true if this module is a system module; note that the StdLib is
709717
/// considered a system module.
710718
bool isSystemModule() const {

include/swift/AST/ModuleDependencies.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "swift/AST/Import.h"
2222
#include "swift/AST/LinkLibrary.h"
2323
#include "swift/AST/SearchPathOptions.h"
24+
#include "swift/Basic/CXXStdlibKind.h"
2425
#include "swift/Basic/LLVM.h"
2526
#include "clang/CAS/CASOptions.h"
2627
#include "clang/Tooling/DependencyScanning/DependencyScanningService.h"
@@ -135,7 +136,7 @@ void registerBackDeployLibraries(
135136
std::function<void(const LinkLibrary &)> RegistrationCallback);
136137
void registerCxxInteropLibraries(
137138
const llvm::Triple &Target, StringRef mainModuleName, bool hasStaticCxx,
138-
bool hasStaticCxxStdlib,
139+
bool hasStaticCxxStdlib, CXXStdlibKind cxxStdlibKind,
139140
std::function<void(const LinkLibrary &)> RegistrationCallback);
140141
} // namespace dependencies
141142

include/swift/Basic/CXXStdlibKind.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//===--- CXXStdlibKind.h ----------------------------------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2024 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+
#ifndef SWIFT_BASIC_CXX_STDLIB_KIND_H
14+
#define SWIFT_BASIC_CXX_STDLIB_KIND_H
15+
16+
namespace swift {
17+
18+
enum class CXXStdlibKind : uint8_t {
19+
/// Use the default C++ stdlib for a particular platform: libc++ for Darwin,
20+
/// libstdc++ for most Linux distros.
21+
PlatformDefault = 0,
22+
23+
/// Use libc++ instead of the default C++ stdlib on a platform where libc++
24+
/// is not the default, e.g. Ubuntu.
25+
OverrideLibcxx = 1,
26+
};
27+
28+
} // namespace swift
29+
30+
#endif // SWIFT_BASIC_CXX_STDLIB_KIND_H

include/swift/Basic/LangOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define SWIFT_BASIC_LANGOPTIONS_H
2020

2121
#include "swift/AST/DiagnosticsFrontend.h"
22+
#include "swift/Basic/CXXStdlibKind.h"
2223
#include "swift/Basic/Feature.h"
2324
#include "swift/Basic/FixedBitSet.h"
2425
#include "swift/Basic/FunctionBodySkipping.h"
@@ -321,6 +322,8 @@ namespace swift {
321322
void setCxxInteropFromArgs(llvm::opt::ArgList &Args,
322323
swift::DiagnosticEngine &Diags);
323324

325+
CXXStdlibKind CXXStdlib = CXXStdlibKind::PlatformDefault;
326+
324327
bool CForeignReferenceTypes = false;
325328

326329
/// Imports getters and setters as computed properties.

include/swift/Serialization/Validation.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define SWIFT_SERIALIZATION_VALIDATION_H
1515

1616
#include "swift/AST/Identifier.h"
17+
#include "swift/Basic/CXXStdlibKind.h"
1718
#include "swift/Basic/LLVM.h"
1819
#include "swift/Basic/Version.h"
1920
#include "swift/Serialization/SerializationOptions.h"
@@ -141,6 +142,7 @@ class ExtendedValidationInfo {
141142
unsigned IsAllowModuleWithCompilerErrorsEnabled : 1;
142143
unsigned IsConcurrencyChecked : 1;
143144
unsigned HasCxxInteroperability : 1;
145+
unsigned CXXStdlibKind : 1;
144146
unsigned AllowNonResilientAccess: 1;
145147
unsigned SerializePackageEnabled: 1;
146148
} Bits;
@@ -241,6 +243,13 @@ class ExtendedValidationInfo {
241243
void setHasCxxInteroperability(bool val) {
242244
Bits.HasCxxInteroperability = val;
243245
}
246+
247+
CXXStdlibKind getCXXStdlibKind() const {
248+
return static_cast<CXXStdlibKind>(Bits.CXXStdlibKind);
249+
}
250+
void setCXXStdlibKind(CXXStdlibKind kind) {
251+
Bits.CXXStdlibKind = static_cast<uint8_t>(kind);
252+
}
244253
};
245254

246255
struct SearchPath {

lib/AST/Module.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,7 @@ ModuleDecl::ModuleDecl(Identifier name, ASTContext &ctx,
725725
Bits.ModuleDecl.IsConcurrencyChecked = 0;
726726
Bits.ModuleDecl.ObjCNameLookupCachePopulated = 0;
727727
Bits.ModuleDecl.HasCxxInteroperability = 0;
728+
Bits.ModuleDecl.CXXStdlibKind = 0;
728729
Bits.ModuleDecl.AllowNonResilientAccess = 0;
729730
Bits.ModuleDecl.SerializePackageEnabled = 0;
730731
}

lib/AST/ModuleDependencies.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -540,9 +540,9 @@ void
540540
swift::dependencies::registerCxxInteropLibraries(
541541
const llvm::Triple &Target,
542542
StringRef mainModuleName,
543-
bool hasStaticCxx, bool hasStaticCxxStdlib,
543+
bool hasStaticCxx, bool hasStaticCxxStdlib, CXXStdlibKind cxxStdlibKind,
544544
std::function<void(const LinkLibrary&)> RegistrationCallback) {
545-
if (Target.isOSDarwin())
545+
if (Target.isOSDarwin() || cxxStdlibKind == CXXStdlibKind::OverrideLibcxx)
546546
RegistrationCallback(LinkLibrary("c++", LibraryKind::Library));
547547
else if (Target.isOSLinux())
548548
RegistrationCallback(LinkLibrary("stdc++", LibraryKind::Library));

lib/AST/ModuleLoader.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,13 @@ void ModuleLoader::findOverlayFiles(SourceLoc diagLoc, ModuleDecl *module,
172172
using namespace llvm::sys;
173173
using namespace file_types;
174174

175+
// If an overlay for CxxStdlib was requested, only proceed if compiling with
176+
// the platform-default C++ stdlib.
177+
if (module->getName() == module->getASTContext().Id_CxxStdlib &&
178+
module->getASTContext().LangOpts.CXXStdlib !=
179+
CXXStdlibKind::PlatformDefault)
180+
return;
181+
175182
// If cross import information is passed on command-line, prefer use that.
176183
auto &crossImports = module->getASTContext().SearchPathOpts.CrossImportInfo;
177184
auto overlays = crossImports.find(module->getNameStr());

lib/ClangImporter/ClangImporter.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4298,8 +4298,10 @@ ModuleDecl *ClangModuleUnit::getOverlayModule() const {
42984298
}
42994299
// If this Clang module is a part of the C++ stdlib, and we haven't loaded
43004300
// the overlay for it so far, it is a split libc++ module (e.g. std_vector).
4301-
// Load the CxxStdlib overlay explicitly.
4302-
if (!overlay && importer::isCxxStdModule(clangModule)) {
4301+
// Load the CxxStdlib overlay explicitly, if building with the
4302+
// platform-default C++ stdlib.
4303+
if (!overlay && importer::isCxxStdModule(clangModule) &&
4304+
Ctx.LangOpts.CXXStdlib == CXXStdlibKind::PlatformDefault) {
43034305
ImportPath::Module::Builder builder(Ctx.Id_CxxStdlib);
43044306
overlay = owner.loadModule(SourceLoc(), std::move(builder).get());
43054307
}

lib/ClangImporter/ClangIncludePaths.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,10 @@ static void getLibStdCxxFileMapping(
256256
if (triple.isAndroid()
257257
|| (triple.isMusl() && triple.getVendor() == llvm::Triple::Swift))
258258
return;
259+
// Make sure we are building with libstdc++. On platforms where libstdc++ is
260+
// the default C++ stdlib, users can still compile with `-Xcc -stdlib=libc++`.
261+
if (ctx.LangOpts.CXXStdlib == CXXStdlibKind::OverrideLibcxx)
262+
return;
259263

260264
// Extract the libstdc++ installation path from Clang driver.
261265
auto clangDriver = createClangDriver(ctx, vfs);

lib/DependencyScan/ScanDependencies.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1429,7 +1429,8 @@ static void resolveImplicitLinkLibraries(const CompilerInstance &instance,
14291429
bool hasStaticCxxStdlib = OptionalCxxStdLibDep.has_value() &&
14301430
OptionalCxxStdLibDep.value()->isStaticLibrary();
14311431
registerCxxInteropLibraries(langOpts.Target, mainModuleName, hasStaticCxx,
1432-
hasStaticCxxStdlib, addLinkLibrary);
1432+
hasStaticCxxStdlib, langOpts.CXXStdlib,
1433+
addLinkLibrary);
14331434
}
14341435

14351436
if (!irGenOpts.UseJIT && !langOpts.hasFeature(Feature::Embedded))

lib/Frontend/CompilerInvocation.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,16 @@ void LangOptions::setCxxInteropFromArgs(ArgList &Args,
627627
cxxInteropCompatVersion =
628628
validateCxxInteropCompatibilityMode("swift-5.9").second;
629629
}
630+
631+
for (const Arg *A : Args.filtered(options::OPT_Xcc)) {
632+
StringRef clangArg = A->getValue();
633+
if (clangArg.consume_front("-stdlib")) {
634+
clangArg.consume_front("=");
635+
if (clangArg.equals("libc++") && Target.isOSLinux())
636+
CXXStdlib = CXXStdlibKind::OverrideLibcxx;
637+
// If the stdlib argument is invalid, Clang will emit an error.
638+
}
639+
}
630640
}
631641

632642
static std::optional<swift::StrictConcurrency>

lib/Frontend/Frontend.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1465,6 +1465,8 @@ ModuleDecl *CompilerInstance::getMainModule() const {
14651465
if (Invocation.getLangOptions().EnableCXXInterop &&
14661466
Invocation.getLangOptions().RequireCxxInteropToImportCxxInteropModule)
14671467
MainModule->setHasCxxInteroperability();
1468+
if (Invocation.getLangOptions().EnableCXXInterop)
1469+
MainModule->setCXXStdlibKind(Invocation.getLangOptions().CXXStdlib);
14681470
if (Invocation.getLangOptions().AllowNonResilientAccess)
14691471
MainModule->setAllowNonResilientAccess();
14701472
if (Invocation.getSILOptions().EnableSerializePackage)

lib/IRGen/IRGenModule.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1646,6 +1646,7 @@ void IRGenModule::addLinkLibraries() {
16461646
getSwiftModule()->getName().str(),
16471647
hasStaticCxx,
16481648
hasStaticCxxStdlib,
1649+
Context.LangOpts.CXXStdlib,
16491650
registerLinkLibrary);
16501651
}
16511652

lib/Serialization/ModuleFile.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,11 @@ class ModuleFile
642642
return Core->Bits.HasCxxInteroperability;
643643
}
644644

645+
/// The kind of the C++ stdlib that this module was built with.
646+
CXXStdlibKind getCXXStdlibKind() const {
647+
return static_cast<CXXStdlibKind>(Core->Bits.CXXStdlibKind);
648+
}
649+
645650
/// Whether the module is resilient. ('-enable-library-evolution')
646651
ResilienceStrategy getResilienceStrategy() const {
647652
return ResilienceStrategy(Core->Bits.ResilienceStrategy);

lib/Serialization/ModuleFileSharedCore.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,11 @@ static bool readOptionsBlock(llvm::BitstreamCursor &cursor,
198198
case options_block::HAS_CXX_INTEROPERABILITY_ENABLED:
199199
extendedInfo.setHasCxxInteroperability(true);
200200
break;
201+
case options_block::CXX_STDLIB_KIND:
202+
unsigned rawKind;
203+
options_block::CXXStdlibKindLayout::readRecord(scratch, rawKind);
204+
extendedInfo.setCXXStdlibKind(static_cast<CXXStdlibKind>(rawKind));
205+
break;
201206
case options_block::ALLOW_NON_RESILIENT_ACCESS:
202207
extendedInfo.setAllowNonResilientAccess(true);
203208
break;
@@ -1461,6 +1466,7 @@ ModuleFileSharedCore::ModuleFileSharedCore(
14611466
extInfo.isAllowModuleWithCompilerErrorsEnabled();
14621467
Bits.IsConcurrencyChecked = extInfo.isConcurrencyChecked();
14631468
Bits.HasCxxInteroperability = extInfo.hasCxxInteroperability();
1469+
Bits.CXXStdlibKind = static_cast<uint8_t>(extInfo.getCXXStdlibKind());
14641470
Bits.AllowNonResilientAccess = extInfo.allowNonResilientAccess();
14651471
Bits.SerializePackageEnabled = extInfo.serializePackageEnabled();
14661472
MiscVersion = info.miscVersion;

lib/Serialization/ModuleFileSharedCore.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,10 @@ class ModuleFileSharedCore {
391391
/// Whether this module is built with C++ interoperability enabled.
392392
unsigned HasCxxInteroperability : 1;
393393

394+
/// Whether this module uses the platform default C++ stdlib, or an
395+
/// overridden C++ stdlib.
396+
unsigned CXXStdlibKind : 1;
397+
394398
/// Whether this module is built with -allow-non-resilient-access.
395399
unsigned AllowNonResilientAccess : 1;
396400

lib/Serialization/ModuleFormat.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5858
/// describe what change you made. The content of this comment isn't important;
5959
/// it just ensures a conflict if two people change the module format.
6060
/// Don't worry about adhering to the 80-column limit for this line.
61-
const uint16_t SWIFTMODULE_VERSION_MINOR = 881; // Changes to LifetimeDependence
61+
const uint16_t SWIFTMODULE_VERSION_MINOR = 882; // CXXStdlibKind
6262

6363
/// A standard hash seed used for all string hashes in a serialized module.
6464
///
@@ -949,6 +949,7 @@ namespace options_block {
949949
HAS_CXX_INTEROPERABILITY_ENABLED,
950950
ALLOW_NON_RESILIENT_ACCESS,
951951
SERIALIZE_PACKAGE_ENABLED,
952+
CXX_STDLIB_KIND,
952953
};
953954

954955
using SDKPathLayout = BCRecordLayout<
@@ -1032,6 +1033,11 @@ namespace options_block {
10321033
HAS_CXX_INTEROPERABILITY_ENABLED
10331034
>;
10341035

1036+
using CXXStdlibKindLayout = BCRecordLayout<
1037+
CXX_STDLIB_KIND,
1038+
BCFixed<1>
1039+
>;
1040+
10351041
using AllowNonResilientAccess = BCRecordLayout<
10361042
ALLOW_NON_RESILIENT_ACCESS
10371043
>;

lib/Serialization/Serialization.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,7 @@ void Serializer::writeBlockInfoBlock() {
853853
BLOCK_RECORD(options_block, MODULE_ABI_NAME);
854854
BLOCK_RECORD(options_block, IS_CONCURRENCY_CHECKED);
855855
BLOCK_RECORD(options_block, HAS_CXX_INTEROPERABILITY_ENABLED);
856+
BLOCK_RECORD(options_block, CXX_STDLIB_KIND);
856857
BLOCK_RECORD(options_block, MODULE_PACKAGE_NAME);
857858
BLOCK_RECORD(options_block, MODULE_EXPORT_AS_NAME);
858859
BLOCK_RECORD(options_block, PLUGIN_SEARCH_OPTION);
@@ -1134,6 +1135,10 @@ void Serializer::writeHeader() {
11341135
options_block::HasCxxInteroperabilityEnabledLayout
11351136
CxxInteroperabilityEnabled(Out);
11361137
CxxInteroperabilityEnabled.emit(ScratchRecord);
1138+
1139+
options_block::CXXStdlibKindLayout CXXStdlibKind(Out);
1140+
CXXStdlibKind.emit(ScratchRecord,
1141+
static_cast<uint8_t>(M->getCXXStdlibKind()));
11371142
}
11381143

11391144
if (Options.SerializeOptionsForDebugging) {

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -954,8 +954,10 @@ LoadedFile *SerializedModuleLoaderBase::loadAST(
954954
M.setABIName(Ctx.getIdentifier(loadedModuleFile->getModuleABIName()));
955955
if (loadedModuleFile->isConcurrencyChecked())
956956
M.setIsConcurrencyChecked();
957-
if (loadedModuleFile->hasCxxInteroperability())
957+
if (loadedModuleFile->hasCxxInteroperability()) {
958958
M.setHasCxxInteroperability();
959+
M.setCXXStdlibKind(loadedModuleFile->getCXXStdlibKind());
960+
}
959961
if (!loadedModuleFile->getModulePackageName().empty()) {
960962
M.setPackageName(Ctx.getIdentifier(loadedModuleFile->getModulePackageName()));
961963
}
@@ -1055,6 +1057,17 @@ LoadedFile *SerializedModuleLoaderBase::loadAST(
10551057
M.getName());
10561058
Ctx.Diags.diagnose(loc, diag::enable_cxx_interop_docs);
10571059
}
1060+
// Modules built with libc++ cannot be imported into modules that are built
1061+
// with libstdc++, and vice versa. Make an exception for Cxx.swiftmodule since
1062+
// it doesn't refer to any C++ stdlib symbols, and for CxxStdlib.swiftmodule
1063+
// since we skipped loading the overlay for the module.
1064+
if (M.hasCxxInteroperability() && Ctx.LangOpts.EnableCXXInterop &&
1065+
M.getCXXStdlibKind() != Ctx.LangOpts.CXXStdlib &&
1066+
M.getName() != Ctx.Id_Cxx && M.getName() != Ctx.Id_CxxStdlib) {
1067+
auto loc = diagLoc.value_or(SourceLoc());
1068+
Ctx.Diags.diagnose(loc, diag::cxx_stdlib_kind_mismatch, M.getName(),
1069+
M.getCXXStdlibKind(), Ctx.LangOpts.CXXStdlib);
1070+
}
10581071

10591072
return fileUnit;
10601073
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// RUN: not %target-swift-frontend -typecheck -Xcc -stdlib=invalid -cxx-interoperability-mode=default %s 2>&1 | %FileCheck %s
2+
3+
// CHECK: error: invalid library name in argument '-stdlib=invalid'

0 commit comments

Comments
 (0)