https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/116332
>From 5973de1d4c368a26fd179954a13de94595f35575 Mon Sep 17 00:00:00 2001 From: Younan Zhang <zyn7...@gmail.com> Date: Fri, 15 Nov 2024 14:09:14 +0800 Subject: [PATCH 1/2] [Clang][Parser] Make 'T...[N]' within a function parameter a valid pack expansion prior to C++2c --- .../clang/Basic/DiagnosticParseKinds.td | 5 ++++ clang/lib/Parse/ParseExprCXX.cpp | 18 ++++++++++++++ .../CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp | 5 ++-- clang/test/Parser/cxx0x-decl.cpp | 8 ++----- .../SemaCXX/cxx2c-pack-indexing-ext-diags.cpp | 24 +++++++++++++++++++ 5 files changed, 52 insertions(+), 8 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 0da509280068ad..7b408f3eed5ba5 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -718,6 +718,11 @@ def warn_empty_init_statement : Warning< "has no effect">, InGroup<EmptyInitStatement>, DefaultIgnore; def err_keyword_as_parameter : Error < "invalid parameter name: '%0' is a keyword">; +def warn_pre_cxx26_ambiguous_pack_indexing_type : Warning< + "parameter packs without specifying a name would become a pack indexing " + "declaration in C++2c onwards">, InGroup<CXXPre26Compat>; +def note_add_a_name_to_pre_cxx26_parameter_packs : Note< + "add a name to disambiguate">; // C++ derived classes def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">; diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index ce3624f366a2a1..c596785b267b5b 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -242,7 +242,25 @@ bool Parser::ParseOptionalCXXScopeSpecifier( SourceLocation Start = Tok.getLocation(); DeclSpec DS(AttrFactory); SourceLocation CCLoc; + TentativeParsingAction MaybePackIndexing(*this, /*Unannotated=*/true); SourceLocation EndLoc = ParsePackIndexingType(DS); + // C++ [cpp23.dcl.dcl-2]: + // Previously, T...[n] would declare a pack of function parameters. + // T...[n] is now a pack-index-specifier. [...] Valid C++ 2023 code that + // declares a pack of parameters without specifying a declarator-id + // becomes ill-formed. + if (!Tok.is(tok::coloncolon) && !getLangOpts().CPlusPlus26 && + getCurScope()->isFunctionDeclarationScope()) { + Diag(DS.getEllipsisLoc(), + diag::warn_pre_cxx26_ambiguous_pack_indexing_type); + Diag(DS.getEllipsisLoc(), + diag::note_add_a_name_to_pre_cxx26_parameter_packs); + MaybePackIndexing.Revert(); + return false; + } + + MaybePackIndexing.Commit(); + if (DS.getTypeSpecType() == DeclSpec::TST_error) return false; diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp index dbb6e60d9b93d7..0ae08da280b152 100644 --- a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp @@ -58,8 +58,9 @@ void b(T[] ...); template<typename T> void c(T ... []); // expected-error {{expected expression}} \ - // expected-error {{'T' does not refer to the name of a parameter pack}} \ - // expected-warning {{pack indexing is a C++2c extension}} + // expected-error {{type 'T[]' of function parameter pack does not contain any unexpanded parameter packs}} \ + // expected-warning {{would become a pack indexing declaration in C++2c onwards}} \ + // expected-note {{add a name to disambiguate}} template<typename T> void d(T ... x[]); // expected-error{{type 'T[]' of function parameter pack does not contain any unexpanded parameter packs}} diff --git a/clang/test/Parser/cxx0x-decl.cpp b/clang/test/Parser/cxx0x-decl.cpp index a0b3266c738ff5..91b97df459df92 100644 --- a/clang/test/Parser/cxx0x-decl.cpp +++ b/clang/test/Parser/cxx0x-decl.cpp @@ -214,12 +214,8 @@ struct MemberComponentOrder : Base { void NoMissingSemicolonHere(struct S [3]); template<int ...N> void NoMissingSemicolonHereEither(struct S... [N]); -// expected-error@-1 {{'S' does not refer to the name of a parameter pack}} \ -// expected-error@-1 {{declaration of anonymous struct must be a definition}} \ -// expected-error@-1 {{expected parameter declarator}} \ -// expected-error@-1 {{pack indexing is a C++2c extension}} \ - - +// expected-warning@-1 {{parameter packs without specifying a name would become a pack indexing declaration in C++2c onwards}} \ +// expected-note@-1 {{add a name to disambiguate}} // This must be at the end of the file; we used to look ahead past the EOF token here. // expected-error@+1 {{expected unqualified-id}} expected-error@+1{{expected ';'}} diff --git a/clang/test/SemaCXX/cxx2c-pack-indexing-ext-diags.cpp b/clang/test/SemaCXX/cxx2c-pack-indexing-ext-diags.cpp index 80dfeb9b6a8bf5..f4dbd5ca539635 100644 --- a/clang/test/SemaCXX/cxx2c-pack-indexing-ext-diags.cpp +++ b/clang/test/SemaCXX/cxx2c-pack-indexing-ext-diags.cpp @@ -19,3 +19,27 @@ void f(T... t) { // cxx11-warning@+1 {{pack indexing is a C++2c extension}} T...[0] c; } + +template <typename... T> +void g(T... [1]); // cxx11-warning {{parameter packs without specifying a name would become a pack indexing declaration in C++2c onwards}} \ + // cxx11-note {{add a name to disambiguate}} \ + // cxx26-warning {{pack indexing is incompatible with C++ standards before C++2c}} \ + // cxx26-note {{candidate function template not viable}} + +template <typename... T> +void h(T... param[1]); + +template <class T> +struct S { + using type = T; +}; + +template <typename... T> +void h(typename T... [1]::type); // cxx11-warning {{pack indexing is a C++2c extension}} \ + // cxx26-warning {{pack indexing is incompatible with C++ standards before C++2c}} + +void call() { + g<int, double>(nullptr, nullptr); // cxx26-error {{no matching function for call to 'g'}} + h<int, double>(nullptr, nullptr); + h<S<int>, S<const char *>>("hello"); +} >From c48988ae40d6a6934a75b527cb9d3d4a42de1faa Mon Sep 17 00:00:00 2001 From: Younan Zhang <zyn7...@gmail.com> Date: Sat, 16 Nov 2024 21:24:41 +0800 Subject: [PATCH 2/2] Accept 'T...[]' within a function parameter scope --- clang/lib/Parse/ParseExprCXX.cpp | 3 ++- clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp | 9 +++++---- clang/test/Parser/cxx2c-pack-indexing.cpp | 5 ++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index c596785b267b5b..66ba5e2cd074c3 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -238,7 +238,8 @@ bool Parser::ParseOptionalCXXScopeSpecifier( else if (!HasScopeSpecifier && Tok.is(tok::identifier) && GetLookAheadToken(1).is(tok::ellipsis) && - GetLookAheadToken(2).is(tok::l_square)) { + GetLookAheadToken(2).is(tok::l_square) && + !GetLookAheadToken(3).is(tok::r_square)) { SourceLocation Start = Tok.getLocation(); DeclSpec DS(AttrFactory); SourceLocation CCLoc; diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp index 0ae08da280b152..a633c108bc22cd 100644 --- a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp @@ -57,10 +57,11 @@ template<typename T> void b(T[] ...); template<typename T> -void c(T ... []); // expected-error {{expected expression}} \ - // expected-error {{type 'T[]' of function parameter pack does not contain any unexpanded parameter packs}} \ - // expected-warning {{would become a pack indexing declaration in C++2c onwards}} \ - // expected-note {{add a name to disambiguate}} +void c(T ... []); // expected-error {{type 'T[]' of function parameter pack does not contain any unexpanded parameter packs}} + +// A function that takes pointers to each type T as arguments, after any decay. +template <typename ...T> +void g(T...[]); template<typename T> void d(T ... x[]); // expected-error{{type 'T[]' of function parameter pack does not contain any unexpanded parameter packs}} diff --git a/clang/test/Parser/cxx2c-pack-indexing.cpp b/clang/test/Parser/cxx2c-pack-indexing.cpp index c279bdd7af8c44..45a0e047221e1f 100644 --- a/clang/test/Parser/cxx2c-pack-indexing.cpp +++ b/clang/test/Parser/cxx2c-pack-indexing.cpp @@ -12,8 +12,7 @@ struct S { // expected-note {{to match this '['}} \ // expected-warning{{declaration does not declare anything}} - T...[]; // expected-error{{expected expression}} \ - // expected-warning{{declaration does not declare anything}} + T...[]; // expected-error{{expected member name or ';' after declaration specifiers}} void f(auto... v) { decltype(v...[1]) a = v...[1]; @@ -65,7 +64,7 @@ int main() { } -namespace GH11460 { +namespace GH111460 { template <typename... T> requires( ); // expected-error {{expected expression}} struct SS { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits