Revert 363295, it caused PR42276. Also revert follow-ups 363337, 363340.

Revert 363340 "Remove unused SK_LValueToRValue initialization step."
Revert 363337 "PR23833, DR2140: an lvalue-to-rvalue conversion on a glvalue of type"
Revert 363295 "C++ DR712 and others: handle non-odr-use resulting from an lvalue-to-rvalue conversion applied to a member access or similar not-quite-trivial lvalue expression."

llvm-svn: 363352
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 72e1119..77d4441 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -1885,11 +1885,6 @@
                                            ExprValueKind VK) {
   unsigned PathSize = (BasePath ? BasePath->size() : 0);
   void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
-  // Per C++ [conv.lval]p3, lvalue-to-rvalue conversions on class and
-  // std::nullptr_t have special semantics not captured by CK_LValueToRValue.
-  assert((Kind != CK_LValueToRValue ||
-          !(T->isNullPtrType() || T->getAsCXXRecordDecl())) &&
-         "invalid type for lvalue-to-rvalue conversion");
   ImplicitCastExpr *E =
     new (Buffer) ImplicitCastExpr(T, Kind, Operand, PathSize, VK);
   if (PathSize)
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index f027ab9..db18ac4 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -1077,16 +1077,17 @@
   return constant;
 }
 
-Address CodeGenModule::createUnnamedGlobalFrom(const VarDecl &D,
-                                               llvm::Constant *Constant,
-                                               CharUnits Align) {
+static Address createUnnamedGlobalFrom(CodeGenModule &CGM, const VarDecl &D,
+                                       CGBuilderTy &Builder,
+                                       llvm::Constant *Constant,
+                                       CharUnits Align) {
   auto FunctionName = [&](const DeclContext *DC) -> std::string {
     if (const auto *FD = dyn_cast<FunctionDecl>(DC)) {
       if (const auto *CC = dyn_cast<CXXConstructorDecl>(FD))
         return CC->getNameAsString();
       if (const auto *CD = dyn_cast<CXXDestructorDecl>(FD))
         return CD->getNameAsString();
-      return getMangledName(FD);
+      return CGM.getMangledName(FD);
     } else if (const auto *OM = dyn_cast<ObjCMethodDecl>(DC)) {
       return OM->getNameAsString();
     } else if (isa<BlockDecl>(DC)) {
@@ -1098,39 +1099,22 @@
     }
   };
 
-  // Form a simple per-variable cache of these values in case we find we
-  // want to reuse them.
-  llvm::GlobalVariable *&CacheEntry = InitializerConstants[&D];
-  if (!CacheEntry || CacheEntry->getInitializer() != Constant) {
-    auto *Ty = Constant->getType();
-    bool isConstant = true;
-    llvm::GlobalVariable *InsertBefore = nullptr;
-    unsigned AS =
-        getContext().getTargetAddressSpace(getStringLiteralAddressSpace());
-    llvm::GlobalVariable *GV = new llvm::GlobalVariable(
-        getModule(), Ty, isConstant, llvm::GlobalValue::PrivateLinkage,
-        Constant,
-        "__const." + FunctionName(D.getParentFunctionOrMethod()) + "." +
-            D.getName(),
-        InsertBefore, llvm::GlobalValue::NotThreadLocal, AS);
-    GV->setAlignment(Align.getQuantity());
-    GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
-    CacheEntry = GV;
-  } else if (CacheEntry->getAlignment() < Align.getQuantity()) {
-    CacheEntry->setAlignment(Align.getQuantity());
-  }
+  auto *Ty = Constant->getType();
+  bool isConstant = true;
+  llvm::GlobalVariable *InsertBefore = nullptr;
+  unsigned AS = CGM.getContext().getTargetAddressSpace(
+      CGM.getStringLiteralAddressSpace());
+  llvm::GlobalVariable *GV = new llvm::GlobalVariable(
+      CGM.getModule(), Ty, isConstant, llvm::GlobalValue::PrivateLinkage,
+      Constant,
+      "__const." + FunctionName(D.getParentFunctionOrMethod()) + "." +
+          D.getName(),
+      InsertBefore, llvm::GlobalValue::NotThreadLocal, AS);
+  GV->setAlignment(Align.getQuantity());
+  GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
 
-  return Address(CacheEntry, Align);
-}
-
-static Address createUnnamedGlobalForMemcpyFrom(CodeGenModule &CGM,
-                                                const VarDecl &D,
-                                                CGBuilderTy &Builder,
-                                                llvm::Constant *Constant,
-                                                CharUnits Align) {
-  Address SrcPtr = CGM.createUnnamedGlobalFrom(D, Constant, Align);
-  llvm::Type *BP = llvm::PointerType::getInt8PtrTy(CGM.getLLVMContext(),
-                                                   SrcPtr.getAddressSpace());
+  Address SrcPtr = Address(GV, Align);
+  llvm::Type *BP = llvm::PointerType::getInt8PtrTy(CGM.getLLVMContext(), AS);
   if (SrcPtr.getType() != BP)
     SrcPtr = Builder.CreateBitCast(SrcPtr, BP);
   return SrcPtr;
@@ -1213,10 +1197,10 @@
   }
 
   // Copy from a global.
-  Builder.CreateMemCpy(Loc,
-                       createUnnamedGlobalForMemcpyFrom(
-                           CGM, D, Builder, constant, Loc.getAlignment()),
-                       SizeVal, isVolatile);
+  Builder.CreateMemCpy(
+      Loc,
+      createUnnamedGlobalFrom(CGM, D, Builder, constant, Loc.getAlignment()),
+      SizeVal, isVolatile);
 }
 
 static void emitStoresForZeroInit(CodeGenModule &CGM, const VarDecl &D,
@@ -1779,10 +1763,10 @@
       llvm::PHINode *Cur = Builder.CreatePHI(Begin.getType(), 2, "vla.cur");
       Cur->addIncoming(Begin.getPointer(), OriginBB);
       CharUnits CurAlign = Loc.getAlignment().alignmentOfArrayElement(EltSize);
-      Builder.CreateMemCpy(Address(Cur, CurAlign),
-                           createUnnamedGlobalForMemcpyFrom(
-                               CGM, D, Builder, Constant, ConstantAlign),
-                           BaseSizeInChars, isVolatile);
+      Builder.CreateMemCpy(
+          Address(Cur, CurAlign),
+          createUnnamedGlobalFrom(CGM, D, Builder, Constant, ConstantAlign),
+          BaseSizeInChars, isVolatile);
       llvm::Value *Next =
           Builder.CreateInBoundsGEP(Int8Ty, Cur, BaseSizeInChars, "vla.next");
       llvm::Value *Done = Builder.CreateICmpEQ(Next, End, "vla-init.isdone");
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index f0d8619..d5ce487 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1422,11 +1422,10 @@
 }
 
 /// Try to emit a reference to the given value without producing it as
-/// an l-value.  This is just an optimization, but it avoids us needing
-/// to emit global copies of variables if they're named without triggering
-/// a formal use in a context where we can't emit a direct reference to them,
-/// for instance if a block or lambda or a member of a local class uses a
-/// const int variable or constexpr variable from an enclosing function.
+/// an l-value.  This is actually more than an optimization: we can't
+/// produce an l-value for variables that we never actually captured
+/// in a block or lambda, which means const int variables or constexpr
+/// literals or similar.
 CodeGenFunction::ConstantEmission
 CodeGenFunction::tryEmitAsConstant(DeclRefExpr *refExpr) {
   ValueDecl *value = refExpr->getDecl();
@@ -2451,97 +2450,33 @@
   return LValue::MakeGlobalReg(Address(Ptr, Alignment), VD->getType());
 }
 
-/// Determine whether we can emit a reference to \p VD from the current
-/// context, despite not necessarily having seen an odr-use of the variable in
-/// this context.
-static bool canEmitSpuriousReferenceToVariable(CodeGenFunction &CGF,
-                                               const DeclRefExpr *E,
-                                               const VarDecl *VD,
-                                               bool IsConstant) {
-  // For a variable declared in an enclosing scope, do not emit a spurious
-  // reference even if we have a capture, as that will emit an unwarranted
-  // reference to our capture state, and will likely generate worse code than
-  // emitting a local copy.
-  if (E->refersToEnclosingVariableOrCapture())
-    return false;
-
-  // For a local declaration declared in this function, we can always reference
-  // it even if we don't have an odr-use.
-  if (VD->hasLocalStorage()) {
-    return VD->getDeclContext() ==
-           dyn_cast_or_null<DeclContext>(CGF.CurCodeDecl);
-  }
-
-  // For a global declaration, we can emit a reference to it if we know
-  // for sure that we are able to emit a definition of it.
-  VD = VD->getDefinition(CGF.getContext());
-  if (!VD)
-    return false;
-
-  // Don't emit a spurious reference if it might be to a variable that only
-  // exists on a different device / target.
-  // FIXME: This is unnecessarily broad. Check whether this would actually be a
-  // cross-target reference.
-  if (CGF.getLangOpts().OpenMP || CGF.getLangOpts().CUDA ||
-      CGF.getLangOpts().OpenCL) {
-    return false;
-  }
-
-  // We can emit a spurious reference only if the linkage implies that we'll
-  // be emitting a non-interposable symbol that will be retained until link
-  // time.
-  switch (CGF.CGM.getLLVMLinkageVarDefinition(VD, IsConstant)) {
-  case llvm::GlobalValue::ExternalLinkage:
-  case llvm::GlobalValue::LinkOnceODRLinkage:
-  case llvm::GlobalValue::WeakODRLinkage:
-  case llvm::GlobalValue::InternalLinkage:
-  case llvm::GlobalValue::PrivateLinkage:
-    return true;
-  default:
-    return false;
-  }
-}
-
 LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
   const NamedDecl *ND = E->getDecl();
   QualType T = E->getType();
 
-  assert(E->isNonOdrUse() != NOUR_Unevaluated &&
-         "should not emit an unevaluated operand");
-
   if (const auto *VD = dyn_cast<VarDecl>(ND)) {
     // Global Named registers access via intrinsics only
     if (VD->getStorageClass() == SC_Register &&
         VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())
       return EmitGlobalNamedRegister(VD, CGM);
 
-    // If this DeclRefExpr does not constitute an odr-use of the variable,
-    // we're not permitted to emit a reference to it in general, and it might
-    // not be captured if capture would be necessary for a use. Emit the
-    // constant value directly instead.
-    if (E->isNonOdrUse() == NOUR_Constant &&
-        (VD->getType()->isReferenceType() ||
-         !canEmitSpuriousReferenceToVariable(*this, E, VD, true))) {
-      VD->getAnyInitializer(VD);
-      llvm::Constant *Val = ConstantEmitter(*this).emitAbstract(
-          E->getLocation(), *VD->evaluateValue(), VD->getType());
-      assert(Val && "failed to emit constant expression");
+    // A DeclRefExpr for a reference initialized by a constant expression can
+    // appear without being odr-used. Directly emit the constant initializer.
+    VD->getAnyInitializer(VD);
+    if (E->isNonOdrUse() == NOUR_Constant && VD->getType()->isReferenceType()) {
+      llvm::Constant *Val =
+        ConstantEmitter(*this).emitAbstract(E->getLocation(),
+                                            *VD->evaluateValue(),
+                                            VD->getType());
+      assert(Val && "failed to emit reference constant expression");
+      // FIXME: Eventually we will want to emit vector element references.
 
-      Address Addr = Address::invalid();
-      if (!VD->getType()->isReferenceType()) {
-        // Spill the constant value to a global.
-        Addr = CGM.createUnnamedGlobalFrom(*VD, Val,
-                                           getContext().getDeclAlign(VD));
-      } else {
-        // Should we be using the alignment of the constant pointer we emitted?
-        CharUnits Alignment =
-            getNaturalTypeAlignment(E->getType(),
-                                    /* BaseInfo= */ nullptr,
-                                    /* TBAAInfo= */ nullptr,
-                                    /* forPointeeType= */ true);
-        Addr = Address(Val, Alignment);
-      }
-      return MakeAddrLValue(Addr, T, AlignmentSource::Decl);
+      // Should we be using the alignment of the constant pointer we emitted?
+      CharUnits Alignment = getNaturalTypeAlignment(E->getType(),
+                                                    /* BaseInfo= */ nullptr,
+                                                    /* TBAAInfo= */ nullptr,
+                                                    /* forPointeeType= */ true);
+      return MakeAddrLValue(Address(Val, Alignment), T, AlignmentSource::Decl);
     }
 
     // FIXME: Handle other kinds of non-odr-use DeclRefExprs.
@@ -2577,7 +2512,7 @@
   // FIXME: We should be able to assert this for FunctionDecls as well!
   // FIXME: We should be able to assert this for all DeclRefExprs, not just
   // those with a valid source location.
-  assert((ND->isUsed(false) || !isa<VarDecl>(ND) || E->isNonOdrUse() ||
+  assert((ND->isUsed(false) || !isa<VarDecl>(ND) ||
           !E->getLocation().isValid()) &&
          "Should not use decl without marking it used!");
 
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index 3b1c5bf..a76058c 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -1352,8 +1352,7 @@
   // (int*)0 - Null pointer expressions.
   if (const CastExpr *ICE = dyn_cast<CastExpr>(E))
     return ICE->getCastKind() == CK_NullToPointer &&
-           CGF.getTypes().isPointerZeroInitializable(E->getType()) &&
-           !E->HasSideEffects(CGF.getContext());
+        CGF.getTypes().isPointerZeroInitializable(E->getType());
   // '\0'
   if (const CharacterLiteral *CL = dyn_cast<CharacterLiteral>(E))
     return CL->getValue() == 0;
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index c416753..267402d 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -2148,14 +2148,14 @@
 
   case CK_NullToPointer:
     if (MustVisitNullValue(E))
-      CGF.EmitIgnoredExpr(E);
+      (void) Visit(E);
 
     return CGF.CGM.getNullPointer(cast<llvm::PointerType>(ConvertType(DestTy)),
                               DestTy);
 
   case CK_NullToMemberPointer: {
     if (MustVisitNullValue(E))
-      CGF.EmitIgnoredExpr(E);
+      (void) Visit(E);
 
     const MemberPointerType *MPT = CE->getType()->getAs<MemberPointerType>();
     return CGF.CGM.getCXXABI().EmitNullMemberPointer(MPT);
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index 95964af..8c1bc07 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -362,10 +362,6 @@
   llvm::SmallVector<std::pair<llvm::GlobalValue *, llvm::Constant *>, 8>
     GlobalValReplacements;
 
-  /// Variables for which we've emitted globals containing their constant
-  /// values along with the corresponding globals, for opportunistic reuse.
-  llvm::DenseMap<const VarDecl*, llvm::GlobalVariable*> InitializerConstants;
-
   /// Set of global decls for which we already diagnosed mangled name conflict.
   /// Required to not issue a warning (on a mangling conflict) multiple times
   /// for the same decl.
@@ -627,9 +623,6 @@
     StaticLocalDeclGuardMap[D] = C;
   }
 
-  Address createUnnamedGlobalFrom(const VarDecl &D, llvm::Constant *Constant,
-                                  CharUnits Align);
-
   bool lookupRepresentativeDecl(StringRef MangledName,
                                 GlobalDecl &Result) const;
 
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index a561b04..d444a35 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -635,10 +635,8 @@
   if (E->getType().getObjCLifetime() == Qualifiers::OCL_Weak)
     Cleanup.setExprNeedsCleanups(true);
 
-  // C++ [conv.lval]p3:
-  //   If T is cv std::nullptr_t, the result is a null pointer constant.
-  CastKind CK = T->isNullPtrType() ? CK_NullToPointer : CK_LValueToRValue;
-  Res = ImplicitCastExpr::Create(Context, T, CK, E, nullptr, VK_RValue);
+  Res = ImplicitCastExpr::Create(Context, T, CK_LValueToRValue, E, nullptr,
+                                 VK_RValue);
 
   // C11 6.3.2.1p2:
   //   ... if the lvalue has atomic type, the value has the non-atomic version
@@ -15808,32 +15806,6 @@
   return DeclRefType;
 }
 
-namespace {
-// Helper to copy the template arguments from a DeclRefExpr or MemberExpr.
-// The produced TemplateArgumentListInfo* points to data stored within this
-// object, so should only be used in contexts where the pointer will not be
-// used after the CopiedTemplateArgs object is destroyed.
-class CopiedTemplateArgs {
-  bool HasArgs;
-  TemplateArgumentListInfo TemplateArgStorage;
-public:
-  template<typename RefExpr>
-  CopiedTemplateArgs(RefExpr *E) : HasArgs(E->hasExplicitTemplateArgs()) {
-    if (HasArgs)
-      E->copyTemplateArgumentsInto(TemplateArgStorage);
-  }
-  operator TemplateArgumentListInfo*()
-#ifdef __has_cpp_attribute
-#if __has_cpp_attribute(clang::lifetimebound)
-  [[clang::lifetimebound]]
-#endif
-#endif
-  {
-    return HasArgs ? &TemplateArgStorage : nullptr;
-  }
-};
-}
-
 /// Walk the set of potential results of an expression and mark them all as
 /// non-odr-uses if they satisfy the side-conditions of the NonOdrUseReason.
 ///
@@ -15925,11 +15897,16 @@
 
     // Rebuild as a non-odr-use DeclRefExpr.
     MarkNotOdrUsed();
+    TemplateArgumentListInfo TemplateArgStorage, *TemplateArgs = nullptr;
+    if (DRE->hasExplicitTemplateArgs()) {
+      DRE->copyTemplateArgumentsInto(TemplateArgStorage);
+      TemplateArgs = &TemplateArgStorage;
+    }
     return DeclRefExpr::Create(
         S.Context, DRE->getQualifierLoc(), DRE->getTemplateKeywordLoc(),
         DRE->getDecl(), DRE->refersToEnclosingVariableOrCapture(),
         DRE->getNameInfo(), DRE->getType(), DRE->getValueKind(),
-        DRE->getFoundDecl(), CopiedTemplateArgs(DRE), NOUR);
+        DRE->getFoundDecl(), TemplateArgs, NOUR);
   }
 
   case Expr::FunctionParmPackExprClass: {
@@ -15947,107 +15924,52 @@
     break;
   }
 
+  // FIXME: Implement these.
   //   -- If e is a subscripting operation with an array operand...
-  case Expr::ArraySubscriptExprClass: {
-    auto *ASE = cast<ArraySubscriptExpr>(E);
-    Expr *OldBase = ASE->getBase()->IgnoreImplicit();
-    if (!OldBase->getType()->isArrayType())
-      break;
-    ExprResult Base = Rebuild(OldBase);
-    if (!Base.isUsable())
-      return Base;
-    Expr *LHS = ASE->getBase() == ASE->getLHS() ? Base.get() : ASE->getLHS();
-    Expr *RHS = ASE->getBase() == ASE->getRHS() ? Base.get() : ASE->getRHS();
-    SourceLocation LBracketLoc = ASE->getBeginLoc(); // FIXME: Not stored.
-    return S.ActOnArraySubscriptExpr(nullptr, LHS, LBracketLoc, RHS,
-                                     ASE->getRBracketLoc());
-  }
+  //   -- If e is a class member access expression [...] naming a non-static
+  //      data member...
 
+  //   -- If e is a class member access expression naming a static data member,
+  //      ...
   case Expr::MemberExprClass: {
     auto *ME = cast<MemberExpr>(E);
-    // -- If e is a class member access expression [...] naming a non-static
-    //    data member...
-    if (isa<FieldDecl>(ME->getMemberDecl())) {
-      ExprResult Base = Rebuild(ME->getBase());
-      if (!Base.isUsable())
-        return Base;
-      return MemberExpr::Create(
-          S.Context, Base.get(), ME->isArrow(), ME->getOperatorLoc(),
-          ME->getQualifierLoc(), ME->getTemplateKeywordLoc(),
-          ME->getMemberDecl(), ME->getFoundDecl(), ME->getMemberNameInfo(),
-          CopiedTemplateArgs(ME), ME->getType(), ME->getValueKind(),
-          ME->getObjectKind(), ME->isNonOdrUse());
-    }
-
     if (ME->getMemberDecl()->isCXXInstanceMember())
+      // FIXME: Recurse to the left-hand side.
       break;
 
-    // -- If e is a class member access expression naming a static data member,
-    //    ...
     if (ME->isNonOdrUse() || IsPotentialResultOdrUsed(ME->getMemberDecl()))
       break;
 
     // Rebuild as a non-odr-use MemberExpr.
     MarkNotOdrUsed();
+    TemplateArgumentListInfo TemplateArgStorage, *TemplateArgs = nullptr;
+    if (ME->hasExplicitTemplateArgs()) {
+      ME->copyTemplateArgumentsInto(TemplateArgStorage);
+      TemplateArgs = &TemplateArgStorage;
+    }
     return MemberExpr::Create(
         S.Context, ME->getBase(), ME->isArrow(), ME->getOperatorLoc(),
         ME->getQualifierLoc(), ME->getTemplateKeywordLoc(), ME->getMemberDecl(),
-        ME->getFoundDecl(), ME->getMemberNameInfo(), CopiedTemplateArgs(ME),
+        ME->getFoundDecl(), ME->getMemberNameInfo(), TemplateArgs,
         ME->getType(), ME->getValueKind(), ME->getObjectKind(), NOUR);
     return ExprEmpty();
   }
 
-  case Expr::BinaryOperatorClass: {
-    auto *BO = cast<BinaryOperator>(E);
-    Expr *LHS = BO->getLHS();
-    Expr *RHS = BO->getRHS();
-    // -- If e is a pointer-to-member expression of the form e1 .* e2 ...
-    if (BO->getOpcode() == BO_PtrMemD) {
-      ExprResult Sub = Rebuild(LHS);
-      if (!Sub.isUsable())
-        return Sub;
-      LHS = Sub.get();
-    //   -- If e is a comma expression, ...
-    } else if (BO->getOpcode() == BO_Comma) {
-      ExprResult Sub = Rebuild(RHS);
-      if (!Sub.isUsable())
-        return Sub;
-      RHS = Sub.get();
-    } else {
-      break;
-    }
-    return S.BuildBinOp(nullptr, BO->getOperatorLoc(), BO->getOpcode(),
-                        LHS, RHS);
-  }
+  // FIXME: Implement this.
+  //   -- If e is a pointer-to-member expression of the form e1 .* e2 ...
 
   //   -- If e has the form (e1)...
   case Expr::ParenExprClass: {
-    auto *PE = cast<ParenExpr>(E);
+    auto *PE = dyn_cast<ParenExpr>(E);
     ExprResult Sub = Rebuild(PE->getSubExpr());
     if (!Sub.isUsable())
       return Sub;
     return S.ActOnParenExpr(PE->getLParen(), PE->getRParen(), Sub.get());
   }
 
+  // FIXME: Implement these.
   //   -- If e is a glvalue conditional expression, ...
-  // We don't apply this to a binary conditional operator. FIXME: Should we?
-  case Expr::ConditionalOperatorClass: {
-    auto *CO = cast<ConditionalOperator>(E);
-    ExprResult LHS = Rebuild(CO->getLHS());
-    if (LHS.isInvalid())
-      return ExprError();
-    ExprResult RHS = Rebuild(CO->getRHS());
-    if (RHS.isInvalid())
-      return ExprError();
-    if (!LHS.isUsable() && !RHS.isUsable())
-      return ExprEmpty();
-    if (!LHS.isUsable())
-      LHS = CO->getLHS();
-    if (!RHS.isUsable())
-      RHS = CO->getRHS();
-    return S.ActOnConditionalOp(CO->getQuestionLoc(), CO->getColonLoc(),
-                                CO->getCond(), LHS.get(), RHS.get());
-  }
+  //   -- If e is a comma expression, ...
 
   // [Clang extension]
   //   -- If e has the form __extension__ e1...
@@ -16066,7 +15988,7 @@
   //   -- If e has the form _Generic(...), the set of potential results is the
   //      union of the sets of potential results of the associated expressions.
   case Expr::GenericSelectionExprClass: {
-    auto *GSE = cast<GenericSelectionExpr>(E);
+    auto *GSE = dyn_cast<GenericSelectionExpr>(E);
 
     SmallVector<Expr *, 4> AssocExprs;
     bool AnyChanged = false;
@@ -16094,7 +16016,7 @@
   //      results is the union of the sets of potential results of the
   //      second and third subexpressions.
   case Expr::ChooseExprClass: {
-    auto *CE = cast<ChooseExpr>(E);
+    auto *CE = dyn_cast<ChooseExpr>(E);
 
     ExprResult LHS = Rebuild(CE->getLHS());
     if (LHS.isInvalid())
@@ -16117,38 +16039,13 @@
 
   // Step through non-syntactic nodes.
   case Expr::ConstantExprClass: {
-    auto *CE = cast<ConstantExpr>(E);
+    auto *CE = dyn_cast<ConstantExpr>(E);
     ExprResult Sub = Rebuild(CE->getSubExpr());
     if (!Sub.isUsable())
       return Sub;
     return ConstantExpr::Create(S.Context, Sub.get());
   }
 
-  // We could mostly rely on the recursive rebuilding to rebuild implicit
-  // casts, but not at the top level, so rebuild them here.
-  case Expr::ImplicitCastExprClass: {
-    auto *ICE = cast<ImplicitCastExpr>(E);
-    // Only step through the narrow set of cast kinds we expect to encounter.
-    // Anything else suggests we've left the region in which potential results
-    // can be found.
-    switch (ICE->getCastKind()) {
-    case CK_NoOp:
-    case CK_DerivedToBase:
-    case CK_UncheckedDerivedToBase: {
-      ExprResult Sub = Rebuild(ICE->getSubExpr());
-      if (!Sub.isUsable())
-        return Sub;
-      CXXCastPath Path(ICE->path());
-      return S.ImpCastExprToType(Sub.get(), ICE->getType(), ICE->getCastKind(),
-                                 ICE->getValueKind(), &Path);
-    }
-
-    default:
-      break;
-    }
-    break;
-  }
-
   default:
     break;
   }
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index d5ef5ed..1a1d934 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -3282,6 +3282,7 @@
   case SK_QualificationConversionXValue:
   case SK_QualificationConversionLValue:
   case SK_AtomicConversion:
+  case SK_LValueToRValue:
   case SK_ListInitialization:
   case SK_UnwrapInitList:
   case SK_RewrapInitList:
@@ -3465,6 +3466,15 @@
   Steps.push_back(S);
 }
 
+void InitializationSequence::AddLValueToRValueStep(QualType Ty) {
+  assert(!Ty.hasQualifiers() && "rvalues may not have qualifiers");
+
+  Step S;
+  S.Kind = SK_LValueToRValue;
+  S.Type = Ty;
+  Steps.push_back(S);
+}
+
 void InitializationSequence::AddConversionSequenceStep(
     const ImplicitConversionSequence &ICS, QualType T,
     bool TopLevelOfInitList) {
@@ -7495,6 +7505,7 @@
   case SK_QualificationConversionXValue:
   case SK_QualificationConversionRValue:
   case SK_AtomicConversion:
+  case SK_LValueToRValue:
   case SK_ConversionSequence:
   case SK_ConversionSequenceNoNarrowing:
   case SK_ListInitialization:
@@ -7766,6 +7777,14 @@
       break;
     }
 
+    case SK_LValueToRValue: {
+      assert(CurInit.get()->isGLValue() && "cannot load from a prvalue");
+      CurInit = ImplicitCastExpr::Create(S.Context, Step->Type,
+                                         CK_LValueToRValue, CurInit.get(),
+                                         /*BasePath=*/nullptr, VK_RValue);
+      break;
+    }
+
     case SK_ConversionSequence:
     case SK_ConversionSequenceNoNarrowing: {
       if (const auto *FromPtrType =
@@ -8987,6 +9006,10 @@
       OS << "non-atomic-to-atomic conversion";
       break;
 
+    case SK_LValueToRValue:
+      OS << "load (lvalue to rvalue)";
+      break;
+
     case SK_ConversionSequence:
       OS << "implicit conversion sequence (";
       S->ICS->dump(); // FIXME: use OS
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index cc62cf1..df78b49 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -378,6 +378,7 @@
       case CK_BitCast:
       case CK_AddressSpaceConversion:
       case CK_BooleanToSignedIntegral:
+      case CK_NullToPointer:
       case CK_IntegralToPointer:
       case CK_PointerToIntegral: {
         SVal V = state->getSVal(Ex, LCtx);
@@ -502,12 +503,6 @@
         Bldr.generateNode(CastE, Pred, state);
         continue;
       }
-      case CK_NullToPointer: {
-        SVal V = svalBuilder.makeNull();
-        state = state->BindExpr(CastE, LCtx, V);
-        Bldr.generateNode(CastE, Pred, state);
-        continue;
-      }
       case CK_NullToMemberPointer: {
         SVal V = svalBuilder.getMemberPointer(nullptr);
         state = state->BindExpr(CastE, LCtx, V);