Skip to content

Commit 9604bdf

Browse files
authored
[clang] Allow parentheses around CTAD declarators (#132829)
Fixes #39811
1 parent fa0498f commit 9604bdf

File tree

7 files changed

+52
-16
lines changed

7 files changed

+52
-16
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,8 @@ Bug Fixes to C++ Support
452452
- Fixed a Clang regression in C++20 mode where unresolved dependent call expressions were created inside non-dependent contexts (#GH122892)
453453
- Clang now emits the ``-Wunused-variable`` warning when some structured bindings are unused
454454
and the ``[[maybe_unused]]`` attribute is not applied. (#GH125810)
455+
- Declarations using class template argument deduction with redundant
456+
parentheses around the declarator are no longer rejected. (#GH39811)
455457
- Fixed a crash caused by invalid declarations of ``std::initializer_list``. (#GH132256)
456458
- Clang no longer crashes when establishing subsumption between some constraint expressions. (#GH122581)
457459
- Clang now issues an error when placement new is used to modify a const-qualified variable

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2617,10 +2617,9 @@ def err_decltype_auto_initializer_list : Error<
26172617
"cannot deduce 'decltype(auto)' from initializer list">;
26182618

26192619
// C++17 deduced class template specialization types
2620-
def err_deduced_class_template_compound_type : Error<
2621-
"cannot %select{form pointer to|form reference to|form array of|"
2622-
"form function returning|use parentheses when declaring variable with}0 "
2623-
"deduced class template specialization type">;
2620+
def err_deduced_class_template_compound_type
2621+
: Error<"cannot form %select{pointer to|reference to|array of|function "
2622+
"returning}0 deduced class template specialization type">;
26242623
def err_deduced_non_class_or_alias_template_specialization_type : Error<
26252624
"%select{<error>|function template|variable template|alias template|"
26262625
"template template parameter|concept|template}0 %1 requires template "

clang/lib/Sema/SemaType.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4281,8 +4281,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
42814281

42824282
// If T is 'decltype(auto)', the only declarators we can have are parens
42834283
// and at most one function declarator if this is a function declaration.
4284-
// If T is a deduced class template specialization type, we can have no
4285-
// declarator chunks at all.
4284+
// If T is a deduced class template specialization type, only parentheses
4285+
// are allowed.
42864286
if (auto *DT = T->getAs<DeducedType>()) {
42874287
const AutoType *AT = T->getAs<AutoType>();
42884288
bool IsClassTemplateDeduction = isa<DeducedTemplateSpecializationType>(DT);
@@ -4296,11 +4296,6 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
42964296
unsigned DiagKind = 0;
42974297
switch (DeclChunk.Kind) {
42984298
case DeclaratorChunk::Paren:
4299-
// FIXME: Rejecting this is a little silly.
4300-
if (IsClassTemplateDeduction) {
4301-
DiagKind = 4;
4302-
break;
4303-
}
43044299
continue;
43054300
case DeclaratorChunk::Function: {
43064301
if (IsClassTemplateDeduction) {

clang/test/CXX/drs/cwg23xx.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,20 @@ class C {
379379
};
380380
} // namespace cwg2370
381381

382+
namespace cwg2376 { // cwg2376: 21
383+
#if __cplusplus >= 201703L
384+
template<int = 0> class C {};
385+
386+
C a;
387+
const volatile C b = C<2>();
388+
C (c) = {};
389+
C* d;
390+
// expected-error@-1 {{cannot form pointer to deduced class template specialization type}}
391+
C e[1];
392+
// expected-error@-1 {{cannot form array of deduced class template specialization type}}
393+
#endif
394+
}
395+
382396
namespace cwg2386 { // cwg2386: 9
383397
// Otherwise, if the qualified-id std::tuple_size<E> names a complete class
384398
// type **with a member value**, the expression std::tuple_size<E>::value shall

clang/test/Parser/cxx1z-class-template-argument-deduction.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ namespace template_template_arg_pack {
3939
template<typename...> struct YP {};
4040

4141
struct Z { template<typename T> struct Q {}; }; // expected-note 2{{here}}
42-
42+
4343
template<typename T> using ZId = Z;
4444

4545
template<typename ...Ts> struct A {
@@ -152,7 +152,7 @@ namespace decl {
152152
A a;
153153
A b = 0;
154154
const A c = 0;
155-
A (parens) = 0; // expected-error {{cannot use parentheses when declaring variable with deduced class template specialization type}}
155+
A (parens) = 0;
156156
A *p = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
157157
A &r = *p; // expected-error {{cannot form reference to deduced class template specialization type}}
158158
A arr[3] = 0; // expected-error {{cannot form array of deduced class template specialization type}}
@@ -179,7 +179,7 @@ namespace typename_specifier {
179179
}
180180
typename ::A a = 0;
181181
const typename ::A b = 0;
182-
typename ::A (parens) = 0; // expected-error {{cannot use parentheses when declaring variable with deduced class template specialization type}}
182+
typename ::A (parens) = 0;
183183
typename ::A *p = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
184184
typename ::A &r = *p; // expected-error {{cannot form reference to deduced class template specialization type}}
185185
typename ::A arr[3] = 0; // expected-error {{cannot form array of deduced class template specialization type}}
@@ -217,7 +217,7 @@ namespace typename_specifier {
217217
}
218218

219219
namespace parenthesized {
220-
template<typename T> struct X { X(T); };
220+
template<typename T> struct X { X(T); };
221221
auto n = (X([]{}));
222222
}
223223

clang/test/SemaCXX/ctad.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,31 @@
11
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-unused-value -std=c++20 %s
22

3+
namespace GH39811 {
4+
5+
template<int = 0> class C {};
6+
7+
C (a);
8+
C (b) = C();
9+
C (c) {};
10+
C (((((d)))));
11+
12+
template<C (e)> class X;
13+
template<C (...f)> class Y;
14+
15+
void test() {
16+
C (g);
17+
C (h) = C();
18+
C (i) {};
19+
(void)g;
20+
(void)h;
21+
(void)i;
22+
}
23+
24+
C* (bad1); // expected-error {{cannot form pointer to deduced class template specialization type}}
25+
C (*bad2); // expected-error {{cannot form pointer to deduced class template specialization type}}
26+
27+
}
28+
329
namespace GH64347 {
430

531
template<typename X, typename Y> struct A { X x; Y y;};

clang/www/cxx_dr_status.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14091,7 +14091,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
1409114091
<td><a href="https://cplusplus.github.io/CWG/issues/2376.html">2376</a></td>
1409214092
<td>CD5</td>
1409314093
<td>Class template argument deduction with array declarator</td>
14094-
<td class="unknown" align="center">Unknown</td>
14094+
<td class="unreleased" align="center">Clang 21</td>
1409514095
</tr>
1409614096
<tr id="2377">
1409714097
<td><a href="https://cplusplus.github.io/CWG/issues/2377.html">2377</a></td>

0 commit comments

Comments
 (0)