https://github.com/cor3ntin updated 
https://github.com/llvm/llvm-project/pull/173537

>From 9eed555bd86be4accc2096cc40e5de30c809afda Mon Sep 17 00:00:00 2001
From: Corentin Jabot <[email protected]>
Date: Wed, 24 Dec 2025 14:30:29 +0100
Subject: [PATCH 1/8] [Clang] Instantiate constexpr function when they are
 needed.

This is a rework of #115168, with the sole aim of fixing #73232.
The scaffolding is introduced here is necessary - but not sufficient
for reflection.

Reading the comments on #115168, I think we need to separate multiple
concerns:
   - Do we have access to Sema (which this PR provides)
   - Can we mutate the AST - which is something individual callers
     will have to figure out.

This does **not** fix #59966, as the change is complicated enough
that i want to explore it in a separate PR.

Fixes #73232
---
 clang/docs/ReleaseNotes.rst                   | 155 ++++++++++++++++++
 clang/include/clang/AST/ASTContext.h          |  17 ++
 clang/include/clang/Sema/Sema.h               |   3 +
 clang/lib/AST/ASTContext.cpp                  |   7 +
 clang/lib/AST/ByteCode/Interp.cpp             |  30 +++-
 clang/lib/AST/ByteCode/InterpState.cpp        |   2 +
 clang/lib/AST/ByteCode/State.h                |   2 +
 clang/lib/AST/ExprConstant.cpp                |  42 ++++-
 clang/lib/Interpreter/IncrementalParser.cpp   |   6 +-
 clang/lib/Parse/ParseAST.cpp                  |   6 +
 clang/lib/Sema/Sema.cpp                       |  30 ++++
 .../SemaCXX/constexpr-late-instantiation.cpp  |  84 +++++++++-
 .../constexpr-subobj-initialization.cpp       |   5 +-
 .../SemaCXX/cxx2b-consteval-propagate.cpp     |   5 +-
 14 files changed, 374 insertions(+), 20 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 5ac5ae4a7d37e..009a09819f359 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -140,9 +140,97 @@ Non-comprehensive list of changes in this release
   Usable in constant expressions. Implicit conversion is supported for
   class/struct types with conversion operators.
 
+<<<<<<< HEAD
 - A new generic bit-reverse builtin function ``__builtin_bitreverseg`` that
   extends bit-reversal support to all standard integers type, including
   ``_BitInt``
+=======
+- Added ``__builtin_elementwise_ldexp``.
+
+- Added ``__builtin_elementwise_fshl`` and ``__builtin_elementwise_fshr``.
+
+- ``__builtin_elementwise_abs`` can now be used in constant expression.
+
+- Added ``__builtin_elementwise_minnumnum`` and 
``__builtin_elementwise_maxnumnum``.
+
+- Trapping UBSan (e.g. ``-fsanitize=undefined -fsanitize-trap=undefined``) now
+  emits a string describing the reason for trapping into the generated debug
+  info. This feature allows debuggers (e.g. LLDB) to display the reason for
+  trapping if the trap is reached. The string is currently encoded in the debug
+  info as an artificial frame that claims to be inlined at the trap location.
+  The function used for the artificial frame is an artificial function whose
+  name encodes the reason for trapping. The encoding used is currently the same
+  as ``__builtin_verbose_trap`` but might change in the future. This feature is
+  enabled by default but can be disabled by compiling with
+  ``-fno-sanitize-debug-trap-reasons``. The feature has a ``basic`` and
+  ``detailed`` mode (the default). The ``basic`` mode emits a hard-coded string
+  per trap kind (e.g. ``Integer addition overflowed``) and the ``detailed`` 
mode
+  emits a more descriptive string describing each individual trap (e.g. 
``signed
+  integer addition overflow in 'a + b'``). The ``detailed`` mode produces 
larger
+  debug info than ``basic`` but is more helpful for debugging. The
+  ``-fsanitize-debug-trap-reasons=`` flag can be used to switch between the
+  different modes or disable the feature entirely. Note due to trap merging in
+  optimized builds (i.e. in each function all traps of the same kind get merged
+  into the same trap instruction) the trap reasons might be removed. To prevent
+  this build without optimizations (i.e. use `-O0` or use the `optnone` 
function
+  attribute) or use the `fno-sanitize-merge=` flag in optimized builds.
+
+- ``__builtin_elementwise_max`` and ``__builtin_elementwise_min`` functions 
for integer types can
+  now be used in constant expressions.
+
+- A vector of booleans is now a valid condition for the ternary ``?:`` 
operator.
+  This binds to a simple vector select operation.
+
+- Added ``__builtin_masked_load``, ``__builtin_masked_expand_load``,
+  ``__builtin_masked_store``, ``__builtin_masked_compress_store`` for
+  conditional memory loads from vectors. Binds to the LLVM intrinsics of the
+  same name.
+
+- Added ``__builtin_masked_gather`` and ``__builtin_masked_scatter`` for
+  conditional gathering and scattering operations on vectors. Binds to the LLVM
+  intrinsics of the same name.
+
+- The ``__builtin_popcountg``, ``__builtin_ctzg``, and ``__builtin_clzg``
+  functions now accept fixed-size boolean vectors.
+
+- Use of ``__has_feature`` to detect the ``ptrauth_qualifier`` and 
``ptrauth_intrinsics``
+  features has been deprecated, and is restricted to the arm64e target only. 
The
+  correct method to check for these features is to test for the ``__PTRAUTH__``
+  macro.
+
+- Added a new builtin, ``__builtin_dedup_pack``, to remove duplicate types 
from a parameter pack.
+  This feature is particularly useful in template metaprogramming for 
normalizing type lists.
+  The builtin produces a new, unexpanded parameter pack that can be used in 
contexts like template
+  argument lists or base specifiers.
+
+  .. code-block:: c++
+
+    template <typename...> struct TypeList;
+
+    // The resulting type is TypeList<int, double, char>
+    using MyTypeList = TypeList<__builtin_dedup_pack<int, double, int, char, 
double>...>;
+
+  Currently, the use of ``__builtin_dedup_pack`` is limited to template 
arguments and base
+  specifiers, it also must be used within a template context.
+
+- ``__builtin_assume_dereferenceable`` now accepts non-constant size operands.
+
+- Fixed a crash when the second argument to ``__builtin_assume_aligned`` was 
not constant (#GH161314)
+
+- Introduce support for :doc:`allocation tokens <AllocToken>` to enable
+  allocator-level heap organization strategies. A feature to instrument all
+  allocation functions with a token ID can be enabled via the
+  ``-fsanitize=alloc-token`` flag.
+
+- A new generic byte swap builtin function ``__builtin_bswapg`` that extends 
the existing
+  __builtin_bswap{16,32,64} function family to support all standard integer 
types.
+
+- A builtin ``__builtin_infer_alloc_token(<args>, ...)`` is provided to allow
+  compile-time querying of allocation token IDs, where the builtin arguments
+  mirror those normally passed to an allocation function.
+
+- Clang now rejects the invalid use of ``constexpr`` with ``auto`` and an 
explicit type in C. (#GH163090)
+>>>>>>> 3f06fd997749 ([Clang] Instantiate constexpr function when they are 
needed.)
 
 New Compiler Flags
 ------------------
@@ -230,6 +318,7 @@ Improvements to Clang's diagnostics
 
   .. code-block:: c++
 
+<<<<<<< HEAD
     struct DanglingView {
       std::string_view view;
       DanglingView(std::string s) : view(s) {}  // warning: address of stack 
memory escapes to a field
@@ -246,6 +335,14 @@ Improvements to Clang's diagnostics
 
 - The ``-Wloop-analysis`` warning has been extended to catch more cases of
   variable modification inside lambda expressions (#GH132038).
+=======
+- Fixed a crash when enabling ``-fdiagnostics-format=sarif`` and the output
+  carries messages like 'In file included from ...' or 'In module ...'.
+  Now the include/import locations are written into 
`sarif.run.result.relatedLocations`.
+
+- Clang now generates a fix-it for C++20 designated initializers when the
+  initializers do not match the declaration order in the structure.
+>>>>>>> 3f06fd997749 ([Clang] Instantiate constexpr function when they are 
needed.)
 
 Improvements to Clang's time-trace
 ----------------------------------
@@ -280,10 +377,68 @@ Bug Fixes to Attribute Support
 
 Bug Fixes to C++ Support
 ^^^^^^^^^^^^^^^^^^^^^^^^
+<<<<<<< HEAD
 - Fixed a crash when instantiating ``requires`` expressions involving 
substitution failures in C++ concepts. (#GH176402)
 - Fixed a crash when a default argument is passed to an explicit object 
parameter. (#GH176639)
 - Fixed a crash when diagnosing an invalid static member function with an 
explicit object parameter (#GH177741)
 - Fixed a crash when evaluating uninitialized GCC vector/ext_vector_type 
vectors in ``constexpr``. (#GH180044)
+=======
+- Diagnose binding a reference to ``*nullptr`` during constant evaluation. 
(#GH48665)
+- Suppress ``-Wdeprecated-declarations`` in implicitly generated functions. 
(#GH147293)
+- Fix a crash when deleting a pointer to an incomplete array (#GH150359).
+- Fixed a mismatched lambda scope bug when propagating up ``consteval`` within 
nested lambdas. (#GH145776)
+- Disallow immediate escalation in destructors. (#GH109096)
+- Fix an assertion failure when expression in assumption attribute
+  (``[[assume(expr)]]``) creates temporary objects.
+- Fix the dynamic_cast to final class optimization to correctly handle
+  casts that are guaranteed to fail (#GH137518).
+- Fix bug rejecting partial specialization of variable templates with auto 
NTTPs (#GH118190).
+- Fix a crash if errors "member of anonymous [...] redeclares" and
+  "initializing multiple members of union" coincide (#GH149985).
+- Fix a crash when using ``explicit(bool)`` in pre-C++11 language modes. 
(#GH152729)
+- Fix the parsing of variadic member functions when the ellipis immediately 
follows a default argument.(#GH153445)
+- Fix a crash when using an explicit object parameter in a non-member function 
with an invalid return type.(#GH173943)
+- Fixed a bug that caused ``this`` captured by value in a lambda with a 
dependent explicit object parameter to not be
+  instantiated properly. (#GH154054)
+- Fixed a bug where our ``member-like constrained friend`` checking caused an 
incorrect analysis of lambda captures. (#GH156225)
+- Fixed a crash when implicit conversions from initialize list to arrays of
+  unknown bound during constant evaluation. (#GH151716)
+- Instantiate constexpr functions as needed before they are evaluated. 
(#GH73232)
+- Support the dynamic_cast to final class optimization with pointer
+  authentication enabled. (#GH152601)
+- Fix the check for narrowing int-to-float conversions, so that they are 
detected in
+  cases where converting the float back to an integer is undefined behaviour 
(#GH157067).
+- Stop rejecting C++11-style attributes on the first argument of constructors 
in older
+  standards. (#GH156809).
+- Fix a crash when applying binary or ternary operators to two same function 
types with different spellings,
+  where at least one of the function parameters has an attribute which affects
+  the function type.
+- Fix an assertion failure when a ``constexpr`` variable is only referenced 
through
+  ``__builtin_addressof``, and related issues with builtin arguments. 
(#GH154034)
+- Fix an assertion failure when taking the address on a non-type template 
parameter argument of
+  object type. (#GH151531)
+- Suppress ``-Wdouble-promotion`` when explicitly asked for with C++ list 
initialization (#GH33409).
+- Fix the result of `__builtin_is_implicit_lifetime` for types with a 
user-provided constructor. (#GH160610)
+- Correctly deduce return types in ``decltype`` expressions. (#GH160497) 
(#GH56652) (#GH116319) (#GH161196)
+- Fixed a crash in the pre-C++23 warning for attributes before a lambda 
declarator (#GH161070).
+- Fix a crash when attempting to deduce a deduction guide from a non deducible 
template template parameter. (#130604)
+- Fix for clang incorrectly rejecting the default construction of a union with
+  nontrivial member when another member has an initializer. (#GH81774)
+- Fixed a template depth issue when parsing lambdas inside a type constraint. 
(#GH162092)
+- Fix the support of zero-length arrays in SFINAE context. (#GH170040)
+- Diagnose unresolved overload sets in non-dependent compound requirements. 
(#GH51246) (#GH97753)
+- Fix a crash when extracting unavailable member type from alias in template 
deduction. (#GH165560)
+- Fix incorrect diagnostics for lambdas with init-captures inside braced 
initializers. (#GH163498)
+- Fixed an issue where templates prevented nested anonymous records from 
checking the deletion of special members. (#GH167217)
+- Fixed serialization of pack indexing types, where we failed to expand those 
packs from a PCH/module. (#GH172464)
+- Fixed spurious diagnoses of certain nested lambda expressions. (#GH149121) 
(#GH156579)
+- Fix the result of ``__is_pointer_interconvertible_base_of`` when arguments 
are qualified and passed via template parameters. (#GH135273)
+- Fixed a crash when evaluating nested requirements in requires-expressions 
that reference invented parameters. (#GH166325)
+- Fixed a crash when standard comparison categories (e.g. 
``std::partial_ordering``) are defined with incorrect static member types. 
(#GH170015) (#GH56571)
+- Fixed a crash when parsing the ``enable_if`` attribute on C function 
declarations with identifier-list parameters. (#GH173826)
+- Fixed an assertion failure triggered by nested lambdas during capture 
handling. (#GH172814)
+- Fixed an assertion failure in vector conversions involving 
instantiation-dependent template expressions. (#GH173347)
+>>>>>>> 3f06fd997749 ([Clang] Instantiate constexpr function when they are 
needed.)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index 6b819de2fb36d..bf75813922c6e 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -44,6 +44,7 @@
 #include "llvm/ADT/StringSet.h"
 #include "llvm/ADT/TinyPtrVector.h"
 #include "llvm/Support/TypeSize.h"
+#include <memory>
 #include <optional>
 
 namespace llvm {
@@ -215,6 +216,16 @@ struct TypeInfoChars {
   }
 };
 
+/// Interface that allows constant evaluator to call Sema
+/// and mutate the AST.
+struct SemaProxy {
+  virtual ~SemaProxy() = default;
+
+  virtual void
+  InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
+                                FunctionDecl *Function) = 0;
+};
+
 /// Holds long-lived AST nodes (such as types and decls) that can be
 /// referred to throughout the semantic analysis of a file.
 class ASTContext : public RefCountedBase<ASTContext> {
@@ -786,6 +797,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
   /// Keeps track of the deallocated DeclListNodes for future reuse.
   DeclListNode *ListNodeFreeList = nullptr;
 
+  std::unique_ptr<SemaProxy> SemaProxyPtr;
+
 public:
   IdentifierTable &Idents;
   SelectorTable &Selectors;
@@ -1409,6 +1422,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
   /// with this AST context, if any.
   ASTMutationListener *getASTMutationListener() const { return Listener; }
 
+  SemaProxy *getSemaProxy();
+
+  void setSemaProxy(std::unique_ptr<SemaProxy> Proxy);
+
   void PrintStats() const;
   const SmallVectorImpl<Type *>& getTypes() const { return Types; }
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 9424b80d5cdb6..fa8a54a3730ac 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -910,6 +910,9 @@ class Sema final : public SemaBase {
   /// initialized but before it parses anything.
   void Initialize();
 
+  void RegisterSemaProxy();
+  void UnregisterSemaProxy();
+
   /// This virtual key function only exists to limit the emission of debug info
   /// describing the Sema class. GCC and Clang only emit debug info for a class
   /// with a vtable when the vtable is emitted. Sema is final and not
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 3f63420cae91e..eb70a9d91cc0c 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -926,6 +926,13 @@ 
ASTContext::setExternalSource(IntrusiveRefCntPtr<ExternalASTSource> Source) {
   ExternalSource = std::move(Source);
 }
 
+SemaProxy *ASTContext::getSemaProxy() { return SemaProxyPtr.get(); }
+
+void ASTContext::setSemaProxy(std::unique_ptr<SemaProxy> Proxy) {
+  assert((!SemaProxyPtr || !Proxy) && "SemaProxy already set");
+  SemaProxyPtr = std::move(Proxy);
+}
+
 void ASTContext::PrintStats() const {
   llvm::errs() << "\n*** AST Context Stats:\n";
   llvm::errs() << "  " << Types.size() << " types total.\n";
diff --git a/clang/lib/AST/ByteCode/Interp.cpp 
b/clang/lib/AST/ByteCode/Interp.cpp
index bb259822c3dfe..11f629d0d97c5 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -7,6 +7,7 @@
 
//===----------------------------------------------------------------------===//
 
 #include "Interp.h"
+#include "ByteCode/Source.h"
 #include "Compiler.h"
 #include "Function.h"
 #include "InterpFrame.h"
@@ -1624,13 +1625,30 @@ bool CheckBitCast(InterpState &S, CodePtr OpPC, const 
Type *TargetType,
   return true;
 }
 
-static void compileFunction(InterpState &S, const Function *Func) {
-  const FunctionDecl *Definition = Func->getDecl()->getDefinition();
-  if (!Definition)
+static void compileFunction(InterpState &S, const Function *Func,
+                            SourceLocation Loc) {
+
+  const FunctionDecl *Fn = Func->getDecl();
+
+  // [C++26] [temp.inst] p5
+  // [...] the function template specialization is implicitly instantiated
+  // when the specialization is referenced in a context that requires a 
function
+  // definition to exist or if the existence of the definition affects the
+  // semantics of the program.
+  if (!Fn->isDefined() && Fn->isImplicitlyInstantiable() && Fn->isConstexpr() 
&&
+      S.inConstantContext() && !S.TryConstantInitialization &&
+      !S.checkingPotentialConstantExpression()) {
+    SemaProxy *SP = S.getASTContext().getSemaProxy();
+    if (!SP)
+      return;
+    SP->InstantiateFunctionDefinition(Loc, const_cast<FunctionDecl *>(Fn));
+  }
+  Fn = Fn->getDefinition();
+  if (!Fn)
     return;
 
   Compiler<ByteCodeEmitter>(S.getContext(), S.P)
-      .compileFunc(Definition, const_cast<Function *>(Func));
+      .compileFunc(Fn, const_cast<Function *>(Func));
 }
 
 bool CallVar(InterpState &S, CodePtr OpPC, const Function *Func,
@@ -1656,7 +1674,7 @@ bool CallVar(InterpState &S, CodePtr OpPC, const Function 
*Func,
   }
 
   if (!Func->isFullyCompiled())
-    compileFunction(S, Func);
+    compileFunction(S, Func, S.Current->getLocation(OpPC));
 
   if (!CheckCallable(S, OpPC, Func))
     return false;
@@ -1733,7 +1751,7 @@ bool Call(InterpState &S, CodePtr OpPC, const Function 
*Func,
   }
 
   if (!Func->isFullyCompiled())
-    compileFunction(S, Func);
+    compileFunction(S, Func, S.Current->getLocation(OpPC));
 
   if (!CheckCallable(S, OpPC, Func))
     return cleanup();
diff --git a/clang/lib/AST/ByteCode/InterpState.cpp 
b/clang/lib/AST/ByteCode/InterpState.cpp
index df507bd5507c3..d8a8d76b9f06d 100644
--- a/clang/lib/AST/ByteCode/InterpState.cpp
+++ b/clang/lib/AST/ByteCode/InterpState.cpp
@@ -24,6 +24,7 @@ InterpState::InterpState(const State &Parent, Program &P, 
InterpStack &Stk,
       StepsLeft(Ctx.getLangOpts().ConstexprStepLimit),
       InfiniteSteps(StepsLeft == 0) {
   InConstantContext = Parent.InConstantContext;
+  TryConstantInitialization = Parent.TryConstantInitialization;
   CheckingPotentialConstantExpression =
       Parent.CheckingPotentialConstantExpression;
   CheckingForUndefinedBehavior = Parent.CheckingForUndefinedBehavior;
@@ -38,6 +39,7 @@ InterpState::InterpState(const State &Parent, Program &P, 
InterpStack &Stk,
       Current(&BottomFrame), StepsLeft(Ctx.getLangOpts().ConstexprStepLimit),
       InfiniteSteps(StepsLeft == 0) {
   InConstantContext = Parent.InConstantContext;
+  TryConstantInitialization = Parent.TryConstantInitialization;
   CheckingPotentialConstantExpression =
       Parent.CheckingPotentialConstantExpression;
   CheckingForUndefinedBehavior = Parent.CheckingForUndefinedBehavior;
diff --git a/clang/lib/AST/ByteCode/State.h b/clang/lib/AST/ByteCode/State.h
index a720033c7914b..841da0836516d 100644
--- a/clang/lib/AST/ByteCode/State.h
+++ b/clang/lib/AST/ByteCode/State.h
@@ -187,6 +187,8 @@ class State {
   /// is set; this is used when evaluating ICEs in C.
   bool CheckingForUndefinedBehavior = false;
 
+  bool TryConstantInitialization = false;
+
   EvaluationMode EvalMode;
   ASTContext &Ctx;
   Expr::EvalStatus &EvalStatus;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 2c13befec02f2..7ceea521640f2 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -43,6 +43,7 @@
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/CurrentSourceLocExprScope.h"
+#include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/InferAlloc.h"
 #include "clang/AST/OSLog.h"
@@ -53,6 +54,7 @@
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/DiagnosticSema.h"
+#include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/TargetBuiltins.h"
 #include "clang/Basic/TargetInfo.h"
 #include "llvm/ADT/APFixedPoint.h"
@@ -6961,6 +6963,28 @@ static bool handleTrivialCopy(EvalInfo &Info, const 
ParmVarDecl *Param,
       CopyObjectRepresentation);
 }
 
+static void InstantiateFunctionBeforeCall(const FunctionDecl *FD,
+                                          EvalInfo &Info, SourceLocation Loc) {
+
+  // [C++26] [temp.inst] p5
+  // [...] the function template specialization is implicitly instantiated
+  // when the specialization is referenced in a context that requires a 
function
+  // definition to exist or if the existence of the definition affects the
+  // semantics of the program.
+
+  if (!FD->isDefined() && FD->isImplicitlyInstantiable() && FD->isConstexpr() 
&&
+      Info.InConstantContext && !Info.TryConstantInitialization &&
+      !Info.checkingPotentialConstantExpression()) {
+
+    SemaProxy *SP = Info.getASTContext().getSemaProxy();
+    // Try to instantiate the definition if Sema is available
+    // (i.e during the initial parse of the TU).
+    if (SP) {
+      SP->InstantiateFunctionDefinition(Loc, const_cast<FunctionDecl *>(FD));
+    }
+  }
+}
+
 /// Evaluate a function call.
 static bool HandleFunctionCall(SourceLocation CallLoc,
                                const FunctionDecl *Callee,
@@ -7354,6 +7378,8 @@ static bool HandleDestructionImpl(EvalInfo &Info, 
SourceRange CallRange,
   if (!Info.CheckCallLimit(CallRange.getBegin()))
     return false;
 
+  InstantiateFunctionBeforeCall(DD, Info, CallRange.getBegin());
+
   const FunctionDecl *Definition = nullptr;
   const Stmt *Body = DD->getBody(Definition);
 
@@ -8819,10 +8845,13 @@ class ExprEvaluatorBase
              CallScope.destroy();
     }
 
-    const FunctionDecl *Definition = nullptr;
-    Stmt *Body = FD->getBody(Definition);
     SourceLocation Loc = E->getExprLoc();
 
+    InstantiateFunctionBeforeCall(FD, Info, Loc);
+
+    const FunctionDecl *Definition = nullptr;
+    const Stmt *Body = FD->getBody(Definition);
+
     // Treat the object argument as `this` when evaluating defaulted
     // special menmber functions
     if (FD->hasCXXExplicitFunctionObjectParameter())
@@ -11340,8 +11369,10 @@ bool RecordExprEvaluator::VisitCXXConstructExpr(const 
CXXConstructExpr *E,
     return handleDefaultInitValue(T, Result);
   }
 
+  InstantiateFunctionBeforeCall(FD, Info, E->getBeginLoc());
+
   const FunctionDecl *Definition = nullptr;
-  auto Body = FD->getBody(Definition);
+  const Stmt *Body = FD->getBody(Definition);
 
   if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition, Body))
     return false;
@@ -11381,8 +11412,9 @@ bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
   if (FD->isInvalidDecl() || FD->getParent()->isInvalidDecl())
     return false;
 
+  InstantiateFunctionBeforeCall(FD, Info, E->getBeginLoc());
   const FunctionDecl *Definition = nullptr;
-  auto Body = FD->getBody(Definition);
+  const Stmt *Body = FD->getBody(Definition);
 
   if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition, Body))
     return false;
@@ -20796,6 +20828,8 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const 
ASTContext &Ctx,
                     : EvaluationMode::ConstantFold);
   Info.setEvaluatingDecl(VD, Value);
   Info.InConstantContext = IsConstantInitialization;
+  Info.TryConstantInitialization =
+      !VD->isConstexpr() && !VD->hasAttr<ConstInitAttr>();
 
   SourceLocation DeclLoc = VD->getLocation();
   QualType DeclTy = VD->getType();
diff --git a/clang/lib/Interpreter/IncrementalParser.cpp 
b/clang/lib/Interpreter/IncrementalParser.cpp
index bf08911e23533..5a24342e73ca4 100644
--- a/clang/lib/Interpreter/IncrementalParser.cpp
+++ b/clang/lib/Interpreter/IncrementalParser.cpp
@@ -42,9 +42,13 @@ IncrementalParser::IncrementalParser(CompilerInstance 
&Instance,
     External->StartTranslationUnit(Consumer);
 
   P->Initialize();
+  S.RegisterSemaProxy();
 }
 
-IncrementalParser::~IncrementalParser() { P.reset(); }
+IncrementalParser::~IncrementalParser() {
+  S.UnregisterSemaProxy();
+  P.reset();
+}
 
 llvm::Expected<TranslationUnitDecl *>
 IncrementalParser::ParseOrWrapTopLevelDecl() {
diff --git a/clang/lib/Parse/ParseAST.cpp b/clang/lib/Parse/ParseAST.cpp
index c8ee625eb57ad..1cea282f13a00 100644
--- a/clang/lib/Parse/ParseAST.cpp
+++ b/clang/lib/Parse/ParseAST.cpp
@@ -21,6 +21,7 @@
 #include "clang/Sema/Sema.h"
 #include "clang/Sema/SemaConsumer.h"
 #include "clang/Sema/TemplateInstCallback.h"
+#include "llvm/ADT/ScopeExit.h"
 #include "llvm/Support/CrashRecoveryContext.h"
 #include "llvm/Support/TimeProfiler.h"
 #include <cstdio>
@@ -161,6 +162,11 @@ void clang::ParseAST(Sema &S, bool PrintStats, bool 
SkipFunctionBodies) {
       return M;
     });
     P.Initialize();
+
+    auto Unregister =
+        llvm::make_scope_exit([&S]() { S.UnregisterSemaProxy(); });
+    S.RegisterSemaProxy();
+
     Parser::DeclGroupPtrTy ADecl;
     Sema::ModuleImportState ImportState;
     EnterExpressionEvaluationContext PotentiallyEvaluated(
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index d53527af38653..90b919974586b 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -75,11 +75,14 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Support/TimeProfiler.h"
+#include <memory>
 #include <optional>
 
 using namespace clang;
 using namespace sema;
 
+static std::unique_ptr<SemaProxy> getSemaProxyImplementation(Sema &SemaRef);
+
 SourceLocation Sema::getLocForEndOfToken(SourceLocation Loc, unsigned Offset) {
   return Lexer::getLocForEndOfToken(Loc, Offset, SourceMgr, LangOpts);
 }
@@ -622,6 +625,15 @@ Sema::~Sema() {
   SemaPPCallbackHandler->reset();
 }
 
+void Sema::RegisterSemaProxy() {
+  // Let the AST context relies on Sema for
+  // ast mutations features that require semantic analysis
+  // (lazy instantiation, reflection, etc).
+  Context.setSemaProxy(getSemaProxyImplementation(*this));
+}
+
+void Sema::UnregisterSemaProxy() { Context.setSemaProxy({}); }
+
 void Sema::runWithSufficientStackSpace(SourceLocation Loc,
                                        llvm::function_ref<void()> Fn) {
   StackHandler.runWithSufficientStackSpace(Loc, Fn);
@@ -2964,3 +2976,21 @@ Attr *Sema::CreateAnnotationAttr(const ParsedAttr &AL) {
 
   return CreateAnnotationAttr(AL, Str, Args);
 }
+
+class SemaProxyImplementation final : public SemaProxy {
+private:
+  Sema &SemaRef;
+
+public:
+  SemaProxyImplementation(Sema &SemaRef) : SemaRef(SemaRef) {}
+  void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
+                                     FunctionDecl *Function) override {
+    SemaRef.InstantiateFunctionDefinition(
+        PointOfInstantiation, Function, /*Recursive=*/true,
+        /*DefinitionRequired=*/true, /*AtEndOfTU=*/false);
+  }
+};
+
+std::unique_ptr<SemaProxy> getSemaProxyImplementation(Sema &SemaRef) {
+  return std::make_unique<SemaProxyImplementation>(SemaRef);
+}
diff --git a/clang/test/SemaCXX/constexpr-late-instantiation.cpp 
b/clang/test/SemaCXX/constexpr-late-instantiation.cpp
index 9aec0c90e61dc..59cfbfdff0e03 100644
--- a/clang/test/SemaCXX/constexpr-late-instantiation.cpp
+++ b/clang/test/SemaCXX/constexpr-late-instantiation.cpp
@@ -1,16 +1,90 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify
-// RUN: %clang_cc1 %s -fexperimental-new-constant-interpreter -fsyntax-only 
-verify
+// RUN: %clang_cc1 %s -std=c++14 -fsyntax-only -verify
+// RUN: %clang_cc1 %s -std=c++20 -fsyntax-only -verify
+// RUN: %clang_cc1 %s -std=c++2c -fsyntax-only -verify
+
+// RUN: %clang_cc1 %s -std=c++14 -fsyntax-only 
-fexperimental-new-constant-interpreter -verify
+// RUN: %clang_cc1 %s -std=c++20 -fsyntax-only 
-fexperimental-new-constant-interpreter -verify
+// RUN: %clang_cc1 %s -std=c++2c -fsyntax-only 
-fexperimental-new-constant-interpreter -verify
 
 template <typename T>
-constexpr T foo(T a);   // expected-note {{declared here}}
+constexpr T foo(T a);   // expected-note {{explicit instantiation refers here}}
 
 int main() {
   int k = foo<int>(5);  // Ok
-  constexpr int j =     // expected-error {{constexpr variable 'j' must be 
initialized by a constant expression}}
-          foo<int>(5);  // expected-note {{undefined function 'foo<int>' 
cannot be used in a constant expression}}
+  constexpr int j =
+          foo<int>(5);  // expected-error {{explicit instantiation of 
undefined function template 'foo'}} \
+                        // expected-error {{constexpr variable 'j' must be 
initialized by a constant expression}}
 }
 
 template <typename T>
 constexpr T foo(T a) {
   return a;
 }
+
+
+namespace GH73232 {
+namespace ex1 {
+template <typename T>
+constexpr void g(T);
+
+constexpr int f() {
+  g(0);
+  return 0;
+}
+
+template <typename T>
+constexpr void g(T) {}
+
+constexpr auto z = f();
+}
+
+namespace ex2 {
+template <typename> constexpr static void fromType();
+
+void registerConverter() { fromType<int>(); }
+template <typename> struct QMetaTypeId  {};
+template <typename T> constexpr void fromType() {
+  (void)QMetaTypeId<T>{};
+}
+template <> struct QMetaTypeId<int> {};
+} // namespace ex2
+
+namespace ex3 {
+
+#if __cplusplus > 202302L
+struct A {
+    consteval A(int i) {
+        chk(i);
+    }
+    constexpr void chk(auto) {}
+};
+A a{1};
+
+#endif
+
+}
+
+} // namespace GH73232
+
+
+namespace GH156255 {
+
+class X
+{
+public:
+    constexpr int f( int x ) const
+    {
+        return g( x );
+    }
+
+private:
+
+    template<class T>
+    constexpr T g( T x ) const
+    {
+        return x;
+    }
+};
+
+constexpr int x = X().f( 1 );
+}
diff --git a/clang/test/SemaCXX/constexpr-subobj-initialization.cpp 
b/clang/test/SemaCXX/constexpr-subobj-initialization.cpp
index f0252df1e2ce1..c2e51d3920f6a 100644
--- a/clang/test/SemaCXX/constexpr-subobj-initialization.cpp
+++ b/clang/test/SemaCXX/constexpr-subobj-initialization.cpp
@@ -47,12 +47,13 @@ constexpr Bar bb; // expected-error {{must be initialized 
by a constant expressi
 
 template <typename Ty>
 struct Baz {
-  constexpr Baz(); // expected-note {{declared here}}
+  constexpr Baz(); // expected-note {{explicit instantiation refers here}}
 };
 
 struct Quux : Baz<Foo>, private Bar {
   int i;
-  constexpr Quux() : i(12) {} // expected-note {{undefined constructor 'Baz' 
cannot be used in a constant expression}}
+  constexpr Quux() : i(12) {} // expected-error {{explicit instantiation of 
undefined member function 'Baz' of class template 'Baz<Foo>'}} \
+                              // expected-note {{subexpression not valid in a 
constant expression}}
 };
 
 constexpr Quux qx; // expected-error {{must be initialized by a constant 
expression}} \
diff --git a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp 
b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp
index 39097d17441f7..a2c5b583904f2 100644
--- a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp
+++ b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp
@@ -75,10 +75,11 @@ struct a {
 a aa(fdupe<int>((f<int>(7))));
 
 template <typename T>
-constexpr int foo(T t);     // expected-note {{declared here}}
+constexpr int foo(T t);     // expected-note {{explicit instantiation refers 
here}}
 
 a bb(f<int>(foo<int>(7))); // expected-error{{call to immediate function 
'f<int>' is not a constant expression}} \
-                           // expected-note{{undefined function 'foo<int>' 
cannot be used in a constant expression}}
+                           // expected-error{{explicit instantiation of 
undefined function template 'foo'}} \
+                           // expected-note{{subexpression not valid in a 
constant expression}}
 
 }
 

>From 3a3ad6cb7cb21df5fb9757770dfb7ffe1be1f071 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <[email protected]>
Date: Fri, 2 Jan 2026 10:11:38 +0100
Subject: [PATCH 2/8] Address some review comments

---
 clang/docs/ReleaseNotes.rst                   |  2 +-
 clang/lib/AST/ByteCode/Interp.cpp             | 12 ++---
 clang/lib/AST/ByteCode/InterpState.cpp        |  4 +-
 clang/lib/AST/ByteCode/State.h                |  4 +-
 clang/lib/AST/ExprConstant.cpp                |  4 +-
 clang/lib/Sema/Sema.cpp                       |  5 +-
 .../SemaCXX/constexpr-late-instantiation.cpp  | 49 +++++++++++++++++++
 7 files changed, 65 insertions(+), 15 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 009a09819f359..e0b69dac70baa 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -403,7 +403,7 @@ Bug Fixes to C++ Support
 - Fixed a bug where our ``member-like constrained friend`` checking caused an 
incorrect analysis of lambda captures. (#GH156225)
 - Fixed a crash when implicit conversions from initialize list to arrays of
   unknown bound during constant evaluation. (#GH151716)
-- Instantiate constexpr functions as needed before they are evaluated. 
(#GH73232)
+- Instantiate constexpr functions as needed before they are evaluated. 
(#GH73232) (#GH35052) (#GH100897)
 - Support the dynamic_cast to final class optimization with pointer
   authentication enabled. (#GH152601)
 - Fix the check for narrowing int-to-float conversions, so that they are 
detected in
diff --git a/clang/lib/AST/ByteCode/Interp.cpp 
b/clang/lib/AST/ByteCode/Interp.cpp
index 11f629d0d97c5..b725ccc6a1a20 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -7,7 +7,6 @@
 
//===----------------------------------------------------------------------===//
 
 #include "Interp.h"
-#include "ByteCode/Source.h"
 #include "Compiler.h"
 #include "Function.h"
 #include "InterpFrame.h"
@@ -1626,7 +1625,7 @@ bool CheckBitCast(InterpState &S, CodePtr OpPC, const 
Type *TargetType,
 }
 
 static void compileFunction(InterpState &S, const Function *Func,
-                            SourceLocation Loc) {
+                            CodePtr OpPC) {
 
   const FunctionDecl *Fn = Func->getDecl();
 
@@ -1636,12 +1635,13 @@ static void compileFunction(InterpState &S, const 
Function *Func,
   // definition to exist or if the existence of the definition affects the
   // semantics of the program.
   if (!Fn->isDefined() && Fn->isImplicitlyInstantiable() && Fn->isConstexpr() 
&&
-      S.inConstantContext() && !S.TryConstantInitialization &&
+      S.inConstantContext() && !S.PerformingTrialEvaluation &&
       !S.checkingPotentialConstantExpression()) {
     SemaProxy *SP = S.getASTContext().getSemaProxy();
     if (!SP)
       return;
-    SP->InstantiateFunctionDefinition(Loc, const_cast<FunctionDecl *>(Fn));
+    SP->InstantiateFunctionDefinition(S.Current->getLocation(OpPC),
+                                      const_cast<FunctionDecl *>(Fn));
   }
   Fn = Fn->getDefinition();
   if (!Fn)
@@ -1674,7 +1674,7 @@ bool CallVar(InterpState &S, CodePtr OpPC, const Function 
*Func,
   }
 
   if (!Func->isFullyCompiled())
-    compileFunction(S, Func, S.Current->getLocation(OpPC));
+    compileFunction(S, Func, OpPC);
 
   if (!CheckCallable(S, OpPC, Func))
     return false;
@@ -1751,7 +1751,7 @@ bool Call(InterpState &S, CodePtr OpPC, const Function 
*Func,
   }
 
   if (!Func->isFullyCompiled())
-    compileFunction(S, Func, S.Current->getLocation(OpPC));
+    compileFunction(S, Func, OpPC);
 
   if (!CheckCallable(S, OpPC, Func))
     return cleanup();
diff --git a/clang/lib/AST/ByteCode/InterpState.cpp 
b/clang/lib/AST/ByteCode/InterpState.cpp
index d8a8d76b9f06d..4d6c182392e1c 100644
--- a/clang/lib/AST/ByteCode/InterpState.cpp
+++ b/clang/lib/AST/ByteCode/InterpState.cpp
@@ -24,7 +24,7 @@ InterpState::InterpState(const State &Parent, Program &P, 
InterpStack &Stk,
       StepsLeft(Ctx.getLangOpts().ConstexprStepLimit),
       InfiniteSteps(StepsLeft == 0) {
   InConstantContext = Parent.InConstantContext;
-  TryConstantInitialization = Parent.TryConstantInitialization;
+  PerformingTrialEvaluation = Parent.PerformingTrialEvaluation;
   CheckingPotentialConstantExpression =
       Parent.CheckingPotentialConstantExpression;
   CheckingForUndefinedBehavior = Parent.CheckingForUndefinedBehavior;
@@ -39,7 +39,7 @@ InterpState::InterpState(const State &Parent, Program &P, 
InterpStack &Stk,
       Current(&BottomFrame), StepsLeft(Ctx.getLangOpts().ConstexprStepLimit),
       InfiniteSteps(StepsLeft == 0) {
   InConstantContext = Parent.InConstantContext;
-  TryConstantInitialization = Parent.TryConstantInitialization;
+  PerformingTrialEvaluation = Parent.PerformingTrialEvaluation;
   CheckingPotentialConstantExpression =
       Parent.CheckingPotentialConstantExpression;
   CheckingForUndefinedBehavior = Parent.CheckingForUndefinedBehavior;
diff --git a/clang/lib/AST/ByteCode/State.h b/clang/lib/AST/ByteCode/State.h
index 841da0836516d..c4a4071f6f359 100644
--- a/clang/lib/AST/ByteCode/State.h
+++ b/clang/lib/AST/ByteCode/State.h
@@ -187,7 +187,9 @@ class State {
   /// is set; this is used when evaluating ICEs in C.
   bool CheckingForUndefinedBehavior = false;
 
-  bool TryConstantInitialization = false;
+  /// Whether we are performing trial evaluation, i.e when evaluating the
+  /// initializer of a constant-initialized variable.
+  bool PerformingTrialEvaluation = false;
 
   EvaluationMode EvalMode;
   ASTContext &Ctx;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 7ceea521640f2..d2026108e9de1 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -6973,7 +6973,7 @@ static void InstantiateFunctionBeforeCall(const 
FunctionDecl *FD,
   // semantics of the program.
 
   if (!FD->isDefined() && FD->isImplicitlyInstantiable() && FD->isConstexpr() 
&&
-      Info.InConstantContext && !Info.TryConstantInitialization &&
+      Info.InConstantContext && !Info.PerformingTrialEvaluation &&
       !Info.checkingPotentialConstantExpression()) {
 
     SemaProxy *SP = Info.getASTContext().getSemaProxy();
@@ -20828,7 +20828,7 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const 
ASTContext &Ctx,
                     : EvaluationMode::ConstantFold);
   Info.setEvaluatingDecl(VD, Value);
   Info.InConstantContext = IsConstantInitialization;
-  Info.TryConstantInitialization =
+  Info.PerformingTrialEvaluation =
       !VD->isConstexpr() && !VD->hasAttr<ConstInitAttr>();
 
   SourceLocation DeclLoc = VD->getLocation();
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 90b919974586b..bdc5155214730 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -75,7 +75,6 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Support/TimeProfiler.h"
-#include <memory>
 #include <optional>
 
 using namespace clang;
@@ -626,8 +625,8 @@ Sema::~Sema() {
 }
 
 void Sema::RegisterSemaProxy() {
-  // Let the AST context relies on Sema for
-  // ast mutations features that require semantic analysis
+  // Let the AST context rely on Sema for
+  // AST mutation features that require semantic analysis
   // (lazy instantiation, reflection, etc).
   Context.setSemaProxy(getSemaProxyImplementation(*this));
 }
diff --git a/clang/test/SemaCXX/constexpr-late-instantiation.cpp 
b/clang/test/SemaCXX/constexpr-late-instantiation.cpp
index 59cfbfdff0e03..cbfd26587c128 100644
--- a/clang/test/SemaCXX/constexpr-late-instantiation.cpp
+++ b/clang/test/SemaCXX/constexpr-late-instantiation.cpp
@@ -88,3 +88,52 @@ class X
 
 constexpr int x = X().f( 1 );
 }
+
+
+namespace GH35052 {
+
+template <typename F>
+constexpr int func(F f) {
+    if constexpr (f(1UL)) {
+        return 1;
+    }
+    return 0;
+}
+
+int test() {
+    auto predicate = [](auto v) constexpr -> bool  { return v == 1; };
+    return func(predicate);
+}
+
+}  // namespace GH35052
+
+namespace GH115118 {
+
+struct foo {
+    foo(const foo&) = default;
+    foo(auto)
+        requires([]<int = 0>() -> bool { return true; }())
+    {}
+};
+
+struct bar {
+    foo x;
+};
+
+}  // namespace GH115118
+
+namespace GH100897 {
+
+template <typename>
+constexpr auto foo() noexcept {
+    constexpr auto extract_size = []<typename argument_t>() constexpr -> int {
+        return 1;
+    };
+
+    constexpr int result = extract_size.template operator()<int>();
+    return result;
+}
+
+void test() { foo<void>(); }
+
+}  // namespace GH100897

>From 1b7302264724fbb9b7c68457ad5b679a809e87bd Mon Sep 17 00:00:00 2001
From: Corentin Jabot <[email protected]>
Date: Fri, 2 Jan 2026 13:15:57 +0100
Subject: [PATCH 3/8] fix tests

---
 clang/test/SemaCXX/constexpr-late-instantiation.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/clang/test/SemaCXX/constexpr-late-instantiation.cpp 
b/clang/test/SemaCXX/constexpr-late-instantiation.cpp
index cbfd26587c128..24df761cf0a52 100644
--- a/clang/test/SemaCXX/constexpr-late-instantiation.cpp
+++ b/clang/test/SemaCXX/constexpr-late-instantiation.cpp
@@ -89,6 +89,7 @@ class X
 constexpr int x = X().f( 1 );
 }
 
+#if __cplusplus > 202002L
 
 namespace GH35052 {
 
@@ -105,6 +106,7 @@ int test() {
     return func(predicate);
 }
 
+
 }  // namespace GH35052
 
 namespace GH115118 {
@@ -122,6 +124,7 @@ struct bar {
 
 }  // namespace GH115118
 
+
 namespace GH100897 {
 
 template <typename>
@@ -137,3 +140,5 @@ constexpr auto foo() noexcept {
 void test() { foo<void>(); }
 
 }  // namespace GH100897
+
+#endif

>From 693f142b0900fc2df9cfa22b638dc97f2e450955 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <[email protected]>
Date: Fri, 9 Jan 2026 10:50:19 +0100
Subject: [PATCH 4/8] address more feedback

---
 clang/docs/ReleaseNotes.rst                 | 13 ++++++++--
 clang/include/clang/AST/ASTContext.h        |  2 +-
 clang/include/clang/Sema/Sema.h             |  4 +--
 clang/lib/AST/ByteCode/Interp.cpp           |  4 +--
 clang/lib/AST/ExprConstShared.h             |  4 +++
 clang/lib/AST/ExprConstant.cpp              | 27 ++++++++++++---------
 clang/lib/Interpreter/IncrementalParser.cpp |  4 +--
 clang/lib/Parse/ParseAST.cpp                | 24 ++++++++++--------
 clang/lib/Sema/Sema.cpp                     |  6 ++---
 9 files changed, 55 insertions(+), 33 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e0b69dac70baa..3af3f81b4f53c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -221,8 +221,8 @@ Non-comprehensive list of changes in this release
   allocator-level heap organization strategies. A feature to instrument all
   allocation functions with a token ID can be enabled via the
   ``-fsanitize=alloc-token`` flag.
-
-- A new generic byte swap builtin function ``__builtin_bswapg`` that extends 
the existing
+ 
+- A new generic byte swap builtin function ``__builtin_bswapg`` that extends 
the existing 
   __builtin_bswap{16,32,64} function family to support all standard integer 
types.
 
 - A builtin ``__builtin_infer_alloc_token(<args>, ...)`` is provided to allow
@@ -318,6 +318,7 @@ Improvements to Clang's diagnostics
 
   .. code-block:: c++
 
+<<<<<<< HEAD
 <<<<<<< HEAD
     struct DanglingView {
       std::string_view view;
@@ -343,6 +344,14 @@ Improvements to Clang's diagnostics
 - Clang now generates a fix-it for C++20 designated initializers when the
   initializers do not match the declaration order in the structure.
 >>>>>>> 3f06fd997749 ([Clang] Instantiate constexpr function when they are 
 >>>>>>> needed.)
+=======
+- Fixed a crash when enabling ``-fdiagnostics-format=sarif`` and the output 
+  carries messages like 'In file included from ...' or 'In module ...'.
+  Now the include/import locations are written into 
`sarif.run.result.relatedLocations`.
+
+- Clang now generates a fix-it for C++20 designated initializers when the 
+  initializers do not match the declaration order in the structure. 
+>>>>>>> ea6211a89115 (address more feedback)
 
 Improvements to Clang's time-trace
 ----------------------------------
diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index bf75813922c6e..7ba0cde3aba8e 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -222,7 +222,7 @@ struct SemaProxy {
   virtual ~SemaProxy() = default;
 
   virtual void
-  InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
+  instantiateFunctionDefinition(SourceLocation PointOfInstantiation,
                                 FunctionDecl *Function) = 0;
 };
 
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index fa8a54a3730ac..45f236034bb0e 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -910,8 +910,8 @@ class Sema final : public SemaBase {
   /// initialized but before it parses anything.
   void Initialize();
 
-  void RegisterSemaProxy();
-  void UnregisterSemaProxy();
+  void registerSemaProxy();
+  void unregisterSemaProxy();
 
   /// This virtual key function only exists to limit the emission of debug info
   /// describing the Sema class. GCC and Clang only emit debug info for a class
diff --git a/clang/lib/AST/ByteCode/Interp.cpp 
b/clang/lib/AST/ByteCode/Interp.cpp
index b725ccc6a1a20..a7729741cbc5c 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1634,13 +1634,13 @@ static void compileFunction(InterpState &S, const 
Function *Func,
   // when the specialization is referenced in a context that requires a 
function
   // definition to exist or if the existence of the definition affects the
   // semantics of the program.
-  if (!Fn->isDefined() && Fn->isImplicitlyInstantiable() && Fn->isConstexpr() 
&&
+  if (FunctionDefinitionCanBeLazilyInstantiated(Func->getDecl()) &&
       S.inConstantContext() && !S.PerformingTrialEvaluation &&
       !S.checkingPotentialConstantExpression()) {
     SemaProxy *SP = S.getASTContext().getSemaProxy();
     if (!SP)
       return;
-    SP->InstantiateFunctionDefinition(S.Current->getLocation(OpPC),
+    SP->instantiateFunctionDefinition(S.Current->getLocation(OpPC),
                                       const_cast<FunctionDecl *>(Fn));
   }
   Fn = Fn->getDefinition();
diff --git a/clang/lib/AST/ExprConstShared.h b/clang/lib/AST/ExprConstShared.h
index 550b36c232161..a88e8fc4fa96e 100644
--- a/clang/lib/AST/ExprConstShared.h
+++ b/clang/lib/AST/ExprConstShared.h
@@ -28,6 +28,7 @@ class LangOptions;
 class ASTContext;
 class CharUnits;
 class Expr;
+class FunctionDecl;
 } // namespace clang
 using namespace clang;
 /// Values returned by __builtin_classify_type, chosen to match the values
@@ -84,4 +85,7 @@ uint8_t GFNIAffine(uint8_t XByte, const llvm::APInt &AQword,
 llvm::APSInt NormalizeRotateAmount(const llvm::APSInt &Value,
                                    const llvm::APSInt &Amount);
 
+/// Whether we can instantiate FD during constant evaluation
+bool FunctionDefinitionCanBeLazilyInstantiated(const FunctionDecl *FD);
+
 #endif
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index d2026108e9de1..d67cd76a7f407 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -6963,8 +6963,14 @@ static bool handleTrivialCopy(EvalInfo &Info, const 
ParmVarDecl *Param,
       CopyObjectRepresentation);
 }
 
-static void InstantiateFunctionBeforeCall(const FunctionDecl *FD,
-                                          EvalInfo &Info, SourceLocation Loc) {
+bool FunctionDefinitionCanBeLazilyInstantiated(const FunctionDecl *FD) {
+  return !FD->isDefined() && FD->isImplicitlyInstantiable() &&
+         FD->isConstexpr();
+}
+
+static void TryInstantiateFunctionBeforeCall(const FunctionDecl *FD,
+                                             EvalInfo &Info,
+                                             SourceLocation Loc) {
 
   // [C++26] [temp.inst] p5
   // [...] the function template specialization is implicitly instantiated
@@ -6972,16 +6978,15 @@ static void InstantiateFunctionBeforeCall(const 
FunctionDecl *FD,
   // definition to exist or if the existence of the definition affects the
   // semantics of the program.
 
-  if (!FD->isDefined() && FD->isImplicitlyInstantiable() && FD->isConstexpr() 
&&
-      Info.InConstantContext && !Info.PerformingTrialEvaluation &&
+  if (FunctionDefinitionCanBeLazilyInstantiated(FD) && Info.InConstantContext 
&&
+      !Info.PerformingTrialEvaluation &&
       !Info.checkingPotentialConstantExpression()) {
 
     SemaProxy *SP = Info.getASTContext().getSemaProxy();
     // Try to instantiate the definition if Sema is available
     // (i.e during the initial parse of the TU).
-    if (SP) {
-      SP->InstantiateFunctionDefinition(Loc, const_cast<FunctionDecl *>(FD));
-    }
+    if (SP)
+      SP->instantiateFunctionDefinition(Loc, const_cast<FunctionDecl *>(FD));
   }
 }
 
@@ -7378,7 +7383,7 @@ static bool HandleDestructionImpl(EvalInfo &Info, 
SourceRange CallRange,
   if (!Info.CheckCallLimit(CallRange.getBegin()))
     return false;
 
-  InstantiateFunctionBeforeCall(DD, Info, CallRange.getBegin());
+  TryInstantiateFunctionBeforeCall(DD, Info, CallRange.getBegin());
 
   const FunctionDecl *Definition = nullptr;
   const Stmt *Body = DD->getBody(Definition);
@@ -8847,7 +8852,7 @@ class ExprEvaluatorBase
 
     SourceLocation Loc = E->getExprLoc();
 
-    InstantiateFunctionBeforeCall(FD, Info, Loc);
+    TryInstantiateFunctionBeforeCall(FD, Info, Loc);
 
     const FunctionDecl *Definition = nullptr;
     const Stmt *Body = FD->getBody(Definition);
@@ -11369,7 +11374,7 @@ bool RecordExprEvaluator::VisitCXXConstructExpr(const 
CXXConstructExpr *E,
     return handleDefaultInitValue(T, Result);
   }
 
-  InstantiateFunctionBeforeCall(FD, Info, E->getBeginLoc());
+  TryInstantiateFunctionBeforeCall(FD, Info, E->getBeginLoc());
 
   const FunctionDecl *Definition = nullptr;
   const Stmt *Body = FD->getBody(Definition);
@@ -11412,7 +11417,7 @@ bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
   if (FD->isInvalidDecl() || FD->getParent()->isInvalidDecl())
     return false;
 
-  InstantiateFunctionBeforeCall(FD, Info, E->getBeginLoc());
+  TryInstantiateFunctionBeforeCall(FD, Info, E->getBeginLoc());
   const FunctionDecl *Definition = nullptr;
   const Stmt *Body = FD->getBody(Definition);
 
diff --git a/clang/lib/Interpreter/IncrementalParser.cpp 
b/clang/lib/Interpreter/IncrementalParser.cpp
index 5a24342e73ca4..5630b96927c38 100644
--- a/clang/lib/Interpreter/IncrementalParser.cpp
+++ b/clang/lib/Interpreter/IncrementalParser.cpp
@@ -42,11 +42,11 @@ IncrementalParser::IncrementalParser(CompilerInstance 
&Instance,
     External->StartTranslationUnit(Consumer);
 
   P->Initialize();
-  S.RegisterSemaProxy();
+  S.registerSemaProxy();
 }
 
 IncrementalParser::~IncrementalParser() {
-  S.UnregisterSemaProxy();
+  S.unregisterSemaProxy();
   P.reset();
 }
 
diff --git a/clang/lib/Parse/ParseAST.cpp b/clang/lib/Parse/ParseAST.cpp
index 1cea282f13a00..01e17a563838a 100644
--- a/clang/lib/Parse/ParseAST.cpp
+++ b/clang/lib/Parse/ParseAST.cpp
@@ -163,22 +163,26 @@ void clang::ParseAST(Sema &S, bool PrintStats, bool 
SkipFunctionBodies) {
     });
     P.Initialize();
 
-    auto Unregister =
-        llvm::make_scope_exit([&S]() { S.UnregisterSemaProxy(); });
-    S.RegisterSemaProxy();
+    S.registerSemaProxy();
 
     Parser::DeclGroupPtrTy ADecl;
     Sema::ModuleImportState ImportState;
     EnterExpressionEvaluationContext PotentiallyEvaluated(
         S, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
 
-    for (bool AtEOF = P.ParseFirstTopLevelDecl(ADecl, ImportState); !AtEOF;
-         AtEOF = P.ParseTopLevelDecl(ADecl, ImportState)) {
-      // If we got a null return and something *was* parsed, ignore it.  This
-      // is due to a top-level semicolon, an action override, or a parse error
-      // skipping something.
-      if (ADecl && !Consumer->HandleTopLevelDecl(ADecl.get()))
-        return;
+    {
+      // Remove the sema proxy after the initial parse.
+      llvm::scope_exit SemaProxyScope([&S]() { S.unregisterSemaProxy(); });
+
+      for (bool AtEOF = P.ParseFirstTopLevelDecl(ADecl, ImportState); !AtEOF;
+           AtEOF = P.ParseTopLevelDecl(ADecl, ImportState)) {
+
+        // If we got a null return and something *was* parsed, ignore it.  This
+        // is due to a top-level semicolon, an action override, or a parse 
error
+        // skipping something.
+        if (ADecl && !Consumer->HandleTopLevelDecl(ADecl.get()))
+          return;
+      }
     }
   }
 
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index bdc5155214730..d562c8dc95374 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -624,14 +624,14 @@ Sema::~Sema() {
   SemaPPCallbackHandler->reset();
 }
 
-void Sema::RegisterSemaProxy() {
+void Sema::registerSemaProxy() {
   // Let the AST context rely on Sema for
   // AST mutation features that require semantic analysis
   // (lazy instantiation, reflection, etc).
   Context.setSemaProxy(getSemaProxyImplementation(*this));
 }
 
-void Sema::UnregisterSemaProxy() { Context.setSemaProxy({}); }
+void Sema::unregisterSemaProxy() { Context.setSemaProxy({}); }
 
 void Sema::runWithSufficientStackSpace(SourceLocation Loc,
                                        llvm::function_ref<void()> Fn) {
@@ -2982,7 +2982,7 @@ class SemaProxyImplementation final : public SemaProxy {
 
 public:
   SemaProxyImplementation(Sema &SemaRef) : SemaRef(SemaRef) {}
-  void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
+  void instantiateFunctionDefinition(SourceLocation PointOfInstantiation,
                                      FunctionDecl *Function) override {
     SemaRef.InstantiateFunctionDefinition(
         PointOfInstantiation, Function, /*Recursive=*/true,

>From 8daac7ba06c7c8e1c3413c4bc524ad055cc6597f Mon Sep 17 00:00:00 2001
From: Corentin Jabot <[email protected]>
Date: Mon, 16 Feb 2026 19:53:16 +0100
Subject: [PATCH 5/8] fix rebase

---
 clang/docs/ReleaseNotes.rst       | 173 +-----------------------------
 clang/lib/AST/ByteCode/Interp.cpp |   2 +-
 2 files changed, 6 insertions(+), 169 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 3af3f81b4f53c..68400853e36fc 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -140,97 +140,9 @@ Non-comprehensive list of changes in this release
   Usable in constant expressions. Implicit conversion is supported for
   class/struct types with conversion operators.
 
-<<<<<<< HEAD
 - A new generic bit-reverse builtin function ``__builtin_bitreverseg`` that
   extends bit-reversal support to all standard integers type, including
   ``_BitInt``
-=======
-- Added ``__builtin_elementwise_ldexp``.
-
-- Added ``__builtin_elementwise_fshl`` and ``__builtin_elementwise_fshr``.
-
-- ``__builtin_elementwise_abs`` can now be used in constant expression.
-
-- Added ``__builtin_elementwise_minnumnum`` and 
``__builtin_elementwise_maxnumnum``.
-
-- Trapping UBSan (e.g. ``-fsanitize=undefined -fsanitize-trap=undefined``) now
-  emits a string describing the reason for trapping into the generated debug
-  info. This feature allows debuggers (e.g. LLDB) to display the reason for
-  trapping if the trap is reached. The string is currently encoded in the debug
-  info as an artificial frame that claims to be inlined at the trap location.
-  The function used for the artificial frame is an artificial function whose
-  name encodes the reason for trapping. The encoding used is currently the same
-  as ``__builtin_verbose_trap`` but might change in the future. This feature is
-  enabled by default but can be disabled by compiling with
-  ``-fno-sanitize-debug-trap-reasons``. The feature has a ``basic`` and
-  ``detailed`` mode (the default). The ``basic`` mode emits a hard-coded string
-  per trap kind (e.g. ``Integer addition overflowed``) and the ``detailed`` 
mode
-  emits a more descriptive string describing each individual trap (e.g. 
``signed
-  integer addition overflow in 'a + b'``). The ``detailed`` mode produces 
larger
-  debug info than ``basic`` but is more helpful for debugging. The
-  ``-fsanitize-debug-trap-reasons=`` flag can be used to switch between the
-  different modes or disable the feature entirely. Note due to trap merging in
-  optimized builds (i.e. in each function all traps of the same kind get merged
-  into the same trap instruction) the trap reasons might be removed. To prevent
-  this build without optimizations (i.e. use `-O0` or use the `optnone` 
function
-  attribute) or use the `fno-sanitize-merge=` flag in optimized builds.
-
-- ``__builtin_elementwise_max`` and ``__builtin_elementwise_min`` functions 
for integer types can
-  now be used in constant expressions.
-
-- A vector of booleans is now a valid condition for the ternary ``?:`` 
operator.
-  This binds to a simple vector select operation.
-
-- Added ``__builtin_masked_load``, ``__builtin_masked_expand_load``,
-  ``__builtin_masked_store``, ``__builtin_masked_compress_store`` for
-  conditional memory loads from vectors. Binds to the LLVM intrinsics of the
-  same name.
-
-- Added ``__builtin_masked_gather`` and ``__builtin_masked_scatter`` for
-  conditional gathering and scattering operations on vectors. Binds to the LLVM
-  intrinsics of the same name.
-
-- The ``__builtin_popcountg``, ``__builtin_ctzg``, and ``__builtin_clzg``
-  functions now accept fixed-size boolean vectors.
-
-- Use of ``__has_feature`` to detect the ``ptrauth_qualifier`` and 
``ptrauth_intrinsics``
-  features has been deprecated, and is restricted to the arm64e target only. 
The
-  correct method to check for these features is to test for the ``__PTRAUTH__``
-  macro.
-
-- Added a new builtin, ``__builtin_dedup_pack``, to remove duplicate types 
from a parameter pack.
-  This feature is particularly useful in template metaprogramming for 
normalizing type lists.
-  The builtin produces a new, unexpanded parameter pack that can be used in 
contexts like template
-  argument lists or base specifiers.
-
-  .. code-block:: c++
-
-    template <typename...> struct TypeList;
-
-    // The resulting type is TypeList<int, double, char>
-    using MyTypeList = TypeList<__builtin_dedup_pack<int, double, int, char, 
double>...>;
-
-  Currently, the use of ``__builtin_dedup_pack`` is limited to template 
arguments and base
-  specifiers, it also must be used within a template context.
-
-- ``__builtin_assume_dereferenceable`` now accepts non-constant size operands.
-
-- Fixed a crash when the second argument to ``__builtin_assume_aligned`` was 
not constant (#GH161314)
-
-- Introduce support for :doc:`allocation tokens <AllocToken>` to enable
-  allocator-level heap organization strategies. A feature to instrument all
-  allocation functions with a token ID can be enabled via the
-  ``-fsanitize=alloc-token`` flag.
- 
-- A new generic byte swap builtin function ``__builtin_bswapg`` that extends 
the existing 
-  __builtin_bswap{16,32,64} function family to support all standard integer 
types.
-
-- A builtin ``__builtin_infer_alloc_token(<args>, ...)`` is provided to allow
-  compile-time querying of allocation token IDs, where the builtin arguments
-  mirror those normally passed to an allocation function.
-
-- Clang now rejects the invalid use of ``constexpr`` with ``auto`` and an 
explicit type in C. (#GH163090)
->>>>>>> 3f06fd997749 ([Clang] Instantiate constexpr function when they are 
needed.)
 
 New Compiler Flags
 ------------------
@@ -318,8 +230,6 @@ Improvements to Clang's diagnostics
 
   .. code-block:: c++
 
-<<<<<<< HEAD
-<<<<<<< HEAD
     struct DanglingView {
       std::string_view view;
       DanglingView(std::string s) : view(s) {}  // warning: address of stack 
memory escapes to a field
@@ -331,27 +241,11 @@ Improvements to Clang's diagnostics
   when accessing a member function on a past-the-end array element.
   (#GH179128)
 
-- Added a missing space to the FixIt for the ``implicit-int`` group of 
diagnostics and 
+- Added a missing space to the FixIt for the ``implicit-int`` group of 
diagnostics and
   made sure that only one such diagnostic and FixIt is emitted per declaration 
group. (#GH179354)
 
 - The ``-Wloop-analysis`` warning has been extended to catch more cases of
   variable modification inside lambda expressions (#GH132038).
-=======
-- Fixed a crash when enabling ``-fdiagnostics-format=sarif`` and the output
-  carries messages like 'In file included from ...' or 'In module ...'.
-  Now the include/import locations are written into 
`sarif.run.result.relatedLocations`.
-
-- Clang now generates a fix-it for C++20 designated initializers when the
-  initializers do not match the declaration order in the structure.
->>>>>>> 3f06fd997749 ([Clang] Instantiate constexpr function when they are 
needed.)
-=======
-- Fixed a crash when enabling ``-fdiagnostics-format=sarif`` and the output 
-  carries messages like 'In file included from ...' or 'In module ...'.
-  Now the include/import locations are written into 
`sarif.run.result.relatedLocations`.
-
-- Clang now generates a fix-it for C++20 designated initializers when the 
-  initializers do not match the declaration order in the structure. 
->>>>>>> ea6211a89115 (address more feedback)
 
 Improvements to Clang's time-trace
 ----------------------------------
@@ -386,68 +280,11 @@ Bug Fixes to Attribute Support
 
 Bug Fixes to C++ Support
 ^^^^^^^^^^^^^^^^^^^^^^^^
-<<<<<<< HEAD
 - Fixed a crash when instantiating ``requires`` expressions involving 
substitution failures in C++ concepts. (#GH176402)
 - Fixed a crash when a default argument is passed to an explicit object 
parameter. (#GH176639)
 - Fixed a crash when diagnosing an invalid static member function with an 
explicit object parameter (#GH177741)
-- Fixed a crash when evaluating uninitialized GCC vector/ext_vector_type 
vectors in ``constexpr``. (#GH180044)
-=======
-- Diagnose binding a reference to ``*nullptr`` during constant evaluation. 
(#GH48665)
-- Suppress ``-Wdeprecated-declarations`` in implicitly generated functions. 
(#GH147293)
-- Fix a crash when deleting a pointer to an incomplete array (#GH150359).
-- Fixed a mismatched lambda scope bug when propagating up ``consteval`` within 
nested lambdas. (#GH145776)
-- Disallow immediate escalation in destructors. (#GH109096)
-- Fix an assertion failure when expression in assumption attribute
-  (``[[assume(expr)]]``) creates temporary objects.
-- Fix the dynamic_cast to final class optimization to correctly handle
-  casts that are guaranteed to fail (#GH137518).
-- Fix bug rejecting partial specialization of variable templates with auto 
NTTPs (#GH118190).
-- Fix a crash if errors "member of anonymous [...] redeclares" and
-  "initializing multiple members of union" coincide (#GH149985).
-- Fix a crash when using ``explicit(bool)`` in pre-C++11 language modes. 
(#GH152729)
-- Fix the parsing of variadic member functions when the ellipis immediately 
follows a default argument.(#GH153445)
-- Fix a crash when using an explicit object parameter in a non-member function 
with an invalid return type.(#GH173943)
-- Fixed a bug that caused ``this`` captured by value in a lambda with a 
dependent explicit object parameter to not be
-  instantiated properly. (#GH154054)
-- Fixed a bug where our ``member-like constrained friend`` checking caused an 
incorrect analysis of lambda captures. (#GH156225)
-- Fixed a crash when implicit conversions from initialize list to arrays of
-  unknown bound during constant evaluation. (#GH151716)
 - Instantiate constexpr functions as needed before they are evaluated. 
(#GH73232) (#GH35052) (#GH100897)
-- Support the dynamic_cast to final class optimization with pointer
-  authentication enabled. (#GH152601)
-- Fix the check for narrowing int-to-float conversions, so that they are 
detected in
-  cases where converting the float back to an integer is undefined behaviour 
(#GH157067).
-- Stop rejecting C++11-style attributes on the first argument of constructors 
in older
-  standards. (#GH156809).
-- Fix a crash when applying binary or ternary operators to two same function 
types with different spellings,
-  where at least one of the function parameters has an attribute which affects
-  the function type.
-- Fix an assertion failure when a ``constexpr`` variable is only referenced 
through
-  ``__builtin_addressof``, and related issues with builtin arguments. 
(#GH154034)
-- Fix an assertion failure when taking the address on a non-type template 
parameter argument of
-  object type. (#GH151531)
-- Suppress ``-Wdouble-promotion`` when explicitly asked for with C++ list 
initialization (#GH33409).
-- Fix the result of `__builtin_is_implicit_lifetime` for types with a 
user-provided constructor. (#GH160610)
-- Correctly deduce return types in ``decltype`` expressions. (#GH160497) 
(#GH56652) (#GH116319) (#GH161196)
-- Fixed a crash in the pre-C++23 warning for attributes before a lambda 
declarator (#GH161070).
-- Fix a crash when attempting to deduce a deduction guide from a non deducible 
template template parameter. (#130604)
-- Fix for clang incorrectly rejecting the default construction of a union with
-  nontrivial member when another member has an initializer. (#GH81774)
-- Fixed a template depth issue when parsing lambdas inside a type constraint. 
(#GH162092)
-- Fix the support of zero-length arrays in SFINAE context. (#GH170040)
-- Diagnose unresolved overload sets in non-dependent compound requirements. 
(#GH51246) (#GH97753)
-- Fix a crash when extracting unavailable member type from alias in template 
deduction. (#GH165560)
-- Fix incorrect diagnostics for lambdas with init-captures inside braced 
initializers. (#GH163498)
-- Fixed an issue where templates prevented nested anonymous records from 
checking the deletion of special members. (#GH167217)
-- Fixed serialization of pack indexing types, where we failed to expand those 
packs from a PCH/module. (#GH172464)
-- Fixed spurious diagnoses of certain nested lambda expressions. (#GH149121) 
(#GH156579)
-- Fix the result of ``__is_pointer_interconvertible_base_of`` when arguments 
are qualified and passed via template parameters. (#GH135273)
-- Fixed a crash when evaluating nested requirements in requires-expressions 
that reference invented parameters. (#GH166325)
-- Fixed a crash when standard comparison categories (e.g. 
``std::partial_ordering``) are defined with incorrect static member types. 
(#GH170015) (#GH56571)
-- Fixed a crash when parsing the ``enable_if`` attribute on C function 
declarations with identifier-list parameters. (#GH173826)
-- Fixed an assertion failure triggered by nested lambdas during capture 
handling. (#GH172814)
-- Fixed an assertion failure in vector conversions involving 
instantiation-dependent template expressions. (#GH173347)
->>>>>>> 3f06fd997749 ([Clang] Instantiate constexpr function when they are 
needed.)
+- Fixed a crash when evaluating uninitialized GCC vector/ext_vector_type 
vectors in ``constexpr``. (#GH180044)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -548,7 +385,7 @@ AST Matchers
 
 clang-format
 ------------
-- Add ``ObjCSpaceAfterMethodDeclarationPrefix`` option to control space 
between the 
+- Add ``ObjCSpaceAfterMethodDeclarationPrefix`` option to control space 
between the
   '-'/'+' and the return type in Objective-C method declarations
 
 libclang
@@ -586,8 +423,8 @@ Python Binding Changes
   Affected methods: ``isKindOptional``, ``isKindTypedText``, 
``isKindPlaceHolder``,
   ``isKindInformative`` and ``isKindResultType``.
 - Add a deprecation warning to ``CodeCompletionResults.results``.
-  This property will become an implementation detail with changed behavior in 
a 
-  future release and should not be used directly.. Existing uses of 
+  This property will become an implementation detail with changed behavior in a
+  future release and should not be used directly.. Existing uses of
   ``CodeCompletionResults.results`` should be changed to directly use
   ``CodeCompletionResults``: it nows supports ``__len__`` and ``__getitem__``,
   so it can be used the same as ``CodeCompletionResults.results``.
diff --git a/clang/lib/AST/ByteCode/Interp.cpp 
b/clang/lib/AST/ByteCode/Interp.cpp
index a7729741cbc5c..2b750cfb4e0d7 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1960,7 +1960,7 @@ bool CallPtr(InterpState &S, CodePtr OpPC, uint32_t 
ArgSize,
   // because the Call/CallVirt below might access the instance pointer
   // but the Function's information about them is wrong.
   if (!F->isFullyCompiled())
-    compileFunction(S, F);
+    compileFunction(S, F, OpPC);
 
   if (!CheckCallable(S, OpPC, F))
     return false;

>From 0a1ca008eceaff8c71d821150a84c129302a6be3 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <[email protected]>
Date: Mon, 16 Feb 2026 20:23:25 +0100
Subject: [PATCH 6/8] check lookup happens in the appropriate context

---
 .../SemaCXX/constexpr-late-instantiation.cpp  | 22 +++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/clang/test/SemaCXX/constexpr-late-instantiation.cpp 
b/clang/test/SemaCXX/constexpr-late-instantiation.cpp
index 24df761cf0a52..38f056aacb607 100644
--- a/clang/test/SemaCXX/constexpr-late-instantiation.cpp
+++ b/clang/test/SemaCXX/constexpr-late-instantiation.cpp
@@ -91,6 +91,28 @@ constexpr int x = X().f( 1 );
 
 #if __cplusplus > 202002L
 
+namespace instantiation_context_lookup {
+
+static constexpr int i = 42;
+static constexpr int v = 8;
+
+
+constexpr int f(auto);
+
+constexpr int g(int v = 42) {
+    static constexpr int i = 1;
+    return f(1);
+    return 0;
+}
+
+constexpr int f(auto) {
+    return i + v;
+}
+
+static_assert(g() == 50);
+
+}
+
 namespace GH35052 {
 
 template <typename F>

>From 1b130562ce70518bbe549e3e765b3d2215e6bc03 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <[email protected]>
Date: Mon, 2 Mar 2026 15:11:50 +0100
Subject: [PATCH 7/8] add comments

---
 clang/include/clang/AST/ASTContext.h                | 6 ++++++
 clang/test/SemaCXX/constexpr-late-instantiation.cpp | 7 ++++---
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index f4ca6cf85259e..de06582636c29 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1440,8 +1440,14 @@ class ASTContext : public RefCountedBase<ASTContext> {
   /// with this AST context, if any.
   ASTMutationListener *getASTMutationListener() const { return Listener; }
 
+  /// Returns a SemaProxy*, i.e an object through which interact with Sema.
+  /// This will return null, unless setSemaProxy has been called.
+  /// As Sema is only available during parsing, getSemaProxy will return null
+  /// during CodeGen and when using the AST from tooling.
   SemaProxy *getSemaProxy();
 
+  /// Set the SemaProxy instance
+  /// This function is called from Sema during the initial parsing of a TU.
   void setSemaProxy(std::unique_ptr<SemaProxy> Proxy);
 
   void PrintStats() const;
diff --git a/clang/test/SemaCXX/constexpr-late-instantiation.cpp 
b/clang/test/SemaCXX/constexpr-late-instantiation.cpp
index 38f056aacb607..f6e13d762ae1a 100644
--- a/clang/test/SemaCXX/constexpr-late-instantiation.cpp
+++ b/clang/test/SemaCXX/constexpr-late-instantiation.cpp
@@ -86,6 +86,7 @@ class X
     }
 };
 
+// check that g is instantiated here.
 constexpr int x = X().f( 1 );
 }
 
@@ -125,7 +126,7 @@ constexpr int func(F f) {
 
 int test() {
     auto predicate = [](auto v) constexpr -> bool  { return v == 1; };
-    return func(predicate);
+    return func(predicate); // check that "predicate" is instantiated.
 }
 
 
@@ -141,7 +142,7 @@ struct foo {
 };
 
 struct bar {
-    foo x;
+    foo x; // check that the lambda gets instantiated.
 };
 
 }  // namespace GH115118
@@ -159,7 +160,7 @@ constexpr auto foo() noexcept {
     return result;
 }
 
-void test() { foo<void>(); }
+void test() { foo<void>(); } // check that the lambda gets instantiated.
 
 }  // namespace GH100897
 

>From 7a88bbe246447d43fbd8d2d74a6b339533bc58f3 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <[email protected]>
Date: Mon, 2 Mar 2026 15:14:36 +0100
Subject: [PATCH 8/8] inline getSemaProxy

---
 clang/include/clang/AST/ASTContext.h | 2 +-
 clang/lib/AST/ASTContext.cpp         | 2 --
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index de06582636c29..07045b286e7c9 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1444,7 +1444,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
   /// This will return null, unless setSemaProxy has been called.
   /// As Sema is only available during parsing, getSemaProxy will return null
   /// during CodeGen and when using the AST from tooling.
-  SemaProxy *getSemaProxy();
+  SemaProxy *getSemaProxy() { return SemaProxyPtr.get(); }
 
   /// Set the SemaProxy instance
   /// This function is called from Sema during the initial parsing of a TU.
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 8e8ffb1138607..da6b38595cb9b 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -963,8 +963,6 @@ 
ASTContext::setExternalSource(IntrusiveRefCntPtr<ExternalASTSource> Source) {
   ExternalSource = std::move(Source);
 }
 
-SemaProxy *ASTContext::getSemaProxy() { return SemaProxyPtr.get(); }
-
 void ASTContext::setSemaProxy(std::unique_ptr<SemaProxy> Proxy) {
   assert((!SemaProxyPtr || !Proxy) && "SemaProxy already set");
   SemaProxyPtr = std::move(Proxy);

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to