diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -1546,6 +1546,7 @@
     APValue::LValueBase Base;
     CharUnits Offset;
     SubobjectDesignator Designator;
+    const Expr *LExpr = nullptr;
     bool IsNullPtr : 1;
     bool InvalidBase : 1;
 
@@ -1554,6 +1555,7 @@
     const CharUnits &getLValueOffset() const { return Offset; }
     SubobjectDesignator &getLValueDesignator() { return Designator; }
     const SubobjectDesignator &getLValueDesignator() const { return Designator;}
+    const Expr *getExpr() const { return LExpr; }
     bool isNullPointer() const { return IsNullPtr;}
 
     unsigned getLValueCallIndex() const { return Base.getCallIndex(); }
@@ -1591,6 +1593,8 @@
       Offset = CharUnits::fromQuantity(0);
       InvalidBase = BInvalid;
       Designator = SubobjectDesignator(getType(B));
+      if (!LExpr)
+        LExpr = B.dyn_cast<const Expr *>();
       IsNullPtr = false;
     }
 
@@ -6100,8 +6104,11 @@
     if (!handleTrivialCopy(Info, MD->getParamDecl(0), Args[0], RHSValue,
                            MD->getParent()->isUnion()))
       return false;
+    const Expr *LHS = This->getExpr();
+    if (!LHS)
+      return false;
     if (Info.getLangOpts().CPlusPlus20 && MD->isTrivial() &&
-        !HandleUnionActiveMemberChange(Info, Args[0], *This))
+        !HandleUnionActiveMemberChange(Info, LHS, *This))
       return false;
     if (!handleAssignment(Info, Args[0], *This, MD->getThisType(),
                           RHSValue))
@@ -8058,10 +8065,20 @@
 namespace {
 class LValueExprEvaluator
   : public LValueExprEvaluatorBase<LValueExprEvaluator> {
+  friend class LValueExprEvaluatorBase<LValueExprEvaluator>;
+  friend class ExprEvaluatorBase<LValueExprEvaluator>;
+  friend class ConstStmtVisitor<LValueExprEvaluator, bool>;
+  friend class StmtVisitorBase<llvm::make_const_ptr, LValueExprEvaluator, bool>;
 public:
   LValueExprEvaluator(EvalInfo &Info, LValue &Result, bool InvalidBaseOK) :
     LValueExprEvaluatorBaseTy(Info, Result, InvalidBaseOK) {}
 
+  bool Evaluate(const Expr *E) {
+    Result.LExpr = E;
+    return Visit(E);
+  }
+
+protected:
   bool VisitVarDecl(const Expr *E, const VarDecl *VD);
   bool VisitUnaryPreIncDec(const UnaryOperator *UO);
 
@@ -8123,7 +8140,7 @@
   assert(!E->isValueDependent());
   assert(E->isGLValue() || E->getType()->isFunctionType() ||
          E->getType()->isVoidType() || isa<ObjCSelectorExpr>(E));
-  return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
+  return LValueExprEvaluator(Info, Result, InvalidBaseOK).Evaluate(E);
 }
 
 bool LValueExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) {
@@ -8424,7 +8441,7 @@
 
   // C++17 onwards require that we evaluate the RHS first.
   APValue RHS;
-  if (!Evaluate(RHS, this->Info, CAO->getRHS())) {
+  if (!::Evaluate(RHS, this->Info, CAO->getRHS())) {
     if (!Info.noteFailure())
       return false;
     Success = false;
@@ -8448,7 +8465,7 @@
 
   // C++17 onwards require that we evaluate the RHS first.
   APValue NewVal;
-  if (!Evaluate(NewVal, this->Info, E->getRHS())) {
+  if (!::Evaluate(NewVal, this->Info, E->getRHS())) {
     if (!Info.noteFailure())
       return false;
     Success = false;
diff --git a/clang/test/SemaCXX/constant-expression-cxx2a.cpp b/clang/test/SemaCXX/constant-expression-cxx2a.cpp
--- a/clang/test/SemaCXX/constant-expression-cxx2a.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx2a.cpp
@@ -1447,3 +1447,11 @@
   constexpr bool b = [a = S(), b = S()] { return a.p == b.p; }();
   static_assert(!b);
 }
+
+namespace PR45879 {
+struct Base {
+  int m;
+};
+struct Derived : Base {};
+constexpr int k = ((Base{} = Derived{}), 0);
+} // namespace PR45879