diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -2727,7 +2727,11 @@
     TRY_TO(TraverseStmt(S->getExpr()));
 })
 
-DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {})
+DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {
+  if (getDerived().shouldVisitImplicitCode())
+    TRY_TO(TraverseStmt(S->getExpr()));
+})
+
 DEF_TRAVERSE_STMT(CXXDeleteExpr, {})
 DEF_TRAVERSE_STMT(ExprWithCleanups, {})
 DEF_TRAVERSE_STMT(CXXInheritedCtorInitExpr, {})
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2667,7 +2667,8 @@
   "immediate function %0 used before it is defined">;
 
 def note_immediate_function_reason : Note<
-  "%0 is an immediate function because its body "
+  "%0 is an immediate %select{function|constructor}5 because "
+  "%select{its body|the%select{| default}7 initializer of %8}6 "
   "%select{evaluates the address of %select{an immediate|a consteval}2 "
   "function %1|contains a call to %select{an immediate|a consteval}2 "
   "%select{function|constructor}4 %1 and that call is not a constant "
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -1078,10 +1078,13 @@
   public:
     SynthesizedFunctionScope(Sema &S, DeclContext *DC)
         : S(S), SavedContext(S, DC) {
+      auto *FD = dyn_cast<FunctionDecl>(DC);
       S.PushFunctionScope();
       S.PushExpressionEvaluationContext(
-          Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
-      if (auto *FD = dyn_cast<FunctionDecl>(DC)) {
+          (FD && FD->isConsteval())
+              ? ExpressionEvaluationContext::ImmediateFunctionContext
+              : ExpressionEvaluationContext::PotentiallyEvaluated);
+      if (FD) {
         FD->setWillHaveBody(true);
         S.ExprEvalContexts.back().InImmediateFunctionContext =
             FD->isImmediateFunction();
@@ -1106,8 +1109,10 @@
     ~SynthesizedFunctionScope() {
       if (PushedCodeSynthesisContext)
         S.popCodeSynthesisContext();
-      if (auto *FD = dyn_cast<FunctionDecl>(S.CurContext))
+      if (auto *FD = dyn_cast<FunctionDecl>(S.CurContext)) {
         FD->setWillHaveBody(false);
+        S.CheckImmediateEscalatingFunctionDefinition(FD, S.getCurFunction());
+      }
       S.PopExpressionEvaluationContext();
       S.PopFunctionScopeInfo();
     }
@@ -6569,7 +6574,7 @@
   ExprResult CheckForImmediateInvocation(ExprResult E, FunctionDecl *Decl);
 
   bool CheckImmediateEscalatingFunctionDefinition(
-      FunctionDecl *FD, bool HasImmediateEscalatingExpression);
+      FunctionDecl *FD, const sema::FunctionScopeInfo *FSI);
 
   void MarkExpressionAsImmediateEscalating(Expr *E);
 
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -5319,6 +5319,10 @@
   const Decl *TargetDecl =
       OrigCallee.getAbstractInfo().getCalleeDecl().getDecl();
 
+  assert((!isa_and_present<FunctionDecl>(TargetDecl) ||
+          !cast<FunctionDecl>(TargetDecl)->isImmediateFunction()) &&
+         "trying to emit a call to an immediate function");
+
   CalleeType = getContext().getCanonicalType(CalleeType);
 
   auto PointeeType = cast<PointerType>(CalleeType)->getPointeeType();
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -15575,8 +15575,7 @@
     if (FD) {
       FD->setBody(Body);
       FD->setWillHaveBody(false);
-      CheckImmediateEscalatingFunctionDefinition(
-          FD, FSI->FoundImmediateEscalatingExpression);
+      CheckImmediateEscalatingFunctionDefinition(FD, FSI);
 
       if (getLangOpts().CPlusPlus14) {
         if (!FD->isInvalidDecl() && Body && !FD->isDependentContext() &&
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -46,6 +46,7 @@
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/SaveAndRestore.h"
 #include <map>
 #include <optional>
 #include <set>
@@ -2438,13 +2439,12 @@
 }
 
 bool Sema::CheckImmediateEscalatingFunctionDefinition(
-    FunctionDecl *FD, bool HasImmediateEscalatingExpression) {
-  if (!FD->hasBody() || !getLangOpts().CPlusPlus20 ||
-      !FD->isImmediateEscalating())
+    FunctionDecl *FD, const sema::FunctionScopeInfo *FSI) {
+  if (!getLangOpts().CPlusPlus20 || !FD->isImmediateEscalating())
     return true;
   FD->setBodyContainsImmediateEscalatingExpressions(
-      HasImmediateEscalatingExpression);
-  if (HasImmediateEscalatingExpression) {
+      FSI->FoundImmediateEscalatingExpression);
+  if (FSI->FoundImmediateEscalatingExpression) {
     auto it = UndefinedButUsed.find(FD->getCanonicalDecl());
     if (it != UndefinedButUsed.end()) {
       Diag(it->second, diag::err_immediate_function_used_before_definition)
@@ -2464,59 +2464,73 @@
   assert(FD->hasBody() && "expected the function to have a body");
   struct ImmediateEscalatingExpressionsVisitor
       : public RecursiveASTVisitor<ImmediateEscalatingExpressionsVisitor> {
+
     using Base = RecursiveASTVisitor<ImmediateEscalatingExpressionsVisitor>;
     Sema &SemaRef;
+
     const FunctionDecl *FD;
+    bool IsConstructor;
+    CXXCtorInitializer *CurrentInit = nullptr;
+
     ImmediateEscalatingExpressionsVisitor(Sema &SemaRef, const FunctionDecl *FD)
-        : SemaRef(SemaRef), FD(FD) {}
+        : SemaRef(SemaRef), FD(FD), IsConstructor(isa<CXXConstructorDecl>(FD)) {
+    }
 
     bool shouldVisitImplicitCode() const { return true; }
     bool shouldVisitLambdaBody() const { return false; }
 
+    void Diag(const Expr *E, const FunctionDecl *Fn, bool IsCall) {
+      SemaRef.Diag(E->getBeginLoc(), diag::note_immediate_function_reason)
+          << FD << Fn << Fn->isConsteval() << IsCall
+          << isa<CXXConstructorDecl>(Fn) << IsConstructor
+          << (CurrentInit != nullptr)
+          << (CurrentInit != nullptr && !CurrentInit->isWritten())
+          << (CurrentInit != nullptr ? CurrentInit->getAnyMember() : nullptr)
+          << E->getSourceRange();
+    }
     bool TraverseCallExpr(CallExpr *E) {
       if (const auto *DR =
               dyn_cast<DeclRefExpr>(E->getCallee()->IgnoreImplicit());
           DR && DR->isImmediateEscalating()) {
-        SemaRef.Diag(E->getBeginLoc(), diag::note_immediate_function_reason)
-            << FD << E->getDirectCallee() << E->getDirectCallee()->isConsteval()
-            << /*Call*/ 1 << /*Function*/ 0 << E->getSourceRange();
-      }
-      for (auto A : E->arguments()) {
-        getDerived().TraverseStmt(A);
+        Diag(E, E->getDirectCallee(), /*IsCall=*/true);
+        return false;
       }
+
+      for (auto A : E->arguments())
+        if (!getDerived().TraverseStmt(A))
+          return false;
+
       return true;
     }
+
     bool VisitDeclRefExpr(DeclRefExpr *E) {
       if (const auto *ReferencedFn = dyn_cast<FunctionDecl>(E->getDecl());
           ReferencedFn && E->isImmediateEscalating()) {
-        SemaRef.Diag(E->getBeginLoc(), diag::note_immediate_function_reason)
-            << FD << ReferencedFn << ReferencedFn->isConsteval()
-            << /*Address*/ 0 << /*Function*/ 0 << E->getSourceRange();
+        Diag(E, ReferencedFn, /*IsCall=*/false);
+        return false;
       }
+
       return true;
     }
+
     bool VisitCXXConstructExpr(CXXConstructExpr *E) {
       CXXConstructorDecl *D = E->getConstructor();
       if (E->isImmediateEscalating()) {
-        SemaRef.Diag(E->getBeginLoc(), diag::note_immediate_function_reason)
-            << FD << D << D->isConsteval() << /*Call*/ 1 << /*Constructor*/ 1
-            << E->getSourceRange();
+        Diag(E, D, /*IsCall=*/true);
+        return false;
       }
       return true;
     }
 
-    // These nodes can never contain an immediate escalating expression,
-    // we can skip them to avoid unecessary work.
-    bool TraverseDecl(Decl *D) {
-      if (isa<FunctionDecl, RecordDecl>(D))
-        return true;
-      return Base::TraverseDecl(D);
+    bool TraverseConstructorInitializer(CXXCtorInitializer *Init) {
+      llvm::SaveAndRestore RAII(CurrentInit, Init);
+      return Base::TraverseConstructorInitializer(Init);
     }
     bool TraverseType(QualType T) { return true; }
     bool VisitBlockExpr(BlockExpr *T) { return true; }
 
   } Visitor(*this, FD);
-  Visitor.TraverseStmt(FD->getBody());
+  Visitor.TraverseDecl(const_cast<FunctionDecl *>(FD));
 }
 
 /// Get the class that is directly named by the current context. This is the
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -6084,17 +6084,11 @@
   ImmediateCallVisitor(const ASTContext &Ctx) : Context(Ctx) {}
 
   bool HasImmediateCalls = false;
-  bool IsImmediateInvocation = false;
-
   bool shouldVisitImplicitCode() const { return true; }
 
   bool VisitCallExpr(CallExpr *E) {
-    if (const FunctionDecl *FD = E->getDirectCallee()) {
+    if (const FunctionDecl *FD = E->getDirectCallee())
       HasImmediateCalls |= FD->isImmediateFunction();
-      if (FD->isConsteval() && !E->isCXX11ConstantExpr(Context))
-        IsImmediateInvocation = true;
-    }
-
     return RecursiveASTVisitor<ImmediateCallVisitor>::VisitStmt(E);
   }
 
@@ -6224,6 +6218,8 @@
   if (Field->isInvalidDecl())
     return ExprError();
 
+  CXXThisScopeRAII This(*this, Field->getParent(), Qualifiers());
+
   auto *ParentRD = cast<CXXRecordDecl>(Field->getParent());
 
   std::optional<ExpressionEvaluationContextRecord::InitializationContext>
@@ -6271,13 +6267,6 @@
   if (!NestedDefaultChecking)
     V.TraverseDecl(Field);
   if (V.HasImmediateCalls) {
-    // C++23 [expr.const]/p15
-    // An aggregate initialization is an immediate invocation
-    // if it evaluates a default member initializer that has a subexpression
-    // that is an immediate-escalating expression.
-    ExprEvalContexts.back().InImmediateFunctionContext |=
-        V.IsImmediateInvocation;
-
     ExprEvalContexts.back().DelayedDefaultInitializationContext = {Loc, Field,
                                                                    CurContext};
     ExprEvalContexts.back().IsCurrentlyCheckingDefaultArgumentOrInitializer =
@@ -18439,6 +18428,11 @@
     if (!CE.getInt())
       EvaluateAndDiagnoseImmediateInvocation(SemaRef, CE);
   for (auto *DR : Rec.ReferenceToConsteval) {
+    // If the expression is immediate escalating, it is not an error;
+    // The outer context itself becomes immediate and further errors,
+    // if any, will be handled by DiagnoseImmediateEscalatingReason.
+    if (DR->isImmediateEscalating())
+      continue;
     const auto *FD = cast<FunctionDecl>(DR->getDecl());
     const NamedDecl *ND = FD;
     if (const auto *MD = dyn_cast<CXXMethodDecl>(ND);
@@ -18464,8 +18458,15 @@
       SemaRef.Diag(DR->getBeginLoc(), diag::err_invalid_consteval_take_address)
           << ND << isa<CXXRecordDecl>(ND) << FD->isConsteval();
       SemaRef.Diag(ND->getLocation(), diag::note_declared_at);
+      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);
+      }
       if (FD->isImmediateEscalating() && !FD->isConsteval())
         SemaRef.DiagnoseImmediateEscalatingReason(FD);
+
     } else {
       SemaRef.MarkExpressionAsImmediateEscalating(DR);
     }
@@ -18914,6 +18915,12 @@
   // or of another default member initializer (ie a PotentiallyEvaluatedIfUsed
   // context), its initializers may not be referenced yet.
   if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Func)) {
+    EnterExpressionEvaluationContext EvalContext(
+        *this,
+        Constructor->isImmediateFunction()
+            ? ExpressionEvaluationContext::ImmediateFunctionContext
+            : ExpressionEvaluationContext::PotentiallyEvaluated,
+        Constructor);
     for (CXXCtorInitializer *Init : Constructor->inits()) {
       if (Init->isInClassMemberInitializer())
         runWithSufficientStackSpace(Init->getSourceLocation(), [&]() {
diff --git a/clang/test/CodeGenCXX/cxx2c-consteval-consteval.cpp b/clang/test/CodeGenCXX/cxx2c-consteval-consteval.cpp
new file mode 100644
--- /dev/null
+++ b/clang/test/CodeGenCXX/cxx2c-consteval-consteval.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -emit-llvm %s -std=c++20 -triple x86_64-unknown-linux-gnu -o - | FileCheck %s
+
+namespace GH63742 {
+
+void side_effect();
+consteval int f(int x) {
+    if (!__builtin_is_constant_evaluated()) side_effect();
+    return x;
+}
+struct SS {
+    int x = f(42);
+    SS();
+};
+SS::SS(){}
+
+}
+
+// CHECK-LABEL: @_ZN7GH637422SSC2Ev
+// CHECK-NOT:   call
+// CHECK:       store i32 42, ptr {{.*}}
+// CHECK:       ret void
diff --git a/clang/test/SemaCXX/cxx2a-consteval-default-params.cpp b/clang/test/SemaCXX/cxx2a-consteval-default-params.cpp
--- a/clang/test/SemaCXX/cxx2a-consteval-default-params.cpp
+++ b/clang/test/SemaCXX/cxx2a-consteval-default-params.cpp
@@ -41,19 +41,22 @@
     }();
 };
 
-consteval int ub(int n) { // expected-note {{declared here}}
+consteval int ub(int n) {
     return 0/n;
 }
 
 struct InitWithLambda {
-    int b = [](int error = undefined()) { // expected-error {{cannot take address of consteval function 'undefined' outside of an immediate invocation}}
+    int b = [](int error = undefined()) {  // expected-note {{undefined function 'undefined' cannot be used in a constant expression}} \
+                                           // expected-note {{'InitWithLambda' is an immediate constructor because the default initializer of 'b' contains a call to a consteval function 'undefined' and that call is not a constant expression}}
         return error;
     }();
-    int c = [](int error = sizeof(undefined()) + ub(0)) { // expected-error {{cannot take address of consteval function 'ub' outside of an immediate invocation}}
+    int c = [](int error = sizeof(undefined()) + ub(0)) {
 
         return error;
     }();
 } i;
+// expected-error@-1 {{call to immediate function 'InitWithLambda::InitWithLambda' is not a constant expression}} \
+   expected-note@-1 {{in call to 'InitWithLambda()'}}
 
 namespace ShouldNotCrash {
     template<typename T>
diff --git a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp
--- a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp
+++ b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp
@@ -34,7 +34,7 @@
 
 template <typename T>
 constexpr T h(T t = id(x)) { // expected-note {{read of non-const variable 'x' is not allowed in a constant expression}} \
-                             // expected-note 2{{'hh<int>' is an immediate function because its body contains a call to a consteval function 'id' and that call is not a constant expression}}
+                             // expected-note {{'hh<int>' is an immediate function because its body contains a call to a consteval function 'id' and that call is not a constant expression}}
     return t;
 }
 
@@ -164,3 +164,169 @@
 int i = g(x); // expected-error {{call to immediate function 'ConstevalConstructor::g<int>' is not a constant expression}} \
               // expected-note {{read of non-const variable 'x' is not allowed in a constant expression}}
 }
+
+
+
+namespace Aggregate {
+consteval int f(int); // expected-note {{declared here}}
+struct S {
+  int x = f(42); // expected-note {{undefined function 'f' cannot be used in a constant expression}} \
+                 // expected-note {{'immediate<int>' is an immediate function because its body contains a call to a consteval function 'f' and that call is not a constant expression}}
+};
+
+constexpr S immediate(auto) {
+    return S{};
+}
+
+void test_runtime() {
+    (void)immediate(0); // expected-error {{call to immediate function 'Aggregate::immediate<int>' is not a constant expression}} \
+                        // expected-note {{in call to 'immediate(0)'}}
+}
+consteval int f(int i) {
+    return i;
+}
+consteval void test() {
+    constexpr S s = immediate(0);
+    static_assert(s.x == 42);
+}
+}
+
+
+
+namespace GH63742 {
+void side_effect(); // expected-note  {{declared here}}
+consteval int f(int x) {
+    if (!x) side_effect(); // expected-note {{non-constexpr function 'side_effect' cannot be used in a constant expression}}
+    return x;
+}
+struct SS {
+  int y = f(1); // Ok
+  int x = f(0); // expected-error {{call to consteval function 'GH63742::f' is not a constant expression}} \
+                // expected-note  {{declared here}} \
+                // expected-note  {{in call to 'f(0)'}}
+  SS();
+};
+SS::SS(){} // expected-note {{in the default initializer of 'x'}}
+
+consteval int f2(int x) {
+    if (!__builtin_is_constant_evaluated()) side_effect();
+    return x;
+}
+struct S2 {
+    int x = f2(0);
+    constexpr S2();
+};
+
+constexpr S2::S2(){}
+S2 s = {};
+constinit S2 s2 = {};
+
+struct S3 {
+    int x = f2(0);
+    S3();
+};
+S3::S3(){}
+
+}
+
+namespace Defaulted {
+consteval int f(int x);
+struct SS {
+  int x = f(0);
+  SS() = default;
+};
+}
+
+namespace DefaultedUse{
+consteval int f(int x);  // expected-note {{declared here}}
+struct SS {
+  int a = sizeof(f(0)); // Ok
+  int x = f(0); // expected-note {{undefined function 'f' cannot be used in a constant expression}} \
+                // expected-note {{'SS' is an immediate constructor because the default initializer of 'x' contains a call to a consteval function 'f' and that call is not a constant expression}}
+  SS() = default;
+};
+
+void test() {
+    [[maybe_unused]] SS s; // expected-error {{call to immediate function 'DefaultedUse::SS::SS' is not a constant expression}} \
+                           //  expected-note {{in call to 'SS()'}}
+}
+}
+
+namespace UserDefinedConstructors {
+consteval int f(int x) {
+    return x;
+}
+extern int NonConst; // expected-note 2{{declared here}}
+
+struct ConstevalCtr {
+    int y;
+    int x = f(y);
+    consteval ConstevalCtr(int yy)
+    : y(f(yy)) {}
+};
+
+ConstevalCtr c1(1);
+ConstevalCtr c2(NonConst);
+// expected-error@-1 {{call to consteval function 'UserDefinedConstructors::ConstevalCtr::ConstevalCtr' is not a constant expression}} \
+// expected-note@-1 {{read of non-const variable 'NonConst' is not allowed in a constant expression}}
+
+struct ImmediateEscalating {
+    int y;
+    int x = f(y);
+    template<typename T>
+    constexpr ImmediateEscalating(T yy)
+    : y(f(yy)) {} // expected-note {{ImmediateEscalating<int>' is an immediate constructor because the initializer of 'y' contains a call to a consteval function 'f' and that call is not a constant expression}}
+};
+
+ImmediateEscalating c3(1);
+ImmediateEscalating c4(NonConst);
+// expected-error@-1 {{call to immediate function 'UserDefinedConstructors::ImmediateEscalating::ImmediateEscalating<int>' is not a constant expression}} \
+// expected-note@-1 {{read of non-const variable 'NonConst' is not allowed in a constant expression}}
+
+
+struct NonEscalating {
+    int y;
+    int x = f(this->y); // expected-error {{call to consteval function 'UserDefinedConstructors::f' is not a constant expression}} \
+                        // expected-note  {{declared here}} \
+                        // expected-note  {{use of 'this' pointer is only allowed within the evaluation of a call to a 'constexpr' member function}}
+    constexpr NonEscalating(int yy) : y(yy) {} // expected-note {{in the default initializer of 'x'}}
+};
+NonEscalating s = {1};
+
+}
+
+namespace AggregateInit {
+
+consteval int f(int x) {
+    return x;
+}
+
+struct S {
+    int i;
+    int j = f(i);
+};
+
+constexpr S  test(auto) {
+    return {};
+}
+
+S s = test(0);
+
+}
+
+namespace GlobalAggregateInit {
+
+consteval int f(int x) {
+    return x;
+}
+
+struct S {
+    int i;
+    int j = f(i); // expected-error {{call to consteval function 'GlobalAggregateInit::f' is not a constant expression}} \
+                  // expected-note {{implicit use of 'this' pointer is only allowed within the evaluation of a call to a 'constexpr' member function}} \
+                  // expected-note {{declared here}}
+};
+
+S s(0); // expected-note {{in the default initializer of 'j'}}
+
+}