[clang] [clang] Allow parentheses around CTAD declarators (PR #132829)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 9 09:38:35 PDT 2025
https://github.com/offsetof updated https://github.com/llvm/llvm-project/pull/132829
>From 66833f41d26a6c6355ef67b2f9041ba771b690b7 Mon Sep 17 00:00:00 2001
From: offsetof <offsetof at mailo.com>
Date: Mon, 24 Mar 2025 20:51:23 +0000
Subject: [PATCH 1/3] [clang] Allow parentheses around CTAD declarators
---
clang/docs/ReleaseNotes.rst | 2 ++
.../clang/Basic/DiagnosticSemaKinds.td | 7 +++--
clang/lib/Sema/SemaType.cpp | 9 ++-----
...xx1z-class-template-argument-deduction.cpp | 8 +++---
clang/test/SemaCXX/ctad.cpp | 26 +++++++++++++++++++
5 files changed, 37 insertions(+), 15 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f919b66dd0e41..24c65dbef5869 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -358,6 +358,8 @@ Bug Fixes to C++ Support
- Fixed a Clang regression in C++20 mode where unresolved dependent call expressions were created inside non-dependent contexts (#GH122892)
- Clang now emits the ``-Wunused-variable`` warning when some structured bindings are unused
and the ``[[maybe_unused]]`` attribute is not applied. (#GH125810)
+- Declarations using class template argument deduction with redundant
+ parentheses around the declarator are no longer rejected. (#GH39811)
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index c77cde297dc32..a19975f6d6bdf 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2612,10 +2612,9 @@ def err_decltype_auto_initializer_list : Error<
"cannot deduce 'decltype(auto)' from initializer list">;
// C++17 deduced class template specialization types
-def err_deduced_class_template_compound_type : Error<
- "cannot %select{form pointer to|form reference to|form array of|"
- "form function returning|use parentheses when declaring variable with}0 "
- "deduced class template specialization type">;
+def err_deduced_class_template_compound_type
+ : Error<"cannot form %select{pointer to|reference to|array of|function "
+ "returning}0 deduced class template specialization type">;
def err_deduced_non_class_or_alias_template_specialization_type : Error<
"%select{<error>|function template|variable template|alias template|"
"template template parameter|concept|template}0 %1 requires template "
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index aec33303780a0..16315d93ef8ce 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -4282,8 +4282,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// If T is 'decltype(auto)', the only declarators we can have are parens
// and at most one function declarator if this is a function declaration.
- // If T is a deduced class template specialization type, we can have no
- // declarator chunks at all.
+ // If T is a deduced class template specialization type, only parentheses
+ // are allowed.
if (auto *DT = T->getAs<DeducedType>()) {
const AutoType *AT = T->getAs<AutoType>();
bool IsClassTemplateDeduction = isa<DeducedTemplateSpecializationType>(DT);
@@ -4297,11 +4297,6 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
unsigned DiagKind = 0;
switch (DeclChunk.Kind) {
case DeclaratorChunk::Paren:
- // FIXME: Rejecting this is a little silly.
- if (IsClassTemplateDeduction) {
- DiagKind = 4;
- break;
- }
continue;
case DeclaratorChunk::Function: {
if (IsClassTemplateDeduction) {
diff --git a/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp b/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp
index a1594333abae7..d29eed40b1864 100644
--- a/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp
+++ b/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp
@@ -39,7 +39,7 @@ namespace template_template_arg_pack {
template<typename...> struct YP {};
struct Z { template<typename T> struct Q {}; }; // expected-note 2{{here}}
-
+
template<typename T> using ZId = Z;
template<typename ...Ts> struct A {
@@ -152,7 +152,7 @@ namespace decl {
A a;
A b = 0;
const A c = 0;
- A (parens) = 0; // expected-error {{cannot use parentheses when declaring variable with deduced class template specialization type}}
+ A (parens) = 0;
A *p = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
A &r = *p; // expected-error {{cannot form reference to deduced class template specialization type}}
A arr[3] = 0; // expected-error {{cannot form array of deduced class template specialization type}}
@@ -179,7 +179,7 @@ namespace typename_specifier {
}
typename ::A a = 0;
const typename ::A b = 0;
- typename ::A (parens) = 0; // expected-error {{cannot use parentheses when declaring variable with deduced class template specialization type}}
+ typename ::A (parens) = 0;
typename ::A *p = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
typename ::A &r = *p; // expected-error {{cannot form reference to deduced class template specialization type}}
typename ::A arr[3] = 0; // expected-error {{cannot form array of deduced class template specialization type}}
@@ -217,7 +217,7 @@ namespace typename_specifier {
}
namespace parenthesized {
- template<typename T> struct X { X(T); };
+ template<typename T> struct X { X(T); };
auto n = (X([]{}));
}
diff --git a/clang/test/SemaCXX/ctad.cpp b/clang/test/SemaCXX/ctad.cpp
index 00a861d0f567c..d727c7e66c34c 100644
--- a/clang/test/SemaCXX/ctad.cpp
+++ b/clang/test/SemaCXX/ctad.cpp
@@ -1,5 +1,31 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-unused-value -std=c++20 %s
+namespace GH39811 {
+
+template<int = 0> class C {};
+
+C (a);
+C (b) = C();
+C (c) {};
+C (((((d)))));
+
+template<C (e)> class X;
+template<C (...f)> class Y;
+
+void test() {
+ C (g);
+ C (h) = C();
+ C (i) {};
+ (void)g;
+ (void)h;
+ (void)i;
+}
+
+C* (bad1); // expected-error {{cannot form pointer to deduced class template specialization type}}
+C (*bad2); // expected-error {{cannot form pointer to deduced class template specialization type}}
+
+}
+
namespace GH64347 {
template<typename X, typename Y> struct A { X x; Y y;};
>From 9d717f0f65fd5dcf3d585bf3737830a1065e0abc Mon Sep 17 00:00:00 2001
From: offsetof <offsetof at mailo.com>
Date: Tue, 25 Mar 2025 15:52:30 +0000
Subject: [PATCH 2/3] fixup! [clang] Allow parentheses around CTAD declarators
Add test for CWG2376
---
clang/test/CXX/drs/cwg23xx.cpp | 14 ++++++++++++++
clang/www/cxx_dr_status.html | 2 +-
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/clang/test/CXX/drs/cwg23xx.cpp b/clang/test/CXX/drs/cwg23xx.cpp
index d144cf9e4e868..78ad38d07a163 100644
--- a/clang/test/CXX/drs/cwg23xx.cpp
+++ b/clang/test/CXX/drs/cwg23xx.cpp
@@ -379,6 +379,20 @@ class C {
};
} // namespace cwg2370
+namespace cwg2376 { // cwg2376: 21
+#if __cpp_deduction_guides >= 201703
+template<int = 0> class C {};
+
+C a;
+const volatile C b = C<2>();
+C (c) = {};
+C* d;
+// expected-error at -1 {{cannot form pointer to deduced class template specialization type}}
+C e[1];
+// expected-error at -1 {{cannot form array of deduced class template specialization type}}
+#endif
+}
+
namespace cwg2386 { // cwg2386: 9
// Otherwise, if the qualified-id std::tuple_size<E> names a complete class
// type **with a member value**, the expression std::tuple_size<E>::value shall
diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 16a9b26052f87..d00ae08cc37fd 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -14091,7 +14091,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/2376.html">2376</a></td>
<td>CD5</td>
<td>Class template argument deduction with array declarator</td>
- <td class="unknown" align="center">Unknown</td>
+ <td class="unreleased" align="center">Clang 21</td>
</tr>
<tr id="2377">
<td><a href="https://cplusplus.github.io/CWG/issues/2377.html">2377</a></td>
>From de8abdb934ab6837caf9f39294c71d18bc174417 Mon Sep 17 00:00:00 2001
From: offsetof <offsetof at mailo.com>
Date: Wed, 2 Apr 2025 14:29:47 +0000
Subject: [PATCH 3/3] fixup! [clang] Allow parentheses around CTAD declarators
Replace feature-test macro with `__cplusplus`
---
clang/test/CXX/drs/cwg23xx.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/test/CXX/drs/cwg23xx.cpp b/clang/test/CXX/drs/cwg23xx.cpp
index 78ad38d07a163..78cecb8b71bca 100644
--- a/clang/test/CXX/drs/cwg23xx.cpp
+++ b/clang/test/CXX/drs/cwg23xx.cpp
@@ -380,7 +380,7 @@ class C {
} // namespace cwg2370
namespace cwg2376 { // cwg2376: 21
-#if __cpp_deduction_guides >= 201703
+#if __cplusplus >= 201703L
template<int = 0> class C {};
C a;
More information about the cfe-commits
mailing list