Skip to content

Commit

Permalink
Merge pull request #1914 from jckarter/SR-1055-2.2
Browse files Browse the repository at this point in the history
IRGen: Set instanceStart correctly in ObjC rodata when first stored property is empty.
  • Loading branch information
tkremenek committed Mar 29, 2016
2 parents 72b2caa + df18829 commit ba1034b
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 4 deletions.
4 changes: 3 additions & 1 deletion lib/IRGen/GenClass.cpp
Expand Up @@ -988,7 +988,9 @@ namespace {
|| Layout->getElements().size() == FirstFieldIndex) {
instanceStart = instanceSize;
} else if (Layout->getElement(FirstFieldIndex).getKind()
== ElementLayout::Kind::Fixed) {
== ElementLayout::Kind::Fixed ||
Layout->getElement(FirstFieldIndex).getKind()
== ElementLayout::Kind::Empty) {
// FIXME: assumes layout is always sequential!
instanceStart = Layout->getElement(FirstFieldIndex).getByteOffset();
} else {
Expand Down
3 changes: 2 additions & 1 deletion lib/IRGen/StructLayout.cpp
Expand Up @@ -307,7 +307,8 @@ void StructLayoutBuilder::addNonFixedSizeElement(ElementLayout &elt) {

/// Add an empty element to the aggregate.
void StructLayoutBuilder::addEmptyElement(ElementLayout &elt) {
elt.completeEmpty(elt.getType().isPOD(ResilienceExpansion::Maximal));
elt.completeEmpty(elt.getType().isPOD(ResilienceExpansion::Maximal),
CurSize);
}

/// Add an element at the fixed offset of the current end of the
Expand Down
9 changes: 7 additions & 2 deletions lib/IRGen/StructLayout.h
Expand Up @@ -137,9 +137,13 @@ class ElementLayout {
Index = other.Index;
}

void completeEmpty(IsPOD_t isPOD) {
void completeEmpty(IsPOD_t isPOD, Size byteOffset) {
TheKind = unsigned(Kind::Empty);
IsPOD = unsigned(isPOD);
// We still want to give empty fields an offset for use by things like
// ObjC ivar emission. We use the first field in a class layout as the
// instanceStart.
ByteOffset = byteOffset.getValue();
Index = 0; // make a complete write of the bitfield
}

Expand Down Expand Up @@ -187,7 +191,8 @@ class ElementLayout {

/// Given that this element has a fixed offset, return that offset in bytes.
Size getByteOffset() const {
assert(isCompleted() && getKind() == Kind::Fixed);
assert(isCompleted() &&
(getKind() == Kind::Fixed || getKind() == Kind::Empty));
return Size(ByteOffset);
}

Expand Down
30 changes: 30 additions & 0 deletions test/IRGen/objc_class_empty_fields.swift
@@ -0,0 +1,30 @@
// RUN: %target-swift-frontend -primary-file %s -emit-ir | FileCheck %s --check-prefix=CHECK-%target-ptrsize

// REQUIRES: objc_interop

// SR-1055

// CHECK-64: @_DATA__TtC23objc_class_empty_fields14OneEnumWrapper = private constant { {{.*}}* } { i32 {{[0-9]+}}, i32 16, i32 24
// CHECK-32: @_DATA__TtC23objc_class_empty_fields14OneEnumWrapper = private constant { {{.*}}* } { i32 {{[0-9]+}}, i32 12, i32 16

enum OneCaseEnum {
case X
}

class OneEnumWrapper {
var myVar: OneCaseEnum
var whyVar: OneCaseEnum
var x: Int

init(v: OneCaseEnum)
{
self.myVar = v
self.whyVar = v
self.x = 0
}
}

let e = OneCaseEnum.X
print(e)
let x = OneEnumWrapper(v: e)
print(x)

0 comments on commit ba1034b

Please sign in to comment.