Skip to content

Commit 3c8573c

Browse files
committed
[4.2] AllocStackHoisting: Don't hoist alloc_stacks in the presence of an availability guard
Explaination: Alloc_stack hoisting would hoist alloc_stacks out of availability guards causing runtime errors. Scope: This bug has been there for several releases. Risk: Low. Disables hoisting of alloc_stacks if there is an availablity macro. This disables inlinability of _stdlib_isOSVersionAtLeast. I don't see value in making it inlinable as long as _swift_stdlib_operatingSystemVersion is opaque. rdar://41849700
1 parent 27c4f07 commit 3c8573c

File tree

3 files changed

+33
-2
lines changed

3 files changed

+33
-2
lines changed

lib/IRGen/AllocStackHoisting.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,13 @@ void HoistAllocStack::collectHoistableInstructions() {
348348
FunctionExits.push_back(Term);
349349
continue;
350350
}
351-
351+
// Don't perform alloc_stack hoisting in functions with availability.
352+
if (auto *Apply = dyn_cast<ApplyInst>(&Inst)) {
353+
if (Apply->hasSemantics("availability.osversion")) {
354+
AllocStackToHoist.clear();
355+
return;
356+
}
357+
}
352358
auto *ASI = dyn_cast<AllocStackInst>(&Inst);
353359
if (!ASI) {
354360
continue;

stdlib/public/core/Availability.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ import SwiftShims
1717
///
1818
/// This is a magic entry point known to the compiler. It is called in
1919
/// generated code for API availability checking.
20-
@inlinable // FIXME(sil-serialize-all)
20+
/// Note: It is important not to make this function inlinable. There is a pass
21+
/// that relies on being able to tell whether this function is called. It does
22+
/// this using the semantics attribute.
2123
@_semantics("availability.osversion")
2224
public func _stdlib_isOSVersionAtLeast(
2325
_ major: Builtin.Word,

test/IRGen/availability.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -primary-file %s -emit-ir | %FileCheck %s
2+
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -primary-file %s -O -emit-ir | %FileCheck %s
3+
4+
// REQUIRES: objc_interop
5+
6+
import Foundation
7+
8+
// We mustn't hoist the alloc_stack for measurement out of the availability
9+
// guard.
10+
11+
// CHECK-LABEL: define{{.*}} @{{.*}}dontHoist
12+
// CHECK-NOT: S10Foundation11MeasurementVySo17NSUnitTemperature
13+
// CHECK: call swiftcc i1 @"$Ss26_stdlib_isOSVersionAtLeastyBi1_Bw_BwBwtF"(
14+
// CHECK: S10Foundation11MeasurementVySo17NSUnitTemperature
15+
16+
public func dontHoist() {
17+
if #available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) {
18+
let measurement = Measurement<UnitTemperature>(value: Double(42), unit: .celsius)
19+
print("\(measurement)")
20+
} else {
21+
print("Not measurement")
22+
}
23+
}

0 commit comments

Comments
 (0)