Don't trap when creating a Set from a literal with duplicate elements

rdar://problem/19178760

Swift SVN r23791
This commit is contained in:
David Farler
2014-12-08 23:09:04 +00:00
parent 933ac28760
commit 324411a44b
3 changed files with 31 additions and 33 deletions

View File

@@ -1882,11 +1882,16 @@ internal struct _Native${Self}Storage<${TypeParametersDecl}> :
%if Self == 'Set': %if Self == 'Set':
var count = 0
for key in elements { for key in elements {
var (i, found) = nativeStorage._find(key, nativeStorage._bucket(key)) var (i, found) = nativeStorage._find(key, nativeStorage._bucket(key))
_precondition(!found, "${Self} literal contains duplicate keys") if found {
continue
}
nativeStorage[i.offset] = Element(key: key) nativeStorage[i.offset] = Element(key: key)
++count
} }
nativeStorage.count = count
%elif Self == 'Dictionary': %elif Self == 'Dictionary':
@@ -1895,10 +1900,10 @@ internal struct _Native${Self}Storage<${TypeParametersDecl}> :
_precondition(!found, "${Self} literal contains duplicate keys") _precondition(!found, "${Self} literal contains duplicate keys")
nativeStorage[i.offset] = Element(key: key, value: value) nativeStorage[i.offset] = Element(key: key, value: value)
} }
nativeStorage.count = elements.count
%end %end
nativeStorage.count = elements.count
return nativeStorage return nativeStorage
} }
} }

View File

@@ -2422,20 +2422,31 @@ SetTestSuite.test("SetBridgeFromObjectiveCConditional") {
// Public API // Public API
SetTestSuite.test("init(SequenceType:)") { SetTestSuite.test("init(SequenceType:)") {
let s1 = Set([1010, 2020, 3030]) let s1 = Set([1010, 2020, 3030])
var s2 = Set<Int>() var s2 = Set<Int>()
s2.insert(1010) s2.insert(1010)
s2.insert(2020) s2.insert(2020)
s2.insert(3030) s2.insert(3030)
expectEqual(s1, s2) expectEqual(s1, s2)
// Test the uniquing capabilities of a set // Test the uniquing capabilities of a set
let s3 = Set([ let s3 = Set([
1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010,
1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010,
2020, 2020, 2020, 3030, 3030, 3030 2020, 2020, 2020, 3030, 3030, 3030
]) ])
expectEqual(s1, s3) expectEqual(s1, s3)
}
SetTestSuite.test("init(arrayLiteral:)") {
let s1: Set<Int> = [1010, 2020, 3030, 1010, 2020, 3030]
let s2 = Set([1010, 2020, 3030])
var s3 = Set<Int>()
s3.insert(1010)
s3.insert(2020)
s3.insert(3030)
expectEqual(s1, s2)
expectEqual(s2, s3)
} }
SetTestSuite.test("isSubsetOf.Set.Set") { SetTestSuite.test("isSubsetOf.Set.Set") {

View File

@@ -3,9 +3,6 @@
// RUN: xcrun -sdk %target-sdk-name clang++ -arch %target-cpu %S/Inputs/CatchCrashes.cpp -c -o %t/CatchCrashes.o // RUN: xcrun -sdk %target-sdk-name clang++ -arch %target-cpu %S/Inputs/CatchCrashes.cpp -c -o %t/CatchCrashes.o
// RUN: %target-build-swift %s -Xlinker %t/CatchCrashes.o -o %t/a.out // RUN: %target-build-swift %s -Xlinker %t/CatchCrashes.o -o %t/a.out
// //
// RUN: %target-run %t/a.out DuplicateKeys1 2>&1 | FileCheck %s -check-prefix=CHECK
// RUN: %target-run %t/a.out DuplicateKeys2 2>&1 | FileCheck %s -check-prefix=CHECK
// RUN: %target-run %t/a.out DuplicateKeys3 2>&1 | FileCheck %s -check-prefix=CHECK
// RUN: %target-run %t/a.out RemoveInvalidIndex1 2>&1 | FileCheck %s -check-prefix=CHECK // RUN: %target-run %t/a.out RemoveInvalidIndex1 2>&1 | FileCheck %s -check-prefix=CHECK
// RUN: %target-run %t/a.out RemoveInvalidIndex2 2>&1 | FileCheck %s -check-prefix=CHECK // RUN: %target-run %t/a.out RemoveInvalidIndex2 2>&1 | FileCheck %s -check-prefix=CHECK
// RUN: %target-run %t/a.out RemoveInvalidIndex3 2>&1 | FileCheck %s -check-prefix=CHECK // RUN: %target-run %t/a.out RemoveInvalidIndex3 2>&1 | FileCheck %s -check-prefix=CHECK
@@ -72,21 +69,6 @@ if true {
var nss: NSSet = s var nss: NSSet = s
} }
if arg == "DuplicateKeys1" {
println("OK")
let s: Set<Int> = [10, 20, 30, 10]
}
if arg == "DuplicateKeys2" {
println("OK")
let s: Set<Int> = [10, 20, 30, 10]
}
if arg == "DuplicateKeys3" {
println("OK")
var s: Set<Int> = [10, 10]
}
if arg == "RemoveInvalidIndex1" { if arg == "RemoveInvalidIndex1" {
var s = Set<Int>() var s = Set<Int>()
let index = s.startIndex let index = s.startIndex