[clang] [Clang] Instantiate constexpr function when they are needed. (PR #173537)
Daniel M. Katz via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 5 12:52:44 PST 2026
katzdm wrote:
> Here's a test-case without library headers:
>
> ```
> template <typename T>
> struct unique_ptr {
> constexpr ~unique_ptr() {
> static_assert(sizeof(T));
> }
> T* ptr;
> };
>
> struct X;
>
> struct Y {
> Y() {}
> unique_ptr<X> member_;
> };
>
> struct X { int a; };
> ```
My reading of this is: `unique_ptr<X>::~unique_ptr()` is used by `Y::~Y()`; it has two points of instantiation:
1. immediately after the definition of `Y` and
2. at the end of the translation unit.
An implementation is free to choose either, so a program (like the one above) for which the choice matters is IFNDR. Clang is choosing (1) when the function is `constexpr` (see [here](https://github.com/llvm/llvm-project/blob/main/clang/lib/Sema/SemaExpr.cpp#L18955-L18966)), whereas GCC chooses (2). In that sense, there is no problem here.
But if we wish to pursue greater compatibility with GCC, then Clang is, of course, also free to choose (2) - it's worth noting the documented rationale (linked above) for why (1) has up until this time been preferred:
> ```cpp
> else if (Func->isConstexpr())
> // Do not defer instantiations of constexpr functions, to avoid the
> // expression evaluator needing to call back into Sema if it sees a
> // call to such a function.
> InstantiateFunctionDefinition(PointOfInstantiation, Func);
> ```
@cor3ntin - Now that the expression evaluator _can_ call back into `Sema`, is it worth revisiting this design? Perhaps (in a separate follow-on PR?) you might try removing the above early-instantiation. What do you think?
https://github.com/llvm/llvm-project/pull/173537
More information about the cfe-commits
mailing list