Skip to content

Commit 8e79233

Browse files
authored
Merge pull request #63266 from xymus/public-ctor-override-internal
[Serialization] Drop overriding relationship in constructors when safe
2 parents a9b69a1 + 2d8f075 commit 8e79233

File tree

4 files changed

+45
-16
lines changed

4 files changed

+45
-16
lines changed

lib/Serialization/Deserialization.cpp

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3094,7 +3094,7 @@ class DeclDeserializer {
30943094
GenericSignatureID genericSigID;
30953095
uint8_t storedInitKind, rawAccessLevel;
30963096
DeclID overriddenID;
3097-
bool needsNewVTableEntry, firstTimeRequired;
3097+
bool overriddenAffectsABI, needsNewVTableEntry, firstTimeRequired;
30983098
unsigned numArgNames;
30993099
ArrayRef<uint64_t> argNameAndDependencyIDs;
31003100

@@ -3104,6 +3104,7 @@ class DeclDeserializer {
31043104
async, throws, storedInitKind,
31053105
genericSigID,
31063106
overriddenID,
3107+
overriddenAffectsABI,
31073108
rawAccessLevel,
31083109
needsNewVTableEntry,
31093110
firstTimeRequired,
@@ -3130,15 +3131,25 @@ class DeclDeserializer {
31303131
attrs.setRawAttributeChain(DAttrs);
31313132
}
31323133

3133-
auto overridden = MF.getDeclChecked(overriddenID);
3134-
if (!overridden) {
3135-
// Pass through deserialization errors.
3136-
if (overridden.errorIsA<FatalDeserializationError>())
3137-
return overridden.takeError();
3134+
Expected<Decl *> overriddenOrError = MF.getDeclChecked(overriddenID);
3135+
Decl *overridden;
3136+
if (overriddenOrError) {
3137+
overridden = overriddenOrError.get();
3138+
} else if (overriddenOrError.errorIsA<FatalDeserializationError>()) {
3139+
// Pass through fatal deserialization errors.
3140+
return overriddenOrError.takeError();
3141+
} else if (MF.allowCompilerErrors()) {
3142+
// Drop overriding relationship when allowing errors.
3143+
llvm::consumeError(overriddenOrError.takeError());
3144+
overridden = nullptr;
3145+
} else {
3146+
llvm::consumeError(overriddenOrError.takeError());
3147+
if (overriddenAffectsABI || !ctx.LangOpts.EnableDeserializationRecovery) {
3148+
return llvm::make_error<OverrideError>(name, errorFlags,
3149+
numVTableEntries);
3150+
}
31383151

3139-
llvm::consumeError(overridden.takeError());
3140-
return llvm::make_error<OverrideError>(
3141-
name, errorFlags, numVTableEntries);
3152+
overridden = nullptr;
31423153
}
31433154

31443155
for (auto dependencyID : argNameAndDependencyIDs.slice(numArgNames)) {
@@ -3198,7 +3209,7 @@ class DeclDeserializer {
31983209
ctx.evaluator.cacheOutput(NeedsNewVTableEntryRequest{ctor},
31993210
std::move(needsNewVTableEntry));
32003211

3201-
ctor->setOverriddenDecl(cast_or_null<ConstructorDecl>(overridden.get()));
3212+
ctor->setOverriddenDecl(cast_or_null<ConstructorDecl>(overridden));
32023213
if (auto *overridden = ctor->getOverriddenDecl()) {
32033214
if (!attributeChainContains<RequiredAttr>(DAttrs) ||
32043215
!overridden->isRequired()) {

lib/Serialization/ModuleFormat.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5858
/// describe what change you made. The content of this comment isn't important;
5959
/// it just ensures a conflict if two people change the module format.
6060
/// Don't worry about adhering to the 80-column limit for this line.
61-
const uint16_t SWIFTMODULE_VERSION_MINOR = 741; // SIL pack types
61+
const uint16_t SWIFTMODULE_VERSION_MINOR = 742; // Constructor affects ABI
6262

6363
/// A standard hash seed used for all string hashes in a serialized module.
6464
///
@@ -1455,6 +1455,7 @@ namespace decls_block {
14551455
CtorInitializerKindField, // initializer kind
14561456
GenericSignatureIDField, // generic environment
14571457
DeclIDField, // overridden decl
1458+
BCFixed<1>, // whether the overridden decl affects ABI
14581459
AccessLevelField, // access level
14591460
BCFixed<1>, // requires a new vtable slot
14601461
BCFixed<1>, // 'required' but overridden is not (used for recovery)

lib/Serialization/Serialization.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3535,17 +3535,20 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
35353535
// its overrides after they've been compiled: if the declaration is '@objc'
35363536
// and 'dynamic'. In that case, all accesses to the method or property will
35373537
// go through the Objective-C method tables anyway.
3538-
if (overridden->hasClangNode() || overridden->shouldUseObjCDispatch())
3538+
if (!isa<ConstructorDecl>(override) &&
3539+
(overridden->hasClangNode() || overridden->shouldUseObjCDispatch()))
35393540
return false;
35403541

35413542
// In a public-override-internal case, the override doesn't have ABI
3542-
// implications.
3543+
// implications. This corresponds to hiding the override keyword from the
3544+
// module interface.
35433545
auto isPublic = [](const ValueDecl *VD) {
35443546
return VD->getFormalAccessScope(VD->getDeclContext(),
35453547
/*treatUsableFromInlineAsPublic*/true)
35463548
.isPublic();
35473549
};
3548-
if (isPublic(override) && !isPublic(overridden))
3550+
if (override->getDeclContext()->getParentModule()->isResilient() &&
3551+
isPublic(override) && !isPublic(overridden))
35493552
return false;
35503553

35513554
return true;
@@ -4499,9 +4502,12 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
44994502
uint8_t rawAccessLevel = getRawStableAccessLevel(ctor->getFormalAccess());
45004503

45014504
bool firstTimeRequired = ctor->isRequired();
4502-
if (auto *overridden = ctor->getOverriddenDecl())
4505+
auto *overridden = ctor->getOverriddenDecl();
4506+
if (overridden) {
45034507
if (firstTimeRequired && overridden->isRequired())
45044508
firstTimeRequired = false;
4509+
}
4510+
bool overriddenAffectsABI = overriddenDeclAffectsABI(ctor, overridden);
45054511

45064512
unsigned abbrCode = S.DeclTypeAbbrCodes[ConstructorLayout::Code];
45074513
ConstructorLayout::emitRecord(S.Out, S.ScratchRecord, abbrCode,
@@ -4517,7 +4523,8 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
45174523
ctor->getInitKind()),
45184524
S.addGenericSignatureRef(
45194525
ctor->getGenericSignature()),
4520-
S.addDeclRef(ctor->getOverriddenDecl()),
4526+
S.addDeclRef(overridden),
4527+
overriddenAffectsABI,
45214528
rawAccessLevel,
45224529
ctor->needsNewVTableEntry(),
45234530
firstTimeRequired,

test/Serialization/Safety/override-internal-func.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
//--- Lib.swift
2020

2121
open class Base {
22+
internal init() {}
23+
2224
public func publicMethod() -> Int {
2325
return 1
2426
}
@@ -33,6 +35,10 @@ open class Base {
3335
}
3436

3537
open class Derived : Base {
38+
public override init() {
39+
super.init()
40+
}
41+
3642
open override func publicMethod() -> Int {
3743
return super.publicMethod() + 1
3844
}
@@ -63,3 +69,7 @@ public class OtherFinalDerived : Derived {
6369
return super.internalMethod() + 1
6470
}
6571
}
72+
73+
func foo() {
74+
let a = Derived()
75+
}

0 commit comments

Comments
 (0)