[clang] [clang] Fix CTAD not work for function-type and array-type arguments. (PR #78159)

Haojian Wu via cfe-commits cfe-commits at lists.llvm.org
Mon Jan 15 12:21:33 PST 2024


https://github.com/hokein updated https://github.com/llvm/llvm-project/pull/78159

>From f86766ff519ab2b802c0f1ac6c8138cbeadd543a Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Mon, 15 Jan 2024 14:30:18 +0100
Subject: [PATCH 1/3] [clang] Fix CTAD not work for function-type and
 array-type arguments.

Fixes https://github.com/llvm/llvm-project/issues/51710
---
 clang/docs/ReleaseNotes.rst       |  2 ++
 clang/lib/Sema/SemaTemplate.cpp   |  8 +++++++-
 clang/test/SemaCXX/ctad-decay.cpp | 26 ++++++++++++++++++++++++++
 3 files changed, 35 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/SemaCXX/ctad-decay.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 4aba054e252af2..82302bae6d6dc2 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -726,6 +726,8 @@ Bug Fixes in This Version
 - Fix an issue where clang cannot find conversion function with template
   parameter when instantiation of template class.
   Fixes (`#77583 <https://github.com/llvm/llvm-project/issues/77583>`_)
+- Fix an issue where CTAD fails for function-type/array-type arguments.
+  Fixes (`#51710 <https://github.com/llvm/llvm-project/issues/51710>`_)
 
 Bug Fixes to Compiler Builtins
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 5fcc39ec700522..3052b01f7f12ac 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2587,12 +2587,18 @@ struct ConvertConstructorToDeductionGuideTransform {
                           : ParamTy->isRValueReferenceType() ? VK_XValue
                                                              : VK_PRValue);
     }
+    // Handle arrays and functions decay.
+    auto NewType = NewDI->getType();
+    if (NewType->isArrayType())
+      NewType = SemaRef.Context.getArrayDecayedType(NewType);
+    else if (NewType->isFunctionType())
+      NewType = SemaRef.Context.getPointerType(NewType);
 
     ParmVarDecl *NewParam = ParmVarDecl::Create(SemaRef.Context, DC,
                                                 OldParam->getInnerLocStart(),
                                                 OldParam->getLocation(),
                                                 OldParam->getIdentifier(),
-                                                NewDI->getType(),
+                                                NewType,
                                                 NewDI,
                                                 OldParam->getStorageClass(),
                                                 NewDefArg.get());
diff --git a/clang/test/SemaCXX/ctad-decay.cpp b/clang/test/SemaCXX/ctad-decay.cpp
new file mode 100644
index 00000000000000..97063e8fb75659
--- /dev/null
+++ b/clang/test/SemaCXX/ctad-decay.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-unused-value -std=c++20 %s
+// expected-no-diagnostics
+
+namespace GH51710 {
+
+template<typename T>
+struct A{
+  A(T f());
+  A(int f(), T);
+
+  A(T array[10]);
+  A(int array[10], T);
+};
+
+int foo();
+
+void bar() {
+  A test1(foo);
+  A test2(foo, 1);
+
+  int array[10];
+  A test3(array);
+  A test4(array, 1);
+}
+
+} // namespace GH51710

>From 84a414450d08ebaf961007f1dde2ce973e59e183 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Mon, 15 Jan 2024 15:13:55 +0100
Subject: [PATCH 2/3] Move testcases to the existing test file.

---
 clang/lib/Sema/SemaTemplate.cpp               | 12 +++------
 clang/test/SemaCXX/ctad-decay.cpp             | 26 -------------------
 ...xx1z-class-template-argument-deduction.cpp | 23 ++++++++++++++++
 3 files changed, 27 insertions(+), 34 deletions(-)
 delete mode 100644 clang/test/SemaCXX/ctad-decay.cpp

diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 3052b01f7f12ac..bbcedb2fc0b94d 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2594,14 +2594,10 @@ struct ConvertConstructorToDeductionGuideTransform {
     else if (NewType->isFunctionType())
       NewType = SemaRef.Context.getPointerType(NewType);
 
-    ParmVarDecl *NewParam = ParmVarDecl::Create(SemaRef.Context, DC,
-                                                OldParam->getInnerLocStart(),
-                                                OldParam->getLocation(),
-                                                OldParam->getIdentifier(),
-                                                NewType,
-                                                NewDI,
-                                                OldParam->getStorageClass(),
-                                                NewDefArg.get());
+    ParmVarDecl *NewParam = ParmVarDecl::Create(
+        SemaRef.Context, DC, OldParam->getInnerLocStart(),
+        OldParam->getLocation(), OldParam->getIdentifier(), NewType, NewDI,
+        OldParam->getStorageClass(), NewDefArg.get());
     NewParam->setScopeInfo(OldParam->getFunctionScopeDepth(),
                            OldParam->getFunctionScopeIndex());
     SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam);
diff --git a/clang/test/SemaCXX/ctad-decay.cpp b/clang/test/SemaCXX/ctad-decay.cpp
deleted file mode 100644
index 97063e8fb75659..00000000000000
--- a/clang/test/SemaCXX/ctad-decay.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -Wno-unused-value -std=c++20 %s
-// expected-no-diagnostics
-
-namespace GH51710 {
-
-template<typename T>
-struct A{
-  A(T f());
-  A(int f(), T);
-
-  A(T array[10]);
-  A(int array[10], T);
-};
-
-int foo();
-
-void bar() {
-  A test1(foo);
-  A test2(foo, 1);
-
-  int array[10];
-  A test3(array);
-  A test4(array, 1);
-}
-
-} // namespace GH51710
diff --git a/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
index a490d318f54b58..ca3072df8b2e24 100644
--- a/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
+++ b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
@@ -645,4 +645,27 @@ namespace undefined_warnings {
     auto test2 = TemplDObj(.0f);
   }
 }
+
+namespace GH51710 {
+template<typename T>
+struct A {
+  A(T f()) {}
+  A(int f(), T) {}
+
+  A(T array[10]) {}
+  A(int array[10], T) {}
+};
+
+int foo();
+
+void bar() {
+  A test1(foo);
+  A test2(foo, 1);
+
+  int array[10];
+  A test3(array);
+  A test4(array, 1);
+}
+} // namespace GH51710
+
 #endif

>From 53a0939810abee7276f948da5ccf16dfc056ea36 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Mon, 15 Jan 2024 21:20:03 +0100
Subject: [PATCH 3/3] address review comments: add more testcases and use
 getDecayedType API.

---
 clang/lib/Sema/SemaTemplate.cpp                        |  6 ++----
 .../cxx1z-class-template-argument-deduction.cpp        | 10 ++++++++++
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index bbcedb2fc0b94d..80a48c268a648b 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2589,10 +2589,8 @@ struct ConvertConstructorToDeductionGuideTransform {
     }
     // Handle arrays and functions decay.
     auto NewType = NewDI->getType();
-    if (NewType->isArrayType())
-      NewType = SemaRef.Context.getArrayDecayedType(NewType);
-    else if (NewType->isFunctionType())
-      NewType = SemaRef.Context.getPointerType(NewType);
+    if (NewType->isArrayType() || NewType->isFunctionType())
+      NewType = SemaRef.Context.getDecayedType(NewType);
 
     ParmVarDecl *NewParam = ParmVarDecl::Create(
         SemaRef.Context, DC, OldParam->getInnerLocStart(),
diff --git a/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
index ca3072df8b2e24..33ed4295c2e48c 100644
--- a/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
+++ b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
@@ -656,6 +656,13 @@ struct A {
   A(int array[10], T) {}
 };
 
+template<typename T>
+struct B {
+   B(T array[]) {}
+   B(int array[], T) {}
+};
+
+
 int foo();
 
 void bar() {
@@ -665,6 +672,9 @@ void bar() {
   int array[10];
   A test3(array);
   A test4(array, 1);
+
+  B test5(array);
+  B test6(array, 1);
 }
 } // namespace GH51710
 



More information about the cfe-commits mailing list