Merge pull request #13594 from apple/bugfix_largetype
Merge pull request #13590 from shajrawi/large_type_bugfix_part1
diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp
index db8d946..902bcc7 100644
--- a/lib/IRGen/GenProto.cpp
+++ b/lib/IRGen/GenProto.cpp
@@ -323,19 +323,10 @@
// The Self type is abstract, so we can fulfill its metadata from
// the Self metadata parameter.
addSelfMetadataFulfillment(selfTy);
- } else {
- // If the Self type is concrete, we have a witness thunk with a
- // fully substituted Self type. The witness table parameter is not
- // used.
- //
- // FIXME: As above, we should fulfill the Self metadata and
- // conformance from our two special paramaters here. However, the
- // Self metadata will be inexact.
- //
- // For now, just fulfill the generic arguments of 'Self'.
- considerType(selfTy, IsInexact, Sources.size() - 1, MetadataPath());
}
+ considerType(selfTy, IsInexact, Sources.size() - 1, MetadataPath());
+
// The witness table for the Self : P conformance can be
// fulfilled from the Self witness table parameter.
Sources.emplace_back(MetadataSource::Kind::SelfWitnessTable,
diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp
index 1d77564..34e7ba6 100644
--- a/lib/IRGen/IRGenSIL.cpp
+++ b/lib/IRGen/IRGenSIL.cpp
@@ -3759,10 +3759,31 @@
bool isEntryBlock = (i->getParent() == i->getFunction()->getEntryBlock());
auto addr =
type.allocateStack(*this, i->getElementType(), isEntryBlock, dbgname);
-
- emitDebugInfoForAllocStack(i, type, addr.getAddress().getAddress());
-
setLoweredStackAddress(i, addr);
+
+ // Generate Debug Info.
+ if (!Decl)
+ return;
+ emitDebugInfoForAllocStack(i, type, addr.getAddress().getAddress());
+
+ // To make it unambiguous whether a `var` binding has been initialized,
+ // zero-initialize the first pointer-sized field. LLDB uses this to
+ // recognize to detect uninitizialized variables. This can be removed once
+ // swiftc switches to @llvm.dbg.addr() intrinsics. This dead store will get
+ // optimized away when optimizations are enabled.
+ if (!Decl->getType()->getClassOrBoundGenericClass())
+ return;
+
+ auto *AI = dyn_cast<llvm::AllocaInst>(addr.getAddress().getAddress());
+ if (!AI)
+ return;
+
+ auto &DL = IGM.DataLayout;
+ if (DL.getTypeSizeInBits(AI->getAllocatedType()) < DL.getPointerSize())
+ return;
+ auto *BC = Builder.CreateBitCast(AI, IGM.OpaquePtrTy->getPointerTo());
+ Builder.CreateStore(llvm::ConstantPointerNull::get(IGM.OpaquePtrTy), BC,
+ IGM.getPointerAlignment());
}
static void
diff --git a/test/DebugInfo/uninitialized.swift b/test/DebugInfo/uninitialized.swift
new file mode 100644
index 0000000..ca3549e
--- /dev/null
+++ b/test/DebugInfo/uninitialized.swift
@@ -0,0 +1,11 @@
+// RUN: %target-swift-frontend %s -emit-ir -g -o - | %FileCheck %s
+class MyClass {}
+
+// CHECK: define {{.*}} @_T013uninitialized1fyyF
+public func f() {
+ var object: MyClass
+ // CHECK: %[[OBJ:.*]] = alloca %[[T:.*]]*, align
+ // CHECK: call void @llvm.dbg.declare(metadata %[[T]]** %[[OBJ]],
+ // CHECK: %[[BC:.*]] = bitcast %[[T]]** %[[OBJ]] to %swift.opaque**, !dbg
+ // CHECK: store %swift.opaque* null, %swift.opaque** %[[BC]], align {{.*}}, !dbg
+}
diff --git a/test/IRGen/witness_method.sil b/test/IRGen/witness_method.sil
index 3669da7..09cd5e3 100644
--- a/test/IRGen/witness_method.sil
+++ b/test/IRGen/witness_method.sil
@@ -110,7 +110,7 @@
func disrupt() -> GrowthHack
}
-// CHECK-LABEL: define{{( protected)?}} swiftcc void @classArchetypeWitnessMethod(%swift.type* %CoverSheet, %T14witness_method9TPSReportC** noalias nocapture swiftself dereferenceable({{4|8}}), %swift.type* %Self, i8** %SelfWitnessTable)
+// CHECK-LABEL: define{{( protected)?}} swiftcc void @classArchetypeWitnessMethod(%T14witness_method9TPSReportC** noalias nocapture swiftself dereferenceable({{4|8}}), %swift.type* %Self, i8** %SelfWitnessTable)
sil @classArchetypeWitnessMethod : $@convention(witness_method: Strategy) <T><CoverSheet where T : TPSReport<CoverSheet>> (@in_guaranteed T) -> () {
entry(%self : $*T):
diff --git a/test/Interpreter/protocol_extensions.swift b/test/Interpreter/protocol_extensions.swift
index ab001b7..1b15052 100644
--- a/test/Interpreter/protocol_extensions.swift
+++ b/test/Interpreter/protocol_extensions.swift
@@ -315,6 +315,8 @@
class SelfMetadataDerived : SelfMetadataBase {}
+class SelfMetadataGeneric<T> : SelfMetadataTest {}
+
func testSelfMetadata<T : SelfMetadataTest>(_ x: T, _ t: T.T) -> [Any.Type] {
return [x.staticTypeOfSelf(),
x.staticTypeOfSelfTakesT(t),
@@ -348,6 +350,16 @@
expectTrue(SelfMetadataDerived.self == result[2])
expectTrue(SelfMetadataDerived.self == result[3])
}
+
+ // Make sure the calling convention works out if 'Self' is a generic
+ // class too.
+ do {
+ let result = testSelfMetadata(SelfMetadataGeneric<Int>(), 0)
+ expectTrue(SelfMetadataGeneric<Int>.self == result[0])
+ expectTrue(SelfMetadataGeneric<Int>.self == result[1])
+ expectTrue(SelfMetadataGeneric<Int>.self == result[2])
+ expectTrue(SelfMetadataGeneric<Int>.self == result[3])
+ }
}
runAllTests()