Merge remote-tracking branch 'origin/swift-4.0-branch' into stable
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 00c9785..205b65e 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -532,6 +532,15 @@
          SanOpts.has(SanitizerKind::Vptr);
 }
 
+/// Check if a runtime null check for \p Ptr can be omitted.
+static bool canOmitPointerNullCheck(llvm::Value *Ptr) {
+  // Note: do not perform any constant-folding in this function. That is best
+  // left to the IR builder.
+
+  // Pointers to alloca'd memory are non-null.
+  return isa<llvm::AllocaInst>(Ptr->stripPointerCastsNoFollowAliases());
+}
+
 void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
                                     llvm::Value *Ptr, QualType Ty,
                                     CharUnits Alignment,
@@ -553,19 +562,28 @@
   bool AllowNullPointers = TCK == TCK_DowncastPointer || TCK == TCK_Upcast ||
                            TCK == TCK_UpcastToVirtualBase;
   if ((SanOpts.has(SanitizerKind::Null) || AllowNullPointers) &&
-      !SkippedChecks.has(SanitizerKind::Null)) {
+      !SkippedChecks.has(SanitizerKind::Null) &&
+      !canOmitPointerNullCheck(Ptr)) {
     // The glvalue must not be an empty glvalue.
     llvm::Value *IsNonNull = Builder.CreateIsNotNull(Ptr);
 
-    if (AllowNullPointers) {
-      // When performing pointer casts, it's OK if the value is null.
-      // Skip the remaining checks in that case.
-      Done = createBasicBlock("null");
-      llvm::BasicBlock *Rest = createBasicBlock("not.null");
-      Builder.CreateCondBr(IsNonNull, Rest, Done);
-      EmitBlock(Rest);
-    } else {
-      Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::Null));
+    // The IR builder can constant-fold the null check if the pointer points to
+    // a constant.
+    bool PtrIsNonNull =
+        IsNonNull == llvm::ConstantInt::getTrue(getLLVMContext());
+
+    // Skip the null check if the pointer is known to be non-null.
+    if (!PtrIsNonNull) {
+      if (AllowNullPointers) {
+        // When performing pointer casts, it's OK if the value is null.
+        // Skip the remaining checks in that case.
+        Done = createBasicBlock("null");
+        llvm::BasicBlock *Rest = createBasicBlock("not.null");
+        Builder.CreateCondBr(IsNonNull, Rest, Done);
+        EmitBlock(Rest);
+      } else {
+        Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::Null));
+      }
     }
   }
 
diff --git a/test/CodeGenCXX/ubsan-suppress-checks.cpp b/test/CodeGenCXX/ubsan-suppress-checks.cpp
index 8ec9455..d0e7b32 100644
--- a/test/CodeGenCXX/ubsan-suppress-checks.cpp
+++ b/test/CodeGenCXX/ubsan-suppress-checks.cpp
@@ -2,6 +2,20 @@
 // RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=null | FileCheck %s --check-prefixes=CHECK,NULL
 // RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=alignment,null -DCHECK_LAMBDA | FileCheck %s --check-prefixes=LAMBDA
 
+// CHECK-LABEL: define void @_Z22load_non_null_pointersv
+void load_non_null_pointers() {
+  int var;
+  var = *&var;
+
+  int arr[1];
+  arr[0] = arr[0];
+
+  char c = "foo"[0];
+
+  // CHECK-NOT: icmp ne {{.*}}, null, !nosanitize
+  // CHECK: ret void
+}
+
 struct A {
   int foo;
 
@@ -29,8 +43,7 @@
     };
     f();
 
-    // LAMBDA: icmp ne %class.anon* %[[FUNCVAR:.*]], null, !nosanitize
-    // LAMBDA: %[[LAMBDAINT:[0-9]+]] = ptrtoint %class.anon* %[[FUNCVAR]] to i64, !nosanitize
+    // LAMBDA: %[[LAMBDAINT:[0-9]+]] = ptrtoint %class.anon* %[[FUNCVAR:.*]] to i64, !nosanitize
     // LAMBDA: and i64 %[[LAMBDAINT]], 7, !nosanitize
     // LAMBDA: call void @__ubsan_handle_type_mismatch
 
@@ -127,8 +140,8 @@
 struct B {
   operator A*() const { return nullptr; }
 
-  // CHECK-LABEL: define linkonce_odr i32 @_ZN1B11load_memberEv
-  static int load_member() {
+  // CHECK-LABEL: define linkonce_odr i32 @_ZN1B11load_memberEPS_
+  static int load_member(B *bp) {
     // Check &b before converting it to an A*.
     // CHECK: call void @__ubsan_handle_type_mismatch
     //
@@ -136,8 +149,7 @@
     // NULL: call void @__ubsan_handle_type_mismatch
     //
     // CHECK-NOT: call void @__ubsan_handle_type_mismatch
-    B b;
-    return static_cast<A *>(b)->load_member();
+    return static_cast<A *>(*bp)->load_member();
     // CHECK: ret i32
   }
 };
@@ -210,7 +222,7 @@
   A::call_through_reference(*a);
   A::call_through_pointer(a);
 
-  B::load_member();
+  B::load_member(nullptr);
 
   Base *b = new Derived;
   b->load_member_1();
@@ -218,4 +230,6 @@
   Derived *d;
   d->load_member_2();
   d->load_member_3();
+
+  load_non_null_pointers();
 }