Skip to content

Commit d76fe05

Browse files
authored
Merge pull request #15427 from davezarzycki/ensure_oneway_decl_validation
2 parents e3a1afa + 8e09556 commit d76fe05

File tree

2 files changed

+29
-16
lines changed

2 files changed

+29
-16
lines changed

include/swift/AST/Decl.h

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,12 @@ bool conflicting(const OverloadSignature& sig1, const OverloadSignature& sig2,
213213

214214
/// Decl - Base class for all declarations in Swift.
215215
class alignas(1 << DeclAlignInBits) Decl {
216+
enum class ValidationState {
217+
Unchecked,
218+
Checking,
219+
Checked,
220+
};
221+
216222
protected:
217223
union { uint64_t OpaqueBits;
218224

@@ -235,12 +241,8 @@ class alignas(1 << DeclAlignInBits) Decl {
235241
/// FIXME: This is ugly.
236242
EarlyAttrValidation : 1,
237243

238-
/// \brief Whether this declaration is currently being validated.
239-
BeingValidated : 1,
240-
241-
/// \brief Whether we have started validating the declaration; this *isn't*
242-
/// reset after finishing it.
243-
ValidationStarted : 1,
244+
/// \brief The validation state of this declaration.
245+
ValidationState : 2,
244246

245247
/// \brief Whether this declaration was added to the surrounding
246248
/// DeclContext of an active #if config clause.
@@ -609,8 +611,7 @@ class alignas(1 << DeclAlignInBits) Decl {
609611
Bits.Decl.Implicit = false;
610612
Bits.Decl.FromClang = false;
611613
Bits.Decl.EarlyAttrValidation = false;
612-
Bits.Decl.BeingValidated = false;
613-
Bits.Decl.ValidationStarted = false;
614+
Bits.Decl.ValidationState = unsigned(ValidationState::Unchecked);
614615
Bits.Decl.EscapedFromIfConfig = false;
615616
}
616617

@@ -759,25 +760,32 @@ class alignas(1 << DeclAlignInBits) Decl {
759760
/// Whether the declaration has a valid interface type and
760761
/// generic signature.
761762
bool isBeingValidated() const {
762-
return Bits.Decl.BeingValidated;
763+
return Bits.Decl.ValidationState == unsigned(ValidationState::Checking);
763764
}
764765

765766
/// Toggle whether or not the declaration is being validated.
766767
void setIsBeingValidated(bool ibv = true) {
767-
assert(Bits.Decl.BeingValidated != ibv);
768-
Bits.Decl.BeingValidated = ibv;
769768
if (ibv) {
770-
Bits.Decl.ValidationStarted = true;
769+
assert(Bits.Decl.ValidationState == unsigned(ValidationState::Unchecked));
770+
Bits.Decl.ValidationState = unsigned(ValidationState::Checking);
771+
} else {
772+
assert(Bits.Decl.ValidationState == unsigned(ValidationState::Checking));
773+
Bits.Decl.ValidationState = unsigned(ValidationState::Checked);
771774
}
772775
}
773776

774-
bool hasValidationStarted() const { return Bits.Decl.ValidationStarted; }
777+
bool hasValidationStarted() const {
778+
return Bits.Decl.ValidationState >= unsigned(ValidationState::Checking);
779+
}
775780

776781
/// Manually indicate that validation has started for the declaration.
777782
///
778783
/// This is implied by setIsBeingValidated(true) (i.e. starting validation)
779784
/// and so rarely needs to be called directly.
780-
void setValidationStarted() { Bits.Decl.ValidationStarted = true; }
785+
void setValidationStarted() {
786+
if (Bits.Decl.ValidationState != unsigned(ValidationState::Checking))
787+
Bits.Decl.ValidationState = unsigned(ValidationState::Checked);
788+
}
781789

782790
bool escapedFromIfConfig() const {
783791
return Bits.Decl.EscapedFromIfConfig;

lib/Sema/TypeCheckDecl.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6990,8 +6990,13 @@ void TypeChecker::validateDecl(ValueDecl *D) {
69906990
validateAccessControl(aliasDecl);
69916991

69926992
// Check generic parameters, if needed.
6993-
aliasDecl->setIsBeingValidated();
6994-
SWIFT_DEFER { aliasDecl->setIsBeingValidated(false); };
6993+
bool validated = aliasDecl->hasValidationStarted();
6994+
if (!validated)
6995+
aliasDecl->setIsBeingValidated();
6996+
SWIFT_DEFER {
6997+
if (!validated)
6998+
aliasDecl->setIsBeingValidated(false);
6999+
};
69957000

69967001
validateTypealiasType(*this, aliasDecl);
69977002
}

0 commit comments

Comments
 (0)