Skip to content

Commit 78d4bcb

Browse files
authored
Merge pull request #3098 from swiftwasm/release/5.4
[pull] swiftwasm-release/5.4 from release/5.4
2 parents 3a2e61a + 7b3dbf2 commit 78d4bcb

File tree

54 files changed

+386
-69
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+386
-69
lines changed

include/swift/Sema/ConstraintLocator.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,13 @@ class ConstraintLocator : public llvm::FoldingSetNode {
199199
/// via key path dynamic member lookup.
200200
bool isForKeyPathDynamicMemberLookup() const;
201201

202-
/// Determine whether this locator points to one of the key path
203-
/// components.
204-
bool isForKeyPathComponent() const;
202+
/// Determine whether this locator points to element inside
203+
/// of a key path component.
204+
bool isInKeyPathComponent() const;
205+
206+
/// Determine whether this locator points to a result type of
207+
/// a key path component.
208+
bool isForKeyPathComponentResult() const;
205209

206210
/// Determine whether this locator points to the generic parameter.
207211
bool isForGenericParameter() const;

lib/ClangImporter/ClangImporter.cpp

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -555,21 +555,44 @@ importer::getNormalInvocationArguments(
555555
invocationArgStrs.push_back(
556556
"-Werror=non-modular-include-in-framework-module");
557557

558+
bool EnableCXXInterop = LangOpts.EnableCXXInterop;
559+
558560
if (LangOpts.EnableObjCInterop) {
559-
bool EnableCXXInterop = LangOpts.EnableCXXInterop;
560-
invocationArgStrs.insert(
561-
invocationArgStrs.end(),
562-
{"-x", EnableCXXInterop ? "objective-c++" : "objective-c",
563-
EnableCXXInterop ? "-std=gnu++17" : "-std=gnu11", "-fobjc-arc"});
561+
invocationArgStrs.insert(invocationArgStrs.end(), {"-fobjc-arc"});
564562
// TODO: Investigate whether 7.0 is a suitable default version.
565563
if (!triple.isOSDarwin())
566564
invocationArgStrs.insert(invocationArgStrs.end(),
567565
{"-fobjc-runtime=ios-7.0"});
566+
invocationArgStrs.insert(invocationArgStrs.end(), {
567+
"-x", EnableCXXInterop ? "objective-c++" : "objective-c"
568+
});
568569
} else {
569-
bool EnableCXXInterop = LangOpts.EnableCXXInterop;
570-
invocationArgStrs.insert(invocationArgStrs.end(),
571-
{"-x", EnableCXXInterop ? "c++" : "c",
572-
EnableCXXInterop ? "-std=gnu++17" : "-std=gnu11"});
570+
invocationArgStrs.insert(invocationArgStrs.end(), {
571+
"-x", EnableCXXInterop ? "c++" : "c"
572+
});
573+
}
574+
575+
{
576+
const clang::LangStandard &stdcxx =
577+
#if defined(CLANG_DEFAULT_STD_CXX)
578+
*clang::LangStandard::getLangStandardForName(CLANG_DEFAULT_STD_CXX);
579+
#else
580+
clang::LangStandard::getLangStandardForKind(
581+
clang::LangStandard::lang_gnucxx14);
582+
#endif
583+
584+
const clang::LangStandard &stdc =
585+
#if defined(CLANG_DEFAULT_STD_C)
586+
*clang::LangStandard::getLangStandardForName(CLANG_DEFAULT_STD_C);
587+
#else
588+
clang::LangStandard::getLangStandardForKind(
589+
clang::LangStandard::lang_gnu11);
590+
#endif
591+
592+
invocationArgStrs.insert(invocationArgStrs.end(), {
593+
(Twine("-std=") + StringRef(EnableCXXInterop ? stdcxx.getName()
594+
: stdc.getName())).str()
595+
});
573596
}
574597

575598
// Set C language options.

lib/ClangImporter/ImportType.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2302,6 +2302,8 @@ ImportedType ClangImporter::Implementation::importMethodParamsAndReturnType(
23022302
if (kind == SpecialMethodKind::NSDictionarySubscriptGetter &&
23032303
paramTy->isObjCIdType()) {
23042304
swiftParamTy = SwiftContext.getNSCopyingType();
2305+
if (!swiftParamTy)
2306+
return {Type(), false};
23052307
if (optionalityOfParam != OTK_None)
23062308
swiftParamTy = OptionalType::get(swiftParamTy);
23072309

lib/SIL/Verifier/LoadBorrowImmutabilityChecker.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ bool GatherWritesVisitor::visitUse(Operand *op, AccessUseType useTy) {
107107
case SILInstructionKind::AssignInst:
108108
case SILInstructionKind::UncheckedTakeEnumDataAddrInst:
109109
case SILInstructionKind::MarkFunctionEscapeInst:
110+
case SILInstructionKind::DeallocRefInst:
111+
case SILInstructionKind::DeallocPartialRefInst:
110112
writeAccumulator.push_back(op);
111113
return true;
112114

lib/SILOptimizer/LoopTransforms/ArrayBoundsCheckOpts.cpp

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ using ArrayAccessDesc = llvm::PointerIntPair<ValueBase *, 1, bool>;
6767
using IndexedArraySet = llvm::DenseSet<std::pair<ValueBase *, ArrayAccessDesc>>;
6868
using InstructionSet = llvm::SmallPtrSet<SILInstruction *, 16>;
6969

70+
// Should be more than enough to cover "usual" functions.
71+
static constexpr int maxRecursionDepth = 500;
72+
7073
/// The effect an instruction can have on array bounds.
7174
enum class ArrayBoundsEffect {
7275
kNone = 0,
@@ -378,12 +381,17 @@ static bool removeRedundantChecksInBlock(SILBasicBlock &BB, ArraySet &Arrays,
378381
static bool removeRedundantChecks(DominanceInfoNode *CurBB,
379382
ABCAnalysis &ABC,
380383
IndexedArraySet &DominatingSafeChecks,
381-
SILLoop *Loop) {
384+
SILLoop *Loop,
385+
int recursionDepth) {
382386
auto *BB = CurBB->getBlock();
383387
if (!Loop->contains(BB))
384388
return false;
385389
bool Changed = false;
386390

391+
// Avoid a stack overflow for very deep dominator trees.
392+
if (recursionDepth >= maxRecursionDepth)
393+
return false;
394+
387395
// When we come back from the dominator tree recursion we need to remove
388396
// checks that we have seen for the first time.
389397
SmallVector<std::pair<ValueBase *, ArrayAccessDesc>, 8> SafeChecksToPop;
@@ -436,7 +444,8 @@ static bool removeRedundantChecks(DominanceInfoNode *CurBB,
436444
// Traverse the children in the dominator tree inside the loop.
437445
for (auto Child: *CurBB)
438446
Changed |=
439-
removeRedundantChecks(Child, ABC, DominatingSafeChecks, Loop);
447+
removeRedundantChecks(Child, ABC, DominatingSafeChecks, Loop,
448+
recursionDepth + 1);
440449

441450
// Remove checks we have seen for the first time.
442451
std::for_each(SafeChecksToPop.begin(), SafeChecksToPop.end(),
@@ -930,7 +939,12 @@ static bool hasArrayType(SILValue Value, SILModule &M) {
930939
static bool hoistChecksInLoop(DominanceInfo *DT, DominanceInfoNode *DTNode,
931940
ABCAnalysis &ABC, InductionAnalysis &IndVars,
932941
SILBasicBlock *Preheader, SILBasicBlock *Header,
933-
SILBasicBlock *SingleExitingBlk) {
942+
SILBasicBlock *SingleExitingBlk,
943+
int recursionDepth) {
944+
945+
// Avoid a stack overflow for very deep dominator trees.
946+
if (recursionDepth >= maxRecursionDepth)
947+
return false;
934948

935949
bool Changed = false;
936950
auto *CurBB = DTNode->getBlock();
@@ -1029,7 +1043,7 @@ static bool hoistChecksInLoop(DominanceInfo *DT, DominanceInfoNode *DTNode,
10291043
// Traverse the children in the dominator tree.
10301044
for (auto Child: *DTNode)
10311045
Changed |= hoistChecksInLoop(DT, Child, ABC, IndVars, Preheader,
1032-
Header, SingleExitingBlk);
1046+
Header, SingleExitingBlk, recursionDepth + 1);
10331047

10341048
return Changed;
10351049
}
@@ -1127,7 +1141,8 @@ static bool hoistBoundsChecks(SILLoop *Loop, DominanceInfo *DT, SILLoopInfo *LI,
11271141
// check for safety outside the loop (with ABCAnalysis).
11281142
IndexedArraySet DominatingSafeChecks;
11291143
bool Changed = removeRedundantChecks(DT->getNode(Header), ABC,
1130-
DominatingSafeChecks, Loop);
1144+
DominatingSafeChecks, Loop,
1145+
/*recursionDepth*/ 0);
11311146

11321147
if (!EnableABCHoisting)
11331148
return Changed;
@@ -1233,7 +1248,8 @@ static bool hoistBoundsChecks(SILLoop *Loop, DominanceInfo *DT, SILLoopInfo *LI,
12331248

12341249
// Hoist bounds checks.
12351250
Changed |= hoistChecksInLoop(DT, DT->getNode(Header), ABC, IndVars,
1236-
Preheader, Header, SingleExitingBlk);
1251+
Preheader, Header, SingleExitingBlk,
1252+
/*recursionDepth*/ 0);
12371253
if (Changed) {
12381254
Preheader->getParent()->verify();
12391255
}

lib/Sema/CSBindings.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -577,8 +577,10 @@ ConstraintSystem::determineBestBindings() {
577577

578578
return bindings || !bindings.Defaults.empty() ||
579579
llvm::any_of(bindings.Protocols, [&](Constraint *constraint) {
580-
return bool(
581-
TypeChecker::getDefaultType(constraint->getProtocol(), DC));
580+
return constraint->getKind() ==
581+
ConstraintKind::LiteralConformsTo &&
582+
bool(TypeChecker::getDefaultType(constraint->getProtocol(),
583+
DC));
582584
});
583585
};
584586

@@ -1304,6 +1306,13 @@ bool TypeVarBindingProducer::computeNext() {
13041306
}
13051307
}
13061308

1309+
// There is a tailored fix for optional key path root references,
1310+
// let's not create ambiguity by attempting unwrap when it's
1311+
// not allowed.
1312+
if (binding.Kind != BindingKind::Subtypes &&
1313+
getLocator()->isKeyPathRoot() && type->getOptionalObjectType())
1314+
continue;
1315+
13071316
// Allow solving for T even for a binding kind where that's invalid
13081317
// if fixes are allowed, because that gives us the opportunity to
13091318
// match T? values to the T binding by adding an unwrap fix.

lib/Sema/CSDiagnostics.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3930,7 +3930,7 @@ bool AllowTypeOrInstanceMemberFailure::diagnoseAsError() {
39303930
// If this is a reference to a static member by one of the key path
39313931
// components, let's provide a tailored diagnostic and return because
39323932
// that is unsupported so there is no fix-it.
3933-
if (locator->isForKeyPathComponent()) {
3933+
if (locator->isInKeyPathComponent()) {
39343934
InvalidStaticMemberRefInKeyPath failure(getSolution(), Member, locator);
39353935
return failure.diagnoseAsError();
39363936
}

lib/Sema/CSDiagnostics.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1543,7 +1543,7 @@ class InvalidMemberRefInKeyPath : public FailureDiagnostic {
15431543
ConstraintLocator *locator)
15441544
: FailureDiagnostic(solution, locator), Member(member) {
15451545
assert(member->hasName());
1546-
assert(locator->isForKeyPathComponent() ||
1546+
assert(locator->isInKeyPathComponent() ||
15471547
locator->isForKeyPathDynamicMemberLookup());
15481548
}
15491549

lib/Sema/CSSimplify.cpp

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7371,8 +7371,21 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
73717371

73727372
// Record a hole for memberTy to make it possible to form solutions
73737373
// when contextual result type cannot be deduced e.g. `let _ = x.foo`.
7374-
if (auto *memberTypeVar = memberTy->getAs<TypeVariableType>())
7375-
recordPotentialHole(memberTypeVar);
7374+
if (auto *memberTypeVar = memberTy->getAs<TypeVariableType>()) {
7375+
if (getFixedType(memberTypeVar)) {
7376+
// If member has been bound before the base and the base was
7377+
// incorrect at that (e.g. fallback to default `Any` type),
7378+
// then we need to re-activate all of the constraints
7379+
// associated with this member reference otherwise some of
7380+
// the constraints could be left unchecked in inactive state.
7381+
// This is especially important for key path expressions because
7382+
// `key path` constraint can't be retired until all components
7383+
// are simplified.
7384+
addTypeVariableConstraintsToWorkList(memberTypeVar);
7385+
} else {
7386+
recordPotentialHole(memberTypeVar);
7387+
}
7388+
}
73767389

73777390
return SolutionKind::Solved;
73787391
};
@@ -8395,15 +8408,28 @@ ConstraintSystem::simplifyKeyPathConstraint(
83958408
return SolutionKind::Solved;
83968409

83978410
// If we have e.g a missing member somewhere, a component type variable
8398-
// will have been marked as a potential hole.
8399-
// FIXME: This relies on the fact that we only mark an overload type
8400-
// variable as a potential hole once we've added a corresponding fix. We
8401-
// can't use 'isHole' instead, as that doesn't handle cases where the
8402-
// overload type variable gets bound to another type from the context rather
8403-
// than a hole. We need to come up with a better way of handling the
8404-
// relationship between key paths and overloads.
8411+
// would either be marked as a potential hole or would have a fix.
84058412
if (llvm::any_of(componentTypeVars, [&](TypeVariableType *tv) {
8406-
return tv->getImpl().getLocator()->isForKeyPathComponent() &&
8413+
auto *locator = tv->getImpl().getLocator();
8414+
8415+
// Result type of a component could be bound to a contextual
8416+
// (concrete) type if it's the last component in the chain,
8417+
// so the only way to detect errors is to check for fixes.
8418+
if (locator->isForKeyPathComponentResult()) {
8419+
auto path = locator->getPath();
8420+
auto *componentLoc =
8421+
getConstraintLocator(locator->getAnchor(), path.drop_back());
8422+
8423+
if (hasFixFor(componentLoc, FixKind::DefineMemberBasedOnUse) ||
8424+
hasFixFor(componentLoc, FixKind::UnwrapOptionalBase) ||
8425+
hasFixFor(componentLoc,
8426+
FixKind::UnwrapOptionalBaseWithOptionalResult))
8427+
return true;
8428+
}
8429+
8430+
// If something inside of a component is marked as a hole,
8431+
// let's consider while component to be invalid.
8432+
return locator->isInKeyPathComponent() &&
84078433
tv->getImpl().canBindToHole();
84088434
})) {
84098435
return SolutionKind::Solved;

lib/Sema/ConstraintLocator.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,12 +168,16 @@ bool ConstraintLocator::isForKeyPathDynamicMemberLookup() const {
168168
return !path.empty() && path.back().isKeyPathDynamicMember();
169169
}
170170

171-
bool ConstraintLocator::isForKeyPathComponent() const {
171+
bool ConstraintLocator::isInKeyPathComponent() const {
172172
return llvm::any_of(getPath(), [&](const LocatorPathElt &elt) {
173173
return elt.isKeyPathComponent();
174174
});
175175
}
176176

177+
bool ConstraintLocator::isForKeyPathComponentResult() const {
178+
return isLastElement<LocatorPathElt::KeyPathComponentResult>();
179+
}
180+
177181
bool ConstraintLocator::isForGenericParameter() const {
178182
return isLastElement<LocatorPathElt::GenericParameter>();
179183
}

0 commit comments

Comments
 (0)