[clang] 9221bed - Revert "Implement CWG2631"

Corentin Jabot via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 30 07:04:33 PST 2022


Author: Corentin Jabot
Date: 2022-11-30T16:03:05+01:00
New Revision: 9221bedfd7d5f58ef36d45698823ca43030ce8eb

URL: https://github.com/llvm/llvm-project/commit/9221bedfd7d5f58ef36d45698823ca43030ce8eb
DIFF: https://github.com/llvm/llvm-project/commit/9221bedfd7d5f58ef36d45698823ca43030ce8eb.diff

LOG: Revert "Implement CWG2631"

This reverts commit 26fa17ed2914bd80c066d36b325fd3104e45554c.
This reverts commit 4403c4f9e77e673a2771edfc7ab0ebb234e97485.

There is still an ODR issue causing linker errors, investigating.

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/AST/ExprCXX.h
    clang/include/clang/AST/Stmt.h
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/include/clang/Sema/Sema.h
    clang/lib/AST/ASTImporter.cpp
    clang/lib/AST/Decl.cpp
    clang/lib/AST/ExprCXX.cpp
    clang/lib/Parse/ParseCXXInlineMethods.cpp
    clang/lib/Parse/ParseDeclCXX.cpp
    clang/lib/Sema/SemaDeclCXX.cpp
    clang/lib/Sema/SemaExpr.cpp
    clang/lib/Sema/SemaTemplateInstantiate.cpp
    clang/lib/Sema/TreeTransform.h
    clang/lib/Serialization/ASTReaderStmt.cpp
    clang/lib/Serialization/ASTWriterStmt.cpp
    clang/test/CXX/class/class.local/p1-0x.cpp
    clang/test/CXX/drs/dr26xx.cpp
    clang/test/CodeGenCXX/builtin-source-location.cpp
    clang/test/SemaCXX/cxx11-default-member-initializers.cpp
    clang/test/SemaCXX/source_location.cpp
    clang/www/cxx_dr_status.html

Removed: 
    clang/test/CodeGenCXX/default-arguments-with-immediate.cpp
    clang/test/PCH/default-argument-with-immediate-calls.cpp
    clang/test/SemaCXX/cxx2a-consteval-default-params.cpp


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 6ac35d48ccabb..7580b14fac5d6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -618,11 +618,6 @@ C++ Language Changes in Clang
 - Implemented DR2358 allowing init captures in lambdas in default arguments.
 - implemented `DR2654 <https://wg21.link/cwg2654>`_ which undeprecates
   all compound assignements operations on volatile qualified variables.
-- Implemented DR2631. Invalid ``consteval`` calls in default arguments and default
-  member initializers are diagnosed when and if the default is used.
-  This Fixes `Issue 56379 <https://github.com/llvm/llvm-project/issues/56379>`_
-  and changes the value of ``std::source_location::current()``
-  used in default parameters calls compared to previous versions of Clang.
 
 C++20 Feature Support
 ^^^^^^^^^^^^^^^^^^^^^

diff  --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
index 098720d9469f0..0b927c0294752 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -1245,12 +1245,8 @@ class CXXThrowExpr : public Expr {
 /// This wraps up a function call argument that was created from the
 /// corresponding parameter's default argument, when the call did not
 /// explicitly supply arguments for all of the parameters.
-class CXXDefaultArgExpr final
-    : public Expr,
-      private llvm::TrailingObjects<CXXDefaultArgExpr, Expr *> {
+class CXXDefaultArgExpr final : public Expr {
   friend class ASTStmtReader;
-  friend class ASTReader;
-  friend TrailingObjects;
 
   /// The parameter whose default is being used.
   ParmVarDecl *Param;
@@ -1259,7 +1255,7 @@ class CXXDefaultArgExpr final
   DeclContext *UsedContext;
 
   CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *Param,
-                    Expr *RewrittenExpr, DeclContext *UsedContext)
+                    DeclContext *UsedContext)
       : Expr(SC,
              Param->hasUnparsedDefaultArg()
                  ? Param->getType().getNonReferenceType()
@@ -1268,58 +1264,28 @@ class CXXDefaultArgExpr final
              Param->getDefaultArg()->getObjectKind()),
         Param(Param), UsedContext(UsedContext) {
     CXXDefaultArgExprBits.Loc = Loc;
-    CXXDefaultArgExprBits.HasRewrittenInit = RewrittenExpr != nullptr;
-    if (RewrittenExpr)
-      *getTrailingObjects<Expr *>() = RewrittenExpr;
     setDependence(computeDependence(this));
   }
 
-  CXXDefaultArgExpr(EmptyShell Empty, bool HasRewrittenInit)
-      : Expr(CXXDefaultArgExprClass, Empty) {
-    CXXDefaultArgExprBits.HasRewrittenInit = HasRewrittenInit;
-  }
-
-  size_t numTrailingObjects() const {
-    return CXXDefaultArgExprBits.HasRewrittenInit;
-  }
-
 public:
-  static CXXDefaultArgExpr *CreateEmpty(const ASTContext &C,
-                                        bool HasRewrittenInit);
+  CXXDefaultArgExpr(EmptyShell Empty) : Expr(CXXDefaultArgExprClass, Empty) {}
 
   // \p Param is the parameter whose default argument is used by this
   // expression.
   static CXXDefaultArgExpr *Create(const ASTContext &C, SourceLocation Loc,
-                                   ParmVarDecl *Param, Expr *RewrittenExpr,
-                                   DeclContext *UsedContext);
+                                   ParmVarDecl *Param,
+                                   DeclContext *UsedContext) {
+    return new (C)
+        CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param, UsedContext);
+  }
+
   // Retrieve the parameter that the argument was created from.
   const ParmVarDecl *getParam() const { return Param; }
   ParmVarDecl *getParam() { return Param; }
 
-  bool hasRewrittenInit() const {
-    return CXXDefaultArgExprBits.HasRewrittenInit;
-  }
-
-  // Retrieve the argument to the function call.
-  Expr *getExpr();
-  const Expr *getExpr() const {
-    return const_cast<CXXDefaultArgExpr *>(this)->getExpr();
-  }
-
-  Expr *getRewrittenExpr() {
-    return hasRewrittenInit() ? *getTrailingObjects<Expr *>() : nullptr;
-  }
-
-  const Expr *getRewrittenExpr() const {
-    return const_cast<CXXDefaultArgExpr *>(this)->getRewrittenExpr();
-  }
-
-  // Retrieve the rewritten init expression (for an init expression containing
-  // immediate calls) with the top level FullExpr and ConstantExpr stripped off.
-  Expr *getAdjustedRewrittenExpr();
-  const Expr *getAdjustedRewrittenExpr() const {
-    return const_cast<CXXDefaultArgExpr *>(this)->getAdjustedRewrittenExpr();
-  }
+  // Retrieve the actual argument to the function call.
+  const Expr *getExpr() const { return getParam()->getDefaultArg(); }
+  Expr *getExpr() { return getParam()->getDefaultArg(); }
 
   const DeclContext *getUsedContext() const { return UsedContext; }
   DeclContext *getUsedContext() { return UsedContext; }
@@ -1356,13 +1322,10 @@ class CXXDefaultArgExpr final
 /// is implicitly used in a mem-initializer-list in a constructor
 /// (C++11 [class.base.init]p8) or in aggregate initialization
 /// (C++1y [dcl.init.aggr]p7).
-class CXXDefaultInitExpr final
-    : public Expr,
-      private llvm::TrailingObjects<CXXDefaultArgExpr, Expr *> {
-
-  friend class ASTStmtReader;
+class CXXDefaultInitExpr : public Expr {
   friend class ASTReader;
-  friend TrailingObjects;
+  friend class ASTStmtReader;
+
   /// The field whose default is being used.
   FieldDecl *Field;
 
@@ -1370,29 +1333,16 @@ class CXXDefaultInitExpr final
   DeclContext *UsedContext;
 
   CXXDefaultInitExpr(const ASTContext &Ctx, SourceLocation Loc,
-                     FieldDecl *Field, QualType Ty, DeclContext *UsedContext,
-                     Expr *RewrittenInitExpr);
-
-  CXXDefaultInitExpr(EmptyShell Empty, bool HasRewrittenInit)
-      : Expr(CXXDefaultInitExprClass, Empty) {
-    CXXDefaultInitExprBits.HasRewrittenInit = HasRewrittenInit;
-  }
+                     FieldDecl *Field, QualType Ty, DeclContext *UsedContext);
 
-  size_t numTrailingObjects() const {
-    return CXXDefaultInitExprBits.HasRewrittenInit;
-  }
+  CXXDefaultInitExpr(EmptyShell Empty) : Expr(CXXDefaultInitExprClass, Empty) {}
 
 public:
-  static CXXDefaultInitExpr *CreateEmpty(const ASTContext &C,
-                                         bool HasRewrittenInit);
   /// \p Field is the non-static data member whose default initializer is used
   /// by this expression.
   static CXXDefaultInitExpr *Create(const ASTContext &Ctx, SourceLocation Loc,
-                                    FieldDecl *Field, DeclContext *UsedContext,
-                                    Expr *RewrittenInitExpr);
-
-  bool hasRewrittenInit() const {
-    return CXXDefaultInitExprBits.HasRewrittenInit;
+                                    FieldDecl *Field, DeclContext *UsedContext) {
+    return new (Ctx) CXXDefaultInitExpr(Ctx, Loc, Field, Field->getType(), UsedContext);
   }
 
   /// Get the field whose initializer will be used.
@@ -1400,23 +1350,13 @@ class CXXDefaultInitExpr final
   const FieldDecl *getField() const { return Field; }
 
   /// Get the initialization expression that will be used.
-  Expr *getExpr();
   const Expr *getExpr() const {
-    return const_cast<CXXDefaultInitExpr *>(this)->getExpr();
-  }
-
-  /// Retrieve the initializing expression with evaluated immediate calls, if
-  /// any.
-  const Expr *getRewrittenExpr() const {
-    assert(hasRewrittenInit() && "expected a rewritten init expression");
-    return *getTrailingObjects<Expr *>();
+    assert(Field->getInClassInitializer() && "initializer hasn't been parsed");
+    return Field->getInClassInitializer();
   }
-
-  /// Retrieve the initializing expression with evaluated immediate calls, if
-  /// any.
-  Expr *getRewrittenExpr() {
-    assert(hasRewrittenInit() && "expected a rewritten init expression");
-    return *getTrailingObjects<Expr *>();
+  Expr *getExpr() {
+    assert(Field->getInClassInitializer() && "initializer hasn't been parsed");
+    return Field->getInClassInitializer();
   }
 
   const DeclContext *getUsedContext() const { return UsedContext; }

diff  --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 7f9d36ec1c4be..c65cdeb574cc9 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -690,9 +690,6 @@ class alignas(void *) Stmt {
 
     unsigned : NumExprBits;
 
-    /// Whether this CXXDefaultArgExpr rewrote its argument and stores a copy.
-    unsigned HasRewrittenInit : 1;
-
     /// The location where the default argument expression was used.
     SourceLocation Loc;
   };
@@ -703,10 +700,6 @@ class alignas(void *) Stmt {
 
     unsigned : NumExprBits;
 
-    /// Whether this CXXDefaultInitExprBitfields rewrote its argument and stores
-    /// a copy.
-    unsigned HasRewrittenInit : 1;
-
     /// The location where the default initializer expression was used.
     SourceLocation Loc;
   };

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index e13f059933a97..15f85b778ccc6 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2646,10 +2646,6 @@ def err_invalid_consteval_take_address : Error<
   " of an immediate invocation">;
 def err_invalid_consteval_call : Error<
   "call to consteval function %q0 is not a constant expression">;
-def note_invalid_consteval_initializer : Note<
-  "in the default initalizer of %0">;
-def note_invalid_consteval_initializer_here : Note<
-  "initialized here %0">;
 def err_invalid_consteval_decl_kind : Error<
   "%0 cannot be declared consteval">;
 def err_invalid_constexpr : Error<

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index a8614f742a7e9..e4ae554114807 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -1330,25 +1330,6 @@ class Sema final {
     bool InDiscardedStatement;
     bool InImmediateFunctionContext;
 
-    bool IsCurrentlyCheckingDefaultArgumentOrInitializer = false;
-
-    // When evaluating immediate functions in the initializer of a default
-    // argument or default member initializer, this is the declaration whose
-    // default initializer is being evaluated and the location of the call
-    // or constructor definition.
-    struct InitializationContext {
-      InitializationContext(SourceLocation Loc, ValueDecl *Decl,
-                            DeclContext *Context)
-          : Loc(Loc), Decl(Decl), Context(Context) {
-        assert(Decl && Context && "invalid initialization context");
-      }
-
-      SourceLocation Loc;
-      ValueDecl *Decl = nullptr;
-      DeclContext *Context = nullptr;
-    };
-    llvm::Optional<InitializationContext> DelayedDefaultInitializationContext;
-
     ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context,
                                       unsigned NumCleanupObjects,
                                       CleanupInfo ParentCleanup,
@@ -6229,22 +6210,19 @@ class Sema final {
                         bool IsStdInitListInitialization, bool RequiresZeroInit,
                         unsigned ConstructKind, SourceRange ParenRange);
 
-  ExprResult ConvertMemberDefaultInitExpression(FieldDecl *FD, Expr *InitExpr,
-                                                SourceLocation InitLoc);
-
   ExprResult BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field);
 
 
   /// Instantiate or parse a C++ default argument expression as necessary.
   /// Return true on error.
   bool CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD,
-                              ParmVarDecl *Param, Expr *Init = nullptr,
-                              bool SkipImmediateInvocations = true);
+                              ParmVarDecl *Param);
 
   /// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating
   /// the default expr if needed.
-  ExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD,
-                                    ParmVarDecl *Param, Expr *Init = nullptr);
+  ExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc,
+                                    FunctionDecl *FD,
+                                    ParmVarDecl *Param);
 
   /// FinalizeVarWithDestructor - Prepare for calling destructor on the
   /// constructed variable.
@@ -9648,63 +9626,6 @@ class Sema final {
     return ExprEvalContexts.back().isImmediateFunctionContext();
   }
 
-  bool isCheckingDefaultArgumentOrInitializer() const {
-    assert(!ExprEvalContexts.empty() &&
-           "Must be in an expression evaluation context");
-    const ExpressionEvaluationContextRecord &Ctx = ExprEvalContexts.back();
-    return (Ctx.Context ==
-            ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed) ||
-           Ctx.IsCurrentlyCheckingDefaultArgumentOrInitializer;
-  }
-
-  bool isCheckingDefaultArgumentOrInitializerOfOuterEntity() const {
-    assert(!ExprEvalContexts.empty() &&
-           "Must be in an expression evaluation context");
-    for (const auto &Ctx : llvm::reverse(ExprEvalContexts)) {
-      if ((Ctx.Context ==
-           ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed) ||
-          Ctx.IsCurrentlyCheckingDefaultArgumentOrInitializer)
-        return true;
-      if (Ctx.isConstantEvaluated() || Ctx.isImmediateFunctionContext() ||
-          Ctx.isUnevaluated())
-        return false;
-    }
-    return false;
-  }
-
-  llvm::Optional<ExpressionEvaluationContextRecord::InitializationContext>
-  InnermostDeclarationWithDelayedImmediateInvocations() const {
-    assert(!ExprEvalContexts.empty() &&
-           "Must be in an expression evaluation context");
-    for (const auto &Ctx : llvm::reverse(ExprEvalContexts)) {
-      if (Ctx.Context == ExpressionEvaluationContext::PotentiallyEvaluated &&
-          Ctx.DelayedDefaultInitializationContext)
-        return Ctx.DelayedDefaultInitializationContext;
-      if (Ctx.isConstantEvaluated() || Ctx.isImmediateFunctionContext() ||
-          Ctx.isUnevaluated())
-        break;
-    }
-    return llvm::None;
-  }
-
-  llvm::Optional<ExpressionEvaluationContextRecord::InitializationContext>
-  OutermostDeclarationWithDelayedImmediateInvocations() const {
-    assert(!ExprEvalContexts.empty() &&
-           "Must be in an expression evaluation context");
-    llvm::Optional<ExpressionEvaluationContextRecord::InitializationContext>
-        Res;
-    for (auto &Ctx : llvm::reverse(ExprEvalContexts)) {
-      if (Ctx.Context == ExpressionEvaluationContext::PotentiallyEvaluated &&
-          !Ctx.DelayedDefaultInitializationContext && Res)
-        break;
-      if (Ctx.isConstantEvaluated() || Ctx.isImmediateFunctionContext() ||
-          Ctx.isUnevaluated())
-        break;
-      Res = Ctx.DelayedDefaultInitializationContext;
-    }
-    return Res;
-  }
-
   /// RAII class used to determine whether SFINAE has
   /// trapped any errors that occur during template argument
   /// deduction.

diff  --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 42e903724663f..2c728911ee06b 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -7687,16 +7687,9 @@ ExpectedStmt ASTNodeImporter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
     if (Error Err = ImportDefaultArgOfParmVarDecl(*FromParam, ToParam))
       return std::move(Err);
   }
-  Expr *RewrittenInit = nullptr;
-  if (E->hasRewrittenInit()) {
-    ExpectedExpr ExprOrErr = import(E->getExpr());
-    if (!ExprOrErr)
-      return ExprOrErr.takeError();
-    RewrittenInit = ExprOrErr.get();
-  }
+
   return CXXDefaultArgExpr::Create(Importer.getToContext(), *ToUsedLocOrErr,
-                                   *ToParamOrErr, RewrittenInit,
-                                   *UsedContextOrErr);
+                                   *ToParamOrErr, *UsedContextOrErr);
 }
 
 ExpectedStmt
@@ -8388,16 +8381,8 @@ ExpectedStmt ASTNodeImporter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
     ToField->setInClassInitializer(*ToInClassInitializerOrErr);
   }
 
-  Expr *RewrittenInit = nullptr;
-  if (E->hasRewrittenInit()) {
-    ExpectedExpr ExprOrErr = import(E->getExpr());
-    if (!ExprOrErr)
-      return ExprOrErr.takeError();
-    RewrittenInit = ExprOrErr.get();
-  }
-
   return CXXDefaultInitExpr::Create(Importer.getToContext(), *ToBeginLocOrErr,
-                                    ToField, *UsedContextOrErr, RewrittenInit);
+                                    ToField, *UsedContextOrErr);
 }
 
 ExpectedStmt ASTNodeImporter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {

diff  --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 8d9b97fafb230..1efe9c6d40dc0 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2888,7 +2888,8 @@ Expr *ParmVarDecl::getDefaultArg() {
 
   Expr *Arg = getInit();
   if (auto *E = dyn_cast_or_null<FullExpr>(Arg))
-    return E->getSubExpr();
+    if (!isa<ConstantExpr>(E))
+      return E->getSubExpr();
 
   return Arg;
 }

diff  --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index 6a6f692dec787..3bf3eab72846c 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -949,43 +949,9 @@ const IdentifierInfo *UserDefinedLiteral::getUDSuffix() const {
   return cast<FunctionDecl>(getCalleeDecl())->getLiteralIdentifier();
 }
 
-CXXDefaultArgExpr *CXXDefaultArgExpr::CreateEmpty(const ASTContext &C,
-                                                  bool HasRewrittenInit) {
-  size_t Size = totalSizeToAlloc<Expr *>(HasRewrittenInit);
-  auto *Mem = C.Allocate(Size, alignof(CXXDefaultArgExpr));
-  return new (Mem) CXXDefaultArgExpr(EmptyShell(), HasRewrittenInit);
-}
-
-CXXDefaultArgExpr *CXXDefaultArgExpr::Create(const ASTContext &C,
-                                             SourceLocation Loc,
-                                             ParmVarDecl *Param,
-                                             Expr *RewrittenExpr,
-                                             DeclContext *UsedContext) {
-  size_t Size = totalSizeToAlloc<Expr *>(RewrittenExpr != nullptr);
-  auto *Mem = C.Allocate(Size, alignof(CXXDefaultArgExpr));
-  return new (Mem) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param,
-                                     RewrittenExpr, UsedContext);
-}
-
-Expr *CXXDefaultArgExpr::getExpr() {
-  return CXXDefaultArgExprBits.HasRewrittenInit ? getAdjustedRewrittenExpr()
-                                                : getParam()->getDefaultArg();
-}
-
-Expr *CXXDefaultArgExpr::getAdjustedRewrittenExpr() {
-  assert(hasRewrittenInit() &&
-         "expected this CXXDefaultArgExpr to have a rewritten init.");
-  Expr *Init = getRewrittenExpr();
-  if (auto *E = dyn_cast_if_present<FullExpr>(Init))
-    if (!isa<ConstantExpr>(E))
-      return E->getSubExpr();
-  return Init;
-}
-
 CXXDefaultInitExpr::CXXDefaultInitExpr(const ASTContext &Ctx,
                                        SourceLocation Loc, FieldDecl *Field,
-                                       QualType Ty, DeclContext *UsedContext,
-                                       Expr *RewrittenInitExpr)
+                                       QualType Ty, DeclContext *UsedContext)
     : Expr(CXXDefaultInitExprClass, Ty.getNonLValueExprType(Ctx),
            Ty->isLValueReferenceType()   ? VK_LValue
            : Ty->isRValueReferenceType() ? VK_XValue
@@ -993,43 +959,11 @@ CXXDefaultInitExpr::CXXDefaultInitExpr(const ASTContext &Ctx,
            /*FIXME*/ OK_Ordinary),
       Field(Field), UsedContext(UsedContext) {
   CXXDefaultInitExprBits.Loc = Loc;
-  CXXDefaultInitExprBits.HasRewrittenInit = RewrittenInitExpr != nullptr;
-
-  if (CXXDefaultInitExprBits.HasRewrittenInit)
-    *getTrailingObjects<Expr *>() = RewrittenInitExpr;
-
   assert(Field->hasInClassInitializer());
 
   setDependence(computeDependence(this));
 }
 
-CXXDefaultInitExpr *CXXDefaultInitExpr::CreateEmpty(const ASTContext &C,
-                                                    bool HasRewrittenInit) {
-  size_t Size = totalSizeToAlloc<Expr *>(HasRewrittenInit);
-  auto *Mem = C.Allocate(Size, alignof(CXXDefaultInitExpr));
-  return new (Mem) CXXDefaultInitExpr(EmptyShell(), HasRewrittenInit);
-}
-
-CXXDefaultInitExpr *CXXDefaultInitExpr::Create(const ASTContext &Ctx,
-                                               SourceLocation Loc,
-                                               FieldDecl *Field,
-                                               DeclContext *UsedContext,
-                                               Expr *RewrittenInitExpr) {
-
-  size_t Size = totalSizeToAlloc<Expr *>(RewrittenInitExpr != nullptr);
-  auto *Mem = Ctx.Allocate(Size, alignof(CXXDefaultArgExpr));
-  return new (Mem) CXXDefaultInitExpr(Ctx, Loc, Field, Field->getType(),
-                                      UsedContext, RewrittenInitExpr);
-}
-
-Expr *CXXDefaultInitExpr::getExpr() {
-  assert(Field->getInClassInitializer() && "initializer hasn't been parsed");
-  if (hasRewrittenInit())
-    return getRewrittenExpr();
-
-  return Field->getInClassInitializer();
-}
-
 CXXTemporary *CXXTemporary::Create(const ASTContext &C,
                                    const CXXDestructorDecl *Destructor) {
   return new (C) CXXTemporary(Destructor);

diff  --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index 3a7f5426d4a70..d918ea26b9d9d 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -648,11 +648,6 @@ void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) {
 
   Actions.ActOnStartCXXInClassMemberInitializer();
 
-  // The initializer isn't actually potentially evaluated unless it is
-  // used.
-  EnterExpressionEvaluationContext Eval(
-      Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed);
-
   ExprResult Init = ParseCXXMemberInitializer(MI.Field, /*IsFunction=*/false,
                                               EqualLoc);
 

diff  --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 2402ad5416785..e244cfc9948ce 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -3188,11 +3188,7 @@ ExprResult Parser::ParseCXXMemberInitializer(Decl *D, bool IsFunction,
          "Data member initializer not starting with '=' or '{'");
 
   EnterExpressionEvaluationContext Context(
-      Actions,
-      isa_and_present<FieldDecl>(D)
-          ? Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed
-          : Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
-      D);
+      Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluated, D);
   if (TryConsumeToken(tok::equal, EqualLoc)) {
     if (Tok.is(tok::kw_delete)) {
       // In principle, an initializer of '= delete p;' is legal, but it will

diff  --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index fe33f6f360771..194298ab5f7bf 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -4059,21 +4059,6 @@ ExprResult Sema::ActOnRequiresClause(ExprResult ConstraintExpr) {
   return ConstraintExpr;
 }
 
-ExprResult Sema::ConvertMemberDefaultInitExpression(FieldDecl *FD,
-                                                    Expr *InitExpr,
-                                                    SourceLocation InitLoc) {
-  InitializedEntity Entity =
-      InitializedEntity::InitializeMemberFromDefaultMemberInitializer(FD);
-  InitializationKind Kind =
-      FD->getInClassInitStyle() == ICIS_ListInit
-          ? InitializationKind::CreateDirectList(InitExpr->getBeginLoc(),
-                                                 InitExpr->getBeginLoc(),
-                                                 InitExpr->getEndLoc())
-          : InitializationKind::CreateCopy(InitExpr->getBeginLoc(), InitLoc);
-  InitializationSequence Seq(*this, Entity, Kind, InitExpr);
-  return Seq.Perform(*this, Entity, Kind, InitExpr);
-}
-
 /// This is invoked after parsing an in-class initializer for a
 /// non-static C++ class member, and after instantiating an in-class initializer
 /// in a class template. Such actions are deferred until the class is complete.
@@ -4102,13 +4087,31 @@ void Sema::ActOnFinishCXXInClassMemberInitializer(Decl *D,
 
   ExprResult Init = InitExpr;
   if (!FD->getType()->isDependentType() && !InitExpr->isTypeDependent()) {
-    Init = ConvertMemberDefaultInitExpression(FD, InitExpr, InitLoc);
+    InitializedEntity Entity =
+        InitializedEntity::InitializeMemberFromDefaultMemberInitializer(FD);
+    InitializationKind Kind =
+        FD->getInClassInitStyle() == ICIS_ListInit
+            ? InitializationKind::CreateDirectList(InitExpr->getBeginLoc(),
+                                                   InitExpr->getBeginLoc(),
+                                                   InitExpr->getEndLoc())
+            : InitializationKind::CreateCopy(InitExpr->getBeginLoc(), InitLoc);
+    InitializationSequence Seq(*this, Entity, Kind, InitExpr);
+    Init = Seq.Perform(*this, Entity, Kind, InitExpr);
     if (Init.isInvalid()) {
       FD->setInvalidDecl();
       return;
     }
   }
 
+  // C++11 [class.base.init]p7:
+  //   The initialization of each base and member constitutes a
+  //   full-expression.
+  Init = ActOnFinishFullExpr(Init.get(), InitLoc, /*DiscardedValue*/ false);
+  if (Init.isInvalid()) {
+    FD->setInvalidDecl();
+    return;
+  }
+
   InitExpr = Init.get();
 
   FD->setInClassInitializer(InitExpr);
@@ -15644,6 +15647,70 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
       Constructor);
 }
 
+ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field) {
+  assert(Field->hasInClassInitializer());
+
+  // If we already have the in-class initializer nothing needs to be done.
+  if (Field->getInClassInitializer())
+    return CXXDefaultInitExpr::Create(Context, Loc, Field, CurContext);
+
+  // If we might have already tried and failed to instantiate, don't try again.
+  if (Field->isInvalidDecl())
+    return ExprError();
+
+  // Maybe we haven't instantiated the in-class initializer. Go check the
+  // pattern FieldDecl to see if it has one.
+  CXXRecordDecl *ParentRD = cast<CXXRecordDecl>(Field->getParent());
+
+  if (isTemplateInstantiation(ParentRD->getTemplateSpecializationKind())) {
+    CXXRecordDecl *ClassPattern = ParentRD->getTemplateInstantiationPattern();
+    DeclContext::lookup_result Lookup =
+        ClassPattern->lookup(Field->getDeclName());
+
+    FieldDecl *Pattern = nullptr;
+    for (auto *L : Lookup) {
+      if (isa<FieldDecl>(L)) {
+        Pattern = cast<FieldDecl>(L);
+        break;
+      }
+    }
+    assert(Pattern && "We must have set the Pattern!");
+
+    if (!Pattern->hasInClassInitializer() ||
+        InstantiateInClassInitializer(Loc, Field, Pattern,
+                                      getTemplateInstantiationArgs(Field))) {
+      // Don't diagnose this again.
+      Field->setInvalidDecl();
+      return ExprError();
+    }
+    return CXXDefaultInitExpr::Create(Context, Loc, Field, CurContext);
+  }
+
+  // DR1351:
+  //   If the brace-or-equal-initializer of a non-static data member
+  //   invokes a defaulted default constructor of its class or of an
+  //   enclosing class in a potentially evaluated subexpression, the
+  //   program is ill-formed.
+  //
+  // This resolution is unworkable: the exception specification of the
+  // default constructor can be needed in an unevaluated context, in
+  // particular, in the operand of a noexcept-expression, and we can be
+  // unable to compute an exception specification for an enclosed class.
+  //
+  // Any attempt to resolve the exception specification of a defaulted default
+  // constructor before the initializer is lexically complete will ultimately
+  // come here at which point we can diagnose it.
+  RecordDecl *OutermostClass = ParentRD->getOuterLexicalRecordContext();
+  Diag(Loc, diag::err_default_member_initializer_not_yet_parsed)
+      << OutermostClass << Field;
+  Diag(Field->getEndLoc(),
+       diag::note_default_member_initializer_not_yet_parsed);
+  // Recover by marking the field invalid, unless we're in a SFINAE context.
+  if (!isSFINAEContext())
+    Field->setInvalidDecl();
+  return ExprError();
+}
+
 void Sema::FinalizeVarWithDestructor(VarDecl *VD, const RecordType *Record) {
   if (VD->isInvalidDecl()) return;
   // If initializing the variable failed, don't also diagnose problems with

diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 9d9107f78d74b..06c70fbba6ffa 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -5856,10 +5856,8 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
 }
 
 bool Sema::CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD,
-                                  ParmVarDecl *Param, Expr *RewrittenInit,
-                                  bool SkipImmediateInvocations) {
+                                  ParmVarDecl *Param) {
   if (Param->hasUnparsedDefaultArg()) {
-    assert(!RewrittenInit && "Should not have a rewritten init expression yet");
     // If we've already cleared out the location for the default argument,
     // that means we're parsing it right now.
     if (!UnparsedDefaultArgLocs.count(Param)) {
@@ -5876,14 +5874,11 @@ bool Sema::CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD,
     return true;
   }
 
-  if (Param->hasUninstantiatedDefaultArg()) {
-    assert(!RewrittenInit && "Should not have a rewitten init expression yet");
-    if (InstantiateDefaultArgument(CallLoc, FD, Param))
-      return true;
-  }
+  if (Param->hasUninstantiatedDefaultArg() &&
+      InstantiateDefaultArgument(CallLoc, FD, Param))
+    return true;
 
-  Expr *Init = RewrittenInit ? RewrittenInit : Param->getInit();
-  assert(Init && "default argument but no initializer?");
+  assert(Param->hasInit() && "default argument but no initializer?");
 
   // If the default expression creates temporaries, we need to
   // push them to the current stack of expression temporaries so they'll
@@ -5892,250 +5887,34 @@ bool Sema::CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD,
   // bound temporaries; see the comment in PR5810.
   // We don't need to do that with block decls, though, because
   // blocks in default argument expression can never capture anything.
-  if (auto *InitWithCleanup = dyn_cast<ExprWithCleanups>(Init)) {
+  if (auto Init = dyn_cast<ExprWithCleanups>(Param->getInit())) {
     // Set the "needs cleanups" bit regardless of whether there are
     // any explicit objects.
-    Cleanup.setExprNeedsCleanups(InitWithCleanup->cleanupsHaveSideEffects());
+    Cleanup.setExprNeedsCleanups(Init->cleanupsHaveSideEffects());
+
     // Append all the objects to the cleanup list.  Right now, this
     // should always be a no-op, because blocks in default argument
     // expressions should never be able to capture anything.
-    assert(!InitWithCleanup->getNumObjects() &&
+    assert(!Init->getNumObjects() &&
            "default argument expression has capturing blocks?");
   }
+
+  // We already type-checked the argument, so we know it works.
+  // Just mark all of the declarations in this potentially-evaluated expression
+  // as being "referenced".
   EnterExpressionEvaluationContext EvalContext(
       *this, ExpressionEvaluationContext::PotentiallyEvaluated, Param);
-  ExprEvalContexts.back().IsCurrentlyCheckingDefaultArgumentOrInitializer =
-      SkipImmediateInvocations;
-  MarkDeclarationsReferencedInExpr(Init, /*SkipLocalVariables*/ true);
+  MarkDeclarationsReferencedInExpr(Param->getDefaultArg(),
+                                   /*SkipLocalVariables=*/true);
   return false;
 }
 
-struct ImmediateCallVisitor : public RecursiveASTVisitor<ImmediateCallVisitor> {
-  bool HasImmediateCalls = false;
-
-  bool VisitCallExpr(CallExpr *E) {
-    if (const FunctionDecl *FD = E->getDirectCallee())
-      HasImmediateCalls |= FD->isConsteval();
-    return RecursiveASTVisitor<ImmediateCallVisitor>::VisitStmt(E);
-  }
-
-  // SourceLocExpr are not immediate invocations
-  // but CXXDefaultInitExpr/CXXDefaultArgExpr containing a SourceLocExpr
-  // need to be rebuilt so that they refer to the correct SourceLocation and
-  // DeclContext.
-  bool VisitSourceLocExpr(SourceLocExpr *E) {
-    HasImmediateCalls = true;
-    return RecursiveASTVisitor<ImmediateCallVisitor>::VisitStmt(E);
-  }
-
-  // A nested lambda might have parameters with immediate invocations
-  // in their default arguments.
-  // The compound statement is not visited (as it does not constitute a
-  // subexpression).
-  // FIXME: We should consider visiting and transforming captures
-  // with init expressions.
-  bool VisitLambdaExpr(LambdaExpr *E) {
-    return VisitCXXMethodDecl(E->getCallOperator());
-  }
-
-  // Blocks don't support default parameters, and, as for lambdas,
-  // we don't consider their body a subexpression.
-  bool VisitBlockDecl(BlockDecl *B) { return false; }
-
-  bool VisitCompoundStmt(CompoundStmt *B) { return false; }
-
-  bool VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
-    return TraverseStmt(E->getExpr());
-  }
-
-  bool VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
-    return TraverseStmt(E->getExpr());
-  }
-};
-
-struct EnsureImmediateInvocationInDefaultArgs
-    : TreeTransform<EnsureImmediateInvocationInDefaultArgs> {
-  EnsureImmediateInvocationInDefaultArgs(Sema &SemaRef)
-      : TreeTransform(SemaRef) {}
-
-  // Lambda can only have immediate invocations in the default
-  // args of their parameters, which is transformed upon calling the closure.
-  // The body is not a subexpression, so we have nothing to do.
-  // FIXME: Immediate calls in capture initializers should be transformed.
-  ExprResult TransformLambdaExpr(LambdaExpr *E) { return E; }
-  ExprResult TransformBlockExpr(BlockExpr *E) { return E; }
-};
-
 ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
-                                        FunctionDecl *FD, ParmVarDecl *Param,
-                                        Expr *Init) {
+                                        FunctionDecl *FD, ParmVarDecl *Param) {
   assert(Param->hasDefaultArg() && "can't build nonexistent default arg");
-
-  bool NestedDefaultChecking =
-      isCheckingDefaultArgumentOrInitializerOfOuterEntity();
-
-  llvm::Optional<ExpressionEvaluationContextRecord::InitializationContext>
-      InitializationContext =
-          OutermostDeclarationWithDelayedImmediateInvocations();
-  if (!InitializationContext.has_value())
-    InitializationContext.emplace(CallLoc, Param, CurContext);
-
-  if (!Init && !Param->hasUnparsedDefaultArg()) {
-    // Mark that we are replacing a default argument first.
-    // If we are instantiating a template we won't have to
-    // retransform immediate calls.
-    EnterExpressionEvaluationContext EvalContext(
-        *this, ExpressionEvaluationContext::PotentiallyEvaluated, Param);
-    ExprEvalContexts.back().DelayedDefaultInitializationContext = {
-        CallLoc, Param, CurContext};
-
-    if (Param->hasUninstantiatedDefaultArg()) {
-      if (InstantiateDefaultArgument(CallLoc, FD, Param))
-        return ExprError();
-    } else {
-      // CWG2631
-      // An immediate invocation that is not evaluated where it appears is
-      // evaluated and checked for whether it is a constant expression at the
-      // point where the enclosing initializer is used in a function call.
-      ImmediateCallVisitor V;
-      if (!NestedDefaultChecking)
-        V.TraverseDecl(Param);
-      if (V.HasImmediateCalls) {
-        EnsureImmediateInvocationInDefaultArgs Immediate(*this);
-        ExprResult Res = Immediate.TransformExpr(Param->getInit());
-        if (Res.isInvalid())
-          return ExprError();
-        Res = ConvertParamDefaultArgument(Param, Res.get(),
-                                          Res.get()->getBeginLoc());
-        if (Res.isInvalid())
-          return ExprError();
-        Init = Res.get();
-      }
-    }
-  }
-
-  if (CheckCXXDefaultArgExpr(
-          CallLoc, FD, Param, Init,
-          /*SkipImmediateInvocations=*/NestedDefaultChecking))
-    return ExprError();
-
-  return CXXDefaultArgExpr::Create(Context, InitializationContext->Loc, Param,
-                                   Init, InitializationContext->Context);
-}
-
-ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field) {
-  assert(Field->hasInClassInitializer());
-
-  // If we might have already tried and failed to instantiate, don't try again.
-  if (Field->isInvalidDecl())
+  if (CheckCXXDefaultArgExpr(CallLoc, FD, Param))
     return ExprError();
-
-  auto *ParentRD = cast<CXXRecordDecl>(Field->getParent());
-
-  llvm::Optional<ExpressionEvaluationContextRecord::InitializationContext>
-      InitializationContext =
-          OutermostDeclarationWithDelayedImmediateInvocations();
-  if (!InitializationContext.has_value())
-    InitializationContext.emplace(Loc, Field, CurContext);
-
-  Expr *Init = nullptr;
-
-  bool NestedDefaultChecking =
-      isCheckingDefaultArgumentOrInitializerOfOuterEntity();
-
-  if (!Field->getInClassInitializer()) {
-    // Maybe we haven't instantiated the in-class initializer. Go check the
-    // pattern FieldDecl to see if it has one.
-    if (isTemplateInstantiation(ParentRD->getTemplateSpecializationKind())) {
-      CXXRecordDecl *ClassPattern = ParentRD->getTemplateInstantiationPattern();
-      DeclContext::lookup_result Lookup =
-          ClassPattern->lookup(Field->getDeclName());
-
-      FieldDecl *Pattern = nullptr;
-      for (auto *L : Lookup) {
-        if ((Pattern = dyn_cast<FieldDecl>(L)))
-          break;
-      }
-      assert(Pattern && "We must have set the Pattern!");
-      if (!Pattern->hasInClassInitializer() ||
-          InstantiateInClassInitializer(Loc, Field, Pattern,
-                                        getTemplateInstantiationArgs(Field))) {
-        Field->setInvalidDecl();
-        return ExprError();
-      }
-    }
-  } else {
-    // CWG2631
-    // An immediate invocation that is not evaluated where it appears is
-    // evaluated and checked for whether it is a constant expression at the
-    // point where the enclosing initializer is used in a [...] a constructor
-    // definition, or an aggregate initialization.
-    EnterExpressionEvaluationContext EvalContext(
-        *this, ExpressionEvaluationContext::PotentiallyEvaluated, Field);
-    ExprEvalContexts.back().DelayedDefaultInitializationContext = {Loc, Field,
-                                                                   CurContext};
-
-    ImmediateCallVisitor V;
-    if (!NestedDefaultChecking)
-      V.TraverseDecl(Field);
-    if (V.HasImmediateCalls) {
-      EnsureImmediateInvocationInDefaultArgs Immediate(*this);
-      ExprResult Res = Immediate.TransformExpr(Field->getInClassInitializer());
-      if (!Res.isInvalid())
-        Res = ConvertMemberDefaultInitExpression(Field, Res.get(), Loc);
-      if (Res.isInvalid()) {
-        Field->setInvalidDecl();
-        return ExprError();
-      }
-      Init = Res.get();
-    }
-  }
-
-  if (Field->getInClassInitializer()) {
-    Expr *E = Init ? Init : Field->getInClassInitializer();
-    if (!NestedDefaultChecking) {
-      EnterExpressionEvaluationContext EvalContext(
-          *this, ExpressionEvaluationContext::PotentiallyEvaluated, Field);
-      MarkDeclarationsReferencedInExpr(E, /*SkipLocalVariables=*/false);
-    }
-    // C++11 [class.base.init]p7:
-    //   The initialization of each base and member constitutes a
-    //   full-expression.
-    ExprResult Res = ActOnFinishFullExpr(E, /*DiscardedValue=*/false);
-    if (Res.isInvalid()) {
-      Field->setInvalidDecl();
-      return ExprError();
-    }
-    Init = Res.get();
-
-    return CXXDefaultInitExpr::Create(Context, InitializationContext->Loc,
-                                      Field, InitializationContext->Context,
-                                      Init);
-  }
-
-  // DR1351:
-  //   If the brace-or-equal-initializer of a non-static data member
-  //   invokes a defaulted default constructor of its class or of an
-  //   enclosing class in a potentially evaluated subexpression, the
-  //   program is ill-formed.
-  //
-  // This resolution is unworkable: the exception specification of the
-  // default constructor can be needed in an unevaluated context, in
-  // particular, in the operand of a noexcept-expression, and we can be
-  // unable to compute an exception specification for an enclosed class.
-  //
-  // Any attempt to resolve the exception specification of a defaulted default
-  // constructor before the initializer is lexically complete will ultimately
-  // come here at which point we can diagnose it.
-  RecordDecl *OutermostClass = ParentRD->getOuterLexicalRecordContext();
-  Diag(Loc, diag::err_default_member_initializer_not_yet_parsed)
-      << OutermostClass << Field;
-  Diag(Field->getEndLoc(),
-       diag::note_default_member_initializer_not_yet_parsed);
-  // Recover by marking the field invalid, unless we're in a SFINAE context.
-  if (!isSFINAEContext())
-    Field->setInvalidDecl();
-  return ExprError();
+  return CXXDefaultArgExpr::Create(Context, CallLoc, Param, CurContext);
 }
 
 Sema::VariadicCallType
@@ -17762,7 +17541,6 @@ void Sema::CheckUnusedVolatileAssignment(Expr *E) {
 ExprResult Sema::CheckForImmediateInvocation(ExprResult E, FunctionDecl *Decl) {
   if (isUnevaluatedContext() || !E.isUsable() || !Decl ||
       !Decl->isConsteval() || isConstantEvaluated() ||
-      isCheckingDefaultArgumentOrInitializer() ||
       RebuildingImmediateInvocation || isImmediateFunctionContext())
     return E;
 
@@ -17808,14 +17586,8 @@ static void EvaluateAndDiagnoseImmediateInvocation(
       FD = Call->getConstructor();
     else
       llvm_unreachable("unhandled decl kind");
-    assert(FD && FD->isConsteval());
+    assert(FD->isConsteval());
     SemaRef.Diag(CE->getBeginLoc(), diag::err_invalid_consteval_call) << FD;
-    if (auto Context =
-            SemaRef.InnermostDeclarationWithDelayedImmediateInvocations()) {
-      SemaRef.Diag(Context->Loc, diag::note_invalid_consteval_initializer)
-          << Context->Decl;
-      SemaRef.Diag(Context->Decl->getBeginLoc(), diag::note_declared_at);
-    }
     for (auto &Note : Notes)
       SemaRef.Diag(Note.first, Note.second);
     return;
@@ -19961,8 +19733,7 @@ void Sema::MarkDeclRefReferenced(DeclRefExpr *E, const Expr *Base) {
 
   if (auto *FD = dyn_cast<FunctionDecl>(E->getDecl()))
     if (!isUnevaluatedContext() && !isConstantEvaluated() &&
-        !isImmediateFunctionContext() &&
-        !isCheckingDefaultArgumentOrInitializer() && FD->isConsteval() &&
+        !isImmediateFunctionContext() && FD->isConsteval() &&
         !RebuildingImmediateInvocation && !FD->isDependentContext())
       ExprEvalContexts.back().ReferenceToConsteval.insert(E);
   MarkExprReferenced(*this, E->getLocation(), E->getDecl(), E, OdrUse,

diff  --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 709162e01809b..9e41dfbfdbe95 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1978,9 +1978,9 @@ ExprResult TemplateInstantiator::TransformCXXDefaultArgExpr(
   assert(!cast<FunctionDecl>(E->getParam()->getDeclContext())->
              getDescribedFunctionTemplate() &&
          "Default arg expressions are never formed in dependent cases.");
-  return SemaRef.BuildCXXDefaultArgExpr(
-      E->getUsedLocation(), cast<FunctionDecl>(E->getParam()->getDeclContext()),
-      E->getParam());
+  return SemaRef.BuildCXXDefaultArgExpr(E->getUsedLocation(),
+                           cast<FunctionDecl>(E->getParam()->getDeclContext()),
+                                        E->getParam());
 }
 
 template<typename Fn>
@@ -3407,8 +3407,6 @@ bool Sema::InstantiateInClassInitializer(
   ContextRAII SavedContext(*this, Instantiation->getParent());
   EnterExpressionEvaluationContext EvalContext(
       *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
-  ExprEvalContexts.back().DelayedDefaultInitializationContext = {
-      PointOfInstantiation, Instantiation, CurContext};
 
   LocalInstantiationScope Scope(*this, true);
 

diff  --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 701ceb64cdbcf..019ea3efd1a6b 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -3211,10 +3211,9 @@ class TreeTransform {
   /// By default, builds a new default-argument expression, which does not
   /// require any semantic analysis. Subclasses may override this routine to
   /// provide 
diff erent behavior.
-  ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param,
-                                      Expr *RewrittenExpr) {
+  ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param) {
     return CXXDefaultArgExpr::Create(getSema().Context, Loc, Param,
-                                     RewrittenExpr, getSema().CurContext);
+                                     getSema().CurContext);
   }
 
   /// Build a new C++11 default-initialization expression.
@@ -3224,7 +3223,8 @@ class TreeTransform {
   /// routine to provide 
diff erent behavior.
   ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,
                                        FieldDecl *Field) {
-    return getSema().BuildCXXDefaultInitExpr(Loc, Field);
+    return CXXDefaultInitExpr::Create(getSema().Context, Loc, Field,
+                                      getSema().CurContext);
   }
 
   /// Build a new C++ zero-initialization expression.
@@ -12161,20 +12161,11 @@ TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
   if (!Param)
     return ExprError();
 
-  ExprResult InitRes;
-  if (E->hasRewrittenInit()) {
-    InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
-    if (InitRes.isInvalid())
-      return ExprError();
-  }
-
   if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
-      E->getUsedContext() == SemaRef.CurContext &&
-      InitRes.get() == E->getRewrittenExpr())
+      E->getUsedContext() == SemaRef.CurContext)
     return E;
 
-  return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
-                                               InitRes.get());
+  return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param);
 }
 
 template<typename Derived>

diff  --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 08f9f0bf50d03..2a3c6e7231785 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -1824,9 +1824,6 @@ void ASTStmtReader::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
   E->Param = readDeclAs<ParmVarDecl>();
   E->UsedContext = readDeclAs<DeclContext>();
   E->CXXDefaultArgExprBits.Loc = readSourceLocation();
-  E->CXXDefaultArgExprBits.HasRewrittenInit = Record.readInt();
-  if (E->CXXDefaultArgExprBits.HasRewrittenInit)
-    *E->getTrailingObjects<Expr *>() = Record.readSubExpr();
 }
 
 void ASTStmtReader::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
@@ -1834,9 +1831,6 @@ void ASTStmtReader::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
   E->Field = readDeclAs<FieldDecl>();
   E->UsedContext = readDeclAs<DeclContext>();
   E->CXXDefaultInitExprBits.Loc = readSourceLocation();
-  E->CXXDefaultInitExprBits.HasRewrittenInit = Record.readInt();
-  if (E->CXXDefaultInitExprBits.HasRewrittenInit)
-    *E->getTrailingObjects<Expr *>() = Record.readSubExpr();
 }
 
 void ASTStmtReader::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
@@ -3835,13 +3829,11 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
       break;
 
     case EXPR_CXX_DEFAULT_ARG:
-      S = CXXDefaultArgExpr::CreateEmpty(
-          Context, /*HasRewrittenInit=*/Record[ASTStmtReader::NumExprFields]);
+      S = new (Context) CXXDefaultArgExpr(Empty);
       break;
 
     case EXPR_CXX_DEFAULT_INIT:
-      S = CXXDefaultInitExpr::CreateEmpty(
-          Context, /*HasRewrittenInit=*/Record[ASTStmtReader::NumExprFields]);
+      S = new (Context) CXXDefaultInitExpr(Empty);
       break;
 
     case EXPR_CXX_BIND_TEMPORARY:

diff  --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index 6e4101ac122ee..e2ba69ca1eec8 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -1745,9 +1745,6 @@ void ASTStmtWriter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
   Record.AddDeclRef(E->getParam());
   Record.AddDeclRef(cast_or_null<Decl>(E->getUsedContext()));
   Record.AddSourceLocation(E->getUsedLocation());
-  Record.push_back(E->hasRewrittenInit());
-  if (E->hasRewrittenInit())
-    Record.AddStmt(E->getRewrittenExpr());
   Code = serialization::EXPR_CXX_DEFAULT_ARG;
 }
 
@@ -1756,9 +1753,6 @@ void ASTStmtWriter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
   Record.AddDeclRef(E->getField());
   Record.AddDeclRef(cast_or_null<Decl>(E->getUsedContext()));
   Record.AddSourceLocation(E->getExprLoc());
-  Record.push_back(E->hasRewrittenInit());
-  if (E->hasRewrittenInit())
-    Record.AddStmt(E->getRewrittenExpr());
   Code = serialization::EXPR_CXX_DEFAULT_INIT;
 }
 

diff  --git a/clang/test/CXX/class/class.local/p1-0x.cpp b/clang/test/CXX/class/class.local/p1-0x.cpp
index 096f5080099ec..49125f5f9b062 100644
--- a/clang/test/CXX/class/class.local/p1-0x.cpp
+++ b/clang/test/CXX/class/class.local/p1-0x.cpp
@@ -11,8 +11,8 @@ void f() {
     int x = 3; // expected-note{{'x' declared here}}
     struct C {
       int& x2 = x; // expected-error{{reference to local variable 'x' declared in enclosing lambda expression}}
-    }c; // expected-note {{required here}}
+    };
   };
-  C(); // expected-note {{required here}}
+  C();
 }
 

diff  --git a/clang/test/CXX/drs/dr26xx.cpp b/clang/test/CXX/drs/dr26xx.cpp
index 68a0e9b2a2688..6aa0e5053bc9a 100644
--- a/clang/test/CXX/drs/dr26xx.cpp
+++ b/clang/test/CXX/drs/dr26xx.cpp
@@ -88,19 +88,3 @@ void f() {
     brachiosaur |= neck;                // OK
 }
 }
-
-namespace dr2631 { // dr2631: 16
-  constexpr int g();
-  consteval int f() {
-    return g();
-  }
-  int k(int x = f()) {
-    return x;
-  }
-  constexpr int g() {
-    return 42;
-  }
-  int test() {
-    return k();
-  }
-}

diff  --git a/clang/test/CodeGenCXX/builtin-source-location.cpp b/clang/test/CodeGenCXX/builtin-source-location.cpp
index 7af6749d0d6d6..6e44e6b0e60e3 100644
--- a/clang/test/CodeGenCXX/builtin-source-location.cpp
+++ b/clang/test/CodeGenCXX/builtin-source-location.cpp
@@ -1,6 +1,4 @@
 // RUN: %clang_cc1 -no-opaque-pointers -std=c++2a -fblocks %s -triple x86_64-unknown-unknown -emit-llvm -o %t.ll
-// RUN: %clang_cc1 -no-opaque-pointers -std=c++14 -fblocks %s -triple x86_64-unknown-unknown -emit-llvm -o %t.ll
-
 
 // This needs to be performed before #line directives which alter filename
 // RUN: %clang_cc1 -no-opaque-pointers -fno-file-reproducible -fmacro-prefix-map=%p=/UNLIKELY/PATH -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-PREFIX-MAP

diff  --git a/clang/test/CodeGenCXX/default-arguments-with-immediate.cpp b/clang/test/CodeGenCXX/default-arguments-with-immediate.cpp
deleted file mode 100644
index 54a02ffc06836..0000000000000
--- a/clang/test/CodeGenCXX/default-arguments-with-immediate.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-// RUN: %clang_cc1 -std=c++2a -triple x86_64-elf-gnu %s -emit-llvm -o - | FileCheck %s
-
-consteval int immediate() { return 0;}
-static int ext();
-void f(int a = immediate() + ext());
-
-void test_function() {
-    f();
-    f(0);
-    // CHECK: call noundef i32 @_ZL3extv()
-    // CHECK: add
-    // CHECK: call {{.*}} @_Z1fi
-    // CHECK: call {{.*}} @_Z1fi
-}
-
-// CHECK: define {{.*}} i32 @_ZL3extv()
-
-static constexpr int not_immediate();
-struct A {
-    int a = immediate() + not_immediate();
-};
-
-void test_member() {
-    // CHECK: call void @_ZN1AC2Ev
-    A defaulted;
-    // CHECK-NOT: call void @_ZN1AC2Ev
-    A provided{0};
-}
-
-// CHECK: define {{.*}} void @_ZN1AC2Ev{{.*}}
-// CHECK: %call = call noundef i32 @_ZL13not_immediatev()
-
-int never_referenced() {return 42;};
-
-
-namespace not_used {
-
-struct A {
-    int a = immediate() + never_referenced();
-};
-void f(int a = immediate() + never_referenced());
-
-void g() {
-    A a{0};
-    f(0);
-}
-
-}
-
-static int ext() {return 0;}
-static constexpr int not_immediate() {return 0;}
-
-// CHECK-NOT: define {{.*}} i32 _ZL16never_referencedv()(
-// CHECK: define {{.*}} i32 @_ZL13not_immediatev()

diff  --git a/clang/test/PCH/default-argument-with-immediate-calls.cpp b/clang/test/PCH/default-argument-with-immediate-calls.cpp
deleted file mode 100644
index 510605a23d4e7..0000000000000
--- a/clang/test/PCH/default-argument-with-immediate-calls.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-// RUN: %clang_cc1 -std=c++20 -emit-pch %s -o %t
-// RUN: %clang_cc1 -std=c++20 -include-pch %t -verify %s
-// expected-no-diagnostics
-
-#ifndef HEADER_INCLUDED
-#define HEADER_INCLUDED
-
-consteval int immediate();
-int regular_function() {
-    return 0;
-}
-
-struct S {
-  int a = immediate() + regular_function();
-};
-
-int f(int arg = immediate()) {
-    return arg;
-}
-
-#else
-
-consteval int immediate() {
-    return 0;
-}
-
-void test() {
-    f(0);
-    f();
-    S s{0};
-    S t{0};
-}
-
-#endif

diff  --git a/clang/test/SemaCXX/cxx11-default-member-initializers.cpp b/clang/test/SemaCXX/cxx11-default-member-initializers.cpp
index d32ff48bf0ce0..9353e633fafbc 100644
--- a/clang/test/SemaCXX/cxx11-default-member-initializers.cpp
+++ b/clang/test/SemaCXX/cxx11-default-member-initializers.cpp
@@ -12,13 +12,3 @@ namespace PR31692 {
   // A::X can now be default-constructed.
   static_assert(__is_constructible(A::X), "");
 }
-
-
-struct S {
-} constexpr s;
-struct C {
-  C(S);
-};
-class MemInit {
-  C m = s;
-};

diff  --git a/clang/test/SemaCXX/cxx2a-consteval-default-params.cpp b/clang/test/SemaCXX/cxx2a-consteval-default-params.cpp
deleted file mode 100644
index abeb27fd03e35..0000000000000
--- a/clang/test/SemaCXX/cxx2a-consteval-default-params.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++2b %s
-
-consteval int undefined();  // expected-note 4 {{declared here}}
-
-void check_lambdas_unused(
-    int a = []
-    {
-        // The body of a lambda is not a subexpression of the lambda
-        // so this is immediately evaluated even if the parameter
-        // is never used.
-        return undefined();  // expected-error {{not a constant expression}} \
-                             // expected-note  {{undefined function 'undefined'}}
-    }(),
-    int b = [](int no_error = undefined()) {
-        return no_error;
-    }(0),
-    int c = [](int defaulted = undefined()) {
-        return defaulted;
-    }()
-) {}
-
-int check_lambdas_used(
-    int b = [](int no_error = undefined()) {
-        return no_error;
-    }(0),
-    int c = [](int defaulted = undefined()) { // expected-error {{not a constant expression}} \
-                              // expected-note  {{declared here}} \
-                              // expected-note  {{undefined function 'undefined'}}
-        return defaulted;
-    }(),  // expected-note {{in the default initalizer of 'defaulted'}}
-    int d = [](int defaulted = sizeof(undefined())) {
-        return defaulted;
-    }()
-) {
-    return 0;
-}
-
-int test_check_lambdas_used = check_lambdas_used();
-
-struct UnusedInitWithLambda {
-    int a = [] {
-        return undefined();  // expected-error {{not a constant expression}} \
-                             // expected-note  {{undefined function 'undefined'}}
-    }();
-    // UnusedInitWithLambda is never constructed, so the initializer
-    // of b and undefined() are never evaluated.
-    int b = [](int no_error = undefined()) {
-        return no_error;
-    }();
-};
-
-consteval int ub(int n) {
-    return 0/n; // expected-note  {{division}}
-}
-
-struct InitWithLambda {
-    int b = [](int error = undefined()) { // expected-error {{not a constant expression}} \
-                              // expected-note  {{declared here}} \
-                              // expected-note  {{undefined function 'undefined'}}
-        return error;
-    }(); // expected-note {{in the default initalizer of 'error'}}
-    int c = [](int error = sizeof(undefined()) + ub(0)) { // expected-error {{'ub' is not a constant expression}} \
-                                                          // expected-note  {{declared here}} \
-                                                          // expected-note {{in call to 'ub(0)}}
-        return error;
-    }(); // expected-note {{in the default initalizer of 'error'}}
-} i; // expected-note {{in implicit default constructor}}
-
-namespace ShouldNotCrash {
-    template<typename T>
-    struct F {
-        template<typename U>
-        F(const U&) {}
-    };
-    struct A {
-        static constexpr auto x = [] {};
-        F<int> f = x;
-    };
-    void f(A a = A()) { }
-}

diff  --git a/clang/test/SemaCXX/source_location.cpp b/clang/test/SemaCXX/source_location.cpp
index 9cfe9207dd14d..ccb385f60dc4b 100644
--- a/clang/test/SemaCXX/source_location.cpp
+++ b/clang/test/SemaCXX/source_location.cpp
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fexceptions -verify %s
-// RUN: %clang_cc1 -std=c++2a -fcxx-exceptions -DUSE_CONSTEVAL -fexceptions -verify %s
 // expected-no-diagnostics
 
 #define assert(...) ((__VA_ARGS__) ? ((void)0) : throw 42)
@@ -9,22 +8,15 @@
 template <unsigned>
 struct Printer;
 
-#ifdef USE_CONSTEVAL
-#define SOURCE_LOC_EVAL_KIND consteval
-#else
-#define SOURCE_LOC_EVAL_KIND constexpr
-#endif
-
 namespace std {
 class source_location {
   struct __impl;
 
 public:
-  static SOURCE_LOC_EVAL_KIND source_location
-    current(const __impl *__p = __builtin_source_location()) noexcept {
-      source_location __loc;
-      __loc.__m_impl = __p;
-      return __loc;
+  static constexpr source_location current(const __impl *__p = __builtin_source_location()) noexcept {
+    source_location __loc;
+    __loc.__m_impl = __p;
+    return __loc;
   }
   constexpr source_location() = default;
   constexpr source_location(source_location const &) = default;
@@ -601,51 +593,3 @@ namespace TestConstexprContext {
   }
   static_assert(test());
 }
-
-namespace Lambda {
-#line 8000 "TestLambda.cpp"
-constexpr int nested_lambda(int l = []{
-  return SL::current().line();
-}()) {
-  return l;
-}
-static_assert(nested_lambda() == __LINE__ - 4);
-
-constexpr int lambda_param(int l = [](int l = SL::current().line()) {
-  return l;
-}()) {
-  return l;
-}
-static_assert(lambda_param() == __LINE__);
-
-
-}
-
-constexpr int compound_literal_fun(int a =
-                  (int){ SL::current().line() }
-) { return a ;}
-static_assert(compound_literal_fun() == __LINE__);
-
-struct CompoundLiteral {
-  int a = (int){ SL::current().line() };
-};
-static_assert(CompoundLiteral{}.a == __LINE__);
-
-
-// FIXME
-// Init captures are subexpressions of the lambda expression
-// so according to the standard immediate invocations in init captures
-// should be evaluated at the call site.
-// However Clang does not yet implement this as it would introduce
-// a fair bit of complexity.
-// We intend to implement that functionality once we find real world
-// use cases that require it.
-constexpr int test_init_capture(int a =
-                [b = SL::current().line()] { return b; }()) {
-  return a;
-}
-#ifdef USE_CONSTEVAL
-static_assert(test_init_capture() == __LINE__ - 4);
-#else
-static_assert(test_init_capture() == __LINE__ );
-#endif

diff  --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 6d020f05b489a..cec9fe58cf601 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -15594,7 +15594,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
     <td><a href="https://wg21.link/cwg2631">2631</a></td>
     <td>DR</td>
     <td>Immediate function evaluations in default arguments</td>
-    <td class="unreleased" align="center">Clang 16</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="2632">
     <td><a href="https://wg21.link/cwg2632">2632</a></td>


        


More information about the cfe-commits mailing list