================
@@ -16746,13 +16736,23 @@ ExprResult
TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
// specific annotations, such as implicit casts, are discarded. Calling the
// corresponding sema action is necessary to recover those. Otherwise,
// equivalency of the result would be lost.
+ //
+ // In unevaluated contexts (e.g. inside decltype), CheckTemplateArgument
+ // forces constant evaluation that is inappropriate and may fail for
+ // valid expressions (e.g. function calls with by-value class parameters).
+ // Since we only need the type in such contexts, we can tolerate the
+ // failure and proceed with the transformed replacement as-is.
TemplateArgument SugaredConverted, CanonicalConverted;
- Replacement = SemaRef.CheckTemplateArgument(
+ ExprResult Checked = SemaRef.CheckTemplateArgument(
Param, ParamType, Replacement.get(), SugaredConverted,
CanonicalConverted,
/*StrictCheck=*/false, Sema::CTAK_Specified);
- if (Replacement.isInvalid())
- return true;
+ if (Checked.isInvalid()) {
+ if (!SemaRef.isUnevaluatedContext())
+ return true;
+ } else {
+ Replacement = Checked;
+ }
----------------
wx257osn2 wrote:
The key point of this PR is that when `Checked.isInvalid() &&
SemaRef.isUnevaluatedContext()` holds, we **do not** update `Replacement` with
`Checked`. So I think merging that part would be difficult.
As an alternative, we could reduce the nesting by writing something like:
```cpp
if (!Checked.isInvalid())
Replacement = Checked;
else if (!SemaRef.isUnevaluatedContext())
return true;
```
That said, this is not entirely pleasant either, since `!Checked.isInvalid()`
is a double negative. But `ActionResult` does not have an `isValid()` method,
so if we want to reduce the nesting, this seems to be about the only reasonable
option.
https://github.com/llvm/llvm-project/pull/196791
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits