mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-14 15:46:32 +00:00
[clang] Allow parentheses around CTAD declarators (#132829)
Fixes #39811
This commit is contained in:
parent
fa0498fdae
commit
9604bdf118
@ -452,6 +452,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)
|
||||
- Fixed a crash caused by invalid declarations of ``std::initializer_list``. (#GH132256)
|
||||
- Clang no longer crashes when establishing subsumption between some constraint expressions. (#GH122581)
|
||||
- Clang now issues an error when placement new is used to modify a const-qualified variable
|
||||
|
@ -2617,10 +2617,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 "
|
||||
|
@ -4281,8 +4281,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);
|
||||
@ -4296,11 +4296,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) {
|
||||
|
@ -379,6 +379,20 @@ class C {
|
||||
};
|
||||
} // namespace cwg2370
|
||||
|
||||
namespace cwg2376 { // cwg2376: 21
|
||||
#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
|
||||
|
@ -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([]{}));
|
||||
}
|
||||
|
||||
|
@ -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;};
|
||||
|
@ -14091,7 +14091,7 @@ and <I>POD class</I></td>
|
||||
<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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user