diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index e457de4..5c891be 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -15,6 +15,7 @@
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
+#include "clang/AST/ExprOpenMP.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Sema/Designator.h"
@@ -6348,18 +6349,28 @@
   RK_StdInitializerList,
 };
 
-/// A temporary or local variable.
-using Local = llvm::PointerUnion<MaterializeTemporaryExpr*, ValueDecl*>;
+/// A temporary or local variable. This will be one of:
+///  * A MaterializeTemporaryExpr.
+///  * A DeclRefExpr whose declaration is a local.
+///  * An AddrLabelExpr.
+///  * A BlockExpr for a block with captures.
+using Local = Expr*;
 
 /// Expressions we stepped over when looking for the local state. Any steps
 /// that would inhibit lifetime extension or take us out of subexpressions of
 /// the initializer are included.
 struct IndirectLocalPathEntry {
-  enum {
+  enum EntryKind {
     DefaultInit,
     AddressOf,
+    VarInit,
+    LValToRVal,
   } Kind;
   Expr *E;
+  Decl *D = nullptr;
+  IndirectLocalPathEntry() {}
+  IndirectLocalPathEntry(EntryKind K, Expr *E) : Kind(K), E(E) {}
+  IndirectLocalPathEntry(EntryKind K, Expr *E, Decl *D) : Kind(K), E(E), D(D) {}
 };
 
 using IndirectLocalPath = llvm::SmallVectorImpl<IndirectLocalPathEntry>;
@@ -6370,16 +6381,24 @@
   RevertToOldSizeRAII(IndirectLocalPath &Path) : Path(Path) {}
   ~RevertToOldSizeRAII() { Path.resize(OldSize); }
 };
+
+using LocalVisitor = llvm::function_ref<bool(IndirectLocalPath &Path, Local L,
+                                             ReferenceKind RK)>;
 }
 
-template <typename LocalVisitor>
+static bool isVarOnPath(IndirectLocalPath &Path, VarDecl *VD) {
+  for (auto E : Path)
+    if (E.Kind == IndirectLocalPathEntry::VarInit && E.D == VD)
+      return true;
+  return false;
+}
+
 static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
                                              Expr *Init, LocalVisitor Visit,
                                              bool RevisitSubinits);
 
 /// Visit the locals that would be reachable through a reference bound to the
 /// glvalue expression \c Init.
-template <typename LocalVisitor>
 static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path,
                                                   Expr *Init, ReferenceKind RK,
                                                   LocalVisitor Visit) {
@@ -6390,6 +6409,9 @@
   do {
     Old = Init;
 
+    if (auto *EWC = dyn_cast<ExprWithCleanups>(Init))
+      Init = EWC->getSubExpr();
+
     if (InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {
       // If this is just redundant braces around an initializer, step over it.
       if (ILE->isTransparent())
@@ -6409,20 +6431,22 @@
     // Per the current approach for DR1299, look through array element access
     // on array glvalues when performing lifetime extension.
     if (auto *ASE = dyn_cast<ArraySubscriptExpr>(Init)) {
-      auto *ICE = dyn_cast<ImplicitCastExpr>(ASE->getBase());
-      if (!ICE || ICE->getCastKind() != CK_ArrayToPointerDecay)
-        return;
-      Init = ICE->getSubExpr();
+      Init = ASE->getBase();
+      auto *ICE = dyn_cast<ImplicitCastExpr>(Init);
+      if (ICE && ICE->getCastKind() == CK_ArrayToPointerDecay)
+        Init = ICE->getSubExpr();
+      else
+        // We can't lifetime extend through this but we might still find some
+        // retained temporaries.
+        return visitLocalsRetainedByInitializer(Path, Init, Visit, true);
     }
 
     // Step into CXXDefaultInitExprs so we can diagnose cases where a
     // constructor inherits one as an implicit mem-initializer.
     if (auto *DIE = dyn_cast<CXXDefaultInitExpr>(Init)) {
-      Path.push_back({IndirectLocalPathEntry::DefaultInit, DIE});
+      Path.push_back(
+          {IndirectLocalPathEntry::DefaultInit, DIE, DIE->getField()});
       Init = DIE->getExpr();
-
-      if (auto *EWC = dyn_cast<ExprWithCleanups>(Init))
-        Init = EWC->getSubExpr();
     }
   } while (Init != Old);
 
@@ -6432,22 +6456,64 @@
                                        true);
   }
 
-  // If we find the name of a local non-reference parameter, we could have a
-  // lifetime problem.
-  if (auto *DRE = dyn_cast<DeclRefExpr>(Init->IgnoreParens())) {
+  switch (Init->getStmtClass()) {
+  case Stmt::DeclRefExprClass: {
+    // If we find the name of a local non-reference parameter, we could have a
+    // lifetime problem.
+    auto *DRE = cast<DeclRefExpr>(Init);
     auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
     if (VD && VD->hasLocalStorage() &&
         !DRE->refersToEnclosingVariableOrCapture()) {
-      // FIXME: Recurse to the initializer of a local reference.
-      if (!VD->getType()->isReferenceType())
-        Visit(Path, Local(VD), RK);
+      if (!VD->getType()->isReferenceType()) {
+        Visit(Path, Local(DRE), RK);
+      } else if (isa<ParmVarDecl>(DRE->getDecl())) {
+        // The lifetime of a reference parameter is unknown; assume it's OK
+        // for now.
+        break;
+      } else if (VD->getInit() && !isVarOnPath(Path, VD)) {
+        Path.push_back({IndirectLocalPathEntry::VarInit, DRE, VD});
+        visitLocalsRetainedByReferenceBinding(Path, VD->getInit(),
+                                              RK_ReferenceBinding, Visit);
+      }
     }
+    break;
+  }
+
+  case Stmt::UnaryOperatorClass: {
+    // The only unary operator that make sense to handle here
+    // is Deref.  All others don't resolve to a "name."  This includes
+    // handling all sorts of rvalues passed to a unary operator.
+    const UnaryOperator *U = cast<UnaryOperator>(Init);
+    if (U->getOpcode() == UO_Deref)
+      visitLocalsRetainedByInitializer(Path, U->getSubExpr(), Visit, true);
+    break;
+  }
+
+  case Stmt::OMPArraySectionExprClass: {
+    visitLocalsRetainedByInitializer(
+        Path, cast<OMPArraySectionExpr>(Init)->getBase(), Visit, true);
+    break;
+  }
+
+  case Stmt::ConditionalOperatorClass:
+  case Stmt::BinaryConditionalOperatorClass: {
+    auto *C = cast<AbstractConditionalOperator>(Init);
+    if (!C->getTrueExpr()->getType()->isVoidType())
+      visitLocalsRetainedByReferenceBinding(Path, C->getTrueExpr(), RK, Visit);
+    if (!C->getFalseExpr()->getType()->isVoidType())
+      visitLocalsRetainedByReferenceBinding(Path, C->getFalseExpr(), RK, Visit);
+    break;
+  }
+
+  // FIXME: Visit the left-hand side of an -> or ->*.
+
+  default:
+    break;
   }
 }
 
 /// Visit the locals that would be reachable through an object initialized by
 /// the prvalue expression \c Init.
-template <typename LocalVisitor>
 static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
                                              Expr *Init, LocalVisitor Visit,
                                              bool RevisitSubinits) {
@@ -6456,13 +6522,13 @@
   // Step into CXXDefaultInitExprs so we can diagnose cases where a
   // constructor inherits one as an implicit mem-initializer.
   if (auto *DIE = dyn_cast<CXXDefaultInitExpr>(Init)) {
-    Path.push_back({IndirectLocalPathEntry::DefaultInit, DIE});
+    Path.push_back({IndirectLocalPathEntry::DefaultInit, DIE, DIE->getField()});
     Init = DIE->getExpr();
-
-    if (auto *EWC = dyn_cast<ExprWithCleanups>(Init))
-      Init = EWC->getSubExpr();
   }
 
+  if (auto *EWC = dyn_cast<ExprWithCleanups>(Init))
+    Init = EWC->getSubExpr();
+
   // Dig out the expression which constructs the extended temporary.
   Init = const_cast<Expr *>(Init->skipRValueSubobjectAdjustments());
 
@@ -6528,15 +6594,119 @@
     return;
   }
 
-  // If the initializer is the address of a local, we could have a lifetime
-  // problem.
-  if (auto *Op = dyn_cast<UnaryOperator>(Init->IgnoreParenImpCasts())) {
-    if (Op->getOpcode() == UO_AddrOf) {
-      Path.push_back({IndirectLocalPathEntry::AddressOf, Op});
-      Init = Op->getSubExpr();
-      return visitLocalsRetainedByReferenceBinding(Path, Init,
+  // Step over value-preserving rvalue casts.
+  while (auto *CE = dyn_cast<CastExpr>(Init)) {
+    switch (CE->getCastKind()) {
+    case CK_LValueToRValue:
+      // If we can match the lvalue to a const object, we can look at its
+      // initializer.
+      Path.push_back({IndirectLocalPathEntry::LValToRVal, CE});
+      return visitLocalsRetainedByReferenceBinding(
+          Path, Init, RK_ReferenceBinding,
+          [&](IndirectLocalPath &Path, Local L, ReferenceKind RK) -> bool {
+        if (auto *DRE = dyn_cast<DeclRefExpr>(L)) {
+          auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
+          if (VD && VD->getType().isConstQualified() && VD->getInit()) {
+            Path.push_back({IndirectLocalPathEntry::VarInit, DRE, VD});
+            visitLocalsRetainedByInitializer(Path, VD->getInit(), Visit, true);
+          }
+        } else if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(L)) {
+          if (MTE->getType().isConstQualified())
+            visitLocalsRetainedByInitializer(Path, MTE->GetTemporaryExpr(),
+                                             Visit, true);
+        }
+        return false;
+      });
+
+      // We assume that objects can be retained by pointers cast to integers,
+      // but not if the integer is cast to floating-point type or to _Complex.
+      // We assume that casts to 'bool' do not preserve enough information to
+      // retain a local object.
+    case CK_NoOp:
+    case CK_BitCast:
+    case CK_BaseToDerived:
+    case CK_DerivedToBase:
+    case CK_UncheckedDerivedToBase:
+    case CK_Dynamic:
+    case CK_ToUnion:
+    case CK_IntegralToPointer:
+    case CK_PointerToIntegral:
+    case CK_VectorSplat:
+    case CK_IntegralCast:
+    case CK_CPointerToObjCPointerCast:
+    case CK_BlockPointerToObjCPointerCast:
+    case CK_AnyPointerToBlockPointerCast:
+    case CK_AddressSpaceConversion:
+      break;
+
+    case CK_ArrayToPointerDecay:
+      // Model array-to-pointer decay as taking the address of the array
+      // lvalue.
+      Path.push_back({IndirectLocalPathEntry::AddressOf, CE});
+      return visitLocalsRetainedByReferenceBinding(Path, CE->getSubExpr(),
                                                    RK_ReferenceBinding, Visit);
+
+    default:
+      return;
     }
+
+    Init = CE->getSubExpr();
+  }
+
+  Init = Init->IgnoreParens();
+  switch (Init->getStmtClass()) {
+  case Stmt::UnaryOperatorClass: {
+    auto *UO = cast<UnaryOperator>(Init);
+    // If the initializer is the address of a local, we could have a lifetime
+    // problem.
+    if (UO->getOpcode() == UO_AddrOf) {
+      Path.push_back({IndirectLocalPathEntry::AddressOf, UO});
+      visitLocalsRetainedByReferenceBinding(Path, UO->getSubExpr(),
+                                            RK_ReferenceBinding, Visit);
+    }
+    break;
+  }
+
+  case Stmt::BinaryOperatorClass: {
+    // Handle pointer arithmetic.
+    auto *BO = cast<BinaryOperator>(Init);
+    BinaryOperatorKind BOK = BO->getOpcode();
+    if (!BO->getType()->isPointerType() || (BOK != BO_Add && BOK != BO_Sub))
+      break;
+
+    if (BO->getLHS()->getType()->isPointerType())
+      visitLocalsRetainedByInitializer(Path, BO->getLHS(), Visit, true);
+    else if (BO->getRHS()->getType()->isPointerType())
+      visitLocalsRetainedByInitializer(Path, BO->getRHS(), Visit, true);
+    break;
+  }
+
+  case Stmt::ConditionalOperatorClass:
+  case Stmt::BinaryConditionalOperatorClass: {
+    auto *C = cast<AbstractConditionalOperator>(Init);
+    // In C++, we can have a throw-expression operand, which has 'void' type
+    // and isn't interesting from a lifetime perspective.
+    if (!C->getTrueExpr()->getType()->isVoidType())
+      visitLocalsRetainedByInitializer(Path, C->getTrueExpr(), Visit, true);
+    if (!C->getFalseExpr()->getType()->isVoidType())
+      visitLocalsRetainedByInitializer(Path, C->getFalseExpr(), Visit, true);
+    break;
+  }
+
+  case Stmt::BlockExprClass:
+    if (cast<BlockExpr>(Init)->getBlockDecl()->hasCaptures()) {
+      // This is a local block, whose lifetime is that of the function.
+      Visit(Path, Local(cast<BlockExpr>(Init)), RK_ReferenceBinding);
+    }
+    break;
+
+  case Stmt::AddrLabelExprClass:
+    // We want to warn if the address of a label would escape the function.
+    Visit(Path, Local(cast<AddrLabelExpr>(Init)), RK_ReferenceBinding);
+    break;
+
+  default:
+    break;
   }
 }
 
@@ -6563,58 +6733,20 @@
 
   auto TemporaryVisitor = [&](IndirectLocalPath &Path, Local L,
                               ReferenceKind RK) -> bool {
-    // If we found a path to a local variable or similar, check whether the
-    // initialized object will outlive it.
-    if (auto *VD = L.dyn_cast<ValueDecl*>()) {
-      switch (LK) {
-      case LK_FullExpression:
-        llvm_unreachable("already handled this");
+    Expr *First = Path.empty() ? L : Path.front().E;
+    SourceLocation DiagLoc = First->getLocStart();
+    SourceRange DiagRange = First->getSourceRange();
 
-      case LK_Extended:
-        break;
-
-      case LK_MemInitializer: {
-        // Paths via a default initializer can only occur during error recovery
-        // (there's no other way that a default initializer can refer to a
-        // local). Don't produce a bogus warning on those cases.
-        if (std::any_of(Path.begin(), Path.end(), [](IndirectLocalPathEntry E) {
-              return E.Kind == IndirectLocalPathEntry::DefaultInit;
-            }))
-          break;
-
-        if (auto *Member =
-                ExtendingEntity ? ExtendingEntity->getDecl() : nullptr) {
-          bool AddressTaken =
-              !Path.empty() &&
-              Path.back().Kind == IndirectLocalPathEntry::AddressOf;
-          Diag(Init->getExprLoc(),
-               AddressTaken ? diag::warn_init_ptr_member_to_parameter_addr
-                            : diag::warn_bind_ref_member_to_parameter)
-              << Member << VD << isa<ParmVarDecl>(VD) << Init->getSourceRange();
-          Diag(Member->getLocation(),
-               diag::note_ref_or_ptr_member_declared_here)
-              << (unsigned)AddressTaken;
-        }
-        break;
-      }
-
-      case LK_New:
-        break;
-
-      case LK_Return:
-      case LK_StmtExprResult:
-        // FIXME: Move -Wreturn-stack-address checks here.
-        return false;
-      }
-      return false;
-    }
-
-    auto *MTE = L.get<MaterializeTemporaryExpr*>();
     switch (LK) {
     case LK_FullExpression:
       llvm_unreachable("already handled this");
 
-    case LK_Extended:
+    case LK_Extended: {
+      auto *MTE = dyn_cast<MaterializeTemporaryExpr>(L);
+      if (!MTE)
+        // FIXME: Warn on this.
+        return false;
+
       // Lifetime-extend the temporary.
       if (Path.empty()) {
         // Update the storage duration of the materialized temporary.
@@ -6632,70 +6764,138 @@
         // FIXME: Properly handle this situation. Perhaps the easiest approach
         // would be to clone the initializer expression on each use that would
         // lifetime extend its temporaries.
-        Diag(MTE->getExprLoc(),
+        Diag(DiagLoc,
              RK == RK_ReferenceBinding
                  ? diag::warn_default_member_init_temporary_not_extended
-                 : diag::warn_default_member_init_init_list_not_extended);
+                 : diag::warn_default_member_init_init_list_not_extended)
+            << DiagRange;
       } else {
         // FIXME: Warn on this.
+        return false;
       }
       break;
+    }
 
-    case LK_MemInitializer:
-      // Under C++ DR1696, if a mem-initializer (or a default member
-      // initializer used by the absence of one) would lifetime-extend a
-      // temporary, the program is ill-formed.
-      if (auto *ExtendingDecl =
-              ExtendingEntity ? ExtendingEntity->getDecl() : nullptr) {
-        bool IsSubobjectMember = ExtendingEntity != &Entity;
-        Diag(MTE->getExprLoc(), diag::err_bind_ref_member_to_temporary)
-            << ExtendingDecl << Init->getSourceRange() << IsSubobjectMember
-            << RK;
-        // Don't bother adding a note pointing to the field if we're inside its
-        // default member initializer; our primary diagnostic points to the
-        // same place in that case.
-        if (Path.empty() ||
-            Path.back().Kind != IndirectLocalPathEntry::DefaultInit) {
-          Diag(ExtendingDecl->getLocation(),
-               diag::note_lifetime_extending_member_declared_here)
-              << RK << IsSubobjectMember;
+    case LK_MemInitializer: {
+      if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(L)) {
+        // Under C++ DR1696, if a mem-initializer (or a default member
+        // initializer used by the absence of one) would lifetime-extend a
+        // temporary, the program is ill-formed.
+        if (auto *ExtendingDecl =
+                ExtendingEntity ? ExtendingEntity->getDecl() : nullptr) {
+          bool IsSubobjectMember = ExtendingEntity != &Entity;
+          Diag(DiagLoc, diag::err_bind_ref_member_to_temporary)
+              << ExtendingDecl << IsSubobjectMember << RK << DiagRange;
+          // Don't bother adding a note pointing to the field if we're inside
+          // its default member initializer; our primary diagnostic points to
+          // the same place in that case.
+          if (Path.empty() ||
+              Path.back().Kind != IndirectLocalPathEntry::DefaultInit) {
+            Diag(ExtendingDecl->getLocation(),
+                 diag::note_lifetime_extending_member_declared_here)
+                << RK << IsSubobjectMember;
+          }
+        } else {
+          // We have a mem-initializer but no particular field within it; this
+          // is either a base class or a delegating initializer directly
+          // initializing the base-class from something that doesn't live long
+          // enough.
+          //
+          // FIXME: Warn on this.
+          return false;
         }
       } else {
-        // We have a mem-initializer but no particular field within it; this
-        // is either a base class or a delegating initializer directly
-        // initializing the base-class from something that doesn't live long
-        // enough. Either way, that can't happen.
-        // FIXME: Move CheckForDanglingReferenceOrPointer checks here.
-        llvm_unreachable(
-            "temporary initializer for base class / delegating ctor");
+        // Paths via a default initializer can only occur during error recovery
+        // (there's no other way that a default initializer can refer to a
+        // local). Don't produce a bogus warning on those cases.
+        if (std::any_of(Path.begin(), Path.end(), [](IndirectLocalPathEntry E) {
+              return E.Kind == IndirectLocalPathEntry::DefaultInit;
+            }))
+          return false;
+
+        auto *DRE = dyn_cast<DeclRefExpr>(L);
+        auto *VD = DRE ? dyn_cast<VarDecl>(DRE->getDecl()) : nullptr;
+        if (!VD) {
+          // A member was initialized to a local block.
+          // FIXME: Warn on this.
+          return false;
+        }
+
+        if (auto *Member =
+                ExtendingEntity ? ExtendingEntity->getDecl() : nullptr) {
+          bool IsPointer = Member->getType()->isAnyPointerType();
+          Diag(DiagLoc, IsPointer ? diag::warn_init_ptr_member_to_parameter_addr
+                                  : diag::warn_bind_ref_member_to_parameter)
+              << Member << VD << isa<ParmVarDecl>(VD) << DiagRange;
+          Diag(Member->getLocation(),
+               diag::note_ref_or_ptr_member_declared_here)
+              << (unsigned)IsPointer;
+        }
       }
       break;
+    }
 
     case LK_New:
-      if (RK == RK_ReferenceBinding) {
-        Diag(MTE->getExprLoc(), diag::warn_new_dangling_reference);
+      if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(L)) {
+        Diag(DiagLoc, RK == RK_ReferenceBinding
+                          ? diag::warn_new_dangling_reference
+                          : diag::warn_new_dangling_initializer_list)
+            << (ExtendingEntity != &Entity) << DiagRange;
       } else {
-        Diag(MTE->getExprLoc(), diag::warn_new_dangling_initializer_list)
-            << (ExtendingEntity != &Entity);
+        // We can't determine if the allocation outlives the local declaration.
+        return false;
       }
       break;
 
     case LK_Return:
     case LK_StmtExprResult:
-      // FIXME: Move -Wreturn-stack-address checks here.
-      return false;
+      if (auto *DRE = dyn_cast<DeclRefExpr>(L)) {
+        // We can't determine if the local variable outlives the statement
+        // expression.
+        if (LK == LK_StmtExprResult)
+          return false;
+        Diag(DiagLoc, diag::warn_ret_stack_addr_ref)
+            << Entity.getType()->isReferenceType() << DRE->getDecl()
+            << isa<ParmVarDecl>(DRE->getDecl()) << DiagRange;
+      } else if (isa<BlockExpr>(L)) {
+        Diag(DiagLoc, diag::err_ret_local_block) << DiagRange;
+      } else if (isa<AddrLabelExpr>(L)) {
+        Diag(DiagLoc, diag::warn_ret_addr_label) << DiagRange;
+      } else {
+        Diag(DiagLoc, diag::warn_ret_local_temp_addr_ref)
+         << Entity.getType()->isReferenceType() << DiagRange;
+      }
+      break;
     }
 
-    // FIXME: Model these as CodeSynthesisContexts to fix the note emission
-    // order.
-    for (auto Elem : llvm::reverse(Path)) {
+    for (unsigned I = 0; I != Path.size(); ++I) {
+      auto Elem = Path[I];
+
+      // Highlight the range of the next step within this path element.
+      SourceRange Range;
+      if (I < Path.size() - 1)
+        Range = Path[I + 1].E->getSourceRange();
+      else
+        Range = L->getSourceRange();
+
       switch (Elem.Kind) {
-      case IndirectLocalPathEntry::DefaultInit:
-        Diag(Elem.E->getExprLoc(), diag::note_in_default_member_initalizer_here)
-            << cast<CXXDefaultInitExpr>(Elem.E)->getField();
+      case IndirectLocalPathEntry::AddressOf:
+      case IndirectLocalPathEntry::LValToRVal:
+        // These exist primarily to mark the path as not permitting lifetime
+        // extension.
         break;
 
-      case IndirectLocalPathEntry::AddressOf:
+      case IndirectLocalPathEntry::DefaultInit: {
+        auto *FD = cast<FieldDecl>(Elem.D);
+        Diag(FD->getLocation(), diag::note_init_with_default_member_initalizer)
+            << FD << Range;
+        break;
+      }
+
+      case IndirectLocalPathEntry::VarInit:
+        const VarDecl *VD = cast<VarDecl>(Elem.D);
+        Diag(VD->getLocation(), diag::note_local_var_initializer)
+            << VD->getType()->isReferenceType() << VD->getDeclName() << Range;
         break;
       }
     }
