mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
PredictableMemOpt: Don't try to diagnose recursive value types.
They're invalid, and we don't want to blow the stack trying to decompose a type with infinite elements. Fixes rdar://problem/17920535. Swift SVN r23775
This commit is contained in:
@@ -155,6 +155,12 @@ public:
|
|||||||
return !isAddressOnly();
|
return !isAddressOnly();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// True if the type was successfully lowered, false if there was an error
|
||||||
|
/// during type lowering.
|
||||||
|
virtual bool isValid() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// isTrivial - Returns true if the type is trivial, meaning it is a loadable
|
/// isTrivial - Returns true if the type is trivial, meaning it is a loadable
|
||||||
/// value type with no reference type members that require releasing.
|
/// value type with no reference type members that require releasing.
|
||||||
bool isTrivial() const {
|
bool isTrivial() const {
|
||||||
|
|||||||
@@ -895,7 +895,6 @@ namespace {
|
|||||||
AddressOnlyTypeLowering(SILType type)
|
AddressOnlyTypeLowering(SILType type)
|
||||||
: TypeLowering(type, IsNotTrivial, IsAddressOnly) {}
|
: TypeLowering(type, IsNotTrivial, IsAddressOnly) {}
|
||||||
|
|
||||||
public:
|
|
||||||
void emitCopyInto(SILBuilder &B, SILLocation loc,
|
void emitCopyInto(SILBuilder &B, SILLocation loc,
|
||||||
SILValue src, SILValue dest, IsTake_t isTake,
|
SILValue src, SILValue dest, IsTake_t isTake,
|
||||||
IsInitialization_t isInit) const override {
|
IsInitialization_t isInit) const override {
|
||||||
@@ -946,9 +945,15 @@ namespace {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A class that acts as a stand-in for unimplemented types.
|
/// A class that acts as a stand-in for improperly recursive types.
|
||||||
class UnimplementedTypeLowering : public AddressOnlyTypeLowering {
|
class RecursiveErrorTypeLowering : public AddressOnlyTypeLowering {
|
||||||
using AddressOnlyTypeLowering::AddressOnlyTypeLowering;
|
public:
|
||||||
|
RecursiveErrorTypeLowering(SILType type)
|
||||||
|
: AddressOnlyTypeLowering(type) {}
|
||||||
|
|
||||||
|
bool isValid() const override {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Build the appropriate TypeLowering subclass for the given type.
|
/// Build the appropriate TypeLowering subclass for the given type.
|
||||||
@@ -1161,7 +1166,7 @@ const TypeLowering *TypeConverter::find(TypeKey k) {
|
|||||||
nomTy->getDeclaredTypeInContext());
|
nomTy->getDeclaredTypeInContext());
|
||||||
} else
|
} else
|
||||||
assert(false && "non-nominal types should not be recursive");
|
assert(false && "non-nominal types should not be recursive");
|
||||||
found->second = new (*this, k.isDependent()) UnimplementedTypeLowering(
|
found->second = new (*this, k.isDependent()) RecursiveErrorTypeLowering(
|
||||||
SILType::getPrimitiveAddressType(k.SubstType));
|
SILType::getPrimitiveAddressType(k.SubstType));
|
||||||
}
|
}
|
||||||
return found->second;
|
return found->second;
|
||||||
@@ -1169,6 +1174,9 @@ const TypeLowering *TypeConverter::find(TypeKey k) {
|
|||||||
|
|
||||||
void TypeConverter::insert(TypeKey k, const TypeLowering *tl) {
|
void TypeConverter::insert(TypeKey k, const TypeLowering *tl) {
|
||||||
auto &Types = k.isDependent() ? DependentTypes : IndependentTypes;
|
auto &Types = k.isDependent() ? DependentTypes : IndependentTypes;
|
||||||
|
// TODO: Types[k] should always be null at this point, except that we
|
||||||
|
// rely on type lowering to discover recursive value types right now.
|
||||||
|
if (!Types[k])
|
||||||
Types[k] = tl;
|
Types[k] = tl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ STATISTIC(NumAllocRemoved, "Number of allocations completely removed");
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
static unsigned getNumSubElements(SILType T, SILModule &M) {
|
static unsigned getNumSubElements(SILType T, SILModule &M) {
|
||||||
|
if (!M.getTypeLowering(T).isValid())
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (auto TT = T.getAs<TupleType>()) {
|
if (auto TT = T.getAs<TupleType>()) {
|
||||||
unsigned NumElements = 0;
|
unsigned NumElements = 0;
|
||||||
for (auto index : indices(TT.getElementTypes()))
|
for (auto index : indices(TT.getElementTypes()))
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// RUN: %swift -emit-silgen -verify %s
|
// RUN: %swift -emit-sil -verify %s
|
||||||
|
|
||||||
struct SelfRecursiveStruct { // expected-error{{recursive value type}}
|
struct SelfRecursiveStruct { // expected-error{{recursive value type}}
|
||||||
let a: SelfRecursiveStruct
|
let a: SelfRecursiveStruct
|
||||||
@@ -37,3 +37,12 @@ enum RecursiveByGenericSubstitutionEnum<T> {
|
|||||||
struct RecursiveByGenericSubstitutionStruct { // expected-error{{recursive value type}}
|
struct RecursiveByGenericSubstitutionStruct { // expected-error{{recursive value type}}
|
||||||
let a: RecursiveByGenericSubstitutionEnum<RecursiveByGenericSubstitutionStruct>
|
let a: RecursiveByGenericSubstitutionEnum<RecursiveByGenericSubstitutionStruct>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct RecursiveWithLocal { // expected-error{{recursive value type 'RecursiveWithLocal' is not allowed}}
|
||||||
|
init(t: Local) { self.t = t }
|
||||||
|
struct Local {
|
||||||
|
init(s: RecursiveWithLocal) { self.s = s }
|
||||||
|
var s: RecursiveWithLocal
|
||||||
|
}
|
||||||
|
var t: Local
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user