[clang] [clang] Fix CTAD not work for C++ explicit type conversion (functional annotation). (PR #75779)

Haojian Wu via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 18 01:49:22 PST 2023


https://github.com/hokein created https://github.com/llvm/llvm-project/pull/75779

Fixes https://github.com/llvm/llvm-project/issues/64347

>From 073f3d87bc9e22e3fb80ee9ab297e0bd6e4127f2 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Mon, 18 Dec 2023 10:41:45 +0100
Subject: [PATCH] [clang] Fix CTAD not work for C++ explicit type conversion
 (functional annotation).

Fixes https://github.com/llvm/llvm-project/issues/64347
---
 clang/docs/ReleaseNotes.rst |  2 ++
 clang/lib/Sema/SemaDecl.cpp |  2 +-
 clang/lib/Sema/SemaInit.cpp | 11 +++++++----
 clang/test/SemaCXX/ctad.cpp | 19 +++++++++++++++++++
 4 files changed, 29 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/SemaCXX/ctad.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f5ae6bb8925202..0bb614c2237794 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -685,6 +685,8 @@ Bug Fixes in This Version
   (`#62157 <https://github.com/llvm/llvm-project/issues/62157>`_) and
   (`#64885 <https://github.com/llvm/llvm-project/issues/64885>`_) and
   (`#65568 <https://github.com/llvm/llvm-project/issues/65568>`_)
+- Fix an issue where CTAD fails for explicit type conversion. Fixes
+  (#64347 <https://github.com/llvm/llvm-project/issues/64347>`_)
 
 Bug Fixes to Compiler Builtins
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index be6a136ef37bc4..85e1d28b0e3fdd 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -12957,7 +12957,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
     // FIXME: Initialization should not be taking a mutable list of inits.
     SmallVector<Expr*, 8> InitsCopy(DeduceInits.begin(), DeduceInits.end());
     return DeduceTemplateSpecializationFromInitializer(TSI, Entity, Kind,
-                                                       InitsCopy, PL);
+                                                       InitsCopy);
   }
 
   if (DirectInit) {
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 4028b2d642b212..7036a88df6b90e 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -10573,7 +10573,7 @@ static bool isOrIsDerivedFromSpecializationOf(CXXRecordDecl *RD,
 
 QualType Sema::DeduceTemplateSpecializationFromInitializer(
     TypeSourceInfo *TSInfo, const InitializedEntity &Entity,
-    const InitializationKind &Kind, MultiExprArg Inits, ParenListExpr *PL) {
+    const InitializationKind &Kind, MultiExprArg Inits) {
   auto *DeducedTST = dyn_cast<DeducedTemplateSpecializationType>(
       TSInfo->getType()->getContainedDeducedType());
   assert(DeducedTST && "not a deduced template specialization type");
@@ -10804,9 +10804,12 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
     if (getLangOpts().CPlusPlus20 && !HasAnyDeductionGuide) {
       if (ListInit && ListInit->getNumInits()) {
         SynthesizeAggrGuide(ListInit);
-      } else if (PL && PL->getNumExprs()) {
-        InitListExpr TempListInit(getASTContext(), PL->getLParenLoc(),
-                                  PL->exprs(), PL->getRParenLoc());
+      } else if (Inits.size()) { // parenthesized expression-list
+        // Inits are expressions inside the parentheses. We don't have
+        // the parentheses source locaitons, use the begin/end of Inits as the
+        // best heuristic.
+        InitListExpr TempListInit(getASTContext(), Inits.front()->getBeginLoc(),
+                                  Inits, Inits.back()->getEndLoc());
         SynthesizeAggrGuide(&TempListInit);
       }
     }
diff --git a/clang/test/SemaCXX/ctad.cpp b/clang/test/SemaCXX/ctad.cpp
new file mode 100644
index 00000000000000..10806f107b4ee9
--- /dev/null
+++ b/clang/test/SemaCXX/ctad.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-unused-value -std=c++20 %s
+// expected-no-diagnostics
+
+namespace GH64347 {
+
+template<typename X, typename Y> struct A { X x; Y y;};
+void test() {
+   A(1, 2);
+   new A(1, 2);
+}
+
+template<A a>
+void f() { (void)a; }
+void k() {
+  // Test CTAD works for non-type template arguments.
+  f<A(0, 0)>();
+}
+
+} // namespace GH64347



More information about the cfe-commits mailing list