https://github.com/Endilll updated https://github.com/llvm/llvm-project/pull/92295
>From a0d5a234431f3db2f0283ffa0909bf8c254aa611 Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov <serebrennikov.vladis...@gmail.com> Date: Wed, 15 May 2024 20:20:43 +0300 Subject: [PATCH 1/5] [clang] Implement CWG2428 "Deprecating a concept" --- clang/include/clang/Sema/Sema.h | 3 ++- clang/lib/Parse/ParseTemplate.cpp | 15 +++++++++------ clang/lib/Sema/SemaTemplate.cpp | 8 +++++++- clang/test/CXX/drs/cwg24xx.cpp | 28 ++++++++++++++++++++++++++++ clang/www/cxx_dr_status.html | 22 +++++++++++++++++----- 5 files changed, 63 insertions(+), 13 deletions(-) diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 6a414aa57f32b..330076ca77371 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -9356,7 +9356,8 @@ class Sema final : public SemaBase { Decl *ActOnConceptDefinition(Scope *S, MultiTemplateParamsArg TemplateParameterLists, const IdentifierInfo *Name, - SourceLocation NameLoc, Expr *ConstraintExpr); + SourceLocation NameLoc, Expr *ConstraintExpr, + const ParsedAttributesView &Attrs); void CheckConceptRedefinition(ConceptDecl *NewDecl, LookupResult &Previous, bool &AddToScope); diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index 665253a6674d2..b8f2b3f9657e7 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -167,9 +167,11 @@ Parser::DeclGroupPtrTy Parser::ParseTemplateDeclarationOrSpecialization( LastParamListWasEmpty); // Parse the actual template declaration. - if (Tok.is(tok::kw_concept)) - return Actions.ConvertDeclToDeclGroup( - ParseConceptDefinition(TemplateInfo, DeclEnd)); + if (Tok.is(tok::kw_concept)) { + Decl *ConceptDecl = ParseConceptDefinition(TemplateInfo, DeclEnd); + ParsingTemplateParams.complete(ConceptDecl); + return Actions.ConvertDeclToDeclGroup(ConceptDecl); + } return ParseDeclarationAfterTemplate( Context, TemplateInfo, ParsingTemplateParams, DeclEnd, AccessAttrs, AS); @@ -316,7 +318,8 @@ Parser::ParseConceptDefinition(const ParsedTemplateInfo &TemplateInfo, const IdentifierInfo *Id = Result.Identifier; SourceLocation IdLoc = Result.getBeginLoc(); - DiagnoseAndSkipCXX11Attributes(); + ParsedAttributes Attrs(AttrFactory); + MaybeParseCXX11Attributes(Attrs); if (!TryConsumeToken(tok::equal)) { Diag(Tok.getLocation(), diag::err_expected) << tok::equal; @@ -335,8 +338,8 @@ Parser::ParseConceptDefinition(const ParsedTemplateInfo &TemplateInfo, ExpectAndConsumeSemi(diag::err_expected_semi_declaration); Expr *ConstraintExpr = ConstraintExprResult.get(); return Actions.ActOnConceptDefinition(getCurScope(), - *TemplateInfo.TemplateParams, - Id, IdLoc, ConstraintExpr); + *TemplateInfo.TemplateParams, Id, IdLoc, + ConstraintExpr, Attrs); } /// ParseTemplateParameters - Parses a template-parameter-list enclosed in diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index c7aac068e264b..2da933896b4da 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -5583,6 +5583,8 @@ Sema::CheckConceptTemplateId(const CXXScopeSpec &SS, /*UpdateArgsWithConversions=*/false)) return ExprError(); + DiagnoseUseOfDecl(NamedConcept, ConceptNameInfo.getLoc()); + auto *CSD = ImplicitConceptSpecializationDecl::Create( Context, NamedConcept->getDeclContext(), NamedConcept->getLocation(), CanonicalConverted); @@ -9787,7 +9789,8 @@ Decl *Sema::ActOnTemplateDeclarator(Scope *S, Decl *Sema::ActOnConceptDefinition( Scope *S, MultiTemplateParamsArg TemplateParameterLists, - const IdentifierInfo *Name, SourceLocation NameLoc, Expr *ConstraintExpr) { + const IdentifierInfo *Name, SourceLocation NameLoc, Expr *ConstraintExpr, + const ParsedAttributesView &Attrs) { DeclContext *DC = CurContext; if (!DC->getRedeclContext()->isFileContext()) { @@ -9849,6 +9852,9 @@ Decl *Sema::ActOnConceptDefinition( ActOnDocumentableDecl(NewDecl); if (AddToScope) PushOnScopeChains(NewDecl, S); + + ProcessDeclAttributeList(S, NewDecl, Attrs); + return NewDecl; } diff --git a/clang/test/CXX/drs/cwg24xx.cpp b/clang/test/CXX/drs/cwg24xx.cpp index 9f876cd870834..805a95c30470e 100644 --- a/clang/test/CXX/drs/cwg24xx.cpp +++ b/clang/test/CXX/drs/cwg24xx.cpp @@ -45,6 +45,34 @@ void fallthrough(int n) { #endif } +namespace cwg2428 { // cwg2428: 19 +#if __cplusplus >= 202002L +template <typename> +concept C [[deprecated]] = true; // #C + +template <typename T> +concept C3 = C<T>; +// expected-warning@-1 {{'C' is deprecated}} +// expected-note@#C {{'C' has been explicitly marked deprecated here}} + +template <typename T, C U> +// expected-warning@-1 {{'C' is deprecated}} +// expected-note@#C {{'C' has been explicitly marked deprecated here}} +requires C<T> +// expected-warning@-1 {{'C' is deprecated}} +// expected-note@#C {{'C' has been explicitly marked deprecated here}} +void f() { + bool b = C<int>; + // expected-warning@-1 {{'C' is deprecated}} + // expected-note@#C {{'C' has been explicitly marked deprecated here}} +}; + +void g(C auto a) {}; +// expected-warning@-1 {{'C' is deprecated}} +// expected-note@#C {{'C' has been explicitly marked deprecated here}} +#endif +} // namespace cwg2428 + namespace cwg2450 { // cwg2450: 18 #if __cplusplus >= 202302L struct S {int a;}; diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html index 92fdcf5556ede..5e33b7492d81d 100755 --- a/clang/www/cxx_dr_status.html +++ b/clang/www/cxx_dr_status.html @@ -10698,7 +10698,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2> <td><a href="https://cplusplus.github.io/CWG/issues/1815.html">1815</a></td> <td>CD4</td> <td>Lifetime extension in aggregate initialization</td> - <td class="unreleased" align="center">Clang 19</td> + <td class="full" align="center">Yes</td> </tr> <tr id="1816"> <td><a href="https://cplusplus.github.io/CWG/issues/1816.html">1816</a></td> @@ -14376,7 +14376,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2> <td><a href="https://cplusplus.github.io/CWG/issues/2428.html">2428</a></td> <td>C++23</td> <td>Deprecating a concept</td> - <td class="unknown" align="center">Unknown</td> + <td class="unreleased" align="center">Clang 19</td> </tr> <tr id="2429"> <td><a href="https://cplusplus.github.io/CWG/issues/2429.html">2429</a></td> @@ -16985,7 +16985,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2> </tr> <tr class="open" id="2863"> <td><a href="https://cplusplus.github.io/CWG/issues/2863.html">2863</a></td> - <td>tentatively ready</td> + <td>drafting</td> <td>Unclear synchronization requirements for object lifetime rules</td> <td align="center">Not resolved</td> </tr> @@ -17021,13 +17021,13 @@ <h2 id="cxxdr">C++ defect report implementation status</h2> </tr> <tr class="open" id="2869"> <td><a href="https://cplusplus.github.io/CWG/issues/2869.html">2869</a></td> - <td>open</td> + <td>review</td> <td><TT>this</TT> in local classes</td> <td align="center">Not resolved</td> </tr> <tr class="open" id="2870"> <td><a href="https://cplusplus.github.io/CWG/issues/2870.html">2870</a></td> - <td>open</td> + <td>review</td> <td>Combining absent <I>encoding-prefix</I>es</td> <td align="center">Not resolved</td> </tr> @@ -17138,6 +17138,18 @@ <h2 id="cxxdr">C++ defect report implementation status</h2> <td>open</td> <td>Missing cases for reference and array types for argument-dependent lookup</td> <td align="center">Not resolved</td> + </tr> + <tr class="open" id="2889"> + <td><a href="https://cplusplus.github.io/CWG/issues/2889.html">2889</a></td> + <td>open</td> + <td>Requiring an accessible destructor for destroying operator delete</td> + <td align="center">Not resolved</td> + </tr> + <tr class="open" id="2890"> + <td><a href="https://cplusplus.github.io/CWG/issues/2890.html">2890</a></td> + <td>open</td> + <td>Defining members of local classes</td> + <td align="center">Not resolved</td> </tr></table> </div> >From 1ad9b19101e47b6d0d3f3c1063b93194d31ccb16 Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov <serebrennikov.vladis...@gmail.com> Date: Wed, 15 May 2024 23:32:07 +0300 Subject: [PATCH 2/5] Address review feedback --- clang/docs/ReleaseNotes.rst | 3 +++ clang/test/CXX/drs/cwg24xx.cpp | 16 ++++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index ae699ebfc6038..1f51879e914f2 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -222,6 +222,9 @@ Resolutions to C++ Defect Reports - Clang now diagnoses declarative nested-name-specifiers with pack-index-specifiers. (`CWG2858: Declarative nested-name-specifiers and pack-index-specifiers <https://cplusplus.github.io/CWG/issues/2858.html>`_). +- Clang now allows attributes on concepts. + (`CWG2428: Deprecating a concept <https://cplusplus.github.io/CWG/issues/2428.html>`_). + - P0522 implementation is enabled by default in all language versions, and provisional wording for CWG2398 is implemented. diff --git a/clang/test/CXX/drs/cwg24xx.cpp b/clang/test/CXX/drs/cwg24xx.cpp index 4fc3d2db789a7..d329a703829db 100644 --- a/clang/test/CXX/drs/cwg24xx.cpp +++ b/clang/test/CXX/drs/cwg24xx.cpp @@ -48,28 +48,32 @@ void fallthrough(int n) { namespace cwg2428 { // cwg2428: 19 #if __cplusplus >= 202002L template <typename> -concept C [[deprecated]] = true; // #C +concept C [[deprecated]] = true; // #cwg2428-C + +template <typename> +[[deprecated]] concept C2 = true; +// expected-error@-1 {{expected unqualified-id}} template <typename T> concept C3 = C<T>; // expected-warning@-1 {{'C' is deprecated}} -// expected-note@#C {{'C' has been explicitly marked deprecated here}} +// expected-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}} template <typename T, C U> // expected-warning@-1 {{'C' is deprecated}} -// expected-note@#C {{'C' has been explicitly marked deprecated here}} +// expected-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}} requires C<T> // expected-warning@-1 {{'C' is deprecated}} -// expected-note@#C {{'C' has been explicitly marked deprecated here}} +// expected-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}} void f() { bool b = C<int>; // expected-warning@-1 {{'C' is deprecated}} - // expected-note@#C {{'C' has been explicitly marked deprecated here}} + // expected-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}} }; void g(C auto a) {}; // expected-warning@-1 {{'C' is deprecated}} -// expected-note@#C {{'C' has been explicitly marked deprecated here}} +// expected-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}} #endif } // namespace cwg2428 >From 019a1694a77c0af6f6fc5bf4cb1bc564acc2c1a1 Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov <serebrennikov.vladis...@gmail.com> Date: Thu, 16 May 2024 13:33:28 +0300 Subject: [PATCH 3/5] Add the test suggested by @cor3ntin --- clang/lib/Sema/SemaDecl.cpp | 10 ++++++++++ clang/lib/Sema/SemaType.cpp | 10 ++++++++++ clang/test/CXX/drs/cwg24xx.cpp | 10 ++++++++++ 3 files changed, 30 insertions(+) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 0dbdf923df95a..fbf1a64df7492 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -7573,6 +7573,16 @@ NamedDecl *Sema::ActOnVariableDeclarator( tryToFixVariablyModifiedVarType(TInfo, R, D.getIdentifierLoc(), /*DiagID=*/0); + if (getLangOpts().CPlusPlus20) { + if (const AutoType *AutoT = R->getAs<AutoType>()) { + if (ConceptDecl *Decl = AutoT->getTypeConstraintConcept()) { + DiagnoseUseOfDecl( + Decl, + TInfo->getTypeLoc().getContainedAutoTypeLoc().getConceptNameLoc()); + } + } + } + bool IsMemberSpecialization = false; bool IsVariableTemplateSpecialization = false; bool IsPartialSpecialization = false; diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index eb67546d048ae..27736485962f4 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -6388,6 +6388,16 @@ TypeResult Sema::ActOnTypeName(Declarator &D) { CheckExtraCXXDefaultArguments(D); } + if (getLangOpts().CPlusPlus20) { + if (const AutoType *AutoT = T->getAs<AutoType>()) { + if (ConceptDecl *Decl = AutoT->getTypeConstraintConcept()) { + DiagnoseUseOfDecl( + Decl, + TInfo->getTypeLoc().getContainedAutoTypeLoc().getConceptNameLoc()); + } + } + } + return CreateParsedType(T, TInfo); } diff --git a/clang/test/CXX/drs/cwg24xx.cpp b/clang/test/CXX/drs/cwg24xx.cpp index d329a703829db..4c7b1506e86ea 100644 --- a/clang/test/CXX/drs/cwg24xx.cpp +++ b/clang/test/CXX/drs/cwg24xx.cpp @@ -74,6 +74,16 @@ void f() { void g(C auto a) {}; // expected-warning@-1 {{'C' is deprecated}} // expected-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}} + +template <typename T> +auto h() -> C auto { +// expected-warning@-1 {{'C' is deprecated}} +// expected-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}} + C auto foo = T(); + // expected-warning@-1 {{'C' is deprecated}} + // expected-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}} + return foo; +} #endif } // namespace cwg2428 >From 308adb3489ef9905966c692669ea17eb644b00d3 Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov <serebrennikov.vladis...@gmail.com> Date: Thu, 16 May 2024 13:56:58 +0300 Subject: [PATCH 4/5] Factor out `CheckConstrainedAuto()` --- clang/include/clang/Sema/Sema.h | 2 ++ clang/lib/Sema/SemaChecking.cpp | 12 ++++++++++++ clang/lib/Sema/SemaDecl.cpp | 10 +--------- clang/lib/Sema/SemaType.cpp | 10 +--------- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 330076ca77371..1ce3f171950bb 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -2022,6 +2022,8 @@ class Sema final : public SemaBase { void CheckTCBEnforcement(const SourceLocation CallExprLoc, const NamedDecl *Callee); + void CheckConstrainedAuto(TypeSourceInfo *TS); + private: void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, const ArraySubscriptExpr *ASE = nullptr, diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index ecd1821651140..5607d8e574bf6 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -8092,6 +8092,18 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, diagnoseArgDependentDiagnoseIfAttrs(FD, ThisArg, Args, Loc); } +void Sema::CheckConstrainedAuto(TypeSourceInfo *TS) { + if (getLangOpts().CPlusPlus20) { + if (const AutoType *AutoT = TS->getType()->getAs<AutoType>()) { + if (ConceptDecl *Decl = AutoT->getTypeConstraintConcept()) { + DiagnoseUseOfDecl( + Decl, + TS->getTypeLoc().getContainedAutoTypeLoc().getConceptNameLoc()); + } + } + } +} + /// CheckConstructorCall - Check a constructor call for correctness and safety /// properties not enforced by the C type system. void Sema::CheckConstructorCall(FunctionDecl *FDecl, QualType ThisType, diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index fbf1a64df7492..7ac2e80c9aeb2 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -7573,15 +7573,7 @@ NamedDecl *Sema::ActOnVariableDeclarator( tryToFixVariablyModifiedVarType(TInfo, R, D.getIdentifierLoc(), /*DiagID=*/0); - if (getLangOpts().CPlusPlus20) { - if (const AutoType *AutoT = R->getAs<AutoType>()) { - if (ConceptDecl *Decl = AutoT->getTypeConstraintConcept()) { - DiagnoseUseOfDecl( - Decl, - TInfo->getTypeLoc().getContainedAutoTypeLoc().getConceptNameLoc()); - } - } - } + CheckConstrainedAuto(TInfo); bool IsMemberSpecialization = false; bool IsVariableTemplateSpecialization = false; diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 27736485962f4..4c54958d7912a 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -6388,15 +6388,7 @@ TypeResult Sema::ActOnTypeName(Declarator &D) { CheckExtraCXXDefaultArguments(D); } - if (getLangOpts().CPlusPlus20) { - if (const AutoType *AutoT = T->getAs<AutoType>()) { - if (ConceptDecl *Decl = AutoT->getTypeConstraintConcept()) { - DiagnoseUseOfDecl( - Decl, - TInfo->getTypeLoc().getContainedAutoTypeLoc().getConceptNameLoc()); - } - } - } + CheckConstrainedAuto(TInfo); return CreateParsedType(T, TInfo); } >From c511b90c140c758420f65252df7da629d6ae6a4b Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov <serebrennikov.vladis...@gmail.com> Date: Thu, 16 May 2024 14:54:20 +0300 Subject: [PATCH 5/5] Allow non-standard attribute spellings --- clang/lib/Parse/ParseTemplate.cpp | 2 +- clang/test/SemaCXX/cxx-deprecated.cpp | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index b8f2b3f9657e7..e6a41d8830caa 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -319,7 +319,7 @@ Parser::ParseConceptDefinition(const ParsedTemplateInfo &TemplateInfo, SourceLocation IdLoc = Result.getBeginLoc(); ParsedAttributes Attrs(AttrFactory); - MaybeParseCXX11Attributes(Attrs); + MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, Attrs); if (!TryConsumeToken(tok::equal)) { Diag(Tok.getLocation(), diag::err_expected) << tok::equal; diff --git a/clang/test/SemaCXX/cxx-deprecated.cpp b/clang/test/SemaCXX/cxx-deprecated.cpp index aa4501d53197a..8e81fc4e3b0c4 100644 --- a/clang/test/SemaCXX/cxx-deprecated.cpp +++ b/clang/test/SemaCXX/cxx-deprecated.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 -fms-extensions %s namespace [[deprecated]] {} // expected-warning {{'deprecated' attribute on anonymous namespace ignored}} @@ -27,3 +28,23 @@ namespace M = N; // expected-warning {{'N' is deprecated}} // Shouldn't diag: [[nodiscard, deprecated("")]] int PR37935(); + +namespace cxx20_concept { +template <typename> +concept C __attribute__((deprecated)) = true; // #C + +template <C T> +// expected-warning@-1 {{'C' is deprecated}} +// expected-note@#C {{'C' has been explicitly marked deprecated here}} +void f(); + +#ifdef _MSC_VER +template <typename> +concept C2 __declspec(deprecated) = true; // #C2 + +template <C2 T> +// expected-warning@-1 {{'C2' is deprecated}} +// expected-note@#C2 {{'C2' has been explicitly marked deprecated here}} +void g(); +#endif +} // namespace cxx20_concept _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits