Skip to content

Commit fddf6ce

Browse files
committed
SILGen: Don't stub unavailable raw value initializers for clang enums.
We must be conservative when generating SIL for raw value initializers of clang enums and not insert an unavailable code reached trap, even if the enum is technically unavailable. It appears that there is a long-standing loophole that allows a clang module to typedef an unavailable type in order to make that type available in Swift even though the underlying type is declared to be unavailable in Swift. This loophole is load-bearing for some existing Swift overlays. Resolves rdar://116378269
1 parent df48b60 commit fddf6ce

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

lib/AST/Availability.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "swift/AST/TypeWalker.h"
2424
#include "swift/AST/Types.h"
2525
#include "swift/Basic/Platform.h"
26+
#include "swift/ClangImporter/ClangModule.h"
2627
#include <map>
2728

2829
using namespace swift;
@@ -312,7 +313,7 @@ bool Decl::isAvailableDuringLowering() const {
312313
UnavailableDeclOptimization::Complete)
313314
return true;
314315

315-
if (hasClangNode())
316+
if (isa<ClangModuleUnit>(getDeclContext()->getModuleScopeContext()))
316317
return true;
317318

318319
return !isUnconditionallyUnavailable(this);
@@ -325,6 +326,9 @@ bool Decl::requiresUnavailableDeclABICompatibilityStubs() const {
325326
UnavailableDeclOptimization::Stub)
326327
return false;
327328

329+
if (isa<ClangModuleUnit>(getDeclContext()->getModuleScopeContext()))
330+
return false;
331+
328332
return isUnconditionallyUnavailable(this);
329333
}
330334

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
// RUN: %target-swift-emit-silgen %t/Overlay.swift -I %t -import-objc-header %t/MyOptions.h -unavailable-decl-optimization=none | %FileCheck %t/Overlay.swift
4+
// RUN: %target-swift-emit-silgen %t/Overlay.swift -I %t -import-objc-header %t/MyOptions.h -unavailable-decl-optimization=stub | %FileCheck %t/Overlay.swift
5+
// RUN: %target-swift-emit-silgen %t/Overlay.swift -I %t -import-objc-header %t/MyOptions.h -unavailable-decl-optimization=complete | %FileCheck %t/Overlay.swift
6+
7+
//--- MyOptions.h
8+
9+
__attribute__((availability(swift, unavailable, message="Unavailable in Swift")))
10+
typedef enum : int {
11+
SomeOption,
12+
} MyOptions;
13+
14+
typedef MyOptions MyOptionsTypedef;
15+
16+
//--- Overlay.swift
17+
18+
// This really shouldn't be allowed, but it is.
19+
let _ = MyOptionsTypedef(rawValue: 1)
20+
21+
// CHECK-LABEL: sil shared [transparent] [serialized]{{.*}} @$sSo9MyOptionsa8rawValueABs5Int32V_tcfC : $@convention(method) (Int32, @thin MyOptions.Type) -> MyOptions {
22+
// CHECK-NOT: ss31_diagnoseUnavailableCodeReacheds5NeverOyFTwb
23+
// CHECK: } // end sil function '$sSo9MyOptionsa8rawValueABs5Int32V_tcfC'

0 commit comments

Comments
 (0)