Skip to content

Commit 336a97b

Browse files
committed
Sema: Diagnose invalid 'self.init' delegation where 'self' is an archetype
This is a corner case but would previously lead to a compiler crash or miscompile. Fixes <rdar://problem/21991470>, <https://bugs.swift.org/browse/SR-5022>.
1 parent 71afed8 commit 336a97b

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

lib/Sema/CSApply.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,16 @@ diagnoseInvalidDynamicConstructorReferences(ConstraintSystem &cs,
357357
return cs.getType(expr);
358358
});
359359

360+
// 'super.' is always OK
361+
if (isa<SuperRefExpr>(base))
362+
return true;
363+
364+
// 'self.' reference with concrete type is OK
365+
if (isa<DeclRefExpr>(base) &&
366+
cast<DeclRefExpr>(base)->getDecl()->getBaseName() == tc.Context.Id_self &&
367+
!baseTy->is<ArchetypeType>())
368+
return true;
369+
360370
// FIXME: The "hasClangNode" check here is a complete hack.
361371
if (isNonFinalClass(instanceTy) &&
362372
!isStaticallyDerived &&
@@ -2535,6 +2545,13 @@ namespace {
25352545
ConstructorDecl *ctor,
25362546
FunctionRefKind functionRefKind,
25372547
Type openedType) {
2548+
2549+
// If the member is a constructor, verify that it can be legally
2550+
// referenced from this base.
2551+
if (!diagnoseInvalidDynamicConstructorReferences(cs, base, nameLoc,
2552+
ctor, SuppressDiagnostics))
2553+
return nullptr;
2554+
25382555
// If the subexpression is a metatype, build a direct reference to the
25392556
// constructor.
25402557
if (cs.getType(base)->is<AnyMetatypeType>()) {

test/decl/ext/protocol.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,22 @@ extension ExtendedProtocol where Self : DerivedWithAlias {
267267
func f4(x: NestedNominal) {}
268268
}
269269

270+
// rdar://problem/21991470 & https://bugs.swift.org/browse/SR-5022
271+
class NonPolymorphicInit {
272+
init() { } // expected-note {{selected non-required initializer 'init()'}}
273+
}
274+
275+
protocol EmptyProtocol { }
276+
277+
// The diagnostic is not very accurate, but at least we reject this.
278+
279+
extension EmptyProtocol where Self : NonPolymorphicInit {
280+
init(string: String) {
281+
self.init()
282+
// expected-error@-1 {{constructing an object of class type 'Self' with a metatype value must use a 'required' initializer}}
283+
}
284+
}
285+
270286
// ----------------------------------------------------------------------------
271287
// Using protocol extensions to satisfy requirements
272288
// ----------------------------------------------------------------------------

0 commit comments

Comments
 (0)