Skip to content

Commit 0837072

Browse files
Merge pull request #17563 from ravikandhadai/DIOptWritePR
Revert "[DefiniteInitialization] Fix the bug that allows overwriting immutable optionals" due to internal build failure <rdar://41501480>
2 parents 88ad6d5 + 964397c commit 0837072

File tree

3 files changed

+11
-145
lines changed

3 files changed

+11
-145
lines changed

lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -950,16 +950,6 @@ void ElementUseCollector::collectUses(SILValue Pointer, unsigned BaseEltNo) {
950950
continue;
951951
}
952952

953-
// unchecked_take_enum_data_addr takes the address of the payload of the
954-
// optional, which could be used to update the payload. So, visit the
955-
// users of this instruction and ensure that there are no overwrites to an
956-
// immutable optional. Note that this special handling is for checking
957-
// immutability and is not for checking initialization before use.
958-
if (auto *enumDataAddr = dyn_cast<UncheckedTakeEnumDataAddrInst>(User)) {
959-
collectUses(enumDataAddr, BaseEltNo);
960-
continue;
961-
}
962-
963953
// We model destroy_addr as a release of the entire value.
964954
if (isa<DestroyAddrInst>(User)) {
965955
trackDestroy(User);

lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,14 +1239,18 @@ void LifetimeChecker::handleEscapeUse(const DIMemoryUse &Use) {
12391239
noteUninitializedMembers(Use);
12401240
return;
12411241
}
1242+
12421243

12431244
Diag<StringRef, bool> DiagMessage;
1244-
if (Inst->getLoc().isASTNode<AbstractClosureExpr>()) {
1245-
DiagMessage = diag::variable_closure_use_uninit;
1246-
} else if (isa<MarkFunctionEscapeInst>(Inst)) {
1247-
DiagMessage = diag::variable_function_use_uninit;
1248-
} else {
1245+
if (isa<MarkFunctionEscapeInst>(Inst)) {
1246+
if (Inst->getLoc().isASTNode<AbstractClosureExpr>())
1247+
DiagMessage = diag::variable_closure_use_uninit;
1248+
else
1249+
DiagMessage = diag::variable_function_use_uninit;
1250+
} else if (isa<UncheckedTakeEnumDataAddrInst>(Inst)) {
12491251
DiagMessage = diag::variable_used_before_initialized;
1252+
} else {
1253+
DiagMessage = diag::variable_closure_use_uninit;
12501254
}
12511255

12521256
diagnoseInitError(Use, DiagMessage);
@@ -1704,11 +1708,10 @@ void LifetimeChecker::handleLoadUseFailure(const DIMemoryUse &Use,
17041708
// If this is a load into a promoted closure capture, diagnose properly as
17051709
// a capture.
17061710
if ((isa<LoadInst>(Inst) || isa<LoadBorrowInst>(Inst)) &&
1707-
Inst->getLoc().isASTNode<AbstractClosureExpr>()) {
1711+
Inst->getLoc().isASTNode<AbstractClosureExpr>())
17081712
diagnoseInitError(Use, diag::variable_closure_use_uninit);
1709-
} else {
1713+
else
17101714
diagnoseInitError(Use, diag::variable_used_before_initialized);
1711-
}
17121715
}
17131716

17141717
/// handleSelfInitUse - When processing a 'self' argument on a class, this is

test/SILOptimizer/definite_init_diagnostics.swift

Lines changed: 0 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -1355,130 +1355,3 @@ class ClassWithUnownedProperties {
13551355
c2 = tmp
13561356
}
13571357
}
1358-
1359-
// Tests for DI when optionals are defined using unchecked_take_enum_data_addr
1360-
// <rdar://38624845>
1361-
1362-
func testOptionalDoubleWrite() -> String? {
1363-
let sConst: String? // expected-note {{change 'let' to 'var' to make it mutable}}
1364-
sConst = ""
1365-
sConst? = "v2" // expected-error {{immutable value 'sConst' may only be initialized once}}
1366-
return sConst
1367-
}
1368-
1369-
func testOptionalDoubleWrite2() -> Int? {
1370-
let x: Int? // expected-note {{change 'let' to 'var' to make it mutable}}
1371-
x = 0
1372-
x? = 0 // expected-error {{immutable value 'x' may only be initialized once}}
1373-
return x
1374-
}
1375-
1376-
protocol DIOptionalTestProtocol {
1377-
var f: Int { get set }
1378-
}
1379-
1380-
func testOptionalDoubleWrite3(p1: DIOptionalTestProtocol) -> DIOptionalTestProtocol? {
1381-
let x: DIOptionalTestProtocol? // expected-note {{change 'let' to 'var' to make it mutable}}
1382-
x = p1
1383-
x? = p1 // expected-error {{immutable value 'x' may only be initialized once}}
1384-
return x
1385-
}
1386-
1387-
func testOptionalWrite() {
1388-
let x: Int? // expected-note {{constant defined here}}
1389-
// expected-warning@-1 {{immutable value 'x' was never used; consider removing it}}
1390-
x? = 0 // expected-error {{constant 'x' used before being initialized}}
1391-
}
1392-
1393-
func testOptionalWriteGenerics<T>(p: T) -> T? {
1394-
let x: T? // expected-note {{constant defined here}}
1395-
// expected-note@-1 {{change 'let' to 'var' to make it mutable}}
1396-
x? = p // expected-error {{constant 'x' used before being initialized}}
1397-
x = p // expected-error {{immutable value 'x' may only be initialized once}}
1398-
return x
1399-
}
1400-
1401-
func testOptionalWriteGenerics2<T>(p: T) -> T? {
1402-
let x: T? // expected-note {{change 'let' to 'var' to make it mutable}}
1403-
x = p
1404-
x? = p // expected-error {{immutable value 'x' may only be initialized once}}
1405-
return x
1406-
}
1407-
1408-
enum TestOptionalEnum {
1409-
case Cons(Int)
1410-
case Nil()
1411-
}
1412-
1413-
func testOptionalWithEnum(p: TestOptionalEnum) -> TestOptionalEnum? {
1414-
let x: TestOptionalEnum? // expected-note {{change 'let' to 'var' to make it mutable}}
1415-
x = p
1416-
x? = p // expected-error {{immutable value 'x' may only be initialized once}}
1417-
return x
1418-
}
1419-
1420-
// Tests for optional chaining
1421-
1422-
class DIOptionalTestClass {
1423-
var r: DIOptionalTestClass? = nil
1424-
var f: Int = 0;
1425-
let g: Int = 0;
1426-
}
1427-
1428-
func testOptionalChaining(p: DIOptionalTestClass?) {
1429-
p?.f = 2
1430-
}
1431-
1432-
func testOptionalChaining2(p: DIOptionalTestClass?) -> DIOptionalTestClass? {
1433-
let x: DIOptionalTestClass?
1434-
x = p
1435-
x?.f = 1
1436-
p?.r?.f = 2
1437-
return x
1438-
}
1439-
1440-
struct DIOptionalTestStruct {
1441-
var f: Int
1442-
}
1443-
1444-
func testOptionalChaining3() -> DIOptionalTestStruct? {
1445-
let x: DIOptionalTestStruct? // expected-note {{change 'let' to 'var' to make it mutable}}
1446-
x = DIOptionalTestStruct(f: 0)
1447-
x?.f = 2 // expected-error {{immutable value 'x' may only be initialized once}}
1448-
return x
1449-
}
1450-
1451-
extension DIOptionalTestStruct {
1452-
public init?() {
1453-
self.f = 0
1454-
}
1455-
}
1456-
1457-
func testOptionalChaining4() -> DIOptionalTestStruct? {
1458-
let x: DIOptionalTestStruct? // expected-note {{change 'let' to 'var' to make it mutable}}
1459-
x = DIOptionalTestStruct()
1460-
x?.f = 2 // expected-error {{immutable value 'x' may only be initialized once}}
1461-
return x
1462-
}
1463-
1464-
struct DIOptionalTestStructPair {
1465-
var pair: (Int, Int)
1466-
}
1467-
1468-
func test6() -> DIOptionalTestStructPair? {
1469-
let x: DIOptionalTestStructPair? // expected-note {{change 'let' to 'var' to make it mutable}}
1470-
x = DIOptionalTestStructPair(pair: (0, 0))
1471-
x?.pair.0 = 1 // expected-error {{immutable value 'x' may only be initialized once}}
1472-
return x
1473-
}
1474-
1475-
func testOptionalChainingWithGenerics<T: DIOptionalTestProtocol>(p: T) -> T? {
1476-
let x: T? // expected-note {{constant defined here}}
1477-
// expected-note@-1 {{constant defined here}}
1478-
// expected-note@-2 {{constant defined here}}
1479-
1480-
// note that here assignment to 'f' is a call to the setter.
1481-
x?.f = 0 // expected-error {{constant 'x' used before being initialized}}
1482-
// expected-error@-1 {{constant 'x' passed by reference before being initialized}}
1483-
return x // expected-error {{constant 'x' used before being initialized}}
1484-
}

0 commit comments

Comments
 (0)