Merge remote-tracking branch 'origin/swift-4.0-branch' into stable
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index 2e41bc2..8c2cb30 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -1767,6 +1767,7 @@
if (TypeSourceInfo *TSI = D->getTypeAsWritten()) \
TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); \
\
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); \
if (!getDerived().shouldVisitTemplateInstantiations() && \
D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) \
/* Returning from here skips traversing the \
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 72dc04e..4553b8d 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -3334,6 +3334,14 @@
unsigned Idx = LeftToRight ? I : E - I - 1;
CallExpr::const_arg_iterator Arg = ArgRange.begin() + Idx;
if (!LeftToRight) MaybeEmitImplicitObjectSize(Idx, *Arg);
+ // If *Arg is an ObjCIndirectCopyRestoreExpr, check that either the types of
+ // the argument and parameter match or the objc method is parameterized.
+ assert((!isa<ObjCIndirectCopyRestoreExpr>(*Arg) ||
+ getContext().hasSameUnqualifiedType((*Arg)->getType(),
+ ArgTypes[Idx]) ||
+ (isa<ObjCMethodDecl>(AC.getDecl()) &&
+ isObjCMethodWithTypeParams(cast<ObjCMethodDecl>(AC.getDecl())))) &&
+ "Argument and parameter types don't match");
EmitCallArg(Args, *Arg, ArgTypes[Idx]);
EmitNonNullArgCheck(Args.back().RV, ArgTypes[Idx], (*Arg)->getExprLoc(),
AC, ParamsToSkip + Idx);
@@ -3385,7 +3393,6 @@
if (const ObjCIndirectCopyRestoreExpr *CRE
= dyn_cast<ObjCIndirectCopyRestoreExpr>(E)) {
assert(getLangOpts().ObjCAutoRefCount);
- assert(getContext().hasSameUnqualifiedType(E->getType(), type));
return emitWritebackArg(*this, args, CRE);
}
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index d01e31f..68d134c 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -37,6 +37,7 @@
#include "llvm/Support/raw_ostream.h"
#include <cstdlib> // ::getenv
#include <system_error>
+#include <sys/utsname.h>
using namespace clang::driver;
using namespace clang::driver::toolchains;
@@ -510,6 +511,56 @@
}
}
+// Clang-900 specific change that's cherry-picked from the LLVM change r307372:
+static std::string getOSVersion() {
+ struct utsname info;
+
+ if (uname(&info))
+ return "";
+
+ return info.release;
+}
+
+static std::string updateTripleOSVersion(std::string TargetTripleString) {
+ // On darwin, we want to update the version to match that of the target.
+ std::string::size_type DarwinDashIdx = TargetTripleString.find("-darwin");
+ if (DarwinDashIdx != std::string::npos) {
+ TargetTripleString.resize(DarwinDashIdx + strlen("-darwin"));
+ TargetTripleString += getOSVersion();
+ return TargetTripleString;
+ }
+ std::string::size_type MacOSDashIdx = TargetTripleString.find("-macos");
+ if (MacOSDashIdx != std::string::npos) {
+ TargetTripleString.resize(MacOSDashIdx);
+ // Reset the OS to darwin as the OS version from `uname` doesn't use the
+ // macOS version scheme.
+ TargetTripleString += "-darwin";
+ TargetTripleString += getOSVersion();
+ }
+ return TargetTripleString;
+}
+
+/// Returns the most appropriate macOS target version for the current process.
+///
+/// If the macOS SDK version is the same or earlier than the system version,
+/// then the SDK version is returned. Otherwise the system version is returned.
+static std::string getSystemOrSDKMacOSVersion(StringRef MacOSSDKVersion) {
+ unsigned Major, Minor, Micro;
+ llvm::Triple SystemTriple(updateTripleOSVersion(llvm::sys::getProcessTriple()));
+ if (!SystemTriple.isMacOSX())
+ return MacOSSDKVersion;
+ SystemTriple.getMacOSXVersion(Major, Minor, Micro);
+ VersionTuple SystemVersion(Major, Minor, Micro);
+ bool HadExtra;
+ if (!Driver::GetReleaseVersion(MacOSSDKVersion, Major, Minor, Micro,
+ HadExtra))
+ return MacOSSDKVersion;
+ VersionTuple SDKVersion(Major, Minor, Micro);
+ if (SDKVersion > SystemVersion)
+ return SystemVersion.getAsString();
+ return MacOSSDKVersion;
+}
+
void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
const OptTable &Opts = getDriver().getOpts();
@@ -602,7 +653,7 @@
SDK.startswith("iPhoneSimulator"))
iOSTarget = Version;
else if (SDK.startswith("MacOSX"))
- OSXTarget = Version;
+ OSXTarget = getSystemOrSDKMacOSVersion(Version);
else if (SDK.startswith("WatchOS") ||
SDK.startswith("WatchSimulator"))
WatchOSTarget = Version;
diff --git a/lib/Frontend/SerializedDiagnosticReader.cpp b/lib/Frontend/SerializedDiagnosticReader.cpp
index c4461d4..81a483a 100644
--- a/lib/Frontend/SerializedDiagnosticReader.cpp
+++ b/lib/Frontend/SerializedDiagnosticReader.cpp
@@ -27,6 +27,9 @@
llvm::BitstreamCursor Stream(**Buffer);
Optional<llvm::BitstreamBlockInfo> BlockInfo;
+ if (Stream.AtEndOfStream())
+ return SDError::InvalidSignature;
+
// Sniff for the signature.
if (Stream.Read(8) != 'D' ||
Stream.Read(8) != 'I' ||
diff --git a/test/CodeGenObjC/parameterized_classes.m b/test/CodeGenObjC/parameterized_classes.m
index 8fe5c52..34aca35 100644
--- a/test/CodeGenObjC/parameterized_classes.m
+++ b/test/CodeGenObjC/parameterized_classes.m
@@ -96,3 +96,31 @@
_destination = a;
}
@end
+
+// CHECK-LABEL: define internal void @"\01-[C0 foo1]"(
+// CHECK: {{.*}} = alloca
+// CHECK: {{.*}} = alloca
+// CHECK: %[[D:.*]] = alloca %[[TY:.*]]*
+// CHECK: %[[TEMP:.*]] = alloca %[[TY]]*
+// CHECK: %[[V4:.*]] = load %[[TY]]*, %[[TY]]** %[[D]]
+// CHECK: store %[[TY]]* %[[V4]], %[[TY]]** %[[TEMP]]
+// CHECK: %[[V7:.*]] = bitcast %[[TY]]** %[[TEMP]] to i8**
+// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8**)*)(i8* %{{.*}}, i8* %{{.*}}, i8** %[[V7]])
+
+@interface P0<ObjectType> : NSObject
+- (void)m0:(ObjectType *)first;
+@end
+
+@interface C0 : NSObject
+-(void)foo1;
+@end
+
+@implementation C0 {
+ P0<NSString *> *x;
+}
+
+-(void)foo1 {
+ NSString *d;
+ [x m0:&d];
+}
+@end
diff --git a/test/Driver/darwin-sdk-vs-os-version.c b/test/Driver/darwin-sdk-vs-os-version.c
new file mode 100644
index 0000000..391f4d5
--- /dev/null
+++ b/test/Driver/darwin-sdk-vs-os-version.c
@@ -0,0 +1,10 @@
+// REQUIRES: system-darwin
+
+// Ensure that we never pick a version that's based on the SDK that's newer than
+// the system version:
+// RUN: rm -rf %t/SDKs/MacOSX10.99.99.sdk
+// RUN: mkdir -p %t/SDKs/MacOSX10.99.99.sdk
+// RUN: %clang -target x86_64-apple-darwin -isysroot %t/SDKs/MacOSX10.99.99.sdk %s -### 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-MACOSX-SYSTEM-VERSION %s
+
+// CHECK-MACOSX-SYSTEM-VERSION-NOT: 10.99.99"
diff --git a/test/Index/Inputs/empty.dia b/test/Index/Inputs/empty.dia
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Index/Inputs/empty.dia
diff --git a/test/Index/read-empty-diags.test b/test/Index/read-empty-diags.test
new file mode 100644
index 0000000..cef751c
--- /dev/null
+++ b/test/Index/read-empty-diags.test
@@ -0,0 +1,2 @@
+// RUN: not c-index-test -read-diagnostics %S/Inputs/empty.dia 2>&1 | FileCheck %s
+// CHECK: Trouble deserializing file (Invalid File): Invalid diagnostics signature
diff --git a/unittests/Tooling/RecursiveASTVisitorTest.cpp b/unittests/Tooling/RecursiveASTVisitorTest.cpp
index 269bdbb..887330c 100644
--- a/unittests/Tooling/RecursiveASTVisitorTest.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTest.cpp
@@ -158,4 +158,62 @@
"static int k = f();\n"));
}
+// Check to ensure that nested name specifiers are visited.
+class NestedNameSpecifiersVisitor
+ : public ExpectedLocationVisitor<NestedNameSpecifiersVisitor> {
+public:
+ bool VisitRecordTypeLoc(RecordTypeLoc RTL) {
+ if (!RTL)
+ return true;
+ Match(RTL.getDecl()->getName(), RTL.getNameLoc());
+ return true;
+ }
+
+ bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
+ if (!NNS)
+ return true;
+ if (const NamespaceDecl *ND =
+ NNS.getNestedNameSpecifier()->getAsNamespace())
+ Match(ND->getName(), NNS.getLocalBeginLoc());
+ return ExpectedLocationVisitor::TraverseNestedNameSpecifierLoc(NNS);
+ }
+};
+
+TEST(RecursiveASTVisitor,
+ NestedNameSpecifiersForTemplateSpecializationsAreVisited) {
+ StringRef Source = R"(
+namespace ns {
+struct Outer {
+ template<typename T, typename U>
+ struct Nested { };
+
+ template<typename T>
+ static T x;
+};
+}
+
+template<>
+struct ns::Outer::Nested<int, int>;
+
+template<>
+struct ns::Outer::Nested<int, int> { };
+
+template<typename T>
+struct ns::Outer::Nested<int, T> { };
+
+template<>
+int ns::Outer::x<int> = 0;
+)";
+ NestedNameSpecifiersVisitor Visitor;
+ Visitor.ExpectMatch("ns", 13, 8);
+ Visitor.ExpectMatch("ns", 16, 8);
+ Visitor.ExpectMatch("ns", 19, 8);
+ Visitor.ExpectMatch("ns", 22, 5);
+ Visitor.ExpectMatch("Outer", 13, 12);
+ Visitor.ExpectMatch("Outer", 16, 12);
+ Visitor.ExpectMatch("Outer", 19, 12);
+ Visitor.ExpectMatch("Outer", 22, 9);
+ EXPECT_TRUE(Visitor.runOver(Source, NestedNameSpecifiersVisitor::Lang_CXX14));
+}
+
} // end anonymous namespace