Skip to content

Commit 4873245

Browse files
Merge pull request #5170 from swiftwasm/katei/merge-main-2023-01-11
Merge main 2023-01-11
2 parents 49f10c2 + 397c18b commit 4873245

14 files changed

+264
-71
lines changed

lib/SIL/Utils/FieldSensitivePrunedLiveness.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -781,7 +781,7 @@ void FieldSensitiveMultiDefPrunedLiveRange::findBoundariesInBlock(
781781
LLVM_DEBUG(llvm::dbgs() << "Has multiple defs!\n");
782782

783783
// Handle a live-out or live-within block with potentially multiple defs
784-
// unsigned prevCount = boundary.getNumLastUsersAndDeadDefs(bitNo);
784+
unsigned prevCount = boundary.getNumLastUsersAndDeadDefs(bitNo);
785785
bool isLive = isLiveOut;
786786
for (auto &inst : llvm::reverse(*block)) {
787787
LLVM_DEBUG(llvm::dbgs() << "Visiting: " << inst);
@@ -861,6 +861,7 @@ void FieldSensitiveMultiDefPrunedLiveRange::findBoundariesInBlock(
861861
<< " Live at beginning of block! No dead args!\n");
862862
}
863863

864-
// assert(prevCount < boundary.getNumLastUsersAndDeadDefs(bitNo) &&
865-
// "findBoundariesInBlock must be called on a live block");
864+
assert((isLiveOut ||
865+
prevCount < boundary.getNumLastUsersAndDeadDefs(bitNo)) &&
866+
"findBoundariesInBlock must be called on a live block");
866867
}

lib/SIL/Utils/PrunedLiveness.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -578,8 +578,15 @@ void MultiDefPrunedLiveness::findBoundariesInBlock(
578578
boundary.deadDefs.push_back(deadArg);
579579
}
580580
}
581+
if (auto *predBB = block->getSinglePredecessorBlock()) {
582+
if (getBlockLiveness(predBB) == PrunedLiveBlocks::LiveOut) {
583+
boundary.boundaryEdges.push_back(block);
584+
}
585+
}
581586
}
582-
assert(prevCount < boundary.deadDefs.size() + boundary.lastUsers.size()
587+
// All live-within blocks must contain a boundary.
588+
assert(isLiveOut
589+
|| (prevCount < boundary.deadDefs.size() + boundary.lastUsers.size())
583590
&& "findBoundariesInBlock must be called on a live block");
584591
}
585592

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3586,34 +3586,6 @@ bool ExprAvailabilityWalker::diagnoseDeclRefAvailability(
35863586
static bool
35873587
diagnoseDeclAsyncAvailability(const ValueDecl *D, SourceRange R,
35883588
const Expr *call, const ExportContext &Where) {
3589-
// FIXME: I don't think this is right, but I don't understand the issue well
3590-
// enough to fix it properly. If the decl context is an abstract
3591-
// closure, we need it to have a type assigned to it before we can
3592-
// determine whether it is an asynchronous context. It will crash
3593-
// when we go to check without one. In TypeChecker::typeCheckExpression
3594-
// (TypeCheckConstraints.cpp:403), we apply a solution before calling
3595-
// `performSyntacticDiagnosticsForTarget`, which eventually calls
3596-
// down to this function. Under most circumstances, the context that
3597-
// we're in is typechecked at that point and has a type assigned.
3598-
// When working with specific result builders, the solution applied
3599-
// results in an expression with an unset type. In these cases, the
3600-
// application makes its way into `ConstraintSystem::applySolution` for
3601-
// closures (CSClosure.cpp:1356). The type is computed, but is
3602-
// squirreled away in the constrain system to be applied once the
3603-
// checks (including this one) approve of the decls within the decl
3604-
// context before applying the type to the expression. It might be
3605-
// possible to drive the constraint solver through the availability
3606-
// checker and into us so that we can ask for it, but that feels wrong
3607-
// too.
3608-
// This behavior is demonstrated by the first use of the `tuplify`
3609-
// function in `testExistingPatternsInCaseStatements` in
3610-
// `test/Constraints/result_builder.swift`.
3611-
const AbstractClosureExpr *declCtxAsExpr =
3612-
dyn_cast<AbstractClosureExpr>(Where.getDeclContext());
3613-
if (declCtxAsExpr && !declCtxAsExpr->getType()) {
3614-
return false;
3615-
}
3616-
36173589
// If we are in a synchronous context, don't check it
36183590
if (!Where.getDeclContext()->isAsyncContext())
36193591
return false;

lib/Sema/TypeCheckRuntimeMetadataAttr.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -283,20 +283,25 @@ Expr *SynthesizeRuntimeMetadataAttrGenerator::evaluate(
283283
initArgument = keyPath;
284284
}
285285

286-
auto reprRange = SourceRange();
287-
if (auto *repr = attr->getTypeRepr())
288-
reprRange = repr->getSourceRange();
286+
SourceRange sourceRange;
287+
if (auto *repr = attr->getTypeRepr()) {
288+
sourceRange = repr->getSourceRange();
289+
} else {
290+
sourceRange = SourceRange(
291+
attachedTo->getAttributeInsertionLoc(/*forModifier=*/false));
292+
}
289293

290-
auto typeExpr = TypeExpr::createImplicitHack(reprRange.Start, attrType, ctx);
294+
auto typeExpr =
295+
TypeExpr::createImplicitHack(sourceRange.Start, attrType, ctx);
291296

292297
// Add the initializer argument at the front of the argument list
293298
SmallVector<Argument, 4> newArgs;
294299
newArgs.push_back({/*loc=*/SourceLoc(), ctx.Id_attachedTo, initArgument});
295300
if (auto *attrArgs = attr->getArgs())
296301
newArgs.append(attrArgs->begin(), attrArgs->end());
297302

298-
ArgumentList *argList = ArgumentList::createImplicit(ctx, reprRange.Start,
299-
newArgs, reprRange.End);
303+
ArgumentList *argList = ArgumentList::createImplicit(
304+
ctx, sourceRange.Start, newArgs, sourceRange.End);
300305
Expr *init = CallExpr::createImplicit(ctx, typeExpr, argList);
301306

302307
// result of generator is an optional always.

stdlib/public/BackDeployConcurrency/TaskCancellation.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,14 @@ public func withTaskCancellationHandler<T>(
4646
// unconditionally add the cancellation record to the task.
4747
// if the task was already cancelled, it will be executed right away.
4848
let record = _taskAddCancellationHandler(handler: handler)
49-
defer { _taskRemoveCancellationHandler(record: record) }
50-
51-
return try await operation()
49+
do {
50+
let result = try await operation()
51+
_taskRemoveCancellationHandler(record: record)
52+
return result
53+
} catch {
54+
_taskRemoveCancellationHandler(record: record)
55+
throw error
56+
}
5257
}
5358

5459
@available(SwiftStdlib 5.1, *)

stdlib/public/BackDeployConcurrency/TaskLocal.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,14 @@ public final class TaskLocal<Value: Sendable>: Sendable, CustomStringConvertible
145145
_checkIllegalTaskLocalBindingWithinWithTaskGroup(file: file, line: line)
146146

147147
_taskLocalValuePush(key: key, value: valueDuringOperation)
148-
defer { _taskLocalValuePop() }
149-
150-
return try await operation()
148+
do {
149+
let result = try await operation()
150+
_taskLocalValuePop()
151+
return result
152+
} catch {
153+
_taskLocalValuePop()
154+
throw error
155+
}
151156
}
152157

153158
/// Binds the task-local to the specific value for the duration of the

stdlib/public/Concurrency/TaskCancellation.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,14 @@ public func withTaskCancellationHandler<T>(
4646
// unconditionally add the cancellation record to the task.
4747
// if the task was already cancelled, it will be executed right away.
4848
let record = _taskAddCancellationHandler(handler: handler)
49-
defer { _taskRemoveCancellationHandler(record: record) }
50-
51-
return try await operation()
49+
do {
50+
let result = try await operation()
51+
_taskRemoveCancellationHandler(record: record)
52+
return result
53+
} catch {
54+
_taskRemoveCancellationHandler(record: record)
55+
throw error
56+
}
5257
}
5358

5459
@available(SwiftStdlib 5.1, *)

stdlib/public/Concurrency/TaskLocal.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,14 @@ public final class TaskLocal<Value: Sendable>: Sendable, CustomStringConvertible
145145
_checkIllegalTaskLocalBindingWithinWithTaskGroup(file: file, line: line)
146146

147147
_taskLocalValuePush(key: key, value: valueDuringOperation)
148-
defer { _taskLocalValuePop() }
149-
150-
return try await operation()
148+
do {
149+
let result = try await operation()
150+
_taskLocalValuePop()
151+
return result
152+
} catch {
153+
_taskLocalValuePop()
154+
throw error
155+
}
151156
}
152157

153158
/// Binds the task-local to the specific value for the duration of the

stdlib/public/core/Macros.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
#if hasAttribute(expression)
13+
#if compiler(>=5.8) && hasAttribute(expression)
1414
/// Specifies the module and type name for an externally-defined macro, which
1515
/// must conform to the appropriate set of `Macro` protocols.
1616
///
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
@runtimeMetadata
2+
public struct Ignore {
3+
public init<T>(attachedTo: T,
4+
fileID: String = #fileID,
5+
line: Int = #line,
6+
column: Int = #column) {}
7+
}
8+
9+
@Ignore
10+
public protocol Ignorable {}

test/SILGen/runtime_attributes.swift

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -enable-experimental-feature RuntimeDiscoverableAttrs -emit-module -o %t -enable-library-evolution %S/Inputs/runtime_metadata_defs.swift
3+
4+
// This uses '-primary-file' to ensure we're conservative with lazy SIL emission.
5+
// RUN: %target-swift-emit-silgen -enable-experimental-feature RuntimeDiscoverableAttrs -primary-file %s -I %t | %FileCheck %s
6+
7+
// REQUIRES: asserts
8+
9+
import runtime_metadata_defs
10+
11+
/// Test that generator has source locations for both explicit and inferred attributes.
12+
13+
// CHECK-LABEL: sil hidden [runtime_accessible] [ossa] @$s18runtime_attributes4TestAaBVmvpfa0A14_metadata_defs6Ignore : $@convention(thin) () -> @out Optional<Ignore>
14+
// CHECK: [[FILE_ID:%.*]] = string_literal utf8 "runtime_attributes/runtime_attributes.swift"
15+
// CHECK: [[STRING_INIT:%.*]] = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC
16+
// CHECK-NEXT: [[FILE_STR:%.*]] = apply [[STRING_INIT]]([[FILE_ID]], {{.*}})
17+
// CHECK: [[LINE_RAW:%.*]] = integer_literal $Builtin.IntLiteral, 25
18+
// CHECK: [[INT_INIT:%.*]] = function_ref @$sSi22_builtinIntegerLiteralSiBI_tcfC
19+
// CHECK-NEXT: [[LINE:%.*]] = apply [[INT_INIT]]([[LINE_RAW]], {{.*}})
20+
// CHECK: [[COLUMN_RAW:%.*]] = integer_literal $Builtin.IntLiteral, 1
21+
// CHECK: [[INT_INIT:%.*]] = function_ref @$sSi22_builtinIntegerLiteralSiBI_tcfC
22+
// CHECK-NEXT: [[COLUMN:%.*]] = apply [[INT_INIT]]([[COLUMN_RAW]], {{.*}})
23+
// CHECK: [[IGNORE_INIT:%.*]] = function_ref @$s21runtime_metadata_defs6IgnoreV10attachedTo6fileID4line6columnACx_SSS2itclufC
24+
// CHECK-NEXT: {{.*}} = apply [[IGNORE_INIT]]<Test.Type>({{.*}}, {{.*}}, [[FILE_STR]], [[LINE]], [[COLUMN]], {{.*}})
25+
struct Test : Ignorable {}
26+
27+
// CHECK-LABEL: sil hidden [runtime_accessible] [ossa] @$s18runtime_attributes8globalFnyycvpfa0A14_metadata_defs6Ignore : $@convention(thin) () -> @out Optional<Ignore>
28+
// CHECK: {{.*}} = string_literal utf8 "runtime_attributes/runtime_attributes.swift"
29+
// CHECK: {{.*}} = integer_literal $Builtin.IntLiteral, 33
30+
// CHECK: {{.*}} = integer_literal $Builtin.IntLiteral, 2
31+
// CHECK: [[IGNORE_INIT:%.*]] = function_ref @$s21runtime_metadata_defs6IgnoreV10attachedTo6fileID4line6columnACx_SSS2itclufC
32+
// CHECK-NEXT: {{.*}} = apply [[IGNORE_INIT]]<() -> ()>({{.*}})
33+
@Ignore func globalFn() {}
34+
35+
struct MemberTests {
36+
// CHECK-LABEL: sil hidden [runtime_accessible] [ossa] @$s18runtime_attributes11MemberTestsV1xSivpfa0A14_metadata_defs6Ignore : $@convention(thin) () -> @out Optional<Ignore>
37+
// CHECK: {{.*}} = string_literal utf8 "runtime_attributes/runtime_attributes.swift"
38+
// CHECK: {{.*}} = integer_literal $Builtin.IntLiteral, 42
39+
// CHECK: {{.*}} = integer_literal $Builtin.IntLiteral, 4
40+
// CHECK: [[IGNORE_INIT:%.*]] = function_ref @$s21runtime_metadata_defs6IgnoreV10attachedTo6fileID4line6columnACx_SSS2itclufC
41+
// CHECK-NEXT: {{.*}} = apply [[IGNORE_INIT]]<WritableKeyPath<MemberTests, Int>>({{.*}})
42+
@Ignore var x: Int = 42
43+
44+
// CHECK-LABEL: sil hidden [runtime_accessible] [ossa] @$s18runtime_attributes11MemberTestsV6instFn_1xSSSi_SaySiGtcvpfa0A14_metadata_defs6Ignore : $@convention(thin) () -> @out Optional<Ignore>
45+
// CHECK: {{.*}} = string_literal utf8 "runtime_attributes/runtime_attributes.swift"
46+
// CHECK: {{.*}} = integer_literal $Builtin.IntLiteral, 50
47+
// CHECK: {{.*}} = integer_literal $Builtin.IntLiteral, 4
48+
// CHECK: [[IGNORE_INIT:%.*]] = function_ref @$s21runtime_metadata_defs6IgnoreV10attachedTo6fileID4line6columnACx_SSS2itclufC
49+
// CHECK-NEXT: {{.*}} = apply [[IGNORE_INIT]]<(MemberTests, Int, [Int]) -> String>({{.*}})
50+
@Ignore func instFn(_: Int, x: [Int]) -> String { "" }
51+
52+
// CHECK-LABEL: sil hidden [runtime_accessible] [ossa] @$s18runtime_attributes11MemberTestsV8staticFn_1ySi_SStSS_SiztcvpZfa0A14_metadata_defs6Ignore : $@convention(thin) () -> @out Optional<Ignore>
53+
// CHECK: {{.*}} = string_literal utf8 "runtime_attributes/runtime_attributes.swift"
54+
// CHECK: {{.*}} = integer_literal $Builtin.IntLiteral, 58
55+
// CHECK: {{.*}} = integer_literal $Builtin.IntLiteral, 4
56+
// CHECK: [[IGNORE_INIT:%.*]] = function_ref @$s21runtime_metadata_defs6IgnoreV10attachedTo6fileID4line6columnACx_SSS2itclufC
57+
// CHECK-NEXT: {{.*}} = apply [[IGNORE_INIT]]<(MemberTests.Type, String, inout Int) -> (Int, String)>({{.*}})
58+
@Ignore static func staticFn(_ x: String, y: inout Int) -> (Int, String) { (42, "") }
59+
60+
// CHECK-LABEL: sil hidden [runtime_accessible] [ossa] @$s18runtime_attributes11MemberTestsV10mutatingFnSiycvpfa0A14_metadata_defs6Ignore : $@convention(thin) () -> @out Optional<Ignore>
61+
// CHECK: {{.*}} = string_literal utf8 "runtime_attributes/runtime_attributes.swift"
62+
// CHECK: {{.*}} = integer_literal $Builtin.IntLiteral, 66
63+
// CHECK: {{.*}} = integer_literal $Builtin.IntLiteral, 4
64+
// CHECK: [[IGNORE_INIT:%.*]] = function_ref @$s21runtime_metadata_defs6IgnoreV10attachedTo6fileID4line6columnACx_SSS2itclufC
65+
// CHECK-NEXT: {{.*}} = apply [[IGNORE_INIT]]<(inout MemberTests) -> Int>({{.*}})
66+
@Ignore mutating func mutatingFn() -> Int { 42 }
67+
}

test/SILOptimizer/moveonly_addresschecker_diagnostics.swift

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2299,16 +2299,15 @@ func copyableStructsInMoveOnlyStructNonConsuming() {
22992299
// Field Sensitive Tests //
23002300
///////////////////////////
23012301

2302-
func fieldSensitiveTestReinitField () {
2302+
func fieldSensitiveTestReinitField() {
23032303
var a = NonTrivialStruct()
23042304
a = NonTrivialStruct()
23052305
classConsume(a.k)
23062306
a.k = Klass()
23072307
classUseMoveOnlyWithoutEscaping(a.k)
23082308
}
23092309

2310-
#if false
2311-
func fieldSensitiveTestReinitFieldMultiBlock1 () {
2310+
func fieldSensitiveTestReinitFieldMultiBlock1() {
23122311
var a = NonTrivialStruct()
23132312
a = NonTrivialStruct()
23142313
classConsume(a.k)
@@ -2318,9 +2317,8 @@ func fieldSensitiveTestReinitFieldMultiBlock1 () {
23182317
classUseMoveOnlyWithoutEscaping(a.k)
23192318
}
23202319
}
2321-
#endif
23222320

2323-
func fieldSensitiveTestReinitFieldMultiBlock2 () {
2321+
func fieldSensitiveTestReinitFieldMultiBlock2() {
23242322
var a = NonTrivialStruct() // expected-error {{'a' used after consume. Lifetime extension of variable requires a copy}}
23252323
a = NonTrivialStruct()
23262324
classConsume(a.k) // expected-note {{consuming use}}
@@ -2332,8 +2330,7 @@ func fieldSensitiveTestReinitFieldMultiBlock2 () {
23322330
classUseMoveOnlyWithoutEscaping(a.k) // expected-note {{non-consuming use}}
23332331
}
23342332

2335-
#if false
2336-
func fieldSensitiveTestReinitFieldMultiBlock3 () {
2333+
func fieldSensitiveTestReinitFieldMultiBlock3() {
23372334
var a = NonTrivialStruct()
23382335
a = NonTrivialStruct()
23392336
classConsume(a.k)
@@ -2346,10 +2343,10 @@ func fieldSensitiveTestReinitFieldMultiBlock3 () {
23462343

23472344
classUseMoveOnlyWithoutEscaping(a.k)
23482345
}
2349-
#endif
23502346

2351-
#if false
2352-
func fieldSensitiveTestReinitFieldMultiBlock4 () {
2347+
// This test sees what happens if we partially reinit along one path and do a
2348+
// full reinit along another path.
2349+
func fieldSensitiveTestReinitFieldMultiBlock4() {
23532350
var a = NonTrivialStruct()
23542351
a = NonTrivialStruct()
23552352
classConsume(a.k)
@@ -2362,4 +2359,43 @@ func fieldSensitiveTestReinitFieldMultiBlock4 () {
23622359

23632360
classUseMoveOnlyWithoutEscaping(a.k)
23642361
}
2365-
#endif
2362+
2363+
func fieldSensitiveTestReinitEnumMultiBlock() {
2364+
var e = NonTrivialEnum.first // expected-error {{'e' used after consume. Lifetime extension of variable requires a copy}}
2365+
e = NonTrivialEnum.second(Klass())
2366+
switch e { // expected-note {{consuming use}}
2367+
case .second:
2368+
e = NonTrivialEnum.third(NonTrivialStruct())
2369+
default:
2370+
break
2371+
}
2372+
nonConsumingUseNonTrivialEnum(e) // expected-note {{non-consuming use}}
2373+
}
2374+
2375+
func fieldSensitiveTestReinitEnumMultiBlock1() {
2376+
var e = NonTrivialEnum.first
2377+
e = NonTrivialEnum.second(Klass())
2378+
switch e {
2379+
case .second:
2380+
e = NonTrivialEnum.third(NonTrivialStruct())
2381+
default:
2382+
e = NonTrivialEnum.fourth(CopyableKlass())
2383+
}
2384+
nonConsumingUseNonTrivialEnum(e)
2385+
}
2386+
2387+
func fieldSensitiveTestReinitEnumMultiBlock2() {
2388+
var e = NonTrivialEnum.first
2389+
e = NonTrivialEnum.second(Klass())
2390+
if boolValue {
2391+
switch e {
2392+
case .second:
2393+
e = NonTrivialEnum.third(NonTrivialStruct())
2394+
default:
2395+
e = NonTrivialEnum.fourth(CopyableKlass())
2396+
}
2397+
} else {
2398+
e = NonTrivialEnum.third(NonTrivialStruct())
2399+
}
2400+
nonConsumingUseNonTrivialEnum(e)
2401+
}

0 commit comments

Comments
 (0)