From da4be0f430d2ef04c6cc33f3ee49e17ed95378db Mon Sep 17 00:00:00 2001 From: Manav Gabhawala Date: Sat, 5 Dec 2015 05:38:40 -0500 Subject: [PATCH 1/4] Fixes Heap Allocations for Large alignMask Uses the aligned_alloc C function from the stdlib instead of malloc so that incase the alignMask is larger than what the system supports we do not get unnecessary crashes. --- stdlib/public/runtime/Heap.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stdlib/public/runtime/Heap.cpp b/stdlib/public/runtime/Heap.cpp index 5480c02107c36..a2c41ae51cff9 100644 --- a/stdlib/public/runtime/Heap.cpp +++ b/stdlib/public/runtime/Heap.cpp @@ -23,8 +23,9 @@ using namespace swift; void *swift::swift_slowAlloc(size_t size, size_t alignMask) { - // FIXME: use posix_memalign if alignMask is larger than the system guarantee. - void *p = malloc(size); + void *p = aligned_alloc(alignMask, size); + // errno will contain error codes if p is a nullptr: + // ENOMEM: insufficient in system memory, EINVAL: alignMask is not a power of two. if (!p) swift::crash("Could not allocate memory."); return p; } From c74340e52fb287cd0bffb1e1bba2d8060f1e4596 Mon Sep 17 00:00:00 2001 From: Manav Gabhawala Date: Sat, 5 Dec 2015 05:58:57 -0500 Subject: [PATCH 2/4] Update Heap.cpp --- stdlib/public/runtime/Heap.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stdlib/public/runtime/Heap.cpp b/stdlib/public/runtime/Heap.cpp index a2c41ae51cff9..de6b9bc17e082 100644 --- a/stdlib/public/runtime/Heap.cpp +++ b/stdlib/public/runtime/Heap.cpp @@ -23,10 +23,10 @@ using namespace swift; void *swift::swift_slowAlloc(size_t size, size_t alignMask) { - void *p = aligned_alloc(alignMask, size); - // errno will contain error codes if p is a nullptr: + void *p; + if (!posix_memalign(&p, alignMask, size)) swift::crash("Could not allocate memory"); + // The return value from posix memalign if not zero will be either of: // ENOMEM: insufficient in system memory, EINVAL: alignMask is not a power of two. - if (!p) swift::crash("Could not allocate memory."); return p; } From b476e96ed43d50c91b4b8b50dc59016a21c26c8a Mon Sep 17 00:00:00 2001 From: Manav Gabhawala Date: Sun, 6 Dec 2015 21:39:42 -0500 Subject: [PATCH 3/4] Undo Heap Changes --- stdlib/public/runtime/Heap.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/stdlib/public/runtime/Heap.cpp b/stdlib/public/runtime/Heap.cpp index de6b9bc17e082..ceab57f9f2b6d 100644 --- a/stdlib/public/runtime/Heap.cpp +++ b/stdlib/public/runtime/Heap.cpp @@ -24,9 +24,8 @@ using namespace swift; void *swift::swift_slowAlloc(size_t size, size_t alignMask) { void *p; - if (!posix_memalign(&p, alignMask, size)) swift::crash("Could not allocate memory"); - // The return value from posix memalign if not zero will be either of: - // ENOMEM: insufficient in system memory, EINVAL: alignMask is not a power of two. + // FIXME: use posix_memalign if alignMask is larger than the system guarantee. + void *p = malloc(size); return p; } From 404e1c695ffe6f59be81fc1e9453d1fe8d07dee5 Mon Sep 17 00:00:00 2001 From: Manav Gabhawala Date: Sun, 6 Dec 2015 21:44:26 -0500 Subject: [PATCH 4/4] Fixes [SR-78] swift compiler seg fault Fixes a segmentation fault where the IRGen module would crash when a generic (empty) struct was part of the source code because it tried to call std::next on an end iterator. --- lib/IRGen/GenType.cpp | 4 ++++ test/IRGen/generic_structs.swift | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 test/IRGen/generic_structs.swift diff --git a/lib/IRGen/GenType.cpp b/lib/IRGen/GenType.cpp index 3067a18fcf9f0..5382b6326a2f2 100644 --- a/lib/IRGen/GenType.cpp +++ b/lib/IRGen/GenType.cpp @@ -2032,6 +2032,10 @@ SILType irgen::getSingletonAggregateFieldType(IRGenModule &IGM, // If there's only one stored property, we have the layout of its field. auto allFields = structDecl->getStoredProperties(); auto field = allFields.begin(); + // If there are no other fields exit early to prevent calling std::next on + // an invalid iterator. + if (field == allFields.end()) + return SILType(); if (std::next(field) == allFields.end()) return t.getFieldType(*field, *IGM.SILMod); diff --git a/test/IRGen/generic_structs.swift b/test/IRGen/generic_structs.swift new file mode 100644 index 0000000000000..97b4ededf2c40 --- /dev/null +++ b/test/IRGen/generic_structs.swift @@ -0,0 +1,26 @@ +// RUN: %target-swift-frontend -primary-file %s -emit-ir | FileCheck %s + +struct A +{ + var b: T1 + var c: T2 + var d: B +} +struct B +{ + var c: T1 + var d: T2 +} + +struct C +{} +struct D +{} + +struct Foo +{ + var b: Bar +} + +struct Bar { +} \ No newline at end of file