Skip to content

Commit afd6858

Browse files
authored
Merge pull request #11265 from slavapestov/small-crasher-fixes
Small crasher fixes
2 parents cfb2a87 + cb3dcbe commit afd6858

18 files changed

+113
-45
lines changed

lib/AST/ASTContext.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,10 @@ CanType ASTContext::getAnyObjectType() const {
701701
}
702702

703703
CanType ASTContext::getNeverType() const {
704-
return getNeverDecl()->getDeclaredType()->getCanonicalType();
704+
auto neverDecl = getNeverDecl();
705+
if (!neverDecl)
706+
return CanType();
707+
return neverDecl->getDeclaredType()->getCanonicalType();
705708
}
706709

707710
TypeAliasDecl *ASTContext::getVoidDecl() const {
@@ -885,6 +888,9 @@ FuncDecl *ASTContext::getEqualIntDecl() const {
885888
if (Impl.EqualIntDecl)
886889
return Impl.EqualIntDecl;
887890

891+
if (!getIntDecl() || !getBoolDecl())
892+
return nullptr;
893+
888894
auto intType = getIntDecl()->getDeclaredType();
889895
auto boolType = getBoolDecl()->getDeclaredType();
890896
SmallVector<ValueDecl *, 30> equalFuncs;

lib/AST/Builtins.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,8 +1062,12 @@ static ValueDecl *getIntToFPWithOverflowOperation(ASTContext &Context,
10621062

10631063
static ValueDecl *getUnreachableOperation(ASTContext &Context,
10641064
Identifier Id) {
1065+
auto NeverTy = Context.getNeverType();
1066+
if (!NeverTy)
1067+
return nullptr;
1068+
10651069
// () -> Never
1066-
return getBuiltinFunction(Id, {}, Context.getNeverType());
1070+
return getBuiltinFunction(Id, {}, NeverTy);
10671071
}
10681072

10691073
static ValueDecl *getOnceOperation(ASTContext &Context,
@@ -1295,8 +1299,11 @@ getSwiftFunctionTypeForIntrinsic(unsigned iid, ArrayRef<Type> TypeArgs,
12951299
llvm::Intrinsic::getAttributes(getGlobalLLVMContext(), ID);
12961300
Info = FunctionType::ExtInfo();
12971301
if (attrs.hasAttribute(llvm::AttributeList::FunctionIndex,
1298-
llvm::Attribute::NoReturn))
1302+
llvm::Attribute::NoReturn)) {
12991303
ResultTy = Context.getNeverType();
1304+
if (!ResultTy)
1305+
return false;
1306+
}
13001307

13011308
return true;
13021309
}

lib/AST/NameLookup.cpp

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -855,29 +855,29 @@ UnqualifiedLookup::UnqualifiedLookup(DeclName Name, DeclContext *DC,
855855
return;
856856
}
857857
}
858+
}
858859

859-
// Check the generic parameters if our context is a generic type or
860-
// extension thereof.
861-
GenericParamList *dcGenericParams = nullptr;
862-
if (auto nominal = dyn_cast<NominalTypeDecl>(DC))
863-
dcGenericParams = nominal->getGenericParams();
864-
else if (auto ext = dyn_cast<ExtensionDecl>(DC))
865-
dcGenericParams = ext->getGenericParams();
866-
else if (auto subscript = dyn_cast<SubscriptDecl>(DC))
867-
dcGenericParams = subscript->getGenericParams();
868-
869-
while (dcGenericParams) {
870-
namelookup::FindLocalVal localVal(SM, Loc, Consumer);
871-
localVal.checkGenericParams(dcGenericParams);
860+
// Check the generic parameters if our context is a generic type or
861+
// extension thereof.
862+
GenericParamList *dcGenericParams = nullptr;
863+
if (auto nominal = dyn_cast<NominalTypeDecl>(DC))
864+
dcGenericParams = nominal->getGenericParams();
865+
else if (auto ext = dyn_cast<ExtensionDecl>(DC))
866+
dcGenericParams = ext->getGenericParams();
867+
else if (auto subscript = dyn_cast<SubscriptDecl>(DC))
868+
dcGenericParams = subscript->getGenericParams();
869+
870+
while (dcGenericParams) {
871+
namelookup::FindLocalVal localVal(SM, Loc, Consumer);
872+
localVal.checkGenericParams(dcGenericParams);
872873

873-
if (!Results.empty())
874-
return;
874+
if (!Results.empty())
875+
return;
875876

876-
if (!isa<ExtensionDecl>(DC))
877-
break;
877+
if (!isa<ExtensionDecl>(DC))
878+
break;
878879

879-
dcGenericParams = dcGenericParams->getOuterParameters();
880-
}
880+
dcGenericParams = dcGenericParams->getOuterParameters();
881881
}
882882

883883
DC = DC->getParentForLookup();

lib/ClangImporter/ImportDecl.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2439,6 +2439,8 @@ namespace {
24392439
ProtocolDecl *protocols[]
24402440
= {cxt.getProtocol(KnownProtocolKind::RawRepresentable),
24412441
cxt.getProtocol(KnownProtocolKind::Equatable)};
2442+
if (!protocols[0] || !protocols[1])
2443+
return nullptr;
24422444

24432445
auto options = getDefaultMakeStructRawValuedOptions();
24442446
options |= MakeStructRawValuedFlags::MakeUnlabeledValueInit;

lib/ClangImporter/ImportType.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,10 @@ namespace {
202202
// of the exit(3) libc function as "func exit(Int32)", not as
203203
// "func exit(CInt)".
204204
static Type unwrapCType(Type T) {
205-
if (auto *NAT = dyn_cast_or_null<NameAliasType>(T.getPointer()))
205+
// Handle missing or invalid stdlib declarations
206+
if (!T || T->hasError())
207+
return Type();
208+
if (auto *NAT = dyn_cast<NameAliasType>(T.getPointer()))
206209
return NAT->getSinglyDesugaredType();
207210
return T;
208211
}
@@ -334,11 +337,14 @@ namespace {
334337
// that 'Unsafe[Mutable]Pointer<T>' implicitly converts to
335338
// 'Unsafe[Mutable]RawPointer' for interoperability.
336339
if (pointeeQualType->isVoidType()) {
337-
return {
338-
(quals.hasConst() ? Impl.SwiftContext.getUnsafeRawPointerDecl()
339-
: Impl.SwiftContext.getUnsafeMutableRawPointerDecl())
340-
->getDeclaredType(),
341-
ImportHint::OtherPointer};
340+
auto pointerTypeDecl =
341+
(quals.hasConst()
342+
? Impl.SwiftContext.getUnsafeRawPointerDecl()
343+
: Impl.SwiftContext.getUnsafeMutableRawPointerDecl());
344+
if (!pointerTypeDecl)
345+
return Type();
346+
return {pointerTypeDecl->getDeclaredType(),
347+
ImportHint::OtherPointer};
342348
}
343349

344350
// All other C pointers to concrete types map to
@@ -359,9 +365,13 @@ namespace {
359365

360366
// If the pointed-to type is unrepresentable in Swift, import as
361367
// OpaquePointer.
362-
if (!pointeeType)
363-
return {Impl.SwiftContext.getOpaquePointerDecl()->getDeclaredType(),
368+
if (!pointeeType) {
369+
auto opaquePointer = Impl.SwiftContext.getOpaquePointerDecl();
370+
if (!opaquePointer)
371+
return Type();
372+
return {opaquePointer->getDeclaredType(),
364373
ImportHint::OtherPointer};
374+
}
365375

366376
if (pointeeQualType->isFunctionType()) {
367377
auto funcTy = pointeeType->castTo<FunctionType>();

lib/Sema/CSDiag.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3792,12 +3792,15 @@ static bool trySequenceSubsequenceConversionFixIts(InFlightDiagnostic &diag,
37923792
ConstraintSystem &CS,
37933793
Type fromType, Type toType,
37943794
Expr *expr) {
3795-
if (CS.TC.Context.getStdlibModule() == nullptr) {
3795+
if (CS.TC.Context.getStdlibModule() == nullptr)
37963796
return false;
3797-
}
3797+
37983798
auto String = CS.TC.getStringType(CS.DC);
37993799
auto Substring = CS.TC.getSubstringType(CS.DC);
38003800

3801+
if (!String || !Substring)
3802+
return false;
3803+
38013804
/// FIXME: Remove this flag when void subscripts are implemented.
38023805
/// Make this unconditional and remove the if statement.
38033806
if (CS.TC.getLangOpts().FixStringToSubstringConversions) {
@@ -4744,13 +4747,17 @@ static bool diagnoseImplicitSelfErrors(Expr *fnExpr, Expr *argExpr,
47444747
// matches what the user actually wrote instead of what the typechecker
47454748
// expects.
47464749
SmallVector<TupleTypeElt, 4> elts;
4747-
for (auto *el : argTuple->getElements()) {
4750+
for (unsigned i = 0, e = argTuple->getNumElements(); i < e; ++i) {
47484751
ConcreteDeclRef ref = nullptr;
4752+
auto *el = argTuple->getElement(i);
47494753
auto typeResult =
47504754
TC.getTypeOfExpressionWithoutApplying(el, CS.DC, ref);
47514755
if (!typeResult)
47524756
return false;
4753-
elts.push_back(typeResult);
4757+
auto flags = ParameterTypeFlags().withInOut(typeResult->is<InOutType>());
4758+
elts.push_back(TupleTypeElt(typeResult->getInOutObjectType(),
4759+
argTuple->getElementName(i),
4760+
flags));
47544761
}
47554762

47564763
argType = TupleType::get(elts, CS.getASTContext());

lib/Sema/TypeCheckAttr.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,9 @@ class AttributeEarlyChecker : public AttributeVisitor<AttributeEarlyChecker> {
164164
diag.fixItInsert(resultLoc, fix);
165165
}
166166

167-
FD->getBodyResultTypeLoc() = TypeLoc::withoutLoc(
168-
TC.Context.getNeverType());
167+
auto neverType = TC.Context.getNeverType();
168+
if (neverType)
169+
FD->getBodyResultTypeLoc() = TypeLoc::withoutLoc(neverType);
169170
}
170171
}
171172

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2185,8 +2185,15 @@ bool TypeChecker::typeCheckBinding(Pattern *&pattern, Expr *&initializer,
21852185
options |= TR_EditorPlaceholder;
21862186
}
21872187

2188+
// FIXME: initTy should be the same as resultTy; now that typeCheckExpression()
2189+
// returns a Type and not bool, we should be able to simplify the listener
2190+
// implementation here.
2191+
auto initTy = listener.getInitType();
2192+
if (initTy->hasDependentMember())
2193+
return true;
2194+
21882195
// Apply the solution to the pattern as well.
2189-
if (coercePatternToType(pattern, DC, listener.getInitType(), options,
2196+
if (coercePatternToType(pattern, DC, initTy, options,
21902197
nullptr, TypeLoc(), listener.isInOut())) {
21912198
return true;
21922199
}

lib/Sema/TypeCheckPattern.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1503,7 +1503,9 @@ bool TypeChecker::coercePatternToType(Pattern *&P, DeclContext *dc, Type type,
15031503
}
15041504

15051505
EnumElementDecl *elementDecl = Context.getOptionalSomeDecl(optionalKind);
1506-
assert(elementDecl && "missing optional some decl?!");
1506+
if (!elementDecl)
1507+
return true;
1508+
15071509
OP->setElementDecl(elementDecl);
15081510

15091511
Pattern *sub = OP->getSubPattern();

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5608,6 +5608,8 @@ bool TypeChecker::useObjectiveCBridgeableConformances(DeclContext *dc,
56085608
auto keyType = args[0];
56095609
auto *hashableProto =
56105610
TC.Context.getProtocol(KnownProtocolKind::Hashable);
5611+
if (!hashableProto)
5612+
return Action::Stop;
56115613

56125614
auto result = TC.conformsToProtocol(
56135615
keyType, hashableProto, DC, options,

lib/Sema/TypeCheckStmt.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,9 @@ static void tryDiagnoseUnnecessaryCastOverOptionSet(ASTContext &Ctx,
237237
auto *NTD = ResultType->getAnyNominal();
238238
if (!NTD)
239239
return;
240-
auto optionSetType = dyn_cast<ProtocolDecl>(Ctx.getOptionSetDecl());
240+
auto optionSetType = dyn_cast_or_null<ProtocolDecl>(Ctx.getOptionSetDecl());
241+
if (!optionSetType)
242+
return;
241243
SmallVector<ProtocolConformance *, 4> conformances;
242244
if (!(optionSetType &&
243245
NTD->lookupConformance(module, optionSetType, conformances)))

lib/Sema/TypeCheckType.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,13 @@ Type TypeChecker::resolveTypeInContext(
274274

275275
assert(foundDC);
276276

277+
// selfType is the self type of the context, unless the
278+
// context is a protocol type, in which case we might have
279+
// to use the existential type or superclass bound as a
280+
// parent type instead.
277281
Type selfType;
278-
if (isa<NominalTypeDecl>(typeDecl)) {
282+
if (isa<NominalTypeDecl>(typeDecl) &&
283+
typeDecl->getDeclContext()->getAsProtocolOrProtocolExtensionContext()) {
279284
// When looking up a nominal type declaration inside of a
280285
// protocol extension, always use the nominal type and
281286
// not the protocol 'Self' type.
@@ -292,7 +297,8 @@ Type TypeChecker::resolveTypeInContext(
292297

293298
if (selfType->is<GenericTypeParamType>() &&
294299
typeDecl->getDeclContext()->getAsClassOrClassExtensionContext()) {
295-
// We found a member of a class from a protocol extension.
300+
// We found a member of a class from a protocol or protocol
301+
// extension.
296302
//
297303
// Get the superclass of the 'Self' type parameter.
298304
auto *sig = foundDC->getGenericSignatureOfContext();

test/Constraints/members.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,3 +417,15 @@ extension Array where Element == Int {
417417
// expected-error@-1 {{use of 'min' nearly matches global function 'min' in module 'Swift' rather than instance method 'min()'}}
418418
}
419419
}
420+
421+
// Crash in diagnoseImplicitSelfErrors()
422+
423+
struct Aardvark {
424+
var snout: Int
425+
426+
mutating func burrow() {
427+
dig(&snout, .y) // expected-error {{type 'Int' has no member 'y'}}
428+
}
429+
430+
func dig(_: inout Int, _: Int) {}
431+
}

test/decl/ext/protocol.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,8 @@ protocol ConformedProtocol {
237237
class BaseWithAlias<T> : ConformedProtocol {
238238
typealias ConcreteAlias = T
239239

240+
struct NestedNominal {}
241+
240242
func baseMethod(_: T) {}
241243
}
242244

@@ -261,6 +263,8 @@ extension ExtendedProtocol where Self : DerivedWithAlias {
261263
func f3(x: AbstractConformanceAlias) {
262264
let _: DerivedWithAlias = x
263265
}
266+
267+
func f4(x: NestedNominal) {}
264268
}
265269

266270
// ----------------------------------------------------------------------------

validation-test/SIL/crashers/016-swift-typechecker-typecheckfunctionbodyuntil.sil

Lines changed: 0 additions & 2 deletions
This file was deleted.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// RUN: not %target-sil-opt %s
2+
func n->a{return:}class a

validation-test/compiler_crashers/28821-isa-protocoldecl-nominal-cannot-be-a-protocol.swift renamed to validation-test/compiler_crashers_fixed/28821-isa-protocoldecl-nominal-cannot-be-a-protocol.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
77

88
// REQUIRES: asserts
9-
// RUN: not --crash %target-swift-frontend %s -emit-ir
9+
// RUN: not %target-swift-frontend %s -emit-ir
1010
protocol A{{}protocol A{func a:Self.a}typealias e:A.a

validation-test/compiler_crashers/28825-isa-classdecl-nominaldecl-expected-a-class-here.swift renamed to validation-test/compiler_crashers_fixed/28825-isa-classdecl-nominaldecl-expected-a-class-here.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
77

88
// REQUIRES: asserts
9-
// RUN: not --crash %target-swift-frontend %s -emit-ir
9+
// RUN: not %target-swift-frontend %s -emit-ir
1010
protocol b:a{init(t:a}class a{class a

0 commit comments

Comments
 (0)