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

via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 16 00:54:40 PST 2024


Author: Haojian Wu
Date: 2024-01-16T09:54:36+01:00
New Revision: f725bb960d45ada3cc4667dd7aa22792d389c7e7

URL: https://github.com/llvm/llvm-project/commit/f725bb960d45ada3cc4667dd7aa22792d389c7e7
DIFF: https://github.com/llvm/llvm-project/commit/f725bb960d45ada3cc4667dd7aa22792d389c7e7.diff

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

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

When transforming a constructor into a corresponding deduction guide,
the decayed types (function/array type) were not handled properly which
made clang fail to compile valid code. The patch teaches clang handle
these decayed type in the transformation.

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/SemaTemplate.cpp
    clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 174392da17551e..ea57769a4a5795 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -748,6 +748,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..80a48c268a648b 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2587,15 +2587,15 @@ struct ConvertConstructorToDeductionGuideTransform {
                           : ParamTy->isRValueReferenceType() ? VK_XValue
                                                              : VK_PRValue);
     }
-
-    ParmVarDecl *NewParam = ParmVarDecl::Create(SemaRef.Context, DC,
-                                                OldParam->getInnerLocStart(),
-                                                OldParam->getLocation(),
-                                                OldParam->getIdentifier(),
-                                                NewDI->getType(),
-                                                NewDI,
-                                                OldParam->getStorageClass(),
-                                                NewDefArg.get());
+    // Handle arrays and functions decay.
+    auto NewType = NewDI->getType();
+    if (NewType->isArrayType() || NewType->isFunctionType())
+      NewType = SemaRef.Context.getDecayedType(NewType);
+
+    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/cxx1z-class-template-argument-deduction.cpp b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
index a490d318f54b58..33ed4295c2e48c 100644
--- a/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
+++ b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
@@ -645,4 +645,37 @@ 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) {}
+};
+
+template<typename T>
+struct B {
+   B(T array[]) {}
+   B(int array[], T) {}
+};
+
+
+int foo();
+
+void bar() {
+  A test1(foo);
+  A test2(foo, 1);
+
+  int array[10];
+  A test3(array);
+  A test4(array, 1);
+
+  B test5(array);
+  B test6(array, 1);
+}
+} // namespace GH51710
+
 #endif


        


More information about the cfe-commits mailing list