Skip to content

Commit 041be0b

Browse files
Merge pull request #4452 from swiftwasm/main
[pull] swiftwasm from main
2 parents f0480a7 + b00c07b commit 041be0b

38 files changed

+743
-319
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4635,6 +4635,9 @@ ERROR(distributed_actor_func_param_not_codable,none,
46354635
ERROR(distributed_actor_target_result_not_codable,none,
46364636
"result type %0 of %1 %2 does not conform to serialization requirement '%3'",
46374637
(Type, DescriptiveDeclKind, Identifier, StringRef))
4638+
ERROR(distributed_actor_system_serialization_req_must_be_protocol,none,
4639+
"'SerializationRequirement' type witness %0 must be a protocol type",
4640+
(Type))
46384641
ERROR(distributed_actor_remote_func_implemented_manually,none,
46394642
"distributed instance method's %0 remote counterpart %1 cannot not be implemented manually.",
46404643
(Identifier, Identifier))

include/swift/AST/NameLookup.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,9 @@ void lookupVisibleMemberDecls(VisibleDeclConsumer &Consumer,
491491

492492
namespace namelookup {
493493

494+
/// Add semantic members to \p type before attempting a semantic lookup.
495+
void installSemanticMembersIfNeeded(Type type, DeclNameRef name);
496+
494497
void extractDirectlyReferencedNominalTypes(
495498
Type type, SmallVectorImpl<NominalTypeDecl *> &decls);
496499

include/swift/Reflection/ReflectionContext.h

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,8 +1377,15 @@ class ReflectionContext
13771377
return std::string("failure reading allocation pool contents");
13781378
auto Pool = reinterpret_cast<const PoolRange *>(PoolBytes.get());
13791379

1380+
// Limit how many iterations of this loop we'll do, to avoid potential
1381+
// infinite loops when reading bad data. Limit to 1 million iterations. In
1382+
// normal operation, each pool allocation is 16kB, so that would be ~16GB of
1383+
// metadata which is far more than any normal program should have.
1384+
unsigned LoopCount = 0;
1385+
unsigned LoopLimit = 1000000;
1386+
13801387
auto TrailerPtr = Pool->Begin + Pool->Remaining;
1381-
while (TrailerPtr) {
1388+
while (TrailerPtr && LoopCount++ < LoopLimit) {
13821389
auto TrailerBytes = getReader()
13831390
.readBytes(RemoteAddress(TrailerPtr), sizeof(PoolTrailer));
13841391
if (!TrailerBytes)
@@ -1426,8 +1433,15 @@ class ReflectionContext
14261433
if (!BacktraceListNextPtr)
14271434
return llvm::None;
14281435

1436+
// Limit how many iterations of this loop we'll do, to avoid potential
1437+
// infinite loops when reading bad data. Limit to 1 billion iterations. In
1438+
// normal operation, a program shouldn't have anywhere near 1 billion
1439+
// metadata allocations.
1440+
unsigned LoopCount = 0;
1441+
unsigned LoopLimit = 1000000000;
1442+
14291443
auto BacktraceListNext = BacktraceListNextPtr->getResolvedAddress();
1430-
while (BacktraceListNext) {
1444+
while (BacktraceListNext && LoopCount++ < LoopLimit) {
14311445
auto HeaderBytes = getReader().readBytes(
14321446
RemoteAddress(BacktraceListNext),
14331447
sizeof(MetadataAllocationBacktraceHeader<Runtime>));
@@ -1473,30 +1487,40 @@ class ReflectionContext
14731487
// provide the whole thing as one big chunk.
14741488
size_t HeaderSize =
14751489
llvm::alignTo(sizeof(*Slab), llvm::Align(MaximumAlignment));
1476-
AsyncTaskAllocationChunk Chunk;
14771490

1478-
Chunk.Start = SlabPtr + HeaderSize;
1479-
Chunk.Length = Slab->CurrentOffset;
1480-
Chunk.Kind = AsyncTaskAllocationChunk::ChunkKind::Unknown;
1491+
AsyncTaskAllocationChunk AllocatedSpaceChunk;
1492+
AllocatedSpaceChunk.Start = SlabPtr + HeaderSize;
1493+
AllocatedSpaceChunk.Length = Slab->CurrentOffset;
1494+
AllocatedSpaceChunk.Kind = AsyncTaskAllocationChunk::ChunkKind::Unknown;
1495+
1496+
// Provide a second chunk just for the Next pointer, so the client knows
1497+
// that there's an allocation there.
1498+
AsyncTaskAllocationChunk NextPtrChunk;
1499+
NextPtrChunk.Start =
1500+
SlabPtr + offsetof(typename StackAllocator::Slab, Next);
1501+
NextPtrChunk.Length = sizeof(Slab->Next);
1502+
NextPtrChunk.Kind = AsyncTaskAllocationChunk::ChunkKind::RawPointer;
14811503

14821504
// Total slab size is the slab's capacity plus the header.
14831505
StoredPointer SlabSize = Slab->Capacity + HeaderSize;
14841506

1485-
return {llvm::None, {Slab->Next, SlabSize, {Chunk}}};
1507+
return {llvm::None,
1508+
{Slab->Next, SlabSize, {NextPtrChunk, AllocatedSpaceChunk}}};
14861509
}
14871510

14881511
std::pair<llvm::Optional<std::string>, AsyncTaskInfo>
1489-
asyncTaskInfo(StoredPointer AsyncTaskPtr) {
1512+
asyncTaskInfo(StoredPointer AsyncTaskPtr, unsigned ChildTaskLimit,
1513+
unsigned AsyncBacktraceLimit) {
14901514
loadTargetPointers();
14911515

14921516
if (supportsPriorityEscalation)
14931517
return asyncTaskInfo<
14941518
AsyncTask<Runtime, ActiveTaskStatusWithEscalation<Runtime>>>(
1495-
AsyncTaskPtr);
1519+
AsyncTaskPtr, ChildTaskLimit, AsyncBacktraceLimit);
14961520
else
14971521
return asyncTaskInfo<
14981522
AsyncTask<Runtime, ActiveTaskStatusWithoutEscalation<Runtime>>>(
1499-
AsyncTaskPtr);
1523+
AsyncTaskPtr, ChildTaskLimit, AsyncBacktraceLimit);
15001524
}
15011525

15021526
std::pair<llvm::Optional<std::string>, ActorInfo>
@@ -1588,7 +1612,8 @@ class ReflectionContext
15881612

15891613
template <typename AsyncTaskType>
15901614
std::pair<llvm::Optional<std::string>, AsyncTaskInfo>
1591-
asyncTaskInfo(StoredPointer AsyncTaskPtr) {
1615+
asyncTaskInfo(StoredPointer AsyncTaskPtr, unsigned ChildTaskLimit,
1616+
unsigned AsyncBacktraceLimit) {
15921617
auto AsyncTaskObj = readObj<AsyncTaskType>(AsyncTaskPtr);
15931618
if (!AsyncTaskObj)
15941619
return {std::string("failure reading async task"), {}};
@@ -1620,8 +1645,9 @@ class ReflectionContext
16201645
Info.RunJob = getRunJob(AsyncTaskObj.get());
16211646

16221647
// Find all child tasks.
1648+
unsigned ChildTaskLoopCount = 0;
16231649
auto RecordPtr = AsyncTaskObj->PrivateStorage.Status.Record;
1624-
while (RecordPtr) {
1650+
while (RecordPtr && ChildTaskLoopCount++ < ChildTaskLimit) {
16251651
auto RecordObj = readObj<TaskStatusRecord<Runtime>>(RecordPtr);
16261652
if (!RecordObj)
16271653
break;
@@ -1661,7 +1687,8 @@ class ReflectionContext
16611687
// Walk the async backtrace.
16621688
if (Info.HasIsRunning && !Info.IsRunning) {
16631689
auto ResumeContext = AsyncTaskObj->ResumeContextAndReserved[0];
1664-
while (ResumeContext) {
1690+
unsigned AsyncBacktraceLoopCount = 0;
1691+
while (ResumeContext && AsyncBacktraceLoopCount++ < AsyncBacktraceLimit) {
16651692
auto ResumeContextObj = readObj<AsyncContext<Runtime>>(ResumeContext);
16661693
if (!ResumeContextObj)
16671694
break;

include/swift/Sema/CSFix.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,11 +316,19 @@ enum class FixKind : uint8_t {
316316
/// succeed.
317317
AllowNoopCheckedCast,
318318

319+
/// Warn about special runtime case where statically known
320+
/// checked cast from existentials to CFType always succeed.
321+
AllowNoopExistentialToCFTypeCheckedCast,
322+
319323
/// Allow a runtime checked cast where at compile time the from is
320324
/// convertible, but runtime does not support such convertions. e.g.
321325
/// function type casts.
322326
AllowUnsupportedRuntimeCheckedCast,
323327

328+
/// Allow a runtime checked cast where it is known at compile time
329+
/// always fails.
330+
AllowCheckedCastToUnrelated,
331+
324332
/// Allow reference to a static member on a protocol metatype
325333
/// even though result type of the reference doesn't conform
326334
/// to an expected protocol.
@@ -2789,6 +2797,31 @@ class AllowNoopCheckedCast final : public CheckedCastContextualMismatchWarning {
27892797
}
27902798
};
27912799

2800+
class AllowNoopExistentialToCFTypeCheckedCast final
2801+
: public CheckedCastContextualMismatchWarning {
2802+
AllowNoopExistentialToCFTypeCheckedCast(ConstraintSystem &cs, Type fromType,
2803+
Type toType, CheckedCastKind kind,
2804+
ConstraintLocator *locator)
2805+
: CheckedCastContextualMismatchWarning(
2806+
cs, FixKind::AllowNoopExistentialToCFTypeCheckedCast, fromType,
2807+
toType, kind, locator) {}
2808+
2809+
public:
2810+
std::string getName() const override {
2811+
return "checked cast from existential to CFType always succeeds";
2812+
}
2813+
2814+
bool diagnose(const Solution &solution, bool asNote = false) const override;
2815+
2816+
static AllowNoopExistentialToCFTypeCheckedCast *
2817+
attempt(ConstraintSystem &cs, Type fromType, Type toType,
2818+
CheckedCastKind kind, ConstraintLocator *locator);
2819+
2820+
static bool classof(ConstraintFix *fix) {
2821+
return fix->getKind() == FixKind::AllowNoopExistentialToCFTypeCheckedCast;
2822+
}
2823+
};
2824+
27922825
class AllowUnsupportedRuntimeCheckedCast final
27932826
: public CheckedCastContextualMismatchWarning {
27942827
AllowUnsupportedRuntimeCheckedCast(ConstraintSystem &cs, Type fromType,
@@ -2816,6 +2849,29 @@ class AllowUnsupportedRuntimeCheckedCast final
28162849
}
28172850
};
28182851

2852+
class AllowCheckedCastToUnrelated final
2853+
: public CheckedCastContextualMismatchWarning {
2854+
AllowCheckedCastToUnrelated(ConstraintSystem &cs, Type fromType, Type toType,
2855+
CheckedCastKind kind, ConstraintLocator *locator)
2856+
: CheckedCastContextualMismatchWarning(
2857+
cs, FixKind::AllowCheckedCastToUnrelated, fromType, toType, kind,
2858+
locator) {}
2859+
2860+
public:
2861+
std::string getName() const override { return "checked cast always fails"; }
2862+
2863+
bool diagnose(const Solution &solution, bool asNote = false) const override;
2864+
2865+
static AllowCheckedCastToUnrelated *attempt(ConstraintSystem &cs,
2866+
Type fromType, Type toType,
2867+
CheckedCastKind kind,
2868+
ConstraintLocator *locator);
2869+
2870+
static bool classof(ConstraintFix *fix) {
2871+
return fix->getKind() == FixKind::AllowCheckedCastToUnrelated;
2872+
}
2873+
};
2874+
28192875
class AllowInvalidStaticMemberRefOnProtocolMetatype final
28202876
: public ConstraintFix {
28212877
AllowInvalidStaticMemberRefOnProtocolMetatype(ConstraintSystem &cs,

lib/AST/DistributedDecl.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -271,12 +271,24 @@ swift::getDistributedSerializationRequirements(
271271
if (existentialRequirementTy->isAny())
272272
return true; // we're done here, any means there are no requirements
273273

274-
auto serialReqType = existentialRequirementTy->castTo<ExistentialType>()
275-
->getConstraintType()
276-
->getDesugaredType();
274+
if (auto alias = dyn_cast<TypeAliasType>(existentialRequirementTy.getPointer())) {
275+
auto ty = alias->getDesugaredType();
276+
if (isa<ClassType>(ty) || isa<StructType>(ty) || isa<EnumType>(ty)) {
277+
// SerializationRequirement cannot be class or struct nowadays
278+
return false;
279+
}
280+
}
281+
282+
ExistentialType *serialReqType = existentialRequirementTy
283+
->castTo<ExistentialType>();
284+
if (!serialReqType || serialReqType->hasError()) {
285+
return false;
286+
}
287+
288+
auto desugaredTy = serialReqType->getConstraintType()->getDesugaredType();
277289
auto flattenedRequirements =
278290
flattenDistributedSerializationTypeToRequiredProtocols(
279-
serialReqType);
291+
desugaredTy);
280292
for (auto p : flattenedRequirements) {
281293
requirementProtos.insert(p);
282294
}

lib/AST/NameLookup.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1592,6 +1592,32 @@ void namelookup::pruneLookupResultSet(const DeclContext *dc, NLOptions options,
15921592
filterForDiscriminator(decls, M->getDebugClient());
15931593
}
15941594

1595+
// An unfortunate hack to kick the decl checker into adding semantic members to
1596+
// the current type before we attempt a semantic lookup. The places this method
1597+
// looks needs to be in sync with \c extractDirectlyReferencedNominalTypes.
1598+
// See the note in \c synthesizeSemanticMembersIfNeeded about a better, more
1599+
// just, and peaceful world.
1600+
void namelookup::installSemanticMembersIfNeeded(Type type, DeclNameRef name) {
1601+
// Look-through class-bound archetypes to ensure we synthesize e.g.
1602+
// inherited constructors.
1603+
if (auto archetypeTy = type->getAs<ArchetypeType>()) {
1604+
if (auto super = archetypeTy->getSuperclass()) {
1605+
type = super;
1606+
}
1607+
}
1608+
1609+
if (type->isExistentialType()) {
1610+
auto layout = type->getExistentialLayout();
1611+
if (auto super = layout.explicitSuperclass) {
1612+
type = super;
1613+
}
1614+
}
1615+
1616+
if (auto *current = type->getAnyNominal()) {
1617+
current->synthesizeSemanticMembersIfNeeded(name.getFullName());
1618+
}
1619+
}
1620+
15951621
/// Inspect the given type to determine which nominal type declarations it
15961622
/// directly references, to facilitate name lookup into those types.
15971623
void namelookup::extractDirectlyReferencedNominalTypes(

lib/IDE/ExprContextAnalysis.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "swift/AST/Initializer.h"
2222
#include "swift/AST/LazyResolver.h"
2323
#include "swift/AST/Module.h"
24+
#include "swift/AST/NameLookup.h"
2425
#include "swift/AST/ParameterList.h"
2526
#include "swift/AST/Pattern.h"
2627
#include "swift/AST/SourceFile.h"
@@ -364,6 +365,9 @@ static void collectPossibleCalleesByQualifiedLookup(
364365
if (!baseInstanceTy->mayHaveMembers())
365366
return;
366367

368+
// Make sure we've resolved implicit members.
369+
namelookup::installSemanticMembersIfNeeded(baseInstanceTy, name);
370+
367371
bool isOnMetaType = baseTy->is<AnyMetatypeType>();
368372

369373
SmallVector<ValueDecl *, 2> decls;

0 commit comments

Comments
 (0)