Skip to content

Commit 239f32f

Browse files
authored
Merge branch 'swift-5.1-branch' into fix/SR-11478_5.1
2 parents f24844d + bb70f0e commit 239f32f

File tree

11 files changed

+280
-27
lines changed

11 files changed

+280
-27
lines changed

lib/Basic/Platform.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,8 @@ swift::getSwiftRuntimeCompatibilityVersionForTarget(const llvm::Triple &Triple){
323323
if (Major == 10) {
324324
if (Minor <= 14) {
325325
return llvm::VersionTuple(5, 0);
326+
} else if (Minor <= 15) {
327+
return llvm::VersionTuple(5, 1);
326328
} else {
327329
return None;
328330
}
@@ -333,13 +335,17 @@ swift::getSwiftRuntimeCompatibilityVersionForTarget(const llvm::Triple &Triple){
333335
Triple.getiOSVersion(Major, Minor, Micro);
334336
if (Major <= 12) {
335337
return llvm::VersionTuple(5, 0);
338+
} else if (Major <= 13) {
339+
return llvm::VersionTuple(5, 1);
336340
} else {
337341
return None;
338342
}
339343
} else if (Triple.isWatchOS()) {
340344
Triple.getWatchOSVersion(Major, Minor, Micro);
341345
if (Major <= 5) {
342346
return llvm::VersionTuple(5, 0);
347+
} else if (Major <= 6) {
348+
return llvm::VersionTuple(5, 1);
343349
} else {
344350
return None;
345351
}

lib/IRGen/GenDecl.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2559,13 +2559,22 @@ static llvm::GlobalVariable *createGOTEquivalent(IRGenModule &IGM,
25592559
// rdar://problem/50968433: Unnamed_addr constants appear to get emitted
25602560
// with incorrect alignment by the LLVM JIT in some cases. Don't use
25612561
// unnamed_addr as a workaround.
2562-
if (!IGM.getOptions().UseJIT) {
2562+
// rdar://problem/53836960: LLVM miscompiles relative references to local
2563+
// symbols.
2564+
if (!IGM.getOptions().UseJIT
2565+
&& (!IGM.Triple.isOSDarwin()
2566+
|| (IGM.Triple.getArch() != llvm::Triple::x86 &&
2567+
IGM.Triple.getArchName() != "armv7" &&
2568+
IGM.Triple.getArchName() != "armv7s" &&
2569+
IGM.Triple.getArchName() != "thumbv7" &&
2570+
IGM.Triple.getArchName() != "thumbv7s" &&
2571+
!IGM.Triple.isWatchABI()))) {
25632572
gotEquivalent->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
25642573
} else {
25652574
ApplyIRLinkage(IRLinkage::InternalLinkOnceODR)
25662575
.to(gotEquivalent);
25672576
}
2568-
2577+
25692578
return gotEquivalent;
25702579
}
25712580

lib/IRGen/GenKeyPath.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -649,9 +649,10 @@ getInitializerForComputedComponent(IRGenModule &IGM,
649649
}
650650

651651
static llvm::Constant *
652-
emitMetadataTypeRefForKeyPath(IRGenModule &IGM, CanType type) {
652+
emitMetadataTypeRefForKeyPath(IRGenModule &IGM, CanType type,
653+
CanGenericSignature sig) {
653654
// Produce a mangled name for the type.
654-
auto constant = IGM.getTypeRef(type, MangledTypeRefRole::Metadata);
655+
auto constant = IGM.getTypeRef(type, sig, MangledTypeRefRole::Metadata);
655656

656657
// Mask the bottom bit to tell the key path runtime this is a mangled name
657658
// rather than a direct reference.
@@ -837,6 +838,10 @@ emitKeyPathComponent(IRGenModule &IGM,
837838
SmallVector<llvm::Constant *, 4> externalSubArgs;
838839
auto componentSig = externalDecl->getInnermostDeclContext()
839840
->getGenericSignatureOfContext();
841+
842+
auto componentCanSig = componentSig
843+
? componentSig->getCanonicalSignature()
844+
: CanGenericSignature();
840845
auto subs = component.getExternalSubstitutions();
841846
if (!subs.empty()) {
842847
enumerateGenericSignatureRequirements(
@@ -847,7 +852,7 @@ emitKeyPathComponent(IRGenModule &IGM,
847852
if (!reqt.Protocol) {
848853
// Type requirement.
849854
externalSubArgs.push_back(
850-
emitMetadataTypeRefForKeyPath(IGM, substType));
855+
emitMetadataTypeRefForKeyPath(IGM, substType, componentCanSig));
851856
} else {
852857
// Protocol requirement.
853858
auto conformance = subs.lookupConformance(
@@ -1182,9 +1187,11 @@ IRGenModule::getAddrOfKeyPathPattern(KeyPathPattern *pattern,
11821187
getAddrOfGenericEnvironment(pattern->getGenericSignature()));
11831188
// Store type references for the root and leaf.
11841189
fields.addRelativeAddress(
1185-
emitMetadataTypeRefForKeyPath(*this, rootTy));
1190+
emitMetadataTypeRefForKeyPath(*this, rootTy,
1191+
pattern->getGenericSignature()));
11861192
fields.addRelativeAddress(
1187-
emitMetadataTypeRefForKeyPath(*this, valueTy));
1193+
emitMetadataTypeRefForKeyPath(*this, valueTy,
1194+
pattern->getGenericSignature()));
11881195

11891196
// Add a pointer to the ObjC KVC compatibility string, if there is one, or
11901197
// null otherwise.
@@ -1238,7 +1245,9 @@ IRGenModule::getAddrOfKeyPathPattern(KeyPathPattern *pattern,
12381245
// For all but the last component, we pack in the type of the component.
12391246
if (i + 1 != pattern->getComponents().size()) {
12401247
fields.addRelativeAddress(
1241-
emitMetadataTypeRefForKeyPath(*this, component.getComponentType()));
1248+
emitMetadataTypeRefForKeyPath(*this,
1249+
component.getComponentType(),
1250+
pattern->getGenericSignature()));
12421251
}
12431252
baseTy = component.getComponentType();
12441253
}

lib/IRGen/GenMeta.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1680,11 +1680,16 @@ namespace {
16801680
}
16811681

16821682
void addUnderlyingTypeAndConformances() {
1683+
auto sig = O->getOpaqueInterfaceGenericSignature();
16831684
auto underlyingType = Type(O->getUnderlyingInterfaceType())
16841685
.subst(*O->getUnderlyingTypeSubstitutions())
1685-
->getCanonicalType(O->getOpaqueInterfaceGenericSignature());
1686+
->getCanonicalType(sig);
16861687

1687-
B.addRelativeAddress(IGM.getTypeRef(underlyingType,
1688+
auto contextSig = O->getGenericSignature()
1689+
? O->getGenericSignature()->getCanonicalSignature()
1690+
: CanGenericSignature();
1691+
1692+
B.addRelativeAddress(IGM.getTypeRef(underlyingType, contextSig,
16881693
MangledTypeRefRole::Metadata));
16891694

16901695
auto opaqueType = O->getDeclaredInterfaceType()
@@ -1698,7 +1703,7 @@ namespace {
16981703

16991704
auto witnessTableRef = IGM.emitWitnessTableRefString(
17001705
underlyingType, underlyingConformance,
1701-
O->getGenericSignature(),
1706+
contextSig,
17021707
/*setLowBit*/ false);
17031708
B.addRelativeAddress(witnessTableRef);
17041709
}

lib/IRGen/GenReflection.cpp

Lines changed: 132 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "swift/AST/PrettyStackTrace.h"
2121
#include "swift/AST/ProtocolConformance.h"
2222
#include "swift/AST/SubstitutionMap.h"
23+
#include "swift/Basic/Platform.h"
2324
#include "swift/IRGen/Linking.h"
2425
#include "swift/Reflection/MetadataSourceBuilder.h"
2526
#include "swift/Reflection/Records.h"
@@ -38,6 +39,7 @@
3839
#include "IRGenMangler.h"
3940
#include "IRGenModule.h"
4041
#include "LoadableTypeInfo.h"
42+
#include "MetadataRequest.h"
4143

4244
using namespace swift;
4345
using namespace irgen;
@@ -168,13 +170,117 @@ class PrintMetadataSource
168170
}
169171
};
170172

173+
// Return whether the Swift runtime supports demangling a given
174+
// type.
175+
static bool
176+
doesRuntimeSupportDemanglingType(IRGenModule &IGM, CanType type) {
177+
// Associated types of opaque types weren't mangled in a usable form by the
178+
// Swift 5.1 runtime, so we needed to add a new mangling in 5.2.
179+
if (type->hasOpaqueArchetype()) {
180+
auto hasOpaqueAssocType = type.findIf([](CanType t) -> bool {
181+
if (auto a = dyn_cast<NestedArchetypeType>(t)) {
182+
return isa<OpaqueTypeArchetypeType>(a->getRoot());
183+
}
184+
return false;
185+
});
186+
187+
if (hasOpaqueAssocType)
188+
return false;
189+
// Although opaque types in general were only added in Swift 5.1,
190+
// declarations that use them are already covered by availability
191+
// guards, so we don't need to limit availability of mangled names
192+
// involving them.
193+
}
194+
195+
return true;
196+
}
197+
198+
// Produce a fallback mangled type name that uses an open-coded callback
199+
// to form the metadata. This is useful for working around bugs in older
200+
// runtimes, or supporting new type system features when deploying back.
201+
//
202+
// Note that this functionality is limited, because the demangler callback
203+
// mechanism can only produce complete metadata. It can't be used in situations
204+
// where completing the metadata during demangling might cause cyclic
205+
// dependencies.
206+
static llvm::Constant *
207+
getTypeRefByFunction(IRGenModule &IGM,
208+
CanGenericSignature sig,
209+
CanType t) {
210+
IRGenMangler mangler;
211+
std::string symbolName =
212+
mangler.mangleSymbolNameForMangledMetadataAccessorString(
213+
"get_type_metadata", sig, t);
214+
auto constant = IGM.getAddrOfStringForMetadataRef(symbolName, /*align*/2,
215+
/*low bit*/false,
216+
[&](ConstantInitBuilder &B) {
217+
llvm::Function *accessor;
218+
219+
// Otherwise, we need to emit a helper function to bind the arguments
220+
// out of the demangler's argument buffer.
221+
auto fnTy = llvm::FunctionType::get(IGM.TypeMetadataPtrTy,
222+
{IGM.Int8PtrTy}, /*vararg*/ false);
223+
accessor =
224+
llvm::Function::Create(fnTy, llvm::GlobalValue::PrivateLinkage,
225+
symbolName, IGM.getModule());
226+
accessor->setAttributes(IGM.constructInitialAttributes());
227+
228+
SmallVector<GenericRequirement, 4> requirements;
229+
GenericEnvironment *genericEnv = nullptr;
230+
if (sig) {
231+
enumerateGenericSignatureRequirements(sig,
232+
[&](GenericRequirement reqt) { requirements.push_back(reqt); });
233+
genericEnv = sig->createGenericEnvironment();
234+
}
235+
236+
{
237+
IRGenFunction IGF(IGM, accessor);
238+
if (IGM.DebugInfo)
239+
IGM.DebugInfo->emitArtificialFunction(IGF, accessor);
240+
241+
auto bindingsBufPtr = IGF.collectParameters().claimNext();
242+
243+
auto substT = genericEnv
244+
? genericEnv->mapTypeIntoContext(t)->getCanonicalType()
245+
: t;
246+
247+
bindFromGenericRequirementsBuffer(IGF, requirements,
248+
Address(bindingsBufPtr, IGM.getPointerAlignment()),
249+
MetadataState::Complete,
250+
[&](CanType t) {
251+
return genericEnv
252+
? genericEnv->mapTypeIntoContext(t)->getCanonicalType()
253+
: t;
254+
});
255+
256+
auto ret = IGF.emitTypeMetadataRef(substT);
257+
IGF.Builder.CreateRet(ret);
258+
}
259+
// Form the mangled name with its relative reference.
260+
auto S = B.beginStruct();
261+
S.setPacked(true);
262+
S.add(llvm::ConstantInt::get(IGM.Int8Ty, 255));
263+
S.add(llvm::ConstantInt::get(IGM.Int8Ty, 9));
264+
S.addRelativeAddress(accessor);
265+
266+
// And a null terminator!
267+
S.addInt(IGM.Int8Ty, 0);
268+
269+
return S.finishAndCreateFuture();
270+
});
271+
return constant;
272+
}
273+
171274
llvm::Constant *IRGenModule::getTypeRef(Type type,
172275
GenericSignature *genericSig,
173276
MangledTypeRefRole role) {
174-
return getTypeRef(type->getCanonicalType(genericSig), role);
277+
return getTypeRef(type->getCanonicalType(genericSig),
278+
genericSig ? genericSig->getCanonicalSignature() : CanGenericSignature(),
279+
role);
175280
}
176281

177282
llvm::Constant *IRGenModule::getTypeRef(CanType type,
283+
CanGenericSignature genericSig,
178284
MangledTypeRefRole role) {
179285

180286
switch (role) {
@@ -184,6 +290,12 @@ llvm::Constant *IRGenModule::getTypeRef(CanType type,
184290
// ensuring that we can always reconstruct type metadata from a mangled name
185291
// in-process.
186292
IRGen.noteUseOfTypeMetadata(type);
293+
// If the minimum deployment target's runtime demangler wouldn't understand
294+
// this mangled name, then fall back to generating a "mangled name" with a
295+
// symbolic reference with a callback function.
296+
if (!doesRuntimeSupportDemanglingType(*this, type)) {
297+
return getTypeRefByFunction(*this, genericSig, type);
298+
}
187299
break;
188300

189301
case MangledTypeRefRole::Reflection:
@@ -223,7 +335,7 @@ IRGenModule::emitWitnessTableRefString(CanType type,
223335

224336
IRGenMangler mangler;
225337
std::string symbolName =
226-
mangler.mangleSymbolNameForKeyPathMetadata(
338+
mangler.mangleSymbolNameForMangledConformanceAccessorString(
227339
"get_witness_table", genericSig, type, conformance);
228340

229341
return getAddrOfStringForMetadataRef(symbolName, /*alignment=*/2,
@@ -376,7 +488,10 @@ class ReflectionMetadataBuilder {
376488
void addTypeRef(Type type, GenericSignature *genericSig,
377489
MangledTypeRefRole role =
378490
MangledTypeRefRole::Reflection) {
379-
addTypeRef(type->getCanonicalType(genericSig), role);
491+
addTypeRef(type->getCanonicalType(genericSig),
492+
genericSig ? genericSig->getCanonicalSignature()
493+
: CanGenericSignature(),
494+
role);
380495
}
381496

382497
/// Add a 32-bit relative offset to a mangled typeref string
@@ -388,9 +503,10 @@ class ReflectionMetadataBuilder {
388503
/// For reflection records which are demangled to produce type metadata
389504
/// in-process, pass MangledTypeRefRole::Metadata instead.
390505
void addTypeRef(CanType type,
506+
CanGenericSignature sig,
391507
MangledTypeRefRole role =
392508
MangledTypeRefRole::Reflection) {
393-
B.addRelativeAddress(IGM.getTypeRef(type, role));
509+
B.addRelativeAddress(IGM.getTypeRef(type, sig, role));
394510
addBuiltinTypeRefs(type);
395511
}
396512

@@ -487,7 +603,10 @@ class AssociatedTypeMetadataBuilder : public ReflectionMetadataBuilder {
487603
for (auto AssocTy : AssociatedTypes) {
488604
auto NameGlobal = IGM.getAddrOfFieldName(AssocTy.first);
489605
B.addRelativeAddress(NameGlobal);
490-
addTypeRef(AssocTy.second);
606+
addTypeRef(AssocTy.second,
607+
Nominal->getGenericSignature()
608+
? Nominal->getGenericSignature()->getCanonicalSignature()
609+
: CanGenericSignature());
491610
}
492611
}
493612

@@ -683,7 +802,7 @@ class FixedTypeMetadataBuilder : public ReflectionMetadataBuilder {
683802
}
684803

685804
void layout() override {
686-
addTypeRef(type);
805+
addTypeRef(type, CanGenericSignature());
687806

688807
B.addInt32(ti->getFixedSize().getValue());
689808

@@ -726,7 +845,7 @@ class BoxDescriptorBuilder : public ReflectionMetadataBuilder {
726845
B.addInt32(0); // Number of sources
727846
B.addInt32(0); // Number of generic bindings
728847

729-
addTypeRef(BoxedType);
848+
addTypeRef(BoxedType, CanGenericSignature());
730849
}
731850

732851
llvm::GlobalVariable *emit() {
@@ -919,9 +1038,13 @@ class CaptureDescriptorBuilder : public ReflectionMetadataBuilder {
9191038
B.addInt32(MetadataSources.size());
9201039
B.addInt32(Layout.getBindings().size());
9211040

1041+
auto sig = OrigCalleeType->getGenericSignature()
1042+
? OrigCalleeType->getGenericSignature()->getCanonicalSignature()
1043+
: CanGenericSignature();
1044+
9221045
// Now add typerefs of all of the captures.
9231046
for (auto CaptureType : CaptureTypes) {
924-
addTypeRef(CaptureType);
1047+
addTypeRef(CaptureType, sig);
9251048
addBuiltinTypeRefs(CaptureType);
9261049
}
9271050

@@ -931,7 +1054,7 @@ class CaptureDescriptorBuilder : public ReflectionMetadataBuilder {
9311054
auto GenericParam = GenericAndSource.first->getCanonicalType();
9321055
auto Source = GenericAndSource.second;
9331056

934-
addTypeRef(GenericParam);
1057+
addTypeRef(GenericParam, sig);
9351058
addMetadataSource(Source);
9361059
}
9371060
}

lib/IRGen/IRGenMangler.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,22 @@ std::string IRGenMangler::mangleSymbolNameForAssociatedConformanceWitness(
277277
return finalize();
278278
}
279279

280-
std::string IRGenMangler::mangleSymbolNameForKeyPathMetadata(
280+
std::string IRGenMangler::mangleSymbolNameForMangledMetadataAccessorString(
281+
const char *kind,
282+
CanGenericSignature genericSig,
283+
CanType type) {
284+
beginManglingWithoutPrefix();
285+
Buffer << kind << " ";
286+
287+
if (genericSig)
288+
appendGenericSignature(genericSig);
289+
290+
if (type)
291+
appendType(type);
292+
return finalize();
293+
}
294+
295+
std::string IRGenMangler::mangleSymbolNameForMangledConformanceAccessorString(
281296
const char *kind,
282297
CanGenericSignature genericSig,
283298
CanType type,

0 commit comments

Comments
 (0)