[clang] [clang][Sema] fix incorrect ambiguous function call which use designated-initializer as template argument (PR #167159)
Zhikai Zeng via cfe-commits
cfe-commits at lists.llvm.org
Fri Nov 21 08:35:29 PST 2025
https://github.com/Backl1ght updated https://github.com/llvm/llvm-project/pull/167159
>From 8528d48181f51f6c1426af9ae1d9b6bbb1d9344e Mon Sep 17 00:00:00 2001
From: Backl1ght <backlight.zzk at gmail.com>
Date: Sat, 8 Nov 2025 17:13:21 +0000
Subject: [PATCH 1/4] add check
---
clang/docs/ReleaseNotes.rst | 2 ++
clang/lib/Sema/SemaInit.cpp | 2 ++
.../SemaTemplate/temp_arg_nontype_cxx2c.cpp | 23 +++++++++++++++++++
3 files changed, 27 insertions(+)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 62c8c0130c3d0..af62069cbb8e5 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -495,6 +495,8 @@ Bug Fixes in This Version
- Accept empty enumerations in MSVC-compatible C mode. (#GH114402)
- Fix a bug leading to incorrect code generation with complex number compound assignment and bitfield values, which also caused a crash with UBsan. (#GH166798)
- Fixed false-positive shadow diagnostics for lambdas in explicit object member functions. (#GH163731)
+- Fixed a incorrect diagnostic for ambiguous function call that use a
+ designated-initializer as template argument. (#GH166784)
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index cc6ddf568d346..58c1c01c9b3ba 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -2937,6 +2937,8 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
}
FieldDecl *KnownField = D->getFieldDecl();
+ if (KnownField && KnownField->getParent() != RD)
+ KnownField = nullptr;
if (!KnownField) {
const IdentifierInfo *FieldName = D->getFieldName();
ValueDecl *VD = SemaRef.tryLookupUnambiguousFieldDecl(RD, FieldName);
diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx2c.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx2c.cpp
index c4ac36e263bc8..613956324cb35 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype_cxx2c.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx2c.cpp
@@ -134,3 +134,26 @@ namespace error_on_type_instantiation {
template void g<int>();
// expected-note at -1 {{in instantiation of function template specialization}}
}
+
+namespace GH166784 {
+
+struct A {
+ int a;
+};
+struct B {
+ int b;
+};
+template <A a> void f() {
+ static_assert(a.a == 42);
+}
+template <B b> void f() {
+ static_assert(b.b == 42);
+}
+
+using T1 = decltype(f<{.a = 42}>());
+using T2 = decltype(f<A{.a = 42}>());
+
+using T3 = decltype(f<{.b = 42}>());
+using T4 = decltype(f<B{.b = 42}>());
+
+} // namespace GH166784
>From 800e168dacd0bd814237e18009c949a2209f046f Mon Sep 17 00:00:00 2001
From: Backl1ght <backlight.zzk at gmail.com>
Date: Sat, 8 Nov 2025 17:26:08 +0000
Subject: [PATCH 2/4] fix typo
---
clang/docs/ReleaseNotes.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index af62069cbb8e5..856627f85ad1b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -495,7 +495,7 @@ Bug Fixes in This Version
- Accept empty enumerations in MSVC-compatible C mode. (#GH114402)
- Fix a bug leading to incorrect code generation with complex number compound assignment and bitfield values, which also caused a crash with UBsan. (#GH166798)
- Fixed false-positive shadow diagnostics for lambdas in explicit object member functions. (#GH163731)
-- Fixed a incorrect diagnostic for ambiguous function call that use a
+- Fixed an incorrect diagnostic for ambiguous function call that use a
designated-initializer as template argument. (#GH166784)
Bug Fixes to Compiler Builtins
>From 85f694c7821460f059c5c10a39fbfa310d93acaf Mon Sep 17 00:00:00 2001
From: Backl1ght <backlight.zzk at gmail.com>
Date: Sun, 9 Nov 2025 06:51:09 +0000
Subject: [PATCH 3/4] fix typo
---
clang/docs/ReleaseNotes.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 856627f85ad1b..c33e19abfa78e 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -495,7 +495,7 @@ Bug Fixes in This Version
- Accept empty enumerations in MSVC-compatible C mode. (#GH114402)
- Fix a bug leading to incorrect code generation with complex number compound assignment and bitfield values, which also caused a crash with UBsan. (#GH166798)
- Fixed false-positive shadow diagnostics for lambdas in explicit object member functions. (#GH163731)
-- Fixed an incorrect diagnostic for ambiguous function call that use a
+- Fixed an incorrect diagnostic for ambiguous function call that uses a
designated-initializer as template argument. (#GH166784)
Bug Fixes to Compiler Builtins
>From 5f94e74cf2a81440ccf525cacf43239a20b5d915 Mon Sep 17 00:00:00 2001
From: Backl1ght <backlight.zzk at gmail.com>
Date: Fri, 21 Nov 2025 16:21:41 +0000
Subject: [PATCH 4/4] clear field decls after check done
---
clang/include/clang/AST/Expr.h | 5 +++++
clang/lib/Sema/SemaInit.cpp | 2 --
clang/lib/Sema/SemaTemplate.cpp | 15 +++++++++++++++
3 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 573cc72db35c6..594d21b021a93 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -5628,6 +5628,11 @@ class DesignatedInitExpr final
FieldInfo.NameOrField = reinterpret_cast<uintptr_t>(FD);
}
+ void clearFieldDecl() {
+ assert(isFieldDesignator() && "Only valid on a field designator");
+ FieldInfo.NameOrField = reinterpret_cast<uintptr_t>(getFieldName()) | 0x1;
+ }
+
SourceLocation getDotLoc() const {
assert(isFieldDesignator() && "Only valid on a field designator");
return FieldInfo.DotLoc;
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 58c1c01c9b3ba..cc6ddf568d346 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -2937,8 +2937,6 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
}
FieldDecl *KnownField = D->getFieldDecl();
- if (KnownField && KnownField->getParent() != RD)
- KnownField = nullptr;
if (!KnownField) {
const IdentifierInfo *FieldName = D->getFieldName();
ValueDecl *VD = SemaRef.tryLookupUnambiguousFieldDecl(RD, FieldName);
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 4a9e1bc93b918..a58facb4ff76c 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -7291,11 +7291,26 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType,
Result = ActOnConstantExpression(Result.get());
if (Result.isInvalid() || !Result.get())
return ExprError();
+ Expr* OldDeductionArg = DeductionArg;
setDeductionArg(ActOnFinishFullExpr(Result.get(), Arg->getBeginLoc(),
/*DiscardedValue=*/false,
/*IsConstexpr=*/true,
/*IsTemplateArgument=*/true)
.get());
+ // As for designated initializer, there might be multiple candidate
+ // template parameter types, we must clear field decls of designators
+ // to make sure results of current check will not affect checks for
+ // later types.
+ if (InitListExpr* ILE = dyn_cast<InitListExpr>(OldDeductionArg)) {
+ for (Expr* I : ILE->inits()) {
+ if (DesignatedInitExpr *DIE = dyn_cast<DesignatedInitExpr>(I)) {
+ for (DesignatedInitExpr::Designator& D: DIE->designators()) {
+ if (D.isFieldDesignator())
+ D.clearFieldDecl();
+ }
+ }
+ }
+ }
IsConvertedConstantExpression = false;
}
More information about the cfe-commits
mailing list