Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
7 changes: 3 additions & 4 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -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 "
Expand Down
9 changes: 2 additions & 7 deletions clang/lib/Sema/SemaType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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) {
Expand Down
14 changes: 14 additions & 0 deletions clang/test/CXX/drs/cwg23xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,20 @@ class C {
};
} // namespace cwg2370

namespace cwg2376 { // cwg2376: 21
#if __cpp_deduction_guides >= 201703
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#if __cpp_deduction_guides >= 201703
#if __cplusplus >= 201703L

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
Expand Down
8 changes: 4 additions & 4 deletions clang/test/Parser/cxx1z-class-template-argument-deduction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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}}
Expand All @@ -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}}
Expand Down Expand Up @@ -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([]{}));
}

Expand Down
26 changes: 26 additions & 0 deletions clang/test/SemaCXX/ctad.cpp
Original file line number Diff line number Diff line change
@@ -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;};
Expand Down
2 changes: 1 addition & 1 deletion clang/www/cxx_dr_status.html
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down