https://github.com/offsetof updated https://github.com/llvm/llvm-project/pull/132829
>From 66833f41d26a6c6355ef67b2f9041ba771b690b7 Mon Sep 17 00:00:00 2001 From: offsetof <offse...@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 <offse...@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@-1 {{cannot form pointer to deduced class template specialization type}} +C e[1]; +// expected-error@-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 <offse...@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; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits