Skip to content

Commit 61e77bd

Browse files
authored
Merge pull request swiftlang#32942 from slavapestov/fix-same-type-concrete-crash
GSB: Fix use-after-free error when vending ResolvedType
2 parents 88cad6b + b76733b commit 61e77bd

File tree

5 files changed

+134
-88
lines changed

5 files changed

+134
-88
lines changed

include/swift/AST/GenericSignatureBuilder.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -743,12 +743,6 @@ class GenericSignatureBuilder {
743743
TypeArrayView<GenericTypeParamType> genericParams,
744744
EquivalenceClass *equivClass);
745745

746-
/// Realize a potential archetype for the given type.
747-
///
748-
/// The resolved archetype will be written back into the unresolved type,
749-
/// to make the next resolution more efficient.
750-
PotentialArchetype *realizePotentialArchetype(UnresolvedType &type);
751-
752746
public:
753747
/// Try to resolve the equivalence class of the given type.
754748
///

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 6 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2380,20 +2380,9 @@ const RequirementSource *GenericSignatureBuilder::resolveSuperConformance(
23802380
return superclassSource;
23812381
}
23822382

2383-
/// Realize a potential archetype for this type parameter.
2384-
PotentialArchetype *ResolvedType::realizePotentialArchetype(
2385-
GenericSignatureBuilder &builder) {
2386-
// Realize and cache the potential archetype.
2387-
return builder.realizePotentialArchetype(type);
2388-
}
2389-
23902383
Type ResolvedType::getDependentType(GenericSignatureBuilder &builder) const {
2391-
// Already-resolved potential archetype.
2392-
if (auto pa = type.dyn_cast<PotentialArchetype *>())
2393-
return pa->getDependentType(builder.getGenericParams());
2394-
2395-
Type result = type.get<Type>();
2396-
return result->isTypeParameter() ? result : Type();
2384+
return storage.get<PotentialArchetype *>()
2385+
->getDependentType(builder.getGenericParams());
23972386
}
23982387

23992388
auto PotentialArchetype::getOrCreateEquivalenceClass(
@@ -3550,20 +3539,6 @@ static Type resolveDependentMemberTypes(
35503539
});
35513540
}
35523541

3553-
PotentialArchetype *GenericSignatureBuilder::realizePotentialArchetype(
3554-
UnresolvedType &type) {
3555-
if (auto pa = type.dyn_cast<PotentialArchetype *>())
3556-
return pa;
3557-
3558-
auto pa = maybeResolveEquivalenceClass(type.get<Type>(),
3559-
ArchetypeResolutionKind::WellFormed,
3560-
/*wantExactPotentialArchetype=*/true)
3561-
.getPotentialArchetypeIfKnown();
3562-
if (pa) type = pa;
3563-
3564-
return pa;
3565-
}
3566-
35673542
static Type getStructuralType(TypeDecl *typeDecl, bool keepSugar) {
35683543
if (auto typealias = dyn_cast<TypeAliasDecl>(typeDecl)) {
35693544
if (typealias->getUnderlyingTypeRepr() != nullptr) {
@@ -3677,19 +3652,7 @@ ResolvedType GenericSignatureBuilder::maybeResolveEquivalenceClass(
36773652
if (!nestedPA)
36783653
return ResolvedType::forUnresolved(baseEquivClass);
36793654

3680-
// If base resolved to the anchor, then the nested potential archetype
3681-
// we found is the resolved potential archetype. Return it directly,
3682-
// so it doesn't need to be resolved again.
3683-
if (basePA == resolvedBase.getPotentialArchetypeIfKnown())
3684-
return ResolvedType(nestedPA);
3685-
3686-
// Compute the resolved dependent type to return.
3687-
Type resolvedBaseType = resolvedBase.getDependentType(*this);
3688-
Type resolvedMemberType =
3689-
DependentMemberType::get(resolvedBaseType, assocType);
3690-
3691-
return ResolvedType(resolvedMemberType,
3692-
nestedPA->getOrCreateEquivalenceClass(*this));
3655+
return ResolvedType(nestedPA);
36933656
} else {
36943657
auto *concreteDecl =
36953658
baseEquivClass->lookupNestedType(*this, depMemTy->getName());
@@ -4561,8 +4524,7 @@ GenericSignatureBuilder::addSameTypeRequirementBetweenTypeParameters(
45614524
if (equivClass2) {
45624525
equivClass = equivClass2;
45634526
} else {
4564-
auto pa1 = type1.realizePotentialArchetype(*this);
4565-
equivClass = pa1->getOrCreateEquivalenceClass(*this);
4527+
equivClass = type1.getEquivalenceClass(*this);
45664528
}
45674529
}
45684530

@@ -4574,8 +4536,8 @@ GenericSignatureBuilder::addSameTypeRequirementBetweenTypeParameters(
45744536

45754537
// Both sides are type parameters; equate them.
45764538
// FIXME: Realizes potential archetypes far too early.
4577-
auto OrigT1 = type1.realizePotentialArchetype(*this);
4578-
auto OrigT2 = type2.realizePotentialArchetype(*this);
4539+
auto OrigT1 = type1.getPotentialArchetypeIfKnown();
4540+
auto OrigT2 = type2.getPotentialArchetypeIfKnown();
45794541

45804542
// Operate on the representatives
45814543
auto T1 = OrigT1->getRepresentative();

lib/AST/GenericSignatureBuilderImpl.h

Lines changed: 22 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,20 @@
1313
namespace swift {
1414

1515
class GenericSignatureBuilder::ResolvedType {
16-
llvm::PointerUnion<PotentialArchetype *, Type> type;
17-
EquivalenceClass *equivClass;
16+
llvm::PointerUnion<PotentialArchetype *, Type, EquivalenceClass *> storage;
1817

1918
/// For a type that could not be resolved further unless the given
2019
/// equivalence class changes.
21-
ResolvedType(EquivalenceClass *equivClass)
22-
: type(), equivClass(equivClass) { }
20+
ResolvedType(EquivalenceClass *equivClass) : storage(equivClass) { }
21+
22+
/// A concrete resolved type.
23+
ResolvedType(Type type) : storage(type) {
24+
assert(!type->isTypeParameter());
25+
}
2326

2427
public:
2528
/// A specific resolved potential archetype.
26-
ResolvedType(PotentialArchetype *pa)
27-
: type(pa), equivClass(pa->getEquivalenceClassIfPresent()) { }
28-
29-
/// A resolved type within the given equivalence class.
30-
ResolvedType(Type type, EquivalenceClass *equivClass)
31-
: type(type), equivClass(equivClass) {
32-
assert(type->isTypeParameter() == static_cast<bool>(equivClass) &&
33-
"type parameters must have equivalence classes");
34-
}
29+
ResolvedType(PotentialArchetype *pa) : storage(pa) { }
3530

3631
/// Return an unresolved result, which could be resolved when we
3732
/// learn more information about the given equivalence class.
@@ -41,11 +36,13 @@ class GenericSignatureBuilder::ResolvedType {
4136

4237
/// Return a result for a concrete type.
4338
static ResolvedType forConcrete(Type concreteType) {
44-
return ResolvedType(concreteType, nullptr);
39+
return ResolvedType(concreteType);
4540
}
4641

4742
/// Determine whether this result was resolved.
48-
explicit operator bool() const { return !type.isNull(); }
43+
explicit operator bool() const {
44+
return storage.is<PotentialArchetype *>() || storage.is<Type>();
45+
}
4946

5047
/// Retrieve the dependent type.
5148
Type getDependentType(GenericSignatureBuilder &builder) const;
@@ -54,51 +51,38 @@ class GenericSignatureBuilder::ResolvedType {
5451
/// a concrete type.
5552
Type getAsConcreteType() const {
5653
assert(*this && "Doesn't contain any result");
57-
if (equivClass) return Type();
58-
return type.dyn_cast<Type>();
54+
return storage.dyn_cast<Type>();
5955
}
6056

61-
/// Realize a potential archetype for this type parameter.
62-
PotentialArchetype *realizePotentialArchetype(
63-
GenericSignatureBuilder &builder);
64-
6557
/// Retrieve the potential archetype, if already known.
6658
PotentialArchetype *getPotentialArchetypeIfKnown() const {
67-
return type.dyn_cast<PotentialArchetype *>();
59+
return storage.dyn_cast<PotentialArchetype *>();
6860
}
6961

7062
/// Retrieve the equivalence class into which a resolved type refers.
7163
EquivalenceClass *getEquivalenceClass(
7264
GenericSignatureBuilder &builder) const {
73-
assert(*this && "Only for resolved types");
74-
if (equivClass) return equivClass;
75-
76-
// Create the equivalence class now.
77-
return type.get<PotentialArchetype *>()
65+
return storage.get<PotentialArchetype *>()
7866
->getOrCreateEquivalenceClass(builder);
7967
}
8068

8169
/// Retrieve the equivalence class into which a resolved type refers.
8270
EquivalenceClass *getEquivalenceClassIfPresent() const {
83-
assert(*this && "Only for resolved types");
84-
if (equivClass) return equivClass;
85-
86-
// Create the equivalence class now.
87-
return type.get<PotentialArchetype *>()->getEquivalenceClassIfPresent();
71+
return storage.get<PotentialArchetype *>()
72+
->getEquivalenceClassIfPresent();
8873
}
8974

9075
/// Retrieve the unresolved result.
9176
EquivalenceClass *getUnresolvedEquivClass() const {
92-
assert(!*this);
93-
return equivClass;
77+
return storage.dyn_cast<EquivalenceClass *>();
9478
}
9579

9680
/// Return an unresolved type.
97-
///
98-
/// This loses equivalence-class information that could be useful, which
99-
/// is unfortunate.
10081
UnresolvedType getUnresolvedType() const {
101-
return type;
82+
assert(!storage.is<EquivalenceClass *>());
83+
if (storage.is<PotentialArchetype *>())
84+
return storage.get<PotentialArchetype *>();
85+
return storage.get<Type>();
10286
}
10387
};
10488

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %target-swift-frontend -emit-ir %s
2+
3+
public protocol P1 {
4+
associatedtype Value
5+
}
6+
7+
public protocol P2 {
8+
associatedtype Value
9+
}
10+
11+
public class Class2<V> : P2 {
12+
public typealias Value = V
13+
}
14+
15+
public class Superclass<T1, T2> where T1 : P1, T2 : P2, T2.Value == T1.Value {
16+
}
17+
18+
public class Subclass<T1, T2> : Superclass<T1, T2> where T1 : P1, T2 : Class2<T1.Value> {
19+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// RUN: %target-swift-frontend -emit-ir %s
2+
3+
public protocol DefaultInitializable {
4+
init()
5+
}
6+
7+
public protocol AdjacencyEdge_ {
8+
associatedtype VertexID: Equatable
9+
associatedtype Properties
10+
11+
var destination: VertexID { get set }
12+
var properties: Properties { get set }
13+
}
14+
15+
public struct AdjacencyEdge<VertexID: Equatable, Properties>: AdjacencyEdge_ {
16+
public var destination: VertexID
17+
public var properties: Properties
18+
}
19+
20+
public protocol AdjacencyVertex_ {
21+
associatedtype Edges: Collection where Edges.Element: AdjacencyEdge_
22+
associatedtype Properties
23+
24+
var edges: Edges { get set }
25+
var properties: Properties { get set }
26+
}
27+
28+
public struct AdjacencyVertex<Edges: Collection, Properties> : AdjacencyVertex_
29+
where Edges.Element: AdjacencyEdge_
30+
{
31+
public var edges: Edges
32+
public var properties: Properties
33+
}
34+
35+
public protocol BinaryFunction {
36+
associatedtype Parameter0
37+
associatedtype Parameter1
38+
associatedtype Result
39+
40+
func callAsFunction(_: Parameter0, _: Parameter1) -> Result
41+
}
42+
43+
public struct GeneralAdjacencyList<
44+
Spine: Collection, VertexIDToIndex: BinaryFunction
45+
>
46+
where Spine.Element : AdjacencyVertex_,
47+
VertexIDToIndex.Parameter0 == Spine,
48+
VertexIDToIndex.Parameter1 == Spine.Element.Edges.Element.VertexID,
49+
VertexIDToIndex.Result == Spine.Index
50+
{
51+
public let vertexIDToIndex: VertexIDToIndex
52+
public var spine: Spine
53+
}
54+
55+
public struct IdentityVertexIDToIndex<Spine: Collection>: BinaryFunction
56+
where Spine.Element : AdjacencyVertex_,
57+
Spine.Element.Edges.Element.VertexID == Spine.Index
58+
{
59+
public func callAsFunction(_: Spine, _ id: Spine.Index) -> Spine.Index {
60+
return id
61+
}
62+
}
63+
64+
public extension GeneralAdjacencyList {
65+
typealias VertexID = VertexIDToIndex.Parameter1
66+
typealias VertexProperties = Spine.Element.Properties
67+
typealias EdgeProperties = Spine.Element.Edges.Element.Properties
68+
69+
struct EdgeID: Equatable {
70+
/// The source vertex.
71+
let source: VertexIDToIndex.Parameter1
72+
/// The position of the edge in `source`'s list of edges.
73+
let targetIndex: Spine.Index
74+
}
75+
}
76+
77+
public extension GeneralAdjacencyList
78+
where VertexIDToIndex == IdentityVertexIDToIndex<Spine>,
79+
Spine: RangeReplaceableCollection,
80+
Spine.Element.Edges: RangeReplaceableCollection
81+
& BidirectionalCollection // Because https://bugs.swift.org/browse/SR-12810
82+
{
83+
func addVertex(storing properties: VertexProperties) -> VertexID {
84+
return spine.indices.first!
85+
}
86+
}
87+

0 commit comments

Comments
 (0)