From 9eee1df2a8be40b8642931c0c73f711a092e727f Mon Sep 17 00:00:00 2001 From: Manav Gabhawala Date: Mon, 7 Dec 2015 01:08:45 -0500 Subject: [PATCH 1/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 | 5 +++++ test/IRGen/generic_structs.swift | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 test/IRGen/generic_structs.swift diff --git a/lib/IRGen/GenType.cpp b/lib/IRGen/GenType.cpp index 3067a18fcf9f0..2e812ecf74e22 100644 --- a/lib/IRGen/GenType.cpp +++ b/lib/IRGen/GenType.cpp @@ -2032,6 +2032,11 @@ 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 From 06839c43ea7d1aaa700cb55c017b4b56100d2c91 Mon Sep 17 00:00:00 2001 From: Manav Gabhawala Date: Mon, 7 Dec 2015 01:12:01 -0500 Subject: [PATCH 2/4] Check using .empty() instead of .end() Updates to check for empty instead of checking iterator at end() for more readability. --- lib/IRGen/GenType.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/IRGen/GenType.cpp b/lib/IRGen/GenType.cpp index 2e812ecf74e22..e8842dfe0b056 100644 --- a/lib/IRGen/GenType.cpp +++ b/lib/IRGen/GenType.cpp @@ -2034,7 +2034,7 @@ SILType irgen::getSingletonAggregateFieldType(IRGenModule &IGM, 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()) + if (allFields.empty()) return SILType(); if (std::next(field) == allFields.end()) From e755c3f617673b64ffec048bbe09e51e37bf6ac1 Mon Sep 17 00:00:00 2001 From: Manav Gabhawala Date: Mon, 7 Dec 2015 02:29:41 -0500 Subject: [PATCH 3/4] Refactored Into 2 Code Paths Refactored the code so that there is only a single branch for when there is one stored property and the rest return a SILType() as per @simonmpilkington suggestion. --- lib/IRGen/GenType.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/IRGen/GenType.cpp b/lib/IRGen/GenType.cpp index e8842dfe0b056..fb6e2344cfaeb 100644 --- a/lib/IRGen/GenType.cpp +++ b/lib/IRGen/GenType.cpp @@ -2031,13 +2031,9 @@ 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 (allFields.empty()) - return SILType(); - if (std::next(field) == allFields.end()) + auto field = allFields.begin(); + if (!allFields.empty() && std::next(field) == allFields.end()) return t.getFieldType(*field, *IGM.SILMod); return SILType(); From 8017cd2164ae5ca71894869f29ac214463169605 Mon Sep 17 00:00:00 2001 From: Manav Gabhawala Date: Mon, 7 Dec 2015 13:52:52 -0500 Subject: [PATCH 4/4] Added empty newline at the end of test case --- test/IRGen/generic_structs.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/IRGen/generic_structs.swift b/test/IRGen/generic_structs.swift index 97b4ededf2c40..faaec4b3f4255 100644 --- a/test/IRGen/generic_structs.swift +++ b/test/IRGen/generic_structs.swift @@ -23,4 +23,4 @@ struct Foo } struct Bar { -} \ No newline at end of file +}