Merge remote-tracking branch 'origin/swift-3.1-branch' into stable

* origin/swift-3.1-branch:
  [Profile] Update testcase for r283948 (NFC)
  [Coverage] Support for C++17 if initializers
  [Coverage] Support for C++17 switch initializers
  [ubsan] Disable bounds-check for flexible array ivars
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index e2943b3..a38dc22 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -708,6 +708,8 @@
           DeclContext::decl_iterator(const_cast<FieldDecl *>(FD)));
       return ++FI == FD->getParent()->field_end();
     }
+  } else if (const auto *IRE = dyn_cast<ObjCIvarRefExpr>(E)) {
+    return IRE->getDecl()->getNextIvar() == nullptr;
   }
 
   return false;
diff --git a/lib/CodeGen/CodeGenPGO.cpp b/lib/CodeGen/CodeGenPGO.cpp
index 4eefdd7..c6c3fa4 100644
--- a/lib/CodeGen/CodeGenPGO.cpp
+++ b/lib/CodeGen/CodeGenPGO.cpp
@@ -458,6 +458,8 @@
 
   void VisitSwitchStmt(const SwitchStmt *S) {
     RecordStmtCount(S);
+    if (S->getInit())
+      Visit(S->getInit());
     Visit(S->getCond());
     CurrentCount = 0;
     BreakContinueStack.push_back(BreakContinue());
@@ -488,6 +490,8 @@
   void VisitIfStmt(const IfStmt *S) {
     RecordStmtCount(S);
     uint64_t ParentCount = CurrentCount;
+    if (S->getInit())
+      Visit(S->getInit());
     Visit(S->getCond());
 
     // Counter tracks the "then" part of an if statement. The count for
diff --git a/lib/CodeGen/CoverageMappingGen.cpp b/lib/CodeGen/CoverageMappingGen.cpp
index 0e51658..66b70e0 100644
--- a/lib/CodeGen/CoverageMappingGen.cpp
+++ b/lib/CodeGen/CoverageMappingGen.cpp
@@ -813,6 +813,8 @@
 
   void VisitSwitchStmt(const SwitchStmt *S) {
     extendRegion(S);
+    if (S->getInit())
+      Visit(S->getInit());
     Visit(S->getCond());
 
     BreakContinueStack.push_back(BreakContinue());
@@ -873,6 +875,9 @@
 
   void VisitIfStmt(const IfStmt *S) {
     extendRegion(S);
+    if (S->getInit())
+      Visit(S->getInit());
+
     // Extend into the condition before we propagate through it below - this is
     // needed to handle macros that generate the "if" but not the condition.
     extendRegion(S->getCond());
diff --git a/test/CodeGenObjC/ubsan-array-bounds.m b/test/CodeGenObjC/ubsan-array-bounds.m
new file mode 100644
index 0000000..38d1eb3
--- /dev/null
+++ b/test/CodeGenObjC/ubsan-array-bounds.m
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -x objective-c -emit-llvm -triple x86_64-apple-macosx10.10.0 -Wno-objc-root-class -fsanitize=array-bounds %s -o - | FileCheck %s
+
+@interface FlexibleArray1 {
+@public
+  char chars[0];
+}
+@end
+@implementation FlexibleArray1
+@end
+
+// CHECK-LABEL: test_FlexibleArray1
+char test_FlexibleArray1(FlexibleArray1 *FA1) {
+  // CHECK-NOT: !nosanitize
+  return FA1->chars[1];
+  // CHECK: }
+}
+
+@interface FlexibleArray2 {
+@public
+  char chars[0];
+}
+@end
+@implementation FlexibleArray2 {
+@public
+  char chars2[0];
+}
+@end
+
+// CHECK-LABEL: test_FlexibleArray2_1
+char test_FlexibleArray2_1(FlexibleArray2 *FA2) {
+  // CHECK: !nosanitize
+  return FA2->chars[1];
+  // CHECK: }
+}
+
+// CHECK-LABEL: test_FlexibleArray2_2
+char test_FlexibleArray2_2(FlexibleArray2 *FA2) {
+  // CHECK-NOT: !nosanitize
+  return FA2->chars2[1];
+  // CHECK: }
+}
+
+@interface FlexibleArray3 {
+@public
+  char chars[0];
+}
+@end
+@implementation FlexibleArray3 {
+@public
+  int i;
+}
+@end
+
+// CHECK-LABEL: test_FlexibleArray3
+char test_FlexibleArray3(FlexibleArray3 *FA3) {
+  // CHECK: !nosanitize
+  return FA3->chars[1];
+  // CHECK: }
+}
diff --git a/test/CoverageMapping/if.c b/test/CoverageMapping/if.cpp
similarity index 70%
rename from test/CoverageMapping/if.c
rename to test/CoverageMapping/if.cpp
index 69544f6..95e6d8a 100644
--- a/test/CoverageMapping/if.c
+++ b/test/CoverageMapping/if.cpp
@@ -1,5 +1,16 @@
-// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name if.c %s | FileCheck %s
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -std=c++1z -triple %itanium_abi_triple -main-file-name if.cpp %s | FileCheck %s
 
+int nop() { return 0; }
+
+// CHECK-LABEL: _Z3foov:
+void foo() {                    // CHECK-NEXT: [[@LINE]]:12 -> [[@LINE+5]]:2 = #0
+  if (int j = true ? nop()      // CHECK-NEXT: [[@LINE]]:22 -> [[@LINE]]:27 = #2
+                   : nop();     // CHECK-NEXT: [[@LINE]]:22 -> [[@LINE]]:27 = (#0 - #2)
+      j)                        // CHECK-NEXT: [[@LINE]]:7 -> [[@LINE]]:8 = #0
+    ++j;                        // CHECK-NEXT: [[@LINE]]:5 -> [[@LINE]]:8 = #1
+}
+
+// CHECK-LABEL: main:
 int main() {                    // CHECK: File 0, [[@LINE]]:12 -> {{[0-9]+}}:2 = #0
   int i = 0;
                                 // CHECK-NEXT: File 0, [[@LINE+1]]:6 -> [[@LINE+1]]:12 = #0
diff --git a/test/CoverageMapping/switch.c b/test/CoverageMapping/switch.cpp
similarity index 81%
rename from test/CoverageMapping/switch.c
rename to test/CoverageMapping/switch.cpp
index 9463eb3..312f26c 100644
--- a/test/CoverageMapping/switch.c
+++ b/test/CoverageMapping/switch.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name switch.c %s | FileCheck %s
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -std=c++1z -triple %itanium_abi_triple -main-file-name switch.cpp %s | FileCheck %s
+
                     // CHECK: foo
 void foo(int i) {   // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+8]]:2 = #0
   switch(i) {
@@ -10,7 +11,7 @@
   int x = 0;        // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:2 = #1
 }
 
-void nop() {}
+int nop() { return 0; }
 
                     // CHECK: bar
 void bar(int i) {   // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+20]]:2 = #0
@@ -35,8 +36,16 @@
   nop();            // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:2 = #6
 }
 
+                    // CHECK: baz
+void baz() {        // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+5]]:2 = #0
+  switch (int i = true ? nop()  // CHECK-NEXT: [[@LINE]]:26 -> [[@LINE]]:31 = #2
+                       : nop(); // CHECK-NEXT: [[@LINE]]:26 -> [[@LINE]]:31 = (#0 - #2)
+          i) {}
+  nop();            // CHECK-NEXT: [[@LINE]]:3 -> [[@LINE+1]]:2 = #1
+}
+
                     // CHECK-NEXT: main
-int main() {        // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+34]]:2 = #0
+int main() {        // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+35]]:2 = #0
   int i = 0;
   switch(i) {
   case 0:           // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+7]]:10 = #2
@@ -48,7 +57,7 @@
   default:          // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:10 = #4
     break;
   }
-  switch(i) {       // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+22]]:2 = #1
+  switch(i) {       // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+23]]:2 = #1
   case 0:           // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+6]]:10 = #6
     i = 1;
     break;
@@ -58,7 +67,7 @@
     break;
   }
 
-  switch(i) {       // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+12]]:2 = #5
+  switch(i) {       // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+13]]:2 = #5
   case 1:           // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+5]]:11 = #10
   case 2:           // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+4]]:11 = (#10 + #11)
     i = 11;
@@ -67,7 +76,8 @@
     i = 99;
   }
 
-  foo(1);           // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:11 = #9
+  foo(1);           // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+3]]:11 = #9
   bar(1);
+  baz();
   return 0;
 }
diff --git a/test/Profile/c-linkage-available_externally.c b/test/Profile/c-linkage-available_externally.c
index 8907839..5ac777b 100644
--- a/test/Profile/c-linkage-available_externally.c
+++ b/test/Profile/c-linkage-available_externally.c
@@ -3,7 +3,7 @@
 // RUN: %clang_cc1 -O2 -triple x86_64-apple-macosx10.9 -main-file-name c-linkage-available_externally.c %s -o - -emit-llvm -fprofile-instrument=clang | FileCheck %s
 
 // CHECK: @__profc_foo = linkonce_odr hidden global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
-// CHECK: @__profd_foo = linkonce_odr hidden global {{.*}} i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc_foo, i32 0, i32 0){{.*}}, section "__DATA,__llvm_prf_data", align 8
+// CHECK: @__profd_foo = linkonce_odr hidden global {{.*}} i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc_foo, i32 0, i32 0){{.*}}, section "__DATA,__llvm_prf_data,regular,live_support", align 8
 inline int foo(void) { return 1; }
 
 int main(void) {
diff --git a/test/Profile/cxx-stmt-initializers.cpp b/test/Profile/cxx-stmt-initializers.cpp
new file mode 100644
index 0000000..44f7edd
--- /dev/null
+++ b/test/Profile/cxx-stmt-initializers.cpp
@@ -0,0 +1,29 @@
+// Tests for instrumentation of C++17 statement initializers
+
+// RUN: %clang_cc1 -x c++ %s -triple %itanium_abi_triple -main-file-name cxx-stmt-initializers.cpp -std=c++1z -o - -emit-llvm -fprofile-instrument=clang > %tgen
+// RUN: FileCheck --input-file=%tgen -check-prefix=CHECK -check-prefix=PGOGEN %s
+
+// PGOGEN: @[[SIC:__profc__Z11switch_initv]] = private global [3 x i64] zeroinitializer
+// PGOGEN: @[[IIC:__profc__Z7if_initv]] = private global [3 x i64] zeroinitializer
+
+// Note: We expect counters for the function entry block, the condition in the
+// switch initializer, and the switch successor block.
+//
+// CHECK-LABEL: define {{.*}}void @_Z11switch_initv()
+// PGOGEN: store {{.*}} @[[SIC]], i64 0, i64 0
+void switch_init() {
+  switch (int i = true ? 0 : 1; i) {}
+  // PGOGEN: store {{.*}} @[[SIC]], i64 0, i64 2
+  // PGOGEN: store {{.*}} @[[SIC]], i64 0, i64 1
+}
+
+// Note: We expect counters for the function entry block, the condition in the
+// if initializer, and the if successor block.
+//
+// CHECK-LABEL: define {{.*}}void @_Z7if_initv()
+// PGOGEN: store {{.*}} @[[IIC]], i64 0, i64 0
+void if_init() {
+  if (int i = true ? 0 : 1; i) {}
+  // PGOGEN: store {{.*}} @[[IIC]], i64 0, i64 2
+  // PGOGEN: store {{.*}} @[[IIC]], i64 0, i64 1
+}