[clang] [Clang] Don't retain template FoundDecl for conversion function calls (PR #138377)
Younan Zhang via cfe-commits
cfe-commits at lists.llvm.org
Fri May 2 21:45:12 PDT 2025
https://github.com/zyn0217 created https://github.com/llvm/llvm-project/pull/138377
In consteval calls rewriting, we expect an instantiated AST to remain untouched. However, this was not true when rebuilding a MemberExpr in TreeTransform, as it relies on FoundDecl to build a resolved member call expression. This is due to the fact that the instantiated CXXMemberCallExpr still holds a template declaration as FoundDecl, leading to a non-dependent-to-dependent transform.
I don't think it makes much sense to preserve a template in FoundDecl. FoundDecl should primarily distinguish declarations whose getUnderlyingDecl() points elsewhere, like UsingShadowDecl.
Fixes https://github.com/llvm/llvm-project/issues/137885
>From 29785ccec0e2e31a22e75915f6a65cd09cc2d453 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Sat, 3 May 2025 12:30:23 +0800
Subject: [PATCH] [Clang] Don't retain template FoundDecl for conversion
function calls
In consteval calls rewriting, we expect an instantiated AST to remain
untouched. However, this was not true when rebuilding a MemberExpr in
TreeTransform, as it relies on FoundDecl to build a resolved member
call expression. This is due to the fact that the instantiated
CXXMemberCallExpr still holds a template declaration as FoundDecl,
leading to a non-dependent-to-dependent transform.
I don't think it makes much sense to preserve a template in FoundDecl.
FoundDecl should primarily distinguish declarations whose
getUnderlyingDecl() points elsewhere, like UsingShadowDecl.
---
clang/docs/ReleaseNotes.rst | 1 +
clang/lib/Sema/SemaOverload.cpp | 8 +++++++-
clang/test/SemaCXX/cxx2a-consteval.cpp | 28 ++++++++++++++++++++++++++
3 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 5ccd346a93b4f..5e26a3052452b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -545,6 +545,7 @@ Bug Fixes to C++ Support
- Clang no longer crashes when establishing subsumption between some constraint expressions. (#GH122581)
- Clang now issues an error when placement new is used to modify a const-qualified variable
in a ``constexpr`` function. (#GH131432)
+- Fixed an incorrect TreeTransform for calls to ``consteval`` functions if a conversion template is present. (#GH137885)
- Clang now emits a warning when class template argument deduction for alias templates is used in C++17. (#GH133806)
Bug Fixes to AST Handling
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 5b224b6c08fef..05707b964bc27 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -3977,7 +3977,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
// phase of [over.match.list] when the initializer list has exactly
// one element that is itself an initializer list, [...] and the
// conversion is to X or reference to cv X, user-defined conversion
- // sequences are not cnosidered.
+ // sequences are not considered.
if (SuppressUserConversions && ListInitializing) {
SuppressUserConversions =
NumArgs == 1 && isa<InitListExpr>(Args[0]) &&
@@ -14750,6 +14750,12 @@ ExprResult Sema::CreateUnresolvedLookupExpr(CXXRecordDecl *NamingClass,
ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl,
CXXConversionDecl *Method,
bool HadMultipleCandidates) {
+ // FoundDecl can be the TemplateDecl of Method. Don't retain a template in
+ // the FoundDecl as it impedes TransformMemberExpr.
+ // We go a bit further here: if there's no difference in UnderlyingDecl,
+ // then using FoundDecl vs Method shouldn't make a difference either.
+ if (FoundDecl->getUnderlyingDecl() == FoundDecl)
+ FoundDecl = Method;
// Convert the expression to match the conversion function's implicit object
// parameter.
ExprResult Exp;
diff --git a/clang/test/SemaCXX/cxx2a-consteval.cpp b/clang/test/SemaCXX/cxx2a-consteval.cpp
index fef4674d17841..d9d144cafdbcc 100644
--- a/clang/test/SemaCXX/cxx2a-consteval.cpp
+++ b/clang/test/SemaCXX/cxx2a-consteval.cpp
@@ -1272,3 +1272,31 @@ int main() {
}
} // namespace GH107175
+
+namespace GH137885 {
+
+template <typename... P> struct A {};
+
+template <int N>
+struct B {
+ consteval B() {}
+
+ template <typename... P> consteval operator A<P...>() const {
+ static_assert(sizeof...(P) == N);
+ return {};
+ }
+};
+
+template <typename T> struct type_identity {
+ using type = T;
+};
+
+template <typename... P>
+void foo(typename type_identity<A<P...>>::type a, P...) {}
+
+void foo() {
+ foo(B<0>());
+ foo(B<5>(), 1, 2, 3, 4, 5);
+}
+
+}
More information about the cfe-commits
mailing list