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
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits