Merge pull request #12602 from phausler/swift-4.0-branch-NSData_isCompact_availability_guard
[Foundation] Guard Data access to NSData._isCompact under availability guards
diff --git a/lib/AST/ASTVerifier.cpp b/lib/AST/ASTVerifier.cpp
index a0a1f3e..7ed2a35 100644
--- a/lib/AST/ASTVerifier.cpp
+++ b/lib/AST/ASTVerifier.cpp
@@ -2038,10 +2038,17 @@
"Storage overrides but setter does not");
if (ASD->getMaterializeForSetFunc() &&
baseASD->getMaterializeForSetFunc() &&
- baseASD->isSetterAccessibleFrom(ASD->getDeclContext()))
- assert(ASD->getMaterializeForSetFunc()->getOverriddenDecl() ==
- baseASD->getMaterializeForSetFunc() &&
- "Storage override but materializeForSet does not");
+ baseASD->isSetterAccessibleFrom(ASD->getDeclContext())) {
+ if (baseASD->getMaterializeForSetFunc()->hasForcedStaticDispatch()) {
+ assert(ASD->getMaterializeForSetFunc()->getOverriddenDecl() == nullptr
+ && "Forced static dispatch materializeForSet should not be "
+ "overridden");
+ } else {
+ assert(ASD->getMaterializeForSetFunc()->getOverriddenDecl() ==
+ baseASD->getMaterializeForSetFunc() &&
+ "Storage override but materializeForSet does not");
+ }
+ }
} else {
if (ASD->getGetter())
assert(!ASD->getGetter()->getOverriddenDecl() &&
diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp
index c4be751..29cf4b4 100644
--- a/lib/SILGen/SILGenApply.cpp
+++ b/lib/SILGen/SILGenApply.cpp
@@ -697,12 +697,12 @@
}
// Allocate the object.
- return ManagedValue(SGF.B.createAllocRefDynamic(
+ return SGF.emitManagedRValueWithCleanup(
+ SGF.B.createAllocRefDynamic(
loc,
selfMetaObjC.getValue(),
SGF.SGM.getLoweredType(type),
- /*objc=*/true, {}, {}),
- selfMetaObjC.getCleanup());
+ /*objc=*/true, {}, {}));
}
//
diff --git a/lib/Sema/CodeSynthesis.cpp b/lib/Sema/CodeSynthesis.cpp
index 9fb20e1..cc0aa71 100644
--- a/lib/Sema/CodeSynthesis.cpp
+++ b/lib/Sema/CodeSynthesis.cpp
@@ -872,6 +872,7 @@
// materializeForSet either.
auto *baseMFS = baseASD->getMaterializeForSetFunc();
if (baseMFS != nullptr &&
+ !baseMFS->hasForcedStaticDispatch() &&
baseASD->isSetterAccessibleFrom(storage->getDeclContext())) {
materializeForSet->setOverriddenDecl(baseMFS);
}
diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp
index 644cfd2..84f800b 100644
--- a/lib/Sema/TypeCheckConstraints.cpp
+++ b/lib/Sema/TypeCheckConstraints.cpp
@@ -623,7 +623,14 @@
// FIXME: If we reach this point, the program we're being handed is likely
// very broken, but it's still conceivable that this may happen due to
// invalid shadowed declarations.
- // llvm_unreachable("Can't represent lookup result");
+ //
+ // Make sure we emit a diagnostic, since returning an ErrorExpr without
+ // producing one will break things downstream.
+ diagnose(Loc, diag::ambiguous_decl_ref, Name);
+ for (auto Result : Lookup) {
+ auto *Decl = Result.Decl;
+ diagnose(Decl, diag::decl_declared_here, Decl->getFullName());
+ }
return new (Context) ErrorExpr(UDRE->getSourceRange());
}
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 48b9784..546a2a1 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -6532,6 +6532,13 @@
!baseASD->isSetterAccessibleFrom(overridingASD->getDeclContext()))
return;
+ // A materializeForSet for an override of storage with a
+ // forced static dispatch materializeForSet is not itself an
+ // override.
+ if (kind == AccessorKind::IsMaterializeForSet &&
+ baseAccessor->hasForcedStaticDispatch())
+ return;
+
// FIXME: Egregious hack to set an 'override' attribute.
if (!overridingAccessor->getAttrs().hasAttribute<OverrideAttr>()) {
auto loc = overridingASD->getOverrideLoc();
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index 88c5771..2c0b9e4 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -6059,7 +6059,8 @@
/// Infer the attribute tostatic-initialize the Objective-C metadata for the
/// given class, if needed.
-static void inferStaticInitializeObjCMetadata(ClassDecl *classDecl) {
+static void inferStaticInitializeObjCMetadata(TypeChecker &tc,
+ ClassDecl *classDecl) {
// If we already have the attribute, there's nothing to do.
if (classDecl->getAttrs().hasAttribute<StaticInitializeObjCMetadataAttr>())
return;
@@ -6071,6 +6072,22 @@
return;
}
+ // If this class isn't always available on the deployment target, don't
+ // mark it as statically initialized.
+ // FIXME: This is a workaround. The proper solution is for IRGen to
+ // only statically initializae the Objective-C metadata when running on
+ // a new-enough OS.
+ if (auto sourceFile = classDecl->getParentSourceFile()) {
+ AvailabilityContext availableInfo = AvailabilityContext::alwaysAvailable();
+ for (Decl *enclosingDecl = classDecl; enclosingDecl;
+ enclosingDecl = enclosingDecl->getDeclContext()
+ ->getInnermostDeclarationDeclContext()) {
+ if (!tc.isDeclAvailable(enclosingDecl, SourceLoc(), sourceFile,
+ availableInfo))
+ return;
+ }
+ }
+
// Infer @_staticInitializeObjCMetadata.
ASTContext &ctx = classDecl->getASTContext();
classDecl->getAttrs().add(
@@ -6188,7 +6205,7 @@
}
// Infer @_staticInitializeObjCMetadata if needed.
- inferStaticInitializeObjCMetadata(classDecl);
+ inferStaticInitializeObjCMetadata(*this, classDecl);
}
}
}
diff --git a/stdlib/public/runtime/Exclusivity.cpp b/stdlib/public/runtime/Exclusivity.cpp
index a9dbfe3..f363dab 100644
--- a/stdlib/public/runtime/Exclusivity.cpp
+++ b/stdlib/public/runtime/Exclusivity.cpp
@@ -27,12 +27,22 @@
// If we're using Clang, and Clang claims not to support thread_local,
// it must be because we're on a platform that doesn't support it.
// Use pthreads.
-#if __clang__ && !__has_feature(cxx_thread_local)
-#define SWIFT_EXCLUSIVITY_USE_THREADLOCAL 0
-#define SWIFT_EXCLUSIVITY_USE_PTHREAD_SPECIFIC 1
+// Workaround: has_feature(cxx_thread_local) is wrong on two old Apple
+// simulators. clang thinks thread_local works there, but it doesn't.
+#if TARGET_OS_SIMULATOR && !TARGET_RT_64_BIT && \
+ ((TARGET_OS_IOS && __IPHONE_OS_VERSION_MIN_REQUIRED__ < 100000) || \
+ (TARGET_OS_WATCH && __WATCHOS_OS_VERSION_MIN_REQUIRED__ < 30000))
+// 32-bit iOS 9 simulator or 32-bit watchOS 2 simulator - use pthreads
+# define SWIFT_EXCLUSIVITY_USE_THREADLOCAL 0
+# define SWIFT_EXCLUSIVITY_USE_PTHREAD_SPECIFIC 1
+#elif __clang__ && !__has_feature(cxx_thread_local)
+// clang without thread_local support - use pthreads
+# define SWIFT_EXCLUSIVITY_USE_THREADLOCAL 0
+# define SWIFT_EXCLUSIVITY_USE_PTHREAD_SPECIFIC 1
#else
-#define SWIFT_EXCLUSIVITY_USE_THREADLOCAL 1
-#define SWIFT_EXCLUSIVITY_USE_PTHREAD_SPECIFIC 0
+// Use thread_local
+# define SWIFT_EXCLUSIVITY_USE_THREADLOCAL 1
+# define SWIFT_EXCLUSIVITY_USE_PTHREAD_SPECIFIC 0
#endif
#endif
diff --git a/test/Constraints/diag_ambiguities.swift b/test/Constraints/diag_ambiguities.swift
index 04dbf66..2bc8432 100644
--- a/test/Constraints/diag_ambiguities.swift
+++ b/test/Constraints/diag_ambiguities.swift
@@ -1,4 +1,4 @@
-// RUN: %target-typecheck-verify-swift
+// RUN: %target-typecheck-verify-swift -verify-ignore-unknown
func f0(_ i: Int, _ d: Double) {} // expected-note{{found this candidate}}
func f0(_ d: Double, _ i: Int) {} // expected-note{{found this candidate}}
@@ -52,3 +52,21 @@
take([overloaded]) // no error
}
}
+
+// rdar://35116378 - Here the ambiguity is in the pre-check pass; make sure
+// we emit a diagnostic instead of crashing.
+struct Movie {}
+
+protocol P {
+ associatedtype itemType
+ var items: [itemType] { get set }
+}
+
+class MoviesViewController : P {
+ let itemType = [Movie].self // expected-note {{'itemType' declared here}}
+ var items: [Movie] = [Movie]()
+
+ func loadData() {
+ _ = itemType // expected-error {{ambiguous use of 'itemType'}}
+ }
+}
diff --git a/test/Interpreter/objc_protocols.swift b/test/Interpreter/objc_protocols.swift
new file mode 100644
index 0000000..f802024
--- /dev/null
+++ b/test/Interpreter/objc_protocols.swift
@@ -0,0 +1,26 @@
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+// REQUIRES: objc_interop
+
+import StdlibUnittest
+import Foundation
+
+@objc protocol Horse {
+ init()
+}
+
+class Pony : Horse {
+ let x = LifetimeTracked(0)
+
+ required init() {}
+}
+
+var ObjCProtocolsTest = TestSuite("ObjCProtocols")
+
+ObjCProtocolsTest.test("InitRequirement") {
+ let t: Horse.Type = Pony.self
+
+ _ = t.init()
+}
+
+runAllTests()
diff --git a/test/SILGen/objc_protocols.swift b/test/SILGen/objc_protocols.swift
index f29c010..9db52f5 100644
--- a/test/SILGen/objc_protocols.swift
+++ b/test/SILGen/objc_protocols.swift
@@ -267,8 +267,7 @@
// CHECK: [[ARCHETYPE_META_OBJC:%[0-9]+]] = thick_to_objc_metatype [[ARCHETYPE_META]] : $@thick (@opened([[N]]) Initializable).Type to $@objc_metatype (@opened([[N]]) Initializable).Type
// CHECK: [[I2_ALLOC:%[0-9]+]] = alloc_ref_dynamic [objc] [[ARCHETYPE_META_OBJC]] : $@objc_metatype (@opened([[N]]) Initializable).Type, $@opened([[N]]) Initializable
// CHECK: [[INIT_WITNESS:%[0-9]+]] = witness_method [volatile] $@opened([[N]]) Initializable, #Initializable.init!initializer.1.foreign : {{.*}}, [[ARCHETYPE_META]]{{.*}} : $@convention(objc_method) <τ_0_0 where τ_0_0 : Initializable> (Int, @owned τ_0_0) -> @owned τ_0_0
- // CHECK: [[I2_COPY:%.*]] = copy_value [[I2_ALLOC]]
- // CHECK: [[I2:%[0-9]+]] = apply [[INIT_WITNESS]]<@opened([[N]]) Initializable>([[I]], [[I2_COPY]]) : $@convention(objc_method) <τ_0_0 where τ_0_0 : Initializable> (Int, @owned τ_0_0) -> @owned τ_0_0
+ // CHECK: [[I2:%[0-9]+]] = apply [[INIT_WITNESS]]<@opened([[N]]) Initializable>([[I]], [[I2_ALLOC]]) : $@convention(objc_method) <τ_0_0 where τ_0_0 : Initializable> (Int, @owned τ_0_0) -> @owned τ_0_0
// CHECK: [[I2_EXIST_CONTAINER:%[0-9]+]] = init_existential_ref [[I2]] : $@opened([[N]]) Initializable : $@opened([[N]]) Initializable, $Initializable
// CHECK: store [[I2_EXIST_CONTAINER]] to [init] [[PB]] : $*Initializable
// CHECK: [[READ:%.*]] = begin_access [read] [unknown] [[PB]] : $*Initializable
diff --git a/test/decl/protocol/conforms/nscoding_availability_osx.swift b/test/decl/protocol/conforms/nscoding_availability_osx.swift
new file mode 100644
index 0000000..b9720cd
--- /dev/null
+++ b/test/decl/protocol/conforms/nscoding_availability_osx.swift
@@ -0,0 +1,22 @@
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -parse-as-library -swift-version 4 %s -target x86_64-apple-macosx10.11 -verify
+
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -parse-as-library -swift-version 4 %s -target x86_64-apple-macosx10.11 -dump-ast 2> %t.ast
+// RUN: %FileCheck %s < %t.ast
+
+// REQUIRES: objc_interop
+// REQUIRES: OS=macosx
+
+import Foundation
+
+// Nested classes that aren't available in our deployment target.
+@available(OSX 10.12, *)
+class CodingI : NSObject, NSCoding {
+ required init(coder: NSCoder) { }
+ func encode(coder: NSCoder) { }
+}
+
+@available(OSX 10.12, *)
+class OuterCodingJ {
+ // CHECK-NOT: class_decl "NestedJ"{{.*}}@_staticInitializeObjCMetadata
+ class NestedJ : CodingI { }
+}
diff --git a/test/multifile/synthesized-accessors/materialize-for-set-1/Inputs/counter.h b/test/multifile/synthesized-accessors/materialize-for-set-1/Inputs/counter.h
new file mode 100644
index 0000000..930dc7b
--- /dev/null
+++ b/test/multifile/synthesized-accessors/materialize-for-set-1/Inputs/counter.h
@@ -0,0 +1,5 @@
+#import <Foundation/Foundation.h>
+
+@interface Counter : NSObject
+@property(readwrite) int value;
+@end
diff --git a/test/multifile/synthesized-accessors/materialize-for-set-1/Inputs/library.swift b/test/multifile/synthesized-accessors/materialize-for-set-1/Inputs/library.swift
new file mode 100644
index 0000000..9211695
--- /dev/null
+++ b/test/multifile/synthesized-accessors/materialize-for-set-1/Inputs/library.swift
@@ -0,0 +1,12 @@
+import Foundation
+import CounterFramework
+
+public protocol CounterProtocol {
+ var value: Int32 { get set }
+}
+
+extension Counter : CounterProtocol {}
+
+open class MyCounter : Counter {
+ open override var value: Int32 { didSet { } }
+}
diff --git a/test/multifile/synthesized-accessors/materialize-for-set-1/Inputs/module.map b/test/multifile/synthesized-accessors/materialize-for-set-1/Inputs/module.map
new file mode 100644
index 0000000..ac68c70
--- /dev/null
+++ b/test/multifile/synthesized-accessors/materialize-for-set-1/Inputs/module.map
@@ -0,0 +1,4 @@
+module CounterFramework {
+ header "counter.h"
+ export *
+}
diff --git a/test/multifile/synthesized-accessors/materialize-for-set-1/main.swift b/test/multifile/synthesized-accessors/materialize-for-set-1/main.swift
new file mode 100644
index 0000000..7944043
--- /dev/null
+++ b/test/multifile/synthesized-accessors/materialize-for-set-1/main.swift
@@ -0,0 +1,17 @@
+// RUN: %empty-directory(%t)
+
+// RUN: mkdir -p %t/onone %t/wmo
+// RUN: %target-build-swift -emit-module -emit-module-path %t/onone/library.swiftmodule -I %S/Inputs/ -module-name=library %S/Inputs/library.swift
+// RUN: %target-build-swift %S/main.swift -I %S/Inputs/ -I %t/onone/ -emit-ir > /dev/null
+
+// RUN: %target-build-swift -emit-module -emit-module-path %t/wmo/library.swiftmodule -I %S/Inputs/ -module-name=library -wmo %S/Inputs/library.swift
+// RUN: %target-build-swift %S/main.swift -I %S/Inputs/ -I %t/wmo/ -emit-ir > /dev/null
+
+// REQUIRES: objc_interop
+
+import Foundation
+import library
+
+class CustomCounter : MyCounter {
+ override var value: Int32 { didSet { } }
+}
diff --git a/test/multifile/synthesized-accessors/materialize-for-set-2/Inputs/counter.h b/test/multifile/synthesized-accessors/materialize-for-set-2/Inputs/counter.h
new file mode 100644
index 0000000..930dc7b
--- /dev/null
+++ b/test/multifile/synthesized-accessors/materialize-for-set-2/Inputs/counter.h
@@ -0,0 +1,5 @@
+#import <Foundation/Foundation.h>
+
+@interface Counter : NSObject
+@property(readwrite) int value;
+@end
diff --git a/test/multifile/synthesized-accessors/materialize-for-set-2/Inputs/library1.swift b/test/multifile/synthesized-accessors/materialize-for-set-2/Inputs/library1.swift
new file mode 100644
index 0000000..7a2041c
--- /dev/null
+++ b/test/multifile/synthesized-accessors/materialize-for-set-2/Inputs/library1.swift
@@ -0,0 +1,8 @@
+import Foundation
+import CounterFramework
+
+public protocol CounterProtocol {
+ var value: Int32 { get set }
+}
+
+extension Counter : CounterProtocol {}
diff --git a/test/multifile/synthesized-accessors/materialize-for-set-2/Inputs/library2.swift b/test/multifile/synthesized-accessors/materialize-for-set-2/Inputs/library2.swift
new file mode 100644
index 0000000..7ac2f8c
--- /dev/null
+++ b/test/multifile/synthesized-accessors/materialize-for-set-2/Inputs/library2.swift
@@ -0,0 +1,6 @@
+import Foundation
+import CounterFramework
+
+open class MyCounter : Counter {
+ open override var value: Int32 { didSet { } }
+}
diff --git a/test/multifile/synthesized-accessors/materialize-for-set-2/Inputs/module.map b/test/multifile/synthesized-accessors/materialize-for-set-2/Inputs/module.map
new file mode 100644
index 0000000..ac68c70
--- /dev/null
+++ b/test/multifile/synthesized-accessors/materialize-for-set-2/Inputs/module.map
@@ -0,0 +1,4 @@
+module CounterFramework {
+ header "counter.h"
+ export *
+}
diff --git a/test/multifile/synthesized-accessors/materialize-for-set-2/main.swift b/test/multifile/synthesized-accessors/materialize-for-set-2/main.swift
new file mode 100644
index 0000000..a9d3ddc
--- /dev/null
+++ b/test/multifile/synthesized-accessors/materialize-for-set-2/main.swift
@@ -0,0 +1,17 @@
+// RUN: %empty-directory(%t)
+
+// RUN: mkdir -p %t/onone %t/wmo
+// RUN: %target-build-swift -emit-module -emit-module-path %t/onone/library.swiftmodule -I %S/Inputs/ -module-name=library %S/Inputs/library1.swift %S/Inputs/library2.swift
+// RUN: %target-build-swift %S/main.swift -I %S/Inputs/ -I %t/onone/ -emit-ir > /dev/null
+
+// RUN: %target-build-swift -emit-module -emit-module-path %t/wmo/library.swiftmodule -I %S/Inputs/ -module-name=library -wmo %S/Inputs/library1.swift %S/Inputs/library2.swift
+// RUN: %target-build-swift %S/main.swift -I %S/Inputs/ -I %t/wmo/ -emit-ir > /dev/null
+
+// REQUIRES: objc_interop
+
+import Foundation
+import library
+
+class CustomCounter : MyCounter {
+ override var value: Int32 { didSet { } }
+}